From a3c0c0539c89678afd08699052ec5f6bd305c393 Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 29 Jul 2012 23:14:52 +0000 Subject: [PATCH 001/222] Creating new Branch to work on GXS services & GXS backend. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5351 b45a01b8-16f6-495d-af2f-9b41ad6348cc From 75eb504a0dbeadb3fac4012b8643913991efb6bc Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 30 Jul 2012 10:58:55 +0000 Subject: [PATCH 002/222] Enabled GXS Build in the branch. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5352 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/libretroshare.pro | 4 ++-- libretroshare/src/rsserver/rsinit.cc | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 1d7ac0863..de151c9a3 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -8,8 +8,8 @@ TARGET = retroshare CONFIG += test_voip # GXS Stuff. -#CONFIG += newcache -#CONFIG += newservices +CONFIG += newcache +CONFIG += newservices # Beware: All data of the stripped services are lost DEFINES *= PQI_DISABLE_TUNNEL diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index bc5bded62..d6a0881da 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1806,6 +1806,7 @@ RsTurtle *rsTurtle = NULL ; #include "services/p3blogs.h" #include "turtle/p3turtle.h" +#define ENABLE_GXS_SERVICES 1 #ifdef ENABLE_GXS_SERVICES #include "services/p3photoservice.h" #include "services/p3wikiservice.h" From 2ba3f73a74b0e7ed5d69c7fec00c10bf72237e6d Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 30 Jul 2012 11:35:26 +0000 Subject: [PATCH 003/222] Same fixes to the branch. - comment out line from future prototype. - added missing #include git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5356 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/retroshare/rsidentity.h | 2 +- libretroshare/src/services/p3idservice.cc | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index 4f9a17907..1e0164e70 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -489,7 +489,7 @@ virtual bool createMsg(uint32_t &token, RsIdMsg &msg, bool isNew) = 0; */ //virtual uint32_t getIdDetails(const std::string &id, std::string &nickname, bool &isGpgKnown, - uint32_t &ownOpinion, float &reputation); +// uint32_t &ownOpinion, float &reputation); //virtual uint32_t getOwnIds(std::list &ownIds); //virtual bool setOpinion(const std::string &id, uint32_t opinion); diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 60abaaaff..1dc8bc3c0 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -28,6 +28,7 @@ #include "util/rsrandom.h" #include #include +#include /**** * #define ID_DEBUG 1 From 363374947feb5698e58e1ab1b1476fdbd2be53b5 Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 30 Jul 2012 23:39:16 +0000 Subject: [PATCH 004/222] Added functions to modify the Sorting Algorithm for PostedLinks. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5359 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/retroshare/rsposted.h | 6 ++++++ libretroshare/src/services/p3posted.cc | 15 +++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/libretroshare/src/retroshare/rsposted.h b/libretroshare/src/retroshare/rsposted.h index 83f497582..be6e30c95 100644 --- a/libretroshare/src/retroshare/rsposted.h +++ b/libretroshare/src/retroshare/rsposted.h @@ -131,6 +131,12 @@ virtual bool getRankedPost(const uint32_t &token, RsPostedPost &post) = 0; virtual bool extractPostedCache(const std::string &str, uint32_t &votes, uint32_t &comments) = 0; + + // Control Ranking Calculations. +virtual bool setViewMode(uint32_t mode) = 0; +virtual bool setViewPeriod(uint32_t period) = 0; +virtual bool setViewRange(uint32_t first, uint32_t count) = 0; + // exposed for testing... virtual float calcPostScore(const RsMsgMetaData &meta) = 0; diff --git a/libretroshare/src/services/p3posted.cc b/libretroshare/src/services/p3posted.cc index 5e3776ee7..a1971f055 100644 --- a/libretroshare/src/services/p3posted.cc +++ b/libretroshare/src/services/p3posted.cc @@ -73,8 +73,8 @@ p3PostedService::p3PostedService(uint16_t type) int p3PostedService::tick() { - //std::cerr << "p3PostedService::tick()"; - //std::cerr << std::endl; + std::cerr << "p3PostedService::tick()"; + std::cerr << std::endl; fakeprocessrequests(); @@ -1267,8 +1267,12 @@ bool p3PostedService::addExtraDummyData() */ + bool p3PostedService::setViewMode(uint32_t mode) { + std::cerr << "p3PostedService::setViewMode() : " << mode; + std::cerr << std::endl; + RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ mViewMode = mode; @@ -1278,6 +1282,9 @@ bool p3PostedService::setViewMode(uint32_t mode) bool p3PostedService::setViewPeriod(uint32_t period) { + std::cerr << "p3PostedService::setViewPeriod() : " << period; + std::cerr << std::endl; + RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ mViewPeriod = period; @@ -1287,6 +1294,9 @@ bool p3PostedService::setViewPeriod(uint32_t period) bool p3PostedService::setViewRange(uint32_t first, uint32_t count) { + std::cerr << "p3PostedService::setViewRange() : " << first << " +" << count; + std::cerr << std::endl; + RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ mViewStart = first; @@ -1563,6 +1573,7 @@ bool p3PostedService::processPosts() { std::cerr << "p3PostedService::processPosts() ERROR getting postList"; std::cerr << std::endl; + background_cleanup(); return false; } From d27eea84daa2dc582471a3d09a517cae1e0c0ded Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 30 Jul 2012 23:55:21 +0000 Subject: [PATCH 005/222] Added Generalised GxsGroupDialog - First pass, still much to do. - Handles Create / Edit and View Group Info. - Created ForumV2GroupDialog / WikiGroupDialog / PostedGroupDialog examples overloading it. Various Improvements to PostedListDialog. - Handle Hot/New/Top options. - Send Period back to libretroshare too. - Named buttons in GUI. Added GxsGroupDialog to Wiki / Posted & ForumsV2. Discovered nasty bug in p3Posted. If there are no posts, its hangs at a Mutex, but I've no idea why. (It happens prior to this code). TODO. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5360 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/RetroShare.pro | 38 +- retroshare-gui/src/gui/ForumsV2Dialog.cpp | 25 +- .../src/gui/Posted/PostedListDialog.cpp | 132 ++++ .../src/gui/Posted/PostedListDialog.h | 11 + .../src/gui/Posted/PostedListDialog.ui | 97 ++- .../src/gui/WikiPoos/WikiDialog.cpp | 53 ++ retroshare-gui/src/gui/WikiPoos/WikiDialog.h | 4 + .../src/gui/gxs/ForumV2GroupDialog.cpp | 100 +++ .../src/gui/gxs/ForumV2GroupDialog.h | 44 ++ retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp | 638 ++++++++++++++++++ retroshare-gui/src/gui/gxs/GxsGroupDialog.h | 176 +++++ retroshare-gui/src/gui/gxs/GxsGroupDialog.ui | 560 +++++++++++++++ .../src/gui/gxs/PostedGroupDialog.cpp | 100 +++ .../src/gui/gxs/PostedGroupDialog.h | 44 ++ .../src/gui/gxs/WikiGroupDialog.cpp | 100 +++ retroshare-gui/src/gui/gxs/WikiGroupDialog.h | 44 ++ 16 files changed, 2117 insertions(+), 49 deletions(-) create mode 100644 retroshare-gui/src/gui/gxs/ForumV2GroupDialog.cpp create mode 100644 retroshare-gui/src/gui/gxs/ForumV2GroupDialog.h create mode 100644 retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp create mode 100644 retroshare-gui/src/gui/gxs/GxsGroupDialog.h create mode 100644 retroshare-gui/src/gui/gxs/GxsGroupDialog.ui create mode 100644 retroshare-gui/src/gui/gxs/PostedGroupDialog.cpp create mode 100644 retroshare-gui/src/gui/gxs/PostedGroupDialog.h create mode 100644 retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp create mode 100644 retroshare-gui/src/gui/gxs/WikiGroupDialog.h diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index 4a6223bd1..ac3200f91 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -1,13 +1,14 @@ CONFIG += qt gui uic qrc resources uitools idle bitdht # Below is for GXS services. -#CONFIG += photoshare -#CONFIG += wikipoos -#CONFIG += thewire -#CONFIG += identities -#CONFIG += forumsv2 -#CONFIG += posted -#CONFIG += unfinished +CONFIG += photoshare +CONFIG += wikipoos +CONFIG += thewire +CONFIG += identities +CONFIG += forumsv2 +CONFIG += posted +CONFIG += unfinished +CONFIG += gxsgui # Other Disabled Bits. @@ -965,3 +966,26 @@ posted { gui/Posted/PostedComments.cpp \ } + +gxsgui { + + HEADERS += gui/gxs/GxsGroupDialog.h \ + gui/gxs/ForumV2GroupDialog.h \ + gui/gxs/WikiGroupDialog.h \ + gui/gxs/PostedGroupDialog.h \ +# gui/gxs/GxsMsgDialog.h \ +# gui/gxs/GxsCommentWidget.h \ + + FORMS += gui/gxs/GxsGroupDialog.ui \ +# gui/gxs/GxsMsgDialog.ui \ +# gui/gxs/GxsCommentWidget.ui \ + + SOURCES += gui/gxs/GxsGroupDialog.cpp \ + gui/gxs/ForumV2GroupDialog.cpp \ + gui/gxs/WikiGroupDialog.cpp \ + gui/gxs/PostedGroupDialog.cpp \ +# gui/gxs/GxsMsgDialog.cpp \ +# gui/gxs/GxsCommentWidget.cpp \ + + +} diff --git a/retroshare-gui/src/gui/ForumsV2Dialog.cpp b/retroshare-gui/src/gui/ForumsV2Dialog.cpp index afc2ed43f..5b1bc363e 100644 --- a/retroshare-gui/src/gui/ForumsV2Dialog.cpp +++ b/retroshare-gui/src/gui/ForumsV2Dialog.cpp @@ -28,10 +28,9 @@ #include "ForumsV2Dialog.h" -#include "forumsv2/CreateForumV2.h" +#include "gxs/ForumV2GroupDialog.h" + #include "forumsv2/CreateForumV2Msg.h" -#include "forumsv2/ForumV2Details.h" -#include "forumsv2/EditForumV2Details.h" #include "msgs/MessageComposer.h" #include "settings/rsharesettings.h" @@ -1499,7 +1498,9 @@ void ForumsV2Dialog::copyMessageLink() void ForumsV2Dialog::newforum() { - CreateForumV2 cf (this); + ForumV2GroupDialog cf (this); + cf.newGroup(); + cf.exec (); } @@ -1561,12 +1562,10 @@ void ForumsV2Dialog::showForumDetails() return; } -#ifndef DISABLE_OTHERCLASSES - ForumV2Details fui; + ForumV2GroupDialog cf (this); + cf.existingGroup(mCurrForumId, GXS_GROUP_DIALOG_SHOW_MODE); - fui.showDetails (mCurrForumId); - fui.exec (); -#endif + cf.exec (); } void ForumsV2Dialog::editForumDetails() @@ -1575,10 +1574,10 @@ void ForumsV2Dialog::editForumDetails() return; } -#ifndef DISABLE_OTHERCLASSES - EditForumV2Details editUi(mCurrForumId, this); - editUi.exec(); -#endif + ForumV2GroupDialog cf (this); + cf.existingGroup(mCurrForumId, GXS_GROUP_DIALOG_EDIT_MODE); + + cf.exec (); } static QString buildReplyHeader(const RsMsgMetaData &meta) diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp index 17e84a386..0d49907d2 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp @@ -23,6 +23,8 @@ #include "PostedListDialog.h" +#include "gui/gxs/PostedGroupDialog.h" + //#include #include @@ -82,6 +84,18 @@ PostedListDialog::PostedListDialog(QWidget *parent) popularTopics = ui.groupTreeWidget->addCategoryItem(tr("Popular Topics"), QIcon(IMAGE_FOLDERGREEN), false); otherTopics = ui.groupTreeWidget->addCategoryItem(tr("Other Topics"), QIcon(IMAGE_FOLDERYELLOW), false); + ui.hotSortButton->setChecked(true); + mSortButton = ui.hotSortButton; + + connect( ui.newTopicButton, SIGNAL( clicked() ), this, SLOT( newGroup() ) ); + + connect( ui.hotSortButton, SIGNAL( released() ), this, SLOT( sortButtonPressed() ) ); + connect( ui.newSortButton, SIGNAL( released() ), this, SLOT( sortButtonPressed() ) ); + connect( ui.topSortButton, SIGNAL( released() ), this, SLOT( sortButtonPressed() ) ); + + connect( ui.sortGroup, SIGNAL( buttonClicked( QAbstractButton * ) ), this, SLOT( sortButtonClicked( QAbstractButton * ) ) ); + connect( ui.periodComboBox, SIGNAL( currentIndexChanged ( int index ) ), this, SLOT( periodChanged ( int ) ) ); + /* Hide platform specific features */ #ifdef Q_WS_WIN @@ -177,6 +191,122 @@ void PostedListDialog::changedTopic(const QString &id) insertThreads(); } +void PostedListDialog::sortButtonPressed() +{ + std::cerr << "PostedListDialog::sortButtonPressed()"; + std::cerr << std::endl; + + QAbstractButton *pressed = NULL; + if (ui.hotSortButton->isChecked()) { + std::cerr << "PostedListDialog::sortButtonPressed() Hot"; + std::cerr << std::endl; + pressed = ui.hotSortButton; + } else if (ui.newSortButton->isChecked()) { + std::cerr << "PostedListDialog::sortButtonPressed() New"; + std::cerr << std::endl; + pressed = ui.newSortButton; + } else if (ui.topSortButton->isChecked()) { + std::cerr << "PostedListDialog::sortButtonPressed() Top"; + std::cerr << std::endl; + pressed = ui.topSortButton; + } + + if ((pressed) && (pressed != mSortButton)) + { + mSortButton = pressed; + sortButtonClicked( mSortButton ); + insertThreads(); + } +} + +void PostedListDialog::sortButtonClicked( QAbstractButton *button ) +{ + std::cerr << "PostedListDialog::sortButtonClicked( From Button Group! )"; + std::cerr << std::endl; + + uint32_t sortMode = RSPOSTED_VIEWMODE_HOT; + + if (button == ui.hotSortButton) { + sortMode = RSPOSTED_VIEWMODE_HOT; + } else if (button == ui.newSortButton) { + sortMode = RSPOSTED_VIEWMODE_LATEST; + } else if (button == ui.topSortButton) { + sortMode = RSPOSTED_VIEWMODE_TOP; + } + + rsPosted->setViewMode(sortMode); +} + + +void PostedListDialog::periodChanged( int index ) +{ + uint32_t periodMode = RSPOSTED_PERIOD_HOUR; + switch (index) + { + case 0: + periodMode = RSPOSTED_PERIOD_HOUR; + break; + + case 1: + periodMode = RSPOSTED_PERIOD_DAY; + break; + + default: + case 2: + periodMode = RSPOSTED_PERIOD_WEEK; + break; + + case 3: + periodMode = RSPOSTED_PERIOD_MONTH; + break; + + case 4: + periodMode = RSPOSTED_PERIOD_YEAR; + break; + } + rsPosted->setViewPeriod(periodMode); +} + + + +/*********************** **** **** **** ***********************/ +/** New / Edit Groups ********************************/ +/*********************** **** **** **** ***********************/ + +void PostedListDialog::newGroup() +{ + PostedGroupDialog cf (this); + cf.newGroup(); + + cf.exec (); +} + +void PostedListDialog::showGroupDetails() +{ + if (mCurrTopicId.empty()) + { + return; + } + + PostedGroupDialog cf (this); + cf.existingGroup(mCurrTopicId, GXS_GROUP_DIALOG_SHOW_MODE); + + cf.exec (); +} + +void PostedListDialog::editGroupDetails() +{ + if (mCurrTopicId.empty()) + { + return; + } + + PostedGroupDialog cf (this); + cf.existingGroup(mCurrTopicId, GXS_GROUP_DIALOG_EDIT_MODE); + + cf.exec (); +} + /*********************** **** **** **** ***********************/ /** Request / Response of Data ********************************/ @@ -292,6 +422,8 @@ void PostedListDialog::loadCurrentForumThreads(const std::string &forumId) if (mThreadLoading) { /* Cleanup */ + std::cerr << "Already Loading -> must Clean ... TODO, retry in a moment"; + return; } clearPosts(); diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.h b/retroshare-gui/src/gui/Posted/PostedListDialog.h index 80383d28d..0cd6c4670 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.h @@ -54,6 +54,15 @@ private slots: void groupListCustomPopupMenu( QPoint /*point*/ ); void changedTopic(const QString &id); +void sortButtonClicked( QAbstractButton *button ); +void sortButtonPressed(); + +void periodChanged( int index ); + + void newGroup(); + void showGroupDetails(); + void editGroupDetails(); + private: void clearPosts(); @@ -86,6 +95,8 @@ void groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo & QTreeWidgetItem *popularTopics; QTreeWidgetItem *otherTopics; + QAbstractButton *mSortButton; + bool mThreadLoading; std::string mCurrTopicId; diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.ui b/retroshare-gui/src/gui/Posted/PostedListDialog.ui index b0ccaa7ee..36a536087 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.ui +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.ui @@ -13,28 +13,61 @@ Form - + - + - - - Hot - - - - - - - New - - - - - - - Top - + + + + -1 + + + 0 + + + + + Hot + + + true + + + true + + + + + + + New + + + true + + + true + + + + + + + Top + + + true + + + false + + + true + + + + @@ -51,7 +84,7 @@ - + Today @@ -89,14 +122,14 @@ - + - New Link Group + New Topic - + Submit Post @@ -132,7 +165,7 @@ - + Refresh @@ -159,14 +192,14 @@ - + Prev - + Next @@ -184,10 +217,16 @@ 0 0 - 461 - 330 + 406 + 333 + + + 0 + 0 + + diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp index 955ad9a5d..e21b2757b 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp @@ -28,6 +28,8 @@ #include "gui/WikiPoos/WikiAddDialog.h" #include "gui/WikiPoos/WikiEditDialog.h" +#include "gui/gxs/WikiGroupDialog.h" + #include #include @@ -131,6 +133,7 @@ void WikiDialog::OpenOrShowAddPageDialog() void WikiDialog::OpenOrShowAddGroupDialog() { +#if 0 if (mAddGroupDialog) { mAddGroupDialog->show(); @@ -140,8 +143,58 @@ void WikiDialog::OpenOrShowAddGroupDialog() mAddGroupDialog = new WikiAddDialog(NULL); mAddGroupDialog->show(); } +#endif + + newGroup(); } +/*********************** **** **** **** ***********************/ +/** New / Edit Groups ********************************/ +/*********************** **** **** **** ***********************/ + +void WikiDialog::newGroup() +{ + WikiGroupDialog cf (this); + cf.newGroup(); + + cf.exec (); +} + +void WikiDialog::showGroupDetails() +{ + std::string groupId = getSelectedGroup(); + if (groupId == "") + { + std::cerr << "WikiDialog::showGroupDetails() No Group selected"; + std::cerr << std::endl; + return; + } + + + WikiGroupDialog cf (this); + cf.existingGroup(groupId, GXS_GROUP_DIALOG_SHOW_MODE); + + cf.exec (); +} + +void WikiDialog::editGroupDetails() +{ + std::string groupId = getSelectedGroup(); + if (groupId == "") + { + std::cerr << "WikiDialog::editGroupDetails() No Group selected"; + std::cerr << std::endl; + return; + } + + + WikiGroupDialog cf (this); + cf.existingGroup(groupId, GXS_GROUP_DIALOG_EDIT_MODE); + + cf.exec (); +} + + void WikiDialog::OpenOrShowEditDialog() { diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.h b/retroshare-gui/src/gui/WikiPoos/WikiDialog.h index 664dba952..5cc3d0977 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.h +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.h @@ -55,6 +55,10 @@ private slots: void groupTreeChanged(); void modTreeChanged(); + void newGroup(); + void showGroupDetails(); + void editGroupDetails(); + private: void clearWikiPage(); diff --git a/retroshare-gui/src/gui/gxs/ForumV2GroupDialog.cpp b/retroshare-gui/src/gui/gxs/ForumV2GroupDialog.cpp new file mode 100644 index 000000000..5a588d644 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/ForumV2GroupDialog.cpp @@ -0,0 +1,100 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include "ForumV2GroupDialog.h" + +#include +#include + +ForumV2GroupDialog::ForumV2GroupDialog(QWidget *parent) + :GxsGroupDialog(rsForumsV2, parent) +{ + + // To start with we only have open forums - with distribution controls. + + uint32_t enabledFlags = ( GXS_GROUP_FLAGS_ICON | + GXS_GROUP_FLAGS_DESCRIPTION | + GXS_GROUP_FLAGS_DISTRIBUTION | + // GXS_GROUP_FLAGS_PUBLISHSIGN | + GXS_GROUP_FLAGS_SHAREKEYS | + // GXS_GROUP_FLAGS_PERSONALSIGN | + // GXS_GROUP_FLAGS_COMMENTS | + 0); + + uint32_t readonlyFlags = 0; + + uint32_t defaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC | + //GXS_GROUP_DEFAULTS_DISTRIB_GROUP | + //GXS_GROUP_DEFAULTS_DISTRIB_LOCAL | + + GXS_GROUP_DEFAULTS_PUBLISH_OPEN | + //GXS_GROUP_DEFAULTS_PUBLISH_THREADS | + //GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED | + //GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED | + + //GXS_GROUP_DEFAULTS_PERSONAL_GPG | + GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED | + //GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | + + //GXS_GROUP_DEFAULTS_COMMENTS_YES | + GXS_GROUP_DEFAULTS_COMMENTS_NO | + 0); + + setFlags(enabledFlags, readonlyFlags, defaultsFlags); + +} + + +bool ForumV2GroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) +{ + // Specific Function. + RsForumV2Group grp; + grp.mMeta = meta; + //grp.mDescription = std::string(desc.toUtf8()); + + rsForumsV2->createGroup(token, grp, true); + return true; +} + +void ForumV2GroupDialog::service_loadExistingGroup(const uint32_t &token) +{ + std::cerr << "ForumV2GroupDialog::service_loadExistingGroup()"; + std::cerr << std::endl; + + RsForumV2Group group; + if (!rsForumsV2->getGroupData(token, group)) + { + std::cerr << "ForumV2GroupDialog::service_loadExistingGroup() ERROR Getting Group"; + std::cerr << std::endl; + + return; + } + + /* must call metadata loader */ + loadExistingGroupMetaData(group.mMeta); + + /* now load any extra data we feel like */ + +} + + + + diff --git a/retroshare-gui/src/gui/gxs/ForumV2GroupDialog.h b/retroshare-gui/src/gui/gxs/ForumV2GroupDialog.h new file mode 100644 index 000000000..f549ae077 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/ForumV2GroupDialog.h @@ -0,0 +1,44 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + + +#ifndef _FORUMV2_GROUP_DIALOG_H +#define _FORUMV2_GROUP_DIALOG_H + +#include "GxsGroupDialog.h" + +class ForumV2GroupDialog : public GxsGroupDialog +{ + Q_OBJECT + +public: + ForumV2GroupDialog(QWidget *parent); + +protected: + virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); +// virtual bool service_CompleteCreateGroup(const RsGroupMetaData &meta); + + virtual void service_loadExistingGroup(const uint32_t &token); + +}; + +#endif + diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp new file mode 100644 index 000000000..3e9118cfc --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -0,0 +1,638 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include + +#include "util/misc.h" +#include "GxsGroupDialog.h" +#include "gui/common/PeerDefs.h" + +#include + +#include + +#include + +#define GXSGROUP_NEWGROUPID 1 +#define GXSGROUP_LOADGROUP 2 + +/** Constructor */ +GxsGroupDialog::GxsGroupDialog(RsTokenService *service, QWidget *parent) +: QDialog(parent), mRsService(service) +{ + /* Invoke the Qt Designer generated object setup routine */ + ui.setupUi(this); + + mTokenQueue = new TokenQueue(service, this); + + // connect up the buttons. + connect( ui.cancelButton, SIGNAL( clicked ( bool ) ), this, SLOT( cancelDialog( ) ) ); + connect( ui.createButton, SIGNAL( clicked ( bool ) ), this, SLOT( submitGroup( ) ) ); + connect( ui.pubKeyShare_cb, SIGNAL( clicked() ), this, SLOT( setShareList( ) )); + + connect( ui.groupLogo, SIGNAL(clicked() ), this , SLOT(addGroupLogo())); + connect( ui.addLogoButton, SIGNAL(clicked() ), this , SLOT(addGroupLogo())); + + if (!ui.pubKeyShare_cb->isChecked()) { + ui.contactsdockWidget->hide(); + this->resize(this->size().width() - ui.contactsdockWidget->size().width(), this->size().height()); + } + + /* initialize key share list */ + ui.keyShareList->setHeaderText(tr("Contacts:")); + ui.keyShareList->setModus(FriendSelectionWidget::MODUS_CHECK); + ui.keyShareList->start(); + + + /* Setup Reasonable Defaults */ + + uint32_t enabledFlags = ( GXS_GROUP_FLAGS_ICON | + GXS_GROUP_FLAGS_DESCRIPTION | + GXS_GROUP_FLAGS_DISTRIBUTION | + GXS_GROUP_FLAGS_PUBLISHSIGN | + GXS_GROUP_FLAGS_SHAREKEYS | + GXS_GROUP_FLAGS_PERSONALSIGN | + GXS_GROUP_FLAGS_COMMENTS ); + + uint32_t readonlyFlags = 0; + + uint32_t defaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC | + //GXS_GROUP_DEFAULTS_DISTRIB_GROUP | + //GXS_GROUP_DEFAULTS_DISTRIB_LOCAL | + + //GXS_GROUP_DEFAULTS_PUBLISH_OPEN | + GXS_GROUP_DEFAULTS_PUBLISH_THREADS | + //GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED | + //GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED | + + //GXS_GROUP_DEFAULTS_PERSONAL_GPG | + //GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED | + GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | + + GXS_GROUP_DEFAULTS_COMMENTS_YES | + //GXS_GROUP_DEFAULTS_COMMENTS_NO | + 0); + + setFlags(enabledFlags, readonlyFlags, defaultsFlags); + +} + +void GxsGroupDialog::setFlags(uint32_t enabledFlags, uint32_t readonlyFlags, uint32_t defaultsFlags) +{ + mEnabledFlags = enabledFlags; + mReadonlyFlags = readonlyFlags; + mDefaultsFlags = defaultsFlags; +} + +void GxsGroupDialog::setMode(uint32_t mode) +{ + mMode = mode; + + /* switch depending on mode */ + switch(mMode) + { + case GXS_GROUP_DIALOG_CREATE_MODE: + { + ui.createButton->setText(tr("Create Group")); + } + break; + + default: + case GXS_GROUP_DIALOG_SHOW_MODE: + { + ui.cancelButton->setVisible(false); + ui.createButton->setText(tr("Close")); + } + break; + + case GXS_GROUP_DIALOG_EDIT_MODE: + { + ui.createButton->setText(tr("Submit Changes")); + } + break; + } +} + + +void GxsGroupDialog::clearForm() +{ + ui.groupName->clear(); + ui.groupDesc->clear(); + + ui.groupName->setFocus(); +} + + +void GxsGroupDialog::setupDefaults() +{ + /* Enable / Show Parts based on Flags */ + + if (mDefaultsFlags & GXS_GROUP_DEFAULTS_DISTRIB_MASK) + { + if (mDefaultsFlags & GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC) + { + ui.typePublic->setChecked(true); + } + else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_DISTRIB_GROUP) + { + ui.typeGroup->setChecked(true); + } + else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_DISTRIB_LOCAL) + { + ui.typeLocal->setChecked(true); + } + else + { + // default + ui.typePublic->setChecked(true); + } + } + + if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PUBLISH_MASK) + { + if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED) + { + ui.publish_encrypt->setChecked(true); + } + else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED) + { + ui.publish_required->setChecked(true); + } + else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PUBLISH_THREADS) + { + ui.publish_threads->setChecked(true); + } + else + { + // default + ui.publish_open->setChecked(true); + } + } + + if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PERSONAL_MASK) + { + if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PERSONAL_PGP) + { + ui.personal_pgp->setChecked(true); + } + else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED) + { + ui.personal_required->setChecked(true); + } + else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB) + { + ui.personal_ifnopub->setChecked(true); + } + else + { + // default + ui.personal_ifnopub->setChecked(true); + } + } + + if (mDefaultsFlags & GXS_GROUP_DEFAULTS_COMMENTS_MASK) + { + if (mDefaultsFlags & GXS_GROUP_DEFAULTS_COMMENTS_YES) + { + ui.comments_allowed->setChecked(true); + } + else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_COMMENTS_NO) + { + ui.comments_no->setChecked(true); + } + else + { + // default + ui.comments_no->setChecked(true); + } + + } +} + +void GxsGroupDialog::setupVisibility() +{ + { + ui.groupLogo->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ICON); + ui.addLogoButton->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ICON); + } + + { + ui.groupDesc->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DESCRIPTION); + ui.groupDescLabel->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DESCRIPTION); + } + + { + ui.distribGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DISTRIBUTION); + } + + { + ui.publishGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_PUBLISHSIGN); + } + + { + ui.pubKeyShare_cb->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_SHAREKEYS); + } + + { + ui.personalGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_PERSONALSIGN); + } + + { + ui.commentGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_COMMENTS); + } + + { + ui.extraFrame->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_EXTRA); + } +} + + +void GxsGroupDialog::newGroup() +{ + setupDefaults(); + setupVisibility(); + clearForm(); + + setMode(GXS_GROUP_DIALOG_CREATE_MODE); + + service_NewGroup(); +} + + +void GxsGroupDialog::existingGroup(std::string groupId, uint32_t mode) +{ + setupDefaults(); + setupVisibility(); + clearForm(); + + setMode(mode); + + service_ExistingGroup(); + + /* request data */ + { + RsTokReqOptions opts; + + std::list grpIds; + grpIds.push_back(groupId); + + std::cerr << "GxsGroupDialog::existingGroup() Requesting Data."; + std::cerr << std::endl; + + uint32_t token; + mTokenQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, GXSGROUP_LOADGROUP); + } +} + +bool GxsGroupDialog::loadExistingGroupMetaData(const RsGroupMetaData &meta) +{ + /* should set stuff - according to parameters */ + setGroupSignFlags(meta.mSignFlags); + ui.groupName->setText(QString::fromUtf8(meta.mGroupName.c_str())); + + return true; +} + + + +bool GxsGroupDialog::service_NewGroup() +{ + /* setup any extra bits */ + return true; +} + + +bool GxsGroupDialog::service_ExistingGroup() +{ + /* setup any extra bits */ + return true; +} + + +void GxsGroupDialog::submitGroup() +{ + std::cerr << "GxsGroupDialog::submitGroup()"; + std::cerr << std::endl; + + /* switch depending on mode */ + switch(mMode) + { + case GXS_GROUP_DIALOG_CREATE_MODE: + { + /* just close if down */ + createGroup(); + } + break; + + default: + case GXS_GROUP_DIALOG_SHOW_MODE: + { + /* just close if down */ + cancelDialog(); + } + break; + + case GXS_GROUP_DIALOG_EDIT_MODE: + { + /* TEMP: just close if down */ + cancelDialog(); + } + break; + } +} + + + + + + +void GxsGroupDialog::createGroup() +{ + QString name = misc::removeNewLine(ui.groupName->text()); + QString desc = ui.groupDesc->toPlainText(); //toHtml(); + uint32_t flags = 0; + + if(name.isEmpty()) + { + /* error message */ + QMessageBox::warning(this, "RetroShare", tr("Please add a Name"), QMessageBox::Ok, QMessageBox::Ok); + return; //Don't add a empty name!! + } + + if (mRsService) + { + + uint32_t token; + RsGroupMetaData meta; + + // Fill in the MetaData as best we can. + meta.mGroupName = std::string(name.toUtf8()); + //meta.mDesc = std::string(desc.toUtf8()); + + meta.mGroupFlags = flags; + meta.mSignFlags = getGroupSignFlags(); + + // These ones shouldn't be needed here - but will be used, until we have fully functional backend. + meta.mSubscribeFlags = RSGXS_GROUP_SUBSCRIBE_ADMIN; + meta.mPublishTs = time(NULL); + + if (service_CreateGroup(token, meta)) + { + // get the Queue to handle response. + mTokenQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_SUMMARY, GXSGROUP_NEWGROUPID); + } + } +} + +uint32_t GxsGroupDialog::getGroupSignFlags() +{ + /* grab from the ui options -> */ + uint32_t signFlags = 0; + if (ui.publish_encrypt->isChecked()) { + signFlags |= RSGXS_GROUP_SIGN_PUBLISH_ENCRYPTED; + } else if (ui.publish_required->isChecked()) { + signFlags |= RSGXS_GROUP_SIGN_PUBLISH_ALLSIGNED; + } else if (ui.publish_threads->isChecked()) { + signFlags |= RSGXS_GROUP_SIGN_PUBLISH_THREADHEAD; + } else { // publish_open (default). + signFlags |= RSGXS_GROUP_SIGN_PUBLISH_NONEREQ; + } + +// Author Signature. + if (ui.personal_pgp->isChecked()) { + signFlags |= RSGXS_GROUP_SIGN_AUTHOR_GPG; + } else if (ui.personal_required->isChecked()) { + signFlags |= RSGXS_GROUP_SIGN_AUTHOR_REQUIRED; + } else if (ui.personal_ifnopub->isChecked()) { + signFlags |= RSGXS_GROUP_SIGN_AUTHOR_IFNOPUBSIGN; + } else { // shouldn't allow this one. + signFlags |= RSGXS_GROUP_SIGN_AUTHOR_NONE; + } + return signFlags; +} + +void GxsGroupDialog::setGroupSignFlags(uint32_t signFlags) +{ + + if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_ENCRYPTED) { + ui.publish_encrypt->setChecked(true); + } else if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_ALLSIGNED) { + ui.publish_required->setChecked(true); + } else if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_THREADHEAD) { + ui.publish_threads->setChecked(true); + } else if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_NONEREQ) { + ui.publish_open->setChecked(true); + } + + if (signFlags & RSGXS_GROUP_SIGN_AUTHOR_GPG) { + ui.personal_pgp->setChecked(true); + } else if (signFlags & RSGXS_GROUP_SIGN_AUTHOR_REQUIRED) { + ui.personal_required->setChecked(true); + } else if (signFlags & RSGXS_GROUP_SIGN_AUTHOR_IFNOPUBSIGN) { + ui.personal_ifnopub->setChecked(true); + } else if (signFlags & RSGXS_GROUP_SIGN_AUTHOR_NONE) { + // Its the same... but not quite. + //ui.personal_noifpub->setChecked(); + } + + /* guess at comments */ + if ((signFlags & RSGXS_GROUP_SIGN_PUBLISH_THREADHEAD) + && (signFlags & RSGXS_GROUP_SIGN_AUTHOR_IFNOPUBSIGN)) + { + ui.comments_allowed->setChecked(true); + } + else + { + ui.comments_no->setChecked(true); + } + + +} + + + +bool GxsGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) +{ + token = 0; + return false; +} + +bool GxsGroupDialog::service_CompleteCreateGroup(const RsGroupMetaData &meta) +{ + /* dummy function - for overloading */ + return true; +} + +void GxsGroupDialog::completeCreateGroup(const RsGroupMetaData &newMeta) +{ + std::cerr << "GxsGroupDialog::completeCreateGroup() Created Group with MetaData: "; + std::cerr << std::endl; + std::cerr << newMeta; + std::cerr << std::endl; + + sendShareList(newMeta.mGroupId); + + service_CompleteCreateGroup(newMeta); + + std::cerr << "GxsGroupDialog::completeCreateGroup() Should Close!"; + std::cerr << std::endl; + + close(); +} + +void GxsGroupDialog::cancelDialog() +{ + std::cerr << "GxsGroupDialog::cancelDialog() Should Close!"; + std::cerr << std::endl; + + close(); +} + + +void GxsGroupDialog::addGroupLogo() +{ + QPixmap img = misc::getOpenThumbnailedPicture(this, tr("Load Group Logo"), 64, 64); + + if (img.isNull()) + return; + + picture = img; + + // to show the selected + ui.groupLogo->setIcon(picture); +} + + + +/*********************************************************************************** + Share Lists. + ***********************************************************************************/ + +void GxsGroupDialog::sendShareList(std::string groupId) +{ + if (!mRsService) + { + std::cerr << "GxsGroupDialog::sendShareList() GXS Service not active"; + std::cerr << std::endl; + return; + } + + if (ui.pubKeyShare_cb->isChecked()) + { + std::list shareList; + ui.keyShareList->selectedSslIds(shareList, false); + mRsService->groupShareKeys(groupId, shareList); + } + close(); +} + +void GxsGroupDialog::setShareList() +{ + if (ui.pubKeyShare_cb->isChecked()){ + this->resize(this->size().width() + ui.contactsdockWidget->size().width(), this->size().height()); + ui.contactsdockWidget->show(); + } else { // hide share widget + ui.contactsdockWidget->hide(); + this->resize(this->size().width() - ui.contactsdockWidget->size().width(), this->size().height()); + } +} + + +/*********************************************************************************** + Handle Callbacks for Load / Create. + ***********************************************************************************/ + +void GxsGroupDialog::loadNewGroupId(const uint32_t &token) +{ + std::cerr << "GxsGroupDialog::loadNewGroupId()"; + std::cerr << std::endl; + + std::list groupInfo; + mRsService->getGroupSummary(token, groupInfo); + + if (groupInfo.size() == 1) + { + RsGroupMetaData fi = groupInfo.front(); + completeCreateGroup(fi); + } + else + { + std::cerr << "GxsGroupDialog::loadNewGroupId() ERROR INVALID Number of Forums Created"; + std::cerr << std::endl; + } +} + + +void GxsGroupDialog::service_loadExistingGroup(const uint32_t &token) +{ + std::cerr << "GxsGroupDialog::service_loadExistingGroup() ERROR Must be Overloaded"; + std::cerr << std::endl; + +#if 0 + std::list groupInfo; + mRsService->getGroupSummary(token, groupInfo); + + if (groupInfo.size() == 1) + { + RsGroupMetaData fi = groupInfo.front(); + completeCreateGroup(fi); + } + else + { + std::cerr << "GxsGroupDialog::loadNewGroupId() ERROR INVALID Number of Forums Created"; + std::cerr << std::endl; + } +#endif + +} + + +void GxsGroupDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) +{ + std::cerr << "GxsGroupDialog::loadRequest() UserType: " << req.mUserType; + std::cerr << std::endl; + + if (queue != mTokenQueue) + { + std::cerr << "GxsGroupDialog::loadRequest() Queue ERROR"; + std::cerr << std::endl; + return; + } + + /* now switch on req */ + switch(req.mUserType) + { + + case GXSGROUP_NEWGROUPID: + loadNewGroupId(req.mToken); + break; + case GXSGROUP_LOADGROUP: + service_loadExistingGroup(req.mToken); + break; + default: + std::cerr << "GxsGroupDialog::loadRequest() UNKNOWN UserType "; + std::cerr << std::endl; + + } +} + + + diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h new file mode 100644 index 000000000..165b1dc23 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h @@ -0,0 +1,176 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + + +#ifndef _GXS_GROUP_DIALOG_H +#define _GXS_GROUP_DIALOG_H + +#include "ui_GxsGroupDialog.h" + +#include "util/TokenQueue.h" + + +/******** + * Notes: + * + * This is a generic Group Dialog, which is expected to be overloaded to include + * specific data for a specific service. + * + * To acheive this, we have a GxsGroupExtension widget + * - programmatically added to the GUI. + * - called to fill in fields in the Data Structures. + * + * To enable extension, we have a bunch of flags so various options can + * be shown / disabled for each specific service. + * - Enabled. + * - Defaults. + * - ReadOnly + * + * This form will be used for Create/Edit & View of Group Info. + */ + +class GxsGroupExtension: public QWidget +{ +public: + GxsGroupExtension() : QWidget() { return; } + +}; + + +#define GXS_GROUP_FLAGS_ICON 0x00000001 +#define GXS_GROUP_FLAGS_DESCRIPTION 0x00000002 +#define GXS_GROUP_FLAGS_DISTRIBUTION 0x00000004 +#define GXS_GROUP_FLAGS_PUBLISHSIGN 0x00000008 +#define GXS_GROUP_FLAGS_SHAREKEYS 0x00000010 +#define GXS_GROUP_FLAGS_PERSONALSIGN 0x00000020 +#define GXS_GROUP_FLAGS_COMMENTS 0x00000040 + +#define GXS_GROUP_FLAGS_EXTRA 0x00000100 + +#define GXS_GROUP_DEFAULTS_DISTRIB_MASK 0x0000000f +#define GXS_GROUP_DEFAULTS_PUBLISH_MASK 0x000000f0 +#define GXS_GROUP_DEFAULTS_PERSONAL_MASK 0x00000f00 +#define GXS_GROUP_DEFAULTS_COMMENTS_MASK 0x0000f000 + +#define GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC 0x00000001 +#define GXS_GROUP_DEFAULTS_DISTRIB_GROUP 0x00000002 +#define GXS_GROUP_DEFAULTS_DISTRIB_LOCAL 0x00000004 + +#define GXS_GROUP_DEFAULTS_PUBLISH_OPEN 0x00000010 +#define GXS_GROUP_DEFAULTS_PUBLISH_THREADS 0x00000020 +#define GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED 0x00000040 +#define GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED 0x00000080 + +#define GXS_GROUP_DEFAULTS_PERSONAL_PGP 0x00000100 +#define GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED 0x00000200 +#define GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB 0x00000400 + +#define GXS_GROUP_DEFAULTS_COMMENTS_YES 0x00001000 +#define GXS_GROUP_DEFAULTS_COMMENTS_NO 0x00002000 + +#define GXS_GROUP_DIALOG_CREATE_MODE 1 +#define GXS_GROUP_DIALOG_SHOW_MODE 2 +#define GXS_GROUP_DIALOG_EDIT_MODE 3 + +class GxsGroupDialog : public QDialog, public TokenResponse +{ + Q_OBJECT + +public: + GxsGroupDialog(RsTokenService *service, QWidget *parent = 0); + + void setFlags(uint32_t enabledFlags, uint32_t readonlyFlags, uint32_t defaultFlags); + void setMode(uint32_t mode); + + /*** Open Window -> in Correct Mode */ + void newGroup(); + void existingGroup(std::string groupId, uint32_t mode); + + // Callback for all Loads. +virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); + + + // Functions that can be overloaded for specific stuff. + +protected slots: + void submitGroup(); + void addGroupLogo(); + +protected: + + // Functions to be overloaded. + + // Group Creation. + virtual bool service_NewGroup(); + virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); + virtual bool service_CompleteCreateGroup(const RsGroupMetaData &meta); + + // Group Edit / Display. + virtual bool service_ExistingGroup(); // Initial Setup. + virtual void service_loadExistingGroup(const uint32_t &token); + + bool loadExistingGroupMetaData(const RsGroupMetaData &meta); + + +private slots: + /* actions to take.... */ + void cancelDialog(); + + // set private forum key share list + void setShareList(); + +private: + + void setGroupSignFlags(uint32_t signFlags); + uint32_t getGroupSignFlags(); + + void setupDefaults(); + void setupVisibility(); + void clearForm(); + + void createGroup(); + + virtual void completeCreateGroup(const RsGroupMetaData &newForumMeta); + + + void sendShareList(std::string forumId); + + void loadNewGroupId(const uint32_t &token); + + std::list mShareList; + + QPixmap picture; + + RsTokenService *mRsService; + TokenQueue *mTokenQueue; + + uint32_t mMode; + + uint32_t mEnabledFlags; + uint32_t mReadonlyFlags; + uint32_t mDefaultsFlags; + + /** Qt Designer generated object */ + Ui::GxsGroupDialog ui; +}; + +#endif + diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui new file mode 100644 index 000000000..c349988a6 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui @@ -0,0 +1,560 @@ + + + GxsGroupDialog + + + + 0 + 0 + 695 + 658 + + + + Create new Forum + + + + :/images/rstray3.png:/images/rstray3.png + + + + 0 + + + 0 + + + + + + 16777215 + 64 + + + + QFrame#frame_2{background-image: url(:/images/connect/connectFriendBanner.png);} + + + QFrame::NoFrame + + + QFrame::Raised + + + + 6 + + + + + + 48 + 48 + + + + + + + + + + :/images/konversation64.png + + + true + + + + + + + color: rgb(255, 255, 255); + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Arial'; font-size:24pt; font-weight:600; color:#ffffff;">New Group</span></p></body></html> + + + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + + + + + + + 0 + + + 4 + + + + + 0 + + + + + + 64 + 64 + + + + + 64 + 64 + + + + +border: 2px solid white; +border-radius: 10px; + + + + + + + + :/images/channels.png:/images/channels.png + + + + 64 + 64 + + + + + + + + + + Name + + + + + + + + + + + + 0 + + + + + Add Icon + + + + :/images/add_image24.png:/images/add_image24.png + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Key recipients can publish to restricted-type channels, and can view and publish for private-type channels + + + Share Publish Key + + + + + + + + + + + + + + true + + + + 0 + 0 + + + + + 300 + 524287 + + + + + 220 + 0 + + + + + 0 + 0 + + + + check peers you would like to share private publish key with + + + false + + + QDockWidget::NoDockWidgetFeatures + + + Share Key With + + + + + 0 + + + 0 + + + + + + 0 + 4 + + + + + 20 + 0 + + + + + 300 + 16777215 + + + + + 220 + 0 + + + + + 200 + 0 + + + + + + + + + + + + + + Description + + + + + + + + + + + + Message Distribution + + + + 0 + + + 4 + + + + + + + Public + + + + + + + Restricted to Group + + + + + + + Only For Your Friends + + + + + + + + + + + + Select Group of Friends + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Edit Groups + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Publish Signatures + + + + 0 + + + 4 + + + + + Open + + + + + + + New Thread + + + + + + + Required + + + + + + + Encrypted Msgs + + + + + + + + + + Personal Signatures + + + + 0 + + + 4 + + + + + PGP Required + + + + + + + Signature Required + + + + + + + If No Publish Signature + + + + + + + + + + Comments + + + + 0 + + + 4 + + + + + Allow Comments + + + + + + + No Comments + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + Qt::Horizontal + + + + 238 + 20 + + + + + + + + Cancel + + + + + + + Create + + + true + + + + + + + + + + + FriendSelectionWidget + QWidget +
gui/common/FriendSelectionWidget.h
+ 1 +
+
+ + + + +
diff --git a/retroshare-gui/src/gui/gxs/PostedGroupDialog.cpp b/retroshare-gui/src/gui/gxs/PostedGroupDialog.cpp new file mode 100644 index 000000000..f357d9d50 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/PostedGroupDialog.cpp @@ -0,0 +1,100 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include "PostedGroupDialog.h" + +#include +#include + +PostedGroupDialog::PostedGroupDialog(QWidget *parent) + :GxsGroupDialog(rsPosted, parent) +{ + + // To start with we only have open forums - with distribution controls. + + uint32_t enabledFlags = ( GXS_GROUP_FLAGS_ICON | + GXS_GROUP_FLAGS_DESCRIPTION | + GXS_GROUP_FLAGS_DISTRIBUTION | + GXS_GROUP_FLAGS_PUBLISHSIGN | + GXS_GROUP_FLAGS_SHAREKEYS | + GXS_GROUP_FLAGS_PERSONALSIGN | + GXS_GROUP_FLAGS_COMMENTS | + 0); + + uint32_t readonlyFlags = 0; + + uint32_t defaultsFlags = ( //GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC | + //GXS_GROUP_DEFAULTS_DISTRIB_GROUP | + GXS_GROUP_DEFAULTS_DISTRIB_LOCAL | + + //GXS_GROUP_DEFAULTS_PUBLISH_OPEN | + //GXS_GROUP_DEFAULTS_PUBLISH_THREADS | + GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED | + //GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED | + + //GXS_GROUP_DEFAULTS_PERSONAL_GPG | + //GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED | + GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | + + //GXS_GROUP_DEFAULTS_COMMENTS_YES | + GXS_GROUP_DEFAULTS_COMMENTS_NO | + 0); + + setFlags(enabledFlags, readonlyFlags, defaultsFlags); + +} + + +bool PostedGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) +{ + // Specific Function. + RsPostedGroup grp; + grp.mMeta = meta; + //grp.mDescription = std::string(desc.toUtf8()); + + rsPosted->submitGroup(token, grp, true); + return true; +} + +void PostedGroupDialog::service_loadExistingGroup(const uint32_t &token) +{ + std::cerr << "PostedGroupDialog::service_loadExistingGroup()"; + std::cerr << std::endl; + + RsPostedGroup group; + if (!rsPosted->getGroup(token, group)) + { + std::cerr << "PostedGroupDialog::service_loadExistingGroup() ERROR Getting Group"; + std::cerr << std::endl; + + return; + } + + /* must call metadata loader */ + loadExistingGroupMetaData(group.mMeta); + + /* now load any extra data we feel like */ + +} + + + + diff --git a/retroshare-gui/src/gui/gxs/PostedGroupDialog.h b/retroshare-gui/src/gui/gxs/PostedGroupDialog.h new file mode 100644 index 000000000..f9ef3d8cc --- /dev/null +++ b/retroshare-gui/src/gui/gxs/PostedGroupDialog.h @@ -0,0 +1,44 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + + +#ifndef _POSTED_GROUP_DIALOG_H +#define _POSTED_GROUP_DIALOG_H + +#include "GxsGroupDialog.h" + +class PostedGroupDialog : public GxsGroupDialog +{ + Q_OBJECT + +public: + PostedGroupDialog(QWidget *parent); + +protected: + virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); +// virtual bool service_CompleteCreateGroup(const RsGroupMetaData &meta); + + virtual void service_loadExistingGroup(const uint32_t &token); + +}; + +#endif + diff --git a/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp b/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp new file mode 100644 index 000000000..7a7875f43 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp @@ -0,0 +1,100 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include "WikiGroupDialog.h" + +#include +#include + +WikiGroupDialog::WikiGroupDialog(QWidget *parent) + :GxsGroupDialog(rsWiki, parent) +{ + + // To start with we only have open forums - with distribution controls. + + uint32_t enabledFlags = ( GXS_GROUP_FLAGS_ICON | + GXS_GROUP_FLAGS_DESCRIPTION | + GXS_GROUP_FLAGS_DISTRIBUTION | + // GXS_GROUP_FLAGS_PUBLISHSIGN | + GXS_GROUP_FLAGS_SHAREKEYS | + // GXS_GROUP_FLAGS_PERSONALSIGN | + // GXS_GROUP_FLAGS_COMMENTS | + 0); + + uint32_t readonlyFlags = 0; + + uint32_t defaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC | + //GXS_GROUP_DEFAULTS_DISTRIB_GROUP | + //GXS_GROUP_DEFAULTS_DISTRIB_LOCAL | + + GXS_GROUP_DEFAULTS_PUBLISH_OPEN | + //GXS_GROUP_DEFAULTS_PUBLISH_THREADS | + //GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED | + //GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED | + + //GXS_GROUP_DEFAULTS_PERSONAL_GPG | + GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED | + //GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | + + //GXS_GROUP_DEFAULTS_COMMENTS_YES | + GXS_GROUP_DEFAULTS_COMMENTS_NO | + 0); + + setFlags(enabledFlags, readonlyFlags, defaultsFlags); + +} + + +bool WikiGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) +{ + // Specific Function. + RsWikiGroup grp; + grp.mMeta = meta; + //grp.mDescription = std::string(desc.toUtf8()); + + rsWiki->createGroup(token, grp, true); + return true; +} + +void WikiGroupDialog::service_loadExistingGroup(const uint32_t &token) +{ + std::cerr << "WikiGroupDialog::service_loadExistingGroup()"; + std::cerr << std::endl; + + RsWikiGroup group; + if (!rsWiki->getGroupData(token, group)) + { + std::cerr << "WikiGroupDialog::service_loadExistingGroup() ERROR Getting Group"; + std::cerr << std::endl; + + return; + } + + /* must call metadata loader */ + loadExistingGroupMetaData(group.mMeta); + + /* now load any extra data we feel like */ + +} + + + + diff --git a/retroshare-gui/src/gui/gxs/WikiGroupDialog.h b/retroshare-gui/src/gui/gxs/WikiGroupDialog.h new file mode 100644 index 000000000..946763e93 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/WikiGroupDialog.h @@ -0,0 +1,44 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + + +#ifndef _WIKI_GROUP_DIALOG_H +#define _WIKI_GROUP_DIALOG_H + +#include "GxsGroupDialog.h" + +class WikiGroupDialog : public GxsGroupDialog +{ + Q_OBJECT + +public: + WikiGroupDialog(QWidget *parent); + +protected: + virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); +// virtual bool service_CompleteCreateGroup(const RsGroupMetaData &meta); + + virtual void service_loadExistingGroup(const uint32_t &token); + +}; + +#endif + From 79957e96a95169099f6a9043752e1b42e8cb54f9 Mon Sep 17 00:00:00 2001 From: drbob Date: Tue, 31 Jul 2012 12:12:53 +0000 Subject: [PATCH 006/222] * Correctly return empty list -> if there is no data for Rankings. * Extra debug for p3postings in general. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5362 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/services/p3posted.cc | 132 +++++++++++++++++-------- 1 file changed, 92 insertions(+), 40 deletions(-) diff --git a/libretroshare/src/services/p3posted.cc b/libretroshare/src/services/p3posted.cc index a1971f055..ee5859ca5 100644 --- a/libretroshare/src/services/p3posted.cc +++ b/libretroshare/src/services/p3posted.cc @@ -78,7 +78,7 @@ int p3PostedService::tick() fakeprocessrequests(); - + // Contine Ranking Request. checkRankingRequest(); @@ -426,32 +426,6 @@ bool p3PostedService::getComment(const uint32_t &token, RsPostedComment &comment return ans; } - - - - - /* Poll */ -/*** - * THE STANDARD ONE IS REPLACED - SO WE CAN HANDLE RANKING REQUESTS - * Its defined lower - next to the ranking code. - ***/ - -#if 0 -uint32_t p3PostedService::requestStatus(const uint32_t token) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - - checkRequestStatus(token, status, reqtype, anstype, ts); - - return status; -} - -#endif - - /* Cancel Request */ bool p3PostedService::cancelRequest(const uint32_t &token) { @@ -1384,11 +1358,15 @@ static uint32_t convertPeriodFlagToSeconds(uint32_t periodMode) #define POSTED_RANKINGS_INITIAL_CHECK 1 #define POSTED_RANKINGS_DATA_REQUEST 2 -#define POSTED_RANKINGS_DATA_DONE 3 +#define POSTED_RANKINGS_NODATA 3 +#define POSTED_RANKINGS_DATA_DONE 4 /* Poll */ uint32_t p3PostedService::requestStatus(const uint32_t token) { + std::cerr << "p3PostedService::requestStatus() Token: " << token; + std::cerr << std::endl; + uint32_t status; uint32_t reqtype; uint32_t anstype; @@ -1400,17 +1378,31 @@ uint32_t p3PostedService::requestStatus(const uint32_t token) RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ if ((mProcessingRanking) && (token == mRankingExternalToken)) { + std::cerr << "p3PostedService::requestStatus() is RankingToken"; + std::cerr << std::endl; + { switch(mRankingState) { case POSTED_RANKINGS_INITIAL_CHECK: status = GXS_REQUEST_STATUS_PENDING; + std::cerr << "p3PostedService::requestStatus() RANKING PENDING"; + std::cerr << std::endl; + return status; + break; + case POSTED_RANKINGS_NODATA: + status = GXS_REQUEST_STATUS_COMPLETE; + std::cerr << "p3PostedService::requestStatus() RANKING RETURNED NO DATA"; + std::cerr << std::endl; return status; break; case POSTED_RANKINGS_DATA_REQUEST: // Switch to real token. int_token = mRankingInternalToken; + std::cerr << "p3PostedService::requestStatus() Flipping to Int Token: " << int_token; + std::cerr << std::endl; break; + } } } @@ -1427,26 +1419,24 @@ bool p3PostedService::getRankedPost(const uint32_t &token, RsPostedPost &post) if (!mProcessingRanking) { + std::cerr << "p3PostedService::getRankedPost() ERROR not processing"; + std::cerr << std::endl; return false; } if (token != mRankingExternalToken) { - + std::cerr << "p3PostedService::getRankedPost() ERROR wrong token"; + std::cerr << std::endl; return false; } - if (mRankingState != POSTED_RANKINGS_DATA_REQUEST) + if (mRankingState == POSTED_RANKINGS_NODATA) { + std::cerr << "p3PostedService::getRankedPost() No Data for this request - sorry"; + std::cerr << std::endl; - return false; - - } - - - if (!getPost(mRankingInternalToken, post)) - { /* clean up */ mProcessingRanking = false; mRankingExternalToken = 0; @@ -1456,6 +1446,34 @@ bool p3PostedService::getRankedPost(const uint32_t &token, RsPostedPost &post) return false; } + if (mRankingState != POSTED_RANKINGS_DATA_REQUEST) + { + + std::cerr << "p3PostedService::getRankedPost() ERROR wrong state"; + std::cerr << std::endl; + + return false; + + } + + + if (!getPost(mRankingInternalToken, post)) + { + std::cerr << "p3PostedService::getRankedPost() End of Posts for this token"; + std::cerr << std::endl; + + /* clean up */ + mProcessingRanking = false; + mRankingExternalToken = 0; + mRankingInternalToken = 0; + mRankingState = POSTED_RANKINGS_DATA_DONE; + + return false; + } + + std::cerr << "p3PostedService::getRankedPost() Got Post"; + std::cerr << std::endl; + return true; } @@ -1500,6 +1518,8 @@ bool p3PostedService::requestRanking(uint32_t &token, std::string groupId) { RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ + std::cerr << "p3PostedService::requestRanking() Saved Internal Token: " << posttoken; + std::cerr << std::endl; mRankingInternalToken = posttoken; } return true; @@ -1512,16 +1532,23 @@ bool p3PostedService::checkRankingRequest() RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ if (!mProcessingRanking) { + //std::cerr << "p3PostedService::checkRankingRequest() Not Processing"; + //std::cerr << std::endl; return false; } if (mRankingState != POSTED_RANKINGS_INITIAL_CHECK) { + std::cerr << "p3PostedService::checkRankingRequest() Not in Initial Check"; + std::cerr << std::endl; return false; } /* here it actually running! */ token = mRankingInternalToken; + + std::cerr << "p3PostedService::checkRankingRequest() Running with token: " << token; + std::cerr << std::endl; } @@ -1529,10 +1556,23 @@ bool p3PostedService::checkRankingRequest() uint32_t reqtype; uint32_t anstype; time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); + if (checkRequestStatus(token, status, reqtype, anstype, ts)) + { + std::cerr << "p3PostedService::checkRankingRequest() checkRequestStatus => OK"; + std::cerr << std::endl; + } + else + { + std::cerr << "p3PostedService::checkRankingRequest() checkRequestStatus => ERROR"; + std::cerr << std::endl; + return false; + } if (status == GXS_REQUEST_STATUS_COMPLETE) { + std::cerr << "p3PostedService::checkRankingRequest() Init Complete => processPosts"; + std::cerr << std::endl; + processPosts(); } return true; @@ -1571,9 +1611,13 @@ bool p3PostedService::processPosts() if (!getMsgSummary(token, postList)) { - std::cerr << "p3PostedService::processPosts() ERROR getting postList"; + std::cerr << "p3PostedService::processPosts() No Data for Request"; std::cerr << std::endl; - background_cleanup(); + + /* put it into a state, where the GUI will get to read an empty Queue */ + RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ + mRankingState = POSTED_RANKINGS_NODATA; + return false; } @@ -1623,12 +1667,20 @@ bool p3PostedService::processPosts() RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ mRankingState = POSTED_RANKINGS_DATA_REQUEST; mRankingInternalToken = token; + + std::cerr << "p3PostedService::processPosts() Second Stage: token: " << token; + std::cerr << std::endl; } return true; } + + + + + /***** Background Processing **** * * Process Each Message - as it arrives. From e6c6ed9b91b918713766b738f80d07c9e773cdac Mon Sep 17 00:00:00 2001 From: drbob Date: Tue, 31 Jul 2012 12:15:58 +0000 Subject: [PATCH 007/222] * Fixed Nasty Bug: Double Increment in TokenQueue list iteration => infinite Loop. * Corrected header file names. * Only queue TokenRequest if RankingRequest returns true. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5363 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/Posted/PostedListDialog.cpp | 9 +++++---- retroshare-gui/src/gui/forumsv2/CreateForumV2.cpp | 2 +- retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.cpp | 2 +- retroshare-gui/src/gui/forumsv2/EditForumV2Details.cpp | 2 +- retroshare-gui/src/gui/forumsv2/ForumV2Details.cpp | 2 +- retroshare-gui/src/gui/gxs/ForumV2GroupDialog.cpp | 2 +- retroshare-gui/src/util/TokenQueue.cpp | 2 +- 7 files changed, 11 insertions(+), 10 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp index 0d49907d2..745035c7e 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp @@ -455,10 +455,11 @@ void PostedListDialog::requestGroupThreadData_InsertThreads(const std::string &g //mPostedQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, POSTEDDIALOG_INSERTTHREADS); // Do specific Posted Request.... - rsPosted->requestRanking(token, groupId); - // get the Queue to handle response. - mPostedQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_DATA, POSTEDDIALOG_INSERTTHREADS); - + if (rsPosted->requestRanking(token, groupId)) + { + // get the Queue to handle response. + mPostedQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_DATA, POSTEDDIALOG_INSERTTHREADS); + } } diff --git a/retroshare-gui/src/gui/forumsv2/CreateForumV2.cpp b/retroshare-gui/src/gui/forumsv2/CreateForumV2.cpp index 0463b7941..d261c024e 100644 --- a/retroshare-gui/src/gui/forumsv2/CreateForumV2.cpp +++ b/retroshare-gui/src/gui/forumsv2/CreateForumV2.cpp @@ -27,7 +27,7 @@ #include -#include +#include #include #include diff --git a/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.cpp b/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.cpp index 4df3ebc3c..19920ac91 100644 --- a/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.cpp +++ b/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.cpp @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include "gui/settings/rsharesettings.h" diff --git a/retroshare-gui/src/gui/forumsv2/EditForumV2Details.cpp b/retroshare-gui/src/gui/forumsv2/EditForumV2Details.cpp index 7d04594d9..5d7d9c690 100644 --- a/retroshare-gui/src/gui/forumsv2/EditForumV2Details.cpp +++ b/retroshare-gui/src/gui/forumsv2/EditForumV2Details.cpp @@ -21,7 +21,7 @@ #include "EditForumV2Details.h" -#include +#include #include "util/misc.h" diff --git a/retroshare-gui/src/gui/forumsv2/ForumV2Details.cpp b/retroshare-gui/src/gui/forumsv2/ForumV2Details.cpp index 29f0c750f..0f3d0f4dc 100644 --- a/retroshare-gui/src/gui/forumsv2/ForumV2Details.cpp +++ b/retroshare-gui/src/gui/forumsv2/ForumV2Details.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include diff --git a/retroshare-gui/src/gui/gxs/ForumV2GroupDialog.cpp b/retroshare-gui/src/gui/gxs/ForumV2GroupDialog.cpp index 5a588d644..f462181d2 100644 --- a/retroshare-gui/src/gui/gxs/ForumV2GroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/ForumV2GroupDialog.cpp @@ -21,7 +21,7 @@ #include "ForumV2GroupDialog.h" -#include +#include #include ForumV2GroupDialog::ForumV2GroupDialog(QWidget *parent) diff --git a/retroshare-gui/src/util/TokenQueue.cpp b/retroshare-gui/src/util/TokenQueue.cpp index 232e17bb4..1c0cf7a0f 100644 --- a/retroshare-gui/src/util/TokenQueue.cpp +++ b/retroshare-gui/src/util/TokenQueue.cpp @@ -104,7 +104,7 @@ void TokenQueue::pollRequests() std::list::iterator it; double pollPeriod = 1.0; // max poll period. - for(it = mRequests.begin(); it != mRequests.end(); it++) + for(it = mRequests.begin(); it != mRequests.end();) { if (checkForRequest(it->mToken)) { From 3f5c96ab8aa59577566e3902092940d03f9cf292 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Tue, 31 Jul 2012 21:27:34 +0000 Subject: [PATCH 008/222] photov2 items serialisation/deserialisation git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5364 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/serialiser/rsgxsitems.h | 8 +- .../src/serialiser/rsphotov2items.cc | 470 +++++++++++++++++- libretroshare/src/serialiser/rsphotov2items.h | 15 +- 3 files changed, 475 insertions(+), 18 deletions(-) diff --git a/libretroshare/src/serialiser/rsgxsitems.h b/libretroshare/src/serialiser/rsgxsitems.h index 89e18457e..f13ca774b 100644 --- a/libretroshare/src/serialiser/rsgxsitems.h +++ b/libretroshare/src/serialiser/rsgxsitems.h @@ -118,22 +118,22 @@ class RsGxsGrpItem : public RsItem public: - RsGxsGrpItem() : RsItem(0) { return; } + RsGxsGrpItem(uint16_t service, uint8_t subtype) + : RsItem(RS_PKT_VERSION_SERVICE, service, subtype) { return; } virtual ~RsGxsGrpItem(){} RsGroupMetaData meta; - }; class RsGxsMsgItem : public RsItem { public: - RsGxsMsgItem() : RsItem(0) { return; } + RsGxsMsgItem(uint16_t service, uint8_t subtype) + : RsItem(RS_PKT_VERSION_SERVICE, service, subtype) { return; } virtual ~RsGxsMsgItem(){} RsMsgMetaData meta; - }; diff --git a/libretroshare/src/serialiser/rsphotov2items.cc b/libretroshare/src/serialiser/rsphotov2items.cc index 8dbf98703..921deca22 100644 --- a/libretroshare/src/serialiser/rsphotov2items.cc +++ b/libretroshare/src/serialiser/rsphotov2items.cc @@ -1,45 +1,491 @@ /* - * rsphotov2items.cc + * libretroshare/src/retroshare: rsphoto.h + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Christopher Evi-Parker, Robert Fernie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". * - * Created on: 22 Jul 2012 - * Author: crispy */ + #include "rsphotov2items.h" +#define GXS_PHOTO_SERIAL_DEBUG +uint32_t RsGxsPhotoSerialiser::size(RsItem* item) +{ -uint32_t RsGxsPhotoSerialiser::size(RsItem* item) { + RsGxsPhotoPhotoItem* ppItem = NULL; + RsGxsPhotoAlbumItem* paItem = NULL; + + if((ppItem = dynamic_cast(item)) != NULL) + { + return sizeGxsPhotoPhotoItem(ppItem); + } + else if((paItem = dynamic_cast(item)) != NULL) + { + return sizeGxsPhotoAlbumItem(paItem); + } + else + { +#ifdef GXS_PHOTO_SERIAL_DEBUG + +#endif + return NULL; + } } -bool RsGxsPhotoSerialiser::serialise(RsItem* item, void* data, uint32_t* size) { +bool RsGxsPhotoSerialiser::serialise(RsItem* item, void* data, uint32_t* size) +{ + + RsGxsPhotoPhotoItem* ppItem = NULL; + RsGxsPhotoAlbumItem* paItem = NULL; + + if((ppItem = dynamic_cast(item)) != NULL) + { + return serialiseGxsPhotoPhotoItem(ppItem, data, size); + } + else if((paItem = dynamic_cast(item)) != NULL) + { + return serialiseGxsPhotoAlbumItem(paItem, data, size); + } + else + { +#ifdef GXS_PHOTO_SERIAL_DEBUG + +#endif + return false; + } + } -RsItem* RsGxsPhotoSerialiser::deserialise(void* data, uint32_t* size) { +RsItem* RsGxsPhotoSerialiser::deserialise(void* data, uint32_t* size) +{ + +#ifdef RSSERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::deserialise()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_TYPE_PHOTO != getRsItemService(rstype))) + { + return NULL; /* wrong type */ + } + + switch(getRsItemSubType(rstype)) + { + + case RS_PKT_SUBTYPE_NXS_SYNC_GRP: + return deserialiseGxsPhotoPhotoItem(data, size); + case RS_PKT_SUBTYPE_NXS_SYNC_GRP_ITEM: + return deserialiseGxsPhotoAlbumItem(data, size); + default: + { +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::deserialise(): subtype could not be dealt with" + << std::endl; +#endif + break; + } + } + return NULL; } -uint32_t RsGxsPhotoSerialiser::sizeGxsPhotoAlbumItem(RsGxsPhotoAlbumItem* item) { +uint32_t RsGxsPhotoSerialiser::sizeGxsPhotoAlbumItem(RsGxsPhotoAlbumItem* item) +{ + const RsPhotoAlbum& album = item->album; + uint32_t s = 8; // header + s += GetTlvStringSize(album.mCaption); + s += GetTlvStringSize(album.mCategory); + s += GetTlvStringSize(album.mDescription); + s += GetTlvStringSize(album.mHashTags); + s += GetTlvStringSize(album.mOther); + s += GetTlvStringSize(album.mPhotoPath); + s += GetTlvStringSize(album.mPhotographer); + s += GetTlvStringSize(album.mWhen); + s += GetTlvStringSize(album.mWhere); + + RsTlvBinaryData b(item->PacketService()); // TODO, need something more persisitent + b.setBinData(album.mThumbnail.data, album.mThumbnail.size); + s += GetTlvStringSize(album.mThumbnail.type); + s += b.TlvSize(); + + return s; } bool RsGxsPhotoSerialiser::serialiseGxsPhotoAlbumItem(RsGxsPhotoAlbumItem* item, void* data, - uint32_t* size) { + uint32_t* size) +{ + +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::serialiseGxsPhotoAlbumItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsPhotoAlbumItem(item); + uint32_t offset = 0; + + if(*size < tlvsize){ +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::serialiseGxsPhotoAlbumItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsPhotoAlbumItem */ + + ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mCaption); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mCategory); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mDescription); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mHashTags); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mOther); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mPhotoPath); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mPhotographer); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mWhen); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mWhere); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mThumbnail.type); + RsTlvBinaryData b(item->PacketService()); // TODO, need something more persisitent + b.setBinData(item->album.mThumbnail.data, item->album.mThumbnail.size); + b.SetTlv(item->album.mThumbnail.data, tlvsize, &offset); + + if(offset != tlvsize) + { +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::serialiseGxsPhotoAlbumItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef GXS_PHOTO_SERIAL_DEBUG + if (!ok) + { + std::cerr << "RsGxsPhotoSerialiser::serialiseGxsPhotoAlbumItem() NOK" << std::endl; + } +#endif + + return ok; } RsGxsPhotoAlbumItem* RsGxsPhotoSerialiser::deserialiseGxsPhotoAlbumItem(void* data, - uint32_t* size) { + uint32_t* size) +{ + + +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::deserialiseGxsPhotoAlbumItem()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_TYPE_PHOTO != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_PHOTO_ITEM != getRsItemSubType(rstype))) + { +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::deserialiseGxsPhotoAlbumItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::deserialiseGxsPhotoAlbumItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsPhotoAlbumItem* item = new RsGxsPhotoAlbumItem(); + /* skip the header */ + offset += 8; + + + ok &= GetTlvString(data, rssize, &offset, 1, item->album.mCaption); + ok &= GetTlvString(data, rssize, &offset, 1, item->album.mCategory); + ok &= GetTlvString(data, rssize, &offset, 1, item->album.mDescription); + ok &= GetTlvString(data, rssize, &offset, 1, item->album.mHashTags); + ok &= GetTlvString(data, rssize, &offset, 1, item->album.mOther); + ok &= GetTlvString(data, rssize, &offset, 1, item->album.mPhotoPath); + ok &= GetTlvString(data, rssize, &offset, 1, item->album.mPhotographer); + ok &= GetTlvString(data, rssize, &offset, 1, item->album.mWhen); + ok &= GetTlvString(data, rssize, &offset, 1, item->album.mWhere); + ok &= GetTlvString(data, rssize, &offset, 1, item->album.mThumbnail.type); + + RsTlvBinaryData b(RS_SERVICE_TYPE_PHOTO); // TODO, need something more persisitent + ok &= b.GetTlv(data, rssize, &offset); + item->album.mThumbnail.data = (uint8_t*)b.bin_data; + item->album.mThumbnail.size = b.bin_len; + b.TlvShallowClear(); + + if (offset != rssize) + { +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::deserialiseGxsPhotoAlbumItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::deserialiseGxsPhotoAlbumItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; } -uint32_t RsGxsPhotoSerialiser::sizeGxsPhotoPhotoItem(RsGxsPhotoPhotoItem* item) { +uint32_t RsGxsPhotoSerialiser::sizeGxsPhotoPhotoItem(RsGxsPhotoPhotoItem* item) +{ + + const RsPhotoPhoto& photo = item->photo; + + uint32_t s = 8; // header size + s += GetTlvStringSize(photo.mCaption); + s += GetTlvStringSize(photo.mCategory); + s += GetTlvStringSize(photo.mDescription); + s += GetTlvStringSize(photo.mHashTags); + s += GetTlvStringSize(photo.mOther); + s += GetTlvStringSize(photo.mPhotographer); + s += GetTlvStringSize(photo.mWhen); + s += GetTlvStringSize(photo.mWhere); + + RsTlvBinaryData b(item->PacketService()); // TODO, need something more persisitent + b.setBinData(photo.mThumbnail.data, photo.mThumbnail.size); + s += GetTlvStringSize(photo.mThumbnail.type); + s += b.TlvSize(); + + return s; } bool RsGxsPhotoSerialiser::serialiseGxsPhotoPhotoItem(RsGxsPhotoPhotoItem* item, void* data, - uint32_t* size) { + uint32_t* size) +{ + + +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::serialiseGxsPhotoPhotoItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsPhotoPhotoItem(item); + uint32_t offset = 0; + + if(*size < tlvsize){ +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::serialiseGxsPhotoPhotoItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsPhotoAlbumItem */ + + ok &= SetTlvString(data, tlvsize, &offset, 1, item->photo.mCaption); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->photo.mCategory); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->photo.mDescription); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->photo.mHashTags); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->photo.mOther); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->photo.mPhotographer); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->photo.mWhen); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->photo.mWhere); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->photo.mThumbnail.type); + RsTlvBinaryData b(RS_SERVICE_TYPE_PHOTO); // TODO, need something more persisitent + b.setBinData(item->photo.mThumbnail.data, item->photo.mThumbnail.size); + b.SetTlv(item->photo.mThumbnail.data, tlvsize, &offset); + + if(offset != tlvsize) + { +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::serialiseGxsPhotoPhotoItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef GXS_PHOTO_SERIAL_DEBUG + if (!ok) + { + std::cerr << "RsGxsPhotoSerialiser::serialiseGxsPhotoPhotoItem() NOK" << std::endl; + } +#endif + + return ok; } RsGxsPhotoPhotoItem* RsGxsPhotoSerialiser::deserialiseGxsPhotoPhotoItem(void* data, - uint32_t* size) { + uint32_t* size) +{ + + +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::deserialiseGxsPhotoPhotoItem()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_TYPE_PHOTO != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_PHOTO_SHOW_ITEM != getRsItemSubType(rstype))) + { +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::deserialiseGxsPhotoPhotoItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::deserialiseGxsPhotoPhotoItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsPhotoPhotoItem* item = new RsGxsPhotoPhotoItem(); + /* skip the header */ + offset += 8; + + ok &= GetTlvString(data, rssize, &offset, 1, item->photo.mCaption); + ok &= GetTlvString(data, rssize, &offset, 1, item->photo.mCategory); + ok &= GetTlvString(data, rssize, &offset, 1, item->photo.mDescription); + ok &= GetTlvString(data, rssize, &offset, 1, item->photo.mHashTags); + ok &= GetTlvString(data, rssize, &offset, 1, item->photo.mOther); + ok &= GetTlvString(data, rssize, &offset, 1, item->photo.mPhotographer); + ok &= GetTlvString(data, rssize, &offset, 1, item->photo.mWhen); + ok &= GetTlvString(data, rssize, &offset, 1, item->photo.mWhere); + ok &= GetTlvString(data, rssize, &offset, 1, item->photo.mThumbnail.type); + + RsTlvBinaryData b(RS_SERVICE_TYPE_PHOTO); // TODO, need something more persisitent + ok &= b.GetTlv(data, rssize, &offset); + item->photo.mThumbnail.data = (uint8_t*)(b.bin_data); + item->photo.mThumbnail.size = b.bin_len; + b.TlvShallowClear(); + + if (offset != rssize) + { +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::deserialiseGxsPhotoPhotoItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::deserialiseGxsPhotoPhotoItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; } + +void RsGxsPhotoAlbumItem::clear() +{ + album.mCaption.clear(); + album.mCategory.clear(); + album.mDescription.clear(); + album.mHashTags.clear(); + album.mOther.clear(); + album.mPhotoPath.clear(); + album.mPhotographer.clear(); + album.mWhen.clear(); + album.mWhere.clear(); + album.mThumbnail.deleteImage(); +} + +std::ostream& RsGxsPhotoAlbumItem::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsGxsPhotoAlbumItem", indent); + uint16_t int_Indent = indent + 2; + + + printRsItemEnd(out ,"RsGxsPhotoAlbumItem", indent); + return out; +} + +void RsGxsPhotoPhotoItem::clear() +{ + photo.mCaption.clear(); + photo.mCategory.clear(); + photo.mDescription.clear(); + photo.mHashTags.clear(); + photo.mOther.clear(); + photo.mPhotographer.clear(); + photo.mWhen.clear(); + photo.mWhere.clear(); + photo.mThumbnail.deleteImage(); +} + +std::ostream& RsGxsPhotoPhotoItem::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsGxsPhotoPhotoItem", indent); + uint16_t int_Indent = indent + 2; + + + printRsItemEnd(out ,"RsGxsPhotoPhotoItem", indent); + return out; +} + diff --git a/libretroshare/src/serialiser/rsphotov2items.h b/libretroshare/src/serialiser/rsphotov2items.h index b44ceee62..89cc9c4f9 100644 --- a/libretroshare/src/serialiser/rsphotov2items.h +++ b/libretroshare/src/serialiser/rsphotov2items.h @@ -33,6 +33,7 @@ #include "serialiser/rstlvtypes.h" #include "rsgxsitems.h" +#include "rsphotoitems.h" #include "retroshare/rsphotoV2.h" @@ -41,7 +42,13 @@ class RsGxsPhotoAlbumItem : public RsGxsGrpItem public: - RsGxsPhotoAlbumItem() {} + RsGxsPhotoAlbumItem(): RsGxsGrpItem(RS_SERVICE_TYPE_PHOTO, + RS_PKT_SUBTYPE_PHOTO_ITEM) { return;} + + virtual void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + RsPhotoAlbum album; }; @@ -49,7 +56,11 @@ class RsGxsPhotoPhotoItem : public RsGxsMsgItem { public: - RsGxsPhotoPhotoItem() {} + RsGxsPhotoPhotoItem(): RsGxsMsgItem(RS_SERVICE_TYPE_PHOTO, + RS_PKT_SUBTYPE_PHOTO_SHOW_ITEM) {return; } + + virtual void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); RsPhotoPhoto photo; }; From c3ea5cbab6cd668d6fd2e5e47fc3a57a22d79206 Mon Sep 17 00:00:00 2001 From: drbob Date: Wed, 1 Aug 2012 01:44:23 +0000 Subject: [PATCH 009/222] * Added FlagFilter to TokenOptions. * Added data to posted data * modified dummyData to have nested Comments. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5365 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/retroshare/rsidentity.h | 8 +- libretroshare/src/retroshare/rsposted.h | 5 + libretroshare/src/services/p3gxsservice.cc | 114 +++++++++++++++++++-- libretroshare/src/services/p3posted.cc | 59 ++++++++++- 4 files changed, 174 insertions(+), 12 deletions(-) diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index 1e0164e70..9f82890f9 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -73,7 +73,9 @@ class RsTokReqOptions RsTokReqOptions() { mOptions = 0; - mStatusFilter = 0; mStatusMask = 0; mSubscribeFilter = 0; + mStatusFilter = 0; mStatusMask = 0; + mFlagsFilter = 0; mFlagsMask = 0; + mSubscribeFilter = 0; mBefore = 0; mAfter = 0; } @@ -84,6 +86,10 @@ class RsTokReqOptions uint32_t mStatusFilter; uint32_t mStatusMask; + // MsgFlags or GroupsFlags, depends on Request. + uint32_t mFlagsFilter; + uint32_t mFlagsMask; + uint32_t mSubscribeFilter; // Only for Groups. // Time range... again applied after Options. diff --git a/libretroshare/src/retroshare/rsposted.h b/libretroshare/src/retroshare/rsposted.h index be6e30c95..e98fc8d2b 100644 --- a/libretroshare/src/retroshare/rsposted.h +++ b/libretroshare/src/retroshare/rsposted.h @@ -77,6 +77,9 @@ class RsPostedPost: public RsPostedMsg mMeta.mMsgFlags = RSPOSTED_MSGTYPE_POST; return; } + + std::string mLink; + std::string mNotes; }; @@ -99,6 +102,8 @@ class RsPostedComment: public RsPostedMsg mMeta.mMsgFlags = RSPOSTED_MSGTYPE_COMMENT; return; } + + std::string mComment; }; diff --git a/libretroshare/src/services/p3gxsservice.cc b/libretroshare/src/services/p3gxsservice.cc index f2b316011..3d4e7e150 100644 --- a/libretroshare/src/services/p3gxsservice.cc +++ b/libretroshare/src/services/p3gxsservice.cc @@ -370,6 +370,33 @@ static bool checkGroupFilter(const RsTokReqOptions &opts, const RsGroupMetaData statusMatch = true; } + bool flagsMatch = false; + if (opts.mFlagsMask) + { + // Exact Flags match required. + if ((opts.mFlagsMask & opts.mFlagsFilter) == (opts.mFlagsMask & group.mGroupFlags)) + { + std::cerr << "checkGroupFilter() Accepting Group as Flags Match: "; + std::cerr << " Mask: " << opts.mFlagsMask << " FlagsFilter: " << opts.mFlagsFilter; + std::cerr << " GroupFlags: " << group.mGroupFlags << " GroupId: " << group.mGroupId; + std::cerr << std::endl; + + flagsMatch = true; + } + else + { + std::cerr << "checkGroupFilter() Dropping Group due to !Flags Match "; + std::cerr << " Mask: " << opts.mFlagsMask << " FlagsFilter: " << opts.mFlagsFilter; + std::cerr << " GroupFlags: " << group.mGroupFlags << " GroupId: " << group.mGroupId; + std::cerr << std::endl; + } + } + else + { + // no status comparision, + flagsMatch = true; + } + bool subMatch = false; if (opts.mSubscribeFilter) { @@ -397,7 +424,7 @@ static bool checkGroupFilter(const RsTokReqOptions &opts, const RsGroupMetaData subMatch = true; } - return (statusMatch && subMatch); + return (statusMatch && flagsMatch && subMatch); } @@ -429,7 +456,35 @@ static bool checkMsgFilter(const RsTokReqOptions &opts, const RsMsgMetaData &msg // no status comparision, statusMatch = true; } - return statusMatch; + + bool flagsMatch = false; + if (opts.mFlagsMask) + { + // Exact Flags match required. + if ((opts.mFlagsMask & opts.mFlagsFilter) == (opts.mFlagsMask & msg.mMsgFlags)) + { + std::cerr << "checkMsgFilter() Accepting Msg as Flags Match: "; + std::cerr << " Mask: " << opts.mFlagsMask << " FlagsFilter: " << opts.mFlagsFilter; + std::cerr << " MsgFlags: " << msg.mMsgFlags << " MsgId: " << msg.mMsgId; + std::cerr << std::endl; + + flagsMatch = true; + } + else + { + std::cerr << "checkMsgFilter() Dropping Msg due to !Flags Match "; + std::cerr << " Mask: " << opts.mFlagsMask << " FlagsFilter: " << opts.mFlagsFilter; + std::cerr << " MsgFlags: " << msg.mMsgFlags << " MsgId: " << msg.mMsgId; + std::cerr << std::endl; + } + } + else + { + // no status comparision, + flagsMatch = true; + } + + return (statusMatch && flagsMatch); } @@ -687,6 +742,7 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt bool onlyLatestMsgs = false; bool onlyAllVersions = false; bool onlyChildMsgs = false; + bool onlyThreadMsgs = false; if (opts.mOptions & RS_TOKREQOPT_MSG_LATEST) { @@ -708,6 +764,13 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt onlyChildMsgs = true; } + if (opts.mOptions & RS_TOKREQOPT_MSG_THREAD) + { + std::cerr << "GxsDataProxy::getMsgRelatedList() MSG_THREAD"; + std::cerr << std::endl; + onlyThreadMsgs = true; + } + if (onlyAllVersions && onlyChildMsgs) { std::cerr << "GxsDataProxy::getMsgRelatedList() ERROR Incompatible FLAGS (VERSIONS & PARENT)"; @@ -716,6 +779,14 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt return false; } + if (onlyAllVersions && onlyThreadMsgs) + { + std::cerr << "GxsDataProxy::getMsgRelatedList() ERROR Incompatible FLAGS (VERSIONS & THREAD)"; + std::cerr << std::endl; + + return false; + } + if ((!onlyLatestMsgs) && onlyChildMsgs) { std::cerr << "GxsDataProxy::getMsgRelatedList() ERROR Incompatible FLAGS (!LATEST & PARENT)"; @@ -724,9 +795,25 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt return false; } + if ((!onlyLatestMsgs) && onlyThreadMsgs) + { + std::cerr << "GxsDataProxy::getMsgRelatedList() ERROR Incompatible FLAGS (!LATEST & THREAD)"; + std::cerr << std::endl; + + return false; + } + + if (onlyChildMsgs && onlyThreadMsgs) + { + std::cerr << "GxsDataProxy::getMsgRelatedList() ERROR Incompatible FLAGS (PARENT & THREAD)"; + std::cerr << std::endl; + + return false; + } + /* FALL BACK OPTION */ - if ((!onlyLatestMsgs) && (!onlyAllVersions) && (!onlyChildMsgs)) + if ((!onlyLatestMsgs) && (!onlyAllVersions) && (!onlyChildMsgs) && (!onlyThreadMsgs)) { std::cerr << "GxsDataProxy::getMsgRelatedList() FALLBACK -> NO FLAGS -> JUST COPY"; std::cerr << std::endl; @@ -755,7 +842,7 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt if (onlyLatestMsgs) { - if (onlyChildMsgs) + if (onlyChildMsgs || onlyThreadMsgs) { // RUN THROUGH ALL MSGS... in map origId -> TS. std::map > origMsgTs; @@ -763,16 +850,27 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt for(mit = mMsgMetaData.begin(); mit != mMsgMetaData.end(); mit++) { // skip msgs that aren't children. - if (mit->second.mParentId != origMsgId) + if (onlyChildMsgs) { - continue; + if (mit->second.mParentId != origMsgId) + { + continue; + } + } + else /* onlyThreadMsgs */ + { + if (mit->second.mThreadId != (*it)) + { + continue; + } } + oit = origMsgTs.find(mit->second.mOrigMsgId); bool addMsg = false; if (oit == origMsgTs.end()) { - std::cerr << "GxsDataProxy::getMsgList() Found New OrigMsgId: "; + std::cerr << "GxsDataProxy::getMsgRelatedList() Found New OrigMsgId: "; std::cerr << mit->second.mOrigMsgId; std::cerr << " MsgId: " << mit->second.mMsgId; std::cerr << " TS: " << mit->second.mPublishTs; @@ -783,7 +881,7 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt // check timestamps. else if (oit->second.second < mit->second.mPublishTs) { - std::cerr << "GxsDataProxy::getMsgList() Found Later Msg. OrigMsgId: "; + std::cerr << "GxsDataProxy::getMsgRelatedList() Found Later Msg. OrigMsgId: "; std::cerr << mit->second.mOrigMsgId; std::cerr << " MsgId: " << mit->second.mMsgId; std::cerr << " TS: " << mit->second.mPublishTs; diff --git a/libretroshare/src/services/p3posted.cc b/libretroshare/src/services/p3posted.cc index ee5859ca5..02458126f 100644 --- a/libretroshare/src/services/p3posted.cc +++ b/libretroshare/src/services/p3posted.cc @@ -953,8 +953,11 @@ std::ostream &operator<<(std::ostream &out, const RsPostedGroup &group) bool p3PostedService::generateDummyData() { #define MAX_GROUPS 10 //100 -#define MAX_POSTS 100 //1000 -#define MAX_COMMENTS 5000 //10000 +#define MAX_POSTS 50 //1000 + +#define MAX_BASE_COMMENTS 1000 //10000 +#define MAX_COMMENTS 4000 //10000 + #define MAX_VOTES 10000 //10000 std::list mGroups; @@ -1056,7 +1059,7 @@ bool p3PostedService::generateDummyData() } - for(i = 0; i < MAX_COMMENTS; i++) + for(i = 0; i < MAX_BASE_COMMENTS; i++) { /* generate a base thread */ @@ -1106,6 +1109,56 @@ bool p3PostedService::generateDummyData() } + for(i = 0; i < MAX_COMMENTS; i++) + { + /* generate a base thread */ + + /* rotate the Forum Groups Around, then pick one. + */ + + int rnd = (int) (RSRandom::random_f32() * 10.0); + + for(j = 0; j < rnd; j++) + { + RsPostedComment head = mComments.front(); + mComments.pop_front(); + mComments.push_back(head); + } + + RsPostedComment parent = mComments.front(); + + /* now create a new child msg */ + + RsPostedComment comment; + + /* fill in key data + * GroupId + * MsgId + * OrigMsgId + * ThreadId + * ParentId + * PublishTS (take Forum TS + a bit ). + * + * ChildTS ???? + */ + snprintf(name, DUMMY_NAME_MAX_LEN, "%s => Comment_%d", parent.mMeta.mMsgName.c_str(), i+1); + comment.mMeta.mMsgName = name; + //comment.mMsg = name; + + comment.mMeta.mGroupId = parent.mMeta.mGroupId; + comment.mMeta.mMsgId = genRandomId(); + comment.mMeta.mOrigMsgId = comment.mMeta.mMsgId; + comment.mMeta.mThreadId = parent.mMeta.mThreadId; + comment.mMeta.mParentId = parent.mMeta.mOrigMsgId; + + comment.mMeta.mPublishTs = parent.mMeta.mPublishTs + (RSRandom::random_f32() * 10000); + if (comment.mMeta.mPublishTs > now) + comment.mMeta.mPublishTs = now - 1; + + mComments.push_back(comment); + } + + for(i = 0; i < MAX_VOTES; i++) { /* generate a base thread */ From 48683a19d59d3971890ddc3adb017df167c045e2 Mon Sep 17 00:00:00 2001 From: drbob Date: Wed, 1 Aug 2012 01:47:53 +0000 Subject: [PATCH 010/222] * Added first pass at Generic Comment Tree. - Specific to Posted at the moment. * Modified Posted to load Comments when Post "comment" button is pressed. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5366 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/RetroShare.pro | 6 +- .../src/gui/Posted/PostedComments.cpp | 11 + .../src/gui/Posted/PostedComments.h | 5 + .../src/gui/Posted/PostedComments.ui | 164 +++----- .../src/gui/Posted/PostedDialog.cpp | 1 + retroshare-gui/src/gui/Posted/PostedItem.cpp | 13 + retroshare-gui/src/gui/Posted/PostedItem.h | 9 + retroshare-gui/src/gui/Posted/PostedItem.ui | 2 +- .../src/gui/Posted/PostedListDialog.cpp | 11 + .../src/gui/Posted/PostedListDialog.h | 3 + .../src/gui/Posted/PostedListDialog.ui | 3 + .../src/gui/gxs/GxsCommentTreeWidget.cpp | 372 ++++++++++++++++++ .../src/gui/gxs/GxsCommentTreeWidget.h | 88 +++++ 13 files changed, 576 insertions(+), 112 deletions(-) create mode 100644 retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp create mode 100644 retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index ac3200f91..4e3c47782 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -973,19 +973,19 @@ gxsgui { gui/gxs/ForumV2GroupDialog.h \ gui/gxs/WikiGroupDialog.h \ gui/gxs/PostedGroupDialog.h \ + gui/gxs/GxsCommentTreeWidget.h \ # gui/gxs/GxsMsgDialog.h \ -# gui/gxs/GxsCommentWidget.h \ FORMS += gui/gxs/GxsGroupDialog.ui \ # gui/gxs/GxsMsgDialog.ui \ -# gui/gxs/GxsCommentWidget.ui \ +# gui/gxs/GxsCommentTreeWidget.ui \ SOURCES += gui/gxs/GxsGroupDialog.cpp \ gui/gxs/ForumV2GroupDialog.cpp \ gui/gxs/WikiGroupDialog.cpp \ gui/gxs/PostedGroupDialog.cpp \ + gui/gxs/GxsCommentTreeWidget.cpp \ # gui/gxs/GxsMsgDialog.cpp \ -# gui/gxs/GxsCommentWidget.cpp \ } diff --git a/retroshare-gui/src/gui/Posted/PostedComments.cpp b/retroshare-gui/src/gui/Posted/PostedComments.cpp index 4e1f73bab..00328335a 100644 --- a/retroshare-gui/src/gui/Posted/PostedComments.cpp +++ b/retroshare-gui/src/gui/Posted/PostedComments.cpp @@ -83,8 +83,19 @@ PostedComments::PostedComments(QWidget *parent) /* setup TokenQueue */ //mPhotoQueue = new TokenQueue(rsPhoto, this); + ui.treeWidget->setup(rsPosted); + } +void PostedComments::loadComments( std::string threadId ) +{ + std::cerr << "PostedComments::loadComments(" << threadId << ")"; + std::cerr << std::endl; + + ui.treeWidget->requestComments(threadId); +} + + #if 0 void PhotoDialog::notifySelection(PhotoItem *item, int ptype) diff --git a/retroshare-gui/src/gui/Posted/PostedComments.h b/retroshare-gui/src/gui/Posted/PostedComments.h index 78d52354d..9da5a8447 100644 --- a/retroshare-gui/src/gui/Posted/PostedComments.h +++ b/retroshare-gui/src/gui/Posted/PostedComments.h @@ -43,6 +43,9 @@ class PostedComments: public QWidget, public TokenResponse public: PostedComments(QWidget *parent = 0); +public slots: + void loadComments( std::string ); + private: void loadRequest(const TokenQueue *queue, const TokenRequest &req) { return; } @@ -53,6 +56,8 @@ virtual void notifySelection(PhotoItem *item, int ptype); void notifyAlbumSelection(PhotoItem *item); void notifyPhotoSelection(PhotoItem *item); + + private slots: void checkUpdate(); diff --git a/retroshare-gui/src/gui/Posted/PostedComments.ui b/retroshare-gui/src/gui/Posted/PostedComments.ui index 0b974c14f..e2ea38c34 100644 --- a/retroshare-gui/src/gui/Posted/PostedComments.ui +++ b/retroshare-gui/src/gui/Posted/PostedComments.ui @@ -13,8 +13,8 @@ Form - - + + @@ -51,119 +51,67 @@
- - - - Today - - - - - Yesterday - - - - - This Week - - - - - This Month - - - - - This Year - - + + + Refresh +
- - - - - - - - Refresh - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Showing 1-100 - - - - - - - Prev - - - - - - - Next - - - - - - - - - true - - - - - 0 - 0 - 382 - 302 - - - - - - - - - - 0 - 0 - - - - - 1 - - - - - + + + + + Stuff + + + + + New Column + + + + + Yes More + + + + + more, more, more + + + + + More Stuff + + + + + Less Stuff + + + + + More + + + + + asdf + + +
+ + + GxsCommentTreeWidget + QTreeWidget +
gui/gxs/GxsCommentTreeWidget.h
+
+
diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.cpp b/retroshare-gui/src/gui/Posted/PostedDialog.cpp index 934fd02dd..38d92a186 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedDialog.cpp @@ -70,6 +70,7 @@ PostedDialog::PostedDialog(QWidget *parent) QString comments("Comments"); ui.tabWidget->addTab(mPostedComments, comments); + connect(mPostedList, SIGNAL(loadComments( std::string ) ), mPostedComments, SLOT(loadComments( std::string ) ) ); } diff --git a/retroshare-gui/src/gui/Posted/PostedItem.cpp b/retroshare-gui/src/gui/Posted/PostedItem.cpp index e1b57e754..92c7717dc 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.cpp +++ b/retroshare-gui/src/gui/Posted/PostedItem.cpp @@ -72,10 +72,23 @@ PostedItem::PostedItem(PostedHolder *parent, const RsPostedPost &post) ts.setTime_t(post.mMeta.mPublishTs); dateLabel->setText(ts.toString(QString("yyyy/MM/dd hh:mm:ss"))); + mThreadId = post.mMeta.mThreadId; + mParent = parent; + + connect( commentButton, SIGNAL( clicked() ), this, SLOT( loadComments() ) ); + return; } +void PostedItem::loadComments() +{ + std::cerr << "PostedItem::loadComments() Requesting for " << mThreadId; + std::cerr << std::endl; + mParent->requestComments(mThreadId); +} + + #if 0 PhotoItem::PhotoItem(PhotoHolder *parent, const RsPhotoAlbum &album) diff --git a/retroshare-gui/src/gui/Posted/PostedItem.h b/retroshare-gui/src/gui/Posted/PostedItem.h index c0d830811..b13925802 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.h +++ b/retroshare-gui/src/gui/Posted/PostedItem.h @@ -36,6 +36,8 @@ class PostedHolder public: virtual void deletePostedItem(PostedItem *, uint32_t ptype) = 0; virtual void notifySelection(PostedItem *item, int ptype) = 0; + +virtual void requestComments(std::string threadId) = 0; }; class PostedItem : public QWidget, private Ui::PostedItem @@ -55,9 +57,16 @@ public: protected: //void mousePressEvent(QMouseEvent *event); +private slots: + void loadComments(); + private: uint32_t mType; bool mSelected; + + std::string mThreadId; + PostedHolder *mParent; + }; diff --git a/retroshare-gui/src/gui/Posted/PostedItem.ui b/retroshare-gui/src/gui/Posted/PostedItem.ui index ad1501e08..bacacace5 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.ui +++ b/retroshare-gui/src/gui/Posted/PostedItem.ui @@ -265,7 +265,7 @@ border-radius: 10px}
- + View Comments diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp index 745035c7e..0c926be1e 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp @@ -185,6 +185,17 @@ void PostedListDialog::updateDisplay() } +void PostedListDialog::requestComments(std::string threadId) +{ + /* call a signal */ + std::cerr << "PostedListDialog::requestComments(" << threadId << ")"; + std::cerr << std::endl; + + loadComments(threadId); + +} + + void PostedListDialog::changedTopic(const QString &id) { mCurrTopicId = id.toStdString(); diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.h b/retroshare-gui/src/gui/Posted/PostedListDialog.h index 0cd6c4670..14dd7c2ca 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.h @@ -47,7 +47,10 @@ public: virtual void deletePostedItem(PostedItem *, uint32_t ptype) { return; } virtual void notifySelection(PostedItem *item, int ptype) { return; } +virtual void requestComments(std::string threadId); +signals: + void loadComments( std::string ); private slots: diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.ui b/retroshare-gui/src/gui/Posted/PostedListDialog.ui index 36a536087..a685a6d99 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.ui +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.ui @@ -18,6 +18,9 @@ + + false + -1 diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp new file mode 100644 index 000000000..e1ea83ec4 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp @@ -0,0 +1,372 @@ +/**************************************************************** +* RetroShare is distributed under the following license: +* +* Copyright (C) 2008 Robert Fernie +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, +* Boston, MA 02110-1301, USA. +****************************************************************/ + +#include +#include + +#include "gui/gxs/GxsCommentTreeWidget.h" + +#include + +#define PCITEM_COLUMN_DATE 0 +#define PCITEM_COLUMN_COMMENT 1 +#define PCITEM_COLUMN_AUTHOR 2 +#define PCITEM_COLUMN_SERVSTRING 3 +#define PCITEM_COLUMN_MSGID 4 +#define PCITEM_COLUMN_PARENTID 5 + +#define GXSCOMMENTS_LOADTHREAD 1 + +// Temporarily make this specific. +#include "retroshare/rsposted.h" + + +GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent) + :QTreeWidget(parent), mRsService(NULL), mTokenQueue(NULL) +{ + + return; +} + +void GxsCommentTreeWidget::setup(RsTokenService *service) +{ + mRsService = service; + mTokenQueue = new TokenQueue(service, this); + + return; +} + + +/* Load Comments */ +void GxsCommentTreeWidget::requestComments(std::string threadId) +{ + /* request comments */ + + service_requestComments(threadId); +} + +void GxsCommentTreeWidget::service_requestComments(std::string threadId) +{ + /* request comments */ + //std::cerr << "GxsCommentTreeWidget::service_requestComments() ERROR must be overloaded!"; + //std::cerr << std::endl; + + std::cerr << "GxsCommentTreeWidget::service_requestComments(" << threadId << ")"; + std::cerr << std::endl; + + RsTokReqOptions opts; + + opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; + opts.mFlagsFilter = RSPOSTED_MSGTYPE_COMMENT; + opts.mFlagsMask = RSPOSTED_MSGTYPE_COMMENT; + + std::list msgIds; + msgIds.push_back(threadId); + + mThreadId = threadId; + + uint32_t token; + mTokenQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, GXSCOMMENTS_LOADTHREAD); +} + + +/* Generic Handling */ +void GxsCommentTreeWidget::clearItems() +{ + mPendingInsertMap.clear(); + mLoadingMap.clear(); +} + + +void GxsCommentTreeWidget::completeItems() +{ + /* handle pending items */ + std::string parentId; + QTreeWidgetItem *parent = NULL; + QList topLevelItems; + + std::map::iterator lit; + std::multimap::iterator pit; + + std::cerr << "GxsCommentTreeWidget::completeItems() " << mPendingInsertMap.size(); + std::cerr << " PendingItems"; + std::cerr << std::endl; + + for(pit = mPendingInsertMap.begin(); pit != mPendingInsertMap.end(); pit++) + { + std::cerr << "GxsCommentTreeWidget::completeItems() item->parent: " << pit->first; + std::cerr << std::endl; + + if (pit->first != parentId) + { + /* find parent */ + parentId = pit->first; + lit = mLoadingMap.find(pit->first); + if (lit != mLoadingMap.end()) + { + parent = lit->second; + } + else + { + parent = NULL; + } + } + + if (parent) + { + std::cerr << "GxsCommentTreeWidget::completeItems() Added to Parent"; + std::cerr << std::endl; + + parent->addChild(pit->second); + } + else if (parentId == mThreadId) + { + std::cerr << "GxsCommentTreeWidget::completeItems() Added to topLevelItems"; + std::cerr << std::endl; + + topLevelItems.append(pit->second); + } + else + { + + /* missing parent -> insert At Top Level */ + QTreeWidgetItem *missingItem = service_createMissingItem(pit->first); + + std::cerr << "GxsCommentTreeWidget::completeItems() Added MissingItem"; + std::cerr << std::endl; + + parent = missingItem; + parent->addChild(pit->second); + topLevelItems.append(parent); + } + } + + /* now push final tree into Tree */ + clear(); + insertTopLevelItems(0, topLevelItems); + + /* cleanup temp stuff */ + mLoadingMap.clear(); + mPendingInsertMap.clear(); +} + + +void GxsCommentTreeWidget::addItem(std::string itemId, std::string parentId, QTreeWidgetItem *item) +{ + std::cerr << "GxsCommentTreeWidget::addItem() Id: " << itemId; + std::cerr << " ParentId: " << parentId; + std::cerr << std::endl; + + /* store in map -> for children */ + mLoadingMap[itemId] = item; + + std::map::iterator it; + it = mLoadingMap.find(parentId); + if (it != mLoadingMap.end()) + { + std::cerr << "GxsCommentTreeWidget::addItem() Added to Parent"; + std::cerr << std::endl; + + it->second->addChild(item); + } + else + { + std::cerr << "GxsCommentTreeWidget::addItem() Added to Pending List"; + std::cerr << std::endl; + + mPendingInsertMap.insert(std::make_pair(parentId, item)); + } +} + +void GxsCommentTreeWidget::loadThread(const uint32_t &token) +{ + clearItems(); + + service_loadThread(token); + + completeItems(); +} + + +void GxsCommentTreeWidget::service_loadThread(const uint32_t &token) +{ + std::cerr << "GxsCommentTreeWidget::service_loadThread() ERROR must be overloaded!"; + std::cerr << std::endl; + + RsPostedComment comment; + while(rsPosted->getComment(token, comment)) + { + /* convert to a QTreeWidgetItem */ + std::cerr << "GxsCommentTreeWidget::service_loadThread() Got Comment: " << comment; + std::cerr << std::endl; + + QTreeWidgetItem *item = new QTreeWidgetItem(); + QString text; + + { + QDateTime qtime; + qtime.setTime_t(comment.mMeta.mPublishTs); + + text = qtime.toString("yyyy-MM-dd hh:mm:ss"); + item->setText(PCITEM_COLUMN_DATE, text); + } + + text = QString::fromUtf8(comment.mComment.c_str()); + item->setText(PCITEM_COLUMN_COMMENT, text); + + text = QString::fromUtf8(comment.mMeta.mAuthorId.c_str()); + if (text.isEmpty()) + { + item->setText(PCITEM_COLUMN_AUTHOR, tr("Anonymous")); + } + else + { + item->setText(PCITEM_COLUMN_AUTHOR, text); + } + + + text = QString::fromUtf8(comment.mMeta.mMsgId.c_str()); + item->setText(PCITEM_COLUMN_MSGID, text); + + text = QString::fromUtf8(comment.mMeta.mParentId.c_str()); + item->setText(PCITEM_COLUMN_PARENTID, text); + + text = QString::fromUtf8(comment.mMeta.mServiceString.c_str()); + item->setText(PCITEM_COLUMN_SERVSTRING, text); + + addItem(comment.mMeta.mMsgId, comment.mMeta.mParentId, item); + } + + return; +} + +QTreeWidgetItem *GxsCommentTreeWidget::service_createMissingItem(std::string parent) +{ + //std::cerr << "GxsCommentTreeWidget::service_createMissingItem() ERROR must be overloaded!"; + //std::cerr << std::endl; + + std::cerr << "GxsCommentTreeWidget::service_createMissingItem()"; + std::cerr << std::endl; + + QTreeWidgetItem *item = new QTreeWidgetItem(); + QString text("Unknown"); + + item->setText(PCITEM_COLUMN_DATE, text); + + item->setText(PCITEM_COLUMN_COMMENT, text); + + item->setText(PCITEM_COLUMN_AUTHOR, text); + + item->setText(PCITEM_COLUMN_MSGID, text); + + item->setText(PCITEM_COLUMN_SERVSTRING, text); + + text = QString::fromUtf8(parent.c_str()); + item->setText(PCITEM_COLUMN_PARENTID, text); + + return item; +} + + +void GxsCommentTreeWidget::loadRequest(const TokenQueue *queue, const TokenRequest &req) +{ + std::cerr << "GxsCommentTreeWidget::loadRequest() UserType: " << req.mUserType; + std::cerr << std::endl; + + if (queue != mTokenQueue) + { + std::cerr << "GxsCommentTreeWidget::loadRequest() Queue ERROR"; + std::cerr << std::endl; + return; + } + + /* now switch on req */ + switch(req.mUserType) + { + + case GXSCOMMENTS_LOADTHREAD: + loadThread(req.mToken); + break; + default: + std::cerr << "GxsCommentTreeWidget::loadRequest() UNKNOWN UserType "; + std::cerr << std::endl; + break; + } +} + + + +#if 0 + + +QMimeData * GxsCommentTreeWidget::mimeData ( const QList items ) const +{ + /* extract from each QTreeWidgetItem... all the member text */ + QList::const_iterator it; + QString text; + for(it = items.begin(); it != items.end(); it++) + { + QString line = QString("%1/%2/%3/").arg((*it)->text(SR_NAME_COL), (*it)->text(SR_HASH_COL), (*it)->text(SR_SIZE_COL)); + + bool isLocal = (*it)->data(SR_DATA_COL, SR_ROLE_LOCAL).toBool(); + if (isLocal) + { + line += "Local"; + } + else + { + line += "Remote"; + } + line += "/\n"; + + text += line; + } + + std::cerr << "Created MimeData:"; + std::cerr << std::endl; + + std::string str = text.toUtf8().constData(); + std::cerr << str; + std::cerr << std::endl; + + QMimeData *data = new QMimeData(); + data->setData("application/x-rsfilelist", QByteArray(str.c_str())); + + return data; +} + + + +QStringList GxsCommentTreeWidget::mimeTypes () const +{ + QStringList list; + list.push_back("application/x-rsfilelist"); + + return list; +} + + +Qt::DropActions GxsCommentTreeWidget::supportedDropActions () const +{ + return Qt::CopyAction; +} + +#endif diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h new file mode 100644 index 000000000..41850b9ba --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h @@ -0,0 +1,88 @@ +/**************************************************************** +* RetroShare is distributed under the following license: +* +* Copyright (C) 2008 Robert Fernie +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, +* Boston, MA 02110-1301, USA. +****************************************************************/ + +#ifndef _GXS_COMMENT_TREE_WIDGET_H +#define _GXS_COMMENT_TREE_WIDGET_H + +#include + +#include "util/TokenQueue.h" + +/* indicies for search results item columns SR_ = Search Result */ +#define SR_NAME_COL 0 +#define SR_SIZE_COL 1 +#define SR_ID_COL 2 +#define SR_TYPE_COL 3 +#define SR_AGE_COL 4 +#define SR_HASH_COL 5 +#define SR_SEARCH_ID_COL 6 +#define SR_UID_COL 7 +#define SR_DATA_COL SR_NAME_COL + +#define SR_ROLE_LOCAL Qt::UserRole + +class GxsCommentTreeWidget : public QTreeWidget, public TokenResponse +{ + Q_OBJECT + +public: + GxsCommentTreeWidget(QWidget *parent = 0); + void setup(RsTokenService *service); + + void requestComments(std::string threadId); + + void loadRequest(const TokenQueue *queue, const TokenRequest &req); + +protected: + + /* to be overloaded */ + virtual void service_requestComments(std::string threadId); + virtual void service_loadThread(const uint32_t &token); + virtual QTreeWidgetItem *service_createMissingItem(std::string parent); + + void clearItems(); + void completeItems(); + + void loadThread(const uint32_t &token); + + void addItem(std::string itemId, std::string parentId, QTreeWidgetItem *item); + + + + /* Data */ + std::string mThreadId; + + std::map mLoadingMap; + std::multimap mPendingInsertMap; + + TokenQueue *mTokenQueue; + RsTokenService *mRsService; + + protected: +//virtual QMimeData * mimeData ( const QList items ) const; +//virtual QStringList mimeTypes () const; +//virtual Qt::DropActions supportedDropActions () const; + +}; + + +#endif + From ebc8fa32122ae19b2f92385b45a1cf11bb981094 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Wed, 1 Aug 2012 12:56:06 +0000 Subject: [PATCH 011/222] Fixed bad default value for filter column in ForumsV2Dialog. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5368 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/ForumsV2Dialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/ForumsV2Dialog.cpp b/retroshare-gui/src/gui/ForumsV2Dialog.cpp index 5b1bc363e..09b390e1b 100644 --- a/retroshare-gui/src/gui/ForumsV2Dialog.cpp +++ b/retroshare-gui/src/gui/ForumsV2Dialog.cpp @@ -264,7 +264,7 @@ void ForumsV2Dialog::processSettings(bool bLoad) togglethreadview_internal(); // filterColumn - int nValue = FilterColumnToComboBox(Settings->value("filterColumn", true).toInt()); + int nValue = FilterColumnToComboBox(Settings->value("filterColumn", COLUMN_THREAD_TITLE).toInt()); ui.filterColumnComboBox->setCurrentIndex(nValue); // index of viewBox From 09b5d7a8c68dfd974e3fac03121ba1725a3e9b72 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Thu, 2 Aug 2012 13:17:53 +0000 Subject: [PATCH 012/222] Added the first version of the FeedReader plugin. Added a new method to RsPlugInInterfaces to stop the plugins at shutdown of RetroShare. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5372 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/plugins/pluginmanager.cc | 15 + libretroshare/src/plugins/pluginmanager.h | 2 + libretroshare/src/retroshare/rsplugin.h | 3 + libretroshare/src/rsserver/p3face-config.cc | 3 + libretroshare/src/rsserver/p3face-server.cc | 2 + libretroshare/src/rsserver/p3face.h | 3 + libretroshare/src/rsserver/rsinit.cc | 2 +- plugins/FeedReader/FeedReader.pro | 43 + plugins/FeedReader/FeedReaderPlugin.cpp | 138 ++ plugins/FeedReader/FeedReaderPlugin.h | 60 + plugins/FeedReader/gui/AddFeedDialog.cpp | 299 +++ plugins/FeedReader/gui/AddFeedDialog.h | 64 + plugins/FeedReader/gui/AddFeedDialog.ui | 442 +++++ plugins/FeedReader/gui/FeedReaderConfig.cpp | 80 + plugins/FeedReader/gui/FeedReaderConfig.h | 57 + plugins/FeedReader/gui/FeedReaderConfig.ui | 148 ++ plugins/FeedReader/gui/FeedReaderDialog.cpp | 1088 +++++++++++ plugins/FeedReader/gui/FeedReaderDialog.h | 105 + plugins/FeedReader/gui/FeedReaderDialog.ui | 373 ++++ plugins/FeedReader/gui/FeedReaderNotify.cpp | 36 + plugins/FeedReader/gui/FeedReaderNotify.h | 45 + plugins/FeedReader/gui/FeedReader_images.qrc | 13 + plugins/FeedReader/gui/images/Feed.png | Bin 0 -> 641 bytes plugins/FeedReader/gui/images/FeedAdd.png | Bin 0 -> 1444 bytes .../gui/images/FeedErrorOverlay.png | Bin 0 -> 193 bytes .../gui/images/FeedProcessOverlay.png | Bin 0 -> 848 bytes plugins/FeedReader/gui/images/FeedReader.png | Bin 0 -> 9924 bytes plugins/FeedReader/gui/images/Folder.png | Bin 0 -> 446 bytes plugins/FeedReader/gui/images/FolderAdd.png | Bin 0 -> 446 bytes plugins/FeedReader/gui/images/Root.png | Bin 0 -> 968 bytes plugins/FeedReader/gui/images/Update.png | Bin 0 -> 1502 bytes plugins/FeedReader/interface/rsFeedReader.h | 181 ++ plugins/FeedReader/lang/FeedReader_de.ts | 339 ++++ plugins/FeedReader/lang/lang.qrc | 5 + plugins/FeedReader/services/p3FeedReader.cc | 1710 +++++++++++++++++ plugins/FeedReader/services/p3FeedReader.h | 113 ++ .../FeedReader/services/p3FeedReaderThread.cc | 1024 ++++++++++ .../FeedReader/services/p3FeedReaderThread.h | 71 + .../FeedReader/services/rsFeedReaderItems.cc | 388 ++++ .../FeedReader/services/rsFeedReaderItems.h | 149 ++ plugins/plugins.pro | 3 +- retroshare-gui/src/gui/MainWindow.cpp | 7 +- 42 files changed, 7004 insertions(+), 7 deletions(-) create mode 100644 plugins/FeedReader/FeedReader.pro create mode 100644 plugins/FeedReader/FeedReaderPlugin.cpp create mode 100644 plugins/FeedReader/FeedReaderPlugin.h create mode 100644 plugins/FeedReader/gui/AddFeedDialog.cpp create mode 100644 plugins/FeedReader/gui/AddFeedDialog.h create mode 100644 plugins/FeedReader/gui/AddFeedDialog.ui create mode 100644 plugins/FeedReader/gui/FeedReaderConfig.cpp create mode 100644 plugins/FeedReader/gui/FeedReaderConfig.h create mode 100644 plugins/FeedReader/gui/FeedReaderConfig.ui create mode 100644 plugins/FeedReader/gui/FeedReaderDialog.cpp create mode 100644 plugins/FeedReader/gui/FeedReaderDialog.h create mode 100644 plugins/FeedReader/gui/FeedReaderDialog.ui create mode 100644 plugins/FeedReader/gui/FeedReaderNotify.cpp create mode 100644 plugins/FeedReader/gui/FeedReaderNotify.h create mode 100644 plugins/FeedReader/gui/FeedReader_images.qrc create mode 100644 plugins/FeedReader/gui/images/Feed.png create mode 100644 plugins/FeedReader/gui/images/FeedAdd.png create mode 100644 plugins/FeedReader/gui/images/FeedErrorOverlay.png create mode 100644 plugins/FeedReader/gui/images/FeedProcessOverlay.png create mode 100644 plugins/FeedReader/gui/images/FeedReader.png create mode 100644 plugins/FeedReader/gui/images/Folder.png create mode 100644 plugins/FeedReader/gui/images/FolderAdd.png create mode 100644 plugins/FeedReader/gui/images/Root.png create mode 100644 plugins/FeedReader/gui/images/Update.png create mode 100644 plugins/FeedReader/interface/rsFeedReader.h create mode 100644 plugins/FeedReader/lang/FeedReader_de.ts create mode 100644 plugins/FeedReader/lang/lang.qrc create mode 100644 plugins/FeedReader/services/p3FeedReader.cc create mode 100644 plugins/FeedReader/services/p3FeedReader.h create mode 100644 plugins/FeedReader/services/p3FeedReaderThread.cc create mode 100644 plugins/FeedReader/services/p3FeedReaderThread.h create mode 100644 plugins/FeedReader/services/rsFeedReaderItems.cc create mode 100644 plugins/FeedReader/services/rsFeedReaderItems.h diff --git a/libretroshare/src/plugins/pluginmanager.cc b/libretroshare/src/plugins/pluginmanager.cc index ea7099943..aed50e791 100644 --- a/libretroshare/src/plugins/pluginmanager.cc +++ b/libretroshare/src/plugins/pluginmanager.cc @@ -134,6 +134,21 @@ void RsPluginManager::loadPlugins(const std::vector& plugin_directo std::cerr << "Loaded a total of " << _plugins.size() << " plugins." << std::endl; } +void RsPluginManager::stopPlugins() +{ + std::cerr << " Stopping plugins." << std::endl; + + for (uint32_t i = 0; i < _plugins.size(); ++i) + { + if (_plugins[i].plugin != NULL) + { + _plugins[i].plugin->stop(); +// delete _plugins[i].plugin; +// _plugins[i].plugin = NULL; + } + } +} + void RsPluginManager::getPluginStatus(int i,uint32_t& status,std::string& file_name,std::string& hash,std::string& error_string) const { if((uint32_t)i >= _plugins.size()) diff --git a/libretroshare/src/plugins/pluginmanager.h b/libretroshare/src/plugins/pluginmanager.h index 2735727ac..7c925edcb 100644 --- a/libretroshare/src/plugins/pluginmanager.h +++ b/libretroshare/src/plugins/pluginmanager.h @@ -78,6 +78,8 @@ class RsPluginManager: public RsPluginHandler, public p3Config // void loadPlugins(const std::vector& explicit_plugin_entries) ; + void stopPlugins(); + void registerCacheServices() ; void registerClientServices(p3ServiceServer *pqih) ; diff --git a/libretroshare/src/retroshare/rsplugin.h b/libretroshare/src/retroshare/rsplugin.h index 4f017f15b..e3cc21d2c 100644 --- a/libretroshare/src/retroshare/rsplugin.h +++ b/libretroshare/src/retroshare/rsplugin.h @@ -94,6 +94,9 @@ class RsPlugin virtual RsPQIService *rs_pqi_service() const { return NULL ; } virtual uint16_t rs_service_id() const { return 0 ; } + // Shutdown + virtual void stop() {} + // Filename used for saving the specific plugin configuration. Both RsCacheService and RsPQIService // derive from p3Config, which means that the service provided by the plugin can load/save its own // config by deriving loadList() and saveList() from p3Config. diff --git a/libretroshare/src/rsserver/p3face-config.cc b/libretroshare/src/rsserver/p3face-config.cc index 9624a43e4..4454a5b86 100644 --- a/libretroshare/src/rsserver/p3face-config.cc +++ b/libretroshare/src/rsserver/p3face-config.cc @@ -31,6 +31,7 @@ #include "pqi/authssl.h" #include "pqi/authgpg.h" #include "retroshare/rsinit.h" +#include "plugins/pluginmanager.h" #include "util/rsdebug.h" const int p3facemsgzone = 11453; @@ -182,6 +183,8 @@ void RsServer::rsGlobalShutDown() join(); ftserver->StopThreads(); + mPluginsManager->stopPlugins(); + // stop the p3distrib threads mForums->join(); mChannels->join(); diff --git a/libretroshare/src/rsserver/p3face-server.cc b/libretroshare/src/rsserver/p3face-server.cc index 9a4a582a1..fba404e68 100644 --- a/libretroshare/src/rsserver/p3face-server.cc +++ b/libretroshare/src/rsserver/p3face-server.cc @@ -62,6 +62,8 @@ RsServer::RsServer(RsIface &i, NotifyBase &callback) pqih = NULL; + mPluginsManager = NULL; + /* services */ ad = NULL; msgSrv = NULL; diff --git a/libretroshare/src/rsserver/p3face.h b/libretroshare/src/rsserver/p3face.h index d7e3a4e90..0290d0b0f 100644 --- a/libretroshare/src/rsserver/p3face.h +++ b/libretroshare/src/rsserver/p3face.h @@ -49,6 +49,7 @@ class p3PeerMgrIMPL; class p3LinkMgrIMPL; class p3NetMgrIMPL; class p3HistoryMgr; +class RsPluginManager; /* The Main Interface Class - for controlling the server */ @@ -161,6 +162,8 @@ class RsServer: public RsControl, public RsThread pqipersongrp *pqih; + RsPluginManager *mPluginsManager; + //sslroot *sslr; /* services */ diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index d6a0881da..9ee634604 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -2177,7 +2177,7 @@ int RsServer::StartupRetroShare() // possible entries include: /usr/lib/retroshare, ~/.retroshare/extensions/, etc. #endif - RsPluginManager *mPluginsManager = new RsPluginManager ; + mPluginsManager = new RsPluginManager ; rsPlugins = mPluginsManager ; mConfigMgr->addConfiguration("plugins.cfg", mPluginsManager); diff --git a/plugins/FeedReader/FeedReader.pro b/plugins/FeedReader/FeedReader.pro new file mode 100644 index 000000000..85b474948 --- /dev/null +++ b/plugins/FeedReader/FeedReader.pro @@ -0,0 +1,43 @@ +!include("../Common/retroshare_plugin.pri"): error("Could not include file ../Common/retroshare_plugin.pri") + +CONFIG += qt uic qrc resources + +SOURCES = FeedReaderPlugin.cpp \ + services/p3FeedReader.cc \ + services/p3FeedReaderThread.cc \ + services/rsFeedReaderItems.cc \ + gui/FeedReaderDialog.cpp \ + gui/AddFeedDialog.cpp \ + gui/FeedReaderNotify.cpp \ + gui/FeedReaderConfig.cpp + +HEADERS = FeedReaderPlugin.h \ + interface/rsFeedReader.h \ + services/p3FeedReader.h \ + services/p3FeedReaderThread.h \ + services/rsFeedReaderItems.h \ + gui/FeedReaderDialog.h \ + gui/AddFeedDialog.h \ + gui/FeedReaderNotify.h \ + gui/FeedReaderConfig.h + +FORMS = gui/FeedReaderDialog.ui \ + gui/AddFeedDialog.ui \ + gui/FeedReaderConfig.ui + +TARGET = FeedReader + +RESOURCES = gui/FeedReader_images.qrc \ + lang/lang.qrc + +win32 { + DEFINES += CURL_STATICLIB + + CURL_DIR = ../../../curl-7.26.0 + LIBXML2_DIR = ../../../libxml2-2.8.0 + LIBICONV_DIR = ../../../libiconv-1.14 + + INCLUDEPATH += $${CURL_DIR}/include $${LIBXML2_DIR}/include $${LIBICONV_DIR}/include + + LIBS += -lcurl -lxml2 -lws2_32 -lwldap32 +} diff --git a/plugins/FeedReader/FeedReaderPlugin.cpp b/plugins/FeedReader/FeedReaderPlugin.cpp new file mode 100644 index 000000000..c83be2c37 --- /dev/null +++ b/plugins/FeedReader/FeedReaderPlugin.cpp @@ -0,0 +1,138 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include +#include + +#include +#include + +#include "FeedReaderPlugin.h" +#include "gui/FeedReaderDialog.h" +#include "gui/FeedReaderConfig.h" +#include "services/p3FeedReader.h" + +#define IMAGE_FEEDREADER ":/images/FeedReader.png" + +static void *inited = new FeedReaderPlugin(); + +extern "C" { +#ifdef WIN32 + __declspec(dllexport) +#endif + void *RETROSHARE_PLUGIN_provide() + { + static FeedReaderPlugin *p = new FeedReaderPlugin(); + + return (void*)p; + } +} + +void FeedReaderPlugin::getPluginVersion(int& major,int& minor,int& svn_rev) const +{ + major = 5; + minor = 1; + svn_rev = 4350; +} + +FeedReaderPlugin::FeedReaderPlugin() +{ + mainpage = NULL ; + mIcon = NULL ; + mPlugInHandler = NULL; + mFeedReader = NULL; +} + +void FeedReaderPlugin::setInterfaces(RsPlugInInterfaces &/*interfaces*/) +{ +} + +ConfigPage *FeedReaderPlugin::qt_config_page() const +{ + return new FeedReaderConfig(); +} + +MainPage *FeedReaderPlugin::qt_page() const +{ + if (mainpage == NULL) { + mainpage = new FeedReaderDialog(mFeedReader); + } + + return mainpage; +} + +RsPQIService *FeedReaderPlugin::rs_pqi_service() const +{ + if (mFeedReader == NULL) { + mFeedReader = new p3FeedReader(mPlugInHandler); + rsFeedReader = mFeedReader; + } + + return mFeedReader; +} + +void FeedReaderPlugin::stop() +{ + if (mFeedReader) { + mFeedReader->stop(); + } +} + +void FeedReaderPlugin::setPlugInHandler(RsPluginHandler *pgHandler) +{ + mPlugInHandler = pgHandler; +} + +QIcon *FeedReaderPlugin::qt_icon() const +{ + if (mIcon == NULL) { + Q_INIT_RESOURCE(FeedReader_images); + + mIcon = new QIcon(IMAGE_FEEDREADER); + } + + return mIcon; +} + +std::string FeedReaderPlugin::getShortPluginDescription() const +{ + return QApplication::translate("FeedReaderPlugin", "This plugin provides a Feedreader.").toUtf8().constData(); +} + +std::string FeedReaderPlugin::getPluginName() const +{ + return QApplication::translate("FeedReaderPlugin", "FeedReader").toUtf8().constData(); +} + +QTranslator* FeedReaderPlugin::qt_translator(QApplication */*app*/, const QString& languageCode) const +{ + if (languageCode == "en") { + return NULL; + } + + QTranslator* translator = new QTranslator(); + if (translator->load(":/lang/FeedReader_" + languageCode + ".qm")) { + return translator; + } + + delete(translator); + return NULL; +} diff --git a/plugins/FeedReader/FeedReaderPlugin.h b/plugins/FeedReader/FeedReaderPlugin.h new file mode 100644 index 000000000..dffcfa7b4 --- /dev/null +++ b/plugins/FeedReader/FeedReaderPlugin.h @@ -0,0 +1,60 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#pragma once + +#include +#include +#include "services/p3FeedReader.h" + +class p3FeedReader; +class RsForums; + +class FeedReaderPlugin: public RsPlugin +{ +public: + FeedReaderPlugin(); + + virtual uint16_t rs_service_id() const { return RS_PKT_TYPE_FEEDREADER_CONFIG; } + virtual RsPQIService *rs_pqi_service() const; + virtual void stop(); + + virtual MainPage *qt_page() const; + virtual QIcon *qt_icon() const; + virtual QTranslator *qt_translator(QApplication *app, const QString &languageCode) const; + + virtual void getPluginVersion(int &major, int &minor, int &svn_rev) const; + virtual void setPlugInHandler(RsPluginHandler *pgHandler); + + virtual std::string configurationFileName() const { return "feedreader.cfg" ; } + + virtual std::string getShortPluginDescription() const; + virtual std::string getPluginName() const; + virtual void setInterfaces(RsPlugInInterfaces& interfaces); + virtual ConfigPage *qt_config_page() const; + +private: + mutable p3FeedReader *mFeedReader; + mutable RsPluginHandler *mPlugInHandler; + mutable MainPage *mainpage; + mutable QIcon *mIcon; +}; + diff --git a/plugins/FeedReader/gui/AddFeedDialog.cpp b/plugins/FeedReader/gui/AddFeedDialog.cpp new file mode 100644 index 000000000..5013eaf5a --- /dev/null +++ b/plugins/FeedReader/gui/AddFeedDialog.cpp @@ -0,0 +1,299 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include +#include +#include + +#include "AddFeedDialog.h" +#include "ui_AddFeedDialog.h" +#include "retroshare/rsforums.h" + +bool sortForumInfo(const ForumInfo& info1, const ForumInfo& info2) +{ + return QString::fromStdWString(info1.forumName).compare(QString::fromStdWString(info2.forumName), Qt::CaseInsensitive); +} + +AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, QWidget *parent) + : QDialog(parent), mFeedReader(feedReader), ui(new Ui::AddFeedDialog) +{ + ui->setupUi(this); + + connect(ui->buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(createFeed())); + connect(ui->buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); + + connect(ui->useAuthenticationCheckBox, SIGNAL(toggled(bool)), this, SLOT(authenticationToggled())); + connect(ui->useStandardStorageTimeCheckBox, SIGNAL(toggled(bool)), this, SLOT(useStandardStorageTimeToggled())); + connect(ui->useStandardUpdateInterval, SIGNAL(toggled(bool)), this, SLOT(useStandardUpdateIntervalToggled())); + connect(ui->useStandardProxyCheckBox, SIGNAL(toggled(bool)), this, SLOT(useStandardProxyToggled())); + connect(ui->typeForumRadio, SIGNAL(toggled(bool)), this, SLOT(typeForumToggled())); + + connect(ui->urlLineEdit, SIGNAL(textChanged(QString)), this, SLOT(validate())); + connect(ui->nameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(validate())); + connect(ui->useInfoFromFeedCheckBox, SIGNAL(toggled(bool)), this, SLOT(validate())); + + ui->activatedCheckBox->setChecked(true); + ui->typeLocalRadio->setChecked(true); + ui->forumComboBox->setEnabled(false); + ui->useInfoFromFeedCheckBox->setChecked(true); + ui->updateForumInfoCheckBox->setEnabled(false); + ui->updateForumInfoCheckBox->setChecked(true); + ui->forumNameLabel->hide(); + ui->useAuthenticationCheckBox->setChecked(false); + ui->useStandardStorageTimeCheckBox->setChecked(true); + ui->useStandardUpdateInterval->setChecked(true); + ui->useStandardProxyCheckBox->setChecked(true); + + /* not yet supported */ + ui->authenticationGroupBox->setEnabled(false); + + /* fill own forums */ + std::list forumList; + if (rsForums->getForumList(forumList)) { + forumList.sort(sortForumInfo); + for (std::list::iterator it = forumList.begin(); it != forumList.end(); ++it) { + ForumInfo &forumInfo = *it; + /* show only own anonymous forums */ + if ((forumInfo.subscribeFlags & RS_DISTRIB_ADMIN) && (forumInfo.forumFlags & RS_DISTRIB_AUTHEN_ANON)) { + ui->forumComboBox->addItem(QString::fromStdWString(forumInfo.forumName), QString::fromStdString(forumInfo.forumId)); + } + } + } + /* insert item to create a new forum */ + ui->forumComboBox->insertItem(0, tr("Create a new anonymous public forum"), ""); + ui->forumComboBox->setCurrentIndex(0); + + validate(); + + ui->urlLineEdit->setFocus(); +} + +AddFeedDialog::~AddFeedDialog() +{ + delete ui; +} + +void AddFeedDialog::authenticationToggled() +{ + bool checked = ui->useAuthenticationCheckBox->isChecked(); + ui->userLineEdit->setEnabled(checked); + ui->passwordLineEdit->setEnabled(checked); +} + +void AddFeedDialog::useStandardStorageTimeToggled() +{ + bool checked = ui->useStandardStorageTimeCheckBox->isChecked(); + ui->storageTimeSpinBox->setEnabled(!checked); +} + +void AddFeedDialog::useStandardUpdateIntervalToggled() +{ + bool checked = ui->useStandardUpdateInterval->isChecked(); + ui->updateIntervalSpinBox->setEnabled(!checked); +} + +void AddFeedDialog::useStandardProxyToggled() +{ + bool checked = ui->useStandardProxyCheckBox->isChecked(); + ui->proxyAddressLineEdit->setEnabled(!checked); + ui->proxyPortSpinBox->setEnabled(!checked); +} + +void AddFeedDialog::typeForumToggled() +{ + bool checked = ui->typeForumRadio->isChecked(); + ui->forumComboBox->setEnabled(checked); + ui->updateForumInfoCheckBox->setEnabled(checked); +} + +void AddFeedDialog::validate() +{ + bool ok = true; + + if (ui->urlLineEdit->text().isEmpty()) { + ok = false; + } + if (ui->nameLineEdit->text().isEmpty() && !ui->useInfoFromFeedCheckBox->isChecked()) { + ok = false; + } + + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(ok); +} + +bool AddFeedDialog::showError(QWidget *parent, RsFeedAddResult result, const QString &title, const QString &text) +{ + QString error; + + switch (result) { + case RS_FEED_ADD_RESULT_SUCCESS: + /* no error */ + return false; + case RS_FEED_ADD_RESULT_FEED_NOT_FOUND: + error = tr("Feed not found."); + break; + case RS_FEED_ADD_RESULT_PARENT_NOT_FOUND: + error = tr("Parent not found."); + break; + case RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER: + error = tr("Parent is no folder."); + break; + case RS_FEED_ADD_RESULT_FEED_IS_FOLDER: + error = tr("Feed is a folder."); + break; + case RS_FEED_ADD_RESULT_FEED_IS_NO_FOLDER: + error = tr("Feed is no folder."); + break; + default: + error = tr("Unknown error occured."); + } + + QMessageBox::critical(parent, title, text + "\n" + error); + + return true; +} + +void AddFeedDialog::setParent(const std::string &parentId) +{ + mParentId = parentId; +} + +bool AddFeedDialog::fillFeed(const std::string &feedId) +{ + mFeedId = feedId; + + if (!mFeedId.empty()) { + FeedInfo feedInfo; + if (!mFeedReader->getFeedInfo(mFeedId, feedInfo)) { + mFeedId.clear(); + return false; + } + + setWindowTitle(tr("Edit feed")); + ui->typeGroupBox->setEnabled(false); + + mParentId = feedInfo.parentId; + + ui->nameLineEdit->setText(QString::fromUtf8(feedInfo.name.c_str())); + ui->urlLineEdit->setText(QString::fromUtf8(feedInfo.url.c_str())); + ui->useInfoFromFeedCheckBox->setChecked(feedInfo.flag.infoFromFeed); + ui->updateForumInfoCheckBox->setChecked(feedInfo.flag.updateForumInfo); + ui->activatedCheckBox->setChecked(!feedInfo.flag.deactivated); + + ui->descriptionPlainTextEdit->setPlainText(QString::fromUtf8(feedInfo.description.c_str())); + + ui->typeGroupBox->setEnabled(false); + ui->forumComboBox->hide(); + ui->forumNameLabel->clear(); + ui->forumNameLabel->show(); + + if (feedInfo.flag.forum) { + ui->typeForumRadio->setChecked(true); + + if (feedInfo.forumId.empty()) { + ui->forumNameLabel->setText(tr("Not yet created")); + } else { + ForumInfo forumInfo; + if (rsForums->getForumInfo(feedInfo.forumId, forumInfo)) { + ui->forumNameLabel->setText(QString::fromStdWString(forumInfo.forumName)); + } else { + ui->forumNameLabel->setText(tr("Unknown forum")); + } + } + } else { + ui->typeLocalRadio->setChecked(true); + } + + ui->useAuthenticationCheckBox->setChecked(feedInfo.flag.authentication); + ui->userLineEdit->setText(QString::fromUtf8(feedInfo.user.c_str())); + ui->passwordLineEdit->setText(QString::fromUtf8(feedInfo.password.c_str())); + + ui->useStandardProxyCheckBox->setChecked(feedInfo.flag.standardProxy); + ui->proxyAddressLineEdit->setText(QString::fromUtf8(feedInfo.proxyAddress.c_str())); + ui->proxyPortSpinBox->setValue(feedInfo.proxyPort); + + ui->useStandardUpdateInterval->setChecked(feedInfo.flag.standardUpdateInterval); + ui->updateIntervalSpinBox->setValue(feedInfo.updateInterval / 60); + QDateTime dateTime; + dateTime.setTime_t(feedInfo.lastUpdate); + ui->lastUpdate->setText(dateTime.toString()); + + ui->useStandardStorageTimeCheckBox->setChecked(feedInfo.flag.standardStorageTime); + ui->storageTimeSpinBox->setValue(feedInfo.storageTime / (60 * 60 *24)); + } + + return true; +} + +void AddFeedDialog::createFeed() +{ + FeedInfo feedInfo; + if (!mFeedId.empty()) { + if (!mFeedReader->getFeedInfo(mFeedId, feedInfo)) { + QMessageBox::critical(this, tr("Edit feed"), tr("Can't edit feed. Feed does not exist.")); + return; + } + } + + feedInfo.parentId = mParentId; + + feedInfo.name = ui->nameLineEdit->text().toUtf8().constData(); + feedInfo.url = ui->urlLineEdit->text().toUtf8().constData(); + feedInfo.flag.infoFromFeed = ui->useInfoFromFeedCheckBox->isChecked(); + feedInfo.flag.updateForumInfo = ui->updateForumInfoCheckBox->isChecked() && ui->updateForumInfoCheckBox->isEnabled(); + feedInfo.flag.deactivated = !ui->activatedCheckBox->isChecked(); + + feedInfo.description = ui->descriptionPlainTextEdit->toPlainText().toUtf8().constData(); + + feedInfo.flag.forum = ui->typeForumRadio->isChecked(); + if (mFeedId.empty()) { + /* set forum (only when create a new feed) */ + feedInfo.forumId = ui->forumComboBox->itemData(ui->forumComboBox->currentIndex()).toString().toStdString(); + } + + feedInfo.flag.authentication = ui->useAuthenticationCheckBox->isChecked(); + feedInfo.user = ui->userLineEdit->text().toUtf8().constData(); + feedInfo.password = ui->passwordLineEdit->text().toUtf8().constData(); + + feedInfo.flag.standardProxy = ui->useStandardProxyCheckBox->isChecked(); + feedInfo.proxyAddress = ui->proxyAddressLineEdit->text().toUtf8().constData(); + feedInfo.proxyPort = ui->proxyPortSpinBox->value(); + + feedInfo.flag.standardUpdateInterval = ui->useStandardUpdateInterval->isChecked(); + feedInfo.updateInterval = ui->updateIntervalSpinBox->value() * 60; + + feedInfo.flag.standardStorageTime = ui->useStandardStorageTimeCheckBox->isChecked(); + feedInfo.storageTime = ui->storageTimeSpinBox->value() * 60 *60 * 24; + + if (mFeedId.empty()) { + /* add new feed */ + RsFeedAddResult result = mFeedReader->addFeed(feedInfo, mFeedId); + if (showError(this, result, tr("Create feed"), tr("Cannot create feed."))) { + return; + } + } else { + RsFeedAddResult result = mFeedReader->setFeed(mFeedId, feedInfo); + if (showError(this, result, tr("Edit feed"), tr("Cannot change feed."))) { + return; + } + } + + close(); +} diff --git a/plugins/FeedReader/gui/AddFeedDialog.h b/plugins/FeedReader/gui/AddFeedDialog.h new file mode 100644 index 000000000..c117cd789 --- /dev/null +++ b/plugins/FeedReader/gui/AddFeedDialog.h @@ -0,0 +1,64 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#ifndef ADDFEEDDIALOG_H +#define ADDFEEDDIALOG_H + +#include +#include "interface/rsFeedReader.h" + +namespace Ui { +class AddFeedDialog; +} + +class RsFeedReader; + +class AddFeedDialog : public QDialog +{ + Q_OBJECT + +public: + AddFeedDialog(RsFeedReader *feedReader, QWidget *parent); + ~AddFeedDialog(); + + static bool showError(QWidget *parent, RsFeedAddResult result, const QString &title, const QString &text); + + void setParent(const std::string &parentId); + bool fillFeed(const std::string &feedId); + +private slots: + void authenticationToggled(); + void useStandardStorageTimeToggled(); + void useStandardUpdateIntervalToggled(); + void useStandardProxyToggled(); + void typeForumToggled(); + void validate(); + void createFeed(); + +private: + RsFeedReader *mFeedReader; + std::string mFeedId; + std::string mParentId; + + Ui::AddFeedDialog *ui; +}; + +#endif // ADDFEEDDIALOG_H diff --git a/plugins/FeedReader/gui/AddFeedDialog.ui b/plugins/FeedReader/gui/AddFeedDialog.ui new file mode 100644 index 000000000..ed2587dfa --- /dev/null +++ b/plugins/FeedReader/gui/AddFeedDialog.ui @@ -0,0 +1,442 @@ + + + AddFeedDialog + + + + 0 + 0 + 715 + 559 + + + + Create new feed + + + + :/images/rstray3.png:/images/rstray3.png + + + + 0 + + + 0 + + + + + + 16777215 + 64 + + + + QFrame#headerFrame{background-image: url(:/images/connect/connectFriendBanner.png);} + + + QFrame::NoFrame + + + QFrame::Raised + + + + 6 + + + 6 + + + + + + 48 + 48 + + + + + + + + + + :/images/FeedReader.png + + + true + + + + + + + color: rgb(255, 255, 255); + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Arial'; font-size:24pt; font-weight:600; color:#ffffff;">Feed Details</span></p></body></html> + + + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + + + Authentication (not yet supported) + + + + + + Feed needs authentication + + + + + + + User + + + + + + + Password + + + + + + + + + + QLineEdit::Password + + + + + + + + + + Update interval + + + + + + Use standard update interval + + + + + + + Interval in minutes (0 = manual) + + + + + + + + 50 + 16777215 + + + + + + + + + + Last update + + + + + + + + 0 + 0 + + + + Never + + + + + + + + + + + + Storage time + + + + + + Use standard storage time + + + + + + + Days (0 = off) + + + + + + + + 50 + 16777215 + + + + 999999999 + + + + + + + + + + Proxy + + + + + + Use standard proxy + + + + + + + Server + + + + + + + + + + : + + + + + + + 65535 + + + + + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + Type + + + + 6 + + + + + Local Feed + + + + + + + + + Forum + + + + + + + + + + + 0 + 0 + + + + Forum name + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + Misc + + + + + + Activated + + + + + + + Use name and description from feed + + + + + + + Update forum information + + + + + + + + + + + + Description: + + + + + + + + + + + + + + RSS-Feed-URL: + + + + + + + + + + Name: + + + + + + + + + + + + + + + urlLineEdit + nameLineEdit + descriptionPlainTextEdit + typeLocalRadio + typeForumRadio + forumComboBox + activatedCheckBox + useInfoFromFeedCheckBox + updateForumInfoCheckBox + useAuthenticationCheckBox + userLineEdit + passwordLineEdit + useStandardStorageTimeCheckBox + storageTimeSpinBox + useStandardUpdateInterval + updateIntervalSpinBox + useStandardProxyCheckBox + proxyAddressLineEdit + proxyPortSpinBox + buttonBox + + + + + + + diff --git a/plugins/FeedReader/gui/FeedReaderConfig.cpp b/plugins/FeedReader/gui/FeedReaderConfig.cpp new file mode 100644 index 000000000..2b9102c9c --- /dev/null +++ b/plugins/FeedReader/gui/FeedReaderConfig.cpp @@ -0,0 +1,80 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include "FeedReaderConfig.h" +#include "ui_FeedReaderConfig.h" +#include "gui/settings/rsharesettings.h" +#include "interface/rsFeedReader.h" + +/** Constructor */ +FeedReaderConfig::FeedReaderConfig(QWidget *parent, Qt::WFlags flags) + : ConfigPage(parent, flags), ui(new Ui::FeedReaderConfig) +{ + /* Invoke the Qt Designer generated object setup routine */ + ui->setupUi(this); + + connect(ui->useProxyCheckBox, SIGNAL(toggled(bool)), this, SLOT(useProxyToggled())); + + ui->proxyAddressLineEdit->setEnabled(false); + ui->proxyPortSpinBox->setEnabled(false); + + loaded = false; +} + +/** Destructor */ +FeedReaderConfig::~FeedReaderConfig() +{ + delete(ui); +} + +/** Loads the settings for this page */ +void FeedReaderConfig::load() +{ + ui->updateIntervalSpinBox->setValue(rsFeedReader->getStandardUpdateInterval() / 60); + ui->storageTimeSpinBox->setValue(rsFeedReader->getStandardStorageTime() / (60 * 60 *24)); + ui->setMsgToReadOnActivate->setChecked(Settings->valueFromGroup("FeedReaderDialog", "SetMsgToReadOnActivate", true).toBool()); + + std::string proxyAddress; + uint16_t proxyPort; + ui->useProxyCheckBox->setChecked(rsFeedReader->getStandardProxy(proxyAddress, proxyPort)); + ui->proxyAddressLineEdit->setText(QString::fromUtf8(proxyAddress.c_str())); + ui->proxyPortSpinBox->setValue(proxyPort); + + loaded = true; +} + +bool FeedReaderConfig::save(QString &/*errmsg*/) +{ + rsFeedReader->setStandardUpdateInterval(ui->updateIntervalSpinBox->value() * 60); + rsFeedReader->setStandardStorageTime(ui->storageTimeSpinBox->value() * 60 *60 * 24); + rsFeedReader->setStandardProxy(ui->useProxyCheckBox->isChecked(), ui->proxyAddressLineEdit->text().toUtf8().constData(), ui->proxyPortSpinBox->value()); + Settings->setValueToGroup("FeedReaderDialog", "SetMsgToReadOnActivate", ui->setMsgToReadOnActivate->isChecked()); + + return true; +} + +void FeedReaderConfig::useProxyToggled() +{ + bool enabled = ui->useProxyCheckBox->isChecked(); + + ui->proxyAddressLineEdit->setEnabled(enabled); + ui->proxyPortSpinBox->setEnabled(enabled); +} diff --git a/plugins/FeedReader/gui/FeedReaderConfig.h b/plugins/FeedReader/gui/FeedReaderConfig.h new file mode 100644 index 000000000..ed846269a --- /dev/null +++ b/plugins/FeedReader/gui/FeedReaderConfig.h @@ -0,0 +1,57 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#ifndef _FEEDREADERCONFIG_H +#define _FEEDREADERCONFIG_H + +#include "retroshare-gui/configpage.h" + +namespace Ui { +class FeedReaderConfig; +} + +class FeedReaderConfig : public ConfigPage +{ + Q_OBJECT + +public: + /** Default Constructor */ + FeedReaderConfig(QWidget *parent = 0, Qt::WFlags flags = 0); + /** Default Destructor */ + virtual ~FeedReaderConfig(); + + /** Saves the changes on this page */ + virtual bool save(QString &errmsg); + /** Loads the settings for this page */ + virtual void load(); + + virtual QPixmap iconPixmap() const { return QPixmap(":/images/FeedReader.png") ; } + virtual QString pageName() const { return tr("FeedReader") ; } + +private slots: + void useProxyToggled(); + +private: + Ui::FeedReaderConfig *ui; + bool loaded; +}; + +#endif diff --git a/plugins/FeedReader/gui/FeedReaderConfig.ui b/plugins/FeedReader/gui/FeedReaderConfig.ui new file mode 100644 index 000000000..36deae46b --- /dev/null +++ b/plugins/FeedReader/gui/FeedReaderConfig.ui @@ -0,0 +1,148 @@ + + + FeedReaderConfig + + + + 0 + 0 + 508 + 378 + + + + Form + + + + + + Update + + + + + + Interval in minutes (0 = manual) + + + + + + + + 50 + 16777215 + + + + 999999999 + + + + + + + + + + Storage time + + + + + + Days (0 = off) + + + + + + + + 50 + 16777215 + + + + 999999999 + + + + + + + + + + Proxy + + + + + + Use proxy + + + + + + + Server + + + + + + + + + + 65535 + + + + + + + : + + + + + + + + + + Misc + + + + + + Set message to read on activate + + + + + + + + + + Qt::Vertical + + + + 20 + 301 + + + + + + + + + diff --git a/plugins/FeedReader/gui/FeedReaderDialog.cpp b/plugins/FeedReader/gui/FeedReaderDialog.cpp new file mode 100644 index 000000000..15f6baa24 --- /dev/null +++ b/plugins/FeedReader/gui/FeedReaderDialog.cpp @@ -0,0 +1,1088 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "FeedReaderDialog.h" +#include "ui_FeedReaderDialog.h" +#include "FeedReaderNotify.h" +#include "AddFeedDialog.h" +#include "gui/common/RSTreeWidgetItem.h" +#include "util/HandleRichText.h" +#include "gui/settings/rsharesettings.h" +#include "interface/rsFeedReader.h" +#include "retroshare/rsiface.h" + +#define COLUMN_FEED_COUNT 1 +#define COLUMN_FEED_NAME 0 +#define COLUMN_FEED_DATA 0 + +#define ROLE_FEED_ID Qt::UserRole +#define ROLE_FEED_SORT Qt::UserRole + 1 +#define ROLE_FEED_FOLDER Qt::UserRole + 2 +#define ROLE_FEED_UNREAD Qt::UserRole + 3 +#define ROLE_FEED_NAME Qt::UserRole + 4 +#define ROLE_FEED_WORKSTATE Qt::UserRole + 5 +#define ROLE_FEED_LOADING Qt::UserRole + 6 +#define ROLE_FEED_ICON Qt::UserRole + 7 +#define ROLE_FEED_ERROR Qt::UserRole + 8 +#define ROLE_FEED_DEACTIVATED Qt::UserRole + 9 + +#define COLUMN_MSG_COUNT 4 +#define COLUMN_MSG_TITLE 0 +#define COLUMN_MSG_READ 1 +#define COLUMN_MSG_PUBDATE 2 +#define COLUMN_MSG_AUTHOR 3 +#define COLUMN_MSG_DATA 0 + +#define ROLE_MSG_ID Qt::UserRole +#define ROLE_MSG_SORT Qt::UserRole + 1 +#define ROLE_MSG_NEW Qt::UserRole + 2 +#define ROLE_MSG_READ Qt::UserRole + 3 +#define ROLE_MSG_LINK Qt::UserRole + 4 + +static int filterColumnToComboBox(int nIndex) +{ + switch (nIndex) { + case COLUMN_MSG_TITLE: + return 0; + case COLUMN_MSG_PUBDATE: + return 1; + case COLUMN_MSG_AUTHOR: + return 2; + } + + return filterColumnToComboBox(COLUMN_MSG_TITLE); +} + +static int filterColumnFromComboBox(int nIndex) +{ + switch (nIndex) { + case 0: + return COLUMN_MSG_TITLE; + case 1: + return COLUMN_MSG_PUBDATE; + case 2: + return COLUMN_MSG_AUTHOR; + } + + return COLUMN_MSG_TITLE; +} + +FeedReaderDialog::FeedReaderDialog(RsFeedReader *feedReader, QWidget *parent) + : MainPage(parent), mFeedReader(feedReader), ui(new Ui::FeedReaderDialog) +{ + /* Invoke the Qt Designer generated object setup routine */ + ui->setupUi(this); + + mNotify = new FeedReaderNotify(); + mFeedReader->setNotify(mNotify); + connect(mNotify, SIGNAL(notifyFeedChanged(QString,int)), this, SLOT(feedChanged(QString,int))); + connect(mNotify, SIGNAL(notifyMsgChanged(QString,QString,int)), this, SLOT(msgChanged(QString,QString,int))); + + mProcessSettings = false; + + /* connect signals */ + connect(ui->feedTreeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(feedItemChanged(QTreeWidgetItem*))); + connect(ui->msgTreeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(msgItemChanged())); + connect(ui->msgTreeWidget, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(msgItemClicked(QTreeWidgetItem*,int))); + + connect(ui->feedTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(feedTreeCustomPopupMenu(QPoint))); + connect(ui->msgTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(msgTreeCustomPopupMenu(QPoint))); + + connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterItems(QString))); + connect(ui->filterColumnComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterColumnChanged())); + + connect(ui->expandButton, SIGNAL(clicked()), this, SLOT(toggleMsgText())); + + mFeedCompareRole = new RSTreeWidgetItemCompareRole; + mFeedCompareRole->setRole(COLUMN_FEED_NAME, ROLE_FEED_SORT); + + mMsgCompareRole = new RSTreeWidgetItemCompareRole; + mMsgCompareRole->setRole(COLUMN_MSG_TITLE, ROLE_MSG_SORT); + mMsgCompareRole->setRole(COLUMN_MSG_READ, ROLE_MSG_SORT); + mMsgCompareRole->setRole(COLUMN_MSG_PUBDATE, ROLE_MSG_SORT); + mMsgCompareRole->setRole(COLUMN_MSG_AUTHOR, ROLE_MSG_SORT); + + /* initialize root item */ + mRootItem = new QTreeWidgetItem(ui->feedTreeWidget); + QString name = tr("Message Folders"); + mRootItem->setText(COLUMN_FEED_NAME, name); + mRootItem->setIcon(COLUMN_FEED_NAME, QIcon(":/images/Root.png")); + mRootItem->setData(COLUMN_FEED_DATA, ROLE_FEED_NAME, name); + mRootItem->setData(COLUMN_FEED_DATA, ROLE_FEED_FOLDER, true); + mRootItem->setData(COLUMN_FEED_DATA, ROLE_FEED_ICON, QIcon(":/images/Root.png")); + mRootItem->setExpanded(true); + + /* initialize msg list */ + ui->msgTreeWidget->sortItems(COLUMN_MSG_PUBDATE, Qt::DescendingOrder); + + /* set initial size the splitter */ + QList sizes; + sizes << 300 << width(); // Qt calculates the right sizes + ui->splitter->setSizes(sizes); + + /* set header resize modes and initial section sizes */ + QHeaderView *header = ui->msgTreeWidget->header(); + header->setResizeMode(COLUMN_MSG_TITLE, QHeaderView::Interactive); + header->resizeSection(COLUMN_MSG_TITLE, 350); + header->resizeSection(COLUMN_MSG_PUBDATE, 140); + header->resizeSection(COLUMN_MSG_AUTHOR, 150); + + /* set text of column "Read" to empty - without this the column has a number as header text */ + QTreeWidgetItem *headerItem = ui->msgTreeWidget->headerItem(); + headerItem->setText(COLUMN_MSG_READ, ""); + + /* load settings */ + processSettings(true); + + /* Set header sizes for the fixed columns and resize modes, must be set after processSettings */ + header->resizeSection(COLUMN_MSG_READ, 24); + header->setResizeMode(COLUMN_MSG_READ, QHeaderView::Fixed); + + /* initialize feed list */ + ui->feedTreeWidget->sortItems(COLUMN_FEED_NAME, Qt::AscendingOrder); + + ui->msgTreeWidget->installEventFilter(this); +} + +FeedReaderDialog::~FeedReaderDialog() +{ + /* save settings */ + processSettings(false); + + delete(mFeedCompareRole); + delete(mMsgCompareRole); + delete(ui); + + mFeedReader->setNotify(NULL); + delete(mNotify); +} + +void FeedReaderDialog::processSettings(bool load) +{ + mProcessSettings = true; + + QHeaderView *header = ui->msgTreeWidget->header (); + + Settings->beginGroup(QString("FeedReaderDialog")); + + if (load) { + // load settings + + // expandButton + bool value = Settings->value("expandButton", true).toBool(); + ui->expandButton->setChecked(value); + toggleMsgText_internal(); + + // filterColumn + ui->filterColumnComboBox->setCurrentIndex(filterColumnToComboBox(Settings->value("filterColumn", COLUMN_MSG_TITLE).toInt())); + + // state of thread tree + header->restoreState(Settings->value("msgTree").toByteArray()); + + // state of splitter + ui->splitter->restoreState(Settings->value("Splitter").toByteArray()); + ui->msgSplitter->restoreState(Settings->value("msgSplitter").toByteArray()); + } else { + // save settings + + // state of thread tree + Settings->setValue("msgTree", header->saveState()); + + // state of splitter + Settings->setValue("Splitter", ui->splitter->saveState()); + Settings->setValue("msgSplitter", ui->msgSplitter->saveState()); + } + + Settings->endGroup(); + mProcessSettings = false; +} + +void FeedReaderDialog::showEvent(QShowEvent */*event*/) +{ + updateFeeds("", mRootItem); +} + +bool FeedReaderDialog::eventFilter(QObject *obj, QEvent *event) +{ + if (obj == ui->msgTreeWidget) { + if (event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(event); + if (keyEvent) { + if (keyEvent->key() == Qt::Key_Space) { + /* Space pressed */ + QTreeWidgetItem *item = ui->msgTreeWidget->currentItem(); + msgItemClicked(item, COLUMN_MSG_READ); + return true; // eat event + } + if (keyEvent->key() == Qt::Key_Delete) { + /* Delete pressed */ + removeMsg(); + return true; // eat event + } + } + } + } + if (obj == ui->feedTreeWidget) { + if (event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(event); + if (keyEvent) { + if (keyEvent->key() == Qt::Key_Delete) { + /* Delete pressed */ + removeFeed(); + return true; // eat event + } + } + } + } + /* pass the event on to the parent class */ + return MainPage::eventFilter(obj, event); +} + +std::string FeedReaderDialog::currentFeedId() +{ + QTreeWidgetItem *item = ui->feedTreeWidget->currentItem(); + if (!item) { + return ""; + } + + return item->data(COLUMN_FEED_DATA, ROLE_FEED_ID).toString().toStdString(); +} + +std::string FeedReaderDialog::currentMsgId() +{ + QTreeWidgetItem *item = ui->msgTreeWidget->currentItem(); + if (!item) { + return ""; + } + + return item->data(COLUMN_MSG_DATA, ROLE_MSG_ID).toString().toStdString(); +} + +void FeedReaderDialog::feedTreeCustomPopupMenu(QPoint /*point*/) +{ + QMenu contextMnu(this); + + bool folder = false; + QTreeWidgetItem *item = ui->feedTreeWidget->currentItem(); + if (item) { + folder = item->data(COLUMN_FEED_DATA, ROLE_FEED_FOLDER).toBool(); + } + + QMenu *menu = contextMnu.addMenu(QIcon(""), tr("New")); + QAction *action = menu->addAction(QIcon(":/images/FeedAdd.png"), tr("Feed"), this, SLOT(newFeed())); + if (!item || !folder) { + action->setEnabled(false); + } + action = menu->addAction(QIcon(":/images/FolderAdd.png"), tr("Folder"), this, SLOT(newFolder())); + if (!item || !folder) { + action->setEnabled(false); + } + + contextMnu.addSeparator(); + + action = contextMnu.addAction(QIcon(":/images/edit_16.png"), tr("Edit"), this, SLOT(editFeed())); + if (!item || item == mRootItem) { + action->setEnabled(false); + } + + action = contextMnu.addAction(QIcon(":/images/delete.png"), tr("Delete"), this, SLOT(removeFeed())); + if (!item || item == mRootItem) { + action->setEnabled(false); + } + + contextMnu.addSeparator(); + + bool deactivated = false; + if (!folder && item) { + deactivated = item->data(COLUMN_FEED_DATA, ROLE_FEED_DEACTIVATED).toBool(); + } + + action = contextMnu.addAction(QIcon(":/images/Update.png"), tr("Update"), this, SLOT(processFeed())); + action->setEnabled(!deactivated); + + action = contextMnu.addAction(QIcon(""), deactivated ? tr("Activate") : tr("Deactivate"), this, SLOT(activateFeed())); + if (!item || item == mRootItem || folder) { + action->setEnabled(false); + } + + contextMnu.exec(QCursor::pos()); +} + +void FeedReaderDialog::msgTreeCustomPopupMenu(QPoint /*point*/) +{ + QMenu contextMnu(this); + + QList selectedItems = ui->msgTreeWidget->selectedItems(); + + QAction *action = contextMnu.addAction(QIcon(""), tr("Mark as read"), this, SLOT(markAsReadMsg())); + action->setEnabled(!selectedItems.empty()); + + action = contextMnu.addAction(QIcon(""), tr("Mark as unread"), this, SLOT(markAsUnreadMsg())); + action->setEnabled(!selectedItems.empty()); + + action = contextMnu.addAction(QIcon(""), tr("Mark all as read"), this, SLOT(markAllAsReadMsg())); + + contextMnu.addSeparator(); + + action = contextMnu.addAction(QIcon(""), tr("Copy link"), this, SLOT(copyLinkMsg())); + action->setEnabled(!selectedItems.empty()); + + action = contextMnu.addAction(QIcon(""), tr("Remove"), this, SLOT(removeMsg())); + action->setEnabled(!selectedItems.empty()); + + contextMnu.exec(QCursor::pos()); +} + +void FeedReaderDialog::updateFeeds(const std::string &parentId, QTreeWidgetItem *parentItem) +{ + if (!parentItem) { + return; + } + + /* get feed infos */ + std::list feedInfos; + mFeedReader->getFeedList(parentId, feedInfos); + + int index = 0; + QTreeWidgetItem *item; + std::list::iterator feedIt; + + /* update existing and delete not existing feeds */ + while (index < parentItem->childCount()) { + item = parentItem->child(index); + std::string feedId = item->data(COLUMN_FEED_DATA, ROLE_FEED_ID).toString().toStdString(); + + /* search existing feed */ + int found = -1; + for (feedIt = feedInfos.begin (); feedIt != feedInfos.end (); ++feedIt) { + if (feedIt->feedId == feedId) { + /* found it, update it */ + updateFeedItem(item, *feedIt); + + if (feedIt->flag.folder) { + /* process child feeds */ + updateFeeds(feedIt->feedId, item); + } + + feedInfos.erase(feedIt); + found = index; + break; + } + } + if (found >= 0) { + ++index; + } else { + delete(parentItem->takeChild(index)); + } + } + + /* add new feeds */ + for (feedIt = feedInfos.begin (); feedIt != feedInfos.end (); ++feedIt) { + item = new RSTreeWidgetItem(mFeedCompareRole); + parentItem->addChild(item); + updateFeedItem(item, *feedIt); + + if (feedIt->flag.folder) { + /* process child feeds */ + updateFeeds(feedIt->feedId, item); + } + } + calculateFeedItems(); +} + +void FeedReaderDialog::calculateFeedItem(QTreeWidgetItem *item, uint32_t &unreadCount, bool &loading) +{ + uint32_t unreadCountItem = 0; + bool loadingItem = false; + + if (item->data(COLUMN_FEED_DATA, ROLE_FEED_FOLDER).toBool()) { + int childCount = item->childCount(); + for (int index = 0; index < childCount; ++index) { + calculateFeedItem(item->child(index), unreadCountItem, loadingItem); + } + } else { + unreadCountItem = item->data(COLUMN_FEED_DATA, ROLE_FEED_UNREAD).toUInt(); + loadingItem = item->data(COLUMN_FEED_DATA, ROLE_FEED_LOADING).toBool(); + } + + unreadCount += unreadCountItem; + loading = loading || loadingItem; + + QString name = item->data(COLUMN_FEED_DATA, ROLE_FEED_NAME).toString(); + QString workState = item->data(COLUMN_FEED_DATA, ROLE_FEED_WORKSTATE).toString(); + + if (unreadCountItem) { + name += QString(" (%1)").arg(unreadCountItem); + } + if (!workState.isEmpty()) { + name += QString(" (%1)").arg(workState); + } + + item->setText(COLUMN_FEED_NAME, name); + + bool deactivated = item->data(COLUMN_FEED_DATA, ROLE_FEED_DEACTIVATED).toBool(); + + QColor colorActivated; + QColor colorDeactivated = QColor(Qt::gray); + for (int i = 0; i < COLUMN_FEED_COUNT; i++) { + QFont font = item->font(i); + font.setBold(unreadCountItem != 0); + item->setFont(i, font); + + item->setTextColor(COLUMN_FEED_NAME, deactivated ? colorDeactivated : colorActivated); + } + + QIcon icon = item->data(COLUMN_FEED_DATA, ROLE_FEED_ICON).value(); + + if (deactivated) { + /* create disabled icon */ + icon = icon.pixmap(QSize(16, 16), QIcon::Disabled); + } + + QImage overlayIcon; + if (loadingItem) { + /* overlaying icon */ + overlayIcon = QImage(":/images/FeedProcessOverlay.png"); + } else if (item->data(COLUMN_FEED_DATA, ROLE_FEED_ERROR).toBool()) { + overlayIcon = QImage(":/images/FeedErrorOverlay.png"); + } + if (!overlayIcon.isNull()) { + if (icon.isNull()) { + icon = QPixmap::fromImage(overlayIcon); + } else { + QPixmap pixmap = icon.pixmap(QSize(16, 16)); + QPainter painter(&pixmap); + painter.drawImage(0, 0, overlayIcon.scaled(pixmap.size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + painter.end(); + icon = pixmap; + } + } + + item->setIcon(COLUMN_FEED_NAME, icon); +} + +void FeedReaderDialog::calculateFeedItems() +{ + uint32_t unreadCount = 0; + bool loading = false; + + calculateFeedItem(mRootItem, unreadCount, loading); + ui->feedTreeWidget->sortItems(COLUMN_FEED_NAME, Qt::AscendingOrder); +} + +void FeedReaderDialog::updateFeedItem(QTreeWidgetItem *item, FeedInfo &info) +{ + QString workState; + + QIcon icon; + if (info.flag.folder) { + /* use folder icon */ + icon = QIcon(":/images/Folder.png"); + } else { + long todo; // show icon from feed +// if (info.icon.empty()) { + /* use standard icon */ + icon = QIcon(":/images/Feed.png"); +// } else { +// /* use icon from feed */ +// icon = QIcon(QPixmap::fromImage(QImage((uchar*) QByteArray::fromBase64(info.icon.c_str()).constData(), 16, 16, QImage::Format_RGB32))); +// } + } + + item->setData(COLUMN_FEED_DATA, ROLE_FEED_ICON, icon); + + switch (info.workstate) { + case FeedInfo::WAITING: + break; + case FeedInfo::WAITING_TO_DOWNLOAD: + case FeedInfo::DOWNLOADING: + workState = tr("loading"); + break; + case FeedInfo::WAITING_TO_PROCESS: + case FeedInfo::PROCESSING: + workState = tr("processing"); + break; + } + + QString name = QString::fromUtf8(info.name.c_str()); + item->setData(COLUMN_FEED_DATA, ROLE_FEED_NAME, name.isEmpty() ? tr("No name") : name); + item->setData(COLUMN_FEED_DATA, ROLE_FEED_WORKSTATE, workState); + + uint32_t unreadCount; + mFeedReader->getMessageCount(info.feedId, NULL, NULL, &unreadCount); + + item->setData(COLUMN_FEED_NAME, ROLE_FEED_SORT, QString("%1_%2").arg(QString(info.flag.folder ? "0" : "1"), name)); + item->setData(COLUMN_FEED_DATA, ROLE_FEED_UNREAD, unreadCount); + item->setData(COLUMN_FEED_DATA, ROLE_FEED_LOADING, info.workstate != FeedInfo::WAITING); + item->setData(COLUMN_FEED_DATA, ROLE_FEED_ID, QString::fromStdString(info.feedId)); + item->setData(COLUMN_FEED_DATA, ROLE_FEED_FOLDER, info.flag.folder); + item->setData(COLUMN_FEED_DATA, ROLE_FEED_DEACTIVATED, info.flag.deactivated); + item->setData(COLUMN_FEED_DATA, ROLE_FEED_ERROR, info.error); + item->setToolTip(COLUMN_FEED_NAME, info.error ? QString::fromUtf8(info.errorString.c_str()) : ""); +} + +void FeedReaderDialog::updateMsgs(const std::string &feedId) +{ + std::list msgInfos; + if (!mFeedReader->getFeedMsgList(feedId, msgInfos)) { + ui->msgTreeWidget->clear(); + return; + } + + int index = 0; + QTreeWidgetItem *item; + std::list::iterator msgIt; + + /* update existing and delete not existing msgs */ + while (index < ui->msgTreeWidget->topLevelItemCount()) { + item = ui->msgTreeWidget->topLevelItem(index); + std::string msgId = item->data(COLUMN_MSG_DATA, ROLE_MSG_ID).toString().toStdString(); + + /* search existing msg */ + int found = -1; + for (msgIt = msgInfos.begin (); msgIt != msgInfos.end (); ++msgIt) { + if (msgIt->msgId == msgId) { + /* found it, update it */ + updateMsgItem(item, *msgIt); + + msgInfos.erase(msgIt); + found = index; + break; + } + } + if (found >= 0) { + ++index; + } else { + delete(ui->msgTreeWidget->takeTopLevelItem(index)); + } + } + + /* add new msgs */ + for (msgIt = msgInfos.begin (); msgIt != msgInfos.end (); ++msgIt) { + item = new RSTreeWidgetItem(mMsgCompareRole); + updateMsgItem(item, *msgIt); + ui->msgTreeWidget->addTopLevelItem(item); + } + + filterItems(ui->filterLineEdit->text()); +} + +void FeedReaderDialog::calculateMsgIconsAndFonts(QTreeWidgetItem *item) +{ + if (!item) { + return; + } + + bool isnew = item->data(COLUMN_MSG_DATA, ROLE_MSG_NEW).toBool(); + bool read = item->data(COLUMN_MSG_DATA, ROLE_MSG_READ).toBool(); + + if (read) { + item->setIcon(COLUMN_MSG_READ, QIcon(":/images/message-state-read.png")); + } else { + item->setIcon(COLUMN_MSG_READ, QIcon(":/images/message-state-unread.png")); + } + if (isnew) { + item->setIcon(COLUMN_MSG_TITLE, QIcon(":/images/message-state-new.png")); + } else { + item->setIcon(COLUMN_MSG_TITLE, QIcon()); + } + + for (int i = 0; i < COLUMN_FEED_COUNT; i++) { + QFont font = item->font(i); + font.setBold(isnew || !read); + item->setFont(i, font); + } + + item->setData(COLUMN_MSG_READ, ROLE_MSG_SORT, QString("%1_%2_%3").arg(QString(isnew ? "1" : "0"), QString(read ? "0" : "1"), item->data(COLUMN_MSG_TITLE, ROLE_MSG_SORT).toString())); +} + +void FeedReaderDialog::updateMsgItem(QTreeWidgetItem *item, FeedMsgInfo &info) +{ + QString title = QString::fromUtf8(info.title.c_str()); + QDateTime qdatetime; + qdatetime.setTime_t(info.pubDate); + + /* add string to all data */ + QString sort = QString("%1_%2_%2").arg(title, qdatetime.toString("yyyyMMdd_hhmmss"), QString::fromStdString(info.feedId)); + + item->setText(COLUMN_MSG_TITLE, title); + item->setData(COLUMN_MSG_TITLE, ROLE_MSG_SORT, sort); + + QString author = QString::fromUtf8(info.author.c_str()); + item->setText(COLUMN_MSG_AUTHOR, author); + item->setData(COLUMN_MSG_AUTHOR, ROLE_MSG_SORT, author + "_" + sort); + + /* if the message is on same date show only time */ + if (qdatetime.daysTo(QDateTime::currentDateTime()) == 0) { + item->setData(COLUMN_MSG_PUBDATE, Qt::DisplayRole, qdatetime.time()); + } else { + item->setData(COLUMN_MSG_PUBDATE, Qt::DisplayRole, qdatetime); + } + item->setData(COLUMN_MSG_PUBDATE, ROLE_MSG_SORT, QString("%1_%2_%3").arg(qdatetime.toString("yyyyMMdd_hhmmss"), title, QString::fromStdString(info.msgId))); + + item->setData(COLUMN_MSG_DATA, ROLE_MSG_ID, QString::fromStdString(info.msgId)); + item->setData(COLUMN_MSG_DATA, ROLE_MSG_LINK, QString::fromUtf8(info.link.c_str())); + item->setData(COLUMN_MSG_DATA, ROLE_MSG_READ, info.flag.read); + item->setData(COLUMN_MSG_DATA, ROLE_MSG_NEW, info.flag.isnew); + + calculateMsgIconsAndFonts(item); +} + +void FeedReaderDialog::feedChanged(const QString &feedId, int type) +{ + if (!isVisible()) { + /* complete update in showEvent */ + return; + } + + if (feedId.isEmpty()) { + return; + } + + FeedInfo feedInfo; + if (type != NOTIFY_TYPE_DEL) { + if (!mFeedReader->getFeedInfo(feedId.toStdString(), feedInfo)) { + return; + } + } + + if (type == NOTIFY_TYPE_MOD || type == NOTIFY_TYPE_DEL) { + QTreeWidgetItemIterator it(ui->feedTreeWidget); + QTreeWidgetItem *item; + while ((item = *it) != NULL) { + if (item->data(COLUMN_FEED_DATA, ROLE_FEED_ID).toString() == feedId) { + if (type == NOTIFY_TYPE_MOD) { + updateFeedItem(item, feedInfo); + } else { + delete(item); + } + break; + } + ++it; + } + } + + if (type == NOTIFY_TYPE_ADD) { + QString id = QString::fromStdString(feedInfo.parentId); + + QTreeWidgetItemIterator it(ui->feedTreeWidget); + QTreeWidgetItem *itemParent; + while ((itemParent = *it) != NULL) { + if (itemParent->data(COLUMN_FEED_DATA, ROLE_FEED_ID).toString() == id) { + QTreeWidgetItem *item = new RSTreeWidgetItem(mFeedCompareRole); + itemParent->addChild(item); + updateFeedItem(item, feedInfo); + break; + } + ++it; + } + } + calculateFeedItems(); +} + +void FeedReaderDialog::msgChanged(const QString &feedId, const QString &msgId, int type) +{ + if (!isVisible()) { + /* complete update in showEvent */ + return; + } + + if (feedId.isEmpty() || msgId.isEmpty()) { + return; + } + + if (feedId.toStdString() != currentFeedId()) { + return; + } + + FeedMsgInfo msgInfo; + if (type != NOTIFY_TYPE_DEL) { + if (!mFeedReader->getMsgInfo(feedId.toStdString(), msgId.toStdString(), msgInfo)) { + return; + } + } + + if (type == NOTIFY_TYPE_MOD || type == NOTIFY_TYPE_DEL) { + QTreeWidgetItemIterator it(ui->msgTreeWidget); + QTreeWidgetItem *item; + while ((item = *it) != NULL) { + if (item->data(COLUMN_MSG_DATA, ROLE_MSG_ID).toString() == msgId) { + if (type == NOTIFY_TYPE_MOD) { + updateMsgItem(item, msgInfo); + filterItem(item); + } else { + delete(item); + } + break; + } + ++it; + } + } + + if (type == NOTIFY_TYPE_ADD) { + QTreeWidgetItem *item = new RSTreeWidgetItem(mMsgCompareRole); + updateMsgItem(item, msgInfo); + ui->msgTreeWidget->addTopLevelItem(item); + filterItem(item); + } +} + +void FeedReaderDialog::feedItemChanged(QTreeWidgetItem *item) +{ + if (!item) { + ui->msgTreeWidget->clear(); + return; + } + + std::string feedId = item->data(COLUMN_FEED_DATA, ROLE_FEED_ID).toString().toStdString(); + updateMsgs(feedId); +} + +void FeedReaderDialog::msgItemClicked(QTreeWidgetItem *item, int column) +{ + if (item == NULL) { + return; + } + + if (column == COLUMN_MSG_READ) { + QList rows; + rows.append(item); + bool read = item->data(COLUMN_MSG_DATA, ROLE_MSG_READ).toBool(); + setMsgAsReadUnread(rows, !read); + return; + } +} + +void FeedReaderDialog::msgItemChanged() +{ + long todo; // show link somewhere + + std::string feedId = currentFeedId(); + std::string msgId = currentMsgId(); + + if (feedId.empty() || msgId.empty()) { + ui->msgTitle->clear(); +// ui->msgLink->clear(); + ui->msgText->clear(); + return; + } + + QTreeWidgetItem *item = ui->msgTreeWidget->currentItem(); + if (!item) { + /* there is something wrong */ + ui->msgTitle->clear(); +// ui->msgLink->clear(); + ui->msgText->clear(); + return; + } + + /* get msg */ + FeedMsgInfo msgInfo; + if (!mFeedReader->getMsgInfo(feedId, msgId, msgInfo)) { + ui->msgTitle->clear(); +// ui->msgLink->clear(); + ui->msgText->clear(); + return; + } + + bool setToReadOnActive = Settings->valueFromGroup("FeedReaderDialog", "SetMsgToReadOnActivate", true).toBool(); + bool isnew = item->data(COLUMN_MSG_DATA, ROLE_MSG_NEW).toBool(); + bool read = item->data(COLUMN_MSG_DATA, ROLE_MSG_READ).toBool(); + + QList row; + row.append(item); + if (read) { + if (isnew) { + /* something wrong, but set as read again to clear the new flag */ + setMsgAsReadUnread(row, true); + } + } else { + /* set to read/unread */ + setMsgAsReadUnread(row, setToReadOnActive); + } + + QString msgTxt = RsHtml().formatText(ui->msgText->document(), QString::fromUtf8(msgInfo.description.c_str()), RSHTML_FORMATTEXT_EMBED_LINKS); + + ui->msgText->setHtml(msgTxt); + ui->msgTitle->setText(QString::fromUtf8(msgInfo.title.c_str())); +// ui->msgLink->setHtml(RsHtml().formatText(NULL, QString::fromUtf8(msgInfo.link.c_str()), RSHTML_FORMATTEXT_EMBED_LINKS)); +} + +void FeedReaderDialog::setMsgAsReadUnread(QList &rows, bool read) +{ + QList::iterator rowIt; + + std::string feedId = currentFeedId(); + if (feedId.empty()) { + return; + } + + for (rowIt = rows.begin(); rowIt != rows.end(); rowIt++) { + QTreeWidgetItem *item = *rowIt; + bool rowRead = item->data(COLUMN_MSG_DATA, ROLE_MSG_READ).toBool(); + bool rowNew = item->data(COLUMN_MSG_DATA, ROLE_MSG_NEW).toBool(); + + if (rowNew || read != rowRead) { + std::string msgId = item->data(COLUMN_MSG_DATA, ROLE_MSG_ID).toString().toStdString(); + mFeedReader->setMessageRead(feedId, msgId, read); + } + } +} + +void FeedReaderDialog::filterColumnChanged() +{ + if (mProcessSettings) { + return; + } + + filterItems(ui->filterLineEdit->text()); + + // save index + int filterColumn = filterColumnFromComboBox(ui->filterColumnComboBox->currentIndex()); + Settings->setValueToGroup("FeedReaderDialog", "filterColumn", filterColumn); +} + +void FeedReaderDialog::filterItems(const QString& text) +{ + int filterColumn = filterColumnFromComboBox(ui->filterColumnComboBox->currentIndex()); + + int count = ui->msgTreeWidget->topLevelItemCount(); + for (int index = 0; index < count; ++index) { + filterItem(ui->msgTreeWidget->topLevelItem(index), text, filterColumn); + } +} + +void FeedReaderDialog::filterItem(QTreeWidgetItem *item, const QString &text, int filterColumn) +{ + if (text.isEmpty() == false) { + if (item->text(filterColumn).contains(text, Qt::CaseInsensitive)) { + item->setHidden(false); + } else { + item->setHidden(true); + } + } else { + item->setHidden(false); + } +} + +void FeedReaderDialog::filterItem(QTreeWidgetItem *item) +{ + filterItem(item, ui->filterLineEdit->text(), filterColumnFromComboBox(ui->filterColumnComboBox->currentIndex())); +} + +void FeedReaderDialog::toggleMsgText() +{ + // save state of button + Settings->setValueToGroup("FeedReaderDialog", "expandButton", ui->expandButton->isChecked()); + + toggleMsgText_internal(); +} + +void FeedReaderDialog::toggleMsgText_internal() +{ + if (ui->expandButton->isChecked()) { + ui->msgText->setVisible(true); + ui->expandButton->setIcon(QIcon(QString(":/images/edit_remove24.png"))); + ui->expandButton->setToolTip(tr("Hide")); + } else { + ui->msgText->setVisible(false); + ui->expandButton->setIcon(QIcon(QString(":/images/edit_add24.png"))); + ui->expandButton->setToolTip(tr("Expand")); + } +} + +void FeedReaderDialog::newFolder() +{ + QInputDialog dialog; + dialog.setWindowTitle(tr("Add new folder")); + dialog.setLabelText(tr("Please enter a name for the folder")); + dialog.setWindowIcon(QIcon(":/images/FeedReader.png")); + + if (dialog.exec() == QDialog::Accepted && !dialog.textValue().isEmpty()) { + std::string feedId; + RsFeedAddResult result = mFeedReader->addFolder(currentFeedId(), dialog.textValue().toUtf8().constData(), feedId); + AddFeedDialog::showError(this, result, tr("Create folder"), tr("Cannot create folder.")); + } +} + +void FeedReaderDialog::newFeed() +{ + AddFeedDialog dialog(mFeedReader, this); + dialog.setParent(currentFeedId()); + dialog.exec(); +} + +void FeedReaderDialog::removeFeed() +{ + std::string feedId = currentFeedId(); + if (feedId.empty()) { + return; + } + + QTreeWidgetItem *item = ui->feedTreeWidget->currentItem(); + if (!item) { + return; + } + + bool folder = item->data(COLUMN_FEED_DATA, ROLE_FEED_FOLDER).toBool(); + QString name = item->data(COLUMN_FEED_DATA, ROLE_FEED_NAME).toString(); + + if (QMessageBox::question(this, folder ? tr("Remove folder") : tr("Remove feed"), folder ? tr("Do you want to remove the folder %1?").arg(name) : tr("Do you want to remove the feed %1?").arg(name), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes) { + mFeedReader->removeFeed(feedId); + } +} + +void FeedReaderDialog::editFeed() +{ + std::string feedId = currentFeedId(); + if (feedId.empty()) { + return; + } + + QTreeWidgetItem *item = ui->feedTreeWidget->currentItem(); + if (!item) { + return; + } + + bool folder = item->data(COLUMN_FEED_DATA, ROLE_FEED_FOLDER).toBool(); + if (folder) { + QInputDialog dialog; + dialog.setWindowTitle(tr("Edit folder")); + dialog.setLabelText(tr("Please enter a new name for the folder")); + dialog.setWindowIcon(QIcon(":/images/FeedReader.png")); + dialog.setTextValue(item->data(COLUMN_FEED_DATA, ROLE_FEED_NAME).toString()); + + if (dialog.exec() == QDialog::Accepted && !dialog.textValue().isEmpty()) { + RsFeedAddResult result = mFeedReader->setFolder(feedId, dialog.textValue().toUtf8().constData()); + AddFeedDialog::showError(this, result, tr("Create folder"), tr("Cannot create folder.")); + } + } else { + AddFeedDialog dialog(mFeedReader, this); + if (!dialog.fillFeed(feedId)) { + return; + } + dialog.exec(); + + } +} + +void FeedReaderDialog::activateFeed() +{ + std::string feedId = currentFeedId(); + if (feedId.empty()) { + return; + } + + FeedInfo feedInfo; + if (!mFeedReader->getFeedInfo(feedId, feedInfo)) { + return; + } + + if (feedInfo.flag.folder) { + return; + } + + feedInfo.flag.deactivated = !feedInfo.flag.deactivated; + + mFeedReader->setFeed(feedId, feedInfo); +} + +void FeedReaderDialog::processFeed() +{ + std::string feedId = currentFeedId(); + /* empty feed id process all feeds */ + + mFeedReader->processFeed(feedId); +} + +void FeedReaderDialog::markAsReadMsg() +{ + QList selectedItems = ui->msgTreeWidget->selectedItems(); + setMsgAsReadUnread(selectedItems, true); +} + +void FeedReaderDialog::markAsUnreadMsg() +{ + QList selectedItems = ui->msgTreeWidget->selectedItems(); + setMsgAsReadUnread(selectedItems, false); +} + +void FeedReaderDialog::markAllAsReadMsg() +{ + QList items; + + QTreeWidgetItemIterator it(ui->msgTreeWidget); + QTreeWidgetItem *item; + while ((item = *it) != NULL) { + if (!item->isHidden()) { + items.push_back(item); + } + ++it; + } + setMsgAsReadUnread(items, true); +} + +void FeedReaderDialog::copyLinkMsg() +{ + QString links; + + QTreeWidgetItemIterator it(ui->msgTreeWidget, QTreeWidgetItemIterator::Selected); + QTreeWidgetItem *item; + while ((item = *it) != NULL) { + QString link = item->data(COLUMN_MSG_DATA, ROLE_MSG_LINK).toString(); + if (!link.isEmpty()) { + links += link + "\n"; + } + ++it; + } + + if (links.isEmpty()) { + return; + } + + QApplication::clipboard()->setText(links); +} + +void FeedReaderDialog::removeMsg() +{ + std::string feedId = currentFeedId(); + if (feedId.empty()) { + return; + } + + QList selectedItems = ui->msgTreeWidget->selectedItems(); + QList::iterator it; + std::list msgIds; + + for (it = selectedItems.begin(); it != selectedItems.end(); ++it) { + msgIds.push_back((*it)->data(COLUMN_MSG_DATA, ROLE_MSG_ID).toString().toStdString()); + } + mFeedReader->removeMsgs(feedId, msgIds); +} diff --git a/plugins/FeedReader/gui/FeedReaderDialog.h b/plugins/FeedReader/gui/FeedReaderDialog.h new file mode 100644 index 000000000..1bb6c14b8 --- /dev/null +++ b/plugins/FeedReader/gui/FeedReaderDialog.h @@ -0,0 +1,105 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#ifndef _FEEDREADERDIALOG_H +#define _FEEDREADERDIALOG_H + +#include +#include "interface/rsFeedReader.h" + +namespace Ui { +class FeedReaderDialog; +} + +class QTreeWidgetItem; +class RsFeedReader; +class RSTreeWidgetItemCompareRole; +class FeedReaderNotify; + +class FeedReaderDialog : public MainPage +{ + Q_OBJECT + +public: + FeedReaderDialog(RsFeedReader *feedReader, QWidget *parent = 0); + ~FeedReaderDialog(); + +protected: + virtual void showEvent(QShowEvent *e); + bool eventFilter(QObject *obj, QEvent *ev); + +private slots: + void feedTreeCustomPopupMenu(QPoint point); + void msgTreeCustomPopupMenu(QPoint point); + void feedItemChanged(QTreeWidgetItem *item); + void msgItemChanged(); + void msgItemClicked(QTreeWidgetItem *item, int column); + void filterColumnChanged(); + void filterItems(const QString &text); + void toggleMsgText(); + void newFolder(); + void newFeed(); + void removeFeed(); + void editFeed(); + void activateFeed(); + void processFeed(); + void markAsReadMsg(); + void markAsUnreadMsg(); + void markAllAsReadMsg(); + void copyLinkMsg(); + void removeMsg(); + + /* FeedReaderNotify */ + void feedChanged(const QString &feedId, int type); + void msgChanged(const QString &feedId, const QString &msgId, int type); + +private: + std::string currentFeedId(); + std::string currentMsgId(); + void processSettings(bool load); + void updateFeeds(const std::string &parentId, QTreeWidgetItem *parentItem); + void updateFeedItem(QTreeWidgetItem *item, FeedInfo &info); + void updateMsgs(const std::string &feedId); + void calculateMsgIconsAndFonts(QTreeWidgetItem *item); + void updateMsgItem(QTreeWidgetItem *item, FeedMsgInfo &info); + void setMsgAsReadUnread(QList &rows, bool read); + void filterItem(QTreeWidgetItem *item, const QString &text, int filterColumn); + void filterItem(QTreeWidgetItem *item); + void toggleMsgText_internal(); + + void calculateFeedItems(); + void calculateFeedItem(QTreeWidgetItem *item, uint32_t &unreadCount, bool &loading); + + bool mProcessSettings; + QTreeWidgetItem *mRootItem; + RSTreeWidgetItemCompareRole *mFeedCompareRole; + RSTreeWidgetItemCompareRole *mMsgCompareRole; + + // gui interface + RsFeedReader *mFeedReader; + FeedReaderNotify *mNotify; + + /** Qt Designer generated object */ + Ui::FeedReaderDialog *ui; +}; + +#endif + diff --git a/plugins/FeedReader/gui/FeedReaderDialog.ui b/plugins/FeedReader/gui/FeedReaderDialog.ui new file mode 100644 index 000000000..95c076e29 --- /dev/null +++ b/plugins/FeedReader/gui/FeedReaderDialog.ui @@ -0,0 +1,373 @@ + + + FeedReaderDialog + + + + 0 + 0 + 738 + 583 + + + + + + + + + + Qt::Horizontal + + + + + 300 + 300 + + + + QFrame#frame{border: none;} + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + + + QFrame#feedsHeaderFrame{ +background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #FEFEFE, stop:1 #E8E8E8); + +border: 1px solid #CCCCCC;} + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + + + + + + :/images/Feed.png + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Arial'; font-size:10pt; font-weight:600;">Feeds</span></p></body></html> + + + + + + + Qt::Horizontal + + + + 0 + 20 + + + + + + + + + + + + 9 + + + + Qt::CustomContextMenu + + + QAbstractItemView::NoEditTriggers + + + false + + + true + + + + + + + + + + + + + Qt::Vertical + + + + + + + + 0 + 32 + + + + QFrame#frame_2{ +background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #FEFEFE, stop:1 #E8E8E8); + +border: 1px solid #CCCCCC;} + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + + + 2 + + + + + + + + :/images/find-16.png + + + + + + + Search forums + + + + + + + + + + 0 + 0 + + + + + MS Shell Dlg 2 + + + + 0 + + + + Title + + + + + Date + + + + + Author + + + + + + + + + + + + 9 + + + + Qt::CustomContextMenu + + + QAbstractItemView::NoEditTriggers + + + QAbstractItemView::ExtendedSelection + + + true + + + true + + + + Title + + + + + + + + + :/images/message-state-header.png:/images/message-state-header.png + + + + + Date + + + + + Author + + + + + + + + + + + 0 + 0 + + + + + 10 + 75 + true + + + + Message: + + + + + + + QLabel#msgTitle{ +border: 2px solid #CCCCCC; +border-radius: 6px; +background: white;} + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + + 24 + 24 + + + + Qt::NoFocus + + + + + + + :/images/edit_remove24.png:/images/edit_remove24.png + + + true + + + true + + + + + + + + + + + 0 + 10 + + + + + 9 + + + + + + + + + + + LineEditClear + QLineEdit +
gui/common/LineEditClear.h
+
+ + LinkTextBrowser + QTextBrowser +
gui/common/LinkTextBrowser.h
+
+
+ + + + + +
diff --git a/plugins/FeedReader/gui/FeedReaderNotify.cpp b/plugins/FeedReader/gui/FeedReaderNotify.cpp new file mode 100644 index 000000000..59853c114 --- /dev/null +++ b/plugins/FeedReader/gui/FeedReaderNotify.cpp @@ -0,0 +1,36 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include "FeedReaderNotify.h" + +FeedReaderNotify::FeedReaderNotify() : QObject() +{ +} + +void FeedReaderNotify::feedChanged(const std::string &feedId, int type) +{ + emit notifyFeedChanged(QString::fromStdString(feedId), type); +} + +void FeedReaderNotify::msgChanged(const std::string &feedId, const std::string &msgId, int type) +{ + emit notifyMsgChanged(QString::fromStdString(feedId), QString::fromStdString(msgId), type); +} diff --git a/plugins/FeedReader/gui/FeedReaderNotify.h b/plugins/FeedReader/gui/FeedReaderNotify.h new file mode 100644 index 000000000..572b540ac --- /dev/null +++ b/plugins/FeedReader/gui/FeedReaderNotify.h @@ -0,0 +1,45 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#ifndef _FEEDREADERNOTIFY_H +#define _FEEDREADERNOTIFY_H + +#include +#include "interface/rsFeedReader.h" + +class FeedReaderNotify : public QObject, public RsFeedReaderNotify +{ + Q_OBJECT + +public: + FeedReaderNotify(); + + /* RsFeedReaderNotify */ + virtual void feedChanged(const std::string &feedId, int type); + virtual void msgChanged(const std::string &feedId, const std::string &msgId, int type); + +signals: + void notifyFeedChanged(const QString &feedId, int type); + void notifyMsgChanged(const QString &feedId, const QString &msgId, int type); +}; + +#endif + diff --git a/plugins/FeedReader/gui/FeedReader_images.qrc b/plugins/FeedReader/gui/FeedReader_images.qrc new file mode 100644 index 000000000..6acbedfab --- /dev/null +++ b/plugins/FeedReader/gui/FeedReader_images.qrc @@ -0,0 +1,13 @@ + + + images/FeedReader.png + images/Root.png + images/Folder.png + images/Feed.png + images/FeedProcessOverlay.png + images/FeedErrorOverlay.png + images/FolderAdd.png + images/FeedAdd.png + images/Update.png + + diff --git a/plugins/FeedReader/gui/images/Feed.png b/plugins/FeedReader/gui/images/Feed.png new file mode 100644 index 0000000000000000000000000000000000000000..176ec7d0790a42058230a38c2ac247a4571e7e95 GIT binary patch literal 641 zcmV-{0)G98P)_Sg-|jUqJ|+D|<Hprmhci>ug~NUK-1~m_oO}K!hs?23mdn3K zLiXKW$){QE0t%Xg1x+e;h^fHMLV?ow>M%3JQ(G)&!xiL1IblnMAKK&JqGHlR^} z(*h(MP;v_LOEot@(K>-X! z;aeaDm=fTD0IzJoJ^?%eI1a;(hp9s`g+0^);ULs2t@sT1H>#WwkjvLCz-t@e7NA9d zu$K8%P`q6?UxsBx(CdbREl_&}-nPQXCHNvhj{pNUV6Olt1eh&`x|_;(6viJz)38c5 z0X?;FOlifwLRXpg1$ZRDpbcmc;J5%K=ajm523`tCd6+$R5Oy+IJ) z69I-SfM<_{)GQ%|M0Z`2(#K)o0+dUwn+5f2E>%^^55n`K5dDGonS?ZK38}hFQf`%$ z4VA_Ilx~J;FD|R;kd&t_DVxnyp=PR5Ga2oZuK%p>L{iQ4Ud=R_)=X(b&(5O%w6lSm bu@}DquQ%lpkeEAk00000NkvXXu0mjf2i+rl literal 0 HcmV?d00001 diff --git a/plugins/FeedReader/gui/images/FeedAdd.png b/plugins/FeedReader/gui/images/FeedAdd.png new file mode 100644 index 0000000000000000000000000000000000000000..19b38d6d548f30c889eb6039d447a71ba85fb612 GIT binary patch literal 1444 zcmV;V1zY-wP)vzwsvk*o&$(NpU?$`7CUgtX; zXtXsu4Upw(j^idMYgv{t-XI-3#<)Y`dvDg>KR_4$UqhtO2AnrF#yLY0Ig!T8a8Q^j>yqc zPr^UkOF4_tz83hd^op~#hPN`n#YVeWHCZE=jB)6mYJ#?QQ^6lHkkerxa}T*hFLIF% z}nm~}o@za-$GC;QfIC7)@ zeCV_V5E;?7{qS|0#QDwlR6xrHD*;9sK=w93u4rJY8s0!gnxMCoL1%KYu>4m=axROE z?;x^)3v3S3`zpCJbfs;iy>( zbIFu~=*5ukJ%;SSuTTn`)99Hu;nuI<>nRc!?un{^GwUn_NQxHo{Uw-_SzRC_@kn!4 z#Pv0JVnHKZlb4dUYJzi=pX9ZDkb-~bE6#xMm2YvY+bF*9Sxg1|@~&B!RFx7fCJDT) z5*lkIOQM{PP@IREuw+sQLRlw_)7HX0_kC!MHU^QBBZ#-GBmF1?g#I~-o81O+(U)-* zaPl3KP*a&^0P|b{ra4XO;juol>>83cen6)0H?lTD9`T5CB`BKR2z~u)ICA$029g8F z47Q*&?8kD+19Y52*KLEiWPcv;<68u%NQqWc4wm@>%=4P=4^`q0QeB4;yRe<+cj+c@ zh@uSsm3tuuH^OTxrad0rBX`i$=RnQ%cHAJqvab^=;8;VEIHe*jC;)9;1Nhno%9R0z zVmFL-4^@+nfs(gQAbfl^a;XSgpK?sb=hdC4u{e;09v!h5n*A2 zpDLx61|5LirLMyxfG4VlnbX1_PxK7v@;UhSW$lNxHLmUMiB7E)4}&)sk5$d1#`#zr zYoa~WpVW0cKxf&i;2lY1uXl}n^yW|5PZ(h9bDH{U2XMcWKTREFQ^11qP~yyqoASmJKKWwdDN0i>CUKIOFy5mK7?pw{agb&mw-oC% zF1Cl<2$J&85D>&gTK1Fp3jxYpxw6y}m4_GOxnLeM!hmYHF_*OMs%v!gApSrKowTC& y7l8*4;U4&X*x>TsDIVMN#uN^EeGtn3=Kck*o+42OKKWn(0000^v?_mz7ify>{C~Ug&C~T)9l{zU7XM>C01DbBJ1$wzsBZes9s^>bP0l+XkKfg(su literal 0 HcmV?d00001 diff --git a/plugins/FeedReader/gui/images/FeedProcessOverlay.png b/plugins/FeedReader/gui/images/FeedProcessOverlay.png new file mode 100644 index 0000000000000000000000000000000000000000..95526940c20fa6cbd6b2f4e7c96ecc7e7c921530 GIT binary patch literal 848 zcmV-W1F!svP)oW{ zDW$#GOOdpP2El;Z;=xiiR#b$DCPazRnAvPL*$;PSc6RgjF)4+Rqf-RgcP=x}!2AC_ zAMgM5@r;+R08juZ02BZU00n>o!1D=ETcV0ziBMd#kgV7*Cc&}i>3Itf&{Wmt zMn2flO8u%DMzyR6oNv(^&C5xs^8V zdJ|P9;@{Rmdla&k&l7+bKVPS|>}_E1@c@CKK~hUHYK?Kf+ra+*0mM@9!a~?w2_54Q zc42)Gu8nyEP`bTAHMQ3;9(afuj4~CTBBxKo%?c4LhBKr8YAjH!t%XAw_|<@;V-lP8 zJ^c)IJj#+kx-Z^calFxZm_@YYwR-v-T>$?g;nFnTeiZYhdKR6dgixComwK^AV$>x!~>K! zMl^T%6fF_hC$B9DsB*xSau16q^oHOkIVA&+=IH)E*KshYs1FE$I9^`CXcq1!#hk2p adj9|;6)pBTIVCLs0000StO&>uS)ve< z0AYj>5AR{$W90N^4L=L-RlQUJ&DC0@ZjPh;=*jPLSYvv5M~MFBAl0-BNIsH15C~g000{K(ZT*W zKal6<?_01!^k@7iDG<<3=fuAC~28EsPoqkpK{9 zG%|Vj005J}`Hw&=0RYXHq~ibpyyzHQsFW8>#s~laM4*8xut5h5!4#~(4xGUqyucR% zVFpA%3?#rj5JCpzfE)^;7?wd9RKPme1hudO8lVxH;SjXJF*pt9;1XPc>u?taU>Kgl z7`%oF1VP9M6Ja4bh!J9r*dopd7nzO(B4J20l7OTj>4+3jBE`sZqynizYLQ(?Bl0bB z6giDtK>Co|$RIL`{EECsF_eL_Q3KQhbwIhO9~z3rpmWi5G!I>XmZEFX8nhlgfVQHi z(M#xcbO3#dj$?q)F%D*o*1Pf{>6$SWH+$s3q(pv=X`qR|$iJF~TPzlc-O$C3+J1#CT#lv5;6stS0Uu z9wDA3UMCI{Uz12A4#|?_P6{CkNG+sOq(0IRX`DyT~9-sA|ffUF>w zk++Z!kWZ5P$;0Hg6gtI-;!FvmBvPc55=u2?Kjj3apE5$3psG>Lsh-pbs)#zDT1jo7 zc2F-(3)vyY4>O^>2$gY-Gd%Qm(Z8eYv>2*=jns=cMJ`N z4THx>VkjAF8G9M07`GWOnM|ey)0dgZR4~^v8<}UA514ONSSt1^d=-((5|uiYR+WC0 z=c-gyb5%dpd8!Lkt5pxHURHgkMpd&=fR^vEcAI*_=wwAG2sV%zY%w@v@XU~7=xdm1xY6*0;iwVIXu6TaXrs|dqbIl~?uTdNHFy_3W~^@< zVyraYW!!5#VPa`A+oZ&##pJ#z&6I1JX1dX|({#+t$SmBf*sRIyjyctwYo1}g*}U8Q zjfJH}oW)9uHjBrW+LnCF1(r>g_pF#!K2~{F^;XxcN!DEJEbDF7S8PxlSDOr*I-AS3 zsI8l=#CDr)-xT5$k15hA^;2%zG3@;83hbKf2JJcaVfH2VZT8O{%p4LO);n}Nd~$Sk z%yw*Wyz8XlG{dRHsl(}4XB%gsbDi@w7p6;)%MzD%mlsoQr;4X;pL)xc%+^yMd)ZNTI#eJ*$O)i@o$z8)e??LqN_gLa_%;TM>o2SC_kmoO6c3xRt`@J4d zvz#WL)-Y|z+r(Soy~}%GIzByR`p)SCKE^%*pL(B%zNWq+-#xw~e%5}Oeh2)X`#bu} z{g3#+;d$~F@lFL`0l@*~0lk45fwKc^10MvL1f>Tx1&sx}1}_Xg6+#RN4Ot&@lW)Km z@*DYMGu&q^n$Z=?2%QyL8~QNJCQKgI5srq>2;UHXZ>IT7>CCnWh~P(Th`1kV8JQRP zeH1AwGO8}>QM6NZadh`A)~w`N`)9q5@sFvDxjWlxwsLl7tZHmhY-8-3xPZ8-xPf?w z_(k!T5_A(J3GIpG#Ms0=iQ{tu=WLoYoaCBRmULsT<=mpV7v|~C%bs^USv6UZd^m-e z5|^?+<%1wXP%juy<)>~<9TW0|n}ttBzM_qyQL(qUN<5P0omQ3hINdvaL;7fjPeygd zGYL;pD|wL_lDQ-EO;$wK-mK5raoH_7l$?~Dqf!lNmb5F^Ft;eTPi8AClMUo~=55Lw zlZVRpxOiFd;3B_8yA~shQx|tGF!j;$toK>JuS&gYLDkTP@C~gS@r~shUu{a>bfJ1`^^VQ7&C1OKHDNXF zTgC{M|V%fo{xK_dk6MK@9S!GZ*1JJzrV5xZBjOk9!NTH<(q(S+MDf~ zceQX@Dh|Ry<-sT4rhI$jQ0Sq~!`#Eo-%($2E^vo}is5J@NVEf|KK?WT&2;PCq@=ncR8zO#GQ^T~S@VXG71P zKNocFOt)Y6$@AXlk6rM*aP%VgV%sIRORYVwJx6|U{ozQjTW{-S_si{9Jg#)~P3t?+ z@6&(!YQWWV*Z9{iU7vZq@5byKw{9lg9JnRA_4s!7?H6|n?o8ZWdXIRo{Jz@#>IeD{ z>VLHUv1Pz*;P_y`V9&!@5AO~Mho1hF|I>%z(nrik)gwkDjgOrl9~%uCz4Bzvli{bb zrxVZ0epdf^>vOB;-~HnIOV3#R*zgPai_gEVd8zYq@2jb=I>#f&AH2?aJ@Kaet zy{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igW53^O_KHv3lq02}y8L_t(& z-nE-~@MKqY-#_Qx_g?p}f6FYI8A+qjXdfXVA+&%ZkPH%-&4A5f$AN$_wi7556Uuf7 zsT2l`4YnzlQ?^qn%DCd##wM68m=GKZBqWePLP%(xku;#$H2eJa?tbsybMnW%ue*OU z1OCI6uIlOE^zz<2_niAZ-}61^2|wYXs)&dHmR^4H!^{9&c;qkE#e=(qL0_ncPU~f7 z&8jQbZGlm^aSl^O(gE^^qh%gjh+pdg(R4m9NHh>ZiU`hw2)MK!2H>Z#*=+~$vwy=yw|q)h zbZ7B`ck3ux0Z~-|qJR&zxUy^g+kf*K_w;=qljVJ{aJ~lTEn5QOCN46+j69Mq2wb|* z6h+BF?e8S54?g5>iV={*t93c!YYc1b+EpWe;ycx~^N4}WFvU0*~j8c_%MqAQDk^~*1H zPv7zNqBk&y7Yd)<3L?o%;uHj=Fl4GkHl2kj*g~JUJR}B>;d79B%$49vC<`b%NKrvm zA+AhDxN(S!8EMx=P))BmX`6r)zZ1#pXy-3Uq5#ivU|I%YT@s-P}PKEbri+B;C#Rd<~d89D> z^Ph`txspSF{a38J`bON$9J;bXbLbGdxQxVz6g~kBK#>+MMTiHVwnf_KE`g3qMkS9c zCJyl)EF#`x!~_i@FoJ_@oEj89hqz0}$RTc2nA^bWu07b?MK2eCXK(wHm-PSdpWM+U zn7115BhHDmo_5~wg~ydjdEt4~vB%QR1596a9oFv?4jv>fFDKw}WaC-{^@x*naU$Ry z5Hnz9PY*E?>|h#cf@W+oNg?M{`zXLcZ7>x}ybiDdfeu1Vn9ac6rg-P&QKNVIyN(yfK?dA3DHw&ty2iyxlD=ov4Sd|vVF3@c)~PVZB?ag0IHc@WZjGFpXnJfDs9GTIicp(2v9NR9*=Knn1Rt{!v# z^;-uU=J!7S8?lKSjRuMeCypjyF*Z_&7bMv9`e|8s<{;D8-U5Rm_1--bCrP0t`Pt@P zaei#9YZoSaqYY#4vtzQ?UCU+imXL9F6PHPejX`Toeiup5Ac83w-3xFXECeJ#as2T9 zVyPdeh876s(a@(eJB3h683LHHspBLJ6?gWhbAp*6nwcP)$%u?| zWxMxWCTl*0xskn`Hf3f`aSTk^pwXU{wT6zVWD5O6R4kK~0-6X~Bb}0BIe1PCBU7

k3jO2g z%3OW2LY?GQ#x}3@Y^JHwfoKr>Kt&8th^yi- z(!`gS4Ax?dAbZl-oPJvGwy70kGnV^&t!8R&RR4Qb8EB^Ag zQe6HPYn2p>?(;jAqxX73u~sxU9Kcm$8d1`9Efv(keq zZqvn=MHA@@ilIbx^n+t@7&)>uWN~E~EvG4FH=v74*&CW!SITuF4s(+g&&dy&_{%c) z%@q`hSJIBDRRNu z&jhU6fPen`C|>=yu=#3`G6P&OvNIvM~ zVqu~<{^uDk4(2YWeC21cP0!0{KHjq;lFDsWFo(G!*{upOV!_h?Tcg#PbT;5b#PCHU z(IzfaCTbc#puX+CDef{I#GgJzS>pzA(=T@{C=5NL1 zSc{2Rh(k1h>KLRH2%5Bn=)go=)!kbF%*?LWX63N81(sO4Xmy5aL`}tlf>&7s7`aBk zCw^?rQu2B;Pu>FHr;u_s)x=o}vQbc;ZeO3~T@mE`U&OE5PQ3RcsW`C!mW)Leic%+#Z`r z1yjqm`=JAmP$Xy9Ok&FQod)mnAUM4Z;yb8JWtyn#TrpbC)$R4%~RE9;D z-qQ%t=&V~G9l%s?cEy+sfmVIAv<0GyS+o`!#kWi+Z(;*8kNFHckwxRG5@Wi6j;AQq(wYa8^zz z6E6L!5h+Vp*ol4n{pd5F%koU#K4zyPxGO1d`WSIoCj%S9qCjX12t_q1qr|j_tGO*& z0MxauW~K``oJ+#BI#3)@+j7KB08)0Y8brZj#6SP-xJzCOuE?BPvCv@630U5bE$)I7 zk7LK4Msx{$FNPxP#JSq#~%AVJec&lR+!J%H)?r zy_V}{956|tCMM|sqzh9iaOb@VcjG6K^Iw%wT2YF`pT)z`?-QT+R7RmSowCt+%1d5J z&~Ey@X%_D-$=+GhM?Ay%qkWep%@u3)qHM8KP;odSje5~oV}c+)huDm`@2G%~N&8POCfe^!)U_M0 z#l7GIm{eE{Scq5vX;!H3{@sb(Z)@48?^0fHQ*Oy74_ipz)1-ShUOEHUwo8ld)ZTOm z*9JAFn)>J&2*9OI;Y2S-(4=-q1*-><)&0og2&{$C7N5TcDE!XDrcV@3*4h zrt6U_ekJKqBTnGqzysLQ-thwE-$*{FTzWHDz(N6Pm>C*U4M12uxcI}JD}~Fjtio=E zbCotN>PSwhqhe9V8k0(@kX(TgQuG%E?E5;+{@Z~j_dYIJ-uq;9p90gHh zTwGqXQAk(a=>=l$**Zl>UH-I3G*1eoj-o?41+D^d73MmK7$S9IT+ZdTh{KvyZ22&9 zd>8hEKco3Sufq;~1JPVN%jBM4qq^g+__wH22o8&esV6@8_c#sMX^KjjJsWdX%E#GQ z%%JdQIGx&b?$}`O%LPm7_(WGek(Utic!TelbUVmYf%q~#OF?|Zd|Mjj)&{NaJWDl=t7dZxB`f{TCBt2wUy;-fJXOzd zDP=?u>%ifMiFf^bY-v}DoDl*|fFnZZhF_yu9%6Mwn#7?8-~JyXiklU$e2OKSlsgD63q(1j zQ+XkK}hY<-m=TbDr zk+x^3xw0_DNwxJNoMj`oUwqjU!EAH@FMhNdR!k)d=L@7LlL4*zk3*OU+t&Ep>p=si z0gEA(Yo?=f2w=k##0P%=q&~&k*{|ZNH-hhEfi561VoUo@Hz72gh;az>2%N&#~KmAIiJ4SS+{Xniq3?pxYmqeU8Ac@sr!)F|A>>N=^9PpT2A9% z{0VG&8zUZQEpHZV!@t0tb%)185LxGUd@RcA~b zg*8T)bI66Sf!JhmEu}xgkg)rqXX_-AKXuOydcpbKKJt-iE?6&zA36A^OZKBDV;CYBPQ1fAX-9sV_k7@k zH?2->d3x{SKn8Wh^5j^^z=CU1bIRrLY`3#`h(q+5&#&nev|V{8f*tz-%{`w;6_mzA z>_To61#m^l%HO?@;s5?P^`qZ~V7Q_SQsq)l(U`@#2BE=FZyHt9RLoSUqxmytt+(S$ z+5N!NyN5Ub`ukt>s~@Dxw_k)KXdegmM{p`06EG_rWo%Pc3pfM6d zoRD>F6ucs-$0Gu^_aD)y_#JOY{dD?j=+iv%m*``k%ix|x!O*0zx5Uyc8m=f&N&TpH za7`ddHqOSWFf~RXVrJfnnpsrooVP`)9p|v?ft^R5|Iu$>CL)P;Y2y9GX-5759{R)I zc<0-`^R>@^#xL~C@{GdFoLEyQgGb|oX?o5YOY>D#HyQoRmuQ~)2W0jfO#A4uz4&0b zVk-B3a_`nsE7Md{in3I9r}pr~_@L%!(aCBm4c=;OL@H0QVU}v!76x(1?jJn;k25cN z_pO*lGZQnjc4~Kx!L1nZjjw*0n_vC9FZ{uK-*MA-Z~xM_y7NQ7xJ7A}ms36@sgI&A zD-sF44TGl1ZI%X>egq9Tsjwn3Hewv9i4t8R_%YSnWKo|2r0XE$VHSxwRTb@pBE14P z)1%n94nNmp_1Gc#-b4F1>jf`=`_iRn|J{|Zd0S{>!8?cL`LQ(|F~$b(OEd<=r5?)f zz3UCXdjB1_|Jg0ua4&yuhx1hF|R?@{ANKqhFl~PR%SrfJtx*-+S7Bvy27$+KD zspDs+x%p)Yyc(B)j0jd>-s7e!bF)2RdX`vp2%)jXW5-waA6{IVuV;?AO&8yN zRjmhQZ~d7M7v0|OvfB%FzfaNWjGQT_7^?wEL&&zec>KK8g`?Me>A(NipS$m~fBv?2 zUOQzwuDeV+7i>qu5eVsGrL0oVsTq#OGziJaWNdD11rph4i}|*_X`mtN$wh^qnZeD@ z;CnNs7G(92#pCmzncKSk#6>TB*$=zxHy;(zA#s42dW+gq z^D3RWr^;?`k*vIWe^Q;UvB?z8%V1?`>*B#5-K2_w$=`qSkKbH8{KYrF;;IdH_KhzQ zDFf7pA!ssIz?zt+a03?8O&JyvQ?tX+j7nk=UrcfzIYjk@2sZcyPXV|ELobMVJbGwI*RG1ebpVD z_BI}kfuI2kVS4q%(HEP=N<;Lf(YvxEfBC^*`=#y65B!|OmZG@ zk8R6x;ywqBSWLZCDZ5BDWl~fUqq4fN#Bv{+;14ej*?Xezo*s6#>^%4CTYh-etAF8s zR}`zDL*gK&*?-^4pKc@=s}>VAsv*)Keu#z2lycY~9++CU@uVARG~#miVP*07l{)O7 zX=Y-oPBr>;AaA#Q>f`^a`2J_#e*M*3Z2j}D6LX4$MQBzr?WY;U;IqW*q3qzQbx3E% z%z~^QU1ZO$Jv_Sz{mz-+IQOa>@44XW>%ZIGu;oZ+ZsSThy>3yQ?;~!ASjZJunj^H) zSgM`eTAQd=WF)~m-$&y#t~xHxhtrPIgwXWr<%R1oieD=^v@vLmP;J)Ym+^zTS zc;PJ%1AS0Mn}EIZb9vHCPMT*rW#lCroqGp1S*C;>@+Q7qIjzCN{_4eq;rc9( zC7ItewRBXy#ZVTVu0DSE?c1OJ<`-Wwc;@?WoYMJ?>pGFLQxS`4Y-;0x=?!;p+;-Vr z);nYO^prr(RLfmN# zHZ#`@`j~szR4QP|} z7T4r%_vu1Ue&Wp1IAkYFsFOx-TGB2jzwZ#KF}yfGJRNA28p5_T0JWyR%lAK+W1`(F z?Kqc6?R+u7xqk8>aolMe-9>ov`E2ck&MC6`=@#OjxZ_hS0oi0TOJbT{cHtDJ1%h~2 zV-`lDZ=T$c@&2(q#-jPo&WK1rT0_^izm+9(%*sis0MIv>5^P||)PyiClTyb-KjoAN zFwu8b$Gi;QlxI3=W2J!aEjevMn&3V!V~<-8QC6SuSu4Ku`b|LOa0 z0o9=y>F!S(->Ny%!$c;ANVBTwUGZa%6_J*NpQ5NHM-(T$t2rdwTGl2;;ZB|f9<}?F zp*eGD`ey`?wY50prQrYfBh7L6HIblJC;Xb|SN}h1Zwh(wL$G830000Tav*l?S&1Hc>$jxjK^k4{I^Vf z4rIH05K?GNDyfTD4>oofD#f^ ofE%irhe!jyFu;;BDNe@*0DXs)2gXBa2mk;807*qoM6N<$f=+L<6#xJL literal 0 HcmV?d00001 diff --git a/plugins/FeedReader/gui/images/FolderAdd.png b/plugins/FeedReader/gui/images/FolderAdd.png new file mode 100644 index 0000000000000000000000000000000000000000..0075a86c922fc723e96d44d44b4da839451b1f1f GIT binary patch literal 446 zcmV;v0YUzWP)Tav*l?S&1Hc>$jxjK^k4{I^Vf z4rIH05K?GNDyfTD4>oofD#f^ ofE%irhe!jyFu;;BDNe@*0DXs)2gXBa2mk;807*qoM6N<$f=+L<6#xJL literal 0 HcmV?d00001 diff --git a/plugins/FeedReader/gui/images/Root.png b/plugins/FeedReader/gui/images/Root.png new file mode 100644 index 0000000000000000000000000000000000000000..35097f23b328c75478dfd2790e6cd8004019b95f GIT binary patch literal 968 zcmV;(12_DMP)WVGw)SP~wzAin62_LX4UJ?&alzo*BqT-?qY)Ft3}X0b!lHsi`~VWv zAlcOLVJ6GQh+)Aw9bm@LO*U|lIbDZq>2CKzx3=rcy|=e7_x5_M35kC4d^^cGzvns6 z^BjWzxsDC}`TSDWxHljuHct%TrR<`7`9uf#??LN_Q#B<{^usI@jg z&IIxO?byZ0cVEq?va%+#V_z#j(RblrfbEpG{m@Rn%bN~qww23}6&)H1jPS)ncz4tc zhrR{T*-6j(>8I+R?EJ0k_e*EF2Y~J5-B+GzzHoj?+=v%96YMN|42}9~42K5M>pg-& zPY;A;CyEXCu&X2z$com(Q$O@s9ste#odJ9CCzWpd2DB9K$9BtWAZ#2r#Q-jP>T%WE zk4WG-AlC}F;ZcM~?4MT{)t~c#?PKqOSc3hcw*C-a+T4JrOW((M;wYk7Kg!Jg_{IZ_ z`xPMh77*ot#26l0erJ&ceFyS@rDM7)Au$K5YR7P5S38F8?}3=pL8ti?D?$}+uc(k> zNg(wCu%4mN4HOEm^4aM~_dmdUfBYhbrIsW68o?!h!~l00Ic!BzeuEZL1tf{~Z3d8= zDX6Wfbbb0Z3bd76xoi$&1?lX zR}_&JhDY+i?(-{)8J(@-%GpbFlB|Hy1h9Wsx0Obw`|toD@U(ad)Rp_-GF4&p`ZW)$ zT^S>dpG`Lxxf^b9lM|wEe8B{fX22SN0tT$B9ck_(K(x^e(lBTlY^f~8>hfJN%Ju#P zv;8WmJw4Nw+E70vckUgIRlmGVBj^j|&>EmkKyMJh$4g++vnaM&Q0Z`BF5r`S@7I$$ zefC~XRgV$d@jJT>)lGxRqmTC$l$M>6+-=E~gHAfN*DM+nXNb+Bg3!mm+aU?+i0000;nTskpYH9CbEkwC>2nw2(_(ijA?7BRO7xRwrQ&|T0`B^Sd%u<7;9Q3 zX={Q@w87R`5t|xpk(L$#8DQ8(7};U|{Mr7}$Dp!ROYh|6P5%Gyocqpu=UxdW8VXv8 zDFHeRxZQZn^uo;x6ImvC;ah`N52ODs1gX;L0G}C@T&fWTf#(>v8SP9t+WNmnbyxBK zC-75Bu^{qejlut;RVjxb_AlY1Jz6o>Kt{bWoyysZp46W01mYSPK^V-zboLpth1uHF%8ZA z=Km(hiuycx;mhxTzbhY29y3e?*uF*nk6&NYrGw10sSlFYh}{KStY#tj*}+`q5D-fpY-hRUQZlz2H(iAkyLx z(hs4)QQ0Y!Hg6wI@J7syW$QAsgN#bFFczrf3d|0hiau8#>h1Ngh!%8px?s5|XN0?L zU!a5e1u9t}l7hD)L7tA>CSWRIby2{9)B!K9f0ETo&|5dtg)B zz^OU7rEXA+3|%Mn5dN@TMnzjLdK|2GB_*K|{ZcmO7*1nVR|J+lBD*jE`}uvSv>q8I zm>sewc60nu{TvUv=^n5e)~mDK#|~D-LZpZUEDc-=2hLI7pxC^A)R`G|fk+H4#0qC7 za;(74sB&DXP9bl^A%eMvd9rz-cVqJ$V0~CH8U}U^0arf(e;Q^Du*>i(icA^fE=Gv2 zA5y}L@RltNcYLilQxgqAWQGW&6p<>DTmElzZzXgAzRhACL~|dR0?{JI$NW zVZZxy>qrirAvNm0T$q}kc3|liYR=?DlC+5VpXH(K;_bbtupS%jgVl+pSi+_vuMy~x z1NQ=fYm@p>)^QepwI3p|ectc13L2S_A4Dg`9R4cr6X~p|Sg<^imS?=<@3uO;`)R%v zS8J1Cb9W6B%nII3C5N97v`(ToSBZwc8>sC(2`ASyN|H4RCvvjVckfyKHdxUP8)q8= z7s%ik@3U_Ue?xP@gAehb+1Ic+jtx7Jh^oQm?b|4?LhY<4_eMj>T#(mX_z3&KWhHg6%A+B@0a8p-_AFeR31WE zdp>w!xGZZGTG^V!hf@}5LKM>&IAknbQWxBEH(UxbE8Or%J>VdKI~WICY@Inwpp;Vd z%J}=|^AF6Ft0g#CP=M;vhc{8xwG9nD&zy-#Y9kg$7l&pjBK=>tp+(o~^@~7{X%DBP zfn%L(M;E)fhK-qz*#~ntpr--n|^81#i7}5iAU~% zN9KW3>BNAF?5IKwXgK0>a?y&yfU~V*2#h+dBrW{UC7Y%gDL*$HB1;aDMXQP2l75k7 z$wL{>LK;J)k-5Fna8eE&O+>jFL;!;9AB>E0<+{xB8$Rv8M&Y% zx{?eB_4OzTAOZCdFrMNeO2pwyUaliXoXp@yV#Ic4u)~qc2Vt}iMn-bzJ5)ySdFiG` zijN+EKnX*DV`C8FdI<4Lh!fZA)|0Mw;h7Pi#PfS{T;Qun4mpWrml0W{i0O$x)I4bh zWQmP9+~f=V91J`ZYH-`UgOrexr&&*oU@#Q43Nu31!AH3adUZV1l%C|rp`Wv&o3yyb z?m{&8T_Vqz=Rv%fU}R7d4LLkt?|+X#It(0R<@mSw2QHhJ(RSI2a{vGU07*qoM6N<$ Ef?03EkN^Mx literal 0 HcmV?d00001 diff --git a/plugins/FeedReader/interface/rsFeedReader.h b/plugins/FeedReader/interface/rsFeedReader.h new file mode 100644 index 000000000..82d650db9 --- /dev/null +++ b/plugins/FeedReader/interface/rsFeedReader.h @@ -0,0 +1,181 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + + #ifndef RETROSHARE_FEEDREADER_GUI_INTERFACE_H +#define RETROSHARE_FEEDREADER_GUI_INTERFACE_H + +#include +#include +#include + +class RsFeedReader; +extern RsFeedReader *rsFeedReader; + +enum RsFeedAddResult +{ + RS_FEED_ADD_RESULT_SUCCESS, + RS_FEED_ADD_RESULT_FEED_NOT_FOUND, + RS_FEED_ADD_RESULT_PARENT_NOT_FOUND, + RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER, + RS_FEED_ADD_RESULT_FEED_IS_FOLDER, + RS_FEED_ADD_RESULT_FEED_IS_NO_FOLDER +}; + +class FeedInfo +{ +public: + enum WorkState + { + WAITING, + WAITING_TO_DOWNLOAD, + DOWNLOADING, + WAITING_TO_PROCESS, + PROCESSING + }; + +public: + FeedInfo() + { + proxyPort = 0; + updateInterval = 0; + lastUpdate = 0; + storageTime = 0; + error = false; + flag.folder = false; + flag.infoFromFeed = false; + flag.standardStorageTime = false; + flag.standardUpdateInterval = false; + flag.standardProxy = false; + flag.authentication = false; + flag.deactivated = false; + flag.forum = false; + flag.updateForumInfo = false; + } + + std::string feedId; + std::string parentId; + std::string url; + std::string name; + std::string description; + std::string icon; + std::string user; + std::string password; + std::string proxyAddress; + uint16_t proxyPort; + uint32_t updateInterval; + time_t lastUpdate; + uint32_t storageTime; + std::string forumId; + WorkState workstate; + bool error; + std::string errorString; + + struct { + bool folder : 1; + bool infoFromFeed : 1; + bool standardStorageTime : 1; + bool standardUpdateInterval : 1; + bool standardProxy : 1; + bool authentication : 1; + bool deactivated : 1; + bool forum : 1; + bool updateForumInfo : 1; + } flag; +}; + +class FeedMsgInfo +{ +public: + FeedMsgInfo() + { + pubDate = 0; + flag.isnew = false; + flag.read = false; + } + + std::string msgId; + std::string feedId; + std::string title; + std::string link; + std::string author; + std::string description; + time_t pubDate; + + struct { + bool isnew : 1; + bool read : 1; + } flag; +}; + +class RsFeedReaderNotify +{ +public: + RsFeedReaderNotify() {} + + virtual void feedChanged(const std::string &/*feedId*/, int /*type*/) {} + virtual void msgChanged(const std::string &/*feedId*/, const std::string &/*msgId*/, int /*type*/) {} +}; + +class RsFeedReader +{ +public: + RsFeedReader() {} + virtual ~RsFeedReader() {} + + virtual void stop() = 0; + virtual void setNotify(RsFeedReaderNotify *notify) = 0; + + virtual uint32_t getStandardStorageTime() = 0; + virtual void setStandardStorageTime(uint32_t storageTime) = 0; + virtual uint32_t getStandardUpdateInterval() = 0; + virtual void setStandardUpdateInterval(uint32_t updateInterval) = 0; + virtual bool getStandardProxy(std::string &proxyAddress, uint16_t &proxyPort) = 0; + virtual void setStandardProxy(bool useProxy, const std::string &proxyAddress, uint16_t proxyPort) = 0; + + virtual RsFeedAddResult addFolder(const std::string parentId, const std::string &name, std::string &feedId) = 0; + virtual RsFeedAddResult setFolder(const std::string &feedId, const std::string &name) = 0; + virtual RsFeedAddResult addFeed(const FeedInfo &feedInfo, std::string &feedId) = 0; + virtual RsFeedAddResult setFeed(const std::string &feedId, const FeedInfo &feedInfo) = 0; + virtual bool removeFeed(const std::string &feedId) = 0; + virtual void getFeedList(const std::string &parentId, std::list &feedInfos) = 0; + virtual bool getFeedInfo(const std::string &feedId, FeedInfo &feedInfo) = 0; + virtual bool getMsgInfo(const std::string &feedId, const std::string &msgId, FeedMsgInfo &msgInfo) = 0; + virtual bool removeMsg(const std::string &feedId, const std::string &msgId) = 0; + virtual bool removeMsgs(const std::string &feedId, const std::list &msgIds) = 0; + virtual bool getMessageCount(const std::string &feedId, uint32_t *msgCount, uint32_t *newCount, uint32_t *unreadCount) = 0; + virtual bool getFeedMsgList(const std::string &feedId, std::list &msgInfos) = 0; + virtual bool processFeed(const std::string &feedId) = 0; + virtual bool setMessageRead(const std::string &feedId, const std::string &msgId, bool read) = 0; + + /* get Ids */ +// virtual uint32_t getRankingsCount() = 0; +// virtual float getMaxRank() = 0; +// virtual bool getRankings(uint32_t first, uint32_t count, std::list &rids) = 0; +// virtual bool getRankDetails(std::string rid, RsRankDetails &details) = 0; + + /* Add New Comment / Msg */ +// virtual std::string newRankMsg(std::wstring link, std::wstring title, std::wstring comment, int32_t score) = 0; +// virtual bool updateComment(std::string rid, std::wstring comment, int32_t score) = 0; + +// virtual std::string anonRankMsg(std::string rid, std::wstring link, std::wstring title) = 0; +}; + +#endif diff --git a/plugins/FeedReader/lang/FeedReader_de.ts b/plugins/FeedReader/lang/FeedReader_de.ts new file mode 100644 index 000000000..07d48332a --- /dev/null +++ b/plugins/FeedReader/lang/FeedReader_de.ts @@ -0,0 +1,339 @@ + + + + + AddLinksDialog + + + + Add Link + Link hinzufügen + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:18pt; font-weight:600; color:#ffffff;">Add Link to Cloud</span></p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'DejaVu Sans'; font-size:18pt; font-weight:600; color:#ffffff;">Link zur Wolke hinzufügen</span></p></body></html> + + + + Cancel + Abbrechen + + + + Add a new Link + Neuen Link hinzufügen + + + + Title: + Titel: + + + + Url: + Url: + + + + Add Anonymous Link + Anonym hinzufügen + + + + +2 Great! + +2 Großartig! + + + + +1 Good + +1 Gut + + + + 0 Okay + 0 In Ordnung + + + + -1 Sux + -1 Nervt + + + + -2 Bad Link + -2 Schlechter Link + + + + New Link + Neuer Link + + + + Add Link Failure + Link hinzufügen fehlgeschlagen + + + + Missing Link and/or Title + Titel und/oder Url fehlt + + + + LinksCloudPlugin + + + This plugin provides a set of cached links, and a voting system to promote them. + Das Plugin stellt Links und ein Wahlsystem zur Verfügung, um sie zu verbreiten. + + + + LinksCloud + Verknüpfungswolke + + + + LinksDialog + + + Title / Comment + Titel / Kommentar + + + + Score + Punkte + + + + Peer / Link + Nachbar / Link + + + + Sort by + Sortiere nach + + + + Combo + Kombiniert + + + + Time + Zeit + + + + Ranking + Platzierung + + + + In last + Im letzten + + + + Month + Monat + + + + Week + Woche + + + + Day + Tag + + + + + From + Von + + + + All Peers + Alle Nachbarn + + + + Own Links + Eigene Links + + + + Show + Zeige + + + + Top 100 + Top 100 + + + + 101-200 + + + + + 201-300 + + + + + 301-400 + + + + + 401-500 + + + + + Bottom 100 + Letzten 100 + + + + Link: + Link: + + + + Add Anonymous Link + Anonym hinzufügen + + + + Add Link/Comment + Link/Kommentar hinzufügen + + + + Title: + Titel: + + + + Score: + Punkte: + + + + +2 Great! + +2 Großartig! + + + + +1 Good + +1 Gut + + + + 0 Okay + 0 In Ordnung + + + + -1 Sux + -1 Nervt + + + + -2 Bad Link + -2 Schlechter Link + + + + Url: + Url: + + + + <html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><span style=" font-weight:600;">Links Cloud</span></p></body></html> + <html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><span style=" font-weight:600;">Verknüpfungswolke</span></p></body></html> + + + + Add new link + Neuen Link hinzufügen + + + + Share Link Anonymously + Link anonym verteilen + + + + Vote on Link + Wähle für Link + + + + Download + Herunterladen + + + + Expand + Erweitern + + + + Hide + Verbergen + + + + File Request Confirmation + Bestätigung der Dateianforderung + + + + The file has been added to your download list. + Die Datei wurde zur Downloadliste hinzugefügt. + + + + File Request canceled + Dateianforderung abgebrochen + + + + The file has not been added to your download list, because you already have it. + Die folgende Datei wurde nicht zur Downloadliste hinzugefügt, da Du diese schon hast. + + + + File Request Error + Fehler bei der Dateianforderung + + + + The file link is malformed. + Link ist fehlerhaft. + + + diff --git a/plugins/FeedReader/lang/lang.qrc b/plugins/FeedReader/lang/lang.qrc new file mode 100644 index 000000000..67e313476 --- /dev/null +++ b/plugins/FeedReader/lang/lang.qrc @@ -0,0 +1,5 @@ + + + + + diff --git a/plugins/FeedReader/services/p3FeedReader.cc b/plugins/FeedReader/services/p3FeedReader.cc new file mode 100644 index 000000000..712835f4b --- /dev/null +++ b/plugins/FeedReader/services/p3FeedReader.cc @@ -0,0 +1,1710 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include "RsFeedReaderItems.h" +#include "p3FeedReader.h" +#include "p3FeedReaderThread.h" +#include "serialiser/rsconfigitems.h" +#include "retroshare/rsiface.h" +#include "retroshare/rsforums.h" +#include "util/rsstring.h" + +RsFeedReader *rsFeedReader = NULL; + +#define FEEDREADER_CLEAN_INTERVAL 1 * 60 * 60 // check every hour + +/********* + * #define FEEDREADER_DEBUG + *********/ + +p3FeedReader::p3FeedReader(RsPluginHandler* pgHandler) + : RsPQIService(RS_PKT_TYPE_FEEDREADER_CONFIG, CONFIG_TYPE_FEEDREADER, 5, pgHandler), + mFeedReaderMtx("p3FeedReader"), mDownloadMutex("p3FeedReaderDownload"), mProcessMutex("p3FeedReaderProcess") +{ + mNextFeedId = 1; + mNextMsgId = 1; + mStandardUpdateInterval = 60 * 60; // 60 minutes + mStandardStorageTime = 30 * 60 * 60 * 24; // 30 days + mStandardUseProxy = false; + mStandardProxyPort = 0; + mLastClean = 0; + mNotify = NULL; + + /* start download thread */ + p3FeedReaderThread *frt = new p3FeedReaderThread(this, p3FeedReaderThread::DOWNLOAD); + mThreads.push_back(frt); + frt->start(); + + /* start process thread */ + frt = new p3FeedReaderThread(this, p3FeedReaderThread::PROCESS); + mThreads.push_back(frt); + frt->start(); +} + +/***************************************************************************/ +/****************************** RsFeedReader *******************************/ +/***************************************************************************/ + +static void feedToInfo(const RsFeedReaderFeed *feed, FeedInfo &info) +{ + info.feedId = feed->feedId; + info.parentId = feed->parentId; + info.url = feed->url; + info.name = feed->name; + info.description = feed->description; + info.icon = feed->icon; + info.user = feed->user; + info.password = feed->password; + info.proxyAddress = feed->proxyAddress; + info.proxyPort = feed->proxyPort; + info.updateInterval = feed->updateInterval; + info.lastUpdate = feed->lastUpdate; + info.forumId = feed->forumId; + info.storageTime = feed->storageTime; + info.error = (feed->errorState != RS_FEED_ERRORSTATE_OK); // currently only as bool + info.errorString = feed->errorString; + + info.flag.folder = (feed->flag & RS_FEED_FLAG_FOLDER); + info.flag.infoFromFeed = (feed->flag & RS_FEED_FLAG_INFO_FROM_FEED); + info.flag.standardStorageTime = (feed->flag & RS_FEED_FLAG_STANDARD_STORAGE_TIME); + info.flag.standardUpdateInterval = (feed->flag & RS_FEED_FLAG_STANDARD_UPDATE_INTERVAL); + info.flag.standardProxy = (feed->flag & RS_FEED_FLAG_STANDARD_PROXY); + info.flag.authentication = (feed->flag & RS_FEED_FLAG_AUTHENTICATION); + info.flag.deactivated = (feed->flag & RS_FEED_FLAG_DEACTIVATED); + info.flag.forum = (feed->flag & RS_FEED_FLAG_FORUM); + info.flag.updateForumInfo = (feed->flag & RS_FEED_FLAG_UPDATE_FORUM_INFO); + + switch (feed->workstate) { + case RsFeedReaderFeed::WAITING: + info.workstate = FeedInfo::WAITING; + break; + case RsFeedReaderFeed::WAITING_TO_DOWNLOAD: + info.workstate = FeedInfo::WAITING_TO_DOWNLOAD; + break; + case RsFeedReaderFeed::DOWNLOADING: + info.workstate = FeedInfo::DOWNLOADING; + break; + case RsFeedReaderFeed::WAITING_TO_PROCESS: + info.workstate = FeedInfo::WAITING_TO_PROCESS; + break; + case RsFeedReaderFeed::PROCESSING: + info.workstate = FeedInfo::PROCESSING; + break; + } +} + +static void infoToFeed(const FeedInfo &info, RsFeedReaderFeed *feed, bool add) +{ +// feed->feedId = info.feedId; + feed->parentId = info.parentId; + feed->url = info.url; + feed->name = info.name; + feed->description = info.description; +// feed->icon = info.icon; + feed->user = info.user; + feed->password = info.password; + feed->proxyAddress = info.proxyAddress; + feed->proxyPort = info.proxyPort; + feed->updateInterval = info.updateInterval; +// feed->lastUpdate = info.lastUpdate; + feed->storageTime = info.storageTime; + if (add) { + /* set forum id only when adding a feed */ + feed->forumId = info.forumId; + } + + uint32_t oldFlag = feed->flag; + feed->flag = 0; + if (info.flag.infoFromFeed) { + feed->flag |= RS_FEED_FLAG_INFO_FROM_FEED; + } + if (info.flag.standardStorageTime) { + feed->flag |= RS_FEED_FLAG_STANDARD_STORAGE_TIME; + } + if (info.flag.standardUpdateInterval) { + feed->flag |= RS_FEED_FLAG_STANDARD_UPDATE_INTERVAL; + } + if (info.flag.standardProxy) { + feed->flag |= RS_FEED_FLAG_STANDARD_PROXY; + } + if (info.flag.authentication) { + feed->flag |= RS_FEED_FLAG_AUTHENTICATION; + } + if (info.flag.deactivated) { + feed->flag |= RS_FEED_FLAG_DEACTIVATED; + } + if (add) { + /* only set when adding a new feed */ + if (info.flag.folder) { + feed->flag |= RS_FEED_FLAG_FOLDER; + } + if (info.flag.forum) { + feed->flag |= RS_FEED_FLAG_FORUM; + } + } else { + /* use old bits */ + feed->flag |= (oldFlag & (RS_FEED_FLAG_FOLDER | RS_FEED_FLAG_FORUM)); + } + if (info.flag.updateForumInfo) { + feed->flag |= RS_FEED_FLAG_UPDATE_FORUM_INFO; + } +} + +static void feedMsgToInfo(const RsFeedReaderMsg *msg, FeedMsgInfo &info) +{ + info.msgId = msg->msgId; + info.feedId = msg->feedId; + info.title = msg->title; + info.link = msg->link; + info.author = msg->author; + info.description = msg->description; + info.pubDate = msg->pubDate; + + info.flag.isnew = (msg->flag & RS_FEEDMSG_FLAG_NEW); + info.flag.read = (msg->flag & RS_FEEDMSG_FLAG_READ); +} + +void p3FeedReader::setNotify(RsFeedReaderNotify *notify) +{ + mNotify = notify; +} + +uint32_t p3FeedReader::getStandardStorageTime() +{ + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + return mStandardStorageTime; +} + +void p3FeedReader::setStandardStorageTime(uint32_t storageTime) +{ + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + if (mStandardStorageTime != storageTime) { + mStandardStorageTime = storageTime; + IndicateConfigChanged(); + } +} + +uint32_t p3FeedReader::getStandardUpdateInterval() +{ + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + return mStandardUpdateInterval; +} + +void p3FeedReader::setStandardUpdateInterval(uint32_t updateInterval) +{ + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + if (mStandardUpdateInterval != updateInterval) { + mStandardUpdateInterval = updateInterval; + IndicateConfigChanged(); + } +} + +bool p3FeedReader::getStandardProxy(std::string &proxyAddress, uint16_t &proxyPort) +{ + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + proxyAddress = mStandardProxyAddress; + proxyPort = mStandardProxyPort; + return mStandardUseProxy; +} + +void p3FeedReader::setStandardProxy(bool useProxy, const std::string &proxyAddress, uint16_t proxyPort) +{ + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + if (useProxy != mStandardUseProxy || proxyAddress != mStandardProxyAddress || proxyPort != mStandardProxyPort) { + mStandardProxyAddress = proxyAddress; + mStandardProxyPort = proxyPort; + mStandardUseProxy = useProxy; + IndicateConfigChanged(); + } +} + +void p3FeedReader::stop() +{ + /* stop threads */ + std::list::iterator it; + for (it = mThreads.begin(); it != mThreads.end(); ++it) { + (*it)->join(); + } + mThreads.clear(); +} + +RsFeedAddResult p3FeedReader::addFolder(const std::string parentId, const std::string &name, std::string &feedId) +{ + feedId.clear(); + + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + if (!parentId.empty()) { + /* check parent id */ + std::map::iterator parentIt = mFeeds.find(parentId); + if (parentIt == mFeeds.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::addFolder - parent id " << parentId << " not found" << std::endl; +#endif + return RS_FEED_ADD_RESULT_PARENT_NOT_FOUND; + } + + if ((parentIt->second->flag & RS_FEED_FLAG_FOLDER) == 0) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::addFolder - parent " << parentIt->second->name << " is no folder" << std::endl; +#endif + return RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER; + } + } + + RsFeedReaderFeed *fi = new RsFeedReaderFeed; + rs_sprintf(fi->feedId, "%lu", mNextFeedId++); + fi->parentId = parentId; + fi->name = name; + fi->flag = RS_FEED_FLAG_FOLDER; + mFeeds[fi->feedId] = fi; + + feedId = fi->feedId; + } + + IndicateConfigChanged(); + + if (mNotify) { + mNotify->feedChanged(feedId, NOTIFY_TYPE_ADD); + } + + return RS_FEED_ADD_RESULT_SUCCESS; +} + +RsFeedAddResult p3FeedReader::setFolder(const std::string &feedId, const std::string &name) +{ + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setFolder - feed id " << feedId << ", name " << name << std::endl; +#endif + + std::map::iterator feedIt = mFeeds.find(feedId); + if (feedIt == mFeeds.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setFolder - feed id " << feedId << " not found" << std::endl; +#endif + return RS_FEED_ADD_RESULT_FEED_NOT_FOUND; + } + + if ((feedIt->second->flag & RS_FEED_FLAG_FOLDER) == 0) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setFolder - feed " << feedIt->second->name << " is no folder" << std::endl; +#endif + return RS_FEED_ADD_RESULT_FEED_IS_NO_FOLDER; + } + + RsFeedReaderFeed *fi = feedIt->second; + if (fi->name == name) { + return RS_FEED_ADD_RESULT_SUCCESS; + } + fi->name = name; + } + + IndicateConfigChanged(); + + if (mNotify) { + mNotify->feedChanged(feedId, NOTIFY_TYPE_MOD); + } + + return RS_FEED_ADD_RESULT_SUCCESS; +} + +RsFeedAddResult p3FeedReader::addFeed(const FeedInfo &feedInfo, std::string &feedId) +{ + feedId.clear(); + + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::addFeed - add feed " << feedInfo.name << ", url " << feedInfo.url << std::endl; +#endif + + if (!feedInfo.parentId.empty()) { + /* check parent id */ + std::map::iterator parentIt = mFeeds.find(feedInfo.parentId); + if (parentIt == mFeeds.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::addFeed - parent id " << feedInfo.parentId << " not found" << std::endl; +#endif + return RS_FEED_ADD_RESULT_PARENT_NOT_FOUND; + } + + if ((parentIt->second->flag & RS_FEED_FLAG_FOLDER) == 0) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::addFeed - parent " << parentIt->second->name << " is no folder" << std::endl; +#endif + return RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER; + } + } + + RsFeedReaderFeed *fi = new RsFeedReaderFeed; + infoToFeed(feedInfo, fi, true); + rs_sprintf(fi->feedId, "%lu", mNextFeedId++); + + mFeeds[fi->feedId] = fi; + + feedId = fi->feedId; + } + + IndicateConfigChanged(); + + if (mNotify) { + mNotify->feedChanged(feedId, NOTIFY_TYPE_ADD); + } + + return RS_FEED_ADD_RESULT_SUCCESS; +} + +RsFeedAddResult p3FeedReader::setFeed(const std::string &feedId, const FeedInfo &feedInfo) +{ + std::string forumId; + ForumInfo forumInfo; + + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setFeed - set feed " << feedInfo.name << ", url " << feedInfo.url << std::endl; +#endif + + std::map::iterator feedIt = mFeeds.find(feedId); + if (feedIt == mFeeds.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setFeed - feed id " << feedId << " not found" << std::endl; +#endif + return RS_FEED_ADD_RESULT_FEED_NOT_FOUND; + } + + if (feedIt->second->flag & RS_FEED_FLAG_FOLDER) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setFeed - feed " << feedIt->second->name << " is a folder" << std::endl; +#endif + return RS_FEED_ADD_RESULT_FEED_IS_FOLDER; + } + + if (!feedInfo.parentId.empty()) { + /* check parent id */ + std::map::iterator parentIt = mFeeds.find(feedInfo.parentId); + if (parentIt == mFeeds.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setFeed - parent id " << feedInfo.parentId << " not found" << std::endl; +#endif + return RS_FEED_ADD_RESULT_PARENT_NOT_FOUND; + } + + if ((parentIt->second->flag & RS_FEED_FLAG_FOLDER) == 0) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setFeed - parent " << parentIt->second->name << " is no folder" << std::endl; +#endif + return RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER; + } + } + + RsFeedReaderFeed *fi = feedIt->second; + std::string oldName = fi->name; + std::string oldDescription = fi->description; + + infoToFeed(feedInfo, fi, false); + + if ((fi->flag & RS_FEED_FLAG_FORUM) && (fi->flag & RS_FEED_FLAG_UPDATE_FORUM_INFO) && !fi->forumId.empty() && + (fi->name != oldName || fi->description != oldDescription)) { + /* name or description changed, update forum */ + forumId = fi->forumId; + librs::util::ConvertUtf8ToUtf16(fi->name, forumInfo.forumName); + librs::util::ConvertUtf8ToUtf16(fi->description, forumInfo.forumDesc); + } + } + + IndicateConfigChanged(); + + if (mNotify) { + mNotify->feedChanged(feedId, NOTIFY_TYPE_MOD); + } + + if (!forumId.empty()) { + /* name or description changed, update forum */ + if (!rsForums->setForumInfo(forumId, forumInfo)) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setFeed - can't change forum " << forumId << std::endl; +#endif + } + } + + return RS_FEED_ADD_RESULT_SUCCESS; +} + +void p3FeedReader::deleteAllMsgs_locked(RsFeedReaderFeed *fi) +{ + if (!fi) { + return; + } + + std::map::iterator msgIt; + for (msgIt = fi->mMsgs.begin(); msgIt != fi->mMsgs.end(); ++msgIt) { + delete(msgIt->second); + } + + fi->mMsgs.clear(); +} + +bool p3FeedReader::removeFeed(const std::string &feedId) +{ + std::list removedFeedIds; + + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + std::map::iterator feedIt = mFeeds.find(feedId); + if (feedIt == mFeeds.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::removeFeed - feed " << feedId << " not found" << std::endl; +#endif + return false; + } + + removedFeedIds.push_back(feedId); + + RsFeedReaderFeed *fi = feedIt->second; + mFeeds.erase(feedIt); + + if (fi->flag & RS_FEED_FLAG_FOLDER) { + std::list feedIds; + feedIds.push_back(fi->feedId); + while (!feedIds.empty()) { + std::string parentId = feedIds.front(); + feedIds.pop_front(); + + std::map::iterator feedIt1; + for (feedIt1 = mFeeds.begin(); feedIt1 != mFeeds.end(); ) { + RsFeedReaderFeed *fi1 = feedIt1->second; + + if (fi1->parentId == parentId) { + removedFeedIds.push_back(fi1->feedId); + + std::map::iterator tempIt = feedIt1; + ++feedIt1; + mFeeds.erase(tempIt); + + if (fi1->flag & RS_FEED_FLAG_FOLDER) { + feedIds.push_back(fi->feedId); + } + + deleteAllMsgs_locked(fi1); + delete(fi1); + + continue; + } + ++feedIt1; + } + } + } + + deleteAllMsgs_locked(fi); + delete(fi); + } + + IndicateConfigChanged(); + + if (mNotify) { + /* only notify remove of feed */ + std::list::iterator it; + for (it = removedFeedIds.begin(); it != removedFeedIds.end(); ++it) { + mNotify->feedChanged(*it, NOTIFY_TYPE_DEL); + } + } + + return true; +} + +void p3FeedReader::getFeedList(const std::string &parentId, std::list &feedInfos) +{ + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + std::map::iterator feedIt; + for (feedIt = mFeeds.begin(); feedIt != mFeeds.end(); ++feedIt) { + RsFeedReaderFeed *fi = feedIt->second; + + if (fi->parentId == parentId) { + FeedInfo feedInfo; + feedToInfo(fi, feedInfo); + feedInfos.push_back(feedInfo); + } + } +} + +bool p3FeedReader::getFeedInfo(const std::string &feedId, FeedInfo &feedInfo) +{ + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + std::map::iterator feedIt = mFeeds.find(feedId); + if (feedIt == mFeeds.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::getFeedInfo - feed " << feedId << " not found" << std::endl; +#endif + return false; + } + + feedToInfo(feedIt->second, feedInfo); + + return true; +} + +bool p3FeedReader::getMsgInfo(const std::string &feedId, const std::string &msgId, FeedMsgInfo &msgInfo) +{ + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + std::map::iterator feedIt = mFeeds.find(feedId); + if (feedIt == mFeeds.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::getMsgInfo - feed " << feedId << " not found" << std::endl; +#endif + return false; + } + + RsFeedReaderFeed *fi = feedIt->second; + + std::map::iterator msgIt; + msgIt = fi->mMsgs.find(msgId); + if (msgIt == fi->mMsgs.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::getMsgInfo - msg " << msgId << " not found" << std::endl; +#endif + return false; + } + + feedMsgToInfo(msgIt->second, msgInfo); + + return true; +} + +bool p3FeedReader::removeMsg(const std::string &feedId, const std::string &msgId) +{ + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + std::map::iterator feedIt = mFeeds.find(feedId); + if (feedIt == mFeeds.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::removeMsg - feed " << feedId << " not found" << std::endl; +#endif + return false; + } + + RsFeedReaderFeed *fi = feedIt->second; + + std::map::iterator msgIt; + msgIt = fi->mMsgs.find(msgId); + if (msgIt == fi->mMsgs.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::removeMsg - msg " << msgId << " not found" << std::endl; +#endif + return false; + } + + msgIt->second->flag |= RS_FEEDMSG_FLAG_DELETED; + } + + IndicateConfigChanged(); + if (mNotify) { + mNotify->feedChanged(feedId, NOTIFY_TYPE_MOD); + mNotify->msgChanged(feedId, msgId, NOTIFY_TYPE_DEL); + } + + return true; +} + +bool p3FeedReader::removeMsgs(const std::string &feedId, const std::list &msgIds) +{ + std::list removedMsgs; + + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + std::map::iterator feedIt = mFeeds.find(feedId); + if (feedIt == mFeeds.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::removeMsgs - feed " << feedId << " not found" << std::endl; +#endif + return false; + } + + RsFeedReaderFeed *fi = feedIt->second; + + std::list::const_iterator idIt; + for (idIt = msgIds.begin(); idIt != msgIds.end(); ++idIt) { + std::map::iterator msgIt; + msgIt = fi->mMsgs.find(*idIt); + if (msgIt == fi->mMsgs.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::removeMsgs - msg " << *idIt << " not found" << std::endl; +#endif + continue; + } + + msgIt->second->flag |= RS_FEEDMSG_FLAG_DELETED; + + removedMsgs.push_back(*idIt); + } + } + + if (mNotify && !removedMsgs.empty()) { + mNotify->feedChanged(feedId, NOTIFY_TYPE_MOD); + + std::list::iterator it; + for (it = removedMsgs.begin(); it != removedMsgs.end(); ++it) { + mNotify->msgChanged(feedId, *it, NOTIFY_TYPE_DEL); + } + } + + return true; +} + +bool p3FeedReader::getMessageCount(const std::string &feedId, uint32_t *msgCount, uint32_t *newCount, uint32_t *unreadCount) +{ + if (msgCount) *msgCount = 0; + if (unreadCount) *unreadCount = 0; + if (newCount) *newCount = 0; + + if (!msgCount && !unreadCount && !newCount) { + return true; + } + + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + std::map::iterator feedIt = mFeeds.find(feedId); + if (feedIt == mFeeds.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::getMessageCount - feed " << feedId << " not found" << std::endl; +#endif + return false; + } + + RsFeedReaderFeed *fi = feedIt->second; + + std::map::iterator msgIt; + for (msgIt = fi->mMsgs.begin(); msgIt != fi->mMsgs.end(); ++msgIt) { + RsFeedReaderMsg *mi = msgIt->second; + + if (mi->flag & RS_FEEDMSG_FLAG_DELETED) { + continue; + } + + if (msgCount) ++(*msgCount); + if (newCount && (mi->flag & RS_FEEDMSG_FLAG_NEW)) ++(*newCount); + if (unreadCount && (mi->flag & RS_FEEDMSG_FLAG_READ) == 0) ++(*unreadCount); + } + + return true; +} + +bool p3FeedReader::getFeedMsgList(const std::string &feedId, std::list &msgInfos) +{ + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + std::map::iterator feedIt = mFeeds.find(feedId); + if (feedIt == mFeeds.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::getFeedMsgList - feed " << feedId << " not found" << std::endl; +#endif + return false; + } + + RsFeedReaderFeed *fi = feedIt->second; + + std::map::iterator msgIt; + for (msgIt = fi->mMsgs.begin(); msgIt != fi->mMsgs.end(); ++msgIt) { + RsFeedReaderMsg *mi = msgIt->second; + + if (mi->flag & RS_FEEDMSG_FLAG_DELETED) { + continue; + } + + FeedMsgInfo msgInfo; + feedMsgToInfo(mi, msgInfo); + msgInfos.push_back(msgInfo); + } + + return true; +} + +static bool canProcessFeed(RsFeedReaderFeed *fi) +{ + if (fi->flag & RS_FEED_FLAG_DEACTIVATED) { + /* deactivated */ + return false; + } + + if (fi->workstate != RsFeedReaderFeed::WAITING) { + /* should be working */ + return false; + } + + if (fi->flag & RS_FEED_FLAG_FOLDER) { + /* folder */ + return false; + } + + return true; +} + +bool p3FeedReader::processFeed(const std::string &feedId) +{ + std::list feedToDownload; + + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + std::map::iterator feedIt; + + if (feedId.empty()) { + /* process all feeds */ + for (feedIt = mFeeds.begin(); feedIt != mFeeds.end(); ++feedIt) { + RsFeedReaderFeed *fi = feedIt->second; + + if (!canProcessFeed(fi)) { + continue; + } + + /* add to download list */ + feedToDownload.push_back(fi->feedId); + fi->workstate = RsFeedReaderFeed::WAITING_TO_DOWNLOAD; + fi->content.clear(); + +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::processFeed - starting feed " << fi->feedId << " (" << fi->name << ")" << std::endl; +#endif + } + } else { + feedIt = mFeeds.find(feedId); + if (feedIt == mFeeds.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::processFeed - feed " << feedId << " not found" << std::endl; +#endif + return false; + } + + RsFeedReaderFeed *fi = feedIt->second; + if (fi->flag & RS_FEED_FLAG_FOLDER) { + std::list feedIds; + feedIds.push_back(fi->feedId); + while (!feedIds.empty()) { + std::string parentId = feedIds.front(); + feedIds.pop_front(); + + std::map::iterator feedIt1; + for (feedIt1 = mFeeds.begin(); feedIt1 != mFeeds.end(); ++feedIt1) { + RsFeedReaderFeed *fi1 = feedIt1->second; + + if (fi1->parentId == parentId) { + if (fi1->flag & RS_FEED_FLAG_FOLDER) { + feedIds.push_back(fi1->feedId); + } else { + if (canProcessFeed(fi1)) { + fi1->workstate = RsFeedReaderFeed::WAITING_TO_DOWNLOAD; + fi1->content.clear(); + + feedToDownload.push_back(fi1->feedId); +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::processFeed - starting feed " << fi1->feedId << " (" << fi1->name << ")" << std::endl; +#endif + } + } + } + } + } + } else { + if (canProcessFeed(fi)) { + fi->workstate = RsFeedReaderFeed::WAITING_TO_DOWNLOAD; + fi->content.clear(); + + feedToDownload.push_back(fi->feedId); +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::processFeed - starting feed " << fi->feedId << " (" << fi->name << ")" << std::endl; +#endif + } + } + } + } + + std::list notifyIds; + std::list::iterator it; + + if (!feedToDownload.empty()) { + RsStackMutex stack(mDownloadMutex); /******* LOCK STACK MUTEX *********/ + + for (it = feedToDownload.begin(); it != feedToDownload.end(); ++it) { + if (std::find(mDownloadFeeds.begin(), mDownloadFeeds.end(), *it) == mDownloadFeeds.end()) { + mDownloadFeeds.push_back(*it); + notifyIds.push_back(*it); + } + } + } + + if (mNotify) { + for (it = notifyIds.begin(); it != notifyIds.end(); ++it) { + mNotify->feedChanged(*it, NOTIFY_TYPE_MOD); + } + } + + return true; +} + +bool p3FeedReader::setMessageRead(const std::string &feedId, const std::string &msgId, bool read) +{ + bool changed = false; + + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + std::map::iterator feedIt = mFeeds.find(feedId); + if (feedIt == mFeeds.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setMessageRead - feed " << feedId << " not found" << std::endl; +#endif + return false; + } + + RsFeedReaderFeed *fi = feedIt->second; + + std::map::iterator msgIt; + msgIt = fi->mMsgs.find(msgId); + if (msgIt == fi->mMsgs.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setMessageRead - msg " << msgId << " not found" << std::endl; +#endif + return false; + } + + RsFeedReaderMsg *mi = msgIt->second; + uint32_t oldFlag = mi->flag; + mi->flag &= ~RS_FEEDMSG_FLAG_NEW; + if (read) { + /* remove flag new */ + mi->flag |= RS_FEEDMSG_FLAG_READ; + } else { + mi->flag &= ~RS_FEEDMSG_FLAG_READ; + } + + changed = (mi->flag != oldFlag); + } + + if (changed) { + IndicateConfigChanged(); + if (mNotify) { + mNotify->feedChanged(feedId, NOTIFY_TYPE_MOD); + mNotify->msgChanged(feedId, msgId, NOTIFY_TYPE_MOD); + } + } + + return true; +} + +/***************************************************************************/ +/****************************** p3Service **********************************/ +/***************************************************************************/ + +int p3FeedReader::tick() +{ + /* clean feeds */ + cleanFeeds(); + + time_t currentTime = time(NULL); + std::list feedToDownload; + std::map::iterator feedIt; + + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + for (feedIt = mFeeds.begin(); feedIt != mFeeds.end(); ++feedIt) { + RsFeedReaderFeed *fi = feedIt->second; + + if (!canProcessFeed(fi)) { + continue; + } + + uint32_t updateInterval; + if (fi->flag & RS_FEED_FLAG_STANDARD_UPDATE_INTERVAL) { + updateInterval = mStandardUpdateInterval; + } else { + updateInterval = fi->updateInterval; + } + if (fi->lastUpdate == 0 || fi->lastUpdate + (long) updateInterval <= currentTime) { + /* add to download list */ + feedToDownload.push_back(fi->feedId); + fi->workstate = RsFeedReaderFeed::WAITING_TO_DOWNLOAD; + fi->content.clear(); + +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::tick - starting feed " << fi->feedId << " (" << fi->name << ")" << std::endl; +#endif + } + } + } + + std::list notifyIds; + std::list::iterator it; + + if (!feedToDownload.empty()) { + RsStackMutex stack(mDownloadMutex); /******* LOCK STACK MUTEX *********/ + + for (it = feedToDownload.begin(); it != feedToDownload.end(); ++it) { + if (std::find(mDownloadFeeds.begin(), mDownloadFeeds.end(), *it) == mDownloadFeeds.end()) { + mDownloadFeeds.push_back(*it); + notifyIds.push_back(*it); + } + } + } + + if (mNotify) { + for (it = notifyIds.begin(); it != notifyIds.end(); ++it) { + mNotify->feedChanged(*it, NOTIFY_TYPE_MOD); + } + } + + return 0; +} + +void p3FeedReader::cleanFeeds() +{ + time_t currentTime = time(NULL); + + if (mLastClean == 0 || mLastClean + FEEDREADER_CLEAN_INTERVAL <= currentTime) { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + std::list > removedMsgIds; + std::map::iterator feedIt; + for (feedIt = mFeeds.begin(); feedIt != mFeeds.end(); ++feedIt) { + RsFeedReaderFeed *fi = feedIt->second; + + uint32_t storageTime = 0; + if (fi->flag & RS_FEED_FLAG_STANDARD_STORAGE_TIME) { + storageTime = mStandardStorageTime; + } else { + storageTime = fi->storageTime; + } + if (storageTime > 0) { + uint32_t removedMsgs = 0; + + std::map::iterator msgIt; + for (msgIt = fi->mMsgs.begin(); msgIt != fi->mMsgs.end(); ) { + RsFeedReaderMsg *mi = msgIt->second; + + if (mi->flag & RS_FEEDMSG_FLAG_DELETED) { + if (mi->pubDate < currentTime - (long) storageTime) { + removedMsgIds.push_back(std::pair (fi->feedId, mi->msgId)); + delete(mi); + std::map::iterator deleteIt = msgIt++; + fi->mMsgs.erase(deleteIt); + ++removedMsgs; + continue; + } + } + ++msgIt; + } +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::tick - feed " << fi->feedId << " (" << fi->name << ") cleaned, " << removedMsgs << " messages removed" << std::endl; +#endif + } + } + mLastClean = currentTime; + + if (removedMsgIds.size()) { + IndicateConfigChanged(); + + std::list >::iterator it; + for (it = removedMsgIds.begin(); it != removedMsgIds.end(); ++it) { + mNotify->msgChanged(it->first, it->second, NOTIFY_TYPE_DEL); + } + } + } +} + +/***************************************************************************/ +/****************************** p3Config ***********************************/ +/***************************************************************************/ + +RsSerialiser *p3FeedReader::setupSerialiser() +{ + RsSerialiser *rss = new RsSerialiser(); + + /* add in the types we need! */ + rss->addSerialType(new RsFeedReaderSerialiser()); + rss->addSerialType(new RsGeneralConfigSerialiser()); + + return rss; +} + +bool p3FeedReader::saveList(bool &cleanup, std::list & saveData) +{ + mFeedReaderMtx.lock(); /*********************** LOCK *******/ + + cleanup = false; + + RsConfigKeyValueSet *rskv = new RsConfigKeyValueSet(); + + RsTlvKeyValue kv; + kv.key = "StandardStorageTime"; + rs_sprintf(kv.value, "%u", mStandardStorageTime); + rskv->tlvkvs.pairs.push_back(kv); + + kv.key = "StandardUpdateInterval"; + rs_sprintf(kv.value, "%u", mStandardUpdateInterval); + rskv->tlvkvs.pairs.push_back(kv); + + kv.key = "StandardUseProxy"; + rs_sprintf(kv.value, "%hu", mStandardUseProxy ? 1 : 0); + rskv->tlvkvs.pairs.push_back(kv); + + kv.key = "StandardProxyAddress"; + rs_sprintf(kv.value, "%s", mStandardProxyAddress.c_str()); + rskv->tlvkvs.pairs.push_back(kv); + + kv.key = "StandardProxyPort"; + rs_sprintf(kv.value, "%hu", mStandardProxyPort); + rskv->tlvkvs.pairs.push_back(kv); + + /* Add KeyValue to saveList */ + saveData.push_back(rskv); + + std::map::iterator it1; + for (it1 = mFeeds.begin(); it1 != mFeeds.end(); ++it1) { + RsFeedReaderFeed *fi = it1->second; + saveData.push_back(fi); + + std::map::iterator it2; + for (it2 = fi->mMsgs.begin(); it2 != fi->mMsgs.end(); ++it2) { + saveData.push_back(it2->second); + } + } + + /* list completed! */ + return true; +} + +void p3FeedReader::saveDone() +{ + mFeedReaderMtx.unlock(); /*********************** UNLOCK *******/ + return; +} + +bool p3FeedReader::loadList(std::list& load) +{ + std::list::iterator it; + RsFeedReaderFeed *fi; + RsFeedReaderMsg *mi; + RsConfigKeyValueSet *rskv; + +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::loadList() Item Count: " << load.size(); + std::cerr << std::endl; +#endif + + mNextFeedId = 1; + mNextMsgId = 1; + + std::map msgs; + + for (it = load.begin(); it != load.end(); ++it) { + /* switch on type */ + if (NULL != (fi = dynamic_cast(*it))) { + uint32_t feedId = 0; + if (sscanf(fi->feedId.c_str(), "%u", &feedId) == 1) { + RsStackMutex stack(mFeedReaderMtx); /********** STACK LOCKED MTX ******/ + if (mFeeds.find(fi->feedId) != mFeeds.end()) { + /* feed with the same id exists */ + delete mFeeds[fi->feedId]; + } + mFeeds[fi->feedId] = fi; + + if (feedId + 1 > mNextFeedId) { + mNextFeedId = feedId + 1; + } + } else { + /* invalid feed id */ + delete(*it); + } + } else if (NULL != (mi = dynamic_cast(*it))) { + if (msgs.find(mi->msgId) != msgs.end()) { + delete msgs[mi->msgId]; + } + msgs[mi->msgId] = mi; + } else if (NULL != (rskv = dynamic_cast(*it))) { + std::list::iterator kit; + for(kit = rskv->tlvkvs.pairs.begin(); kit != rskv->tlvkvs.pairs.end(); kit++) { + if (kit->key == "StandardStorageTime") { + uint32_t value; + if (sscanf(kit->value.c_str(), "%u", &value) == 1) { + mStandardStorageTime = value; + } + } else if (kit->key == "StandardUpdateInterval") { + uint32_t value; + if (sscanf(kit->value.c_str(), "%u", &value) == 1) { + mStandardUpdateInterval = value; + } + } else if (kit->key == "StandardUseProxy") { + uint16_t value; + if (sscanf(kit->value.c_str(), "%hu", &value) == 1) { + mStandardUseProxy = value == 1 ? true : false; + } + } else if (kit->key == "StandardProxyAddress") { + mStandardProxyAddress = kit->value; + } else if (kit->key == "StandardProxyPort") { + uint16_t value; + if (sscanf(kit->value.c_str(), "%hu", &value) == 1) { + mStandardProxyPort = value; + } + } + } + } else { + /* cleanup */ + delete(*it); + } + } + + /* now sort msgs into feeds */ + RsStackMutex stack(mFeedReaderMtx); /********** STACK LOCKED MTX ******/ + + std::map::iterator it1; + for (it1 = msgs.begin(); it1 != msgs.end(); ++it1) { + uint32_t msgId = 0; + if (sscanf(it1->first.c_str(), "%u", &msgId) == 1) { + std::map::iterator it2 = mFeeds.find(it1->second->feedId); + if (it2 == mFeeds.end()) { + /* feed does not exist exists */ + delete it1->second; + continue; + } + it2->second->mMsgs[it1->first] = it1->second; + if (msgId + 1 > mNextMsgId) { + mNextMsgId = msgId + 1; + } + } else { + /* invalid msg id */ + delete(it1->second); + } + } + + return true; +} + +/***************************************************************************/ +/****************************** internal ***********************************/ +/***************************************************************************/ + +bool p3FeedReader::getFeedToDownload(RsFeedReaderFeed &feed) +{ + std::string feedId; + + { + RsStackMutex stack(mDownloadMutex); /******* LOCK STACK MUTEX *********/ + + if (mDownloadFeeds.empty()) { + /* nothing to download */ + return false; + } + + /* get next feed id to download */ + feedId = mDownloadFeeds.front(); + mDownloadFeeds.pop_front(); + } + + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + /* find feed */ + std::map::iterator it = mFeeds.find(feedId); + if (it == mFeeds.end()) { + /* feed not found */ +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::getFeedToDownload - feed " << feedId << " not found" << std::endl; +#endif + return false; + } + + if (it->second->workstate != RsFeedReaderFeed::WAITING_TO_DOWNLOAD) { + std::cerr << "p3FeedReader::getFeedToDownload - feed in wrong work state for download " << it->second->workstate << std::endl; + return false; + } + + /* set state to downloading */ + it->second->workstate = RsFeedReaderFeed::DOWNLOADING; + + /* return a copy of the feed */ + feed = *(it->second); + +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::getFeedToDownload - feed " << it->second->feedId << " (" << it->second->name << ") is starting to download" << std::endl; +#endif + } + + if (mNotify) { + mNotify->feedChanged(feedId, NOTIFY_TYPE_MOD); + } + + return true; +} + +void p3FeedReader::onDownloadSuccess(const std::string &feedId, const std::string &content, std::string &icon) +{ + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + /* find feed */ + std::map::iterator it = mFeeds.find(feedId); + if (it == mFeeds.end()) { + /* feed not found */ +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::onDownloadSuccess - feed " << feedId << " not found" << std::endl; +#endif + return; + } + + RsFeedReaderFeed *fi = it->second; + fi->workstate = RsFeedReaderFeed::WAITING_TO_PROCESS; + fi->content = content; + + if (fi->icon != icon) { + fi->icon = icon; + + IndicateConfigChanged(); + } + +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::onDownloadSuccess - feed " << fi->feedId << " (" << fi->name << ") add to process" << std::endl; +#endif + } + + { + RsStackMutex stack(mProcessMutex); /******* LOCK STACK MUTEX *********/ + + if (std::find(mProcessFeeds.begin(), mProcessFeeds.end(), feedId) == mProcessFeeds.end()) { + mProcessFeeds.push_back(feedId); + } + + } + + if (mNotify) { + mNotify->feedChanged(feedId, NOTIFY_TYPE_MOD); + } +} + +void p3FeedReader::onDownloadError(const std::string &feedId, p3FeedReaderThread::DownloadResult result, const std::string &error) +{ + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + /* find feed */ + std::map::iterator it = mFeeds.find(feedId); + if (it == mFeeds.end()) { + /* feed not found */ +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::onDownloadError - feed " << feedId << " not found" << std::endl; +#endif + return; + } + + RsFeedReaderFeed *fi = it->second; + fi->workstate = RsFeedReaderFeed::WAITING; + fi->lastUpdate = time(NULL); + fi->content.clear(); + + long todo; // sort error codes + switch (result) { + case p3FeedReaderThread::DOWNLOAD_SUCCESS: + /* this should not happen */ + std::cerr << "p3FeedReader::onDownloadError - success given as error" << std::endl; + fi->errorState = RS_FEED_ERRORSTATE_DOWNLOAD_INTERNAL_ERROR; + break; + case p3FeedReaderThread::DOWNLOAD_ERROR: + fi->errorState = RS_FEED_ERRORSTATE_DOWNLOAD_ERROR; + break; + case p3FeedReaderThread::DOWNLOAD_ERROR_INIT: + case p3FeedReaderThread::DOWNLOAD_INTERNAL_ERROR: + fi->errorState = RS_FEED_ERRORSTATE_DOWNLOAD_INTERNAL_ERROR; + break; + case p3FeedReaderThread::DOWNLOAD_UNKNOWN_CONTENT_TYPE: + fi->errorState = RS_FEED_ERRORSTATE_DOWNLOAD_UNKNOWN_CONTENT_TYPE; + break; + case p3FeedReaderThread::DOWNLOAD_NOT_FOUND: + fi->errorState = RS_FEED_ERRORSTATE_DOWNLOAD_NOT_FOUND; + break; + case p3FeedReaderThread::DOWNLOAD_UNKOWN_RESPONSE_CODE: + fi->errorState = RS_FEED_ERRORSTATE_DOWNLOAD_UNKOWN_RESPONSE_CODE; + break; + default: + fi->errorState = RS_FEED_ERRORSTATE_DOWNLOAD_INTERNAL_ERROR; + } + + fi->errorString = error; + +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::onDownloadError - feed " << fi->feedId << " (" << fi->name << ") error download, result = " << result << ", errorState = " << fi->errorState << ", error = " << error << std::endl; +#endif + + IndicateConfigChanged(); + } + + if (mNotify) { + mNotify->feedChanged(feedId, NOTIFY_TYPE_MOD); + } +} + +bool p3FeedReader::getFeedToProcess(RsFeedReaderFeed &feed) +{ + std::string feedId; + + { + RsStackMutex stack(mProcessMutex); /******* LOCK STACK MUTEX *********/ + + if (mProcessFeeds.empty()) { + /* nothing to process */ + return false; + } + + /* get next feed id to process */ + feedId = mProcessFeeds.front(); + mProcessFeeds.pop_front(); + } + + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + /* find feed */ + std::map::iterator it = mFeeds.find(feedId); + if (it == mFeeds.end()) { + /* feed not found */ +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::getFeedToProcess - feed " << feedId << " not found" << std::endl; +#endif + return false; + } + + if (it->second->workstate != RsFeedReaderFeed::WAITING_TO_PROCESS) { + std::cerr << "p3FeedReader::getFeedToProcess - feed in wrong state for process " << it->second->workstate << std::endl; + return false; + } + + RsFeedReaderFeed *fi = it->second; + + /* set state to processing */ + fi->workstate = RsFeedReaderFeed::PROCESSING; + fi->errorState = RS_FEED_ERRORSTATE_OK; + fi->errorString.clear(); + + /* return a copy of the feed */ + feed = *fi; + +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::getFeedToProcess - feed " << it->second->feedId << " (" << it->second->name << ") is starting to process" << std::endl; +#endif + } + + if (mNotify) { + mNotify->feedChanged(feedId, NOTIFY_TYPE_MOD); + } + + return true; +} + +void p3FeedReader::onProcessSuccess(const std::string &feedId, std::list &msgs) +{ +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::onProcessSuccess - feed " << feedId << " got " << msgs.size() << " messages" << std::endl; +#endif + + std::list addedMsgs; + std::string forumId; + std::list forumMsgs; + + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + /* find feed */ + std::map::iterator it = mFeeds.find(feedId); + if (it == mFeeds.end()) { + /* feed not found */ +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::onProcessSuccess - feed " << feedId << " not found" << std::endl; +#endif + return; + } + + RsFeedReaderFeed *fi = it->second; + bool forum = (fi->flag & RS_FEED_FLAG_FORUM); + uint32_t errorState = RS_FEED_ERRORSTATE_OK; + + if (forum) { + if (fi->forumId.empty()) { + /* create new forum */ + long todo; // search for existing forum? + + /* search for existing own forum */ +// std::list forumList; +// if (rsForums->getForumList(forumList)) { +// std::wstring wName = StringToWString(name); +// for (std::list::iterator it = forumList.begin(); it != forumList.end(); ++it) { +// if (it->forumName == wName) { +// std::cout << "DEBUG_RSS2FORUM: Found existing forum " << it->forumId << " for " << name << std::endl; +// return it->forumId; +// } +// } +// } + + std::wstring forumName; + librs::util::ConvertUtf8ToUtf16(fi->name, forumName); + std::wstring forumDescription; + librs::util::ConvertUtf8ToUtf16(fi->description, forumDescription); + /* create anonymous public forum */ + fi->forumId = rsForums->createForum(forumName, forumDescription, RS_DISTRIB_PUBLIC | RS_DISTRIB_AUTHEN_ANON); + + forumId = fi->forumId; + + if (fi->forumId.empty()) { + errorState = RS_FEED_ERRORSTATE_FORUM_CREATE; + +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::onProcessSuccess - can't create forum for feed " << feedId << " (" << it->second->name << ") - ignore all messages" << std::endl; + } else { + std::cerr << "p3FeedReader::onProcessSuccess - forum " << forumId << " (" << fi->name << ") created" << std::endl; +#endif + } + } else { + /* check forum */ + ForumInfo forumInfo; + if (rsForums->getForumInfo(fi->forumId, forumInfo)) { + if ((forumInfo.subscribeFlags & RS_DISTRIB_ADMIN) == 0) { + errorState = RS_FEED_ERRORSTATE_FORUM_NO_ADMIN; + } else if ((forumInfo.forumFlags & RS_DISTRIB_AUTHEN_REQ) || (forumInfo.forumFlags & RS_DISTRIB_AUTHEN_ANON) == 0) { + errorState = RS_FEED_ERRORSTATE_FORUM_NO_ANONYMOUS_FORUM; + } else { + forumId = fi->forumId; + } + } else { + errorState = RS_FEED_ERRORSTATE_FORUM_NOT_FOUND; + } + } + } + + /* process msgs */ +#ifdef FEEDREADER_DEBUG + uint32_t newMsgs = 0; +#endif + + if (errorState == RS_FEED_ERRORSTATE_OK) { + std::list::iterator newMsgIt; + for (newMsgIt = msgs.begin(); newMsgIt != msgs.end(); ) { + RsFeedReaderMsg *miNew = *newMsgIt; + /* search for exisiting msg */ + std::map::iterator msgIt; + for (msgIt = fi->mMsgs.begin(); msgIt != fi->mMsgs.end(); ++msgIt) { + RsFeedReaderMsg *mi = msgIt->second; + if (mi->title == miNew->title && mi->link == mi->link && mi->author == mi->author) { + /* msg exist */ + break; + } + } + if (msgIt == fi->mMsgs.end()) { + /* add new msg */ + rs_sprintf(miNew->msgId, "%lu", mNextMsgId++); + if (forum) { + miNew->flag = RS_FEEDMSG_FLAG_DELETED; + forumMsgs.push_back(*miNew); +// miNew->description.clear(); + } else { + miNew->flag = RS_FEEDMSG_FLAG_NEW; + addedMsgs.push_back(miNew->msgId); + } + fi->mMsgs[miNew->msgId] = miNew; + newMsgIt = msgs.erase(newMsgIt); + +#ifdef FEEDREADER_DEBUG + ++newMsgs; +#endif + } else { + /* msg was updated */ + ++newMsgIt; + } +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::onProcessSuccess - feed " << fi->feedId << " (" << fi->name << ") added " << newMsgs << "/" << msgs.size() << " messages" << std::endl; +#endif + } + } + + fi->workstate = RsFeedReaderFeed::WAITING; + fi->content.clear(); + fi->lastUpdate = time(NULL); + fi->errorState = errorState; + fi->errorString.clear(); + + IndicateConfigChanged(); + } + + if (!forumId.empty() && !forumMsgs.empty()) { + /* add messages as forum messages */ + std::list::iterator msgIt; + for (msgIt = forumMsgs.begin(); msgIt != forumMsgs.end(); ++msgIt) { + RsFeedReaderMsg &mi = *msgIt; + + /* convert to forum messages */ + ForumMsgInfo forumMsgInfo; + forumMsgInfo.forumId = forumId; + librs::util::ConvertUtf8ToUtf16(mi.title, forumMsgInfo.title); + + std::string description = mi.description; + /* add link */ + if (!mi.link.empty()) { + description += "
" + mi.link + ""; + } + librs::util::ConvertUtf8ToUtf16(description, forumMsgInfo.msg); + + if (rsForums->ForumMessageSend(forumMsgInfo)) { + /* set to new */ + rsForums->setMessageStatus(forumMsgInfo.forumId, forumMsgInfo.msgId, 0, FORUM_MSG_STATUS_MASK); + } else { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::onProcessSuccess - can't add forum message " << mi.title << " for feed " << forumId << std::endl; +#endif + } + } + } + + if (mNotify) { + mNotify->feedChanged(feedId, NOTIFY_TYPE_MOD); + + std::list::iterator it; + for (it = addedMsgs.begin(); it != addedMsgs.end(); ++it) { + mNotify->msgChanged(feedId, *it, NOTIFY_TYPE_ADD); + } + } +} + +void p3FeedReader::onProcessError(const std::string &feedId, p3FeedReaderThread::ProcessResult result) +{ + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + /* find feed */ + std::map::iterator it = mFeeds.find(feedId); + if (it == mFeeds.end()) { + /* feed not found */ +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::onProcessError - feed " << feedId << " not found" << std::endl; +#endif + return; + } + + RsFeedReaderFeed *fi = it->second; + fi->workstate = RsFeedReaderFeed::WAITING; + fi->lastUpdate = time(NULL); + fi->content.clear(); + + long todo; // sort error codes + switch (result) { + case p3FeedReaderThread::PROCESS_SUCCESS: + /* this should not happen */ + std::cerr << "p3FeedReader::onProcessError - success given as error" << std::endl; + fi->errorState = RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR; + break; + case p3FeedReaderThread::PROCESS_ERROR_INIT: + fi->errorState = RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR; + break; + default: + fi->errorState = RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR; + } + +// fi->errorString = error; + +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::onProcessError - feed " << fi->feedId << " (" << fi->name << ") error process, result = " << result << ", errorState = " << fi->errorState << std::endl; +#endif + + IndicateConfigChanged(); + } + + if (mNotify) { + mNotify->feedChanged(feedId, NOTIFY_TYPE_MOD); + } +} + +void p3FeedReader::setFeedInfo(const std::string &feedId, const std::string &name, const std::string &description) +{ + bool changed = false; + std::string forumId; + ForumInfo forumInfo; + + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + /* find feed */ + std::map::iterator it = mFeeds.find(feedId); + if (it == mFeeds.end()) { + /* feed not found */ +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setFeedInfo - feed " << feedId << " not found" << std::endl; +#endif + return; + } + + RsFeedReaderFeed *fi = it->second; + if (fi->name != name) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setFeedInfo - feed " << fi->feedId << " changed name from " << fi->name << " to " << name << std::endl; +#endif + fi->name = name; + changed = true; + } + if (fi->description != description) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setFeedInfo - feed " << fi->feedId << " changed description from " << fi->description << " to " << description << std::endl; +#endif + fi->description = description; + changed = true; + } + + if (changed && (fi->flag & RS_FEED_FLAG_FORUM) && (fi->flag & RS_FEED_FLAG_UPDATE_FORUM_INFO) && !fi->forumId.empty()) { + /* change forum too */ + forumId = fi->forumId; + librs::util::ConvertUtf8ToUtf16(fi->name, forumInfo.forumName); + librs::util::ConvertUtf8ToUtf16(fi->description, forumInfo.forumDesc); + } + } + + if (changed) { + IndicateConfigChanged(); + + if (mNotify) { + mNotify->feedChanged(feedId, NOTIFY_TYPE_MOD); + } + } + + if (!forumId.empty()) { + /* name or description changed, update forum */ + if (!rsForums->setForumInfo(forumId, forumInfo)) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setFeed - can't change forum " << forumId << std::endl; +#endif + } + } +} diff --git a/plugins/FeedReader/services/p3FeedReader.h b/plugins/FeedReader/services/p3FeedReader.h new file mode 100644 index 000000000..2e62e16da --- /dev/null +++ b/plugins/FeedReader/services/p3FeedReader.h @@ -0,0 +1,113 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + + #ifndef P3_FEEDREADER +#define P3_FEEDREADER + +#include "retroshare/rsplugin.h" +#include "plugins/rspqiservice.h" +#include "interface/rsFeedReader.h" +#include "p3FeedReaderThread.h" + +class RsFeedReaderFeed; + +//TODO: get new id's +const uint8_t RS_PKT_TYPE_FEEDREADER_CONFIG = 0xf0; +const uint32_t CONFIG_TYPE_FEEDREADER = 0x0001; + +class p3FeedReader : public RsPQIService, public RsFeedReader +{ +public: + p3FeedReader(RsPluginHandler *pgHandler); + + /****************** FeedReader Interface *************/ + virtual void stop(); + virtual void setNotify(RsFeedReaderNotify *notify); + + virtual uint32_t getStandardStorageTime(); + virtual void setStandardStorageTime(uint32_t storageTime); + virtual uint32_t getStandardUpdateInterval(); + virtual void setStandardUpdateInterval(uint32_t updateInterval); + virtual bool getStandardProxy(std::string &proxyAddress, uint16_t &proxyPort); + virtual void setStandardProxy(bool useProxy, const std::string &proxyAddress, uint16_t proxyPort); + + virtual RsFeedAddResult addFolder(const std::string parentId, const std::string &name, std::string &feedId); + virtual RsFeedAddResult setFolder(const std::string &feedId, const std::string &name); + virtual RsFeedAddResult addFeed(const FeedInfo &feedInfo, std::string &feedId); + virtual RsFeedAddResult setFeed(const std::string &feedId, const FeedInfo &feedInfo); + virtual bool removeFeed(const std::string &feedId); + virtual void getFeedList(const std::string &parentId, std::list &feedInfos); + virtual bool getFeedInfo(const std::string &feedId, FeedInfo &feedInfo); + virtual bool getMsgInfo(const std::string &feedId, const std::string &msgId, FeedMsgInfo &msgInfo); + virtual bool removeMsg(const std::string &feedId, const std::string &msgId); + virtual bool removeMsgs(const std::string &feedId, const std::list &msgIds); + virtual bool getMessageCount(const std::string &feedId, uint32_t *msgCount, uint32_t *newCount, uint32_t *unreadCount); + virtual bool getFeedMsgList(const std::string &feedId, std::list &msgInfos); + virtual bool processFeed(const std::string &feedId); + virtual bool setMessageRead(const std::string &feedId, const std::string &msgId, bool read); + + /****************** p3Service STUFF ******************/ + virtual int tick(); + + /****************** internal STUFF *******************/ + bool getFeedToDownload(RsFeedReaderFeed &feed); + void onDownloadSuccess(const std::string &feedId, const std::string &content, std::string &icon); + void onDownloadError(const std::string &feedId, p3FeedReaderThread::DownloadResult result, const std::string &error); + void onProcessSuccess(const std::string &feedId, std::list &msgs); + void onProcessError(const std::string &feedId, p3FeedReaderThread::ProcessResult result); + + bool getFeedToProcess(RsFeedReaderFeed &feed); + + void setFeedInfo(const std::string &feedId, const std::string &name, const std::string &description); + +protected: + /****************** p3Config STUFF *******************/ + virtual RsSerialiser *setupSerialiser(); + virtual bool saveList(bool &cleanup, std::list&); + virtual bool loadList(std::list& load); + virtual void saveDone(); + +private: + void cleanFeeds(); + void deleteAllMsgs_locked(RsFeedReaderFeed *fi); + + std::list mThreads; + uint32_t mNextFeedId; + uint32_t mNextMsgId; + time_t mLastClean; + RsFeedReaderNotify *mNotify; + + RsMutex mFeedReaderMtx; + uint32_t mStandardUpdateInterval; + uint32_t mStandardStorageTime; + bool mStandardUseProxy; + std::string mStandardProxyAddress; + uint16_t mStandardProxyPort; + std::map mFeeds; + + RsMutex mDownloadMutex; + std::list mDownloadFeeds; + + RsMutex mProcessMutex; + std::list mProcessFeeds; +}; + +#endif diff --git a/plugins/FeedReader/services/p3FeedReaderThread.cc b/plugins/FeedReader/services/p3FeedReaderThread.cc new file mode 100644 index 000000000..02215368e --- /dev/null +++ b/plugins/FeedReader/services/p3FeedReaderThread.cc @@ -0,0 +1,1024 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include "p3FeedReaderThread.h" +#include "rsFeedReaderItems.h" +#include "util/rsstring.h" + +#include +#include +#include + +enum FeedFormat { FORMAT_RSS, FORMAT_RDF }; + +/********* + * #define FEEDREADER_DEBUG + *********/ + +p3FeedReaderThread::p3FeedReaderThread(p3FeedReader *feedReader, Type type) : RsThread(), mFeedReader(feedReader), mType(type) +{ + if (type == PROCESS) { + mCharEncodingHandler = xmlFindCharEncodingHandler ("UTF8"); + + if (!mCharEncodingHandler) { + /* no encoding handler found */ + std::cerr << "p3FeedReaderThread::p3FeedReaderThread - no encoding handler found" << std::endl; + } + } else { + mCharEncodingHandler = NULL; + } +} + +/***************************************************************************/ +/****************************** Thread *************************************/ +/***************************************************************************/ + +void p3FeedReaderThread::run() +{ + while (isRunning()) { +#ifdef WIN32 + Sleep(1000); +#else + usleep(1000000); +#endif + /* every second */ + + switch (mType) { + case DOWNLOAD: + { + RsFeedReaderFeed feed; + if (mFeedReader->getFeedToDownload(feed)) { + std::string content; + std::string icon; + std::string error; + + DownloadResult result = download(feed, content, icon, error); + if (result == DOWNLOAD_SUCCESS) { + mFeedReader->onDownloadSuccess(feed.feedId, content, icon); + } else { + mFeedReader->onDownloadError(feed.feedId, result, error); + } + } + } + break; + case PROCESS: + { + RsFeedReaderFeed feed; + if (mFeedReader->getFeedToProcess(feed)) { + std::list entries; + std::string error; + + ProcessResult result = process(feed, entries, error); + if (result == PROCESS_SUCCESS) { + mFeedReader->onProcessSuccess(feed.feedId, entries); + } else { + mFeedReader->onProcessError(feed.feedId, result); + } + + std::list::iterator it; + for (it = entries.begin(); it != entries.end(); ++it) { + delete (*it); + } + entries.clear(); + } + } + break; + } + } +} + +/***************************************************************************/ +/****************************** Download ***********************************/ +/***************************************************************************/ + +static size_t writeFunctionString (void *ptr, size_t size, size_t nmemb, void *stream) +{ + std::string *s = (std::string*) stream; + s->append ((char*) ptr, size * nmemb); + + return nmemb * size; +} + +static size_t writeFunctionBinary (void *ptr, size_t size, size_t nmemb, void *stream) +{ + std::vector *bytes = (std::vector*) stream; + + std::vector newBytes; + newBytes.resize(size * nmemb); + memcpy(newBytes.data(), ptr, newBytes.size()); + + bytes->insert(bytes->end(), newBytes.begin(), newBytes.end()); + + return nmemb * size; +} + +static int progressCallback (void *clientp, double /*dltotal*/, double /*dlnow*/, double /*ultotal*/, double /*ulnow*/) +{ + p3FeedReaderThread *thread = (p3FeedReaderThread*) clientp; + + if (!thread->isRunning()) { + /* thread was stopped */ + return 1; + } + + long todo; // show progress in gui + + return 0; +} + +static bool getFavicon (std::string url, const std::string &proxy, std::string &icon) +{ + icon.clear(); + + if (url.substr(0, 7) == "http://") { + int found = url.find("/", 7); + if (found >= 0) { + url.erase(found, url.length() - found); + } + } else { + return false; + } + + bool result = false; + + CURL *curl = curl_easy_init(); + if (curl) { + url += "/favicon.ico"; + + std::vector vicon; + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeFunctionBinary); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &vicon); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); + curl_easy_setopt(curl, CURLOPT_COOKIESESSION, 1); + + if (!proxy.empty()) { + curl_easy_setopt(curl, CURLOPT_PROXY, proxy.c_str()); + } + + CURLcode code = curl_easy_perform(curl); + if (code == CURLE_OK) { + long response; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response); + if (response == 200) { + char *contentType = NULL; + curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &contentType); + if (contentType && + (strnicmp(contentType, "image/x-icon", 12) == 0 || + strnicmp(contentType, "application/octet-stream", 24) == 0 || + strnicmp(contentType, "text/plain", 10) == 0)) { + if (!vicon.empty()) { + long todo; // check it + // Set up a base64 encoding BIO that writes to a memory BIO + BIO *b64 = BIO_new(BIO_f_base64()); + if (b64) { + BIO *out = BIO_new(BIO_s_mem()); + if (out) { + BIO_set_flags(out, BIO_CLOSE); // probably redundant + b64 = BIO_push(b64, out); + // Send the data + BIO_write(b64, vicon.data(), vicon.size()); + // Collect the encoded data + BIO_flush(b64); + char* temp; + int count = BIO_get_mem_data(out, &temp); + if (count && temp) { + icon = temp; + result = true; + } + } + BIO_free_all(b64); + } + } +// char *encode = NULL; +// size_t encodeSize = 0; +// code = Curl_base64_encode(curl, (const char*) vicon.data(), vicon.size(), &encode, &encodeSize); +// if (code == CURLE_OK && encodeSize) { +// icon = encode; +// free(encode); +// encode = NULL; +// result = true; +// } + } + } + } + + curl_easy_cleanup(curl); + curl = NULL; + } + + return result; +} + +p3FeedReaderThread::DownloadResult p3FeedReaderThread::download(const RsFeedReaderFeed &feed, std::string &content, std::string &icon, std::string &error) +{ +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::download - feed " << feed.feedId << " (" << feed.name << ")" << std::endl; +#endif + + content.clear(); + error.clear(); + + DownloadResult result; + + CURL *curl = curl_easy_init(); + if (curl) { + std::string proxy; + if (feed.flag & RS_FEED_FLAG_STANDARD_PROXY) { + std::string standardProxyAddress; + uint16_t standardProxyPort; + if (mFeedReader->getStandardProxy(standardProxyAddress, standardProxyPort)) { + rs_sprintf(proxy, "%s:%u", standardProxyAddress.c_str(), standardProxyPort); + } + } else { + if (!feed.proxyAddress.empty() && feed.proxyPort) { + rs_sprintf(proxy, "%s:%u", feed.proxyAddress.c_str(), feed.proxyPort); + } + } + + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progressCallback); + curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(curl, CURLOPT_URL, feed.url.c_str()); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeFunctionString); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &content); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); + + if (!proxy.empty()) { + curl_easy_setopt(curl, CURLOPT_PROXY, proxy.c_str()); + } + + CURLcode code = curl_easy_perform(curl); + if (code == CURLE_OK) { + long response; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response); + if (response == 200) { + char *contentType = NULL; + curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &contentType); + if (contentType && + (strnicmp(contentType, "text/xml", 8) == 0 || + strnicmp(contentType, "application/rss+xml", 19) == 0 || + strnicmp(contentType, "application/xml", 15) == 0 || + strnicmp(contentType, "application/xhtml+xml", 21) == 0)) { + /* ok */ + result = DOWNLOAD_SUCCESS; + } else { + result = DOWNLOAD_UNKNOWN_CONTENT_TYPE; + error = contentType ? contentType : ""; + } + } else if (response == 404) { + result = DOWNLOAD_NOT_FOUND; + } else { + result = DOWNLOAD_UNKOWN_RESPONSE_CODE; + rs_sprintf(error, "%ld", response); + } + } else { + result = DOWNLOAD_ERROR; + error = curl_easy_strerror(code); + } + + curl_easy_cleanup(curl); + curl = NULL; + + getFavicon(feed.url, proxy, icon); + } else { + result = DOWNLOAD_ERROR_INIT; + } + +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::download - feed " << feed.feedId << " (" << feed.name << "), result " << result << ", error = " << error << std::endl; +#endif + + return result; +} + +/***************************************************************************/ +/****************************** Process ************************************/ +/***************************************************************************/ + +static bool convertOutput(xmlCharEncodingHandlerPtr charEncodingHandler, const xmlChar *output, std::string &text) +{ + if (!output) { + return false; + } + + if (charEncodingHandler == NULL || charEncodingHandler->output == NULL) { + return false; + } + + bool result = false; + int sizeOut = xmlStrlen(output) + 1; + int sizeIn = sizeOut * 2 - 1; + char *input = (char*) malloc(sizeIn * sizeof(char)); + + if (input) { + int temp = sizeOut - 1; + int ret = charEncodingHandler->output((xmlChar*) input, &sizeIn, (const xmlChar *) output, &temp); + if ((ret < 0) || (temp - sizeOut + 1)) { + if (ret < 0) { + std::cerr << "convertOutput: conversion wasn't successful." << std::endl; + } else { + std::cerr << "convertOutput: conversion wasn't successful. converted: " << temp << " octets." << std::endl; + } + } else { + text.assign(input, sizeIn); + result = true; + } + + free(input); + input = NULL; + } else { + std::cerr << "convertOutput: no mem" << std::endl; + } + + return result; +} + +static xmlNodePtr findNode(xmlNodePtr node, const char *name, bool children = false) +{ + if (node->name) { + if (xmlStrcasecmp (node->name, (xmlChar*) name) == 0) { + return node; + } + } + + xmlNodePtr nodeFound = NULL; + if (children) { + if (node->children) { + nodeFound = findNode(node->children, name, children); + if (nodeFound) { + return nodeFound; + } + } + } + + if (node->next) { + nodeFound = findNode(node->next, name, children); + if (nodeFound) { + return nodeFound; + } + } + + return NULL; +} + +static xmlNodePtr getNextItem(FeedFormat feedFormat, xmlNodePtr channel, xmlNodePtr item) +{ + if (!channel) { + return NULL; + } + + if (!item) { + switch (feedFormat) { + case FORMAT_RSS: + item = channel->children; + break; + case FORMAT_RDF: + item = channel->next; + break; + default: + return NULL; + } + } else { + item = item->next; + } + for (; item; item = item->next) { + if (item->type == XML_ELEMENT_NODE && xmlStrcasecmp (item->name, (xmlChar*) "item") == 0) { + break; + } + } + + return item; +} + +static bool getChildText(/*xmlCharEncodingHandlerPtr*/ void *charEncodingHandler, xmlNodePtr node, const char *childName, std::string &text) +{ + if (node == NULL || node->children == NULL) { + return FALSE; + } + + xmlNodePtr child = findNode(node->children, childName, true); + if (!child) { + return false; + } + + if (child->type != XML_ELEMENT_NODE) { + return false; + } + + if (!child->children) { + return false; + } + + if (child->children->type != XML_TEXT_NODE) { + return false; + } + + if (child->children->content) { + return convertOutput((xmlCharEncodingHandlerPtr) charEncodingHandler, child->children->content, text); + } + + return true; +} + +static void splitString(std::string s, std::vector &v, const char d) +{ + v.clear(); + + std::string::size_type p; + while ((p = s.find_first_of(d)) != std::string::npos) { + v.push_back(s.substr(0, p)); + s.erase(0, p + 1); + } + if (!s.empty()) { + v.push_back(s); + } +} + +static unsigned int ymdhms_to_seconds(int year, int mon, int day, int hour, int minute, int second) +{ + if (sizeof(time_t) == 4) + { + if ((time_t)-1 < 0) + { + if (year >= 2038) + { + year = 2038; + mon = 0; + day = 1; + hour = 0; + minute = 0; + second = 0; + } + } + else + { + if (year >= 2115) + { + year = 2115; + mon = 0; + day = 1; + hour = 0; + minute = 0; + second = 0; + } + } + } + + unsigned int ret = (day - 32075) /* days */ + + 1461L * (year + 4800L + (mon - 14) / 12) / 4 + + 367 * (mon - 2 - (mon - 14) / 12 * 12) / 12 + - 3 * ((year + 4900L + (mon - 14) / 12) / 100) / 4 + - 2440588; + ret = 24*ret + hour; /* hours */ + ret = 60*ret + minute; /* minutes */ + ret = 60*ret + second; /* seconds */ + + return ret; +} + +static const char haystack[37]="janfebmaraprmayjunjulaugsepoctnovdec"; + +// we follow the recommendation of rfc2822 to consider all +// obsolete time zones not listed here equivalent to "-0000" +static const struct { + const char tzName[4]; + int tzOffset; +} known_zones[] = { + { "UT", 0 }, + { "GMT", 0 }, + { "EST", -300 }, + { "EDT", -240 }, + { "CST", -360 }, + { "CDT", -300 }, + { "MST", -420 }, + { "MDT", -360 }, + { "PST", -480 }, + { "PDT", -420 }, + { { 0,0,0,0 }, 0 } +}; + +// copied from KRFCDate::parseDate +static time_t parseRFC822Date(const std::string &pubDate) +{ + if (pubDate.empty()) + return 0; + + // This parse a date in the form: + // Wednesday, 09-Nov-99 23:12:40 GMT + // or + // Sat, 01-Jan-2000 08:00:00 GMT + // or + // Sat, 01 Jan 2000 08:00:00 GMT + // or + // 01 Jan 99 22:00 +0100 (exceptions in rfc822/rfc2822) + // + // We ignore the weekday + // + time_t result = 0; + int offset = 0; + char *newPosStr; + const char *dateString = pubDate.c_str(); + int day = 0; + char monthStr[4]; + int month = -1; + int year = 0; + int hour = 0; + int minute = 0; + int second = 0; + + // Strip leading space + while(*dateString && isspace(*dateString)) + dateString++; + + // Strip weekday + while(*dateString && !isdigit(*dateString) && !isspace(*dateString)) + dateString++; + + // Strip trailing space + while(*dateString && isspace(*dateString)) + dateString++; + + if (!*dateString) + return result; // Invalid date + + if (isalpha(*dateString)) + { + // ' Nov 5 1994 18:15:30 GMT' + // Strip leading space + while(*dateString && isspace(*dateString)) + dateString++; + + for(int i=0; i < 3;i++) + { + if (!*dateString || (*dateString == '-') || isspace(*dateString)) + return result; // Invalid date + monthStr[i] = tolower(*dateString++); + } + monthStr[3] = '\0'; + + newPosStr = (char*)strstr(haystack, monthStr); + + if (!newPosStr) + return result; // Invalid date + + month = (newPosStr-haystack)/3; // Jan=00, Feb=01, Mar=02, .. + + if ((month < 0) || (month > 11)) + return result; // Invalid date + + while (*dateString && isalpha(*dateString)) + dateString++; // Skip rest of month-name + } + + // ' 09-Nov-99 23:12:40 GMT' + // ' 5 1994 18:15:30 GMT' + day = strtol(dateString, &newPosStr, 10); + dateString = newPosStr; + + if ((day < 1) || (day > 31)) + return result; // Invalid date; + + if (!*dateString) + return result; // Invalid date + + while(*dateString && (isspace(*dateString) || (*dateString == '-'))) + dateString++; + + if (month == -1) + { + for(int i=0; i < 3;i++) + { + if (!*dateString || (*dateString == '-') || isspace(*dateString)) + return result; // Invalid date + monthStr[i] = tolower(*dateString++); + } + monthStr[3] = '\0'; + + newPosStr = (char*)strstr(haystack, monthStr); + + if (!newPosStr) + return result; // Invalid date + + month = (newPosStr-haystack)/3; // Jan=00, Feb=01, Mar=02, .. + + if ((month < 0) || (month > 11)) + return result; // Invalid date + + while (*dateString && isalpha(*dateString)) + dateString++; // Skip rest of month-name + + } + + // '-99 23:12:40 GMT' + while(*dateString && (isspace(*dateString) || (*dateString == '-'))) + dateString++; + + if (!*dateString || !isdigit(*dateString)) + return result; // Invalid date + + // '99 23:12:40 GMT' + year = strtol(dateString, &newPosStr, 10); + dateString = newPosStr; + + // Y2K: Solve 2 digit years + if ((year >= 0) && (year < 50)) + year += 2000; + + if ((year >= 50) && (year < 100)) + year += 1900; // Y2K + + if ((year < 1900) || (year > 2500)) + return result; // Invalid date + + // Don't fail if the time is missing. + if (*dateString) + { + // ' 23:12:40 GMT' + if (!isspace(*dateString++)) + return result; // Invalid date + + hour = strtol(dateString, &newPosStr, 10); + dateString = newPosStr; + + if ((hour < 0) || (hour > 23)) + return result; // Invalid date + + if (!*dateString) + return result; // Invalid date + + // ':12:40 GMT' + if (*dateString++ != ':') + return result; // Invalid date + + minute = strtol(dateString, &newPosStr, 10); + dateString = newPosStr; + + if ((minute < 0) || (minute > 59)) + return result; // Invalid date + + if (!*dateString) + return result; // Invalid date + + // ':40 GMT' + if (*dateString != ':' && !isspace(*dateString)) + return result; // Invalid date + + // seconds are optional in rfc822 + rfc2822 + if (*dateString ==':') { + dateString++; + + second = strtol(dateString, &newPosStr, 10); + dateString = newPosStr; + + if ((second < 0) || (second > 59)) + return result; // Invalid date + } else { + dateString++; + } + + while(*dateString && isspace(*dateString)) + dateString++; + } + + // don't fail if the time zone is missing, some + // broken mail-/news-clients omit the time zone + if (*dateString) { + if ((strncasecmp(dateString, "gmt", 3) == 0) || + (strncasecmp(dateString, "utc", 3) == 0)) + { + dateString += 3; + while(*dateString && isspace(*dateString)) + dateString++; + } + + if ((*dateString == '+') || (*dateString == '-')) { + offset = strtol(dateString, &newPosStr, 10); + if (abs(offset) < 30) + { + dateString = newPosStr; + + offset = offset * 100; + + if (*dateString && *(dateString+1)) + { + dateString++; + int minutes = strtol(dateString, &newPosStr, 10); + if (offset > 0) + offset += minutes; + else + offset -= minutes; + } + } + + if ((offset < -9959) || (offset > 9959)) + return result; // Invalid date + + int sgn = (offset < 0)? -1:1; + offset = abs(offset); + offset = ((offset / 100)*60 + (offset % 100))*sgn; + } else { + for (int i=0; known_zones[i].tzName != 0; i++) { + if (0 == strncasecmp(dateString, known_zones[i].tzName, strlen(known_zones[i].tzName))) { + offset = known_zones[i].tzOffset; + break; + } + } + } + } + + result = ymdhms_to_seconds(year, month+1, day, hour, minute, second); + + // avoid negative time values + if ((offset > 0) && (offset > result)) + offset = 0; + + result -= offset*60; + + // If epoch 0 return epoch +1 which is Thu, 01-Jan-70 00:00:01 GMT + // This is so that parse error and valid epoch 0 return values won't + // be the same for sensitive applications... + if (result < 1) result = 1; + + return result; +} + +// copied and converted to std::string from KRFCDate::parseDateISO8601 +static time_t parseISO8601Date(const std::string &pubDate) +{ + if (pubDate.empty()) { + return 0; + } + + // These dates look like this: + // YYYY-MM-DDTHH:MM:SS + // But they may also have 0, 1 or 2 suffixes. + // Suffix 1: .secfrac (fraction of second) + // Suffix 2: Either 'Z' or +zone or -zone, where zone is HHMM + + unsigned int year = 0; + unsigned int month = 0; + unsigned int mday = 0; + unsigned int hour = 0; + unsigned int min = 0; + unsigned int sec = 0; + + int offset = 0; + + std::string input = pubDate; + + // First find the 'T' separator, if any. + int tPos = input.find('T'); + + // If there is no time, no month or no day specified, fill those missing + // fields so that 'input' matches YYYY-MM-DDTHH:MM:SS + if (-1 == tPos) { + int dashes = 0; + std::string::iterator it; + for (it = input.begin(); it != input.end(); ++it) { + if (*it == '-') { + ++dashes; + } + } + if (0 == dashes) { + input += "-01-01"; + } else if (1 == dashes) { + input += "-01"; + } + tPos = input.length(); + input += "T12:00:00"; + } + + // Now parse the date part. + + std::string dateString = input.substr(0, tPos);//.stripWhiteSpace(); + + std::string timeString = input.substr(tPos + 1);//.stripWhiteSpace(); + + std::vector l; + splitString(dateString, l, '-'); + + if (l.size() < 3) + return 0; + + sscanf(l[0].c_str(), "%u", &year); + sscanf(l[1].c_str(), "%u", &month); + sscanf(l[2].c_str(), "%u", &mday); + + // Z suffix means UTC. + if ('Z' == timeString[timeString.length() - 1]) { + timeString.erase(timeString.length() - 1, 1); + } + + // +zone or -zone suffix (offset from UTC). + + int plusPos = timeString.find_last_of('+'); + + if (-1 != plusPos) { + std::string offsetString = timeString.substr(plusPos + 1); + + unsigned int offsetHour; + unsigned int offsetMinute; + + sscanf(offsetString.substr(0, 1).c_str(), "%u", &offsetHour); + sscanf(offsetString.substr(offsetString.length() - 2).c_str(), "%u", &offsetMinute); + + offset = offsetHour * 60 + offsetMinute; + + timeString = timeString.substr(0, plusPos); + } else { + int minusPos = timeString.find_last_of('-'); + + if (-1 != minusPos) { + std::string offsetString = timeString.substr(minusPos + 1); + + unsigned int offsetHour; + unsigned int offsetMinute; + + sscanf(offsetString.substr(0, 1).c_str(), "%u", &offsetHour); + sscanf(offsetString.substr(offsetString.length() - 2).c_str(), "%u", &offsetMinute); + + timeString = timeString.substr(0, minusPos); + } + } + + // secfrac suffix. + int dotPos = timeString.find_last_of('.'); + + if (-1 != dotPos) { + timeString = timeString.substr(0, dotPos); + } + + // Now parse the time part. + + splitString(timeString, l, ':'); + + if (l.size() < 3) + return 0; + + sscanf(l[0].c_str(), "%u", &hour); + sscanf(l[1].c_str(), "%u", &min); + sscanf(l[2].c_str(), "%u", &sec); + + time_t result = ymdhms_to_seconds(year, month, mday, hour, min, sec); + + // avoid negative time values + if ((offset > 0) && (offset > result)) + offset = 0; + + result -= offset*60; + + // If epoch 0 return epoch +1 which is Thu, 01-Jan-70 00:00:01 GMT + // This is so that parse error and valid epoch 0 return values won't + // be the same for sensitive applications... + if (result < 1) result = 1; + + return result; +} + +p3FeedReaderThread::ProcessResult p3FeedReaderThread::process(const RsFeedReaderFeed &feed, std::list &entries, std::string &error) +{ +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::process - feed " << feed.feedId << " (" << feed.name << ")" << std::endl; +#endif + + ProcessResult result = PROCESS_SUCCESS; + + xmlDocPtr document = xmlReadDoc((const xmlChar*) feed.content.c_str(), "", NULL, XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_COMPACT | XML_PARSE_NOCDATA); + if (document) { + xmlNodePtr root = xmlDocGetRootElement(document); + if (root) { + FeedFormat feedFormat; + if (xmlStrcmp (root->name, (xmlChar*) "rss") == 0) { + feedFormat = FORMAT_RSS; + } else if (xmlStrcmp (root->name, (xmlChar*) "rdf") != 0) { + feedFormat = FORMAT_RDF; + } else { + result = PROCESS_UNKNOWN_FORMAT; + error = "Only RSS or RDF supported"; + } + + if (result == PROCESS_SUCCESS) { + xmlNodePtr channel = findNode(root->children, "channel"); + if (channel) { + /* import header info */ + if (feed.flag & RS_FEED_FLAG_INFO_FROM_FEED) { + std::string title; + if (getChildText(mCharEncodingHandler, channel, "title", title) && !title.empty()) { + std::string::size_type p; + while ((p = title.find_first_of("\r\n")) != std::string::npos) { + title.erase(p, 1); + } + std::string description; + getChildText(mCharEncodingHandler, channel, "description", description); + mFeedReader->setFeedInfo(feed.feedId, title, description); + } + } + + /* get item count */ + xmlNodePtr node; + for (node = NULL; (node = getNextItem(feedFormat, channel, node)) != NULL; ) { + if (!isRunning()) { + break; + } + + std::string title; + if (!getChildText(mCharEncodingHandler, node, "title", title) || title.empty()) { + continue; + } + + /* remove newlines */ + std::string::size_type p; + while ((p = title.find_first_of("\r\n")) != std::string::npos) { + title.erase(p, 1); + } + + RsFeedReaderMsg *item = new RsFeedReaderMsg(); + item->msgId.clear(); // is calculated later + item->feedId = feed.feedId; + item->title = title; + + getChildText(mCharEncodingHandler, node, "link", item->link); + + long todo; // remove sid +// // remove sid= +// CString sLinkUpper = sLink; +// sLinkUpper.MakeUpper (); +// int nSIDStart = sLinkUpper.Find (TEXT("SID=")); +// if (nSIDStart != -1) { +// int nSIDEnd1 = sLinkUpper.Find (TEXT(";"), nSIDStart); +// int nSIDEnd2 = sLinkUpper.Find (TEXT("#"), nSIDStart); + +// if (nSIDEnd1 == -1) { +// nSIDEnd1 = sLinkUpper.GetLength (); +// } +// if (nSIDEnd2 == -1) { +// nSIDEnd2 = sLinkUpper.GetLength (); +// } + +// if (nSIDStart > 0 && sLinkUpper [nSIDStart - 1] == '&') { +// nSIDStart--; +// } + +// int nSIDEnd = min (nSIDEnd1, nSIDEnd2); +// sLink.Delete (nSIDStart, nSIDEnd - nSIDStart); +// } + + getChildText(mCharEncodingHandler, node, "author", item->author); + getChildText(mCharEncodingHandler, node, "description", item->description); + + std::string pubDate; + if (getChildText(mCharEncodingHandler, node, "pubdate", pubDate)) { + item->pubDate = parseRFC822Date(pubDate); + } + if (getChildText(mCharEncodingHandler, node, "date", pubDate)) { + item->pubDate = parseISO8601Date (pubDate); + } + + if (item->pubDate == 0) { + /* use current time */ + item->pubDate = time(NULL); + } + + entries.push_back(item); + } + } else { + result = PROCESS_UNKNOWN_FORMAT; + error = "Channel not found"; + } + } + } else { + result = PROCESS_UNKNOWN_FORMAT; + error = "Can't read document"; + } + + xmlFreeDoc(document); + } else { + result = PROCESS_ERROR_INIT; + } + +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::process - feed " << feed.feedId << " (" << feed.name << "), result " << result << ", error = " << error << std::endl; +#endif + + return result; +} diff --git a/plugins/FeedReader/services/p3FeedReaderThread.h b/plugins/FeedReader/services/p3FeedReaderThread.h new file mode 100644 index 000000000..f27213bad --- /dev/null +++ b/plugins/FeedReader/services/p3FeedReaderThread.h @@ -0,0 +1,71 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + + #ifndef P3_FEEDREADERTHREAD +#define P3_FEEDREADERTHREAD + +#include "util/rsthreads.h" +#include + +class p3FeedReader; +class RsFeedReaderFeed; +class RsFeedReaderMsg; + +class p3FeedReaderThread : public RsThread +{ +public: + enum Type + { + DOWNLOAD, + PROCESS + }; + enum DownloadResult + { + DOWNLOAD_SUCCESS, + DOWNLOAD_ERROR_INIT, + DOWNLOAD_ERROR, + DOWNLOAD_UNKNOWN_CONTENT_TYPE, + DOWNLOAD_NOT_FOUND, + DOWNLOAD_UNKOWN_RESPONSE_CODE, + DOWNLOAD_INTERNAL_ERROR + }; + enum ProcessResult + { + PROCESS_SUCCESS, + PROCESS_ERROR_INIT, + PROCESS_UNKNOWN_FORMAT + }; + +public: + p3FeedReaderThread(p3FeedReader *feedReader, Type type); + +private: + virtual void run(); + + DownloadResult download(const RsFeedReaderFeed &feed, std::string &content, std::string &icon, std::string &error); + ProcessResult process(const RsFeedReaderFeed &feed, std::list &entries, std::string &error); + + p3FeedReader *mFeedReader; + Type mType; + /*xmlCharEncodingHandlerPtr*/ void *mCharEncodingHandler; +}; + +#endif diff --git a/plugins/FeedReader/services/rsFeedReaderItems.cc b/plugins/FeedReader/services/rsFeedReaderItems.cc new file mode 100644 index 000000000..8b6222994 --- /dev/null +++ b/plugins/FeedReader/services/rsFeedReaderItems.cc @@ -0,0 +1,388 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include "serialiser/rsbaseserial.h" +#include "serialiser/rstlvbase.h" +#include "rsFeedReaderItems.h" + +/*************************************************************************/ + +RsFeedReaderFeed::RsFeedReaderFeed() : RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_FEEDREADER_CONFIG, RS_PKT_SUBTYPE_FEEDREADER_FEED) +{ + clear(); +} + +void RsFeedReaderFeed::clear() +{ + feedId.clear(); + parentId.clear(); + name.clear(); + url.clear(); + user.clear(); + password.clear(); + proxyAddress.clear(); + proxyPort = 0; + updateInterval = 0; + lastUpdate = 0; + storageTime = 0; + flag = 0; + forumId.clear(); + description.clear(); + icon.clear(); + errorState = RS_FEED_ERRORSTATE_OK; + errorString.clear(); + + workstate = WAITING; + content.clear(); +} + +std::ostream &RsFeedReaderFeed::print(std::ostream &out, uint16_t /*indent*/) +{ + return out; +} + +uint32_t RsFeedReaderSerialiser::sizeFeed(RsFeedReaderFeed *item) +{ + uint32_t s = 8; /* header */ + s += GetTlvStringSize(item->feedId); + s += GetTlvStringSize(item->parentId); + s += GetTlvStringSize(item->url); + s += GetTlvStringSize(item->name); + s += GetTlvStringSize(item->description); + s += GetTlvStringSize(item->icon); + s += GetTlvStringSize(item->user); + s += GetTlvStringSize(item->password); + s += GetTlvStringSize(item->proxyAddress); + s += sizeof(uint16_t); /* proxyPort */ + s += sizeof(uint32_t); /* updateInterval */ + s += sizeof(time_t); /* lastscan */ + s += sizeof(uint32_t); /* storageTime */ + s += sizeof(uint32_t); /* flag */ + s += GetTlvStringSize(item->forumId); + s += sizeof(uint32_t); /* errorstate */ + s += GetTlvStringSize(item->errorString); + + return s; +} + +/* serialise the data to the buffer */ +bool RsFeedReaderSerialiser::serialiseFeed(RsFeedReaderFeed *item, void *data, uint32_t *pktsize) +{ + uint32_t tlvsize = sizeFeed(item); + uint32_t offset = 0; + + if (*pktsize < tlvsize) + return false; /* not enough space */ + + *pktsize = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* add values */ + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_GENID, item->feedId); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->parentId); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_LINK, item->url); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, item->name); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_COMMENT, item->description); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->icon); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->user); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->password); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->proxyAddress); + ok &= setRawUInt16(data, tlvsize, &offset, item->proxyPort); + ok &= setRawUInt32(data, tlvsize, &offset, item->updateInterval); + ok &= setRawUInt32(data, tlvsize, &offset, item->lastUpdate); + ok &= setRawUInt32(data, tlvsize, &offset, item->storageTime); + ok &= setRawUInt32(data, tlvsize, &offset, item->flag); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->forumId); + ok &= setRawUInt32(data, tlvsize, &offset, item->errorState); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->errorString); + + if (offset != tlvsize) + { + ok = false; + std::cerr << "RsFeedReaderSerialiser::serialiseFeed() Size Error! " << std::endl; + } + + return ok; +} + +RsFeedReaderFeed *RsFeedReaderSerialiser::deserialiseFeed(void *data, uint32_t *pktsize) +{ + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + if ((RS_PKT_VERSION1 != getRsItemVersion(rstype)) || + (RS_PKT_CLASS_CONFIG != getRsItemClass(rstype)) || + (RS_PKT_TYPE_FEEDREADER_CONFIG != getRsItemType(rstype)) || + (RS_PKT_SUBTYPE_FEEDREADER_FEED != getRsItemSubType(rstype))) + { + return NULL; /* wrong type */ + } + + if (*pktsize < rssize) /* check size */ + return NULL; /* not enough data */ + + /* set the packet length */ + *pktsize = rssize; + + bool ok = true; + + /* ready to load */ + RsFeedReaderFeed *item = new RsFeedReaderFeed(); + item->clear(); + + /* skip the header */ + offset += 8; + + /* get values */ + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_GENID, item->feedId); + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_VALUE, item->parentId); + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_LINK, item->url); + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, item->name); + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_COMMENT, item->description); + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_VALUE, item->icon); + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_VALUE, item->user); + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_VALUE, item->password); + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_VALUE, item->proxyAddress); + ok &= getRawUInt16(data, rssize, &offset, &(item->proxyPort)); + ok &= getRawUInt32(data, rssize, &offset, &(item->updateInterval)); + ok &= getRawUInt32(data, rssize, &offset, (uint32_t*) &(item->lastUpdate)); + ok &= getRawUInt32(data, rssize, &offset, &(item->storageTime)); + ok &= getRawUInt32(data, rssize, &offset, &(item->flag)); + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_VALUE, item->forumId); + ok &= getRawUInt32(data, rssize, &offset, &(item->errorState)); + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_VALUE, item->errorString); + + if (offset != rssize) + { + /* error */ + delete item; + return NULL; + } + + if (!ok) + { + delete item; + return NULL; + } + + return item; +} + +/*************************************************************************/ + +RsFeedReaderMsg::RsFeedReaderMsg() : RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_FEEDREADER_CONFIG, RS_PKT_SUBTYPE_FEEDREADER_MSG) +{ + clear(); +} + +void RsFeedReaderMsg::clear() +{ + msgId.clear(); + feedId.clear(); + title.clear(); + link.clear(); + author.clear(); + description.clear(); + pubDate = 0; + flag = 0; +} + +std::ostream &RsFeedReaderMsg::print(std::ostream &out, uint16_t /*indent*/) +{ + return out; +} + +uint32_t RsFeedReaderSerialiser::sizeMsg(RsFeedReaderMsg *item) +{ + uint32_t s = 8; /* header */ + s += GetTlvStringSize(item->msgId); + s += GetTlvStringSize(item->feedId); + s += GetTlvStringSize(item->title); + s += GetTlvStringSize(item->link); + s += GetTlvStringSize(item->author); + s += GetTlvStringSize(item->description); + s += sizeof(time_t); /* pubDate */ + s += sizeof(uint32_t); /* flag */ + + return s; +} + +/* serialise the data to the buffer */ +bool RsFeedReaderSerialiser::serialiseMsg(RsFeedReaderMsg *item, void *data, uint32_t *pktsize) +{ + uint32_t tlvsize = sizeMsg(item); + uint32_t offset = 0; + + if (*pktsize < tlvsize) + return false; /* not enough space */ + + *pktsize = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* add values */ + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_GENID, item->msgId); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->feedId); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, item->title); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_LINK, item->link); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->author); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_COMMENT, item->description); + ok &= setRawUInt32(data, tlvsize, &offset, item->pubDate); + ok &= setRawUInt32(data, tlvsize, &offset, item->flag); + + if (offset != tlvsize) + { + ok = false; + std::cerr << "RsFeedReaderSerialiser::serialiseMsg() Size Error! " << std::endl; + } + + return ok; +} + +RsFeedReaderMsg *RsFeedReaderSerialiser::deserialiseMsg(void *data, uint32_t *pktsize) +{ + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + if ((RS_PKT_VERSION1 != getRsItemVersion(rstype)) || + (RS_PKT_CLASS_CONFIG != getRsItemClass(rstype)) || + (RS_PKT_TYPE_FEEDREADER_CONFIG != getRsItemType(rstype)) || + (RS_PKT_SUBTYPE_FEEDREADER_MSG != getRsItemSubType(rstype))) + { + return NULL; /* wrong type */ + } + + if (*pktsize < rssize) /* check size */ + return NULL; /* not enough data */ + + /* set the packet length */ + *pktsize = rssize; + + bool ok = true; + + /* ready to load */ + RsFeedReaderMsg *item = new RsFeedReaderMsg(); + item->clear(); + + /* skip the header */ + offset += 8; + + /* get values */ + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_GENID, item->msgId); + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_VALUE, item->feedId); + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, item->title); + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_LINK, item->link); + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_VALUE, item->author); + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_COMMENT, item->description); + ok &= getRawUInt32(data, rssize, &offset, (uint32_t*) &(item->pubDate)); + ok &= getRawUInt32(data, rssize, &offset, &(item->flag)); + + if (offset != rssize) + { + /* error */ + delete item; + return NULL; + } + + if (!ok) + { + delete item; + return NULL; + } + + return item; +} + +/*************************************************************************/ + +uint32_t RsFeedReaderSerialiser::size(RsItem *item) +{ + RsFeedReaderFeed *fi; + RsFeedReaderMsg *ei; + + if (NULL != (fi = dynamic_cast(item))) + { + return sizeFeed((RsFeedReaderFeed*) item); + } + if (NULL != (ei = dynamic_cast(item))) + { + return sizeMsg((RsFeedReaderMsg*) item); + } + + return 0; +} + +bool RsFeedReaderSerialiser::serialise(RsItem *item, void *data, uint32_t *pktsize) +{ + RsFeedReaderFeed *fi; + RsFeedReaderMsg *ei; + + if (NULL != (fi = dynamic_cast(item))) + { + return serialiseFeed((RsFeedReaderFeed*) item, data, pktsize); + } + if (NULL != (ei = dynamic_cast(item))) + { + return serialiseMsg((RsFeedReaderMsg*) item, data, pktsize); + } + + return false; +} + +RsItem *RsFeedReaderSerialiser::deserialise(void *data, uint32_t *pktsize) +{ + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + + if ((RS_PKT_VERSION1 != getRsItemVersion(rstype)) || + (RS_PKT_CLASS_CONFIG != getRsItemClass(rstype)) || + (RS_PKT_TYPE_FEEDREADER_CONFIG != getRsItemType(rstype))) + { + return NULL; /* wrong type */ + } + + switch (getRsItemSubType(rstype)) + { + case RS_PKT_SUBTYPE_FEEDREADER_FEED: + return deserialiseFeed(data, pktsize); + case RS_PKT_SUBTYPE_FEEDREADER_MSG: + return deserialiseMsg(data, pktsize); + } + + return NULL; +} diff --git a/plugins/FeedReader/services/rsFeedReaderItems.h b/plugins/FeedReader/services/rsFeedReaderItems.h new file mode 100644 index 000000000..92c911864 --- /dev/null +++ b/plugins/FeedReader/services/rsFeedReaderItems.h @@ -0,0 +1,149 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + + #ifndef RS_FEEDREADER_ITEMS_H +#define RS_FEEDREADER_ITEMS_H + +#include "serialiser/rsserial.h" +#include "serialiser/rstlvtypes.h" + +#include "p3FeedReader.h" + +const uint8_t RS_PKT_SUBTYPE_FEEDREADER_FEED = 0x02; +const uint8_t RS_PKT_SUBTYPE_FEEDREADER_MSG = 0x03; + +/**************************************************************************/ + +#define RS_FEED_ERRORSTATE_OK 0 +#define RS_FEED_ERRORSTATE_DOWNLOAD_INTERNAL_ERROR 1 +#define RS_FEED_ERRORSTATE_DOWNLOAD_ERROR 2 +#define RS_FEED_ERRORSTATE_DOWNLOAD_UNKNOWN_CONTENT_TYPE 3 +#define RS_FEED_ERRORSTATE_DOWNLOAD_NOT_FOUND 4 +#define RS_FEED_ERRORSTATE_DOWNLOAD_UNKOWN_RESPONSE_CODE 5 + +#define RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR 50 + +#define RS_FEED_ERRORSTATE_FORUM_CREATE 100 +#define RS_FEED_ERRORSTATE_FORUM_NOT_FOUND 101 +#define RS_FEED_ERRORSTATE_FORUM_NO_ADMIN 102 +#define RS_FEED_ERRORSTATE_FORUM_NO_ANONYMOUS_FORUM 103 + +#define RS_FEED_FLAG_FOLDER 0x001 +#define RS_FEED_FLAG_INFO_FROM_FEED 0x002 +#define RS_FEED_FLAG_STANDARD_STORAGE_TIME 0x004 +#define RS_FEED_FLAG_STANDARD_UPDATE_INTERVAL 0x008 +#define RS_FEED_FLAG_STANDARD_PROXY 0x010 +#define RS_FEED_FLAG_AUTHENTICATION 0x020 +#define RS_FEED_FLAG_DEACTIVATED 0x040 +#define RS_FEED_FLAG_FORUM 0x080 +#define RS_FEED_FLAG_UPDATE_FORUM_INFO 0x100 + +class RsFeedReaderFeed : public RsItem +{ +public: + enum WorkState { + WAITING, + WAITING_TO_DOWNLOAD, + DOWNLOADING, + WAITING_TO_PROCESS, + PROCESSING + }; + +public: + RsFeedReaderFeed(); + virtual ~RsFeedReaderFeed() {} + + virtual void clear(); + virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); + + std::string feedId; + std::string parentId; + std::string name; + std::string url; + std::string user; + std::string password; + std::string proxyAddress; + uint16_t proxyPort; + uint32_t updateInterval; + time_t lastUpdate; + uint32_t flag; // RS_FEED_FLAG_... + std::string forumId; + uint32_t storageTime; + std::string description; + std::string icon; + uint32_t errorState; + std::string errorString; + + /* Not Serialised */ + WorkState workstate; + std::string content; + + std::map mMsgs; +}; + +#define RS_FEEDMSG_FLAG_DELETED 1 +#define RS_FEEDMSG_FLAG_NEW 2 +#define RS_FEEDMSG_FLAG_READ 4 + +class RsFeedReaderMsg : public RsItem +{ +public: + RsFeedReaderMsg(); + virtual ~RsFeedReaderMsg() {} + + virtual void clear(); + virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); + + std::string msgId; + std::string feedId; + std::string title; + std::string link; + std::string author; + std::string description; + time_t pubDate; + uint32_t flag; // RS_FEEDMSG_FLAG_... +}; + +class RsFeedReaderSerialiser: public RsSerialType +{ +public: + RsFeedReaderSerialiser() : RsSerialType(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_FEEDREADER_CONFIG) {} + virtual ~RsFeedReaderSerialiser() {} + + virtual uint32_t size(RsItem *item); + virtual bool serialise(RsItem *item, void *data, uint32_t *size); + virtual RsItem *deserialise(void *data, uint32_t *size); + +private: + /* For RS_PKT_SUBTYPE_FEEDREADER_FEED */ + virtual uint32_t sizeFeed(RsFeedReaderFeed *item); + virtual bool serialiseFeed(RsFeedReaderFeed *item, void *data, uint32_t *size); + virtual RsFeedReaderFeed *deserialiseFeed(void *data, uint32_t *size); + + /* For RS_PKT_SUBTYPE_FEEDREADER_MSG */ + virtual uint32_t sizeMsg(RsFeedReaderMsg *item); + virtual bool serialiseMsg(RsFeedReaderMsg *item, void *data, uint32_t *size); + virtual RsFeedReaderMsg *deserialiseMsg(void *data, uint32_t *size); +}; + +/**************************************************************************/ + +#endif diff --git a/plugins/plugins.pro b/plugins/plugins.pro index 37b804d8c..a8840da6e 100644 --- a/plugins/plugins.pro +++ b/plugins/plugins.pro @@ -2,4 +2,5 @@ TEMPLATE = subdirs SUBDIRS += \ LinksCloud \ - VOIP + VOIP \ + FeedReader diff --git a/retroshare-gui/src/gui/MainWindow.cpp b/retroshare-gui/src/gui/MainWindow.cpp index 98b95a182..0d97b5fd5 100644 --- a/retroshare-gui/src/gui/MainWindow.cpp +++ b/retroshare-gui/src/gui/MainWindow.cpp @@ -323,10 +323,7 @@ MainWindow::MainWindow(QWidget* parent, Qt::WFlags flags) addAction(new QAction(QIcon(IMAGE_UNFINISHED), tr("Unfinished"), ui.toolBar), SLOT(showApplWindow())); #endif - if (activatePage((Page) Settings->getLastPageInMainWindow()) == false) { - /* Select the first action */ - grp->actions()[0]->setChecked(true); - } + ui.stackPages->setCurrentIndex(Settings->getLastPageInMainWindow()); /** StatusBar section ********/ /* initialize combobox in status bar */ @@ -388,7 +385,7 @@ MainWindow::MainWindow(QWidget* parent, Qt::WFlags flags) /** Destructor. */ MainWindow::~MainWindow() { - Settings->setLastPageInMainWindow(getActivatePage()); + Settings->setLastPageInMainWindow(ui.stackPages->currentIndex()); delete peerstatus; delete natstatus; From d220e14c4a37ce3fdb0c2468269ed132de2612b6 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Fri, 3 Aug 2012 06:39:50 +0000 Subject: [PATCH 013/222] fresh recompile needed! TokenQueueV2 added, first change to photoshare to deal with gxs backend needed to redirect meta types to mine in order to get compilation working and definition fixes to rsgenexchange. Next step is to get GxsRunner going git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5377 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgenexchange.h | 3 +- libretroshare/src/gxs/rsgxs.h | 8 +- libretroshare/src/gxs/rsgxsdataaccess.cc | 15 ++ libretroshare/src/gxs/rstokenservice.h | 22 +++ libretroshare/src/libretroshare.pro | 3 + libretroshare/src/retroshare/rsidentity.h | 153 ++++++++-------- libretroshare/src/retroshare/rsphotoV2.h | 4 +- libretroshare/src/serialiser/rsgxsitems.h | 3 + .../src/services/p3photoserviceV2.cc | 26 +-- .../src/gui/PhotoShare/PhotoAddDialog.cpp | 25 +-- .../src/gui/PhotoShare/PhotoAddDialog.h | 10 +- .../src/gui/PhotoShare/PhotoDialog.cpp | 41 +++-- .../src/gui/PhotoShare/PhotoDialog.h | 14 +- .../src/gui/PhotoShare/PhotoItem.cpp | 2 +- retroshare-gui/src/gui/PhotoShare/PhotoItem.h | 2 +- .../src/gui/PhotoShare/PhotoSlideShow.cpp | 18 +- .../src/gui/PhotoShare/PhotoSlideShow.h | 11 +- .../src/gui/unfinished/ApplicationWindow.cpp | 8 +- retroshare-gui/src/util/TokenQueue.h | 3 +- retroshare-gui/src/util/TokenQueueV2.cpp | 173 ++++++++++++++++++ retroshare-gui/src/util/TokenQueueV2.h | 102 +++++++++++ 21 files changed, 490 insertions(+), 156 deletions(-) create mode 100644 retroshare-gui/src/util/TokenQueueV2.cpp create mode 100644 retroshare-gui/src/util/TokenQueueV2.h diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index ad2aa7e37..4ef50131b 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -32,6 +32,7 @@ #include "rsgds.h" #include "rsnxs.h" #include "rsgxsdataaccess.h" +#include "rsnxsobserver.h" #include "retroshare/rsgxsservice.h" #include "serialiser/rsnxsitems.h" @@ -58,7 +59,7 @@ typedef std::map > GxsMsgMetaMap; * Also notifications are made here on receipt of new data from * connected peers */ -class RsGenExchange : public RsGxsService +class RsGenExchange : public RsGxsService, public RsNxsObserver { public: diff --git a/libretroshare/src/gxs/rsgxs.h b/libretroshare/src/gxs/rsgxs.h index dfa565a32..9c70c8759 100644 --- a/libretroshare/src/gxs/rsgxs.h +++ b/libretroshare/src/gxs/rsgxs.h @@ -31,6 +31,7 @@ * */ +#include "serialiser/rsnxsitems.h" #include #include @@ -38,7 +39,6 @@ #include #include -#include "rsnxsobserver.h" typedef std::map > GxsMsgReq; typedef std::map > GxsMsgIdResult; @@ -46,13 +46,13 @@ typedef std::map > GxsMsgMetaResult typedef std::map > NxsMsgDataResult; typedef std::map > GxsMsgResult; // -class RsGxsService : public RsNxsObserver +class RsGxsService { public: - RsGxsService(); - virtual ~RsGxsService(); + RsGxsService(){} + virtual ~RsGxsService(){} virtual void tick() = 0; diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index 2ea9e7129..5b113b285 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -891,6 +891,21 @@ void RsGxsDataAccess::tokenList(std::list& tokens) { } } +bool RsGxsDataAccess::updateRequestStatus(const uint32_t& token, + const uint32_t& status) { + + RsStackMutex stack(mDataMutex); + + GxsRequest* req = retrieveRequest(token); + + if(req) + req->status = status; + else + return false; + + return true; +} + bool RsGxsDataAccess::checkMsgFilter(const RsTokReqOptions& opts, const RsGxsMsgMetaData* meta) const { bool statusMatch = false; diff --git a/libretroshare/src/gxs/rstokenservice.h b/libretroshare/src/gxs/rstokenservice.h index 7b7acc1b6..ee8835b11 100644 --- a/libretroshare/src/gxs/rstokenservice.h +++ b/libretroshare/src/gxs/rstokenservice.h @@ -40,6 +40,28 @@ #define GXS_REQUEST_TYPE_MSG_META 0x00100000 #define GXS_REQUEST_TYPE_MSG_IDS 0x00200000 + + +// This bit will be filled out over time. +#define RS_TOKREQOPT_MSG_VERSIONS 0x0001 // MSGRELATED: Returns All MsgIds with OrigMsgId = MsgId. +#define RS_TOKREQOPT_MSG_ORIGMSG 0x0002 // MSGLIST: All Unique OrigMsgIds in a Group. +#define RS_TOKREQOPT_MSG_LATEST 0x0004 // MSGLIST: All Latest MsgIds in Group. MSGRELATED: Latest MsgIds for Input Msgs. + +#define RS_TOKREQOPT_MSG_THREAD 0x0010 // MSGRELATED: All Msgs in Thread. MSGLIST: All Unique Thread Ids in Group. +#define RS_TOKREQOPT_MSG_PARENT 0x0020 // MSGRELATED: All Children Msgs. + +#define RS_TOKREQOPT_MSG_AUTHOR 0x0040 // MSGLIST: Messages from this AuthorId + +// Read Status. +#define RS_TOKREQOPT_READ 0x0001 +#define RS_TOKREQOPT_UNREAD 0x0002 + +#define RS_TOKREQ_ANSTYPE_LIST 0x0001 +#define RS_TOKREQ_ANSTYPE_SUMMARY 0x0002 +#define RS_TOKREQ_ANSTYPE_DATA 0x0003 + + + /*! * This class provides useful generic support for GXS style services. * I expect much of this will be incorporated into the base GXS. diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index de151c9a3..70ec2bed2 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -673,6 +673,7 @@ HEADERS += serialiser/rsnxsitems.h \ gxs/rsgxsdataaccess.h \ retroshare/rsgxsservice.h \ serialiser/rsgxsitems.h \ + serialiser/rsphotov2items.h \ util/retrodb.h SOURCES += serialiser/rsnxsitems.cc \ @@ -680,8 +681,10 @@ SOURCES += serialiser/rsnxsitems.cc \ gxs/rsgenexchange.cc \ gxs/rsgxsnetservice.cc \ gxs/rsgxsdata.cc \ + serialiser/rsgxsitems.cc \ services/p3photoserviceV2.cc \ gxs/rsgxsdataaccess.cc \ + serialiser/rsphotov2items.cc \ util/retrodb.cc } diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index 9f82890f9..8ae3a2550 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -215,83 +215,84 @@ class RsTokReqOptions #define RSGXS_MAX_SERVICE_STRING 200 // Sensible limit for dbase usage. +#include "serialiser/rsgxsitems.h" -class RsGroupMetaData -{ - public: - - RsGroupMetaData() - { - mGroupFlags = 0; - mSignFlags = 0; - mSubscribeFlags = 0; - - mPop = 0; - mMsgCount = 0; - mLastPost = 0; - mGroupStatus = 0; - - //mPublishTs = 0; - } - - std::string mGroupId; - std::string mGroupName; - uint32_t mGroupFlags; // Service Specific Options ???? - uint32_t mSignFlags; // Combination of RSGXS_GROUP_SIGN_PUBLISH_MASK & RSGXS_GROUP_SIGN_AUTHOR_MASK. - - time_t mPublishTs; // Mandatory. - std::string mAuthorId; // Optional. - - // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. - - uint32_t mSubscribeFlags; - - uint32_t mPop; // HOW DO WE DO THIS NOW. - uint32_t mMsgCount; // ??? - time_t mLastPost; // ??? - - uint32_t mGroupStatus; - - std::string mServiceString; // Service Specific Free-Form extra storage. -}; - - - - -class RsMsgMetaData -{ - public: - - RsMsgMetaData() - { - mPublishTs = 0; - mMsgFlags = 0; - mMsgStatus = 0; - mChildTs = 0; - } - - std::string mGroupId; - std::string mMsgId; - - std::string mThreadId; - std::string mParentId; - std::string mOrigMsgId; - - std::string mAuthorId; - - std::string mMsgName; - time_t mPublishTs; - - uint32_t mMsgFlags; // Whats this for? (Optional Service Specific - e.g. flag MsgType) - - // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. - // normally READ / UNREAD flags. LOCAL Data. - uint32_t mMsgStatus; - time_t mChildTs; - - std::string mServiceString; // Service Specific Free-Form extra storage. - -}; +//class RsGroupMetaData +//{ +// public: +// +// RsGroupMetaData() +// { +// mGroupFlags = 0; +// mSignFlags = 0; +// mSubscribeFlags = 0; +// +// mPop = 0; +// mMsgCount = 0; +// mLastPost = 0; +// mGroupStatus = 0; +// +// //mPublishTs = 0; +// } +// +// std::string mGroupId; +// std::string mGroupName; +// uint32_t mGroupFlags; // Service Specific Options ???? +// uint32_t mSignFlags; // Combination of RSGXS_GROUP_SIGN_PUBLISH_MASK & RSGXS_GROUP_SIGN_AUTHOR_MASK. +// +// time_t mPublishTs; // Mandatory. +// std::string mAuthorId; // Optional. +// +// // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. +// +// uint32_t mSubscribeFlags; +// +// uint32_t mPop; // HOW DO WE DO THIS NOW. +// uint32_t mMsgCount; // ??? +// time_t mLastPost; // ??? +// +// uint32_t mGroupStatus; +// +// std::string mServiceString; // Service Specific Free-Form extra storage. +//}; +// +// +// +// +//class RsMsgMetaData +//{ +// public: +// +// RsMsgMetaData() +// { +// mPublishTs = 0; +// mMsgFlags = 0; +// mMsgStatus = 0; +// mChildTs = 0; +// } +// +// std::string mGroupId; +// std::string mMsgId; +// +// std::string mThreadId; +// std::string mParentId; +// std::string mOrigMsgId; +// +// std::string mAuthorId; +// +// std::string mMsgName; +// time_t mPublishTs; +// +// uint32_t mMsgFlags; // Whats this for? (Optional Service Specific - e.g. flag MsgType) +// +// // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. +// // normally READ / UNREAD flags. LOCAL Data. +// uint32_t mMsgStatus; +// time_t mChildTs; +// +// std::string mServiceString; // Service Specific Free-Form extra storage. +// +//}; std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta); std::ostream &operator<<(std::ostream &out, const RsMsgMetaData &meta); diff --git a/libretroshare/src/retroshare/rsphotoV2.h b/libretroshare/src/retroshare/rsphotoV2.h index c69c2db91..1ae59bed9 100644 --- a/libretroshare/src/retroshare/rsphotoV2.h +++ b/libretroshare/src/retroshare/rsphotoV2.h @@ -32,8 +32,8 @@ #include "rsgxsservice.h" /* The Main Interface Class - for information about your Peers */ -class RsPhoto; -extern RsPhoto *rsPhoto; +class RsPhotoV2; +extern RsPhotoV2 *rsPhotoV2; /******************* NEW STUFF FOR NEW CACHE SYSTEM *********/ diff --git a/libretroshare/src/serialiser/rsgxsitems.h b/libretroshare/src/serialiser/rsgxsitems.h index f13ca774b..a74c29c17 100644 --- a/libretroshare/src/serialiser/rsgxsitems.h +++ b/libretroshare/src/serialiser/rsgxsitems.h @@ -57,6 +57,7 @@ class RsGroupMetaData std::string mGroupId; std::string mGroupName; uint32_t mGroupFlags; + uint32_t mSignFlags; // Combination of RSGXS_GROUP_SIGN_PUBLISH_MASK & RSGXS_GROUP_SIGN_AUTHOR_MASK. time_t mPublishTs; // Mandatory. std::string mAuthorId; // Optional. @@ -70,6 +71,7 @@ class RsGroupMetaData time_t mLastPost; // ??? uint32_t mGroupStatus; + std::string mServiceString; // Service Specific Free-Form extra storage. }; @@ -109,6 +111,7 @@ class RsMsgMetaData // normally READ / UNREAD flags. LOCAL Data. uint32_t mMsgStatus; time_t mChildTs; + std::string mServiceString; // Service Specific Free-Form extra storage. }; diff --git a/libretroshare/src/services/p3photoserviceV2.cc b/libretroshare/src/services/p3photoserviceV2.cc index f961452e4..31ec27ec0 100644 --- a/libretroshare/src/services/p3photoserviceV2.cc +++ b/libretroshare/src/services/p3photoserviceV2.cc @@ -1,6 +1,8 @@ #include "p3photoserviceV2.h" #include "serialiser/rsphotov2items.h" +RsPhotoV2 *rsPhotoV2 = NULL; + p3PhotoServiceV2::p3PhotoServiceV2(RsGeneralDataService* gds, RsNetworkExchangeService* nes) : RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_TYPE_PHOTO) { @@ -10,31 +12,31 @@ p3PhotoServiceV2::p3PhotoServiceV2(RsGeneralDataService* gds, RsNetworkExchangeS bool p3PhotoServiceV2::updated() { return false; -} +} void p3PhotoServiceV2::groupsChanged(std::list& grpIds) { -} +} void p3PhotoServiceV2::msgsChanged( std::map >& msgs) { -} +} RsTokenServiceV2* p3PhotoServiceV2::getTokenService() { return RsGenExchange::getTokenService(); -} +} bool p3PhotoServiceV2::getGroupList(const uint32_t& token, std::list& groupIds) { return RsGenExchange::getGroupList(token, groupIds); -} +} bool p3PhotoServiceV2::getMsgList(const uint32_t& token, @@ -42,21 +44,21 @@ bool p3PhotoServiceV2::getMsgList(const uint32_t& token, { return RsGenExchange::getMsgList(token, msgIds); -} +} bool p3PhotoServiceV2::getGroupSummary(const uint32_t& token, std::list& groupInfo) { return RsGenExchange::getGroupMeta(token, groupInfo); -} +} bool p3PhotoServiceV2::getMsgSummary(const uint32_t& token, MsgMetaResult& msgInfo) { return RsGenExchange::getMsgMeta(token, msgInfo); -} +} bool p3PhotoServiceV2::getAlbum(const uint32_t& token, std::vector& albums) @@ -78,7 +80,7 @@ bool p3PhotoServiceV2::getAlbum(const uint32_t& token, std::vector } return ok; -} +} bool p3PhotoServiceV2::getPhoto(const uint32_t& token, PhotoResult& photos) @@ -114,19 +116,19 @@ bool p3PhotoServiceV2::getPhoto(const uint32_t& token, PhotoResult& photos) } return ok; -} +} bool p3PhotoServiceV2::submitAlbumDetails(RsPhotoAlbum& album) { return false; -} +} bool p3PhotoServiceV2::submitPhoto(RsPhotoPhoto& photo) { return false; -} +} diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp index 027f0ca37..4786c10b2 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp @@ -45,12 +45,11 @@ PhotoAddDialog::PhotoAddDialog(QWidget *parent) mPhotoDetails = NULL; - mPhotoQueue = new TokenQueue(rsPhoto, this); + mPhotoQueue = new TokenQueueV2(rsPhotoV2->getTokenService(), this); ui.AlbumDrop->setSingleImage(); connect(ui.AlbumDrop, SIGNAL( photosChanged( void ) ), this, SLOT( albumImageChanged( void ) ) ); connect(ui.scrollAreaWidgetContents, SIGNAL( photosChanged( void ) ), this, SLOT( photoImageChanged( void ) ) ); - } @@ -333,7 +332,7 @@ void PhotoAddDialog::publishAlbum() std::cerr << std::endl; uint32_t token; - rsPhoto->submitAlbumDetails(token, album, true); + rsPhotoV2->submitAlbumDetails(album); // tell tokenQueue to expect results from submission. mPhotoQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_SUMMARY, 0); @@ -413,12 +412,12 @@ void PhotoAddDialog::publishPhotos(std::string albumId) if (isNewPhoto) { std::cerr << "Is a New Photo"; - rsPhoto->submitPhoto(token, photo, true); + rsPhotoV2->submitPhoto(photo); } else if (isModifiedPhoto) { std::cerr << "Is Updated"; - rsPhoto->submitPhoto(token, photo, false); + rsPhotoV2->submitPhoto(photo); } else { @@ -479,7 +478,7 @@ void PhotoAddDialog::loadAlbum(const std::string &albumId) RsTokReqOptions opts; uint32_t token; - std::list albumIds; + std::list albumIds; albumIds.push_back(albumId); // We need both Album and Photo Data. @@ -497,9 +496,10 @@ bool PhotoAddDialog::loadPhotoData(const uint32_t &token) bool moreData = true; while(moreData) { + PhotoResult res; RsPhotoPhoto photo; - if (rsPhoto->getPhoto(token, photo)) + if (rsPhotoV2->getPhoto(token, res)) { std::cerr << "PhotoDialog::addAddPhoto() AlbumId: " << photo.mMeta.mGroupId; std::cerr << " PhotoId: " << photo.mMeta.mMsgId; @@ -525,8 +525,9 @@ bool PhotoAddDialog::loadAlbumData(const uint32_t &token) bool moreData = true; while(moreData) { + std::vector albums; RsPhotoAlbum album; - if (rsPhoto->getAlbum(token, album)) + if (rsPhotoV2->getAlbum(token, albums)) { std::cerr << " PhotoAddDialog::loadAlbumData() AlbumId: " << album.mMeta.mGroupId << std::endl; updateAlbumDetails(album); @@ -536,7 +537,9 @@ bool PhotoAddDialog::loadAlbumData(const uint32_t &token) uint32_t token; std::list albumIds; albumIds.push_back(album.mMeta.mGroupId); - mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, albumIds, 0); + GxsMsgReq req; + req[album.mMeta.mGroupId] = std::vector(); + mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, req, 0); } else { @@ -552,7 +555,7 @@ bool PhotoAddDialog::loadCreatedAlbum(const uint32_t &token) std::cerr << std::endl; std::list groupInfo; - if (!rsPhoto->getGroupSummary(token, groupInfo)) + if (!rsPhotoV2->getGroupSummary(token, groupInfo)) { std::cerr << "PhotoAddDialog::loadCreatedAlbum() ERROR Getting MetaData"; std::cerr << std::endl; @@ -575,7 +578,7 @@ bool PhotoAddDialog::loadCreatedAlbum(const uint32_t &token) } -void PhotoAddDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) +void PhotoAddDialog::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req) { std::cerr << "PhotoDialog::loadRequest()"; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.h b/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.h index 5c1a06121..c42bc4774 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.h @@ -26,12 +26,12 @@ #include "ui_PhotoAddDialog.h" -#include -#include "util/TokenQueue.h" +#include +#include "util/TokenQueueV2.h" class PhotoDetailsDialog; -class PhotoAddDialog : public QWidget, public TokenResponse +class PhotoAddDialog : public QWidget, public TokenResponseV2 { Q_OBJECT @@ -39,7 +39,7 @@ public: PhotoAddDialog(QWidget *parent = 0); void loadAlbum(const std::string &albumId); -virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); +virtual void loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req); void clearDialog(); @@ -67,7 +67,7 @@ private: bool loadAlbumData(const uint32_t &token); bool loadCreatedAlbum(const uint32_t &token); - TokenQueue *mPhotoQueue; + TokenQueueV2 *mPhotoQueue; protected: bool mAlbumEdit; // Editing or New. diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index 405e7e397..044e13eae 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -24,7 +24,7 @@ #include "PhotoDialog.h" #include -#include +#include #include #include @@ -79,7 +79,7 @@ PhotoDialog::PhotoDialog(QWidget *parent) /* setup TokenQueue */ - mPhotoQueue = new TokenQueue(rsPhoto, this); + mPhotoQueue = new TokenQueueV2(rsPhotoV2->getTokenService(), this); } @@ -139,10 +139,10 @@ void PhotoDialog::notifyPhotoSelection(PhotoItem *item) void PhotoDialog::checkUpdate() { /* update */ - if (!rsPhoto) + if (!rsPhotoV2) return; - if (rsPhoto->updated()) + if (rsPhotoV2->updated()) { //insertAlbums(); requestAlbumList(); @@ -443,7 +443,7 @@ void PhotoDialog::loadAlbumList(const uint32_t &token) std::cerr << std::endl; std::list albumIds; - rsPhoto->getGroupList(token, albumIds); + rsPhotoV2->getGroupList(token, albumIds); requestAlbumData(albumIds); @@ -458,11 +458,11 @@ void PhotoDialog::loadAlbumList(const uint32_t &token) } -void PhotoDialog::requestAlbumData(const std::list &ids) +void PhotoDialog::requestAlbumData(std::list &ids) { RsTokReqOptions opts; uint32_t token; - mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, 0); + mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, 0); } @@ -477,7 +477,8 @@ bool PhotoDialog::loadAlbumData(const uint32_t &token) while(moreData) { RsPhotoAlbum album; - if (rsPhoto->getAlbum(token, album)) + std::vector albums; + if (rsPhotoV2->getAlbum(token, albums)) { std::cerr << " PhotoDialog::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; @@ -499,11 +500,12 @@ void PhotoDialog::requestPhotoList(const std::string &albumId) { std::list ids; - ids.push_back(albumId); + GxsMsgReq req; + req[albumId] = std::vector(); RsTokReqOptions opts; opts.mOptions = RS_TOKREQOPT_MSG_LATEST; uint32_t token; - mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, ids, 0); + mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, req, 0); } @@ -515,18 +517,19 @@ void PhotoDialog::loadPhotoList(const uint32_t &token) std::cerr << std::endl; - std::list photoIds; + GxsMsgIdResult res; + GxsMsgReq req; - rsPhoto->getMsgList(token, photoIds); - requestPhotoData(photoIds); + rsPhotoV2->getMsgList(token, res); + requestPhotoData(req); } -void PhotoDialog::requestPhotoData(const std::list &photoIds) +void PhotoDialog::requestPhotoData(GxsMsgReq &photoIds) { RsTokReqOptions opts; uint32_t token; - mPhotoQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, photoIds, 0); + mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, photoIds, 0); } @@ -539,8 +542,8 @@ void PhotoDialog::loadPhotoData(const uint32_t &token) while(moreData) { RsPhotoPhoto photo; - - if (rsPhoto->getPhoto(token, photo)) + PhotoResult res; + if (rsPhotoV2->getPhoto(token, res)) { std::cerr << "PhotoDialog::loadPhotoData() AlbumId: " << photo.mMeta.mGroupId; @@ -559,7 +562,7 @@ void PhotoDialog::loadPhotoData(const uint32_t &token) /********************************/ -void PhotoDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) +void PhotoDialog::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req) { std::cerr << "PhotoDialog::loadRequest()"; std::cerr << std::endl; @@ -640,7 +643,7 @@ void PhotoDialog::insertAlbums() std::list filteredAlbumIds; std::list::iterator it; - rsPhoto->getAlbumList(albumIds); + rsPhotoV2->getGroupList(token, al); /* Filter Albums */ /* Sort Albums */ #define MAX_ALBUMS 50 diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h index c99094b2b..339901c2e 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h @@ -27,16 +27,16 @@ #include "retroshare-gui/mainpage.h" #include "ui_PhotoDialog.h" -#include +#include #include #include "gui/PhotoShare/PhotoItem.h" #include "gui/PhotoShare/PhotoAddDialog.h" #include "gui/PhotoShare/PhotoSlideShow.h" -#include "util/TokenQueue.h" +#include "util/TokenQueueV2.h" -class PhotoDialog : public MainPage, public PhotoHolder, public TokenResponse +class PhotoDialog : public MainPage, public PhotoHolder, public TokenResponseV2 { Q_OBJECT @@ -59,16 +59,16 @@ private: /* Request Response Functions for loading data */ void requestAlbumList(); - void requestAlbumData(const std::list &ids); + void requestAlbumData(std::list &ids); void requestPhotoList(const std::string &albumId); - void requestPhotoData(const std::list &photoIds); + void requestPhotoData(GxsMsgReq &photoIds); void loadAlbumList(const uint32_t &token); bool loadAlbumData(const uint32_t &token); void loadPhotoList(const uint32_t &token); void loadPhotoData(const uint32_t &token); - void loadRequest(const TokenQueue *queue, const TokenRequest &req); + void loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req); /* TODO: These functions must be filled in for proper filtering to work @@ -101,7 +101,7 @@ private: PhotoItem *mAlbumSelected; PhotoItem *mPhotoSelected; - TokenQueue *mPhotoQueue; + TokenQueueV2 *mPhotoQueue; /* UI - from Designer */ Ui::PhotoDialog ui; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp index 26611d9d0..b7fefd435 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp @@ -29,7 +29,7 @@ #include "PhotoItem.h" -#include +#include #include #include diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoItem.h b/retroshare-gui/src/gui/PhotoShare/PhotoItem.h index 2e32b3de2..136c15015 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoItem.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoItem.h @@ -26,7 +26,7 @@ #include "ui_PhotoItem.h" -#include +#include class PhotoItem; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp index 3bf2b3cbc..c2fad4ef1 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp @@ -38,7 +38,7 @@ PhotoSlideShow::PhotoSlideShow(QWidget *parent) connect(ui.pushButton_StartStop, SIGNAL( clicked( void ) ), this, SLOT( StartStop( void ) ) ); connect(ui.pushButton_Close, SIGNAL( clicked( void ) ), this, SLOT( closeShow( void ) ) ); - mPhotoQueue = new TokenQueue(rsPhoto, this); + mPhotoQueue = new TokenQueueV2(rsPhotoV2->getTokenService(), this); mRunning = true; mShotActive = true; @@ -49,6 +49,9 @@ PhotoSlideShow::PhotoSlideShow(QWidget *parent) //QTimer::singleShot(5000, this, SLOT(timerEvent())); } +PhotoSlideShow::~PhotoSlideShow(){ + +} void PhotoSlideShow::showPhotoDetails() { @@ -262,8 +265,9 @@ bool PhotoSlideShow::loadPhotoData(const uint32_t &token) while(moreData) { RsPhotoPhoto photo; + PhotoResult res; - if (rsPhoto->getPhoto(token, photo)) + if (rsPhotoV2->getPhoto(token, res)) { RsPhotoPhoto *ptr = new RsPhotoPhoto; *ptr = photo; @@ -299,7 +303,8 @@ bool PhotoSlideShow::loadAlbumData(const uint32_t &token) while(moreData) { RsPhotoAlbum album; - if (rsPhoto->getAlbum(token, album)) + std::vector res; + if (rsPhotoV2->getAlbum(token, res)) { std::cerr << " PhotoSlideShow::loadAlbumData() AlbumId: " << album.mMeta.mGroupId << std::endl; //updateAlbumDetails(album); @@ -309,7 +314,9 @@ bool PhotoSlideShow::loadAlbumData(const uint32_t &token) uint32_t token; std::list albumIds; albumIds.push_back(album.mMeta.mGroupId); - mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, albumIds, 0); + GxsMsgReq req; + req[album.mMeta.mGroupId] = std::vector(); + mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, req, 0); } else { @@ -319,8 +326,7 @@ bool PhotoSlideShow::loadAlbumData(const uint32_t &token) return true; } - -void PhotoSlideShow::loadRequest(const TokenQueue *queue, const TokenRequest &req) +void PhotoSlideShow::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req) { std::cerr << "PhotoSlideShow::loadRequest()"; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.h b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.h index 7cd473035..0b5930691 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.h @@ -26,18 +26,19 @@ #include "ui_PhotoSlideShow.h" -#include -#include "util/TokenQueue.h" +#include +#include "util/TokenQueueV2.h" -class PhotoSlideShow : public QWidget, public TokenResponse +class PhotoSlideShow : public QWidget, public TokenResponseV2 { Q_OBJECT public: PhotoSlideShow(QWidget *parent = 0); + virtual ~PhotoSlideShow(); void loadAlbum(const std::string &albumId); -virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); +virtual void loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req); void clearDialog(); @@ -67,7 +68,7 @@ private: int mImageIdx; bool mShotActive; - TokenQueue *mPhotoQueue; + TokenQueueV2 *mPhotoQueue; Ui::PhotoSlideShow ui; }; diff --git a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp index 3f37f9df8..69fe7f92c 100644 --- a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp +++ b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp @@ -32,7 +32,7 @@ #include -#include "gui/PhotoShare/PhotoDialog.h" +//#include "gui/PhotoShare/PhotoDialog.h" #include "gui/WikiPoos/WikiDialog.h" #include "gui/TheWire/WireDialog.h" #include "gui/Identity/IdDialog.h" @@ -97,9 +97,9 @@ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) ui.stackPages->add(idDialog = new IdDialog(ui.stackPages), createPageAction(QIcon(IMAGE_LIBRARY), tr("Identities"), grp)); - PhotoDialog *photoDialog = NULL; - ui.stackPages->add(photoDialog = new PhotoDialog(ui.stackPages), - createPageAction(QIcon(IMAGE_PHOTO), tr("Photo View"), grp)); + //PhotoDialog *photoDialog = NULL; + //ui.stackPages->add(photoDialog = new PhotoDialog(ui.stackPages), + // createPageAction(QIcon(IMAGE_PHOTO), tr("Photo View"), grp)); WikiDialog *wikiDialog = NULL; ui.stackPages->add(wikiDialog = new WikiDialog(ui.stackPages), diff --git a/retroshare-gui/src/util/TokenQueue.h b/retroshare-gui/src/util/TokenQueue.h index 7a09ca806..b11c131bb 100644 --- a/retroshare-gui/src/util/TokenQueue.h +++ b/retroshare-gui/src/util/TokenQueue.h @@ -29,10 +29,9 @@ #include #include #include - +#include #include - #define COMPLETED_REQUEST 4 #define TOKENREQ_GROUPINFO 1 diff --git a/retroshare-gui/src/util/TokenQueueV2.cpp b/retroshare-gui/src/util/TokenQueueV2.cpp new file mode 100644 index 000000000..934c4b2c1 --- /dev/null +++ b/retroshare-gui/src/util/TokenQueueV2.cpp @@ -0,0 +1,173 @@ +/* + * Token Queue. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "util/TokenQueueV2.h" +#include + +#include + + +/****** + * #define ID_DEBUG 1 + *****/ + +/** Constructor */ +TokenQueueV2::TokenQueueV2(RsTokenServiceV2 *service, TokenResponseV2 *resp) +:QWidget(NULL), mService(service), mResponder(resp) +{ + return; +} + +bool TokenQueueV2::requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, std::list& ids, uint32_t usertype) +{ + uint32_t basictype = TOKENREQ_GROUPINFO; + mService->requestGroupInfo(token, anstype, opts, ids); + queueRequest(token, basictype, anstype, usertype); + + return true; +} + + +bool TokenQueueV2::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, const GxsMsgReq& ids, uint32_t usertype) +{ + uint32_t basictype = TOKENREQ_MSGINFO; + mService->requestMsgInfo(token, anstype, opts, ids); + queueRequest(token, basictype, anstype, usertype); + + return true; +} + + +void TokenQueueV2::queueRequest(uint32_t token, uint32_t basictype, uint32_t anstype, uint32_t usertype) +{ + std::cerr << "TokenQueueV2::queueRequest() Token: " << token << " Type: " << basictype; + std::cerr << " AnsType: " << anstype << " UserType: " << usertype; + std::cerr << std::endl; + + TokenRequestV2 req; + req.mToken = token; + req.mType = basictype; + req.mAnsType = anstype; + req.mUserType = usertype; + + gettimeofday(&req.mRequestTs, NULL); + req.mPollTs = req.mRequestTs; + + mRequests.push_back(req); + + if (mRequests.size() == 1) + { + /* start the timer */ + doPoll(0.1); + } +} + +void TokenQueueV2::doPoll(float dt) +{ + /* single shot poll */ + //mTrigger->singlesshot(dt * 1000); + QTimer::singleShot((int) (dt * 1000.0), this, SLOT(pollRequests())); +} + + +void TokenQueueV2::pollRequests() +{ + std::list::iterator it; + + double pollPeriod = 1.0; // max poll period. + for(it = mRequests.begin(); it != mRequests.end();) + { + if (checkForRequest(it->mToken)) + { + /* clean it up and handle */ + loadRequest(*it); + it = mRequests.erase(it); + } + else + { + /* calculate desired poll period */ + + /* if less then current poll period, adjust */ + + it++; + } + } + + if (mRequests.size() > 0) + { + doPoll(pollPeriod); + } +} + + +bool TokenQueueV2::checkForRequest(uint32_t token) +{ + /* check token */ + return (COMPLETED_REQUEST == mService->requestStatus(token)); +} + + +void TokenQueueV2::loadRequest(const TokenRequestV2 &req) +{ + std::cerr << "TokenQueueV2::loadRequest(): "; + std::cerr << "Token: " << req.mToken << " Type: " << req.mType; + std::cerr << " AnsType: " << req.mAnsType << " UserType: " << req.mUserType; + std::cerr << std::endl; + + mResponder->loadRequest(this, req); + + return; +} + + +bool TokenQueueV2::cancelRequest(const uint32_t token) +{ + /* cancel at lower level first */ + mService->cancelRequest(token); + + std::list::iterator it; + + for(it = mRequests.begin(); it != mRequests.end(); it++) + { + if (it->mToken == token) + { + mRequests.erase(it); + + std::cerr << "TokenQueueV2::cancelRequest() Cleared Request: " << token; + std::cerr << std::endl; + + return true; + } + } + + std::cerr << "TokenQueueV2::cancelRequest() Failed to Find Request: " << token; + std::cerr << std::endl; + + return false; +} + + + + + + diff --git a/retroshare-gui/src/util/TokenQueueV2.h b/retroshare-gui/src/util/TokenQueueV2.h new file mode 100644 index 000000000..40ed5d1da --- /dev/null +++ b/retroshare-gui/src/util/TokenQueueV2.h @@ -0,0 +1,102 @@ +/* + * Token Queue. + * + * Copyright 2012-2012 by Robert Fernie, Christopher Evi-Parker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#ifndef MRK_TOKEN_QUEUE_H +#define MRK_TOKEN_QUEUE_H + +#include +#include +#include +#include +#include + +#include + + + +#define COMPLETED_REQUEST 4 + +#define TOKENREQ_GROUPINFO 1 +#define TOKENREQ_MSGINFO 2 +#define TOKENREQ_MSGRELATEDINFO 3 + +class TokenQueueV2; + +class TokenRequestV2 +{ + public: + uint32_t mToken; + uint32_t mType; + uint32_t mAnsType; + uint32_t mUserType; + struct timeval mRequestTs; + struct timeval mPollTs; +}; + +class TokenResponseV2 +{ + public: + //virtual ~TokenResponse() { return; } + // These Functions are overloaded to get results out. + virtual void loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req) = 0; +}; + + +class TokenQueueV2: public QWidget +{ + Q_OBJECT + +public: + TokenQueueV2(RsTokenServiceV2 *service, TokenResponseV2 *resp); + + /* generic handling of token / response update behaviour */ + bool requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, + std::list& ids, uint32_t usertype); + bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, + const GxsMsgReq& ids, uint32_t usertype); + + bool cancelRequest(const uint32_t token); + + void queueRequest(uint32_t token, uint32_t basictype, uint32_t anstype, uint32_t usertype); + bool checkForRequest(uint32_t token); + void loadRequest(const TokenRequestV2 &req); + +protected: + void doPoll(float dt); + +private slots: + void pollRequests(); + +private: + /* Info for Data Requests */ + std::list mRequests; + + RsTokenServiceV2 *mService; + TokenResponseV2 *mResponder; + + QTimer *mTrigger; +}; + +#endif + + From f710dba2c613da2e2062f39afca5e5b512765005 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Sat, 4 Aug 2012 01:15:40 +0000 Subject: [PATCH 014/222] FeedReader plugin: - fixed compile on Linux - added compatibility with iconv git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5378 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- plugins/FeedReader/FeedReader.pro | 8 +++ plugins/FeedReader/gui/FeedReaderDialog.cpp | 2 +- plugins/FeedReader/services/p3FeedReader.cc | 2 +- .../FeedReader/services/p3FeedReaderThread.cc | 65 +++++++------------ .../FeedReader/services/p3FeedReaderThread.h | 1 + 5 files changed, 36 insertions(+), 42 deletions(-) diff --git a/plugins/FeedReader/FeedReader.pro b/plugins/FeedReader/FeedReader.pro index 85b474948..64aaa1612 100644 --- a/plugins/FeedReader/FeedReader.pro +++ b/plugins/FeedReader/FeedReader.pro @@ -30,6 +30,14 @@ TARGET = FeedReader RESOURCES = gui/FeedReader_images.qrc \ lang/lang.qrc +linux-* { + LIBXML2_DIR = /usr/include/libxml2 + + INCLUDEPATH += $${LIBXML2_DIR} + + LIBS += -lcurl -lxml2 +} + win32 { DEFINES += CURL_STATICLIB diff --git a/plugins/FeedReader/gui/FeedReaderDialog.cpp b/plugins/FeedReader/gui/FeedReaderDialog.cpp index 15f6baa24..d93bf83b8 100644 --- a/plugins/FeedReader/gui/FeedReaderDialog.cpp +++ b/plugins/FeedReader/gui/FeedReaderDialog.cpp @@ -20,7 +20,7 @@ ****************************************************************/ #include -#include +#include #include #include #include diff --git a/plugins/FeedReader/services/p3FeedReader.cc b/plugins/FeedReader/services/p3FeedReader.cc index 712835f4b..0ae7f6ec0 100644 --- a/plugins/FeedReader/services/p3FeedReader.cc +++ b/plugins/FeedReader/services/p3FeedReader.cc @@ -19,7 +19,7 @@ * Boston, MA 02110-1301, USA. ****************************************************************/ -#include "RsFeedReaderItems.h" +#include "rsFeedReaderItems.h" #include "p3FeedReader.h" #include "p3FeedReaderThread.h" #include "serialiser/rsconfigitems.h" diff --git a/plugins/FeedReader/services/p3FeedReaderThread.cc b/plugins/FeedReader/services/p3FeedReaderThread.cc index 02215368e..cbc03fe8b 100644 --- a/plugins/FeedReader/services/p3FeedReaderThread.cc +++ b/plugins/FeedReader/services/p3FeedReaderThread.cc @@ -47,6 +47,11 @@ p3FeedReaderThread::p3FeedReaderThread(p3FeedReader *feedReader, Type type) : Rs } } +p3FeedReaderThread::~p3FeedReaderThread() +{ + xmlCharEncCloseFunc((xmlCharEncodingHandlerPtr) mCharEncodingHandler); +} + /***************************************************************************/ /****************************** Thread *************************************/ /***************************************************************************/ @@ -119,9 +124,9 @@ static size_t writeFunctionString (void *ptr, size_t size, size_t nmemb, void *s static size_t writeFunctionBinary (void *ptr, size_t size, size_t nmemb, void *stream) { - std::vector *bytes = (std::vector*) stream; + std::vector *bytes = (std::vector*) stream; - std::vector newBytes; + std::vector newBytes; newBytes.resize(size * nmemb); memcpy(newBytes.data(), ptr, newBytes.size()); @@ -163,7 +168,7 @@ static bool getFavicon (std::string url, const std::string &proxy, std::string & if (curl) { url += "/favicon.ico"; - std::vector vicon; + std::vector vicon; curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeFunctionBinary); @@ -183,9 +188,9 @@ static bool getFavicon (std::string url, const std::string &proxy, std::string & char *contentType = NULL; curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &contentType); if (contentType && - (strnicmp(contentType, "image/x-icon", 12) == 0 || - strnicmp(contentType, "application/octet-stream", 24) == 0 || - strnicmp(contentType, "text/plain", 10) == 0)) { + (strncasecmp(contentType, "image/x-icon", 12) == 0 || + strncasecmp(contentType, "application/octet-stream", 24) == 0 || + strncasecmp(contentType, "text/plain", 10) == 0)) { if (!vicon.empty()) { long todo; // check it // Set up a base64 encoding BIO that writes to a memory BIO @@ -275,10 +280,10 @@ p3FeedReaderThread::DownloadResult p3FeedReaderThread::download(const RsFeedRead char *contentType = NULL; curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &contentType); if (contentType && - (strnicmp(contentType, "text/xml", 8) == 0 || - strnicmp(contentType, "application/rss+xml", 19) == 0 || - strnicmp(contentType, "application/xml", 15) == 0 || - strnicmp(contentType, "application/xhtml+xml", 21) == 0)) { + (strncasecmp(contentType, "text/xml", 8) == 0 || + strncasecmp(contentType, "application/rss+xml", 19) == 0 || + strncasecmp(contentType, "application/xml", 15) == 0 || + strncasecmp(contentType, "application/xhtml+xml", 21) == 0)) { /* ok */ result = DOWNLOAD_SUCCESS; } else { @@ -317,39 +322,19 @@ p3FeedReaderThread::DownloadResult p3FeedReaderThread::download(const RsFeedRead static bool convertOutput(xmlCharEncodingHandlerPtr charEncodingHandler, const xmlChar *output, std::string &text) { - if (!output) { - return false; - } - - if (charEncodingHandler == NULL || charEncodingHandler->output == NULL) { - return false; - } - bool result = false; - int sizeOut = xmlStrlen(output) + 1; - int sizeIn = sizeOut * 2 - 1; - char *input = (char*) malloc(sizeIn * sizeof(char)); - if (input) { - int temp = sizeOut - 1; - int ret = charEncodingHandler->output((xmlChar*) input, &sizeIn, (const xmlChar *) output, &temp); - if ((ret < 0) || (temp - sizeOut + 1)) { - if (ret < 0) { - std::cerr << "convertOutput: conversion wasn't successful." << std::endl; - } else { - std::cerr << "convertOutput: conversion wasn't successful. converted: " << temp << " octets." << std::endl; - } - } else { - text.assign(input, sizeIn); - result = true; - } - - free(input); - input = NULL; - } else { - std::cerr << "convertOutput: no mem" << std::endl; + xmlBufferPtr out = xmlBufferCreate(); + xmlBufferPtr in = xmlBufferCreateStatic((void*) output, xmlStrlen(output)); + int ret = xmlCharEncOutFunc(charEncodingHandler, out, in); + if (ret >= 0) { + result = true; + text = (char*) xmlBufferContent(out); } + xmlBufferFree(in); + xmlBufferFree(out); + return result; } @@ -413,7 +398,7 @@ static xmlNodePtr getNextItem(FeedFormat feedFormat, xmlNodePtr channel, xmlNode static bool getChildText(/*xmlCharEncodingHandlerPtr*/ void *charEncodingHandler, xmlNodePtr node, const char *childName, std::string &text) { if (node == NULL || node->children == NULL) { - return FALSE; + return false; } xmlNodePtr child = findNode(node->children, childName, true); diff --git a/plugins/FeedReader/services/p3FeedReaderThread.h b/plugins/FeedReader/services/p3FeedReaderThread.h index f27213bad..051cd0325 100644 --- a/plugins/FeedReader/services/p3FeedReaderThread.h +++ b/plugins/FeedReader/services/p3FeedReaderThread.h @@ -56,6 +56,7 @@ public: public: p3FeedReaderThread(p3FeedReader *feedReader, Type type); + virtual ~p3FeedReaderThread(); private: virtual void run(); From b8729de06aada900c690cfc12579318e6d5438ea Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 5 Aug 2012 17:08:29 +0000 Subject: [PATCH 015/222] Added SSHv2 connections to retroshare-nogui. * Using libssh in a seperate thread. * Binds to fixed port, and accepts connections from standard SSH clients. * Only an Echo Server at the moment: Interface to be decided yet. * Only accepts 1 connection, 2nd connection hangs at the moment. * A long way to go before it will be useful! git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5380 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/retroshare-nogui.pro | 21 + retroshare-nogui/src/retroshare.cc | 15 + retroshare-nogui/src/ssh/rssshd.cc | 491 ++++++++++++++++++++++ retroshare-nogui/src/ssh/rssshd.h | 126 ++++++ 4 files changed, 653 insertions(+) create mode 100644 retroshare-nogui/src/ssh/rssshd.cc create mode 100644 retroshare-nogui/src/ssh/rssshd.h diff --git a/retroshare-nogui/src/retroshare-nogui.pro b/retroshare-nogui/src/retroshare-nogui.pro index d2a40eb77..5c3ac86a6 100644 --- a/retroshare-nogui/src/retroshare-nogui.pro +++ b/retroshare-nogui/src/retroshare-nogui.pro @@ -2,6 +2,7 @@ TEMPLATE = app TARGET = retroshare-nogui CONFIG += bitdht #CONFIG += introserver +#CONFIG += sshserver ################################# Linux ########################################## linux-* { @@ -111,6 +112,26 @@ introserver { DEFINES *= RS_INTRO_SERVER } +sshserver { + # This Requires libssh-0.5.* to compile. + # Modify path below to point at it. + # Probably will only work on Linux for the moment. + # + # Use the following commend to generate a Server RSA Key. + # Key should be in current directory - when run/ + # ssh-keygen -t rsa -f rs_ssh_host_rsa_key + # + # You can connect from a standard ssh, eg: ssh -p 7022 127.0.0.1 + # + + INCLUDEPATH += ../../../lib/libssh-0.5.2/include/ + LIBS += ../../../lib/libssh-0.5.2/build/src/libssh.a + LIBS += ../../../lib/libssh-0.5.2/build/src/threads/libssh_threads.a + HEADERS += ssh/rssshd.h + SOURCES += ssh/rssshd.cc + DEFINES *= RS_SSH_SERVER +} + diff --git a/retroshare-nogui/src/retroshare.cc b/retroshare-nogui/src/retroshare.cc index 5b054a925..418f92985 100644 --- a/retroshare-nogui/src/retroshare.cc +++ b/retroshare-nogui/src/retroshare.cc @@ -40,6 +40,10 @@ #include "introserver.h" #endif +#ifdef RS_SSH_SERVER +#include "ssh/rssshd.h" +#endif + /* Basic instructions for running libretroshare as background thread. * ******************************************************************* * * This allows your program to communicate with authenticated peers. @@ -132,6 +136,13 @@ int main(int argc, char **argv) return 1; } +#ifdef RS_SSH_SERVER + // Says it must be called before all the threads are launched! */ + // NB: this port number is not currently used. + RsSshd *ssh = RsSshd::InitRsSshd(22, "rs_ssh_host_rsa_key"); + ssh->adduser("anrsuser", "test"); +#endif + /* Start-up libretroshare server threads */ rsServer -> StartupRetroShare(); @@ -139,6 +150,10 @@ int main(int argc, char **argv) RsIntroServer rsIS; #endif +#ifdef RS_SSH_SERVER + ssh->start(); +#endif + /* pass control to the GUI */ while(1) { diff --git a/retroshare-nogui/src/ssh/rssshd.cc b/retroshare-nogui/src/ssh/rssshd.cc new file mode 100644 index 000000000..493151a0d --- /dev/null +++ b/retroshare-nogui/src/ssh/rssshd.cc @@ -0,0 +1,491 @@ +/* This is a sample implementation of a libssh based SSH server */ +/* +Copyright 2003-2009 Aris Adamantiadis + +This file is part of the SSH Library + +You are free to copy this file, modify it in any way, consider it being public +domain. This does not apply to the rest of the library though, but it is +allowed to cut-and-paste working code from this file to any license of +program. +The goal is to show the API in action. It's not a reference on how terminal +clients must be made or how a client should react. +*/ + +/***** + * Heavily Modified by Robert Fernie 2012... for retroshare project! + * + */ + + +#include + +#include "ssh/rssshd.h" + +#include + +#define RSSSHD_STATE_NULL 0 +#define RSSSHD_STATE_INIT_OK 1 + +RsSshd *rsSshd = NULL; // External Reference Variable. + +// NB: This must be called EARLY before all the threads are launched. +RsSshd *RsSshd::InitRsSshd(uint16_t port, std::string rsakeyfile) +{ + ssh_threads_set_callbacks(ssh_threads_get_pthread()); + ssh_init(); + + rsSshd = new RsSshd(port); + if (rsSshd->init(rsakeyfile)) + { + return rsSshd; + } + + rsSshd = NULL; + return rsSshd; +} + + +RsSshd::RsSshd(uint16_t port) +:mSshMtx("sshMtx"), mPort(port), mChannel(0) +{ + + mState = RSSSHD_STATE_NULL; + mBindState = 0; + + return; +} + + + +int RsSshd::init(std::string pathrsakey) +{ + + mBind=ssh_bind_new(); + mSession=ssh_new(); + + //ssh_bind_options_set(mBind, SSH_BIND_OPTIONS_DSAKEY, KEYS_FOLDER "ssh_host_dsa_key"); + //ssh_bind_options_set(mBind, SSH_BIND_OPTIONS_RSAKEY, KEYS_FOLDER "ssh_host_rsa_key"); + + //ssh_bind_options_set(mBind, SSH_BIND_OPTIONS_BINDPORT_STR, arg); + ssh_bind_options_set(mBind, SSH_BIND_OPTIONS_BINDPORT_STR, "7022"); + //ssh_bind_options_set(mBind, SSH_BIND_OPTIONS_DSAKEY, arg); + //ssh_bind_options_set(mBind, SSH_BIND_OPTIONS_HOSTKEY, arg); + ssh_bind_options_set(mBind, SSH_BIND_OPTIONS_RSAKEY, pathrsakey.c_str()); + ssh_bind_options_set(mBind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3"); + + mState = RSSSHD_STATE_INIT_OK; + mBindState = 0; + + return 1; +} + + +void RsSshd::run() +{ + /* main loop */ + + /* listen */ + bool sshOk = true; + while(sshOk) + { + std::cerr << "RsSshd::run() starting sshd cycle"; + std::cerr << std::endl; + + if (listenConnect()) + { + std::cerr << "RsSshd::run() success connect => setup mSession"; + std::cerr << std::endl; + + if (setupSession()) + { + std::cerr << "RsSshd::run() setup mSession => interactive"; + std::cerr << std::endl; + + interactive(); + } + else + { + std::cerr << "RsSshd::run() setup mSession failed"; + std::cerr << std::endl; + } + } + cleanupSession(); + sleep(5); // have a break; + } +} + + +int RsSshd::listenConnect() +{ + std::cerr << "RsSshd::listenConnect()"; + std::cerr << std::endl; + + if (!mBindState) + { + if(ssh_bind_listen(mBind)<0) + { + printf("Error listening to socket: %s\n",ssh_get_error(mBind)); + return 0; + } + mBindState = 1; + } + else + { + std::cerr << "RsSshd::listenConnect() Already Bound..."; + std::cerr << std::endl; + } + + int r=ssh_bind_accept(mBind,mSession); + if(r==SSH_ERROR) + { + printf("error accepting a connection : %s\n",ssh_get_error(mBind)); + return 0; + } + + if (ssh_handle_key_exchange(mSession)) + { + printf("ssh_handle_key_exchange: %s\n", ssh_get_error(mSession)); + return 0; + } + return 1; +} + + +int RsSshd::setupSession() +{ + std::cerr << "RsSshd::listenConnect()"; + std::cerr << std::endl; + + if (authUser()) + { + std::cerr << "RsSshd::listenConnect() authUser SUCCESS"; + std::cerr << std::endl; + + if (setupChannel()) + { + std::cerr << "RsSshd::listenConnect() setupChannel SUCCESS"; + std::cerr << std::endl; + + if (setupShell()) + { + std::cerr << "RsSshd::listenConnect() setupShell SUCCESS"; + std::cerr << std::endl; + + return 1; + } + } + } + std::cerr << "RsSshd::listenConnect() Failed"; + std::cerr << std::endl; + + return 0; +} + + +int RsSshd::interactive() +{ + std::cerr << "RsSshd::interactive()"; + std::cerr << std::endl; + + doEcho(); + return 1; +} + + + +int RsSshd::authUser() +{ + std::cerr << "RsSshd::authUser()"; + std::cerr << std::endl; + + + ssh_message message; + int auth = 0; + + do { + message=ssh_message_get(mSession); + if(!message) + break; + switch(ssh_message_type(message)){ + case SSH_REQUEST_AUTH: + switch(ssh_message_subtype(message)){ + case SSH_AUTH_METHOD_PASSWORD: + printf("User %s wants to auth with pass %s\n", + ssh_message_auth_user(message), + ssh_message_auth_password(message)); + if(auth_password(ssh_message_auth_user(message), + ssh_message_auth_password(message))){ + auth=1; + ssh_message_auth_reply_success(message,0); + break; + } + // not authenticated, send default message + case SSH_AUTH_METHOD_NONE: + default: + ssh_message_auth_set_methods(message,SSH_AUTH_METHOD_PASSWORD); + ssh_message_reply_default(message); + break; + } + break; + default: + ssh_message_reply_default(message); + } + ssh_message_free(message); + } while (!auth); + + if(!auth){ + printf("auth error: %s\n",ssh_get_error(mSession)); + ssh_disconnect(mSession); + return 0; + } + + std::cerr << "RsSshd::authuser() Success"; + std::cerr << std::endl; + + return 1; +} + + +int RsSshd::setupChannel() +{ + std::cerr << "RsSshd::setupChannel()"; + std::cerr << std::endl; + + ssh_message message; + + + do { + message=ssh_message_get(mSession); + if(message){ + switch(ssh_message_type(message)){ + case SSH_REQUEST_CHANNEL_OPEN: + if(ssh_message_subtype(message)==SSH_CHANNEL_SESSION){ + mChannel=ssh_message_channel_request_open_reply_accept(message); + break; + } + default: + ssh_message_reply_default(message); + } + ssh_message_free(message); + } + } while(message && !mChannel); + if(!mChannel){ + printf("error : %s\n",ssh_get_error(mSession)); + ssh_finalize(); + return 0; + } + + return 1; +} + + +int RsSshd::setupShell() +{ + std::cerr << "RsSshd::setupShell()"; + std::cerr << std::endl; + + int shell = 0; + ssh_message message; + + do { + message=ssh_message_get(mSession); + if(message && ssh_message_type(message)==SSH_REQUEST_CHANNEL && + ssh_message_subtype(message)==SSH_CHANNEL_REQUEST_SHELL){ + shell = 1; + ssh_message_channel_request_reply_success(message); + break; + } + if(!shell){ + ssh_message_reply_default(message); + } + ssh_message_free(message); + } while (message && !shell); + + if(!shell){ + printf("error : %s\n",ssh_get_error(mSession)); + return 0; + } + + return 1; +} + + +int RsSshd::doEcho() +{ + std::cerr << "RsSshd::doEcho()"; + std::cerr << std::endl; + int i = 0; + char buf[2048]; + + do{ + i=ssh_channel_read(mChannel,buf, 2048, 0); + if(i>0) { + ssh_channel_write(mChannel, buf, i); + ssh_channel_write(mChannel, buf, i); + if (write(1,buf,i) < 0) { + printf("error writing to buffer\n"); + return 0; + } + } + } while (i>0); + + std::cerr << "RsSshd::doEcho() Finished"; + std::cerr << std::endl; + + return 1; +} + + +int RsSshd::cleanupSession() +{ + std::cerr << "RsSshd::cleanupSession()"; + std::cerr << std::endl; + + ssh_disconnect(mSession); + return 1; +} + + +int RsSshd::cleanupAll() +{ + std::cerr << "RsSshd::cleanupAll()"; + std::cerr << std::endl; + + cleanupSession(); + if (mBindState) + { + ssh_bind_free(mBind); + mBindState = 0; + } + ssh_finalize(); + return 1; +} + +/***********************************************************************************/ + /* PASSWORDS */ +/***********************************************************************************/ + +int RsSshd::auth_password(char *name, char *pwd) +{ +#ifdef ALLOW_CLEARPWDS + if (auth_password_basic(name, pwd)) + return 1; +#endif // ALLOW_CLEARPWDS + + if (auth_password_hashed(name, pwd)) + return 1; + return 0; +} + +#define RSSSHD_MIN_PASSWORD 4 +#define RSSSHD_MIN_USERNAME 3 + +#ifdef ALLOW_CLEARPWDS +int RsSshd::adduser(std::string username, std::string password) +{ + if (password.length() < RSSSHD_MIN_PASSWORD) + { + std::cerr << "RsSshd::adduser() Password Too Short"; + return 0; + } + + if (username.length() < RSSSHD_MIN_USERNAME) + { + std::cerr << "RsSshd::adduser() Password Too Short"; + return 0; + } + + std::map::iterator it; + it = mPasswords.find(username); + if (it != mPasswords.end()) + { + std::cerr << "RsSshd::adduser() Warning username already exists"; + } + + mPasswords[username] = password; + + return 1; +} + + +int RsSshd::auth_password_basic(char *name, char *pwd) +{ + std::string username(name); + std::string password(pwd); + + std::map::iterator it; + it = mPasswords.find(username); + if (it == mPasswords.end()) + { + std::cerr << "RsSshd::auth_password() Unknown username"; + return 0; + } + + if (it->second == password) + { + std::cerr << "RsSshd::auth_password() logged in " << username; + return 1; + } + + std::cerr << "RsSshd::auth_password() Invalid pwd for " << username; + return 0; +} +#endif // ALLOW_CLEARPWDS + +#define RSSSHD_HASH_PWD_LENGTH 40 + +int RsSshd::adduserpwdhash(std::string username, std::string hash) +{ + if (hash.length() != RSSSHD_HASH_PWD_LENGTH) + { + std::cerr << "RsSshd::adduserpwdhash() Hash Wrong Length"; + return 0; + } + + if (username.length() < RSSSHD_MIN_USERNAME) + { + std::cerr << "RsSshd::adduserpwdhash() Username Too Short"; + return 0; + } + + std::map::iterator it; + it = mPwdHashs.find(username); + if (it != mPwdHashs.end()) + { + std::cerr << "RsSshd::adduser() Warning username already exists"; + } + + mPwdHashs[username] = hash; + + return 1; +} + + +int RsSshd::auth_password_hashed(char *name, char *pwd) +{ + std::cerr << "RsSshd::auth_password_hashed() Not Finished Yet!"; + return 0; + + std::string username(name); + std::string password(pwd); + + std::map::iterator it; + it = mPasswords.find(username); + if (it == mPasswords.end()) + { + std::cerr << "RsSshd::auth_password_hashed() Unknown username"; + return 0; + } + + if (it->second == password) + { + std::cerr << "RsSshd::auth_password_hashed() logged in " << username; + return 1; + } + + std::cerr << "RsSshd::auth_password_hashed() Invalid pwd for " << username; + return 0; +} + + diff --git a/retroshare-nogui/src/ssh/rssshd.h b/retroshare-nogui/src/ssh/rssshd.h new file mode 100644 index 000000000..48623b397 --- /dev/null +++ b/retroshare-nogui/src/ssh/rssshd.h @@ -0,0 +1,126 @@ +/* This is a sample implementation of a libssh based SSH server */ +/* +Copyright 2003-2009 Aris Adamantiadis + +This file is part of the SSH Library + +You are free to copy this file, modify it in any way, consider it being public +domain. This does not apply to the rest of the library though, but it is +allowed to cut-and-paste working code from this file to any license of +program. +The goal is to show the API in action. It's not a reference on how terminal +clients must be made or how a client should react. +*/ + +/***** + * Heavily Modified by Robert Fernie 2012... for retroshare project! + * + */ + + +#ifndef RS_SSHD_INTERFACE_H +#define RS_SSHD_INTERFACE_H + +#include +#include + +#include +#include +#include + +// From inside libretroshare.a +#include "util/rsthreads.h" + +#include +#include + + +#ifndef KEYS_FOLDER +#ifdef _WIN32 +#define KEYS_FOLDER +#else +#define KEYS_FOLDER "/etc/ssh/" +#endif +#endif + + + +/****** + * + * Minimal Options to start with + * + */ + + + +#define ALLOW_CLEARPWDS 1 + +class RsSshd; +extern RsSshd *rsSshd; + +class RsSshd: public RsThread +{ +public: + + // TODO: NB: THIS FN DOES NOT USE A "SLOW" HASH FUNCTION. + // THE FIRST HALF OF THE HASH STRING IS THE SALT +int adduserpwdhash(std::string username, std::string hash); +#ifdef ALLOW_CLEARPWDS +int adduser(std::string username, std::string password); +#endif // ALLOW_CLEARPWDS + + + +virtual void run(); /* overloaded from RsThread => called once the thread is started */ + +// NB: This must be called EARLY before all the threads are launched. +static RsSshd *InitRsSshd(uint16_t port, std::string rsakeyfile); + +private: + RsSshd(uint16_t port); /* private constructor => so can only create with */ + +int init(std::string pathrsakey); + + // High level operations. +int listenConnect(); +int setupSession(); +int interactive(); + + // Lower Level Operations. +int authUser(); +int setupChannel(); +int setupShell(); +int doEcho(); + +int cleanupSession(); +int cleanupAll(); + + /* Password Checking */ +int auth_password(char *name, char *pwd); +int auth_password_hashed(char *name, char *pwd); +#ifdef ALLOW_CLEARPWDS +int auth_password_basic(char *name, char *pwd); +#endif // ALLOW_CLEARPWDS + + // DATA. + + RsMutex mSshMtx; + + uint32_t mState; + uint32_t mBindState; + + uint16_t mPort; + ssh_session mSession; + ssh_bind mBind; + ssh_channel mChannel; + +#ifdef ALLOW_CLEARPWDS + std::map mPasswords; +#endif // ALLOW_CLEARPWDS + std::map mPwdHashs; + +}; + + +#endif + From 39482343105ea4c87bace0a812b748d7b615316f Mon Sep 17 00:00:00 2001 From: thunder2 Date: Mon, 6 Aug 2012 20:42:16 +0000 Subject: [PATCH 016/222] Fixed compile on Windows. Added missing path to sqlite. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5386 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/libretroshare.pro | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 70ec2bed2..0e5c67fa3 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -299,6 +299,11 @@ win32 { OPENPGPSDK_DIR = ../../openpgpsdk/src INCLUDEPATH += . $${SSL_DIR}/include $${UPNPC_DIR} $${PTHREADS_DIR} $${ZLIB_DIR} $${OPENPGPSDK_DIR} + + newcache { + SQLITE_DIR = ../../../sqlite-autoconf-3071300 + INCLUDEPATH += . $${SQLITE_DIR} + } } From a7159470461cdb8afb45276b17862aae2b55ff3b Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Mon, 6 Aug 2012 21:00:38 +0000 Subject: [PATCH 017/222] Added Rs photo v2 item serialisation test, fixed subsequent bugs Reactivated Photodialog. almost completed integration, publishing and item storage working, but data retrieval algorithm needs to be changed (request flags need to be translated, based on update call rather than client assumption) fixed bug in rsgenexchange notification. Added LGPL notices git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5387 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/gxscoreserver.cc | 26 ++- libretroshare/src/gxs/gxscoreserver.h | 36 +++- libretroshare/src/gxs/rsdataservice.cc | 29 ++- libretroshare/src/gxs/rsdataservice.h | 45 ++++- libretroshare/src/gxs/rsgds.h | 4 +- libretroshare/src/gxs/rsgenexchange.cc | 86 ++++++-- libretroshare/src/gxs/rsgenexchange.h | 15 +- libretroshare/src/gxs/rsgxs.h | 9 +- libretroshare/src/gxs/rsgxsdata.cc | 25 +++ libretroshare/src/gxs/rsgxsdata.h | 25 +++ libretroshare/src/gxs/rsgxsdataaccess.cc | 44 +++-- libretroshare/src/gxs/rsgxsdataaccess.h | 15 +- libretroshare/src/gxs/rsgxsnetservice.cc | 26 +++ libretroshare/src/gxs/rsgxsnetservice.h | 25 +++ libretroshare/src/gxs/rsgxsrequesttypes.h | 33 +++- libretroshare/src/gxs/rsnxs.h | 2 +- libretroshare/src/gxs/rsnxsobserver.h | 4 +- libretroshare/src/gxs/rstokenservice.h | 8 +- libretroshare/src/libretroshare.pro | 16 +- libretroshare/src/retroshare/rsgxsservice.h | 1 + libretroshare/src/retroshare/rsphotoV2.h | 183 +++++++++--------- libretroshare/src/rsserver/rsinit.cc | 40 ++++ libretroshare/src/serialiser/rsnxsitems.h | 4 +- .../src/serialiser/rsphotov2items.cc | 16 +- libretroshare/src/services/p3photoservice.cc | 1 + .../src/services/p3photoserviceV2.cc | 66 ++++++- libretroshare/src/services/p3photoserviceV2.h | 16 +- .../src/tests/serialiser/rsphotoitem_test.cc | 139 +++++++++++++ .../src/tests/serialiser/rsphotoitem_test.h | 41 ++++ .../src/gui/PhotoShare/PhotoAddDialog.cpp | 95 ++++----- .../src/gui/PhotoShare/PhotoDialog.cpp | 74 ++++--- .../src/gui/PhotoShare/PhotoSlideShow.cpp | 97 +++++----- .../src/gui/unfinished/ApplicationWindow.cpp | 8 +- retroshare-gui/src/util/TokenQueueV2.cpp | 4 +- retroshare-gui/src/util/TokenQueueV2.h | 8 +- 35 files changed, 916 insertions(+), 350 deletions(-) create mode 100644 libretroshare/src/tests/serialiser/rsphotoitem_test.cc create mode 100644 libretroshare/src/tests/serialiser/rsphotoitem_test.h diff --git a/libretroshare/src/gxs/gxscoreserver.cc b/libretroshare/src/gxs/gxscoreserver.cc index c4068164c..749f96063 100644 --- a/libretroshare/src/gxs/gxscoreserver.cc +++ b/libretroshare/src/gxs/gxscoreserver.cc @@ -1,10 +1,30 @@ + /* - * gxscoreserver.cpp + * libretroshare/src/gxs: gxscoreserver.cc + * + * General Data service, interface for RetroShare. + * + * Copyright 2011-2011 by Evi-Parker Christopher + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". * - * Created on: 24 Jul 2012 - * Author: crispy */ + #include "gxscoreserver.h" GxsCoreServer::GxsCoreServer() diff --git a/libretroshare/src/gxs/gxscoreserver.h b/libretroshare/src/gxs/gxscoreserver.h index b0534e38d..664a93f8a 100644 --- a/libretroshare/src/gxs/gxscoreserver.h +++ b/libretroshare/src/gxs/gxscoreserver.h @@ -1,17 +1,37 @@ -/* - * gxscoreserver.h - * - * Created on: 24 Jul 2012 - * Author: crispy - */ - #ifndef GXSCORESERVER_H_ #define GXSCORESERVER_H_ +/* + * libretroshare/src/gxs: gxscoreserver.h + * + * General Data service, interface for RetroShare. + * + * Copyright 2011-2011 by Evi-Parker Christopher + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + + #include "util/rsthreads.h" #include "gxs/rsgxs.h" -class GxsCoreServer : RsThread { +class GxsCoreServer : public RsThread +{ public: GxsCoreServer(); ~GxsCoreServer(); diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index 932da998f..23d64333c 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -1,3 +1,30 @@ + +/* + * libretroshare/src/gxs: rsdataservice.cc + * + * Data Access, interface for RetroShare. + * + * Copyright 2011-2011 by Evi-Parker Christopher + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + + #include #include "rsdataservice.h" @@ -782,7 +809,7 @@ int RsDataService::updateMessageMetaData(MsgLocMetaData *metaData) } -int RsDataService::removeMsgs(const std::string grpId, const std::vector &msgIds) +int RsDataService::removeMsgs(const GxsMsgReq& msgIds) { return 0; } diff --git a/libretroshare/src/gxs/rsdataservice.h b/libretroshare/src/gxs/rsdataservice.h index 13bc26bf3..e7553683e 100644 --- a/libretroshare/src/gxs/rsdataservice.h +++ b/libretroshare/src/gxs/rsdataservice.h @@ -1,6 +1,31 @@ #ifndef RSDATASERVICE_H #define RSDATASERVICE_H +/* + * libretroshare/src/gxs: rsdataservice.h + * + * General Data service, interface for RetroShare. + * + * Copyright 2011-2011 by Evi-Parker Christopher + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + #include "gxs/rsgds.h" #include "util/retrodb.h" @@ -10,7 +35,7 @@ class RsDataService : public RsGeneralDataService public: RsDataService(const std::string& serviceDir, const std::string& dbName, uint16_t serviceType, RsGxsSearchModule* mod = NULL); - virtual ~RsDataService() ; + virtual ~RsDataService(); /*! * Retrieves all msgs @@ -36,7 +61,7 @@ public: * @param cache whether to store retrieval in mem for faster later retrieval * @return error code */ - int retrieveGxsGrpMetaData(std::map& grp); + int retrieveGxsGrpMetaData(std::map& grp); /*! * Retrieves meta data of all groups stored (most current versions only) @@ -45,7 +70,7 @@ public: * @param cache whether to store retrieval in mem for faster later retrieval * @return error code */ - int retrieveGxsMsgMetaData(const std::vector& grpIds, GxsMsgMetaResult& msgMeta); + int retrieveGxsMsgMetaData(const std::vector& grpIds, GxsMsgMetaResult& msgMeta); /*! * remove msgs in data store @@ -53,14 +78,14 @@ public: * @param msgIds ids of messages to be removed * @return error code */ - int removeMsgs(const std::string grpId, const std::vector& msgIds); + int removeMsgs(const GxsMsgReq& msgIds); /*! * remove groups in data store listed in grpIds param * @param grpIds ids of groups to be removed * @return error code */ - int removeGroups(const std::vector& grpIds); + int removeGroups(const std::vector& grpIds); /*! * @return the cache size set for this RsGeneralDataService in bytes @@ -117,11 +142,11 @@ private: void retrieveMessages(RetroCursor* c, std::vector& msgs); /*! - * Retrieves all the msg results from a cursor - * @param c cursor to result set - * @param msgs messages retrieved from cursor are stored here - */ - void retrieveGroups(RetroCursor* c, std::vector& grps, bool withMeta = false); + * Retrieves all the msg results from a cursor + * @param c cursor to result set + * @param msgs messages retrieved from cursor are stored here + */ + void retrieveGroups(RetroCursor* c, std::vector& grps, bool withMeta = false); /*! * extracts a msg meta item from a cursor at its diff --git a/libretroshare/src/gxs/rsgds.h b/libretroshare/src/gxs/rsgds.h index 4a178f575..1a34747c0 100644 --- a/libretroshare/src/gxs/rsgds.h +++ b/libretroshare/src/gxs/rsgds.h @@ -108,7 +108,7 @@ public: /*! * Retrieves all groups stored * @param grp retrieved groups - * @param withMeta this initialises the meta handles nxs grps + * @param withMeta if true the meta handle of nxs grps is intitialised * @param cache whether to store retrieval in mem for faster later retrieval * @return error code */ @@ -130,7 +130,7 @@ public: * @param cache whether to store retrieval in mem for faster later retrieval * @return error code */ - virtual int retrieveGxsMsgMetaData(const std::vector& grpIds, GxsMsgMetaResult& msgMeta) = 0; + virtual int retrieveGxsMsgMetaData(const std::vector& grpIds, GxsMsgMetaResult& msgMeta) = 0; /*! * remove msgs in data store listed in msgIds param diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 0337ce5a9..5f809e1e7 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -1,3 +1,29 @@ + +/* + * libretroshare/src/gxs: rsgenexchange.cc + * + * RetroShare Gxs exchange interface. + * + * Copyright 2012-2012 by Christopher Evi-Parker, Robert Fernie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + #include "rsgenexchange.h" RsGenExchange::RsGenExchange(RsGeneralDataService *gds, @@ -31,6 +57,9 @@ void RsGenExchange::tick() publishMsgs(); + notifyChanges(mNotifications); + mNotifications.clear(); + } @@ -61,10 +90,6 @@ bool RsGenExchange::getGroupMeta(const uint32_t &token, std::list::iterator cit = metaL.begin(); - for(; cit != metaL.end(); cit++) - delete *cit; - return ok; } @@ -81,14 +106,20 @@ bool RsGenExchange::getMsgMeta(const uint32_t &token, for(; mit != result.end(); mit++) { std::vector& metaV = mit->second; - //msgInfo[mit->first] = metaV; + + msgInfo[mit->first] = std::vector(); + std::vector& msgInfoV = msgInfo[mit->first]; std::vector::iterator vit = metaV.begin(); - + RsMsgMetaData meta; for(; vit != metaV.end(); vit++) { + RsGxsMsgMetaData& m = *(*vit); + meta = m; + msgInfoV.push_back(meta); delete *vit; } + metaV.clear(); } return ok; @@ -108,9 +139,13 @@ bool RsGenExchange::getGroupData(const uint32_t &token, std::vectorgrp; RsItem* item = mSerialiser->deserialise(data.bin_data, &data.bin_len); - RsGxsGrpItem* gItem = dynamic_cast(item); - grpItem.push_back(gItem); - delete *lit; + + if(item != NULL){ + RsGxsGrpItem* gItem = dynamic_cast(item); + gItem->meta = *((*lit)->metaData); + grpItem.push_back(gItem); + delete *lit; + } } } return ok; @@ -139,6 +174,7 @@ bool RsGenExchange::getMsgData(const uint32_t &token, RsItem* item = mSerialiser->deserialise(msg->msg.bin_data, &msg->msg.bin_len); RsGxsMsgItem* mItem = dynamic_cast(item); + mItem->meta = *((*vit)->metaData); // get meta info from nxs msg gxsMsgItems.push_back(mItem); delete msg; } @@ -165,7 +201,7 @@ void RsGenExchange::notifyNewGroups(std::vector &groups) } -void RsGenExchange::notifyNewMessages(std::vector messages) +void RsGenExchange::notifyNewMessages(std::vector& messages) { std::vector::iterator vit = messages.begin(); @@ -180,7 +216,6 @@ bool RsGenExchange::publishGroup(RsGxsGrpItem *grpItem) { RsStackMutex stack(mGenMtx); - mGrpsToPublish.push_back(grpItem); return true; @@ -214,6 +249,7 @@ void RsGenExchange::publishMsgs() if(ok) { msg->metaData = new RsGxsMsgMetaData(); + *(msg->metaData) = msgItem->meta; ok = mDataAccess->addMsgData(msg); if(ok) @@ -223,18 +259,23 @@ void RsGenExchange::publishMsgs() } } + // if addition failed then delete nxs message if(!ok) { #ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::publishMsgs() failed to publish msg " << std::endl; + std::cerr << "RsGenExchange::publishMsgs() failed to serialise msg " << std::endl; #endif delete msg; continue; } - delete msgItem; + delete msgItem; // delete msg item as we're done with it } + + // clear msg list as we're done publishing them and entries + // are invalid + mMsgsToPublish.clear(); } void RsGenExchange::publishGrps() @@ -257,6 +298,7 @@ void RsGenExchange::publishGrps() if(ok) { grp->metaData = new RsGxsGrpMetaData(); + *(grp->metaData) = grpItem->meta; ok = mDataAccess->addGroupData(grp); RsGxsGroupChange* gc = new RsGxsGroupChange(); mNotifications.push_back(gc); @@ -277,15 +319,21 @@ void RsGenExchange::publishGrps() vit = mGrpsToPublish.erase(vit); } + // clear grp list as we're done publishing them and entries + // are invalid + mGrpsToPublish.clear(); +} +void RsGenExchange::processRecvdData() +{ } -void RsGenExchange::processRecvdData() { -} -void RsGenExchange::processRecvdMessages() { -} +void RsGenExchange::processRecvdMessages() +{ +} -void RsGenExchange::processRecvdGroups() { -} +void RsGenExchange::processRecvdGroups() +{ +} diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 4ef50131b..55bc08622 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -2,7 +2,7 @@ #define RSGENEXCHANGE_H /* - * libretroshare/src/retroshare: rsphoto.h + * libretroshare/src/gxs: rsgenexchange.h * * RetroShare C++ Interface. * @@ -81,7 +81,7 @@ public: /*! * @param messages messages are deleted after function returns */ - void notifyNewMessages(std::vector messages); + void notifyNewMessages(std::vector& messages); /*! * @param messages messages are deleted after function returns @@ -192,7 +192,12 @@ protected: */ virtual void notifyChanges(std::vector& changes) = 0; -public: + + void publishGrps(); + + void publishMsgs(); + +private: void processRecvdData(); @@ -200,10 +205,6 @@ public: void processRecvdGroups(); - void publishGrps(); - - void publishMsgs(); - private: RsMutex mGenMtx; diff --git a/libretroshare/src/gxs/rsgxs.h b/libretroshare/src/gxs/rsgxs.h index 9c70c8759..c7d74eff1 100644 --- a/libretroshare/src/gxs/rsgxs.h +++ b/libretroshare/src/gxs/rsgxs.h @@ -4,10 +4,7 @@ /* * libretroshare/src/gxs : rsgxs.h * - * GXS interface for RetroShare. - * Convenience header - * - * Copyright 2011 Christopher Evi-Parker + * Copyright 2012 Christopher Evi-Parker * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -25,9 +22,6 @@ * * Please report all bugs and problems to "retroshare@lunamutt.com". * - * This is *THE* auth manager. It provides the web-of-trust via - * gpgme, and authenticates the certificates that are managed - * by the sublayer AuthSSL. * */ @@ -39,6 +33,7 @@ #include #include +/* data types used throughout Gxs from netservice to genexchange */ typedef std::map > GxsMsgReq; typedef std::map > GxsMsgIdResult; diff --git a/libretroshare/src/gxs/rsgxsdata.cc b/libretroshare/src/gxs/rsgxsdata.cc index f8f733fb0..7c6e57b3d 100644 --- a/libretroshare/src/gxs/rsgxsdata.cc +++ b/libretroshare/src/gxs/rsgxsdata.cc @@ -1,4 +1,29 @@ +/* + * libretroshare/src/gxs: rsgxsdata.cc + * + * Gxs Data types used to specific services + * + * Copyright 2012-2012 by Christopher Evi-Parker, Robert Fernie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + #include "rsgxsdata.h" #include "serialiser/rsbaseserial.h" diff --git a/libretroshare/src/gxs/rsgxsdata.h b/libretroshare/src/gxs/rsgxsdata.h index 8eb686e6b..88f8d0241 100644 --- a/libretroshare/src/gxs/rsgxsdata.h +++ b/libretroshare/src/gxs/rsgxsdata.h @@ -1,6 +1,31 @@ #ifndef RSGXSMETA_H #define RSGXSMETA_H +/* + * libretroshare/src/gxs: rsgxsdata.h + * + * Gxs Data types used to specific services + * + * Copyright 2012-2012 by Christopher Evi-Parker, Robert Fernie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + #include #include "serialiser/rsserial.h" diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index 5b113b285..41ab19f1b 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -41,8 +41,6 @@ #define RS_TOKREQOPT_MSG_UPDATED 0x0200 // MSGLIST: Msg that have been updated from specified groups. #define RS_TOKREQOPT_MSG_UPDATED 0x0200 // MSGLIST: Msg that have been updated from specified groups. - - // Read Status. #define RS_TOKREQOPT_READ 0x0001 #define RS_TOKREQOPT_UNREAD 0x0002 @@ -64,7 +62,7 @@ RsGxsDataAccess::RsGxsDataAccess(RsGeneralDataService* ds) } -bool RsGxsDataAccess::requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, +bool RsGxsDataAccess::requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const std::list &groupIds) { GxsRequest* req = NULL; @@ -117,7 +115,7 @@ void RsGxsDataAccess::generateToken(uint32_t &token) bool RsGxsDataAccess::requestMsgInfo(uint32_t &token, uint32_t ansType, - const RsTokReqOptions &opts, const GxsMsgReq &msgIds) + const RsTokReqOptionsV2 &opts, const GxsMsgReq &msgIds) { GxsRequest* req = NULL; @@ -208,7 +206,7 @@ bool RsGxsDataAccess::requestSetMessageStatus(uint32_t& token, const RsGxsGrpMsg return true; } -void RsGxsDataAccess::setReq(GxsRequest* req, const uint32_t& token, const uint32_t& ansType, const RsTokReqOptions& opts) const +void RsGxsDataAccess::setReq(GxsRequest* req, const uint32_t& token, const uint32_t& ansType, const RsTokReqOptionsV2& opts) const { req->token = token; req->ansType = ansType; @@ -477,7 +475,7 @@ void RsGxsDataAccess::processRequests() GxsRequest* req = it->second; if (req->status == GXS_REQUEST_STATUS_PENDING) { - std::cerr << "p3GxsDataService::fakeprocessrequests() Processing Token: " << req->token << " Status: " + std::cerr << "RsGxsDataAccess::processRequests() Processing Token: " << req->token << " Status: " << req->status << " ReqType: " << req->reqType << " Age: " << now - req->reqTime << std::endl; @@ -606,13 +604,10 @@ bool RsGxsDataAccess::getGroupList(GroupIdReq* req) bool RsGxsDataAccess::getMsgData(MsgDataReq* req) { - - GxsMsgResult result; mDataStore->retrieveNxsMsgs(req->mMsgIds, result, true); req->mMsgData = result; - return true; } @@ -638,7 +633,7 @@ bool RsGxsDataAccess::getMsgList(MsgIdReq* req) std::vector groupIds; GxsMsgReq::iterator mit = req->mMsgIds.begin(); - const RsTokReqOptions& opts = req->Options; + const RsTokReqOptionsV2& opts = req->Options; for(; mit != req->mMsgIds.end(); mit++) groupIds.push_back(mit->first); @@ -796,10 +791,35 @@ bool RsGxsDataAccess::getMsgList(MsgIdReq* req) } filterMsgList(req->mMsgIdResult, opts, metaFilter); + + // delete the data + cleanseMetaFilter(metaFilter); + return true; } -void RsGxsDataAccess::filterMsgList(GxsMsgIdResult& msgIds, const RsTokReqOptions& opts, +void RsGxsDataAccess::cleanseMetaFilter(MsgMetaFilter& filter) +{ + MsgMetaFilter::iterator mit = filter.begin(); + + for(; mit !=filter.end(); mit++) + { + std::map& metaM = + mit->second; + std::map::iterator mit2 + = metaM.begin(); + + for(; mit2 != metaM.end(); mit2++) + { + delete mit2->second; + } + } + + filter.clear(); + return; +} + +void RsGxsDataAccess::filterMsgList(GxsMsgIdResult& msgIds, const RsTokReqOptionsV2& opts, const MsgMetaFilter& msgMetas) const { @@ -906,7 +926,7 @@ bool RsGxsDataAccess::updateRequestStatus(const uint32_t& token, return true; } -bool RsGxsDataAccess::checkMsgFilter(const RsTokReqOptions& opts, const RsGxsMsgMetaData* meta) const +bool RsGxsDataAccess::checkMsgFilter(const RsTokReqOptionsV2& opts, const RsGxsMsgMetaData* meta) const { bool statusMatch = false; if (opts.mStatusMask) diff --git a/libretroshare/src/gxs/rsgxsdataaccess.h b/libretroshare/src/gxs/rsgxsdataaccess.h index 27904d749..83177112a 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.h +++ b/libretroshare/src/gxs/rsgxsdataaccess.h @@ -51,7 +51,7 @@ public: * @param groupIds * @return */ - bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds); + bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const std::list &groupIds); /*! * For requesting info on all messages of one or more groups @@ -61,7 +61,7 @@ public: * @param groupIds * @return */ - bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const GxsMsgReq&); + bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq&); /*! * This sets the status of the message @@ -206,7 +206,7 @@ private: * @param ansType * @param opts */ - void setReq(GxsRequest* req,const uint32_t &token, const uint32_t& ansType, const RsTokReqOptions &opts) const; + void setReq(GxsRequest* req,const uint32_t &token, const uint32_t& ansType, const RsTokReqOptionsV2 &opts) const; /*! * Remove request for request queue @@ -242,6 +242,11 @@ private: */ void tokenList(std::list &tokens); + /*! + * Convenience function to delete the ids + * @param filter the meta filter to clean + */ + void cleanseMetaFilter(MsgMetaFilter& filter); private: @@ -297,7 +302,7 @@ private: * @param opts the request options set by user * @param meta The accompanying meta information for msg, ids */ - void filterMsgList(GxsMsgIdResult& msgIds, const RsTokReqOptions& opts, const MsgMetaFilter& meta) const; + void filterMsgList(GxsMsgIdResult& msgIds, const RsTokReqOptionsV2& opts, const MsgMetaFilter& meta) const; /*! @@ -307,7 +312,7 @@ private: * @param meta meta containing currently defined options for msg * @return true if msg meta passes all options */ - bool checkMsgFilter(const RsTokReqOptions& opts, const RsGxsMsgMetaData* meta) const; + bool checkMsgFilter(const RsTokReqOptionsV2& opts, const RsGxsMsgMetaData* meta) const; private: diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index ee6429e4a..80c6353aa 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -1,3 +1,29 @@ + +/* + * libretroshare/src/gxs: rsgxnetservice.cc + * + * Access to rs network and synchronisation service implementation + * + * Copyright 2012-2012 by Christopher Evi-Parker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + #include "rsgxsnetservice.h" #define NXS_NET_DEBUG diff --git a/libretroshare/src/gxs/rsgxsnetservice.h b/libretroshare/src/gxs/rsgxsnetservice.h index 6d12d5119..c4c0b9b40 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.h +++ b/libretroshare/src/gxs/rsgxsnetservice.h @@ -1,6 +1,31 @@ #ifndef RSGXSNETSERVICE_H #define RSGXSNETSERVICE_H +/* + * libretroshare/src/gxs: rsgxnetservice.h + * + * Access to rs network and synchronisation service implementation + * + * Copyright 2012-2012 by Christopher Evi-Parker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + #include #include diff --git a/libretroshare/src/gxs/rsgxsrequesttypes.h b/libretroshare/src/gxs/rsgxsrequesttypes.h index 293584ab2..4ed5ede01 100644 --- a/libretroshare/src/gxs/rsgxsrequesttypes.h +++ b/libretroshare/src/gxs/rsgxsrequesttypes.h @@ -1,13 +1,30 @@ -/* - * rsgxsrequesttypes.h - * - * Created on: 21 Jul 2012 - * Author: crispy - */ - #ifndef RSGXSREQUESTTYPES_H_ #define RSGXSREQUESTTYPES_H_ +/* + * libretroshare/src/gxs: rgxsrequesttypes.h + * + * Type introspect request types for data access request implementation + * + * Copyright 2012-2012 by Christopher Evi-Parker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ class GxsRequest { @@ -21,7 +38,7 @@ public: uint32_t ansType; uint32_t reqType; - RsTokReqOptions Options; + RsTokReqOptionsV2 Options; uint32_t status; }; diff --git a/libretroshare/src/gxs/rsnxs.h b/libretroshare/src/gxs/rsnxs.h index 67a3f4279..0c201a737 100644 --- a/libretroshare/src/gxs/rsnxs.h +++ b/libretroshare/src/gxs/rsnxs.h @@ -2,7 +2,7 @@ #define RSGNP_H /* - * libretroshare/src/gxs: rsgnp.h + * libretroshare/src/gxs: rsnxs.h * * Network Exchange Service interface for RetroShare. * diff --git a/libretroshare/src/gxs/rsnxsobserver.h b/libretroshare/src/gxs/rsnxsobserver.h index 67ff2f799..627080ae7 100644 --- a/libretroshare/src/gxs/rsnxsobserver.h +++ b/libretroshare/src/gxs/rsnxsobserver.h @@ -2,9 +2,9 @@ #define RSNXSOBSERVER_H /* - * libretroshare/src/gxp: gxp.h + * libretroshare/src/gxs: rsnxsobserver.h * - * Observer, interface for RetroShare. + * Observer interface used by nxs to transport new messages to clients * * Copyright 2011-2012 by Robert Fernie, Evi-Parker Christopher * diff --git a/libretroshare/src/gxs/rstokenservice.h b/libretroshare/src/gxs/rstokenservice.h index ee8835b11..4d4dc1843 100644 --- a/libretroshare/src/gxs/rstokenservice.h +++ b/libretroshare/src/gxs/rstokenservice.h @@ -66,10 +66,10 @@ * This class provides useful generic support for GXS style services. * I expect much of this will be incorporated into the base GXS. */ -class RsTokReqOptions +class RsTokReqOptionsV2 { public: -RsTokReqOptions() +RsTokReqOptionsV2() { mOptions = 0; mStatusFilter = 0; mStatusMask = 0; mSubscribeFilter = 0; @@ -124,7 +124,7 @@ public: * @param groupIds group id to request info for. Leave empty to get info on all groups, * @return */ - virtual bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) = 0; + virtual bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const std::list &groupIds) = 0; /*! * Use this to get msg related information, store this value to pole for request completion @@ -134,7 +134,7 @@ public: * @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs * @return */ - virtual bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const GxsMsgReq& msgIds) = 0; + virtual bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq& msgIds) = 0; diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 0e5c67fa3..8c579dee9 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -53,7 +53,7 @@ testnetwork { } -#CONFIG += debug +CONFIG += debug debug { # DEFINES *= DEBUG # DEFINES *= OPENDHT_DEBUG DHT_DEBUG CONN_DEBUG DEBUG_UDP_SORTER P3DISC_DEBUG DEBUG_UDP_LAYER FT_DEBUG EXTADDRSEARCH_DEBUG @@ -678,19 +678,21 @@ HEADERS += serialiser/rsnxsitems.h \ gxs/rsgxsdataaccess.h \ retroshare/rsgxsservice.h \ serialiser/rsgxsitems.h \ - serialiser/rsphotov2items.h \ - util/retrodb.h + serialiser/rsphotov2items.h \ + util/retrodb.h \ + gxs/gxscoreserver.h SOURCES += serialiser/rsnxsitems.cc \ - gxs/rsdataservice.cc \ - gxs/rsgenexchange.cc \ + gxs/rsdataservice.cc \ + gxs/rsgenexchange.cc \ gxs/rsgxsnetservice.cc \ gxs/rsgxsdata.cc \ serialiser/rsgxsitems.cc \ services/p3photoserviceV2.cc \ gxs/rsgxsdataaccess.cc \ - serialiser/rsphotov2items.cc \ - util/retrodb.cc + serialiser/rsphotov2items.cc \ + util/retrodb.cc \ + gxs/gxscoreserver.cc } diff --git a/libretroshare/src/retroshare/rsgxsservice.h b/libretroshare/src/retroshare/rsgxsservice.h index 96ba495af..d9df811c1 100644 --- a/libretroshare/src/retroshare/rsgxsservice.h +++ b/libretroshare/src/retroshare/rsgxsservice.h @@ -17,6 +17,7 @@ class RsGxsNotify { public: RsGxsNotify(){ return; } + virtual ~RsGxsNotify() {return; } }; diff --git a/libretroshare/src/retroshare/rsphotoV2.h b/libretroshare/src/retroshare/rsphotoV2.h index 1ae59bed9..80ad2ca72 100644 --- a/libretroshare/src/retroshare/rsphotoV2.h +++ b/libretroshare/src/retroshare/rsphotoV2.h @@ -30,6 +30,7 @@ #include #include #include "rsgxsservice.h" +#include "rsphoto.h" /* The Main Interface Class - for information about your Peers */ class RsPhotoV2; @@ -41,20 +42,20 @@ extern RsPhotoV2 *rsPhotoV2; #define RSPHOTO_MODE_OWN 2 #define RSPHOTO_MODE_REMOTE 3 -class RsPhotoThumbnail -{ - public: - RsPhotoThumbnail() - :data(NULL), size(0), type("N/A") { return; } - - bool deleteImage(); - bool copyFrom(const RsPhotoThumbnail &nail); - - // Holds Thumbnail image. - uint8_t *data; - int size; - std::string type; -}; +//class RsPhotoThumbnail +//{ +// public: +// RsPhotoThumbnail() +// :data(NULL), size(0), type("N/A") { return; } +// +// bool deleteImage(); +// bool copyFrom(const RsPhotoThumbnail &nail); +// +// // Holds Thumbnail image. +// uint8_t *data; +// int size; +// std::string type; +//}; /* If these flags are no set - the Photo inherits values from the Album @@ -76,84 +77,84 @@ class RsPhotoThumbnail #define RSPHOTO_FLAGS_ATTRIB_PHOTO 0x2000 // PUSH UP ORDER. -class RsPhotoPhoto -{ - public: +//class RsPhotoPhoto +//{ +// public: +// +// RsMsgMetaData mMeta; +// +// RsPhotoPhoto(); +// +// // THESE ARE IN THE META DATA. +// //std::string mAlbumId; +// //std::string mId; +// //std::string mTitle; // only used by Album. +// std::string mCaption; +// std::string mDescription; +// std::string mPhotographer; +// std::string mWhere; +// std::string mWhen; +// std::string mOther; +// std::string mCategory; +// +// std::string mHashTags; +// +// uint32_t mSetFlags; +// +// int mOrder; +// +// RsPhotoThumbnail mThumbnail; +// +// int mMode; +// +// // These are not saved. +// std::string path; // if in Mode NEW. +// uint32_t mModFlags; +//}; - RsMsgMetaData mMeta; - - RsPhotoPhoto(); - - // THESE ARE IN THE META DATA. - //std::string mAlbumId; - //std::string mId; - //std::string mTitle; // only used by Album. - std::string mCaption; - std::string mDescription; - std::string mPhotographer; - std::string mWhere; - std::string mWhen; - std::string mOther; - std::string mCategory; - - std::string mHashTags; - - uint32_t mSetFlags; - - int mOrder; - - RsPhotoThumbnail mThumbnail; - - int mMode; - - // These are not saved. - std::string path; // if in Mode NEW. - uint32_t mModFlags; -}; - -class RsPhotoAlbumShare -{ - public: - - uint32_t mShareType; - std::string mShareGroupId; - std::string mPublishKey; - uint32_t mCommentMode; - uint32_t mResizeMode; -}; - -class RsPhotoAlbum -{ - public: - RsPhotoAlbum(); - - RsGroupMetaData mMeta; - - // THESE ARE IN THE META DATA. - //std::string mAlbumId; - //std::string mTitle; // only used by Album. - - std::string mCaption; - std::string mDescription; - std::string mPhotographer; - std::string mWhere; - std::string mWhen; - std::string mOther; - std::string mCategory; - - std::string mHashTags; - - RsPhotoThumbnail mThumbnail; - - int mMode; - - std::string mPhotoPath; - RsPhotoAlbumShare mShareOptions; - - // These aren't saved. - uint32_t mSetFlags; - uint32_t mModFlags; -}; +//class RsPhotoAlbumShare +//{ +// public: +// +// uint32_t mShareType; +// std::string mShareGroupId; +// std::string mPublishKey; +// uint32_t mCommentMode; +// uint32_t mResizeMode; +//}; +// +//class RsPhotoAlbum +//{ +// public: +// RsPhotoAlbum(); +// +// RsGroupMetaData mMeta; +// +// // THESE ARE IN THE META DATA. +// //std::string mAlbumId; +// //std::string mTitle; // only used by Album. +// +// std::string mCaption; +// std::string mDescription; +// std::string mPhotographer; +// std::string mWhere; +// std::string mWhen; +// std::string mOther; +// std::string mCategory; +// +// std::string mHashTags; +// +// RsPhotoThumbnail mThumbnail; +// +// int mMode; +// +// std::string mPhotoPath; +// RsPhotoAlbumShare mShareOptions; +// +// // These aren't saved. +// uint32_t mSetFlags; +// uint32_t mModFlags; +//}; std::ostream &operator<<(std::ostream &out, const RsPhotoPhoto &photo); std::ostream &operator<<(std::ostream &out, const RsPhotoAlbum &album); diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 9ee634604..ebc9241bb 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1807,6 +1807,15 @@ RsTurtle *rsTurtle = NULL ; #include "turtle/p3turtle.h" #define ENABLE_GXS_SERVICES 1 +#define ENABLE_GXS_CORE 1 + +#ifdef ENABLE_GXS_CORE +#include "gxs/gxscoreserver.h" +#include "services/p3photoserviceV2.h" +#include "gxs/rsdataservice.h" +#include "gxs/rsgxsnetservice.h" +#endif + #ifdef ENABLE_GXS_SERVICES #include "services/p3photoservice.h" #include "services/p3wikiservice.h" @@ -2256,6 +2265,36 @@ int RsServer::StartupRetroShare() mPluginsManager->registerClientServices(pqih) ; mPluginsManager->registerCacheServices() ; +#ifdef ENABLE_GXS_CORE + + p3PhotoServiceV2 *mPhotoV2 = NULL; + + // first prep the core + + RsGeneralDataService* photo_ds = new RsDataService("./", "photoV2_db", + RS_SERVICE_TYPE_PHOTO, NULL); + + // TODO need net manager + //RsGxsNetService* photo_ns = new RsGxsNetService( + // RS_SERVICE_TYPE_PHOTO, photo_ds, NULL, mPhotoV2); + + + // init gxs services + mPhotoV2 = new p3PhotoServiceV2(photo_ds, NULL); + + GxsCoreServer* mGxsCore = new GxsCoreServer(); + mGxsCore->addService(mPhotoV2); + + // cores read start up servers ! + + // start nxs core core server + //createThread(*photo_ns); + + // start up gxs core server + createThread(*mGxsCore); + +#endif + #ifdef ENABLE_GXS_SERVICES // Testing New Cache Services. p3PhotoService *mPhotos = new p3PhotoService(RS_SERVICE_TYPE_PHOTO); @@ -2543,6 +2582,7 @@ int RsServer::StartupRetroShare() // Testing of new cache system interfaces. rsIdentity = mIdentity; rsPhoto = mPhotos; + rsPhotoV2 = mPhotoV2; rsWiki = mWikis; rsWire = mWire; rsForumsV2 = mForumsV2; diff --git a/libretroshare/src/serialiser/rsnxsitems.h b/libretroshare/src/serialiser/rsnxsitems.h index 02a5fdafe..629468b89 100644 --- a/libretroshare/src/serialiser/rsnxsitems.h +++ b/libretroshare/src/serialiser/rsnxsitems.h @@ -259,7 +259,9 @@ class RsNxsMsg : public RsNxsItem { public: - RsNxsMsg(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_MSG), msg(servtype), meta(servtype) { clear(); return; } + RsNxsMsg(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_MSG), msg(servtype), meta(servtype), + metaData(NULL) { clear(); return; } + ~RsNxsMsg() { if(metaData) delete metaData; } virtual void clear(); virtual std::ostream &print(std::ostream &out, uint16_t indent); diff --git a/libretroshare/src/serialiser/rsphotov2items.cc b/libretroshare/src/serialiser/rsphotov2items.cc index 921deca22..4b64a363e 100644 --- a/libretroshare/src/serialiser/rsphotov2items.cc +++ b/libretroshare/src/serialiser/rsphotov2items.cc @@ -95,9 +95,9 @@ RsItem* RsGxsPhotoSerialiser::deserialise(void* data, uint32_t* size) switch(getRsItemSubType(rstype)) { - case RS_PKT_SUBTYPE_NXS_SYNC_GRP: + case RS_PKT_SUBTYPE_PHOTO_SHOW_ITEM: return deserialiseGxsPhotoPhotoItem(data, size); - case RS_PKT_SUBTYPE_NXS_SYNC_GRP_ITEM: + case RS_PKT_SUBTYPE_PHOTO_ITEM: return deserialiseGxsPhotoAlbumItem(data, size); default: { @@ -174,9 +174,9 @@ bool RsGxsPhotoSerialiser::serialiseGxsPhotoAlbumItem(RsGxsPhotoAlbumItem* item, ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mWhen); ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mWhere); ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mThumbnail.type); - RsTlvBinaryData b(item->PacketService()); // TODO, need something more persisitent - b.setBinData(item->album.mThumbnail.data, item->album.mThumbnail.size); - b.SetTlv(item->album.mThumbnail.data, tlvsize, &offset); + RsTlvBinaryData b(RS_SERVICE_TYPE_PHOTO); // TODO, need something more persisitent + b.setBinData(item->album.mThumbnail.data, item->album.mThumbnail.size); + ok &= b.SetTlv(data, tlvsize, &offset); if(offset != tlvsize) { @@ -340,9 +340,9 @@ bool RsGxsPhotoSerialiser::serialiseGxsPhotoPhotoItem(RsGxsPhotoPhotoItem* item, ok &= SetTlvString(data, tlvsize, &offset, 1, item->photo.mWhen); ok &= SetTlvString(data, tlvsize, &offset, 1, item->photo.mWhere); ok &= SetTlvString(data, tlvsize, &offset, 1, item->photo.mThumbnail.type); - RsTlvBinaryData b(RS_SERVICE_TYPE_PHOTO); // TODO, need something more persisitent - b.setBinData(item->photo.mThumbnail.data, item->photo.mThumbnail.size); - b.SetTlv(item->photo.mThumbnail.data, tlvsize, &offset); + RsTlvBinaryData b(RS_SERVICE_TYPE_PHOTO); // TODO, need something more persisitent + b.setBinData(item->photo.mThumbnail.data, item->photo.mThumbnail.size); + ok &= b.SetTlv(data, tlvsize, &offset); if(offset != tlvsize) { diff --git a/libretroshare/src/services/p3photoservice.cc b/libretroshare/src/services/p3photoservice.cc index e1dd0a50d..ce37ec59a 100644 --- a/libretroshare/src/services/p3photoservice.cc +++ b/libretroshare/src/services/p3photoservice.cc @@ -639,6 +639,7 @@ bool RsPhotoThumbnail::deleteImage() free(data); data = NULL; size = 0; + type.clear(); } return true; } diff --git a/libretroshare/src/services/p3photoserviceV2.cc b/libretroshare/src/services/p3photoserviceV2.cc index 31ec27ec0..e8c747b88 100644 --- a/libretroshare/src/services/p3photoserviceV2.cc +++ b/libretroshare/src/services/p3photoserviceV2.cc @@ -11,16 +11,37 @@ p3PhotoServiceV2::p3PhotoServiceV2(RsGeneralDataService* gds, RsNetworkExchangeS bool p3PhotoServiceV2::updated() { - return false; + bool changed = (!mGroupChange.empty() || !mMsgChange.empty()); + + std::list gL; + std::map > msgs; + + groupsChanged(gL); + msgsChanged(msgs); + + return changed; } -void p3PhotoServiceV2::groupsChanged(std::list& grpIds) { + +void p3PhotoServiceV2::groupsChanged(std::list& grpIds) +{ + while(!mGroupChange.empty()) + { + RsGxsGroupChange* gc = mGroupChange.back(); + std::list& gList = gc->grpIdList; + std::list::iterator lit = gList.begin(); + for(; lit != gList.end(); lit++) + grpIds.push_back(*lit); + + mGroupChange.pop_back(); + delete gc; + } } void p3PhotoServiceV2::msgsChanged( - std::map >& msgs) + std::map >& msgs) { } @@ -33,7 +54,7 @@ RsTokenServiceV2* p3PhotoServiceV2::getTokenService() { bool p3PhotoServiceV2::getGroupList(const uint32_t& token, - std::list& groupIds) + std::list& groupIds) { return RsGenExchange::getGroupList(token, groupIds); } @@ -74,6 +95,7 @@ bool p3PhotoServiceV2::getAlbum(const uint32_t& token, std::vector { RsGxsPhotoAlbumItem* item = dynamic_cast(*vit); RsPhotoAlbum album = item->album; + album.mMeta = item->album.mMeta; delete item; albums.push_back(album); } @@ -105,6 +127,7 @@ bool p3PhotoServiceV2::getPhoto(const uint32_t& token, PhotoResult& photos) if(item) { RsPhotoPhoto photo = item->photo; + photo.mMeta = item->meta; photos[grpId].push_back(photo); delete item; }else @@ -121,14 +144,45 @@ bool p3PhotoServiceV2::getPhoto(const uint32_t& token, PhotoResult& photos) bool p3PhotoServiceV2::submitAlbumDetails(RsPhotoAlbum& album) { - return false; + RsGxsPhotoAlbumItem* albumItem = new RsGxsPhotoAlbumItem(); + albumItem->album = album; + albumItem->meta = album.mMeta; + return RsGenExchange::publishGroup(albumItem); } +void p3PhotoServiceV2::notifyChanges(std::vector& changes) +{ + std::vector::iterator vit = changes.begin(); + + for(; vit != changes.end(); vit++) + { + RsGxsNotify* n = *vit; + RsGxsGroupChange* gc; + RsGxsMsgChange* mc; + if((mc = dynamic_cast(n)) != NULL) + { + mMsgChange.push_back(mc); + } + else if((gc = dynamic_cast(n)) != NULL) + { + mGroupChange.push_back(gc); + } + else + { + delete n; + } + } +} + bool p3PhotoServiceV2::submitPhoto(RsPhotoPhoto& photo) { - return false; + RsGxsPhotoPhotoItem* photoItem = new RsGxsPhotoPhotoItem(); + photoItem->photo = photo; + photoItem->meta = photo.mMeta; + + return RsGenExchange::publishMsg(photoItem); } diff --git a/libretroshare/src/services/p3photoserviceV2.h b/libretroshare/src/services/p3photoserviceV2.h index d92317c91..e2057550c 100644 --- a/libretroshare/src/services/p3photoserviceV2.h +++ b/libretroshare/src/services/p3photoserviceV2.h @@ -43,20 +43,23 @@ public: */ bool updated(); +protected: + + void notifyChanges(std::vector& changes); public: /** Requests **/ - void groupsChanged(std::list& grpIds); + void groupsChanged(std::list& grpIds); - void msgsChanged(std::map >& msgs); + void msgsChanged(std::map >& msgs); RsTokenServiceV2* getTokenService(); bool getGroupList(const uint32_t &token, - std::list &groupIds); + std::list &groupIds); bool getMsgList(const uint32_t &token, GxsMsgIdResult& msgIds); @@ -77,6 +80,11 @@ public: bool submitAlbumDetails(RsPhotoAlbum &album); bool submitPhoto(RsPhotoPhoto &photo); + +private: + + std::vector mGroupChange; + std::vector mMsgChange; }; #endif // P3PHOTOSERVICEV2_H diff --git a/libretroshare/src/tests/serialiser/rsphotoitem_test.cc b/libretroshare/src/tests/serialiser/rsphotoitem_test.cc new file mode 100644 index 000000000..fafd1650d --- /dev/null +++ b/libretroshare/src/tests/serialiser/rsphotoitem_test.cc @@ -0,0 +1,139 @@ +/* + * libretroshare/src/test rsphotoitem_test.cc + * + * Test for photo item serialisation + * + * Copyright 2012-2012 by Christopher Evi-Parker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + + +#include "rsphotoitem_test.h" + + +RsSerialType* init_item(RsGxsPhotoAlbumItem &album) +{ + RsPhotoAlbum& a = album.album; + + randString(SHORT_STR, a.mCaption); + randString(SHORT_STR, a.mCategory); + randString(SHORT_STR, a.mDescription); + randString(SHORT_STR, a.mHashTags); + randString(SHORT_STR, a.mOther); + randString(SHORT_STR, a.mPhotoPath); + randString(SHORT_STR, a.mPhotographer); + randString(SHORT_STR, a.mWhen); + randString(SHORT_STR, a.mWhere); + randString(SHORT_STR, a.mThumbnail.type); + std::string rStr; + randString(SHORT_STR, rStr); + + a.mThumbnail.data = new uint8_t[SHORT_STR]; + memcpy(a.mThumbnail.data, rStr.data(), SHORT_STR); + a.mThumbnail.size = SHORT_STR; + + return new RsGxsPhotoSerialiser(); +} + +RsSerialType* init_item(RsGxsPhotoPhotoItem &photo) +{ + + RsPhotoPhoto& p = photo.photo; + + randString(SHORT_STR, p.mCaption); + randString(SHORT_STR, p.mCategory); + randString(SHORT_STR, p.mDescription); + randString(SHORT_STR, p.mHashTags); + randString(SHORT_STR, p.mOther); + randString(SHORT_STR, p.mPhotographer); + randString(SHORT_STR, p.mWhen); + randString(SHORT_STR, p.mWhere); + randString(SHORT_STR, p.mThumbnail.type); + std::string rStr; + randString(SHORT_STR, rStr); + + p.mThumbnail.data = new uint8_t[SHORT_STR]; + memcpy(p.mThumbnail.data, rStr.data(), SHORT_STR); + p.mThumbnail.size = SHORT_STR; + + return new RsGxsPhotoSerialiser(); +} + + +bool operator == (RsGxsPhotoAlbumItem& l, RsGxsPhotoAlbumItem& r) +{ + RsPhotoAlbum& la = l.album; + RsPhotoAlbum& ra = r.album; + + if(la.mCaption != ra.mCaption) return false; + if(la.mCategory != ra.mCategory) return false; + if(la.mDescription != ra.mDescription) return false; + if(la.mHashTags != ra.mHashTags) return false; + if(la.mOther != ra.mOther) return false; + if(la.mPhotographer!= ra.mPhotographer) return false; + if(la.mPhotoPath != ra.mPhotoPath) return false; + if(la.mWhere != ra.mWhere) return false; + if(la.mWhen != ra.mWhen) return false; + if(!(la.mThumbnail == ra.mThumbnail)) return false; + + return true; +} + + + +bool operator == (RsGxsPhotoPhotoItem& l, RsGxsPhotoPhotoItem& r) +{ + RsPhotoPhoto& la = l.photo; + RsPhotoPhoto& ra = r.photo; + + if(la.mCaption != ra.mCaption) return false; + if(la.mCategory != ra.mCategory) return false; + if(la.mDescription != ra.mDescription) return false; + if(la.mHashTags != ra.mHashTags) return false; + if(la.mOther != ra.mOther) return false; + if(la.mPhotographer!= ra.mPhotographer) return false; + if(la.mWhere != ra.mWhere) return false; + if(la.mWhen != ra.mWhen) return false; + if(!(la.mThumbnail == ra.mThumbnail)) return false; + + return true; +} + +bool operator == (RsPhotoThumbnail& l, RsPhotoThumbnail& r) +{ + if(l.size != r.size) return false; + if(l.type != r.type) return false; + if(memcmp(l.data, r.data,l.size) != 0) return false; + + return true; +} + +INITTEST() + +int main() +{ + std::cerr << "RsPhotoItem Tests" << std::endl; + + test_RsItem(); REPORT("Serialise/Deserialise RsGxsPhotoAlbumItem"); + test_RsItem(); REPORT("Serialise/Deserialise RsGxsPhotoPhotoItem"); + + FINALREPORT("RsPhotoItem Tests"); + + return TESTRESULT(); +} diff --git a/libretroshare/src/tests/serialiser/rsphotoitem_test.h b/libretroshare/src/tests/serialiser/rsphotoitem_test.h new file mode 100644 index 000000000..cd726198e --- /dev/null +++ b/libretroshare/src/tests/serialiser/rsphotoitem_test.h @@ -0,0 +1,41 @@ +/* + * libretroshare/src/test rsphotoitem_test.h + * + * Test for photo item serialisation + * + * Copyright 2012-2012 by Christopher Evi-Parker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#ifndef RSPHOTOITEM_TEST_H_ +#define RSPHOTOITEM_TEST_H_ + +#include "serialiser/rsphotov2items.h" +#include "support.h" + + + +RsSerialType* init_item(RsGxsPhotoAlbumItem& album); +RsSerialType* init_item(RsGxsPhotoPhotoItem& photo); + +bool operator == (RsGxsPhotoAlbumItem& l, RsGxsPhotoAlbumItem& r); +bool operator == (RsGxsPhotoPhotoItem& l, RsGxsPhotoPhotoItem& r); +bool operator == (RsPhotoThumbnail& l, RsPhotoThumbnail& r); + +#endif /* RSPHOTOITEM_TEST_H_ */ diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp index 4786c10b2..9dc756666 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp @@ -476,9 +476,9 @@ void PhotoAddDialog::loadAlbum(const std::string &albumId) clearDialog(); mAlbumEdit = true; - RsTokReqOptions opts; + RsTokReqOptionsV2 opts; uint32_t token; - std::list albumIds; + std::list albumIds; albumIds.push_back(albumId); // We need both Album and Photo Data. @@ -493,27 +493,28 @@ bool PhotoAddDialog::loadPhotoData(const uint32_t &token) std::cerr << "PhotoAddDialog::loadPhotoData()"; std::cerr << std::endl; - bool moreData = true; - while(moreData) - { - PhotoResult res; - RsPhotoPhoto photo; - - if (rsPhotoV2->getPhoto(token, res)) - { - std::cerr << "PhotoDialog::addAddPhoto() AlbumId: " << photo.mMeta.mGroupId; - std::cerr << " PhotoId: " << photo.mMeta.mMsgId; - std::cerr << std::endl; + PhotoResult res; + rsPhotoV2->getPhoto(token, res); + PhotoResult::iterator mit = res.begin(); + + + for(; mit != res.end(); mit++) + { + std::vector& photoV = mit->second; + std::vector::iterator vit = photoV.begin(); + + for(; vit != photoV.end(); vit++) + { + RsPhotoPhoto& photo = *vit; + PhotoItem *item = new PhotoItem(NULL, photo, mAlbumData); + ui.scrollAreaWidgetContents->addPhotoItem(item); + + std::cerr << "PhotoAddDialog::loadPhotoData() AlbumId: " << photo.mMeta.mGroupId; + std::cerr << " PhotoId: " << photo.mMeta.mMsgId; + std::cerr << std::endl; + } + } - PhotoItem *item = new PhotoItem(NULL, photo, mAlbumData); - ui.scrollAreaWidgetContents->addPhotoItem(item); - - } - else - { - moreData = false; - } - } return true; } @@ -521,32 +522,32 @@ bool PhotoAddDialog::loadAlbumData(const uint32_t &token) { std::cerr << "PhotoAddDialog::loadAlbumData()"; std::cerr << std::endl; - - bool moreData = true; - while(moreData) - { - std::vector albums; - RsPhotoAlbum album; - if (rsPhotoV2->getAlbum(token, albums)) - { - std::cerr << " PhotoAddDialog::loadAlbumData() AlbumId: " << album.mMeta.mGroupId << std::endl; - updateAlbumDetails(album); - RsTokReqOptions opts; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - uint32_t token; - std::list albumIds; - albumIds.push_back(album.mMeta.mGroupId); - GxsMsgReq req; - req[album.mMeta.mGroupId] = std::vector(); - mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, req, 0); - } - else - { - moreData = false; - } - } - return true; + std::vector albums; + rsPhotoV2->getAlbum(token, albums); + + std::vector::iterator vit = albums.begin(); + + GxsMsgReq req; + + for(; vit != albums.end(); vit++) + { + RsPhotoAlbum& album = *vit; + + std::cerr << "PhotoAddDialog::loadAlbumData() AlbumId: " << album.mMeta.mGroupId << std::endl; + //updateAlbumDetails(album); + + uint32_t token; + std::list albumIds; + albumIds.push_back(album.mMeta.mGroupId); + req[album.mMeta.mGroupId] = std::vector(); + + } + RsTokReqOptionsV2 opts; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST; + uint32_t t; + mPhotoQueue->requestMsgInfo(t, RS_TOKREQ_ANSTYPE_DATA, opts, req, 0); + return true; } bool PhotoAddDialog::loadCreatedAlbum(const uint32_t &token) diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index 044e13eae..ddea51908 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -431,7 +431,7 @@ void PhotoDialog::requestAlbumList() { std::list ids; - RsTokReqOptions opts; + RsTokReqOptionsV2 opts; uint32_t token; mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, ids, 0); } @@ -454,13 +454,12 @@ void PhotoDialog::loadAlbumList(const uint32_t &token) { requestPhotoList(*it); } - } void PhotoDialog::requestAlbumData(std::list &ids) { - RsTokReqOptions opts; + RsTokReqOptionsV2 opts; uint32_t token; mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, 0); } @@ -473,25 +472,21 @@ bool PhotoDialog::loadAlbumData(const uint32_t &token) clearAlbums(); - bool moreData = true; - while(moreData) - { - RsPhotoAlbum album; - std::vector albums; - if (rsPhotoV2->getAlbum(token, albums)) - { - std::cerr << " PhotoDialog::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; + std::vector albums; + rsPhotoV2->getAlbum(token, albums); - PhotoItem *item = new PhotoItem(this, album); - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - alayout->addWidget(item); - } - else - { - moreData = false; - } - } + std::vector::iterator vit = albums.begin(); + for(; vit != albums.end(); vit++) + { + RsPhotoAlbum& album = *vit; + + std::cerr << " PhotoDialog::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; + + PhotoItem *item = new PhotoItem(this, album); + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); + alayout->addWidget(item); + } return true; } @@ -499,10 +494,9 @@ bool PhotoDialog::loadAlbumData(const uint32_t &token) void PhotoDialog::requestPhotoList(const std::string &albumId) { - std::list ids; GxsMsgReq req; req[albumId] = std::vector(); - RsTokReqOptions opts; + RsTokReqOptionsV2 opts; opts.mOptions = RS_TOKREQOPT_MSG_LATEST; uint32_t token; mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, req, 0); @@ -527,7 +521,7 @@ void PhotoDialog::loadPhotoList(const uint32_t &token) void PhotoDialog::requestPhotoData(GxsMsgReq &photoIds) { - RsTokReqOptions opts; + RsTokReqOptionsV2 opts; uint32_t token; mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, photoIds, 0); } @@ -538,25 +532,25 @@ void PhotoDialog::loadPhotoData(const uint32_t &token) std::cerr << "PhotoDialog::loadPhotoData()"; std::cerr << std::endl; - bool moreData = true; - while(moreData) - { - RsPhotoPhoto photo; - PhotoResult res; - if (rsPhotoV2->getPhoto(token, res)) - { + PhotoResult res; + rsPhotoV2->getPhoto(token, res); + PhotoResult::iterator mit = res.begin(); - std::cerr << "PhotoDialog::loadPhotoData() AlbumId: " << photo.mMeta.mGroupId; - std::cerr << " PhotoId: " << photo.mMeta.mMsgId; - std::cerr << std::endl; - addPhoto(photo); - } - else - { - moreData = false; - } - } + for(; mit != res.end(); mit++) + { + std::vector& photoV = mit->second; + std::vector::iterator vit = photoV.begin(); + + for(; vit != photoV.end(); vit++) + { + RsPhotoPhoto& photo = *vit; + addPhoto(photo); + std::cerr << "PhotoDialog::loadPhotoData() AlbumId: " << photo.mMeta.mGroupId; + std::cerr << " PhotoId: " << photo.mMeta.mMsgId; + std::cerr << std::endl; + } + } } diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp index c2fad4ef1..7330796e3 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp @@ -244,7 +244,7 @@ void PhotoSlideShow::loadAlbum(const std::string &albumId) /* much like main load fns */ clearDialog(); - RsTokReqOptions opts; + RsTokReqOptionsV2 opts; uint32_t token; std::list albumIds; albumIds.push_back(albumId); @@ -261,31 +261,34 @@ bool PhotoSlideShow::loadPhotoData(const uint32_t &token) std::cerr << "PhotoSlideShow::loadPhotoData()"; std::cerr << std::endl; - bool moreData = true; - while(moreData) - { - RsPhotoPhoto photo; - PhotoResult res; - - if (rsPhotoV2->getPhoto(token, res)) - { - RsPhotoPhoto *ptr = new RsPhotoPhoto; - *ptr = photo; - ptr->mThumbnail.data = 0; - ptr->mThumbnail.copyFrom(photo.mThumbnail); + PhotoResult res; + rsPhotoV2->getPhoto(token, res); + PhotoResult::iterator mit = res.begin(); - mPhotos[photo.mMeta.mMsgId] = ptr; - mPhotoOrder[ptr->mOrder] = photo.mMeta.mMsgId; - std::cerr << "PhotoSlideShow::addAddPhoto() AlbumId: " << photo.mMeta.mGroupId; - std::cerr << " PhotoId: " << photo.mMeta.mMsgId; - std::cerr << std::endl; - } - else - { - moreData = false; - } - } + for(; mit != res.end(); mit++) + { + std::vector& photoV = mit->second; + std::vector::iterator vit = photoV.begin(); + + for(; vit != photoV.end(); vit++) + { + RsPhotoPhoto& photo = *vit; + RsPhotoPhoto *ptr = new RsPhotoPhoto; + *ptr = photo; + ptr->mThumbnail.data = 0; + ptr->mThumbnail.copyFrom(photo.mThumbnail); + + mPhotos[photo.mMeta.mMsgId] = ptr; + mPhotoOrder[ptr->mOrder] = photo.mMeta.mMsgId; + + std::cerr << "PhotoSlideShow::addAddPhoto() AlbumId: " << photo.mMeta.mGroupId; + std::cerr << " PhotoId: " << photo.mMeta.mMsgId; + std::cerr << std::endl; + } + } + + // Load and Start. loadImage(); @@ -299,30 +302,30 @@ bool PhotoSlideShow::loadAlbumData(const uint32_t &token) std::cerr << "PhotoSlideShow::loadAlbumData()"; std::cerr << std::endl; - bool moreData = true; - while(moreData) - { - RsPhotoAlbum album; - std::vector res; - if (rsPhotoV2->getAlbum(token, res)) - { - std::cerr << " PhotoSlideShow::loadAlbumData() AlbumId: " << album.mMeta.mGroupId << std::endl; - //updateAlbumDetails(album); + std::vector albums; + rsPhotoV2->getAlbum(token, albums); - RsTokReqOptions opts; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - uint32_t token; - std::list albumIds; - albumIds.push_back(album.mMeta.mGroupId); - GxsMsgReq req; - req[album.mMeta.mGroupId] = std::vector(); - mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, req, 0); - } - else - { - moreData = false; - } - } + std::vector::iterator vit = albums.begin(); + + GxsMsgReq req; + + for(; vit != albums.end(); vit++) + { + RsPhotoAlbum& album = *vit; + + std::cerr << " PhotoSlideShow::loadAlbumData() AlbumId: " << album.mMeta.mGroupId << std::endl; + //updateAlbumDetails(album); + uint32_t token; + std::list albumIds; + albumIds.push_back(album.mMeta.mGroupId); + req[album.mMeta.mGroupId] = std::vector(); + + } + + RsTokReqOptionsV2 opts; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST; + uint32_t t; + mPhotoQueue->requestMsgInfo(t, RS_TOKREQ_ANSTYPE_DATA, opts, req, 0); return true; } diff --git a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp index 69fe7f92c..d3002dc7c 100644 --- a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp +++ b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp @@ -32,7 +32,7 @@ #include -//#include "gui/PhotoShare/PhotoDialog.h" +#include "gui/PhotoShare/PhotoDialog.h" #include "gui/WikiPoos/WikiDialog.h" #include "gui/TheWire/WireDialog.h" #include "gui/Identity/IdDialog.h" @@ -97,9 +97,9 @@ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) ui.stackPages->add(idDialog = new IdDialog(ui.stackPages), createPageAction(QIcon(IMAGE_LIBRARY), tr("Identities"), grp)); - //PhotoDialog *photoDialog = NULL; - //ui.stackPages->add(photoDialog = new PhotoDialog(ui.stackPages), - // createPageAction(QIcon(IMAGE_PHOTO), tr("Photo View"), grp)); + PhotoDialog *photoDialog = NULL; + ui.stackPages->add(photoDialog = new PhotoDialog(ui.stackPages), + createPageAction(QIcon(IMAGE_PHOTO), tr("Photo View"), grp)); WikiDialog *wikiDialog = NULL; ui.stackPages->add(wikiDialog = new WikiDialog(ui.stackPages), diff --git a/retroshare-gui/src/util/TokenQueueV2.cpp b/retroshare-gui/src/util/TokenQueueV2.cpp index 934c4b2c1..4dd444465 100644 --- a/retroshare-gui/src/util/TokenQueueV2.cpp +++ b/retroshare-gui/src/util/TokenQueueV2.cpp @@ -38,7 +38,7 @@ TokenQueueV2::TokenQueueV2(RsTokenServiceV2 *service, TokenResponseV2 *resp) return; } -bool TokenQueueV2::requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, std::list& ids, uint32_t usertype) +bool TokenQueueV2::requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, std::list& ids, uint32_t usertype) { uint32_t basictype = TOKENREQ_GROUPINFO; mService->requestGroupInfo(token, anstype, opts, ids); @@ -48,7 +48,7 @@ bool TokenQueueV2::requestGroupInfo(uint32_t &token, uint32_t anstype, const RsT } -bool TokenQueueV2::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, const GxsMsgReq& ids, uint32_t usertype) +bool TokenQueueV2::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, const GxsMsgReq& ids, uint32_t usertype) { uint32_t basictype = TOKENREQ_MSGINFO; mService->requestMsgInfo(token, anstype, opts, ids); diff --git a/retroshare-gui/src/util/TokenQueueV2.h b/retroshare-gui/src/util/TokenQueueV2.h index 40ed5d1da..aa85ac135 100644 --- a/retroshare-gui/src/util/TokenQueueV2.h +++ b/retroshare-gui/src/util/TokenQueueV2.h @@ -21,8 +21,8 @@ * */ -#ifndef MRK_TOKEN_QUEUE_H -#define MRK_TOKEN_QUEUE_H +#ifndef MRK_TOKEN_QUEUE_V2_H +#define MRK_TOKEN_QUEUE_V2_H #include #include @@ -70,9 +70,9 @@ public: TokenQueueV2(RsTokenServiceV2 *service, TokenResponseV2 *resp); /* generic handling of token / response update behaviour */ - bool requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, + bool requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, std::list& ids, uint32_t usertype); - bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, + bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, const GxsMsgReq& ids, uint32_t usertype); bool cancelRequest(const uint32_t token); From db35ae95af90eee0d52fdbe82254119e42f1adbd Mon Sep 17 00:00:00 2001 From: drbob Date: Tue, 7 Aug 2012 23:55:43 +0000 Subject: [PATCH 018/222] Added Basics of Menu System to retroshare-nogui. * Menu System basic structure complete. * Added functions to NotifyTxt to handle search results. * Running from std::cin at the moment. * Functional Commands: - List Friends, Network. - Show Transfers, Cancel Transfers. - Basic Search, and Download. * Not Connected to SSH server at this point, TODO. * Lots of Other Commands to add (e.g. import/add/remove friends, forums, etc) * Enable via option in retroshare-nogui.pro, instructions at bottom of file. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5390 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/menu/menu.cc | 766 ++++++++++++++++++++++ retroshare-nogui/src/menu/menu.h | 178 +++++ retroshare-nogui/src/menu/menus.cc | 578 ++++++++++++++++ retroshare-nogui/src/menu/menus.h | 269 ++++++++ retroshare-nogui/src/menu/menutest.h | 32 + retroshare-nogui/src/notifytxt.cc | 93 ++- retroshare-nogui/src/notifytxt.h | 19 +- retroshare-nogui/src/retroshare-nogui.pro | 23 +- retroshare-nogui/src/retroshare.cc | 16 +- 9 files changed, 1970 insertions(+), 4 deletions(-) create mode 100644 retroshare-nogui/src/menu/menu.cc create mode 100644 retroshare-nogui/src/menu/menu.h create mode 100644 retroshare-nogui/src/menu/menus.cc create mode 100644 retroshare-nogui/src/menu/menus.h create mode 100644 retroshare-nogui/src/menu/menutest.h diff --git a/retroshare-nogui/src/menu/menu.cc b/retroshare-nogui/src/menu/menu.cc new file mode 100644 index 000000000..604f127be --- /dev/null +++ b/retroshare-nogui/src/menu/menu.cc @@ -0,0 +1,766 @@ + +#include "menu/menu.h" +#include +#include +#include + +#include + +/********************************************************** + * Menu Base Interface. + */ + +int tailrec_printparents(Menu *m, std::ostream &out) +{ + Menu *p = m->parent(); + if (p) + { + tailrec_printparents(p, out); + } + out << m->ShortFnDesc() << " => "; + +#if 0 + MenuList *ml = dynamic_cast(m); + MenuOpBasicKey *mbk = dynamic_cast(m); + MenuOpTwoKeys *mtk = dynamic_cast(m); + + if (ml) + { + out << "MenuList@" << (void *) m << " "; + } + else if (mbk) + { + out << "MenuBasicKey@" << (void *) m << " "; + } + else if (mtk) + { + out << "MenuOpTwoKeys@" << (void *) m << " "; + } + else + { + out << "Menu@" << (void *) m << " "; + } +#endif + + return 1; +} + + + +uint32_t MenuInterface::process(char key) +{ + +#ifdef MENU_DEBUG + std::cerr << "MenuInterface::process(" << key << ")"; + std::cerr << std::endl; +#endif // MENU_DEBUG + + /* call process on current menu */ + uint32_t rt = mCurrentMenu->process(key); + bool doRedraw = true; + bool showError = false; + bool showHelp = false; + +#ifdef MENU_DEBUG + std::cerr << "MenuInterface::process() currentMenu says: " << rt; + std::cerr << std::endl; +#endif // MENU_DEBUG + + switch(rt) + { + case MENU_PROCESS_NONE: + case MENU_PROCESS_DONE: + /* no changes - operation performed, or noop */ + break; + + case MENU_PROCESS_NEEDDATA: + /* no redraw, this could be called many times */ + doRedraw = false; + break; + + case MENU_PROCESS_ERROR: + /* Show Error at top of Page */ + showError = true; + break; + + case MENU_PROCESS_HELP: + /* Show Help at top of Page */ + showHelp = true; + break; + + case MENU_PROCESS_MENU: + /* new menu to switch to */ + if (mCurrentMenu->selectedMenu()) + { + std::cerr << "MenuInterface::process() Switching Menus"; + std::cerr << std::endl; + mCurrentMenu = mCurrentMenu->selectedMenu(); + } + else + { + std::cerr << "MenuInterface::process() ERROR"; + std::cerr << " SelectedMenu == NULL"; + std::cerr << std::endl; + } + break; + + case MENU_PROCESS_TOP: + /* switch to Base Menu */ + mCurrentMenu = mBase; + break; + + case MENU_PROCESS_QUIT: + return MENU_PROCESS_QUIT; + break; + } + + /* now we redraw, and wait for next data */ + if (!doRedraw) + { + return MENU_PROCESS_NEEDDATA; + } + + /* HEADER */ + for(int i = 0; i < 20; i++) + { + std::cerr << std::endl; + } + + /* ERROR */ + if (showError) + { + mCurrentMenu->showError(); + } + /* HELP */ + else if (showHelp) + { + mCurrentMenu->showHelp(); + } + + /* MENU PAGE */ + drawHeader(); + mCurrentMenu->drawPage(); + return MENU_PROCESS_NEEDDATA; +} + +uint32_t MenuInterface::drawHeader() +{ + std::cerr << "======================================================="; + std::cerr << std::endl; + std::cerr << "Retroshare Terminal Menu V2.xxxx ======================"; + std::cerr << std::endl; + + unsigned int nTotal = 0; + unsigned int nConnected = 0; + rsPeers->getPeerCount(&nTotal, &nConnected, false); + + uint32_t netState = rsConfig->getNetState(); + std::string natState("Unknown"); + switch(netState) + { + default: + case RSNET_NETSTATE_BAD_UNKNOWN: + natState = "YELLOW:Unknown"; + break; + + case RSNET_NETSTATE_BAD_OFFLINE: + natState = "GRAY:Offline"; + break; + + case RSNET_NETSTATE_BAD_NATSYM: + natState = "RED:Nasty Firewall"; + break; + + case RSNET_NETSTATE_BAD_NODHT_NAT: + natState = "RED:NoDht & Firewalled"; + break; + + case RSNET_NETSTATE_WARNING_RESTART: + natState = "YELLOW:Restarting"; + break; + + case RSNET_NETSTATE_WARNING_NATTED: + natState = "YELLOW:Firewalled"; + break; + + case RSNET_NETSTATE_WARNING_NODHT: + natState = "YELLOW:DHT Disabled"; + break; + + case RSNET_NETSTATE_GOOD: + natState = "GREEN:Good!"; + break; + + case RSNET_NETSTATE_ADV_FORWARD: + natState = "GREEN:Forwarded Port"; + break; + } + + float downKb = 0; + float upKb = 0; + rsicontrol -> ConfigGetDataRates(downKb, upKb); + + std::cerr << "Friends " << nConnected << "/" << nTotal; + std::cerr << " Network: " << natState; + std::cerr << std::endl; + std::cerr << "Down: " << downKb << " (kB/s) "; + std::cerr << " Up: " << upKb << " (kB/s) "; + std::cerr << std::endl; + std::cerr << "Menu State: "; + tailrec_printparents(mCurrentMenu, std::cerr); + std::cerr << std::endl; + + std::cerr << "======================================================="; + std::cerr << std::endl; + + return 1; +} + +/********************************************************** + * Menu (Base) + */ + +Menu::~Menu() +{ + /* cleanup children */ + mParent = NULL; + mSelectedMenu = NULL; + std::map::iterator it; + + for(it = mChildren.begin(); it != mChildren.end(); it++) + { + delete (it->second); + } + + mChildren.clear(); +} + +int Menu::addMenuItem(char key, Menu *child) +{ + std::map::iterator it; + it = mChildren.find(key); + if (it != mChildren.end()) + { + std::cerr << "Menu::addMenuItem() ERROR DUPLICATE MENU ITEM"; + std::cerr << std::endl; + return 0; + } + mChildren[key] = child; + child->setParent(this); + + return 1; +} + + +uint32_t Menu::process(char key) +{ + /* try standard list ones */ + uint32_t rt = std_process(key); + if (rt) + { + return rt; + } + + /* now try children */ + rt = process_children(key); + if (rt) + { + return rt; + } + + return MENU_PROCESS_NONE; +} + +uint32_t Menu::std_process(char key) +{ + switch(key) + { + case MENU_KEY_QUIT: + return MENU_PROCESS_QUIT; + break; + case MENU_KEY_HELP: + return MENU_PROCESS_HELP; + break; + case MENU_KEY_TOP: + return MENU_PROCESS_TOP; + break; + case MENU_KEY_UP: + setSelectedMenu(parent()); + return MENU_PROCESS_MENU; + break; + } + + return MENU_PROCESS_NONE; +} + + +uint32_t Menu::process_children(char key) +{ + std::map::iterator it; + it = mChildren.find(key); + + if (it == mChildren.end()) + { + return MENU_PROCESS_NONE; + } + + /* have a child */ + + /* now return, depending on type */ + switch(it->second->op()) + { + /* Think I can handle these the same! Both will call DrawPage, + * then Process on New Menu + */ + + case MENU_OP_NEEDDATA: + case MENU_OP_SUBMENU: + setSelectedMenu(it->second); + return MENU_PROCESS_MENU; + break; + + default: + case MENU_OP_INSTANT: + /* done already! */ + setSelectedMenu(NULL); + return MENU_PROCESS_DONE; + break; + + case MENU_OP_ERROR: + /* done already! */ + setSelectedMenu(NULL); + return MENU_PROCESS_ERROR; + break; + } +} + + +uint32_t Menu::drawPage() +{ + std::cerr << "Universal Commands ( "; + std::cerr << (char) MENU_KEY_QUIT << ":Quit "; + std::cerr << (char) MENU_KEY_HELP << ":Help "; + std::cerr << (char) MENU_KEY_TOP << ":Top "; + std::cerr << (char) MENU_KEY_UP << ":Up "; + std::cerr << ")"; + std::cerr << std::endl; + + std::cerr << "Specific Commands ("; + std::map::iterator it; + for(it = mChildren.begin(); it != mChildren.end(); it++) + { + std::cerr << (char) it->first << ":"; + std::cerr << it->second->ShortFnDesc() << " "; + } + std::cerr << ")"; + std::cerr << std::endl; + + return 1; +} + + +uint32_t Menu::drawHelpPage() +{ + std::cerr << "Menu Help: Universal Commands are:"; + std::cerr << std::endl; + std::cerr << "\tKey: " << (char) MENU_KEY_QUIT << " => Quit"; + std::cerr << std::endl; + std::cerr << "\tKey: " << (char) MENU_KEY_HELP << " => Help"; + std::cerr << std::endl; + std::cerr << "\tKey: " << (char) MENU_KEY_TOP << " => Top Menu"; + std::cerr << std::endl; + std::cerr << "\tKey: " << (char) MENU_KEY_UP << " => Up a Menu"; + std::cerr << std::endl; + + std::cerr << "Specific Commands are:"; + std::cerr << std::endl; + std::map::iterator it; + for(it = mChildren.begin(); it != mChildren.end(); it++) + { + std::cerr << "\tKey: " << (char) it->first << " => "; + std::cerr << it->second->ShortFnDesc(); + std::cerr << std::endl; + } + + return 1; +} + + +/********************************************************** + * Menu List (Base) + */ + + +uint32_t MenuList::drawPage() +{ + Menu::drawPage(); + + std::cerr << "Navigation Commands ("; + //std::cerr << (char) MENULIST_KEY_LIST << ":List "; + std::cerr << (char) MENULIST_KEY_NEXT << ":Next "; + std::cerr << (char) MENULIST_KEY_PREV << ":Prev "; + std::cerr << ")"; + std::cerr << std::endl; + + std::cerr << "MenuList::Internals "; + std::cerr << "ListSize: " << getListCount(); + std::cerr << " SelectIdx: " << mSelectIdx; + std::cerr << " Cursor: " << mCursor; + std::cerr << std::endl; + + int i = 0; + + int listCount = getListCount(); + int startCount = mCursor + 1; + int endCount = mCursor + 10; + if (endCount > listCount) + { + endCount = listCount; + } + + if (mSelectIdx >= 0) + { + std::cerr << "Current Selection Idx: " << mSelectIdx << " : "; + std::string desc; + if (getEntryDesc(mSelectIdx, desc) & (desc != "")) + { + std::cerr << desc; + } + else + { + std::cerr << "Missing Description"; + } + std::cerr << std::endl; + } + else + { + std::cerr << "No Current Selection: Use 0 - 9 to choose an Entry"; + std::cerr << std::endl; + } + + + std::cerr << "Showing " << startCount; + std::cerr << " to " << endCount << " of " << listCount << " Entries"; + std::cerr << std::endl; + + std::list::iterator it; + for (it = mList.begin(); it != mList.end(); it++, i++) + { + int curIdx = i - mCursor; + if ((curIdx >= 0) && (curIdx < 10)) + { + if (i == mSelectIdx) + { + std::cerr << "SELECTED => (" << curIdx << ") "; + } + else + { + std::cerr << "\t(" << curIdx << ") "; + } + std::string desc; + if (getEntryDesc(i, desc) & (desc != "")) + { + std::cerr << desc; + } + else + { + std::cerr << *it << " => "; + std::cerr << "Missing Description"; + } + std::cerr << std::endl; + } + } + + return 1; +} + +uint32_t MenuList::drawHelpPage() +{ + Menu::drawPage(); + + std::cerr << "MenuList Help: Navigation Commands are:"; + std::cerr << std::endl; + //std::cerr << "\tKey: " << (char) MENULIST_KEY_LIST << " => List"; + //std::cerr << std::endl; + std::cerr << "\tKey: " << (char) MENULIST_KEY_NEXT << " => Next Page"; + std::cerr << std::endl; + std::cerr << "\tKey: " << (char) MENULIST_KEY_PREV << " => Prev Page"; + std::cerr << std::endl; + + std::cerr << "MenuList::drawPage() Internal Details"; + std::cerr << std::endl; + std::cerr << "List Size: " << getListCount(); + std::cerr << std::endl; + std::cerr << "SelectIdx: " << mSelectIdx; + std::cerr << std::endl; + std::cerr << "Cursor: " << mCursor; + std::cerr << std::endl; + return 1; +} + + +uint32_t MenuList::op() +{ + /* load friend list*/ + mList.clear(); + //rsPeers->getGpgAcceptedList(mList); + mSelectIdx = -1; + mCursor = 0; + + return MENU_OP_ERROR; // SUBMENU -> only for inherited classes; +} + +uint32_t MenuList::getListCount() +{ + return mList.size(); +} + +int MenuList::getCurrentKey(std::string &key) +{ + return getListEntry(mSelectIdx, key); +} + +int MenuList::getCurrentIdx(int &idx) +{ + idx = mSelectIdx; + return 1; +} + +int MenuList::getListEntry(int idx, std::string &key) +{ + if (idx < 0) + { + return MENU_ENTRY_NONE; + } + + std::list::iterator it; + int i = 0; + for (it = mList.begin(); (i < idx) && (it != mList.end()); it++, i++) ; + + if (it != mList.end()) + { + key = *it; + return MENU_ENTRY_OKAY; + } + return MENU_ENTRY_NONE; +} + +int MenuList::getEntryDesc(int idx, std::string &desc) +{ + desc = "Entry Description"; + return MENU_ENTRY_OKAY; +} + +uint32_t MenuList::process(char key) +{ + /* try standard list ones */ + uint32_t rt = Menu::process(key); + if (rt) + { + return rt; + } + + rt = list_process(key); + return rt; +} + +uint32_t MenuList::list_process(char key) +{ + if (((key >= '0') && (key <= '9')) || + ((key >= 'a') && (key <= 'f'))) + { + int idx = 0; + /* select index */ + if ((key >= '0') && (key <= '9')) + { + idx = key - '0'; + } + else + { + idx = key - 'a' + 9; + } + + /* now change selection, dependent on pagination */ + if (mCursor + idx < getListCount()) + { + mSelectIdx = mCursor + idx; + std::cerr << "MenuList::list_process() Selected Idx: " << mSelectIdx; + std::cerr << std::endl; + } + else + { + std::cerr << "MenuList::list_process() Idx Out of Range"; + std::cerr << std::endl; + } + + return MENU_PROCESS_DONE; /* ready for next key stroke */ + } + + + switch(key) + { + case MENULIST_KEY_LIST: + /* send a list to output */ + + return MENU_PROCESS_DONE; /* ready for next key stroke */ + break; + case MENULIST_KEY_NEXT: + /* shift to next page */ + if (mCursor + 10 < getListCount()) + { + mCursor += 10; + } + + return MENU_PROCESS_DONE; + break; + case MENULIST_KEY_PREV: + /* shift to prev page */ + if (((int) mCursor) - 10 >= 0) + { + mCursor -= 10; + } + + return MENU_PROCESS_DONE; + break; + } + + return MENU_PROCESS_NONE; +} + + +uint32_t MenuOpBasicKey::op_basic(std::string key) +{ + parent()->setErrorMessage("MenuOpBasicKey Not Overloaded Correctly"); + return MENU_OP_ERROR; +} + + +uint32_t MenuOpBasicKey::op() +{ + std::string key; + Menu *Parent=parent(); + MenuList *p = dynamic_cast(Parent); + + if (!p) + { + if (Parent) + { + Parent->setErrorMessage("Invalid (Basic) Menu Structure"); + } + return MENU_OP_ERROR; + } + + if (p->getCurrentKey(key)) + { + return op_basic(key); + } + + if (Parent) + { + Parent->setErrorMessage("Invalid Current Keys"); + } + return MENU_OP_ERROR; +} + + + +uint32_t MenuOpTwoKeys::op_twokeys(std::string parentkey, std::string key) +{ + parent()->setErrorMessage("MenuOpTwoKeys Not Overloaded Correctly"); + return MENU_OP_ERROR; +} + + +uint32_t MenuOpTwoKeys::op() +{ + std::string parentkey; + std::string key; + Menu *Parent=parent(); + MenuList *p = dynamic_cast(Parent); + + Menu *grandParent=parent()->parent(); + MenuList *gp = dynamic_cast(grandParent); + + if ((!gp) || (!p)) + { + if (Parent) + { + Parent->setErrorMessage("Invalid (TwoKeys) Menu Structure"); + } + return MENU_OP_ERROR; + } + + if ((gp->getCurrentKey(parentkey)) && (p->getCurrentKey(key))) + { + return op_twokeys(parentkey, key); + } + + if (Parent) + { + Parent->setErrorMessage("Invalid Current Keys"); + } + return MENU_OP_ERROR; +} + + + +/********************************************************** + * Menu Op Line Input (Base) + */ + + +uint32_t MenuOpLineInput::op() +{ + return MENU_OP_NEEDDATA; +} + + +uint32_t MenuOpLineInput::process_lines(std::string input) +{ + std::cerr << "MenuOpLineInput::process_lines() => SHOULD BE OVERLOADED"; + std::cerr << "Input Was: "; + std::cerr << std::endl; + std::cerr << "=================================================="; + std::cerr << std::endl; + std::cerr << input; + std::cerr << "=================================================="; + std::cerr << std::endl; + + return MENU_PROCESS_ERROR; +} + + +uint32_t MenuOpLineInput::process(char key) +{ + /* read data in and add to buffer */ + mInput += key; + if (key != '\n') + { + return MENU_PROCESS_NEEDDATA; + } + + uint32_t rt = process_lines(mInput); + + switch(rt) + { + case MENU_PROCESS_NEEDDATA: + break; + case MENU_PROCESS_ERROR: + std::cerr << "MenuOpLineInput::process() => ERROR"; + std::cerr << std::endl; + case MENU_PROCESS_DONE: + /* cleanup for next command */ + std::cerr << "MenuOpLineInput::process() Clearing Buffer"; + std::cerr << std::endl; + mInput.clear(); + + /* go back to parent menu */ + rt = MENU_PROCESS_MENU; + setSelectedMenu(parent()); + break; + } + + return rt; +} + + diff --git a/retroshare-nogui/src/menu/menu.h b/retroshare-nogui/src/menu/menu.h new file mode 100644 index 000000000..23e3c015d --- /dev/null +++ b/retroshare-nogui/src/menu/menu.h @@ -0,0 +1,178 @@ +#ifndef RSNOGUI_MENU_H +#define RSNOGUI_MENU_H + +#include + +#include +#include +#include + +#define MENU_PROCESS_NONE 0 +#define MENU_PROCESS_TOP 1 +#define MENU_PROCESS_MENU 2 +#define MENU_PROCESS_NEEDDATA 3 +#define MENU_PROCESS_DONE 4 +#define MENU_PROCESS_QUIT 5 +#define MENU_PROCESS_SHUTDOWN 6 +#define MENU_PROCESS_HELP 7 +#define MENU_PROCESS_ERROR 8 + +#define MENU_KEY_QUIT 'Q' +#define MENU_KEY_HELP 'H' +#define MENU_KEY_TOP 'T' +#define MENU_KEY_REPEAT 'R' +#define MENU_KEY_UP 'U' + +#define MENULIST_KEY_LIST 'L' // Don't need this. +#define MENULIST_KEY_NEXT 'N' +#define MENULIST_KEY_PREV 'P' + +#define MENU_OP_ERROR 0 +#define MENU_OP_INSTANT 1 +#define MENU_OP_SUBMENU 2 +#define MENU_OP_NEEDDATA 3 + +#define MENU_ENTRY_NONE 0 +#define MENU_ENTRY_OKAY 1 + +class Menu; +class Screen; + +class Menu +{ +public: + Menu(std::string shortDesc): mParent(NULL), mShortDesc(shortDesc) { return; } +virtual ~Menu(); + + void setParent(Menu *p) { mParent = p; } + Menu *parent() { return mParent; } + Menu *selectedMenu() { return mSelectedMenu; } + int addMenuItem(char key, Menu *child); + +virtual uint32_t op() { return MENU_OP_SUBMENU; } /* what type is it? returns SUBMENU, INSTANT, NEEDINPUT */ +virtual uint32_t process(char key); + + // THE BIT STILL TO BE DEFINED! + +std::string ShortFnDesc() { return mShortDesc; }// Menu Text (for Help). + +//virtual std::string menuText() = 0; +//virtual std::string menuHelp() = 0; +virtual void setOpMessage(std::string msg) { return; } +virtual void setErrorMessage(std::string msg) { return; } +virtual uint32_t drawPage(); // { return 1; } //= 0; +virtual uint32_t drawHelpPage(); // { return 1; } //= 0; +virtual uint32_t showError() { return 1; } //= 0; +virtual uint32_t showHelp() { return 1; } //= 0; + +protected: +virtual uint32_t std_process(char key); /* for H/T/R/Q */ +virtual uint32_t process_children(char key); /* check for children ops */ + + void setSelectedMenu(Menu *m) { mSelectedMenu = m; } + +private: + Menu *mParent; + Menu *mSelectedMenu; + std::string mShortDesc; + std::map mChildren; +}; + + +/********************************************************** + * Generic MenuList... provides a list of KEYS, which + * can be iterated through. + * + * Maintains: List + Current + Next / Previous. + * Single Child, which is called for all. + */ + +class MenuList: public Menu +{ +public: + MenuList(std::string shortDesc): Menu(shortDesc) { return; } + +virtual uint32_t op(); +virtual uint32_t process(char key); + + // List Info. + uint32_t getListCount(); + int getCurrentIdx(int &idx); + int getCurrentKey(std::string &key); + int getListEntry(int idx, std::string &key); +virtual int getEntryDesc(int idx, std::string &desc); + + // Output. +virtual uint32_t drawPage(); +virtual uint32_t drawHelpPage(); + +protected: + virtual uint32_t list_process(char key); + + int32_t mSelectIdx; /* -1 => none */ + uint32_t mCursor; /* offset for list display */ + std::list mList; + +private: +}; + + + +class MenuOpBasicKey: public Menu +{ +public: + MenuOpBasicKey(std::string shortDesc): Menu(shortDesc) { return; } + virtual uint32_t op(); + +protected: + virtual uint32_t op_basic(std::string key); +}; + + + +class MenuOpTwoKeys: public Menu +{ + +public: + MenuOpTwoKeys(std::string shortDesc): Menu(shortDesc) { return; } + virtual uint32_t op(); + +protected: + virtual uint32_t op_twokeys(std::string parentkey, std::string key); + +}; + +/* Read input, line by line... + */ + +class MenuOpLineInput: public Menu +{ + +public: + MenuOpLineInput(std::string shortDesc): Menu(shortDesc) { return; } + virtual uint32_t op(); + virtual uint32_t process(char key); + +protected: + virtual uint32_t process_lines(std::string input); + + std::string mInput; +}; + + + +class MenuInterface +{ +public: + + MenuInterface(Menu *b) :mCurrentMenu(b), mBase(b) { return; } + uint32_t process(char key); + uint32_t drawHeader(); + +private: + Menu *mCurrentMenu; + Menu *mBase; +}; + + +#endif diff --git a/retroshare-nogui/src/menu/menus.cc b/retroshare-nogui/src/menu/menus.cc new file mode 100644 index 000000000..c15d2eb3b --- /dev/null +++ b/retroshare-nogui/src/menu/menus.cc @@ -0,0 +1,578 @@ + +#include +#include +#include +#include "util/rsstring.h" + +#include "menu/menus.h" + +// Can't use: Q, H, T, U (universal) +// or L, N, P (list ops). +// or 0-9,a-f (list selection). + +#define MENU_FRIENDS_KEY_ADD 'A' +#define MENU_FRIENDS_KEY_VIEW 'V' +#define MENU_FRIENDS_KEY_REMOVE 'D' +#define MENU_FRIENDS_KEY_CHAT 'C' + +#define MENU_TRANSFER_KEY_STOP 'S' +#define MENU_TRANSFER_KEY_CANCEL 'C' + +#define MENU_SEARCH_KEY_ADD 'A' +#define MENU_SEARCH_KEY_REMOVE 'D' +#define MENU_SEARCH_KEY_VIEW 'V' +#define MENU_SEARCH_KEY_DOWNLOAD 'G' + +#define MENU_FRIENDS_KEY_ADD 'A' +#define MENU_FRIENDS_KEY_VIEW 'V' +#define MENU_FRIENDS_KEY_REMOVE 'D' +#define MENU_FRIENDS_KEY_CHAT 'C' + + +#define MENU_TOPLEVEL_KEY_FRIENDS 'F' +#define MENU_TOPLEVEL_KEY_NETWORK 'W' +#define MENU_TOPLEVEL_KEY_TRANSFER 'D' +#define MENU_TOPLEVEL_KEY_SEARCH 'S' +#define MENU_TOPLEVEL_KEY_FORUMS 'O' + + +Menu *CreateMenuStructure(NotifyTxt *notify) +{ + /* construct Friends Menu */ + MenuList *friends = new MenuListFriends(); + // No Friends Operations Completed Yet! + //friends->addMenuItem(MENU_FRIENDS_KEY_ADD, new MenuOpFriendsAdd()); + //friends->addMenuItem(MENU_FRIENDS_KEY_VIEW, new MenuOpFriendsViewDetail()); + //friends->addMenuItem(MENU_FRIENDS_KEY_REMOVE, new MenuOpFriendsRemove()); + //friends->addMenuItem(MENU_FRIENDS_KEY_CHAT, new MenuOpFriendsChat()); + + MenuList *network = new MenuListNetwork(); + + MenuList *transfers = new MenuListTransfer(); + //transfers->addMenuItem(MENU_TRANSFER_KEY_STOP, new MenuOpTransferStop()); + transfers->addMenuItem(MENU_TRANSFER_KEY_CANCEL, new MenuOpTransferCancel()); + + MenuList *search = new MenuListSearch(notify); + MenuList *searchlist = new MenuListSearchList(notify); + search->addMenuItem(MENU_SEARCH_KEY_ADD, new MenuOpSearchNew()); + //search->addMenuItem(MENU_SEARCH_KEY_REMOVE, new MenuOpSearchDelete()); + search->addMenuItem(MENU_SEARCH_KEY_VIEW, searchlist); + searchlist->addMenuItem(MENU_SEARCH_KEY_DOWNLOAD, new MenuOpSearchListDownload()); + + // Forums - TODO. + //MenuList *forums = new MenuListForums(); + //forums->addMenuItem(MENU_FRIENDS_KEY_ADD, new MenuOpFriendsAdd()); + //forums->addMenuItem(MENU_FRIENDS_KEY_VIEW, new MenuOpFriendsViewDetail()); + //forums->addMenuItem(MENU_FRIENDS_KEY_REMOVE, new MenuOpFriendsRemove()); + //forums->addMenuItem(MENU_FRIENDS_KEY_CHAT, new MenuOpFriendsChat()); + + + /* Top Level Menu */ + Menu *tlm = new Menu("Top Level Menu"); + + tlm->addMenuItem(MENU_TOPLEVEL_KEY_FRIENDS, friends); + tlm->addMenuItem(MENU_TOPLEVEL_KEY_NETWORK, network); + tlm->addMenuItem(MENU_TOPLEVEL_KEY_TRANSFER, transfers); + tlm->addMenuItem(MENU_TOPLEVEL_KEY_SEARCH, search); + //tlm->addMenuItem(MENU_TOPLEVEL_KEY_FORUMS, forums); + + return tlm; +} + + +/************ + * Friends Menu + */ + + +uint32_t MenuListFriends::op() +{ + MenuList::op(); + + rsPeers->getGPGAcceptedList(mList); + //rsPeers->getGPGValidList(mList); + + return MENU_OP_SUBMENU; +} + +int MenuListFriends::getEntryDesc(int idx, std::string &desc) +{ + std::string gpgId; + + if (!getListEntry(idx, gpgId)) + { + /* error */ + return 0; + } + + RsPeerDetails details; + if (rsPeers->getPeerDetails(gpgId, details)) + { + if (details.accept_connection) + { + desc = "Friend: "; + } + else + { + desc = "Neighbour: "; + } + + desc += "<" + gpgId + "> "; + desc += details.name; + } + return 1; +} + + +uint32_t MenuListNetwork::op() +{ + MenuList::op(); + + rsPeers->getGPGValidList(mList); + //rsPeers->getGPGAcceptedList(mList); + + return MENU_OP_SUBMENU; +} + + +uint32_t MenuOpFriendsAdd::op_basic(std::string key) +{ + + + return MENU_OP_INSTANT; +} + +uint32_t MenuOpFriendsViewDetail::op_basic(std::string key) +{ + + + return MENU_OP_INSTANT; +} + + +uint32_t MenuOpFriendsRemove::op_basic(std::string key) +{ + + + return MENU_OP_INSTANT; +} + + +uint32_t MenuOpFriendsChat::op_basic(std::string key) +{ + + + return MENU_OP_INSTANT; +} + + +/************ + * Transfer Menu + */ + + +uint32_t MenuListTransfer::op() +{ + MenuList::op(); + + /* load friend list*/ + rsFiles->FileDownloads(mList); + + return MENU_OP_SUBMENU; +} + +int MenuListTransfer::getEntryDesc(int idx, std::string &desc) +{ + std::string hash; + if (!getListEntry(idx, hash)) + { + std::cerr << "MenuListTransfer::getEntryDesc() No ListEntry"; + std::cerr << std::endl; + return 0; + } + + FileInfo info; + if (!rsFiles->FileDetails(hash, RS_FILE_HINTS_DOWNLOAD, info)) + { + std::cerr << "MenuListTransfer::getEntryDesc() No FileDetails"; + std::cerr << std::endl; + return 0; + } + + float frac = (float) info.transfered / info.size; + + if (frac != 1.0) + { + if (info.tfRate > 0) + { + rs_sprintf(desc, "<%s> Downloading %3.2f%% from %d Peers @%3.1fKB/s. Name: %s", + info.hash.c_str(), frac, info.peers.size(), info.tfRate, info.fname.c_str()); + } + else + { + rs_sprintf(desc, "<%s> Stalled %3.2f%% Name: %s", + info.hash.c_str(), frac, info.fname.c_str()); + } + } + else + { + rs_sprintf(desc, "<%s> Done! Name: %s", info.hash.c_str(), info.fname.c_str()); + } + return MENU_OP_INSTANT; +} + +uint32_t MenuOpTransferStop::op_basic(std::string key) +{ + rsFiles->FileCancel(key); + parent()->setOpMessage("Stopped Transfer"); + return MENU_OP_INSTANT; +} + +uint32_t MenuOpTransferCancel::op_basic(std::string key) +{ + rsFiles->FileCancel(key); + parent()->setOpMessage("Stopped Transfer"); + return MENU_OP_INSTANT; +} + + +/************ + * Search Menu + */ + + + +uint32_t MenuListSearch::op() +{ + mSelectIdx = -1; + mCursor = 0; + + /* Don't reset List -> done dynamically */ + + return MENU_OP_SUBMENU; +} + +int MenuListSearch::getEntryDesc(int idx, std::string &desc) +{ + std::string strSearchId; + + if (!getListEntry(idx, strSearchId)) + { + /* error */ + return 0; + } + + std::map::iterator it; + std::map::iterator sit; + it = mSearchTerms.find(strSearchId); + sit = mSearchIds.find(strSearchId); + if ((it == mSearchTerms.end()) || (sit == mSearchIds.end())) + { + /* error */ + return 0; + } + + rs_sprintf(desc, "Search(\"%s\") Found %d matches so far", + it->second.c_str(), mNotify->getSearchResultCount(sit->second)); + return 1; +} + + +int MenuListSearch::getCurrentSearchId(uint32_t &id) +{ + std::string strSearchId; + + if (!getListEntry(mSelectIdx, strSearchId)) + { + /* error */ + return 0; + } + + std::map::iterator sit; + sit = mSearchIds.find(strSearchId); + if (sit == mSearchIds.end()) + { + /* error */ + return 0; + } + + id = sit->second; + return 1; +} + +int MenuListSearch::storeSearch(uint32_t searchId, std::string match_string) +{ + std::cerr << "MenuListSearch::storeSearch(" << searchId << " => "; + std::cerr << match_string; + std::cerr << std::endl; + + std::string strSearchId; + rs_sprintf(strSearchId, "%lu", searchId); + mList.push_back(strSearchId); + + mSearchTerms[strSearchId] = match_string; + mSearchIds[strSearchId] = searchId; + + return 1; +} + +int MenuListSearch::removeSearch(std::string strSearchId) +{ + std::cerr << "MenuListSearch::removeSearch(" << strSearchId << ")"; + std::cerr << std::endl; + + std::map::iterator it; + it = mSearchIds.find(strSearchId); + if (it != mSearchIds.end()) + { + /* cleanup local maps */ + + /* cancel search */ + + /* clear results from Notify Collector */ + } + + return 1; +} + + +uint32_t MenuOpSearchNew::process_lines(std::string input) +{ + /* launch search */ + if (input.size() < 4) + { + std::cerr << "MenuOpSearchNew::process_lines() ERROR Input too small"; + std::cerr << std::endl; + return MENU_PROCESS_ERROR; + } + + std::string search = input.substr(0, input.size() - 1); // remove \n. + uint32_t searchId = (uint32_t) rsTurtle->turtleSearch(search); + + /* store request in parent */ + MenuListSearch *ms = dynamic_cast(parent()); + if (ms) + { + ms->storeSearch(searchId, search); + } + + return MENU_PROCESS_DONE; +} + +uint32_t MenuOpSearchDelete::op_basic(std::string key) +{ + + return MENU_OP_INSTANT; +} + + +uint32_t MenuListSearchList::op() +{ + MenuList::op(); + return refresh(); +} + +uint32_t MenuListSearchList::refresh() +{ + Menu* p = parent(); + MenuListSearch *mls = dynamic_cast(p); + if (!mls) + { + std::cerr << "MenuListSearchList::refresh() mls not there"; + std::cerr << std::endl; + return MENU_OP_ERROR; + } + + /* load friend list*/ + mList.clear(); + + uint32_t searchId; + if (!mls->getCurrentSearchId(searchId)) + { + std::cerr << "MenuListSearchList::refresh() currentIdx invalid"; + std::cerr << std::endl; + return MENU_OP_ERROR; + } + + std::cerr << "MenuListSearchList::refresh() searchId: " << searchId; + std::cerr << std::endl; + + std::list::iterator it; + mNotify->getSearchResults(searchId, mSearchResults); + + /* convert into useful list */ + for(it = mSearchResults.begin(); it != mSearchResults.end(); it++) + { + mList.push_back(it->hash); + } + + mSelectIdx = -1; + mCursor = 0; + return MENU_OP_SUBMENU; +} + +int MenuListSearchList::getEntryDesc(int idx, std::string &desc) +{ + std::list::iterator it; + int i = 0; + for (it = mSearchResults.begin(); + (i < idx) && (it != mSearchResults.end()); it++, i++) ; + + if (it != mSearchResults.end()) + { + rs_sprintf(desc, "<%s> Size: %llu Name:%s", + it->hash.c_str(), it->size, it->name.c_str()); + return MENU_ENTRY_OKAY; + } + return MENU_ENTRY_NONE; +} + + +int MenuListSearchList::downloadSelected() +{ + if (mSelectIdx < 0) + { + std::cerr << "MenuListSearchList::downloadSelected() Invalid Selection"; + std::cerr << std::endl; + return MENU_ENTRY_NONE; + } + + std::list::iterator it; + int i = 0; + for (it = mSearchResults.begin(); + (i < mSelectIdx) && (it != mSearchResults.end()); it++, i++) ; + + if (it != mSearchResults.end()) + { + std::list srcIds; + if (rsFiles -> FileRequest(it->name, it->hash, it->size, + "", RS_FILE_HINTS_NETWORK_WIDE, srcIds)) + { + std::cerr << "MenuListSearchList::downloadSelected() Download Started"; + std::cerr << std::endl; + } + else + { + std::cerr << "MenuListSearchList::downloadSelected() Error Starting Download"; + std::cerr << std::endl; + } + return MENU_ENTRY_OKAY; + } + return MENU_ENTRY_NONE; +} + + + +uint32_t MenuOpSearchListDownload::op_basic(std::string key) +{ + Menu* p = parent(); + MenuListSearchList *mlsl = dynamic_cast(p); + if (!mlsl) + { + std::cerr << "MenuOpSearchListDownload::op_basic() ERROR"; + std::cerr << std::endl; + return MENU_OP_ERROR; + } + + mlsl->downloadSelected(); + + return MENU_OP_INSTANT; +} + +/************ + * Forums Menu + */ + + + +uint32_t MenuListForums::op() +{ + /* load friend list*/ + mList.clear(); + rsPeers->getGPGAcceptedList(mList); + mSelectIdx = 0; + + return MENU_OP_SUBMENU; +} + + +int MenuListForums::getEntryDesc(int idx, std::string &desc) +{ + + + return MENU_OP_INSTANT; +} + +uint32_t MenuOpForumDetails::op_basic(std::string key) +{ + + + return MENU_OP_INSTANT; +} + + +uint32_t MenuOpForumSubscribe::op_basic(std::string key) +{ + + + return MENU_OP_INSTANT; +} + + +uint32_t MenuOpForumUnsubscribe::op_basic(std::string key) +{ + + + return MENU_OP_INSTANT; +} + + +uint32_t MenuOpForumCreate::op_basic(std::string key) +{ + + + return MENU_OP_INSTANT; +} + + +uint32_t MenuListForumMsgs::op() +{ + /* load friend list*/ + mList.clear(); + rsPeers->getGPGAcceptedList(mList); + mSelectIdx = 0; + + return MENU_OP_SUBMENU; +} + +int MenuListForumMsgs::getEntryDesc(int idx, std::string &desc) +{ + + + return MENU_OP_INSTANT; +} + +uint32_t MenuOpForumMsgView::op_twokeys(std::string parentkey, std::string key) +{ + + + return MENU_OP_INSTANT; +} + +uint32_t MenuOpForumMsgReply::op_twokeys(std::string parentkey, std::string key) +{ + + + return MENU_OP_INSTANT; +} + + +uint32_t MenuOpForumMsgWrite::op_twokeys(std::string parentkey, std::string key) +{ + + + return MENU_OP_INSTANT; +} + + + diff --git a/retroshare-nogui/src/menu/menus.h b/retroshare-nogui/src/menu/menus.h new file mode 100644 index 000000000..61a26639e --- /dev/null +++ b/retroshare-nogui/src/menu/menus.h @@ -0,0 +1,269 @@ + +#include "menu/menu.h" +#include +#include "notifytxt.h" /* needed to access search results */ +#include + +Menu *CreateMenuStructure(NotifyTxt *notify); + +/************ + * Friends Menu + */ + +class MenuListFriends: public MenuList +{ + +public: + MenuListFriends() :MenuList("Friends") { return; } + + virtual uint32_t op(); + int getEntryDesc(int idx, std::string &desc); + +protected: + MenuListFriends(std::string name) :MenuList(name) { return; } // For Network. +}; + + +class MenuListNetwork: public MenuListFriends +{ + +public: + MenuListNetwork() :MenuListFriends("Network") { return; } + + virtual uint32_t op(); +}; + + +class MenuOpFriendsAdd: public MenuOpBasicKey +{ + public: + + MenuOpFriendsAdd() :MenuOpBasicKey("Add") { return; } + virtual uint32_t op_basic(std::string hash); +}; + + +class MenuOpFriendsViewDetail: public MenuOpBasicKey +{ + public: + + MenuOpFriendsViewDetail() :MenuOpBasicKey("View") { return; } + virtual uint32_t op_basic(std::string hash); +}; + + +class MenuOpFriendsRemove: public MenuOpBasicKey +{ + public: + + MenuOpFriendsRemove() :MenuOpBasicKey("Remove") { return; } + virtual uint32_t op_basic(std::string hash); +}; + + +class MenuOpFriendsChat: public MenuOpBasicKey +{ + public: + + MenuOpFriendsChat() :MenuOpBasicKey("Chat") { return; } + virtual uint32_t op_basic(std::string hash); +}; + + + +/************ + * Transfer Menu + */ + + +class MenuListTransfer: public MenuList +{ + public: + + MenuListTransfer() :MenuList("Downloads") { return; } + virtual uint32_t op(); + int getEntryDesc(int idx, std::string &desc); +}; + + +class MenuOpTransferStop: public MenuOpBasicKey +{ + public: + + MenuOpTransferStop() :MenuOpBasicKey("Stop") { return; } + virtual uint32_t op_basic(std::string hash); +}; + + + +class MenuOpTransferCancel: public MenuOpBasicKey +{ + public: + + MenuOpTransferCancel() :MenuOpBasicKey("Cancel") { return; } + virtual uint32_t op_basic(std::string hash); +}; + + + +/************ + * Search Menu + */ + + +class MenuListSearch: public MenuList +{ + public: + + MenuListSearch(NotifyTxt *notify) + :MenuList("Search"), mNotify(notify) { return; } + + virtual uint32_t op(); + int getEntryDesc(int idx, std::string &desc); + + /* specific Search Functions */ + int getCurrentSearchId(uint32_t &id); + int storeSearch(uint32_t searchId, std::string match_string); + int removeSearch(std::string strSearchId); + +private: + std::map mSearchIds; + std::map mSearchTerms; + NotifyTxt *mNotify; +}; + + +class MenuOpSearchNew: public MenuOpLineInput +{ + public: + + MenuOpSearchNew() :MenuOpLineInput("New") { return; } + virtual uint32_t process_lines(std::string input); +}; + + +class MenuOpSearchDelete: public MenuOpBasicKey +{ + public: + + MenuOpSearchDelete() :MenuOpBasicKey("Delete") { return; } + virtual uint32_t op_basic(std::string hash); +}; + + +class MenuListSearchList: public MenuList +{ + public: + + MenuListSearchList(NotifyTxt *notify) + :MenuList("Results"), mNotify(notify) { return; } + virtual uint32_t op(); + uint32_t refresh(); + int getEntryDesc(int idx, std::string &desc); + int downloadSelected(); + + private: + NotifyTxt *mNotify; + std::list mSearchResults; // local cache for consistency. +}; + + +class MenuOpSearchListDownload: public MenuOpBasicKey +{ + public: + + MenuOpSearchListDownload() :MenuOpBasicKey("Download") { return; } + virtual uint32_t op_basic(std::string hash); +}; + + + +/************ + * Forums Menu + */ + + + +class MenuListForums: public MenuList +{ + public: + + MenuListForums() :MenuList("Forums SubMenu") { return; } + virtual uint32_t op(); + int getEntryDesc(int idx, std::string &desc); +}; + + +class MenuOpForumDetails: public MenuOpBasicKey +{ + public: + + MenuOpForumDetails() :MenuOpBasicKey("Show Forum Details") { return; } + virtual uint32_t op_basic(std::string hash); +}; + + +class MenuOpForumSubscribe: public MenuOpBasicKey +{ + public: + + MenuOpForumSubscribe() :MenuOpBasicKey("Subscribe To Forum") { return; } + virtual uint32_t op_basic(std::string hash); +}; + + +class MenuOpForumUnsubscribe: public MenuOpBasicKey +{ + public: + + MenuOpForumUnsubscribe() :MenuOpBasicKey("Unsubscribe To Forum") { return; } + virtual uint32_t op_basic(std::string hash); +}; + + +class MenuOpForumCreate: public MenuOpBasicKey +{ + public: + + MenuOpForumCreate() :MenuOpBasicKey("Create Forum") { return; } + virtual uint32_t op_basic(std::string hash); +}; + + + +class MenuListForumMsgs: public MenuList +{ + public: + + MenuListForumMsgs() :MenuList("List Forum Msgs") { return; } + virtual uint32_t op(); + int getEntryDesc(int idx, std::string &desc); +}; + +class MenuOpForumMsgView: public MenuOpTwoKeys +{ + public: + + MenuOpForumMsgView() :MenuOpTwoKeys("View Message") { return; } + virtual uint32_t op_twokeys(std::string parentkey, std::string key); +}; + + +class MenuOpForumMsgReply: public MenuOpTwoKeys +{ + public: + + MenuOpForumMsgReply() :MenuOpTwoKeys("Reply to Message") { return; } + virtual uint32_t op_twokeys(std::string parentkey, std::string key); +}; + + +class MenuOpForumMsgWrite: public MenuOpTwoKeys +{ + public: + + MenuOpForumMsgWrite() :MenuOpTwoKeys("Write Message") { return; } + virtual uint32_t op_twokeys(std::string parentkey, std::string key); +}; + + diff --git a/retroshare-nogui/src/menu/menutest.h b/retroshare-nogui/src/menu/menutest.h new file mode 100644 index 000000000..8ff9ef732 --- /dev/null +++ b/retroshare-nogui/src/menu/menutest.h @@ -0,0 +1,32 @@ + +#include +#include "menu/menu.h" + +class MenuTest +{ +public: + MenuTest(MenuInterface *i, std::istream &in, std::ostream &out) + :mMenus(i), mIn(in), mOut(out) + { + return; + } + +int tick() + { + int c = mIn.get(); + uint8_t key = (uint8_t) c; + mMenus->process(key); + + return 1; + } + +private: + + + MenuInterface *mMenus; + std::istream &mIn; + std::ostream &mOut; +}; + + + diff --git a/retroshare-nogui/src/notifytxt.cc b/retroshare-nogui/src/notifytxt.cc index 7bf15b115..9bc01d1a4 100644 --- a/retroshare-nogui/src/notifytxt.cc +++ b/retroshare-nogui/src/notifytxt.cc @@ -95,7 +95,7 @@ bool NotifyTxt::askForPassword(const std::string& key_details, bool prev_is_bad, void NotifyTxt::notifyListChange(int list, int type) { - std::cerr << "NotifyTxt::notifyListChange()" << std::endl; + //std::cerr << "NotifyTxt::notifyListChange()" << std::endl; switch(list) { // case NOTIFY_LIST_NEIGHBOURS: @@ -214,3 +214,94 @@ void NotifyTxt::displayTransfers() iface->unlockData(); /* UnLock Interface */ } + + +/******************* Turtle Search Interface **********/ + +void NotifyTxt::notifyTurtleSearchResult(uint32_t search_id,const std::list& found_files) +{ +// std::cerr << "NotifyTxt::notifyTurtleSearchResult() " << found_files.size(); +// std::cerr << " new results for Id: " << search_id; +// std::cerr << std::endl; + + RsStackMutex stack(mNotifyMtx); /****** LOCKED *****/ + + std::map >::iterator it; + it = mSearchResults.find(search_id); + if (it == mSearchResults.end()) + { + /* new entry */ + mSearchResults[search_id] = found_files; + return; + } + + /* add to existing entry */ + std::list::const_iterator fit; + for(fit = found_files.begin(); fit != found_files.end(); fit++) + { + it->second.push_back(*fit); + } + return; +} + + + /* interface for handling SearchResults */ +void NotifyTxt::getSearchIds(std::list &searchIds) +{ + RsStackMutex stack(mNotifyMtx); /****** LOCKED *****/ + + std::map >::iterator it; + for(it = mSearchResults.begin(); it != mSearchResults.end(); it++) + { + searchIds.push_back(it->first); + } + return; +} + + +int NotifyTxt::getSearchResults(uint32_t id, std::list &searchResults) +{ + RsStackMutex stack(mNotifyMtx); /****** LOCKED *****/ + + std::map >::iterator it; + it = mSearchResults.find(id); + if (it == mSearchResults.end()) + { + return 0; + } + + searchResults = it->second; + return 1; +} + + +int NotifyTxt::getSearchResultCount(uint32_t id) +{ + RsStackMutex stack(mNotifyMtx); /****** LOCKED *****/ + + std::map >::iterator it; + it = mSearchResults.find(id); + if (it == mSearchResults.end()) + { + return 0; + } + return it->second.size(); +} + + +int NotifyTxt::clearSearchId(uint32_t searchId) +{ + RsStackMutex stack(mNotifyMtx); /****** LOCKED *****/ + + std::map >::iterator it; + it = mSearchResults.find(searchId); + if (it == mSearchResults.end()) + { + return 0; + } + + mSearchResults.erase(it); + return 1; +} + + diff --git a/retroshare-nogui/src/notifytxt.h b/retroshare-nogui/src/notifytxt.h index a5b1bb851..373f01339 100644 --- a/retroshare-nogui/src/notifytxt.h +++ b/retroshare-nogui/src/notifytxt.h @@ -27,13 +27,15 @@ #include +#include +#include "util/rsthreads.h" #include class NotifyTxt: public NotifyBase { public: - NotifyTxt() { return; } + NotifyTxt():mNotifyMtx("NotifyMtx") { return; } virtual ~NotifyTxt() { return; } void setRsIface(RsIface *i) { iface = i; } @@ -42,6 +44,15 @@ class NotifyTxt: public NotifyBase virtual void notifyChat(); virtual bool askForPassword(const std::string& key_details, bool prev_is_bad, std::string& password); + virtual void notifyTurtleSearchResult(uint32_t search_id,const std::list& found_files); + + /* interface for handling SearchResults */ + void getSearchIds(std::list &searchIds); + int getSearchResults(uint32_t id, std::list &searchResults); + int clearSearchId(uint32_t searchId); + int getSearchResultCount(uint32_t id); + + private: void displayNeighbours(); @@ -53,6 +64,12 @@ class NotifyTxt: public NotifyBase void displayTransfers(); RsIface *iface; /* so we can get the data */ + + + /* store TurtleSearchResults */ + RsMutex mNotifyMtx; + + std::map > mSearchResults; }; #endif diff --git a/retroshare-nogui/src/retroshare-nogui.pro b/retroshare-nogui/src/retroshare-nogui.pro index 5c3ac86a6..5c72ab734 100644 --- a/retroshare-nogui/src/retroshare-nogui.pro +++ b/retroshare-nogui/src/retroshare-nogui.pro @@ -4,6 +4,17 @@ CONFIG += bitdht #CONFIG += introserver #CONFIG += sshserver +CONFIG += debug +debug { + QMAKE_CFLAGS -= -O2 + QMAKE_CFLAGS += -O0 + QMAKE_CFLAGS += -g + + QMAKE_CXXFLAGS -= -O2 + QMAKE_CXXFLAGS += -O0 + QMAKE_CXXFLAGS += -g +} + ################################# Linux ########################################## linux-* { #CONFIG += version_detail_bash_script @@ -123,12 +134,22 @@ sshserver { # # You can connect from a standard ssh, eg: ssh -p 7022 127.0.0.1 # - + # The Menu system is available from the command-line now, + # but not over SSH yet... + # if it get covered by debug gunk, just press to refresh. + # INCLUDEPATH += ../../../lib/libssh-0.5.2/include/ LIBS += ../../../lib/libssh-0.5.2/build/src/libssh.a LIBS += ../../../lib/libssh-0.5.2/build/src/threads/libssh_threads.a HEADERS += ssh/rssshd.h SOURCES += ssh/rssshd.cc + + HEADERS += menu/menu.h \ + menu/menus.h \ + + SOURCES += menu/menu.cc \ + menu/menus.cc \ + DEFINES *= RS_SSH_SERVER } diff --git a/retroshare-nogui/src/retroshare.cc b/retroshare-nogui/src/retroshare.cc index 418f92985..0f67cd33d 100644 --- a/retroshare-nogui/src/retroshare.cc +++ b/retroshare-nogui/src/retroshare.cc @@ -42,6 +42,10 @@ #ifdef RS_SSH_SERVER #include "ssh/rssshd.h" + +#include "menu/menus.h" +#include "menu/menutest.h" + #endif /* Basic instructions for running libretroshare as background thread. @@ -152,12 +156,17 @@ int main(int argc, char **argv) #ifdef RS_SSH_SERVER ssh->start(); + + Menu *baseMenu = CreateMenuStructure(notify); + MenuInterface *menuInterface = new MenuInterface(baseMenu); + MenuTest menuTest(menuInterface, std::cin, std::cout); + #endif /* pass control to the GUI */ while(1) { - std::cerr << "GUI Tick()" << std::endl; + //std::cerr << "GUI Tick()" << std::endl; #ifndef WINDOWS_SYS sleep(1); #else @@ -167,6 +176,11 @@ int main(int argc, char **argv) #ifdef RS_INTRO_SERVER rsIS.tick(); #endif + +#ifdef RS_SSH_SERVER + menuTest.tick(); +#endif + } return 1; } From fa6517317185b82b40f018e6d0f6a4668700fa1c Mon Sep 17 00:00:00 2001 From: drbob Date: Wed, 8 Aug 2012 09:23:26 +0000 Subject: [PATCH 019/222] switched output from std::cerr to std::cout.... now you can run ./retroshare-nogui 2> /dev/null to get a usable terminal rs console. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5391 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/menu/menu.cc | 224 ++++++++++++++--------------- retroshare-nogui/src/menu/menus.cc | 50 +++---- 2 files changed, 137 insertions(+), 137 deletions(-) diff --git a/retroshare-nogui/src/menu/menu.cc b/retroshare-nogui/src/menu/menu.cc index 604f127be..567dc4b29 100644 --- a/retroshare-nogui/src/menu/menu.cc +++ b/retroshare-nogui/src/menu/menu.cc @@ -51,8 +51,8 @@ uint32_t MenuInterface::process(char key) { #ifdef MENU_DEBUG - std::cerr << "MenuInterface::process(" << key << ")"; - std::cerr << std::endl; + std::cout << "MenuInterface::process(" << key << ")"; + std::cout << std::endl; #endif // MENU_DEBUG /* call process on current menu */ @@ -62,8 +62,8 @@ uint32_t MenuInterface::process(char key) bool showHelp = false; #ifdef MENU_DEBUG - std::cerr << "MenuInterface::process() currentMenu says: " << rt; - std::cerr << std::endl; + std::cout << "MenuInterface::process() currentMenu says: " << rt; + std::cout << std::endl; #endif // MENU_DEBUG switch(rt) @@ -92,15 +92,15 @@ uint32_t MenuInterface::process(char key) /* new menu to switch to */ if (mCurrentMenu->selectedMenu()) { - std::cerr << "MenuInterface::process() Switching Menus"; - std::cerr << std::endl; + std::cout << "MenuInterface::process() Switching Menus"; + std::cout << std::endl; mCurrentMenu = mCurrentMenu->selectedMenu(); } else { - std::cerr << "MenuInterface::process() ERROR"; - std::cerr << " SelectedMenu == NULL"; - std::cerr << std::endl; + std::cout << "MenuInterface::process() ERROR"; + std::cout << " SelectedMenu == NULL"; + std::cout << std::endl; } break; @@ -123,7 +123,7 @@ uint32_t MenuInterface::process(char key) /* HEADER */ for(int i = 0; i < 20; i++) { - std::cerr << std::endl; + std::cout << std::endl; } /* ERROR */ @@ -145,10 +145,10 @@ uint32_t MenuInterface::process(char key) uint32_t MenuInterface::drawHeader() { - std::cerr << "======================================================="; - std::cerr << std::endl; - std::cerr << "Retroshare Terminal Menu V2.xxxx ======================"; - std::cerr << std::endl; + std::cout << "======================================================="; + std::cout << std::endl; + std::cout << "Retroshare Terminal Menu V2.xxxx ======================"; + std::cout << std::endl; unsigned int nTotal = 0; unsigned int nConnected = 0; @@ -200,18 +200,18 @@ uint32_t MenuInterface::drawHeader() float upKb = 0; rsicontrol -> ConfigGetDataRates(downKb, upKb); - std::cerr << "Friends " << nConnected << "/" << nTotal; - std::cerr << " Network: " << natState; - std::cerr << std::endl; - std::cerr << "Down: " << downKb << " (kB/s) "; - std::cerr << " Up: " << upKb << " (kB/s) "; - std::cerr << std::endl; - std::cerr << "Menu State: "; - tailrec_printparents(mCurrentMenu, std::cerr); - std::cerr << std::endl; + std::cout << "Friends " << nConnected << "/" << nTotal; + std::cout << " Network: " << natState; + std::cout << std::endl; + std::cout << "Down: " << downKb << " (kB/s) "; + std::cout << " Up: " << upKb << " (kB/s) "; + std::cout << std::endl; + std::cout << "Menu State: "; + tailrec_printparents(mCurrentMenu, std::cout); + std::cout << std::endl; - std::cerr << "======================================================="; - std::cerr << std::endl; + std::cout << "======================================================="; + std::cout << std::endl; return 1; } @@ -241,8 +241,8 @@ int Menu::addMenuItem(char key, Menu *child) it = mChildren.find(key); if (it != mChildren.end()) { - std::cerr << "Menu::addMenuItem() ERROR DUPLICATE MENU ITEM"; - std::cerr << std::endl; + std::cout << "Menu::addMenuItem() ERROR DUPLICATE MENU ITEM"; + std::cout << std::endl; return 0; } mChildren[key] = child; @@ -337,23 +337,23 @@ uint32_t Menu::process_children(char key) uint32_t Menu::drawPage() { - std::cerr << "Universal Commands ( "; - std::cerr << (char) MENU_KEY_QUIT << ":Quit "; - std::cerr << (char) MENU_KEY_HELP << ":Help "; - std::cerr << (char) MENU_KEY_TOP << ":Top "; - std::cerr << (char) MENU_KEY_UP << ":Up "; - std::cerr << ")"; - std::cerr << std::endl; + std::cout << "Universal Commands ( "; + std::cout << (char) MENU_KEY_QUIT << ":Quit "; + std::cout << (char) MENU_KEY_HELP << ":Help "; + std::cout << (char) MENU_KEY_TOP << ":Top "; + std::cout << (char) MENU_KEY_UP << ":Up "; + std::cout << ")"; + std::cout << std::endl; - std::cerr << "Specific Commands ("; + std::cout << "Specific Commands ("; std::map::iterator it; for(it = mChildren.begin(); it != mChildren.end(); it++) { - std::cerr << (char) it->first << ":"; - std::cerr << it->second->ShortFnDesc() << " "; + std::cout << (char) it->first << ":"; + std::cout << it->second->ShortFnDesc() << " "; } - std::cerr << ")"; - std::cerr << std::endl; + std::cout << ")"; + std::cout << std::endl; return 1; } @@ -361,25 +361,25 @@ uint32_t Menu::drawPage() uint32_t Menu::drawHelpPage() { - std::cerr << "Menu Help: Universal Commands are:"; - std::cerr << std::endl; - std::cerr << "\tKey: " << (char) MENU_KEY_QUIT << " => Quit"; - std::cerr << std::endl; - std::cerr << "\tKey: " << (char) MENU_KEY_HELP << " => Help"; - std::cerr << std::endl; - std::cerr << "\tKey: " << (char) MENU_KEY_TOP << " => Top Menu"; - std::cerr << std::endl; - std::cerr << "\tKey: " << (char) MENU_KEY_UP << " => Up a Menu"; - std::cerr << std::endl; + std::cout << "Menu Help: Universal Commands are:"; + std::cout << std::endl; + std::cout << "\tKey: " << (char) MENU_KEY_QUIT << " => Quit"; + std::cout << std::endl; + std::cout << "\tKey: " << (char) MENU_KEY_HELP << " => Help"; + std::cout << std::endl; + std::cout << "\tKey: " << (char) MENU_KEY_TOP << " => Top Menu"; + std::cout << std::endl; + std::cout << "\tKey: " << (char) MENU_KEY_UP << " => Up a Menu"; + std::cout << std::endl; - std::cerr << "Specific Commands are:"; - std::cerr << std::endl; + std::cout << "Specific Commands are:"; + std::cout << std::endl; std::map::iterator it; for(it = mChildren.begin(); it != mChildren.end(); it++) { - std::cerr << "\tKey: " << (char) it->first << " => "; - std::cerr << it->second->ShortFnDesc(); - std::cerr << std::endl; + std::cout << "\tKey: " << (char) it->first << " => "; + std::cout << it->second->ShortFnDesc(); + std::cout << std::endl; } return 1; @@ -395,18 +395,18 @@ uint32_t MenuList::drawPage() { Menu::drawPage(); - std::cerr << "Navigation Commands ("; - //std::cerr << (char) MENULIST_KEY_LIST << ":List "; - std::cerr << (char) MENULIST_KEY_NEXT << ":Next "; - std::cerr << (char) MENULIST_KEY_PREV << ":Prev "; - std::cerr << ")"; - std::cerr << std::endl; + std::cout << "Navigation Commands ("; + //std::cout << (char) MENULIST_KEY_LIST << ":List "; + std::cout << (char) MENULIST_KEY_NEXT << ":Next "; + std::cout << (char) MENULIST_KEY_PREV << ":Prev "; + std::cout << ")"; + std::cout << std::endl; - std::cerr << "MenuList::Internals "; - std::cerr << "ListSize: " << getListCount(); - std::cerr << " SelectIdx: " << mSelectIdx; - std::cerr << " Cursor: " << mCursor; - std::cerr << std::endl; + std::cout << "MenuList::Internals "; + std::cout << "ListSize: " << getListCount(); + std::cout << " SelectIdx: " << mSelectIdx; + std::cout << " Cursor: " << mCursor; + std::cout << std::endl; int i = 0; @@ -420,28 +420,28 @@ uint32_t MenuList::drawPage() if (mSelectIdx >= 0) { - std::cerr << "Current Selection Idx: " << mSelectIdx << " : "; + std::cout << "Current Selection Idx: " << mSelectIdx << " : "; std::string desc; if (getEntryDesc(mSelectIdx, desc) & (desc != "")) { - std::cerr << desc; + std::cout << desc; } else { - std::cerr << "Missing Description"; + std::cout << "Missing Description"; } - std::cerr << std::endl; + std::cout << std::endl; } else { - std::cerr << "No Current Selection: Use 0 - 9 to choose an Entry"; - std::cerr << std::endl; + std::cout << "No Current Selection: Use 0 - 9 to choose an Entry"; + std::cout << std::endl; } - std::cerr << "Showing " << startCount; - std::cerr << " to " << endCount << " of " << listCount << " Entries"; - std::cerr << std::endl; + std::cout << "Showing " << startCount; + std::cout << " to " << endCount << " of " << listCount << " Entries"; + std::cout << std::endl; std::list::iterator it; for (it = mList.begin(); it != mList.end(); it++, i++) @@ -451,23 +451,23 @@ uint32_t MenuList::drawPage() { if (i == mSelectIdx) { - std::cerr << "SELECTED => (" << curIdx << ") "; + std::cout << "SELECTED => (" << curIdx << ") "; } else { - std::cerr << "\t(" << curIdx << ") "; + std::cout << "\t(" << curIdx << ") "; } std::string desc; if (getEntryDesc(i, desc) & (desc != "")) { - std::cerr << desc; + std::cout << desc; } else { - std::cerr << *it << " => "; - std::cerr << "Missing Description"; + std::cout << *it << " => "; + std::cout << "Missing Description"; } - std::cerr << std::endl; + std::cout << std::endl; } } @@ -478,23 +478,23 @@ uint32_t MenuList::drawHelpPage() { Menu::drawPage(); - std::cerr << "MenuList Help: Navigation Commands are:"; - std::cerr << std::endl; - //std::cerr << "\tKey: " << (char) MENULIST_KEY_LIST << " => List"; - //std::cerr << std::endl; - std::cerr << "\tKey: " << (char) MENULIST_KEY_NEXT << " => Next Page"; - std::cerr << std::endl; - std::cerr << "\tKey: " << (char) MENULIST_KEY_PREV << " => Prev Page"; - std::cerr << std::endl; + std::cout << "MenuList Help: Navigation Commands are:"; + std::cout << std::endl; + //std::cout << "\tKey: " << (char) MENULIST_KEY_LIST << " => List"; + //std::cout << std::endl; + std::cout << "\tKey: " << (char) MENULIST_KEY_NEXT << " => Next Page"; + std::cout << std::endl; + std::cout << "\tKey: " << (char) MENULIST_KEY_PREV << " => Prev Page"; + std::cout << std::endl; - std::cerr << "MenuList::drawPage() Internal Details"; - std::cerr << std::endl; - std::cerr << "List Size: " << getListCount(); - std::cerr << std::endl; - std::cerr << "SelectIdx: " << mSelectIdx; - std::cerr << std::endl; - std::cerr << "Cursor: " << mCursor; - std::cerr << std::endl; + std::cout << "MenuList::drawPage() Internal Details"; + std::cout << std::endl; + std::cout << "List Size: " << getListCount(); + std::cout << std::endl; + std::cout << "SelectIdx: " << mSelectIdx; + std::cout << std::endl; + std::cout << "Cursor: " << mCursor; + std::cout << std::endl; return 1; } @@ -584,13 +584,13 @@ uint32_t MenuList::list_process(char key) if (mCursor + idx < getListCount()) { mSelectIdx = mCursor + idx; - std::cerr << "MenuList::list_process() Selected Idx: " << mSelectIdx; - std::cerr << std::endl; + std::cout << "MenuList::list_process() Selected Idx: " << mSelectIdx; + std::cout << std::endl; } else { - std::cerr << "MenuList::list_process() Idx Out of Range"; - std::cerr << std::endl; + std::cout << "MenuList::list_process() Idx Out of Range"; + std::cout << std::endl; } return MENU_PROCESS_DONE; /* ready for next key stroke */ @@ -717,14 +717,14 @@ uint32_t MenuOpLineInput::op() uint32_t MenuOpLineInput::process_lines(std::string input) { - std::cerr << "MenuOpLineInput::process_lines() => SHOULD BE OVERLOADED"; - std::cerr << "Input Was: "; - std::cerr << std::endl; - std::cerr << "=================================================="; - std::cerr << std::endl; - std::cerr << input; - std::cerr << "=================================================="; - std::cerr << std::endl; + std::cout << "MenuOpLineInput::process_lines() => SHOULD BE OVERLOADED"; + std::cout << "Input Was: "; + std::cout << std::endl; + std::cout << "=================================================="; + std::cout << std::endl; + std::cout << input; + std::cout << "=================================================="; + std::cout << std::endl; return MENU_PROCESS_ERROR; } @@ -746,12 +746,12 @@ uint32_t MenuOpLineInput::process(char key) case MENU_PROCESS_NEEDDATA: break; case MENU_PROCESS_ERROR: - std::cerr << "MenuOpLineInput::process() => ERROR"; - std::cerr << std::endl; + std::cout << "MenuOpLineInput::process() => ERROR"; + std::cout << std::endl; case MENU_PROCESS_DONE: /* cleanup for next command */ - std::cerr << "MenuOpLineInput::process() Clearing Buffer"; - std::cerr << std::endl; + std::cout << "MenuOpLineInput::process() Clearing Buffer"; + std::cout << std::endl; mInput.clear(); /* go back to parent menu */ diff --git a/retroshare-nogui/src/menu/menus.cc b/retroshare-nogui/src/menu/menus.cc index c15d2eb3b..d81f24e95 100644 --- a/retroshare-nogui/src/menu/menus.cc +++ b/retroshare-nogui/src/menu/menus.cc @@ -186,16 +186,16 @@ int MenuListTransfer::getEntryDesc(int idx, std::string &desc) std::string hash; if (!getListEntry(idx, hash)) { - std::cerr << "MenuListTransfer::getEntryDesc() No ListEntry"; - std::cerr << std::endl; + std::cout << "MenuListTransfer::getEntryDesc() No ListEntry"; + std::cout << std::endl; return 0; } FileInfo info; if (!rsFiles->FileDetails(hash, RS_FILE_HINTS_DOWNLOAD, info)) { - std::cerr << "MenuListTransfer::getEntryDesc() No FileDetails"; - std::cerr << std::endl; + std::cout << "MenuListTransfer::getEntryDesc() No FileDetails"; + std::cout << std::endl; return 0; } @@ -302,9 +302,9 @@ int MenuListSearch::getCurrentSearchId(uint32_t &id) int MenuListSearch::storeSearch(uint32_t searchId, std::string match_string) { - std::cerr << "MenuListSearch::storeSearch(" << searchId << " => "; - std::cerr << match_string; - std::cerr << std::endl; + std::cout << "MenuListSearch::storeSearch(" << searchId << " => "; + std::cout << match_string; + std::cout << std::endl; std::string strSearchId; rs_sprintf(strSearchId, "%lu", searchId); @@ -318,8 +318,8 @@ int MenuListSearch::storeSearch(uint32_t searchId, std::string match_string) int MenuListSearch::removeSearch(std::string strSearchId) { - std::cerr << "MenuListSearch::removeSearch(" << strSearchId << ")"; - std::cerr << std::endl; + std::cout << "MenuListSearch::removeSearch(" << strSearchId << ")"; + std::cout << std::endl; std::map::iterator it; it = mSearchIds.find(strSearchId); @@ -341,8 +341,8 @@ uint32_t MenuOpSearchNew::process_lines(std::string input) /* launch search */ if (input.size() < 4) { - std::cerr << "MenuOpSearchNew::process_lines() ERROR Input too small"; - std::cerr << std::endl; + std::cout << "MenuOpSearchNew::process_lines() ERROR Input too small"; + std::cout << std::endl; return MENU_PROCESS_ERROR; } @@ -378,8 +378,8 @@ uint32_t MenuListSearchList::refresh() MenuListSearch *mls = dynamic_cast(p); if (!mls) { - std::cerr << "MenuListSearchList::refresh() mls not there"; - std::cerr << std::endl; + std::cout << "MenuListSearchList::refresh() mls not there"; + std::cout << std::endl; return MENU_OP_ERROR; } @@ -389,13 +389,13 @@ uint32_t MenuListSearchList::refresh() uint32_t searchId; if (!mls->getCurrentSearchId(searchId)) { - std::cerr << "MenuListSearchList::refresh() currentIdx invalid"; - std::cerr << std::endl; + std::cout << "MenuListSearchList::refresh() currentIdx invalid"; + std::cout << std::endl; return MENU_OP_ERROR; } - std::cerr << "MenuListSearchList::refresh() searchId: " << searchId; - std::cerr << std::endl; + std::cout << "MenuListSearchList::refresh() searchId: " << searchId; + std::cout << std::endl; std::list::iterator it; mNotify->getSearchResults(searchId, mSearchResults); @@ -432,8 +432,8 @@ int MenuListSearchList::downloadSelected() { if (mSelectIdx < 0) { - std::cerr << "MenuListSearchList::downloadSelected() Invalid Selection"; - std::cerr << std::endl; + std::cout << "MenuListSearchList::downloadSelected() Invalid Selection"; + std::cout << std::endl; return MENU_ENTRY_NONE; } @@ -448,13 +448,13 @@ int MenuListSearchList::downloadSelected() if (rsFiles -> FileRequest(it->name, it->hash, it->size, "", RS_FILE_HINTS_NETWORK_WIDE, srcIds)) { - std::cerr << "MenuListSearchList::downloadSelected() Download Started"; - std::cerr << std::endl; + std::cout << "MenuListSearchList::downloadSelected() Download Started"; + std::cout << std::endl; } else { - std::cerr << "MenuListSearchList::downloadSelected() Error Starting Download"; - std::cerr << std::endl; + std::cout << "MenuListSearchList::downloadSelected() Error Starting Download"; + std::cout << std::endl; } return MENU_ENTRY_OKAY; } @@ -469,8 +469,8 @@ uint32_t MenuOpSearchListDownload::op_basic(std::string key) MenuListSearchList *mlsl = dynamic_cast(p); if (!mlsl) { - std::cerr << "MenuOpSearchListDownload::op_basic() ERROR"; - std::cerr << std::endl; + std::cout << "MenuOpSearchListDownload::op_basic() ERROR"; + std::cout << std::endl; return MENU_OP_ERROR; } From 8f2ff3eaf5ad5cfcba8fac0d3bda3d8b72330bed Mon Sep 17 00:00:00 2001 From: drbob Date: Thu, 9 Aug 2012 13:45:05 +0000 Subject: [PATCH 020/222] Changes to bring the SSH Menu system online! * Commandline Options added (./retroshare-nogui -h for help). * Added Password Hash system. * Shifted Menu output to std::string buffers. * Built interface to SSH server. * changed menus to lowercase. * Fixed SSH server restart issue. * Updates Output regularly now. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5398 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/menu/menu.cc | 261 ++++++++++++--------- retroshare-nogui/src/menu/menu.h | 67 ++++-- retroshare-nogui/src/menu/menus.cc | 47 ++-- retroshare-nogui/src/menu/menus.h | 3 + retroshare-nogui/src/menu/menutest.h | 64 +++++- retroshare-nogui/src/retroshare-nogui.pro | 10 +- retroshare-nogui/src/retroshare.cc | 262 ++++++++++++++++++++-- retroshare-nogui/src/rstermserver.h | 13 ++ retroshare-nogui/src/ssh/rssshd.cc | 248 ++++++++++++++++++-- retroshare-nogui/src/ssh/rssshd.h | 25 ++- 10 files changed, 814 insertions(+), 186 deletions(-) create mode 100644 retroshare-nogui/src/rstermserver.h diff --git a/retroshare-nogui/src/menu/menu.cc b/retroshare-nogui/src/menu/menu.cc index 567dc4b29..504558837 100644 --- a/retroshare-nogui/src/menu/menu.cc +++ b/retroshare-nogui/src/menu/menu.cc @@ -6,48 +6,59 @@ #include +#include "util/rsstring.h" + /********************************************************** * Menu Base Interface. */ -int tailrec_printparents(Menu *m, std::ostream &out) + // RsTermServer Interface. +void MenuInterface::reset() +{ + mBase->reset(); + mCurrentMenu = mBase; + mInputRequired = false; +} + +int MenuInterface::tick(bool haveInput, char keypress, std::string &output) +{ + if (!haveInput) + { + /* make a harmless key */ + keypress = ' '; + } + + if ((mInputRequired) && (!haveInput)) + { + return 1; + } + + uint32_t rt = process(keypress, mDrawFlags, output); + mInputRequired = (rt == MENU_PROCESS_NEEDDATA); + + if (rt == MENU_PROCESS_QUIT) + { + return -1; + } + return 1; +} + + +int tailrec_printparents(Menu *m, std::string &buffer) { Menu *p = m->parent(); if (p) { - tailrec_printparents(p, out); + tailrec_printparents(p, buffer); } - out << m->ShortFnDesc() << " => "; - -#if 0 - MenuList *ml = dynamic_cast(m); - MenuOpBasicKey *mbk = dynamic_cast(m); - MenuOpTwoKeys *mtk = dynamic_cast(m); - - if (ml) - { - out << "MenuList@" << (void *) m << " "; - } - else if (mbk) - { - out << "MenuBasicKey@" << (void *) m << " "; - } - else if (mtk) - { - out << "MenuOpTwoKeys@" << (void *) m << " "; - } - else - { - out << "Menu@" << (void *) m << " "; - } -#endif - + buffer += m->ShortFnDesc(); + buffer += " => "; return 1; } -uint32_t MenuInterface::process(char key) +uint32_t MenuInterface::process(char key, uint32_t drawFlags, std::string &buffer) { #ifdef MENU_DEBUG @@ -66,18 +77,23 @@ uint32_t MenuInterface::process(char key) std::cout << std::endl; #endif // MENU_DEBUG - switch(rt) + + uint32_t base_rt = (rt & MENU_PROCESS_MASK); + bool needData = (rt & MENU_PROCESS_NEEDDATA); + switch(base_rt) { case MENU_PROCESS_NONE: + if (needData) + { + /* no redraw, this could be called many times */ + doRedraw = false; + } + break; + case MENU_PROCESS_DONE: /* no changes - operation performed, or noop */ break; - case MENU_PROCESS_NEEDDATA: - /* no redraw, this could be called many times */ - doRedraw = false; - break; - case MENU_PROCESS_ERROR: /* Show Error at top of Page */ showError = true; @@ -114,6 +130,11 @@ uint32_t MenuInterface::process(char key) break; } + if (drawFlags & MENU_DRAW_FLAGS_ECHO) + { + buffer += key; + } + /* now we redraw, and wait for next data */ if (!doRedraw) { @@ -123,7 +144,7 @@ uint32_t MenuInterface::process(char key) /* HEADER */ for(int i = 0; i < 20; i++) { - std::cout << std::endl; + buffer += "\r\n"; } /* ERROR */ @@ -138,17 +159,19 @@ uint32_t MenuInterface::process(char key) } /* MENU PAGE */ - drawHeader(); - mCurrentMenu->drawPage(); - return MENU_PROCESS_NEEDDATA; + drawHeader(drawFlags, buffer); + mCurrentMenu->drawPage(drawFlags, buffer); + + if (needData) + return MENU_PROCESS_NEEDDATA; + + return MENU_PROCESS_NONE; } -uint32_t MenuInterface::drawHeader() +uint32_t MenuInterface::drawHeader(uint32_t drawFlags, std::string &buffer) { - std::cout << "======================================================="; - std::cout << std::endl; - std::cout << "Retroshare Terminal Menu V2.xxxx ======================"; - std::cout << std::endl; + buffer += "=======================================================\r\n"; + buffer += "Retroshare Terminal Menu V2.xxxx ======================\r\n"; unsigned int nTotal = 0; unsigned int nConnected = 0; @@ -200,18 +223,19 @@ uint32_t MenuInterface::drawHeader() float upKb = 0; rsicontrol -> ConfigGetDataRates(downKb, upKb); - std::cout << "Friends " << nConnected << "/" << nTotal; - std::cout << " Network: " << natState; - std::cout << std::endl; - std::cout << "Down: " << downKb << " (kB/s) "; - std::cout << " Up: " << upKb << " (kB/s) "; - std::cout << std::endl; - std::cout << "Menu State: "; - tailrec_printparents(mCurrentMenu, std::cout); - std::cout << std::endl; + rs_sprintf_append(buffer, "Friends %d / %d Network: %s\r\n", + nConnected, nTotal, natState.c_str()); - std::cout << "======================================================="; - std::cout << std::endl; + rs_sprintf_append(buffer, "Down: %2.2f Up %2.2f\r\n", downKb, upKb); + + std::string menuState; + tailrec_printparents(mCurrentMenu, menuState); + + buffer += "Menu State: "; + buffer += menuState; + buffer += "\r\n"; + + buffer += "=======================================================\r\n"; return 1; } @@ -251,6 +275,16 @@ int Menu::addMenuItem(char key, Menu *child) return 1; } +void Menu::reset() +{ + mSelectedMenu = NULL; + std::map::iterator it; + for(it = mChildren.begin(); it != mChildren.end(); it++) + { + it->second->reset(); + } +} + uint32_t Menu::process(char key) { @@ -309,11 +343,11 @@ uint32_t Menu::process_children(char key) /* now return, depending on type */ switch(it->second->op()) { - /* Think I can handle these the same! Both will call DrawPage, - * then Process on New Menu - */ - case MENU_OP_NEEDDATA: + setSelectedMenu(it->second); + return MENU_PROCESS_MENU | MENU_PROCESS_NEEDDATA; + break; + case MENU_OP_SUBMENU: setSelectedMenu(it->second); return MENU_PROCESS_MENU; @@ -335,31 +369,40 @@ uint32_t Menu::process_children(char key) } -uint32_t Menu::drawPage() +uint32_t Menu::drawPage(uint32_t drawFlags, std::string &buffer) { - std::cout << "Universal Commands ( "; - std::cout << (char) MENU_KEY_QUIT << ":Quit "; - std::cout << (char) MENU_KEY_HELP << ":Help "; - std::cout << (char) MENU_KEY_TOP << ":Top "; - std::cout << (char) MENU_KEY_UP << ":Up "; - std::cout << ")"; - std::cout << std::endl; + buffer += "Universal Commands ( "; + if (!(drawFlags & MENU_DRAW_FLAGS_NOQUIT)) + { + buffer += (char) MENU_KEY_QUIT; + buffer += ":Quit "; + } + buffer += (char) MENU_KEY_HELP; + buffer += ":Help "; + buffer += (char) MENU_KEY_TOP; + buffer += ":Top "; + buffer += (char) MENU_KEY_UP; + buffer += ":Up "; + buffer += ")"; + buffer += "\r\n"; - std::cout << "Specific Commands ("; + buffer += "Specific Commands ( "; std::map::iterator it; for(it = mChildren.begin(); it != mChildren.end(); it++) { - std::cout << (char) it->first << ":"; - std::cout << it->second->ShortFnDesc() << " "; + buffer += (char) it->first; + buffer += ":"; + buffer += it->second->ShortFnDesc(); + buffer += " "; } - std::cout << ")"; - std::cout << std::endl; + buffer += ")"; + buffer += "\r\n"; return 1; } -uint32_t Menu::drawHelpPage() +uint32_t Menu::drawHelpPage(uint32_t drawFlags, std::string &buffer) { std::cout << "Menu Help: Universal Commands are:"; std::cout << std::endl; @@ -391,22 +434,20 @@ uint32_t Menu::drawHelpPage() */ -uint32_t MenuList::drawPage() +uint32_t MenuList::drawPage(uint32_t drawFlags, std::string &buffer) { - Menu::drawPage(); + Menu::drawPage(drawFlags, buffer); - std::cout << "Navigation Commands ("; - //std::cout << (char) MENULIST_KEY_LIST << ":List "; - std::cout << (char) MENULIST_KEY_NEXT << ":Next "; - std::cout << (char) MENULIST_KEY_PREV << ":Prev "; - std::cout << ")"; - std::cout << std::endl; + buffer += "Navigation Commands ("; + buffer += (char) MENULIST_KEY_NEXT; + buffer += ":Next "; + buffer += (char) MENULIST_KEY_PREV; + buffer += ":Prev "; + buffer += ")"; + buffer += "\r\n"; - std::cout << "MenuList::Internals "; - std::cout << "ListSize: " << getListCount(); - std::cout << " SelectIdx: " << mSelectIdx; - std::cout << " Cursor: " << mCursor; - std::cout << std::endl; + rs_sprintf_append(buffer, "MenuList::Internals ListSize: %d, SelectIdx: %d Cursor: %d\r\n", + getListCount(), mSelectIdx, mCursor); int i = 0; @@ -420,28 +461,28 @@ uint32_t MenuList::drawPage() if (mSelectIdx >= 0) { - std::cout << "Current Selection Idx: " << mSelectIdx << " : "; + + rs_sprintf_append(buffer, "Current Selection Idx: %d : ", mSelectIdx); std::string desc; if (getEntryDesc(mSelectIdx, desc) & (desc != "")) { - std::cout << desc; + buffer += desc; } else { - std::cout << "Missing Description"; + buffer += "Missing Description"; } - std::cout << std::endl; + buffer += "\r\n"; } else { - std::cout << "No Current Selection: Use 0 - 9 to choose an Entry"; - std::cout << std::endl; + buffer += "No Current Selection: Use 0 - 9 to choose an Entry"; + buffer += "\r\n"; } - std::cout << "Showing " << startCount; - std::cout << " to " << endCount << " of " << listCount << " Entries"; - std::cout << std::endl; + rs_sprintf_append(buffer, "Showing %d to %d of %d Entries\r\n", + startCount, endCount, listCount); std::list::iterator it; for (it = mList.begin(); it != mList.end(); it++, i++) @@ -451,32 +492,35 @@ uint32_t MenuList::drawPage() { if (i == mSelectIdx) { - std::cout << "SELECTED => (" << curIdx << ") "; + rs_sprintf_append(buffer, "SELECTED (%d) ", curIdx); } else { - std::cout << "\t(" << curIdx << ") "; + rs_sprintf_append(buffer, "\t(%d) ", curIdx); } std::string desc; if (getEntryDesc(i, desc) & (desc != "")) { - std::cout << desc; + buffer += desc; } else { - std::cout << *it << " => "; - std::cout << "Missing Description"; + buffer += *it; + buffer += " => "; + buffer += "Missing Description"; } - std::cout << std::endl; + buffer += "\r\n"; } } + buffer += "\r\n"; + buffer += "Make Your Choice > "; return 1; } -uint32_t MenuList::drawHelpPage() +uint32_t MenuList::drawHelpPage(uint32_t drawFlags, std::string &buffer) { - Menu::drawPage(); + Menu::drawHelpPage(drawFlags, buffer); std::cout << "MenuList Help: Navigation Commands are:"; std::cout << std::endl; @@ -499,11 +543,18 @@ uint32_t MenuList::drawHelpPage() } +void MenuList::reset() +{ + Menu::reset(); // clears children too. + + mList.clear(); + mSelectIdx = -1; + mCursor = 0; +} + uint32_t MenuList::op() { - /* load friend list*/ mList.clear(); - //rsPeers->getGpgAcceptedList(mList); mSelectIdx = -1; mCursor = 0; @@ -734,7 +785,7 @@ uint32_t MenuOpLineInput::process(char key) { /* read data in and add to buffer */ mInput += key; - if (key != '\n') + if ((key != '\n') && (key != '\r')) { return MENU_PROCESS_NEEDDATA; } diff --git a/retroshare-nogui/src/menu/menu.h b/retroshare-nogui/src/menu/menu.h index 23e3c015d..4d10c762a 100644 --- a/retroshare-nogui/src/menu/menu.h +++ b/retroshare-nogui/src/menu/menu.h @@ -7,25 +7,30 @@ #include #include -#define MENU_PROCESS_NONE 0 -#define MENU_PROCESS_TOP 1 -#define MENU_PROCESS_MENU 2 -#define MENU_PROCESS_NEEDDATA 3 -#define MENU_PROCESS_DONE 4 -#define MENU_PROCESS_QUIT 5 -#define MENU_PROCESS_SHUTDOWN 6 -#define MENU_PROCESS_HELP 7 -#define MENU_PROCESS_ERROR 8 +#include "rstermserver.h" // generic processing command. + +#define MENU_PROCESS_MASK 0x0fff + +#define MENU_PROCESS_NONE 0x0000 +#define MENU_PROCESS_TOP 0x0001 +#define MENU_PROCESS_MENU 0x0002 +#define MENU_PROCESS_DONE 0x0004 +#define MENU_PROCESS_QUIT 0x0008 +#define MENU_PROCESS_SHUTDOWN 0x0010 +#define MENU_PROCESS_HELP 0x0020 +#define MENU_PROCESS_ERROR 0x0040 + +#define MENU_PROCESS_NEEDDATA 0x1000 // Able to be OR'd with ANOTHER CASE. #define MENU_KEY_QUIT 'Q' -#define MENU_KEY_HELP 'H' -#define MENU_KEY_TOP 'T' -#define MENU_KEY_REPEAT 'R' -#define MENU_KEY_UP 'U' +#define MENU_KEY_HELP 'h' +#define MENU_KEY_TOP 't' +#define MENU_KEY_REPEAT 'r' +#define MENU_KEY_UP 'u' -#define MENULIST_KEY_LIST 'L' // Don't need this. -#define MENULIST_KEY_NEXT 'N' -#define MENULIST_KEY_PREV 'P' +#define MENULIST_KEY_LIST 'l' // Don't need this. +#define MENULIST_KEY_NEXT 'n' +#define MENULIST_KEY_PREV 'p' #define MENU_OP_ERROR 0 #define MENU_OP_INSTANT 1 @@ -35,6 +40,11 @@ #define MENU_ENTRY_NONE 0 #define MENU_ENTRY_OKAY 1 +#define MENU_DRAW_FLAGS_STD 0 +#define MENU_DRAW_FLAGS_HTML 1 +#define MENU_DRAW_FLAGS_ECHO 2 +#define MENU_DRAW_FLAGS_NOQUIT 4 + class Menu; class Screen; @@ -49,19 +59,20 @@ virtual ~Menu(); Menu *selectedMenu() { return mSelectedMenu; } int addMenuItem(char key, Menu *child); +virtual void reset(); virtual uint32_t op() { return MENU_OP_SUBMENU; } /* what type is it? returns SUBMENU, INSTANT, NEEDINPUT */ virtual uint32_t process(char key); // THE BIT STILL TO BE DEFINED! std::string ShortFnDesc() { return mShortDesc; }// Menu Text (for Help). +virtual uint32_t drawPage(uint32_t drawFlags, std::string &buffer); +virtual uint32_t drawHelpPage(uint32_t drawFlags, std::string &buffer); //virtual std::string menuText() = 0; //virtual std::string menuHelp() = 0; virtual void setOpMessage(std::string msg) { return; } virtual void setErrorMessage(std::string msg) { return; } -virtual uint32_t drawPage(); // { return 1; } //= 0; -virtual uint32_t drawHelpPage(); // { return 1; } //= 0; virtual uint32_t showError() { return 1; } //= 0; virtual uint32_t showHelp() { return 1; } //= 0; @@ -92,6 +103,7 @@ class MenuList: public Menu public: MenuList(std::string shortDesc): Menu(shortDesc) { return; } +virtual void reset(); virtual uint32_t op(); virtual uint32_t process(char key); @@ -103,8 +115,8 @@ virtual uint32_t process(char key); virtual int getEntryDesc(int idx, std::string &desc); // Output. -virtual uint32_t drawPage(); -virtual uint32_t drawHelpPage(); +virtual uint32_t drawPage(uint32_t drawFlags, std::string &buffer); +virtual uint32_t drawHelpPage(uint32_t drawFlags, std::string &buffer); protected: virtual uint32_t list_process(char key); @@ -161,17 +173,24 @@ protected: -class MenuInterface +class MenuInterface: public RsTermServer { public: - MenuInterface(Menu *b) :mCurrentMenu(b), mBase(b) { return; } - uint32_t process(char key); - uint32_t drawHeader(); + MenuInterface(Menu *b, uint32_t drawFlags) :mCurrentMenu(b), mBase(b), mDrawFlags(drawFlags), mInputRequired(false) { return; } + uint32_t process(char key, uint32_t drawFlags, std::string &buffer); + uint32_t drawHeader(uint32_t drawFlags, std::string &buffer); + + // RsTermServer Interface. + virtual void reset(); + virtual int tick(bool haveInput, char keypress, std::string &output); + private: Menu *mCurrentMenu; Menu *mBase; + uint32_t mDrawFlags; + bool mInputRequired; }; diff --git a/retroshare-nogui/src/menu/menus.cc b/retroshare-nogui/src/menu/menus.cc index d81f24e95..f783abc66 100644 --- a/retroshare-nogui/src/menu/menus.cc +++ b/retroshare-nogui/src/menu/menus.cc @@ -10,30 +10,30 @@ // or L, N, P (list ops). // or 0-9,a-f (list selection). -#define MENU_FRIENDS_KEY_ADD 'A' -#define MENU_FRIENDS_KEY_VIEW 'V' -#define MENU_FRIENDS_KEY_REMOVE 'D' -#define MENU_FRIENDS_KEY_CHAT 'C' +#define MENU_FRIENDS_KEY_ADD 'a' +#define MENU_FRIENDS_KEY_VIEW 'v' +#define MENU_FRIENDS_KEY_REMOVE 'd' +#define MENU_FRIENDS_KEY_CHAT 'c' -#define MENU_TRANSFER_KEY_STOP 'S' -#define MENU_TRANSFER_KEY_CANCEL 'C' +#define MENU_TRANSFER_KEY_STOP 's' +#define MENU_TRANSFER_KEY_CANCEL 'c' -#define MENU_SEARCH_KEY_ADD 'A' -#define MENU_SEARCH_KEY_REMOVE 'D' -#define MENU_SEARCH_KEY_VIEW 'V' -#define MENU_SEARCH_KEY_DOWNLOAD 'G' +#define MENU_SEARCH_KEY_ADD 'a' +#define MENU_SEARCH_KEY_REMOVE 'd' +#define MENU_SEARCH_KEY_VIEW 'v' +#define MENU_SEARCH_KEY_DOWNLOAD 'g' -#define MENU_FRIENDS_KEY_ADD 'A' -#define MENU_FRIENDS_KEY_VIEW 'V' -#define MENU_FRIENDS_KEY_REMOVE 'D' -#define MENU_FRIENDS_KEY_CHAT 'C' +#define MENU_FRIENDS_KEY_ADD 'a' +#define MENU_FRIENDS_KEY_VIEW 'v' +#define MENU_FRIENDS_KEY_REMOVE 'd' +#define MENU_FRIENDS_KEY_CHAT 'c' -#define MENU_TOPLEVEL_KEY_FRIENDS 'F' -#define MENU_TOPLEVEL_KEY_NETWORK 'W' -#define MENU_TOPLEVEL_KEY_TRANSFER 'D' -#define MENU_TOPLEVEL_KEY_SEARCH 'S' -#define MENU_TOPLEVEL_KEY_FORUMS 'O' +#define MENU_TOPLEVEL_KEY_FRIENDS 'f' +#define MENU_TOPLEVEL_KEY_NETWORK 'w' +#define MENU_TOPLEVEL_KEY_TRANSFER 'd' +#define MENU_TOPLEVEL_KEY_SEARCH 's' +#define MENU_TOPLEVEL_KEY_FORUMS 'o' Menu *CreateMenuStructure(NotifyTxt *notify) @@ -199,7 +199,7 @@ int MenuListTransfer::getEntryDesc(int idx, std::string &desc) return 0; } - float frac = (float) info.transfered / info.size; + float frac = 100.0 * (float) info.transfered / info.size; if (frac != 1.0) { @@ -335,6 +335,13 @@ int MenuListSearch::removeSearch(std::string strSearchId) return 1; } +uint32_t MenuOpSearchNew::drawPage(uint32_t drawFlags, std::string &buffer) +{ + buffer += "Enter New Search Term > "; + return 1; +} + + uint32_t MenuOpSearchNew::process_lines(std::string input) { diff --git a/retroshare-nogui/src/menu/menus.h b/retroshare-nogui/src/menu/menus.h index 61a26639e..44806a013 100644 --- a/retroshare-nogui/src/menu/menus.h +++ b/retroshare-nogui/src/menu/menus.h @@ -139,6 +139,9 @@ class MenuOpSearchNew: public MenuOpLineInput MenuOpSearchNew() :MenuOpLineInput("New") { return; } virtual uint32_t process_lines(std::string input); + virtual uint32_t drawPage(uint32_t drawFlags, std::string &buffer); + + }; diff --git a/retroshare-nogui/src/menu/menutest.h b/retroshare-nogui/src/menu/menutest.h index 8ff9ef732..94c58d4ee 100644 --- a/retroshare-nogui/src/menu/menutest.h +++ b/retroshare-nogui/src/menu/menutest.h @@ -15,7 +15,9 @@ int tick() { int c = mIn.get(); uint8_t key = (uint8_t) c; - mMenus->process(key); + uint32_t drawFlags = 0; + std::string buffer; + mMenus->process(key, drawFlags, buffer); return 1; } @@ -28,5 +30,65 @@ private: std::ostream &mOut; }; +#include +#include +#include "rstermserver.h" + +class RsConsole +{ + public: + + RsConsole(RsTermServer *s, int infd, int outfd) + :mServer(s), mIn(infd), mOut(outfd) + { + const int fcflags = fcntl(mIn,F_GETFL); + if (fcflags < 0) + { + std::cerr << "RsConsole() ERROR getting fcntl FLAGS"; + std::cerr << std::endl; + exit(1); + } + if (fcntl(mIn,F_SETFL,fcflags | O_NONBLOCK) <0) + { + std::cerr << "RsConsole() ERROR setting fcntl FLAGS"; + std::cerr << std::endl; + exit(1); + } + } + + int tick() + { + char buf; + std::string output; + int size = read(mIn, &buf, 1); + + bool haveInput = (size > 0); + + int rt = mServer->tick(haveInput, buf, output); + + if (output.size() > 0) + { + write(mOut, output.c_str(), output.size()); + } + + if (rt < 0) + { + std::cerr << "Exit Request"; + exit(1); + } + + if (!haveInput) + { + return 0; + } + + return 1; + } + +private: + + RsTermServer *mServer; + int mIn, mOut; +}; diff --git a/retroshare-nogui/src/retroshare-nogui.pro b/retroshare-nogui/src/retroshare-nogui.pro index 5c72ab734..c4822441a 100644 --- a/retroshare-nogui/src/retroshare-nogui.pro +++ b/retroshare-nogui/src/retroshare-nogui.pro @@ -2,7 +2,7 @@ TEMPLATE = app TARGET = retroshare-nogui CONFIG += bitdht #CONFIG += introserver -#CONFIG += sshserver +CONFIG += sshserver CONFIG += debug debug { @@ -23,6 +23,7 @@ linux-* { LIBS += ../../libretroshare/src/lib/libretroshare.a LIBS += ../../openpgpsdk/src/lib/libops.a -lbz2 LIBS += -lssl -lupnp -lixml -lgnome-keyring + LIBS += -lsqlite3 } linux-g++ { @@ -134,10 +135,12 @@ sshserver { # # You can connect from a standard ssh, eg: ssh -p 7022 127.0.0.1 # - # The Menu system is available from the command-line now, - # but not over SSH yet... + # The Menu system is available from the command-line (-T) and SSH (-S) # if it get covered by debug gunk, just press to refresh. # + # ./retroshare-nogui -h provides some more instructions. + # + INCLUDEPATH += ../../../lib/libssh-0.5.2/include/ LIBS += ../../../lib/libssh-0.5.2/build/src/libssh.a LIBS += ../../../lib/libssh-0.5.2/build/src/threads/libssh_threads.a @@ -146,6 +149,7 @@ sshserver { HEADERS += menu/menu.h \ menu/menus.h \ + rstermserver.h \ SOURCES += menu/menu.cc \ menu/menus.cc \ diff --git a/retroshare-nogui/src/retroshare.cc b/retroshare-nogui/src/retroshare.cc index 0f67cd33d..917511cce 100644 --- a/retroshare-nogui/src/retroshare.cc +++ b/retroshare-nogui/src/retroshare.cc @@ -82,8 +82,198 @@ int main(int argc, char **argv) * LoadPassword(...) set password for existing certificate. **/ + bool strictCheck = true; + +#ifdef RS_SSH_SERVER + /* parse commandline for additional nogui options */ + + int c; + // libretroshare's getopt str - so don't use any of these: "hesamui:p:c:w:l:d:U:r:R:" + // need options for + // enable SSH. (-S) + // set user/password for SSH. -L "user:pwdhash" + // accept RSA Key Auth. -K "RsaPubKeyFile" + // Terminal mode. -T + bool enableSsh = false; + bool enableSshHtml = false; + bool enableSshPwd = false; + bool enableTerminal = false; + bool enableSshRsa = false; + bool genPwdHash = false; + std::string sshUser = "user"; + std::string sshPwdHash = ""; + std::string sshRsaFile = ""; + std::string sshPortStr = "7022"; + + while((c = getopt(argc, argv,"hTL:P:K:GS::")) != -1) + { + switch(c) + { + case 'S': + enableSsh = true; + if (optarg) + { + sshPortStr = optarg; // optional. + } + strictCheck = false; + break; + case 'H': + enableSshHtml = true; + strictCheck = false; + break; + case 'T': + enableTerminal = true; + strictCheck = false; + break; + case 'L': + sshUser = optarg; + strictCheck = false; + break; + case 'P': + enableSshPwd = true; + sshPwdHash = optarg; + strictCheck = false; + break; +#if 0 // NOT FINISHED YET. + case 'K': + enableSshRsa = true; + sshRsaFile = optarg; + strictCheck = false; + break; +#endif + case 'G': + genPwdHash = true; + break; + case 'h': + /* nogui help */ + std::cerr << argv[0] << std::endl; + std::cerr << "Specific Help Options: " << std::endl; + std::cerr << "\t-G Generate a Password Hash for SSH Server" << std::endl; + std::cerr << "\t-T Enable Terminal Interface" << std::endl; + std::cerr << "\t-S [port] Enable SSH Server, optionally specify port" << std::endl; + std::cerr << "\t-L Specify SSH login user (default:user)" << std::endl; + std::cerr << "\t-P Enable SSH login via Password" << std::endl; + //std::cerr << "\t-K [rsapubkeyfile] Enable SSH login via RSA key" << std::endl; + //std::cerr << "\t NB: Two Factor Auth, specify both -P & -K" << std::endl; + std::cerr << std::endl; + std::cerr << "\t To setup rs-nogui as a SSH Server is a three step process: " << std::endl; + std::cerr << "\t 1) \"ssh-keygen -t rsa -f rs_ssh_host_rsa_key\" " << std::endl; + std::cerr << "\t 2) \"./retroshare-nogui -G\" " << std::endl; + std::cerr << "\t 3) \"./retroshare-nogui -S [port] -L -P \" " << std::endl; + std::cerr << std::endl; + std::cerr << "Further Options "; + /* libretroshare will call exit(1) after printing its options */ + break; + + default: + /* let others through - for libretroshare */ + break; + } + } + // reset optind for Retroshare commandline arguments. + optind = 1; + + if (genPwdHash) + { + std::string saltBin; + std::string pwdHashRadix64; + std::string sshPwdForHash = ""; + + std::cout << "Type in your Password:" << std::flush; + char pwd[1024]; + if (!fgets(pwd, 1024, stdin)) + { + std::cerr << "Error Reading Password"; + std::cerr << std::endl; + exit(1); + } + + // strip newline. + for(int i = 0; (i < 1024) && (pwd[i] != '\n') && (pwd[i] != '\0'); i++) + { + sshPwdForHash += pwd[i]; + } + + std::cerr << "Chosen Password : " << sshPwdForHash; + std::cerr << std::endl; + + + GenerateSalt(saltBin); + if (!GeneratePasswordHash(saltBin, sshPwdForHash, pwdHashRadix64)) + { + std::cerr << "Error Generating Password Hash, password probably too short"; + std::cerr << pwdHashRadix64; + std::cerr << std::endl; + exit(1); + } + + std::cout << "Generated Password Hash for rs-nogui: "; + std::cout << pwdHashRadix64; + std::cout << std::endl; + std::cout << std::endl; + + /* checking match */ + if (CheckPasswordHash(pwdHashRadix64, sshPwdForHash)) + { + std::cerr << "Passed Check Okay!"; + std::cerr << std::endl; + } + else + { + std::cerr << "ERROR: Failed CheckPassword!"; + std::cerr << std::endl; + exit(1); + } + + + std::cerr << "Usage: ./retroshare-nogui -S [port] -L -P " << pwdHashRadix64; + std::cerr << std::endl; + exit(1); + } + + + /* enforce conditions */ + if (((enableSshRsa) || (enableSshPwd)) && (!enableSsh)) + { + std::cerr << "ERROR: SSH Server (-S) must be enabled to specify SSH Pwd (-P) or SSH RSA (-K)"; + std::cerr << std::endl; + exit(1); + } + + if (enableSsh && (!enableSshRsa) && (!enableSshPwd)) + { + std::cerr << "ERROR: One of (or both) SSH Pwd (-P) and SSH RSA (-K) must be specified with SSH Server (-S)"; + std::cerr << std::endl; + exit(1); + } + + + /* parse -S, -L & -K parameters */ + if (enableSshRsa) + { + /* check the file exists */ + /* TODO */ + + } + + if (enableSsh) + { + /* try parse it */ + /* TODO */ + + } + + if (enableSshPwd) + { + /* try parse it */ + /* TODO */ + + } +#endif + + RsInit::InitRsConfig(); - int initResult = RsInit::InitRetroShare(argc, argv); + int initResult = RsInit::InitRetroShare(argc, argv, strictCheck); if (initResult < 0) { /* Error occured */ @@ -143,8 +333,25 @@ int main(int argc, char **argv) #ifdef RS_SSH_SERVER // Says it must be called before all the threads are launched! */ // NB: this port number is not currently used. - RsSshd *ssh = RsSshd::InitRsSshd(22, "rs_ssh_host_rsa_key"); - ssh->adduser("anrsuser", "test"); + RsSshd *ssh = NULL; + + if (enableSsh) + { + ssh = RsSshd::InitRsSshd(sshPortStr, "rs_ssh_host_rsa_key"); + // TODO Parse Option + if (enableSshRsa) + { + //ssh->adduser("anrsuser", "test"); + } + + if (enableSshPwd) + { + ssh->adduserpwdhash(sshUser, sshPwdHash); + } + + } + + #endif /* Start-up libretroshare server threads */ @@ -155,11 +362,30 @@ int main(int argc, char **argv) #endif #ifdef RS_SSH_SERVER - ssh->start(); + uint32_t baseDrawFlags = 0; + if (enableSshHtml) + baseDrawFlags = MENU_DRAW_FLAGS_HTML; + + if (enableSsh) + { + /* create menu system for SSH */ + Menu *baseMenu = CreateMenuStructure(notify); + MenuInterface *menuInterface = new MenuInterface(baseMenu, baseDrawFlags | MENU_DRAW_FLAGS_ECHO); + ssh->setTermServer(menuInterface); + + ssh->start(); + } + + //MenuTest *menuTerminal = NULL; + RsConsole *menuTerminal = NULL; + if (enableTerminal) + { + /* Terminal Version */ + Menu *baseMenu = CreateMenuStructure(notify); + MenuInterface *menuInterface = new MenuInterface(baseMenu, baseDrawFlags | MENU_DRAW_FLAGS_NOQUIT); + menuTerminal = new RsConsole(menuInterface, fileno(stdin), fileno(stdout)); + } - Menu *baseMenu = CreateMenuStructure(notify); - MenuInterface *menuInterface = new MenuInterface(baseMenu); - MenuTest menuTest(menuInterface, std::cin, std::cout); #endif @@ -167,20 +393,30 @@ int main(int argc, char **argv) while(1) { //std::cerr << "GUI Tick()" << std::endl; -#ifndef WINDOWS_SYS - sleep(1); -#else - Sleep(1000); -#endif #ifdef RS_INTRO_SERVER rsIS.tick(); #endif + int rt = 0; #ifdef RS_SSH_SERVER - menuTest.tick(); + if (menuTerminal) + { + rt = menuTerminal->tick(); + } #endif + // If we have a MenuTerminal ... + // only want to sleep if there is no input. (rt == 0). + if (rt == 0) + { +#ifndef WINDOWS_SYS + sleep(1); +#else + Sleep(1000); +#endif + } + } return 1; } diff --git a/retroshare-nogui/src/rstermserver.h b/retroshare-nogui/src/rstermserver.h new file mode 100644 index 000000000..2658e8c93 --- /dev/null +++ b/retroshare-nogui/src/rstermserver.h @@ -0,0 +1,13 @@ +#ifndef RS_TERM_SERVER_H +#define RS_TERM_SERVER_H + +class RsTermServer +{ +public: + /* this must be regularly ticked to update the display */ + virtual void reset() = 0; + virtual int tick(bool haveInput, char keypress, std::string &output) = 0; +}; + + +#endif // RS_TERM_SERVER_H diff --git a/retroshare-nogui/src/ssh/rssshd.cc b/retroshare-nogui/src/ssh/rssshd.cc index 493151a0d..0d486d43f 100644 --- a/retroshare-nogui/src/ssh/rssshd.cc +++ b/retroshare-nogui/src/ssh/rssshd.cc @@ -30,12 +30,12 @@ clients must be made or how a client should react. RsSshd *rsSshd = NULL; // External Reference Variable. // NB: This must be called EARLY before all the threads are launched. -RsSshd *RsSshd::InitRsSshd(uint16_t port, std::string rsakeyfile) +RsSshd *RsSshd::InitRsSshd(std::string portStr, std::string rsakeyfile) { ssh_threads_set_callbacks(ssh_threads_get_pthread()); ssh_init(); - rsSshd = new RsSshd(port); + rsSshd = new RsSshd(portStr); if (rsSshd->init(rsakeyfile)) { return rsSshd; @@ -46,12 +46,13 @@ RsSshd *RsSshd::InitRsSshd(uint16_t port, std::string rsakeyfile) } -RsSshd::RsSshd(uint16_t port) -:mSshMtx("sshMtx"), mPort(port), mChannel(0) +RsSshd::RsSshd(std::string portStr) +:mSshMtx("sshMtx"), mPortStr(portStr), mChannel(0) { mState = RSSSHD_STATE_NULL; mBindState = 0; + mTermServer = NULL; return; } @@ -62,13 +63,12 @@ int RsSshd::init(std::string pathrsakey) { mBind=ssh_bind_new(); - mSession=ssh_new(); //ssh_bind_options_set(mBind, SSH_BIND_OPTIONS_DSAKEY, KEYS_FOLDER "ssh_host_dsa_key"); //ssh_bind_options_set(mBind, SSH_BIND_OPTIONS_RSAKEY, KEYS_FOLDER "ssh_host_rsa_key"); //ssh_bind_options_set(mBind, SSH_BIND_OPTIONS_BINDPORT_STR, arg); - ssh_bind_options_set(mBind, SSH_BIND_OPTIONS_BINDPORT_STR, "7022"); + ssh_bind_options_set(mBind, SSH_BIND_OPTIONS_BINDPORT_STR, mPortStr.c_str()); //ssh_bind_options_set(mBind, SSH_BIND_OPTIONS_DSAKEY, arg); //ssh_bind_options_set(mBind, SSH_BIND_OPTIONS_HOSTKEY, arg); ssh_bind_options_set(mBind, SSH_BIND_OPTIONS_RSAKEY, pathrsakey.c_str()); @@ -136,6 +136,7 @@ int RsSshd::listenConnect() std::cerr << std::endl; } + mSession=ssh_new(); int r=ssh_bind_accept(mBind,mSession); if(r==SSH_ERROR) { @@ -188,7 +189,8 @@ int RsSshd::interactive() std::cerr << "RsSshd::interactive()"; std::cerr << std::endl; - doEcho(); + doTermServer(); + //doEcho(); return 1; } @@ -337,12 +339,74 @@ int RsSshd::doEcho() } +int RsSshd::setTermServer(RsTermServer *s) +{ + mTermServer = s; + return 1; +} + + + +int RsSshd::doTermServer() +{ + std::cerr << "RsSshd::doTermServer()"; + std::cerr << std::endl; + + if (!mTermServer) + { + std::cerr << "RsSshd::doTermServer() ERROR Not Set"; + std::cerr << std::endl; + return 0; + } + + mTermServer->reset(); // clear everything for new user. + + bool okay = true; + while(okay) + { + char buf; + int size = ssh_channel_read_nonblocking(mChannel, &buf, 1, 0); + bool haveInput = (size > 0); + std::string output; + + int rt = mTermServer->tick(haveInput, buf, output); + + if (output.size() > 0) + { + ssh_channel_write(mChannel, output.c_str(), output.size()); + } + + if (!haveInput) + { + /* have a little sleep */ + sleep(1); //0000000); // 1/10th sec. + //usleep(10000000); // 1/10th sec. + } + else + { + usleep(10000); // 1/100th sec. + } + + if (rt < 0) + { + okay = false; // exit. + } + } + + std::cerr << "RsSshd::doTermServer() Finished"; + std::cerr << std::endl; + + return 1; +} + + int RsSshd::cleanupSession() { std::cerr << "RsSshd::cleanupSession()"; std::cerr << std::endl; ssh_disconnect(mSession); + ssh_free(mSession); return 1; } @@ -433,15 +497,17 @@ int RsSshd::auth_password_basic(char *name, char *pwd) } #endif // ALLOW_CLEARPWDS -#define RSSSHD_HASH_PWD_LENGTH 40 +//#define RSSSHD_HASH_PWD_LENGTH 40 int RsSshd::adduserpwdhash(std::string username, std::string hash) { +#if 0 if (hash.length() != RSSSHD_HASH_PWD_LENGTH) { std::cerr << "RsSshd::adduserpwdhash() Hash Wrong Length"; return 0; } +#endif if (username.length() < RSSSHD_MIN_USERNAME) { @@ -464,21 +530,18 @@ int RsSshd::adduserpwdhash(std::string username, std::string hash) int RsSshd::auth_password_hashed(char *name, char *pwd) { - std::cerr << "RsSshd::auth_password_hashed() Not Finished Yet!"; - return 0; - std::string username(name); std::string password(pwd); std::map::iterator it; - it = mPasswords.find(username); - if (it == mPasswords.end()) + it = mPwdHashs.find(username); + if (it == mPwdHashs.end()) { std::cerr << "RsSshd::auth_password_hashed() Unknown username"; return 0; } - if (it->second == password) + if (CheckPasswordHash(it->second, password)) { std::cerr << "RsSshd::auth_password_hashed() logged in " << username; return 1; @@ -488,4 +551,161 @@ int RsSshd::auth_password_hashed(char *name, char *pwd) return 0; } +#include "util/radix64.h" +#include "util/rsrandom.h" +#include + +#define RSSSHD_PWD_SALT_LEN 16 +#define RSSSHD_PWD_MIN_LEN 8 + + +#if 0 +int printHex(const char *data, int len) +{ + for(int i = 0; i < len; i++) + { + fprintf(stderr, "%02x", (uint8_t) data[i]); + } + return 1; +} +#endif + + + +int GenerateSalt(std::string &saltBin) +{ + /* get from random */ + for(int i = 0; i < RSSSHD_PWD_SALT_LEN / 4; i++) + { + uint32_t rnd = RSRandom::random_u32(); + saltBin += ((char *) &rnd)[0]; + saltBin += ((char *) &rnd)[1]; + saltBin += ((char *) &rnd)[2]; + saltBin += ((char *) &rnd)[3]; + } + +#if 0 + std::cerr << "HexSalt: "; + printHex(saltBin.c_str(), saltBin.size()); + std::cerr << std::endl; +#endif + + return 1; +} + +int GeneratePasswordHash(std::string saltBin, std::string password, std::string &pwdHashRadix64) +{ +#if 0 + std::cerr << "GeneratePasswordHash()"; + std::cerr << std::endl; + + std::cerr << "HexSalt: "; + printHex(saltBin.c_str(), saltBin.size()); + std::cerr << std::endl; +#endif + + if (saltBin.size() != RSSSHD_PWD_SALT_LEN) + { + return 0; + } + + if (password.size() < RSSSHD_PWD_MIN_LEN) + { + return 0; + } + + EVP_MD_CTX *ctx = EVP_MD_CTX_create(); + EVP_DigestInit(ctx, EVP_sha256()); + + EVP_DigestUpdate(ctx, saltBin.c_str(), saltBin.size()); + EVP_DigestUpdate(ctx, password.c_str(), password.size()); + + + unsigned char hash[1024]; + unsigned int s = 1024 - RSSSHD_PWD_SALT_LEN; + + for(int i = 0; i < RSSSHD_PWD_SALT_LEN; i++) + { + hash[i] = saltBin[i]; + } + + EVP_DigestFinal(ctx, &(hash[RSSSHD_PWD_SALT_LEN]), &s); + + Radix64::encode((char *)hash, s + RSSSHD_PWD_SALT_LEN, pwdHashRadix64); + +#if 0 + std::cerr << "Salt Length: " << RSSSHD_PWD_SALT_LEN; + std::cerr << std::endl; + std::cerr << "Hash Length: " << s; + std::cerr << std::endl; + std::cerr << "Total Length: " << s + RSSSHD_PWD_SALT_LEN; + std::cerr << std::endl; + + + std::cerr << "Encoded Length: " << pwdHashRadix64.size(); + std::cerr << std::endl; + + std::cerr << "GeneratePasswordHash() Output: " << pwdHashRadix64; + std::cerr << std::endl; +#endif + + return 1; +} + + +int CheckPasswordHash(std::string pwdHashRadix64, std::string password) +{ + char output[1024]; + char *buf = NULL; + size_t len = 1024; + Radix64::decode(pwdHashRadix64, buf, len); + for(int i = 0; (i < len) && (i < 1024); i++) + { + output[i] = buf[i]; + } + delete []buf; + +#if 0 + std::cerr << "CheckPasswordHash() Input: " << pwdHashRadix64; + std::cerr << std::endl; + std::cerr << "Decode Length: " << len; + std::cerr << std::endl; + std::cerr << "HexDecoded: "; + printHex(output, len); + std::cerr << std::endl; +#endif + + /* first N bytes are SALT */ + EVP_MD_CTX *ctx = EVP_MD_CTX_create(); + EVP_DigestInit(ctx, EVP_sha256()); + + EVP_DigestUpdate(ctx, output, RSSSHD_PWD_SALT_LEN); + EVP_DigestUpdate(ctx, password.c_str(), password.size()); + +#if 0 + std::cerr << "HexSalt: "; + printHex(output, RSSSHD_PWD_SALT_LEN); + std::cerr << std::endl; +#endif + + unsigned char hash[128]; + unsigned int s = 128; + EVP_DigestFinal(ctx, hash, &s); + + /* Final Comparison */ + if (s != len - RSSSHD_PWD_SALT_LEN) + { + std::cerr << "Length Mismatch"; + return 0; + } + + if (0 == strncmp(&(output[RSSSHD_PWD_SALT_LEN]), (char *) hash, s)) + { + return 1; + } + + return 0; +} + + diff --git a/retroshare-nogui/src/ssh/rssshd.h b/retroshare-nogui/src/ssh/rssshd.h index 48623b397..ef2be2709 100644 --- a/retroshare-nogui/src/ssh/rssshd.h +++ b/retroshare-nogui/src/ssh/rssshd.h @@ -34,6 +34,7 @@ clients must be made or how a client should react. #include #include +#include "rstermserver.h" #ifndef KEYS_FOLDER #ifdef _WIN32 @@ -53,17 +54,22 @@ clients must be made or how a client should react. -#define ALLOW_CLEARPWDS 1 +//#define ALLOW_CLEARPWDS 1 class RsSshd; extern RsSshd *rsSshd; + + // TODO: NB: THIS FN DOES NOT USE A "SLOW" HASH FUNCTION. + // THE FIRST HALF OF THE HASH STRING IS THE SALT +int CheckPasswordHash(std::string pwdHashRadix64, std::string password); +int GeneratePasswordHash(std::string saltBin, std::string password, std::string &pwdHashRadix64); +int GenerateSalt(std::string &saltBin); + class RsSshd: public RsThread { public: - // TODO: NB: THIS FN DOES NOT USE A "SLOW" HASH FUNCTION. - // THE FIRST HALF OF THE HASH STRING IS THE SALT int adduserpwdhash(std::string username, std::string hash); #ifdef ALLOW_CLEARPWDS int adduser(std::string username, std::string password); @@ -74,10 +80,13 @@ int adduser(std::string username, std::string password); virtual void run(); /* overloaded from RsThread => called once the thread is started */ // NB: This must be called EARLY before all the threads are launched. -static RsSshd *InitRsSshd(uint16_t port, std::string rsakeyfile); +static RsSshd *InitRsSshd(std::string portstr, std::string rsakeyfile); + + // Terminal Handling! +int setTermServer(RsTermServer *s); private: - RsSshd(uint16_t port); /* private constructor => so can only create with */ + RsSshd(std::string portStr); /* private constructor => so can only create with */ int init(std::string pathrsakey); @@ -92,6 +101,9 @@ int setupChannel(); int setupShell(); int doEcho(); + // Terminal Handling! +int doTermServer(); + int cleanupSession(); int cleanupAll(); @@ -109,11 +121,12 @@ int auth_password_basic(char *name, char *pwd); uint32_t mState; uint32_t mBindState; - uint16_t mPort; + std::string mPortStr; ssh_session mSession; ssh_bind mBind; ssh_channel mChannel; + RsTermServer *mTermServer; #ifdef ALLOW_CLEARPWDS std::map mPasswords; #endif // ALLOW_CLEARPWDS From 148d1310a2c8d93f0ea0d819a8089b6842639f42 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Fri, 10 Aug 2012 18:06:29 +0000 Subject: [PATCH 021/222] Added new button to open the link of the message in browser or copy the link of the message. Added "RSS: " for the forum feeds. Parse the feedburner:origLink in the rss feed. Moved download functions to a new class CURLWrapper for easy use. Added two new functions (currently only for local feeds for testing): - embed images into the message (works for Qt 4.7 and higher) - save complete web page git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5399 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- plugins/FeedReader/FeedReader.pro | 4 +- plugins/FeedReader/gui/AddFeedDialog.cpp | 32 +- plugins/FeedReader/gui/AddFeedDialog.h | 1 + plugins/FeedReader/gui/AddFeedDialog.ui | 31 +- plugins/FeedReader/gui/FeedReaderDialog.cpp | 60 ++- plugins/FeedReader/gui/FeedReaderDialog.h | 4 +- plugins/FeedReader/gui/FeedReaderDialog.ui | 22 +- plugins/FeedReader/gui/FeedReader_images.qrc | 1 + plugins/FeedReader/gui/images/Link.png | Bin 0 -> 2813 bytes plugins/FeedReader/interface/rsFeedReader.h | 6 +- plugins/FeedReader/services/p3FeedReader.cc | 181 +++++-- plugins/FeedReader/services/p3FeedReader.h | 5 +- .../FeedReader/services/p3FeedReaderThread.cc | 500 ++++++++++++------ .../FeedReader/services/p3FeedReaderThread.h | 6 +- .../FeedReader/services/rsFeedReaderItems.h | 4 +- .../FeedReader/services/util/CURLWrapper.cc | 136 +++++ .../FeedReader/services/util/CURLWrapper.h | 50 ++ 17 files changed, 806 insertions(+), 237 deletions(-) create mode 100644 plugins/FeedReader/gui/images/Link.png create mode 100644 plugins/FeedReader/services/util/CURLWrapper.cc create mode 100644 plugins/FeedReader/services/util/CURLWrapper.h diff --git a/plugins/FeedReader/FeedReader.pro b/plugins/FeedReader/FeedReader.pro index 64aaa1612..769797a66 100644 --- a/plugins/FeedReader/FeedReader.pro +++ b/plugins/FeedReader/FeedReader.pro @@ -6,6 +6,7 @@ SOURCES = FeedReaderPlugin.cpp \ services/p3FeedReader.cc \ services/p3FeedReaderThread.cc \ services/rsFeedReaderItems.cc \ + services/util/CURLWrapper.cc \ gui/FeedReaderDialog.cpp \ gui/AddFeedDialog.cpp \ gui/FeedReaderNotify.cpp \ @@ -16,6 +17,7 @@ HEADERS = FeedReaderPlugin.h \ services/p3FeedReader.h \ services/p3FeedReaderThread.h \ services/rsFeedReaderItems.h \ + services/util/CURLWrapper.h \ gui/FeedReaderDialog.h \ gui/AddFeedDialog.h \ gui/FeedReaderNotify.h \ @@ -39,7 +41,7 @@ linux-* { } win32 { - DEFINES += CURL_STATICLIB + DEFINES += CURL_STATICLIB LIBXML_STATIC CURL_DIR = ../../../curl-7.26.0 LIBXML2_DIR = ../../../libxml2-2.8.0 diff --git a/plugins/FeedReader/gui/AddFeedDialog.cpp b/plugins/FeedReader/gui/AddFeedDialog.cpp index 5013eaf5a..ac0b6106d 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.cpp +++ b/plugins/FeedReader/gui/AddFeedDialog.cpp @@ -46,12 +46,17 @@ AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, QWidget *parent) connect(ui->useStandardProxyCheckBox, SIGNAL(toggled(bool)), this, SLOT(useStandardProxyToggled())); connect(ui->typeForumRadio, SIGNAL(toggled(bool)), this, SLOT(typeForumToggled())); + /* currently only for loacl feeds */ + connect(ui->saveCompletePageCheckBox, SIGNAL(toggled(bool)), this, SLOT(denyForumToggled())); + connect(ui->embedImagesCheckBox, SIGNAL(toggled(bool)), this, SLOT(denyForumToggled())); + connect(ui->urlLineEdit, SIGNAL(textChanged(QString)), this, SLOT(validate())); connect(ui->nameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(validate())); connect(ui->useInfoFromFeedCheckBox, SIGNAL(toggled(bool)), this, SLOT(validate())); + connect(ui->typeLocalRadio, SIGNAL(toggled(bool)), this, SLOT(validate())); + connect(ui->typeForumRadio, SIGNAL(toggled(bool)), this, SLOT(validate())); ui->activatedCheckBox->setChecked(true); - ui->typeLocalRadio->setChecked(true); ui->forumComboBox->setEnabled(false); ui->useInfoFromFeedCheckBox->setChecked(true); ui->updateForumInfoCheckBox->setEnabled(false); @@ -124,6 +129,16 @@ void AddFeedDialog::typeForumToggled() ui->updateForumInfoCheckBox->setEnabled(checked); } +void AddFeedDialog::denyForumToggled() +{ + if (ui->saveCompletePageCheckBox->isChecked() || ui->embedImagesCheckBox->isChecked()) { + ui->typeForumRadio->setEnabled(false); + ui->typeLocalRadio->setChecked(true); + } else { + ui->typeForumRadio->setEnabled(true); + } +} + void AddFeedDialog::validate() { bool ok = true; @@ -134,6 +149,9 @@ void AddFeedDialog::validate() if (ui->nameLineEdit->text().isEmpty() && !ui->useInfoFromFeedCheckBox->isChecked()) { ok = false; } + if (!ui->typeLocalRadio->isChecked() && !ui->typeForumRadio->isChecked()) { + ok = false; + } ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(ok); } @@ -196,6 +214,8 @@ bool AddFeedDialog::fillFeed(const std::string &feedId) ui->useInfoFromFeedCheckBox->setChecked(feedInfo.flag.infoFromFeed); ui->updateForumInfoCheckBox->setChecked(feedInfo.flag.updateForumInfo); ui->activatedCheckBox->setChecked(!feedInfo.flag.deactivated); + ui->embedImagesCheckBox->setChecked(feedInfo.flag.embedImages); + ui->saveCompletePageCheckBox->setChecked(feedInfo.flag.saveCompletePage); ui->descriptionPlainTextEdit->setPlainText(QString::fromUtf8(feedInfo.description.c_str())); @@ -206,6 +226,8 @@ bool AddFeedDialog::fillFeed(const std::string &feedId) if (feedInfo.flag.forum) { ui->typeForumRadio->setChecked(true); + ui->saveCompletePageCheckBox->setEnabled(false); + ui->embedImagesCheckBox->setEnabled(false); if (feedInfo.forumId.empty()) { ui->forumNameLabel->setText(tr("Not yet created")); @@ -259,13 +281,17 @@ void AddFeedDialog::createFeed() feedInfo.flag.infoFromFeed = ui->useInfoFromFeedCheckBox->isChecked(); feedInfo.flag.updateForumInfo = ui->updateForumInfoCheckBox->isChecked() && ui->updateForumInfoCheckBox->isEnabled(); feedInfo.flag.deactivated = !ui->activatedCheckBox->isChecked(); + feedInfo.flag.embedImages = ui->embedImagesCheckBox->isChecked(); + feedInfo.flag.saveCompletePage = ui->saveCompletePageCheckBox->isChecked(); feedInfo.description = ui->descriptionPlainTextEdit->toPlainText().toUtf8().constData(); feedInfo.flag.forum = ui->typeForumRadio->isChecked(); if (mFeedId.empty()) { - /* set forum (only when create a new feed) */ - feedInfo.forumId = ui->forumComboBox->itemData(ui->forumComboBox->currentIndex()).toString().toStdString(); + if (feedInfo.flag.forum) { + /* set forum (only when create a new feed) */ + feedInfo.forumId = ui->forumComboBox->itemData(ui->forumComboBox->currentIndex()).toString().toStdString(); + } } feedInfo.flag.authentication = ui->useAuthenticationCheckBox->isChecked(); diff --git a/plugins/FeedReader/gui/AddFeedDialog.h b/plugins/FeedReader/gui/AddFeedDialog.h index c117cd789..f08d64611 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.h +++ b/plugins/FeedReader/gui/AddFeedDialog.h @@ -50,6 +50,7 @@ private slots: void useStandardUpdateIntervalToggled(); void useStandardProxyToggled(); void typeForumToggled(); + void denyForumToggled(); void validate(); void createFeed(); diff --git a/plugins/FeedReader/gui/AddFeedDialog.ui b/plugins/FeedReader/gui/AddFeedDialog.ui index ed2587dfa..b09be53a8 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.ui +++ b/plugins/FeedReader/gui/AddFeedDialog.ui @@ -7,7 +7,7 @@ 0 0 715 - 559 + 605 @@ -289,13 +289,6 @@ p, li { white-space: pre-wrap; } 6 - - - - Local Feed - - - @@ -323,6 +316,13 @@ p, li { white-space: pre-wrap; } + + + + Local Feed + + + @@ -366,6 +366,20 @@ p, li { white-space: pre-wrap; } + + + + Embed images (experimental for local feeds) + + + + + + + Save complete web page (experimental for local feeds) + + + @@ -416,7 +430,6 @@ p, li { white-space: pre-wrap; } urlLineEdit nameLineEdit descriptionPlainTextEdit - typeLocalRadio typeForumRadio forumComboBox activatedCheckBox diff --git a/plugins/FeedReader/gui/FeedReaderDialog.cpp b/plugins/FeedReader/gui/FeedReaderDialog.cpp index d93bf83b8..ef4438e1a 100644 --- a/plugins/FeedReader/gui/FeedReaderDialog.cpp +++ b/plugins/FeedReader/gui/FeedReaderDialog.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include "FeedReaderDialog.h" #include "ui_FeedReaderDialog.h" @@ -118,6 +119,7 @@ FeedReaderDialog::FeedReaderDialog(RsFeedReader *feedReader, QWidget *parent) connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterItems(QString))); connect(ui->filterColumnComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterColumnChanged())); + connect(ui->linkButton, SIGNAL(clicked()), this, SLOT(openLinkMsg())); connect(ui->expandButton, SIGNAL(clicked()), this, SLOT(toggleMsgText())); mFeedCompareRole = new RSTreeWidgetItemCompareRole; @@ -168,6 +170,18 @@ FeedReaderDialog::FeedReaderDialog(RsFeedReader *feedReader, QWidget *parent) /* initialize feed list */ ui->feedTreeWidget->sortItems(COLUMN_FEED_NAME, Qt::AscendingOrder); + /* build menu for link button */ + QMenu *menu = new QMenu(this); + QAction *action = menu->addAction(tr("Open link in browser"), this, SLOT(openLinkMsg())); + menu->addAction(tr("Copy link to clipboard"), this, SLOT(copyLinkMsg())); + + QFont font = action->font(); + font.setBold(true); + action->setFont(font); + + ui->linkButton->setMenu(menu); + ui->linkButton->setEnabled(false); + ui->msgTreeWidget->installEventFilter(this); } @@ -351,7 +365,7 @@ void FeedReaderDialog::msgTreeCustomPopupMenu(QPoint /*point*/) contextMnu.addSeparator(); - action = contextMnu.addAction(QIcon(""), tr("Copy link"), this, SLOT(copyLinkMsg())); + action = contextMnu.addAction(QIcon(""), tr("Copy link"), this, SLOT(copyLinskMsg())); action->setEnabled(!selectedItems.empty()); action = contextMnu.addAction(QIcon(""), tr("Remove"), this, SLOT(removeMsg())); @@ -522,10 +536,14 @@ void FeedReaderDialog::updateFeedItem(QTreeWidgetItem *item, FeedInfo &info) case FeedInfo::WAITING: break; case FeedInfo::WAITING_TO_DOWNLOAD: + workState = tr("waiting for download"); + break; case FeedInfo::DOWNLOADING: - workState = tr("loading"); + workState = tr("downloading"); break; case FeedInfo::WAITING_TO_PROCESS: + workState = tr("waiting for process"); + break; case FeedInfo::PROCESSING: workState = tr("processing"); break; @@ -791,6 +809,7 @@ void FeedReaderDialog::msgItemChanged() ui->msgTitle->clear(); // ui->msgLink->clear(); ui->msgText->clear(); + ui->linkButton->setEnabled(false); return; } @@ -800,6 +819,7 @@ void FeedReaderDialog::msgItemChanged() ui->msgTitle->clear(); // ui->msgLink->clear(); ui->msgText->clear(); + ui->linkButton->setEnabled(false); return; } @@ -809,6 +829,7 @@ void FeedReaderDialog::msgItemChanged() ui->msgTitle->clear(); // ui->msgLink->clear(); ui->msgText->clear(); + ui->linkButton->setEnabled(false); return; } @@ -832,7 +853,8 @@ void FeedReaderDialog::msgItemChanged() ui->msgText->setHtml(msgTxt); ui->msgTitle->setText(QString::fromUtf8(msgInfo.title.c_str())); -// ui->msgLink->setHtml(RsHtml().formatText(NULL, QString::fromUtf8(msgInfo.link.c_str()), RSHTML_FORMATTEXT_EMBED_LINKS)); + + ui->linkButton->setEnabled(!msgInfo.link.empty()); } void FeedReaderDialog::setMsgAsReadUnread(QList &rows, bool read) @@ -1049,7 +1071,7 @@ void FeedReaderDialog::markAllAsReadMsg() setMsgAsReadUnread(items, true); } -void FeedReaderDialog::copyLinkMsg() +void FeedReaderDialog::copyLinksMsg() { QString links; @@ -1086,3 +1108,33 @@ void FeedReaderDialog::removeMsg() } mFeedReader->removeMsgs(feedId, msgIds); } + +void FeedReaderDialog::copyLinkMsg() +{ + QTreeWidgetItem *item = ui->msgTreeWidget->currentItem(); + if (!item) { + return; + } + + QString link = item->data(COLUMN_MSG_DATA, ROLE_MSG_LINK).toString(); + if (link.isEmpty()) { + return; + } + + QApplication::clipboard()->setText(link); +} + +void FeedReaderDialog::openLinkMsg() +{ + QTreeWidgetItem *item = ui->msgTreeWidget->currentItem(); + if (!item) { + return; + } + + QString link = item->data(COLUMN_MSG_DATA, ROLE_MSG_LINK).toString(); + if (link.isEmpty()) { + return; + } + + QDesktopServices::openUrl(QUrl(link)); +} diff --git a/plugins/FeedReader/gui/FeedReaderDialog.h b/plugins/FeedReader/gui/FeedReaderDialog.h index 1bb6c14b8..7eae19f3e 100644 --- a/plugins/FeedReader/gui/FeedReaderDialog.h +++ b/plugins/FeedReader/gui/FeedReaderDialog.h @@ -64,8 +64,10 @@ private slots: void markAsReadMsg(); void markAsUnreadMsg(); void markAllAsReadMsg(); - void copyLinkMsg(); + void copyLinksMsg(); void removeMsg(); + void openLinkMsg(); + void copyLinkMsg(); /* FeedReaderNotify */ void feedChanged(const QString &feedId, int type); diff --git a/plugins/FeedReader/gui/FeedReaderDialog.ui b/plugins/FeedReader/gui/FeedReaderDialog.ui index 95c076e29..7dbaeea91 100644 --- a/plugins/FeedReader/gui/FeedReaderDialog.ui +++ b/plugins/FeedReader/gui/FeedReaderDialog.ui @@ -268,8 +268,8 @@ border: 1px solid #CCCCCC;} - - + + @@ -289,7 +289,7 @@ border: 1px solid #CCCCCC;} - + QLabel#msgTitle{ @@ -305,7 +305,21 @@ background: white;} - + + + + + :/images/Link.png:/images/Link.png + + + QToolButton::MenuButtonPopup + + + true + + + + diff --git a/plugins/FeedReader/gui/FeedReader_images.qrc b/plugins/FeedReader/gui/FeedReader_images.qrc index 6acbedfab..e1a6c5918 100644 --- a/plugins/FeedReader/gui/FeedReader_images.qrc +++ b/plugins/FeedReader/gui/FeedReader_images.qrc @@ -8,6 +8,7 @@ images/FeedErrorOverlay.png images/FolderAdd.png images/FeedAdd.png + images/Link.png images/Update.png diff --git a/plugins/FeedReader/gui/images/Link.png b/plugins/FeedReader/gui/images/Link.png new file mode 100644 index 0000000000000000000000000000000000000000..8f8fd3bc1bbb57a5d28affaaa6837f5198fcb188 GIT binary patch literal 2813 zcmVPx#AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy24YJ`L;wH)0002_L%V+f000SaNLh0L002k;002k;M#*bF000V9 zNklqy?vji#xENkpn;NaAQL+@&i?JseQ~(jWbN zeBx`*@vnb;&quN=e%6KG{;Q|R;(k%e%kBLK-Qks$aHM784MwO%Bl1RBn0S6eP2Rb# z*NRG95ZHHQx_SN0wX>7erA7Yj_kQdDw6A}f;*m%HmP5k_d1v9D`%^i%qdDz;I&I9~ z-8K7e(wJUdrFqk6*-aHiL%Fp~7PS}KQn|C;#qo2eR}=iC=k(fBC}i ze6$Rde;@h0c#H#XQE%>h`j(>m`sZXic(@<)V=Kv0Yo&caC9zFaA3?Fm$zH->CV29k z=lZUV-h1EeZH+tK?bCyaeQYwT9<@b%QA!!U`K90g2?FYa2j_qJ7ui=GPdA&-pPIE# z|6%N2_|0Zk-PG1cGA~aEFFHacDMh-Uk(y&JOSoJnoUI@#Cqhi6w|OqDJXFryZ6d$6 zWZIY4rkAVryS{jLIQ{KsKb*jKz8fh&_7IKofZ32QJ}_>-@)h4d^I(#XIz7=5P4Ov| zxs8>4B-%-fjbxSeq{qNXE>((QNDw68AQmo$vKF-+wz30fjy5}k1(DhF7tZ1)Ial|U;V=7FMMv5Yp*{6fCRYX zfxltlFMfkf`Qpm1I{n3J>GXZ+{7$Nc7pX8}LEp&DS)b#rKtJ7&N>=IVoMjVe<{FhK zM2O%#gg^*_=_q5eK8M>lM0w?4Yw*T_hlg)BKfiqQWBqDS0^i;vaP;J#kDG?O-7^eN;)tXZU~6LJAEMna4P1W^hQf*2&h z8MJFrUGB5-N@H%i<$o=kcb}Zp1AXNFr}w_0Y$%#{Oc*_%AMs}AGq!nc$*8HA)f(#( z<}{>@A+;H^Emw$o87UeBp|Ku92m}uyMq-Q*BOwMN5noHjI}H+HIdXDW?oNhBc4o!H zwVJ$;cj8)h_)F+0JZq09I_vt6$C}%0Ec9erP&tDUlCE*A2ZapF2yqi_(VziLLu6nh zMIEr#V_g6r5I*94B=~@xDXzS>pTj4n-1h0~462Rn;+DH-d(#~M?(hEf+NnSNDmq4w zO6mEUyZkKleHpQv8Nzl*+L~#j$3=B3yYeUvmC_9X1I&D6TnB7naizsp4s1X=PjC_M z0?tNUB}f_*RBH#5j71xHxCrU(xBtPPJ)JF3X+$Iv7M%;nTveMeF_^8BWbP!{;Q*?` zmcNIo$Z6S%p^-=dHbAUB6c#_LsS5|CN7Vu9K(GN{2ZSt9$qtipKp6^z$yzb>KbI{| z+T^y<8)sjqzjAawSij(`lWNpKUps~m$8kwcZ8TMEP{oR>bQmKMLJ;D+1WHFWvDk@2 z7M@sms64KUxGK=-PiXaa@v+86PZ7(c@Os%v-L-1Er8|cX%Me`GJJ*U6h1}^tU4q)e zPnIZm6Jji|rJ%|c+DN3_>)^o#Lg}G!h^a+SEOF{#7N}>QYUarIRiGR;Xh!9f&FMr8 zhM_l|s#fRdtLR`IsAz(BDsDI7YM<)Rc}z5faUVaNq1YkTmTH<(CmN~bUib15QF}z` zQB#MXI^xt3CXQ<2s3(r`0IqIVq;bIJWXxJ&#dx4qIcuo3NsSIw6-AcSk?2Dq@#hwh z$q>JP7g-e48(mE8$T~Y%)x^mhq4vrkLqytusQ0oE3P+ea?ATI{EcMJ0MsQ)h!n+-& z)0$b)jDC`OS7<*uGml<-`+wr{t#^)u6jKC*nI>L5fG{OeO$eo@sugam5XK>NiO>=y zfe5&Wu%1|YLg{f6OEs#gCl+rlaby^tJ47We;3omKb}UNY7>8;$)32RCAHDY!#qMN7 zD!HyS$B9D5Sq9g-Fjpe-v!E)XOc1t*ta=FFKtzQgLWp~Bq4M}5V5g3HX7P1RjFwPJ z+?k`ONkmowIhuE*)fFq(hf1{2)u@2LrcCtPB=VEdi44GxQ>+rWeXmgNe+^~8sC{(Q z3i|rT2sXak`RxGLalhj)$`EkarljyN@N?j|BN(J+a%dNWq7QPgcTLET%&zqEAYxRwYs@t%-Bjm@d9R zQ4I;zUazmMrC^JqeV*9ZMh)f(lML_(;St&+l|yKU)B%|UR01j$!sNOTLi~rT?Y9n| zxOGyDXQ+PX6Nng*h;i0T8(EgznHt^Bj1pPDBFhxcZS0GQRWl*HF8IXE=JxL(J|w;o2L6 z?Zl|ViIK;Q7ABQ>Gz~#)4n>S^uiicqy?`JI1Z;B~J9ia#;1VpXW9VRfk0eV-n+a(n zA#10kO|yv*|5#V<(e7fmD8o^<-ulMgM0Dl+6C6ozCsuAGwAdC>+<;&OFO>E!Ok*wVy>*VC!Mob!dR#($!wl2Q@52qjh`Wtq(>#n}`z3@}V^1B}R6QYlq z(Bc89`LdGglvJ`U=ch8BI3Im~iiSba&D5FcB(neQl-Wg=g-l=q|4!DhAqN*|N z6qR;RIwv2kl5F2V66Z0dgKnll7+IF(=eXTl~ zPzh1Q+J$nroDMc7o0l&QufKD(*xA@5_~H8;Pk @@ -68,6 +68,8 @@ public: flag.deactivated = false; flag.forum = false; flag.updateForumInfo = false; + flag.embedImages = false; + flag.saveCompletePage = false; } std::string feedId; @@ -98,6 +100,8 @@ public: bool deactivated : 1; bool forum : 1; bool updateForumInfo : 1; + bool embedImages : 1; + bool saveCompletePage : 1; } flag; }; diff --git a/plugins/FeedReader/services/p3FeedReader.cc b/plugins/FeedReader/services/p3FeedReader.cc index 0ae7f6ec0..76b16ea65 100644 --- a/plugins/FeedReader/services/p3FeedReader.cc +++ b/plugins/FeedReader/services/p3FeedReader.cc @@ -30,6 +30,7 @@ RsFeedReader *rsFeedReader = NULL; #define FEEDREADER_CLEAN_INTERVAL 1 * 60 * 60 // check every hour +#define FEEDREADER_FORUM_PREFIX L"RSS: " /********* * #define FEEDREADER_DEBUG @@ -91,6 +92,8 @@ static void feedToInfo(const RsFeedReaderFeed *feed, FeedInfo &info) info.flag.deactivated = (feed->flag & RS_FEED_FLAG_DEACTIVATED); info.flag.forum = (feed->flag & RS_FEED_FLAG_FORUM); info.flag.updateForumInfo = (feed->flag & RS_FEED_FLAG_UPDATE_FORUM_INFO); + info.flag.embedImages = (feed->flag & RS_FEED_FLAG_EMBED_IMAGES); + info.flag.saveCompletePage = (feed->flag & RS_FEED_FLAG_SAVE_COMPLETE_PAGE); switch (feed->workstate) { case RsFeedReaderFeed::WAITING: @@ -151,6 +154,12 @@ static void infoToFeed(const FeedInfo &info, RsFeedReaderFeed *feed, bool add) if (info.flag.deactivated) { feed->flag |= RS_FEED_FLAG_DEACTIVATED; } + if (info.flag.embedImages) { + feed->flag |= RS_FEED_FLAG_EMBED_IMAGES; + } + if (info.flag.saveCompletePage) { + feed->flag |= RS_FEED_FLAG_SAVE_COMPLETE_PAGE; + } if (add) { /* only set when adding a new feed */ if (info.flag.folder) { @@ -950,6 +959,11 @@ int p3FeedReader::tick() } else { updateInterval = fi->updateInterval; } + + if (updateInterval == 0) { + continue; + } + if (fi->lastUpdate == 0 || fi->lastUpdate + (long) updateInterval <= currentTime) { /* add to download list */ feedToDownload.push_back(fi->feedId); @@ -1340,7 +1354,6 @@ void p3FeedReader::onDownloadError(const std::string &feedId, p3FeedReaderThread case p3FeedReaderThread::DOWNLOAD_ERROR: fi->errorState = RS_FEED_ERRORSTATE_DOWNLOAD_ERROR; break; - case p3FeedReaderThread::DOWNLOAD_ERROR_INIT: case p3FeedReaderThread::DOWNLOAD_INTERNAL_ERROR: fi->errorState = RS_FEED_ERRORSTATE_DOWNLOAD_INTERNAL_ERROR; break; @@ -1428,15 +1441,13 @@ bool p3FeedReader::getFeedToProcess(RsFeedReaderFeed &feed) return true; } -void p3FeedReader::onProcessSuccess(const std::string &feedId, std::list &msgs) +bool p3FeedReader::onProcessSuccess_filterMsg(const std::string &feedId, std::list &msgs) { #ifdef FEEDREADER_DEBUG - std::cerr << "p3FeedReader::onProcessSuccess - feed " << feedId << " got " << msgs.size() << " messages" << std::endl; + std::cerr << "p3FeedReader::onProcessSuccess_filterMsg - feed " << feedId << " got " << msgs.size() << " messages" << std::endl; #endif - std::list addedMsgs; - std::string forumId; - std::list forumMsgs; + bool result = true; { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -1446,9 +1457,9 @@ void p3FeedReader::onProcessSuccess(const std::string &feedId, std::listsecond; @@ -1458,6 +1469,10 @@ void p3FeedReader::onProcessSuccess(const std::string &feedId, std::listforumId.empty()) { /* create new forum */ + std::wstring forumName; + librs::util::ConvertUtf8ToUtf16(fi->name, forumName); + forumName.insert(0, FEEDREADER_FORUM_PREFIX); + long todo; // search for existing forum? /* search for existing own forum */ @@ -1472,22 +1487,18 @@ void p3FeedReader::onProcessSuccess(const std::string &feedId, std::listname, forumName); std::wstring forumDescription; librs::util::ConvertUtf8ToUtf16(fi->description, forumDescription); /* create anonymous public forum */ fi->forumId = rsForums->createForum(forumName, forumDescription, RS_DISTRIB_PUBLIC | RS_DISTRIB_AUTHEN_ANON); - forumId = fi->forumId; - if (fi->forumId.empty()) { errorState = RS_FEED_ERRORSTATE_FORUM_CREATE; #ifdef FEEDREADER_DEBUG - std::cerr << "p3FeedReader::onProcessSuccess - can't create forum for feed " << feedId << " (" << it->second->name << ") - ignore all messages" << std::endl; + std::cerr << "p3FeedReader::onProcessSuccess_filterMsg - can't create forum for feed " << feedId << " (" << it->second->name << ") - ignore all messages" << std::endl; } else { - std::cerr << "p3FeedReader::onProcessSuccess - forum " << forumId << " (" << fi->name << ") created" << std::endl; + std::cerr << "p3FeedReader::onProcessSuccess_filterMsg - forum " << forumId << " (" << fi->name << ") created" << std::endl; #endif } } else { @@ -1498,8 +1509,6 @@ void p3FeedReader::onProcessSuccess(const std::string &feedId, std::listforumId; } } else { errorState = RS_FEED_ERRORSTATE_FORUM_NOT_FOUND; @@ -1508,15 +1517,11 @@ void p3FeedReader::onProcessSuccess(const std::string &feedId, std::list::iterator newMsgIt; for (newMsgIt = msgs.begin(); newMsgIt != msgs.end(); ) { RsFeedReaderMsg *miNew = *newMsgIt; - /* search for exisiting msg */ + /* search for existing msg */ std::map::iterator msgIt; for (msgIt = fi->mMsgs.begin(); msgIt != fi->mMsgs.end(); ++msgIt) { RsFeedReaderMsg *mi = msgIt->second; @@ -1525,38 +1530,103 @@ void p3FeedReader::onProcessSuccess(const std::string &feedId, std::listmMsgs.end()) { - /* add new msg */ - rs_sprintf(miNew->msgId, "%lu", mNextMsgId++); - if (forum) { - miNew->flag = RS_FEEDMSG_FLAG_DELETED; - forumMsgs.push_back(*miNew); -// miNew->description.clear(); - } else { - miNew->flag = RS_FEEDMSG_FLAG_NEW; - addedMsgs.push_back(miNew->msgId); - } - fi->mMsgs[miNew->msgId] = miNew; + if (msgIt != fi->mMsgs.end()) { + /* msg exists */ + delete(*newMsgIt); newMsgIt = msgs.erase(newMsgIt); - -#ifdef FEEDREADER_DEBUG - ++newMsgs; -#endif } else { - /* msg was updated */ ++newMsgIt; } + } + } else { + result = false; + } + + fi->content.clear(); + fi->errorState = errorState; + fi->errorString.clear(); + + IndicateConfigChanged(); + } + + if (mNotify) { + mNotify->feedChanged(feedId, NOTIFY_TYPE_MOD); + } + + return result; +} + +void p3FeedReader::onProcessSuccess_addMsgs(const std::string &feedId, bool result, std::list &msgs) +{ #ifdef FEEDREADER_DEBUG - std::cerr << "p3FeedReader::onProcessSuccess - feed " << fi->feedId << " (" << fi->name << ") added " << newMsgs << "/" << msgs.size() << " messages" << std::endl; + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - feed " << feedId << " got " << msgs.size() << " messages" << std::endl; +#endif + + std::list addedMsgs; + std::string forumId; + std::list forumMsgs; + + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + /* find feed */ + std::map::iterator it = mFeeds.find(feedId); + if (it == mFeeds.end()) { + /* feed not found */ +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - feed " << feedId << " not found" << std::endl; +#endif + return; + } + + RsFeedReaderFeed *fi = it->second; + bool forum = (fi->flag & RS_FEED_FLAG_FORUM); + + if (forum) { + forumId = fi->forumId; + if (forumId.empty()) { + /* don't process messages without forum id */ + result = false; +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - feed " << fi->feedId << " (" << fi->name << ") don't process messages without forum id" << std::endl; #endif } } + /* process msgs */ +#ifdef FEEDREADER_DEBUG + uint32_t newMsgs = 0; +#endif + + if (result) { + std::list::iterator newMsgIt; + for (newMsgIt = msgs.begin(); newMsgIt != msgs.end(); ) { + RsFeedReaderMsg *miNew = *newMsgIt; + /* add new msg */ + rs_sprintf(miNew->msgId, "%lu", mNextMsgId++); + if (forum) { + miNew->flag = RS_FEEDMSG_FLAG_DELETED; + forumMsgs.push_back(*miNew); +// miNew->description.clear(); + } else { + miNew->flag = RS_FEEDMSG_FLAG_NEW; + addedMsgs.push_back(miNew->msgId); + } + fi->mMsgs[miNew->msgId] = miNew; + newMsgIt = msgs.erase(newMsgIt); + +#ifdef FEEDREADER_DEBUG + ++newMsgs; +#endif + } +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - feed " << fi->feedId << " (" << fi->name << ") added " << newMsgs << "/" << msgs.size() << " messages" << std::endl; +#endif + } + fi->workstate = RsFeedReaderFeed::WAITING; fi->content.clear(); fi->lastUpdate = time(NULL); - fi->errorState = errorState; - fi->errorString.clear(); IndicateConfigChanged(); } @@ -1584,7 +1654,7 @@ void p3FeedReader::onProcessSuccess(const std::string &feedId, std::listsetMessageStatus(forumMsgInfo.forumId, forumMsgInfo.msgId, 0, FORUM_MSG_STATUS_MASK); } else { #ifdef FEEDREADER_DEBUG - std::cerr << "p3FeedReader::onProcessSuccess - can't add forum message " << mi.title << " for feed " << forumId << std::endl; + std::cerr << "p3FeedReader::onProcessSuccess_filterMsg - can't add forum message " << mi.title << " for feed " << forumId << std::endl; #endif } } @@ -1652,7 +1722,7 @@ void p3FeedReader::setFeedInfo(const std::string &feedId, const std::string &nam { bool changed = false; std::string forumId; - ForumInfo forumInfo; + ForumInfo forumInfoNew; { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -1683,11 +1753,12 @@ void p3FeedReader::setFeedInfo(const std::string &feedId, const std::string &nam changed = true; } - if (changed && (fi->flag & RS_FEED_FLAG_FORUM) && (fi->flag & RS_FEED_FLAG_UPDATE_FORUM_INFO) && !fi->forumId.empty()) { + if ((fi->flag & RS_FEED_FLAG_FORUM) && (fi->flag & RS_FEED_FLAG_UPDATE_FORUM_INFO) && !fi->forumId.empty()) { /* change forum too */ forumId = fi->forumId; - librs::util::ConvertUtf8ToUtf16(fi->name, forumInfo.forumName); - librs::util::ConvertUtf8ToUtf16(fi->description, forumInfo.forumDesc); + librs::util::ConvertUtf8ToUtf16(fi->name, forumInfoNew.forumName); + librs::util::ConvertUtf8ToUtf16(fi->description, forumInfoNew.forumDesc); + forumInfoNew.forumName.insert(0, FEEDREADER_FORUM_PREFIX); } } @@ -1700,10 +1771,22 @@ void p3FeedReader::setFeedInfo(const std::string &feedId, const std::string &nam } if (!forumId.empty()) { - /* name or description changed, update forum */ - if (!rsForums->setForumInfo(forumId, forumInfo)) { + ForumInfo forumInfo; + if (rsForums->getForumInfo(forumId, forumInfo)) { + if (forumInfo.forumName != forumInfoNew.forumName || forumInfo.forumDesc != forumInfoNew.forumDesc) { + /* name or description changed, update forum */ #ifdef FEEDREADER_DEBUG - std::cerr << "p3FeedReader::setFeed - can't change forum " << forumId << std::endl; + std::cerr << "p3FeedReader::setFeed - change forum " << forumId << std::endl; +#endif + if (!rsForums->setForumInfo(forumId, forumInfoNew)) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setFeed - can't change forum " << forumId << std::endl; +#endif + } + } + } else { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setFeed - can't get forum info " << forumId << std::endl; #endif } } diff --git a/plugins/FeedReader/services/p3FeedReader.h b/plugins/FeedReader/services/p3FeedReader.h index 2e62e16da..e4525a65b 100644 --- a/plugins/FeedReader/services/p3FeedReader.h +++ b/plugins/FeedReader/services/p3FeedReader.h @@ -19,7 +19,7 @@ * Boston, MA 02110-1301, USA. ****************************************************************/ - #ifndef P3_FEEDREADER +#ifndef P3_FEEDREADER #define P3_FEEDREADER #include "retroshare/rsplugin.h" @@ -71,7 +71,8 @@ public: bool getFeedToDownload(RsFeedReaderFeed &feed); void onDownloadSuccess(const std::string &feedId, const std::string &content, std::string &icon); void onDownloadError(const std::string &feedId, p3FeedReaderThread::DownloadResult result, const std::string &error); - void onProcessSuccess(const std::string &feedId, std::list &msgs); + bool onProcessSuccess_filterMsg(const std::string &feedId, std::list &msgs); + void onProcessSuccess_addMsgs(const std::string &feedId, bool result, std::list &msgs); void onProcessError(const std::string &feedId, p3FeedReaderThread::ProcessResult result); bool getFeedToProcess(RsFeedReaderFeed &feed); diff --git a/plugins/FeedReader/services/p3FeedReaderThread.cc b/plugins/FeedReader/services/p3FeedReaderThread.cc index cbc03fe8b..b95589c01 100644 --- a/plugins/FeedReader/services/p3FeedReaderThread.cc +++ b/plugins/FeedReader/services/p3FeedReaderThread.cc @@ -22,9 +22,11 @@ #include "p3FeedReaderThread.h" #include "rsFeedReaderItems.h" #include "util/rsstring.h" +#include "util/CURLWrapper.h" -#include #include +#include +#include #include enum FeedFormat { FORMAT_RSS, FORMAT_RDF }; @@ -32,6 +34,7 @@ enum FeedFormat { FORMAT_RSS, FORMAT_RDF }; /********* * #define FEEDREADER_DEBUG *********/ +#define FEEDREADER_DEBUG p3FeedReaderThread::p3FeedReaderThread(p3FeedReader *feedReader, Type type) : RsThread(), mFeedReader(feedReader), mType(type) { @@ -88,21 +91,34 @@ void p3FeedReaderThread::run() { RsFeedReaderFeed feed; if (mFeedReader->getFeedToProcess(feed)) { - std::list entries; + std::list msgs; std::string error; + std::list::iterator it; - ProcessResult result = process(feed, entries, error); + ProcessResult result = process(feed, msgs, error); if (result == PROCESS_SUCCESS) { - mFeedReader->onProcessSuccess(feed.feedId, entries); + /* first, filter the messages */ + bool result = mFeedReader->onProcessSuccess_filterMsg(feed.feedId, msgs); + if (isRunning()) { + if (result) { + long todo; // process new items + /* second, process the descriptions */ + for (it = msgs.begin(); it != msgs.end(); ++it) { + RsFeedReaderMsg *mi = *it; + processMsg(feed, mi); + } + } + /* third, add messages */ + mFeedReader->onProcessSuccess_addMsgs(feed.feedId, result, msgs); + } } else { mFeedReader->onProcessError(feed.feedId, result); } - std::list::iterator it; - for (it = entries.begin(); it != entries.end(); ++it) { + for (it = msgs.begin(); it != msgs.end(); ++it) { delete (*it); } - entries.clear(); + msgs.clear(); } } break; @@ -114,121 +130,110 @@ void p3FeedReaderThread::run() /****************************** Download ***********************************/ /***************************************************************************/ -static size_t writeFunctionString (void *ptr, size_t size, size_t nmemb, void *stream) +static bool isContentType(const std::string &contentType, const char *type) { - std::string *s = (std::string*) stream; - s->append ((char*) ptr, size * nmemb); - - return nmemb * size; + return (strncasecmp(contentType.c_str(), type, strlen(type)) == 0); } -static size_t writeFunctionBinary (void *ptr, size_t size, size_t nmemb, void *stream) +static bool toBase64(const std::vector &data, std::string &base64) { - std::vector *bytes = (std::vector*) stream; + bool result = false; - std::vector newBytes; - newBytes.resize(size * nmemb); - memcpy(newBytes.data(), ptr, newBytes.size()); - - bytes->insert(bytes->end(), newBytes.begin(), newBytes.end()); - - return nmemb * size; -} - -static int progressCallback (void *clientp, double /*dltotal*/, double /*dlnow*/, double /*ultotal*/, double /*ulnow*/) -{ - p3FeedReaderThread *thread = (p3FeedReaderThread*) clientp; - - if (!thread->isRunning()) { - /* thread was stopped */ - return 1; + /* Set up a base64 encoding BIO that writes to a memory BIO */ + BIO *b64 = BIO_new(BIO_f_base64()); + if (b64) { + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + BIO *bmem = BIO_new(BIO_s_mem()); + if (bmem) { + BIO_set_flags(bmem, BIO_CLOSE); // probably redundant + b64 = BIO_push(b64, bmem); + /* Send the data */ + BIO_write(b64, data.data(), data.size()); + /* Collect the encoded data */ + BIO_flush(b64); + char* temp; + int count = BIO_get_mem_data(bmem, &temp); + if (count && temp) { + base64.assign(temp, count); + result = true; + } + } + BIO_free_all(b64); } - long todo; // show progress in gui - - return 0; + return result; } -static bool getFavicon (std::string url, const std::string &proxy, std::string &icon) +static std::string getBaseLink(std::string link) +{ + size_t found = link.rfind('/'); + if (found != std::string::npos) { + link.erase(found + 1); + } + + return link; +} + +static std::string calculateLink(const std::string &baseLink, const std::string &link) +{ + if (link.substr(0, 7) == "http://") { + /* absolute link */ + return link; + } + + /* calculate link of base link */ + std::string resultLink = baseLink; + + /* link should begin with "http://" */ + if (resultLink.substr(0, 7) != "http://") { + resultLink.insert(0, "http://"); + } + + if (link.empty()) { + /* no link */ + return resultLink; + } + + if (*link.begin() == '/') { + /* link begins with "/" */ + size_t found = resultLink.find('/', 7); + if (found != std::string::npos) { + resultLink.erase(found); + } + } else { + /* check for "/" at the end */ + std::string::reverse_iterator it = resultLink.rend (); + it--; + if (*it != '/') { + resultLink += "/"; + } + } + + resultLink += link; + + return resultLink; +} + +static bool getFavicon(CURLWrapper &CURL, const std::string &url, std::string &icon) { icon.clear(); - if (url.substr(0, 7) == "http://") { - int found = url.find("/", 7); - if (found >= 0) { - url.erase(found, url.length() - found); - } - } else { - return false; - } - bool result = false; - CURL *curl = curl_easy_init(); - if (curl) { - url += "/favicon.ico"; - - std::vector vicon; - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); - curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeFunctionBinary); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &vicon); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); - curl_easy_setopt(curl, CURLOPT_COOKIESESSION, 1); - - if (!proxy.empty()) { - curl_easy_setopt(curl, CURLOPT_PROXY, proxy.c_str()); - } - - CURLcode code = curl_easy_perform(curl); - if (code == CURLE_OK) { - long response; - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response); - if (response == 200) { - char *contentType = NULL; - curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &contentType); - if (contentType && - (strncasecmp(contentType, "image/x-icon", 12) == 0 || - strncasecmp(contentType, "application/octet-stream", 24) == 0 || - strncasecmp(contentType, "text/plain", 10) == 0)) { - if (!vicon.empty()) { - long todo; // check it - // Set up a base64 encoding BIO that writes to a memory BIO - BIO *b64 = BIO_new(BIO_f_base64()); - if (b64) { - BIO *out = BIO_new(BIO_s_mem()); - if (out) { - BIO_set_flags(out, BIO_CLOSE); // probably redundant - b64 = BIO_push(b64, out); - // Send the data - BIO_write(b64, vicon.data(), vicon.size()); - // Collect the encoded data - BIO_flush(b64); - char* temp; - int count = BIO_get_mem_data(out, &temp); - if (count && temp) { - icon = temp; - result = true; - } - } - BIO_free_all(b64); - } - } -// char *encode = NULL; -// size_t encodeSize = 0; -// code = Curl_base64_encode(curl, (const char*) vicon.data(), vicon.size(), &encode, &encodeSize); -// if (code == CURLE_OK && encodeSize) { -// icon = encode; -// free(encode); -// encode = NULL; -// result = true; -// } + std::vector vicon; + CURLcode code = CURL.downloadBinary(calculateLink(url, "/favicon.ico"), vicon); + if (code == CURLE_OK) { + if (CURL.responseCode() == 200) { + std::string contentType = CURL.contentType(); + if (isContentType(contentType, "image/x-icon") || + isContentType(contentType, "application/octet-stream") || + isContentType(contentType, "text/plain")) { + if (!vicon.empty()) { + long todo; // check it + result = toBase64(vicon, icon); } } } - - curl_easy_cleanup(curl); - curl = NULL; } return result; @@ -245,68 +250,42 @@ p3FeedReaderThread::DownloadResult p3FeedReaderThread::download(const RsFeedRead DownloadResult result; - CURL *curl = curl_easy_init(); - if (curl) { - std::string proxy; - if (feed.flag & RS_FEED_FLAG_STANDARD_PROXY) { - std::string standardProxyAddress; - uint16_t standardProxyPort; - if (mFeedReader->getStandardProxy(standardProxyAddress, standardProxyPort)) { - rs_sprintf(proxy, "%s:%u", standardProxyAddress.c_str(), standardProxyPort); - } - } else { - if (!feed.proxyAddress.empty() && feed.proxyPort) { - rs_sprintf(proxy, "%s:%u", feed.proxyAddress.c_str(), feed.proxyPort); - } - } + std::string proxy = getProxyForFeed(feed); + CURLWrapper CURL(proxy); + CURLcode code = CURL.downloadText(feed.url, content); - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progressCallback); - curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, this); - curl_easy_setopt(curl, CURLOPT_URL, feed.url.c_str()); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeFunctionString); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &content); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); + if (code == CURLE_OK) { + long responseCode = CURL.responseCode(); - if (!proxy.empty()) { - curl_easy_setopt(curl, CURLOPT_PROXY, proxy.c_str()); - } + switch (responseCode) { + case 200: + { + std::string contentType = CURL.contentType(); - CURLcode code = curl_easy_perform(curl); - if (code == CURLE_OK) { - long response; - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response); - if (response == 200) { - char *contentType = NULL; - curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &contentType); - if (contentType && - (strncasecmp(contentType, "text/xml", 8) == 0 || - strncasecmp(contentType, "application/rss+xml", 19) == 0 || - strncasecmp(contentType, "application/xml", 15) == 0 || - strncasecmp(contentType, "application/xhtml+xml", 21) == 0)) { + if (isContentType(contentType, "text/xml") || + isContentType(contentType, "application/rss+xml") || + isContentType(contentType, "application/xml") || + isContentType(contentType, "application/xhtml+xml")) { /* ok */ result = DOWNLOAD_SUCCESS; } else { result = DOWNLOAD_UNKNOWN_CONTENT_TYPE; - error = contentType ? contentType : ""; + error = contentType; } - } else if (response == 404) { - result = DOWNLOAD_NOT_FOUND; - } else { - result = DOWNLOAD_UNKOWN_RESPONSE_CODE; - rs_sprintf(error, "%ld", response); } - } else { - result = DOWNLOAD_ERROR; - error = curl_easy_strerror(code); + break; + case 404: + result = DOWNLOAD_NOT_FOUND; + break; + default: + result = DOWNLOAD_UNKOWN_RESPONSE_CODE; + rs_sprintf(error, "%ld", responseCode); } - curl_easy_cleanup(curl); - curl = NULL; - - getFavicon(feed.url, proxy, icon); + getFavicon(CURL, feed.url, icon); } else { - result = DOWNLOAD_ERROR_INIT; + result = DOWNLOAD_ERROR; + error = curl_easy_strerror(code); } #ifdef FEEDREADER_DEBUG @@ -320,12 +299,12 @@ p3FeedReaderThread::DownloadResult p3FeedReaderThread::download(const RsFeedRead /****************************** Process ************************************/ /***************************************************************************/ -static bool convertOutput(xmlCharEncodingHandlerPtr charEncodingHandler, const xmlChar *output, std::string &text) +static bool convertToString(xmlCharEncodingHandlerPtr charEncodingHandler, const xmlChar *xmlText, std::string &text) { bool result = false; + xmlBufferPtr in = xmlBufferCreateStatic((void*) xmlText, xmlStrlen(xmlText)); xmlBufferPtr out = xmlBufferCreate(); - xmlBufferPtr in = xmlBufferCreateStatic((void*) output, xmlStrlen(output)); int ret = xmlCharEncOutFunc(charEncodingHandler, out, in); if (ret >= 0) { result = true; @@ -338,6 +317,24 @@ static bool convertOutput(xmlCharEncodingHandlerPtr charEncodingHandler, const x return result; } +static bool convertFromString(xmlCharEncodingHandlerPtr charEncodingHandler, const char *text, xmlChar *&xmlText) +{ + bool result = false; + + xmlBufferPtr in = xmlBufferCreateStatic((void*) text, strlen(text)); + xmlBufferPtr out = xmlBufferCreate(); + int ret = xmlCharEncOutFunc(charEncodingHandler, out, in); + if (ret >= 0) { + result = true; + xmlText = xmlBufferDetach(out); + } + + xmlBufferFree(in); + xmlBufferFree(out); + + return result; +} + static xmlNodePtr findNode(xmlNodePtr node, const char *name, bool children = false) { if (node->name) { @@ -419,12 +416,46 @@ static bool getChildText(/*xmlCharEncodingHandlerPtr*/ void *charEncodingHandler } if (child->children->content) { - return convertOutput((xmlCharEncodingHandlerPtr) charEncodingHandler, child->children->content, text); + return convertToString((xmlCharEncodingHandlerPtr) charEncodingHandler, child->children->content, text); } return true; } +static std::string xmlGetAttr(/*xmlCharEncodingHandlerPtr*/ void *charEncodingHandler, xmlNodePtr node, const char *name) +{ + if (!node || !name) { + return ""; + } + + std::string value; + + xmlChar *xmlValue = xmlGetProp(node, (const xmlChar*) name); + if (xmlValue) { + convertToString((xmlCharEncodingHandlerPtr) charEncodingHandler, xmlValue, value); + xmlFree(xmlValue); + } + + return value; +} + +static bool xmlSetAttr(/*xmlCharEncodingHandlerPtr*/ void *charEncodingHandler, xmlNodePtr node, const char *name, const char *value) +{ + if (!node || !name) { + return false; + } + + xmlChar *xmlValue = NULL; + if (!convertFromString((xmlCharEncodingHandlerPtr) charEncodingHandler, value, xmlValue)) { + return false; + } + + xmlAttrPtr xmlAttr = xmlSetProp (node, (const xmlChar*) name, xmlValue); + xmlFree(xmlValue); + + return xmlAttr != NULL; +} + static void splitString(std::string s, std::vector &v, const char d) { v.clear(); @@ -689,7 +720,7 @@ static time_t parseRFC822Date(const std::string &pubDate) // broken mail-/news-clients omit the time zone if (*dateString) { if ((strncasecmp(dateString, "gmt", 3) == 0) || - (strncasecmp(dateString, "utc", 3) == 0)) + (strncasecmp(dateString, "utc", 3) == 0)) { dateString += 3; while(*dateString && isspace(*dateString)) @@ -942,7 +973,10 @@ p3FeedReaderThread::ProcessResult p3FeedReaderThread::process(const RsFeedReader item->feedId = feed.feedId; item->title = title; - getChildText(mCharEncodingHandler, node, "link", item->link); + /* try feedburner:origLink */ + if (!getChildText(mCharEncodingHandler, node, "origLink", item->link) || item->link.empty()) { + getChildText(mCharEncodingHandler, node, "link", item->link); + } long todo; // remove sid // // remove sid= @@ -969,6 +1003,7 @@ p3FeedReaderThread::ProcessResult p3FeedReaderThread::process(const RsFeedReader // } getChildText(mCharEncodingHandler, node, "author", item->author); + getChildText(mCharEncodingHandler, node, "description", item->description); std::string pubDate; @@ -1007,3 +1042,148 @@ p3FeedReaderThread::ProcessResult p3FeedReaderThread::process(const RsFeedReader return result; } + +std::string p3FeedReaderThread::getProxyForFeed(const RsFeedReaderFeed &feed) +{ + std::string proxy; + if (feed.flag & RS_FEED_FLAG_STANDARD_PROXY) { + std::string standardProxyAddress; + uint16_t standardProxyPort; + if (mFeedReader->getStandardProxy(standardProxyAddress, standardProxyPort)) { + rs_sprintf(proxy, "%s:%u", standardProxyAddress.c_str(), standardProxyPort); + } + } else { + if (!feed.proxyAddress.empty() && feed.proxyPort) { + rs_sprintf(proxy, "%s:%u", feed.proxyAddress.c_str(), feed.proxyPort); + } + } + return proxy; +} + +bool p3FeedReaderThread::processMsg(const RsFeedReaderFeed &feed, RsFeedReaderMsg *msg) +{ + if (!msg) { + return false; + } + + std::string proxy = getProxyForFeed(feed); + + std::string url; + if (feed.flag & RS_FEED_FLAG_SAVE_COMPLETE_PAGE) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") download page " << msg->link << std::endl; +#endif + std::string content; + CURLWrapper CURL(proxy); + CURLcode code = CURL.downloadText(msg->link, content); + + if (code == CURLE_OK && CURL.responseCode() == 200 && isContentType(CURL.contentType(), "text/html")) { + /* ok */ + msg->description = content; + } else { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot download page, CURLCode = " << code << ", responseCode = " << CURL.responseCode() << ", contentType = " << CURL.contentType() << std::endl; +#endif + return false; + } + + /* get effective url (moved location) */ + std::string effectiveUrl = CURL.effectiveUrl(); + url = getBaseLink(effectiveUrl.empty() ? msg->link : effectiveUrl); + } + + /* check if string contains xml chars (very simple test) */ + if (msg->description.find('<') == std::string::npos) { + return true; + } + + bool result = true; + + /* process description */ + long todo; // encoding + htmlDocPtr document = htmlReadMemory(msg->description.c_str(), msg->description.length(), url.c_str(), "", HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING | HTML_PARSE_COMPACT); + if (document) { + xmlNodePtr root = xmlDocGetRootElement(document); + if (root) { + /* process all children */ + std::list parents; + parents.push_back(root); + + while (!parents.empty()) { + if (!isRunning()) { + break; + } + xmlNodePtr node = parents.front(); + parents.pop_front(); + + if (node->type == XML_ELEMENT_NODE) { + /* check for image */ + if (strcasecmp((char*) node->name, "img") == 0) { + bool removeImage = true; + + if (feed.flag & RS_FEED_FLAG_EMBED_IMAGES) { + /* embed image */ + std::string src = xmlGetAttr(mCharEncodingHandler, node, "src"); + if (!src.empty()) { + /* download image */ +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") download image " << src << std::endl; +#endif + std::vector data; + CURLWrapper CURL(proxy); + CURLcode code = CURL.downloadBinary(calculateLink(url, src), data); + if (code == CURLE_OK && CURL.responseCode() == 200) { + std::string contentType = CURL.contentType(); + if (isContentType(contentType, "image/")) { + std::string base64; + if (toBase64(data, base64)) { + std::string imageBase64; + rs_sprintf(imageBase64, "data:%s;base64,%s", contentType.c_str(), base64.c_str()); + if (xmlSetAttr(mCharEncodingHandler, node, "src", imageBase64.c_str())) { + removeImage = false; + } + } + } + } + } + } + + if (removeImage) { + /* remove image */ + xmlUnlinkNode(node); + xmlFreeNode(node); + continue; + } + } + + xmlNodePtr child; + for (child = node->children; child; child = child->next) { + parents.push_back(child); + } + } + } + + xmlChar *html = NULL; + int htmlSize = 0; + htmlDocDumpMemoryFormat(document, &html, &htmlSize, 0); + if (html) { + convertToString((xmlCharEncodingHandlerPtr) mCharEncodingHandler, html, msg->description); + xmlFree(html); + } else { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot dump html" << std::endl; +#endif + result = false; + } + } else { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") no root element" << std::endl; +#endif + result = false; + } + + xmlFreeDoc(document); + } + + return result; +} diff --git a/plugins/FeedReader/services/p3FeedReaderThread.h b/plugins/FeedReader/services/p3FeedReaderThread.h index 051cd0325..b405b8822 100644 --- a/plugins/FeedReader/services/p3FeedReaderThread.h +++ b/plugins/FeedReader/services/p3FeedReaderThread.h @@ -19,7 +19,7 @@ * Boston, MA 02110-1301, USA. ****************************************************************/ - #ifndef P3_FEEDREADERTHREAD +#ifndef P3_FEEDREADERTHREAD #define P3_FEEDREADERTHREAD #include "util/rsthreads.h" @@ -40,7 +40,6 @@ public: enum DownloadResult { DOWNLOAD_SUCCESS, - DOWNLOAD_ERROR_INIT, DOWNLOAD_ERROR, DOWNLOAD_UNKNOWN_CONTENT_TYPE, DOWNLOAD_NOT_FOUND, @@ -64,6 +63,9 @@ private: DownloadResult download(const RsFeedReaderFeed &feed, std::string &content, std::string &icon, std::string &error); ProcessResult process(const RsFeedReaderFeed &feed, std::list &entries, std::string &error); + std::string getProxyForFeed(const RsFeedReaderFeed &feed); + bool processMsg(const RsFeedReaderFeed &feed, RsFeedReaderMsg *msg); + p3FeedReader *mFeedReader; Type mType; /*xmlCharEncodingHandlerPtr*/ void *mCharEncodingHandler; diff --git a/plugins/FeedReader/services/rsFeedReaderItems.h b/plugins/FeedReader/services/rsFeedReaderItems.h index 92c911864..7f6703290 100644 --- a/plugins/FeedReader/services/rsFeedReaderItems.h +++ b/plugins/FeedReader/services/rsFeedReaderItems.h @@ -19,7 +19,7 @@ * Boston, MA 02110-1301, USA. ****************************************************************/ - #ifndef RS_FEEDREADER_ITEMS_H +#ifndef RS_FEEDREADER_ITEMS_H #define RS_FEEDREADER_ITEMS_H #include "serialiser/rsserial.h" @@ -55,6 +55,8 @@ const uint8_t RS_PKT_SUBTYPE_FEEDREADER_MSG = 0x03; #define RS_FEED_FLAG_DEACTIVATED 0x040 #define RS_FEED_FLAG_FORUM 0x080 #define RS_FEED_FLAG_UPDATE_FORUM_INFO 0x100 +#define RS_FEED_FLAG_EMBED_IMAGES 0x200 +#define RS_FEED_FLAG_SAVE_COMPLETE_PAGE 0x400 class RsFeedReaderFeed : public RsItem { diff --git a/plugins/FeedReader/services/util/CURLWrapper.cc b/plugins/FeedReader/services/util/CURLWrapper.cc new file mode 100644 index 000000000..e39d5e99c --- /dev/null +++ b/plugins/FeedReader/services/util/CURLWrapper.cc @@ -0,0 +1,136 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include "CURLWrapper.h" + +//static int progressCallback (void *clientp, double /*dltotal*/, double /*dlnow*/, double /*ultotal*/, double /*ulnow*/) +//{ +// p3FeedReaderThread *thread = (p3FeedReaderThread*) clientp; + +// if (!thread->isRunning()) { +// /* thread was stopped */ +// return 1; +// } + +// long todo; // show progress in gui + +// return 0; +//} + +CURLWrapper::CURLWrapper(const std::string &proxy) +{ + mCurl = curl_easy_init(); + if (mCurl) { + curl_easy_setopt(mCurl, CURLOPT_NOPROGRESS, 0); +// curl_easy_setopt(mCurl, CURLOPT_PROGRESSFUNCTION, progressCallback); +// curl_easy_setopt(mCurl, CURLOPT_PROGRESSDATA, feedReader); + curl_easy_setopt(mCurl, CURLOPT_FOLLOWLOCATION, 1); + curl_easy_setopt(mCurl, CURLOPT_CONNECTTIMEOUT, 60); + curl_easy_setopt(mCurl, CURLOPT_TIMEOUT, 120); + + if (!proxy.empty()) { + curl_easy_setopt(mCurl, CURLOPT_PROXY, proxy.c_str()); + } + } +} + +CURLWrapper::~CURLWrapper() +{ + if (mCurl) { + curl_easy_cleanup(mCurl); + } +} + +static size_t writeFunctionString (void *ptr, size_t size, size_t nmemb, void *stream) +{ + std::string *s = (std::string*) stream; + s->append ((char*) ptr, size * nmemb); + + return nmemb * size; +} + +CURLcode CURLWrapper::downloadText(const std::string &link, std::string &data) +{ + data.clear(); + + if (!mCurl) { + return CURLE_FAILED_INIT; + } + + curl_easy_setopt(mCurl, CURLOPT_URL, link.c_str()); + curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, writeFunctionString); + curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, &data); + + return curl_easy_perform(mCurl); +} + +static size_t writeFunctionBinary (void *ptr, size_t size, size_t nmemb, void *stream) +{ + std::vector *bytes = (std::vector*) stream; + + std::vector newBytes; + newBytes.resize(size * nmemb); + memcpy(newBytes.data(), ptr, newBytes.size()); + + bytes->insert(bytes->end(), newBytes.begin(), newBytes.end()); + + return nmemb * size; +} + +CURLcode CURLWrapper::downloadBinary(const std::string &link, std::vector &data) +{ + data.clear(); + + if (!mCurl) { + return CURLE_FAILED_INIT; + } + + curl_easy_setopt(mCurl, CURLOPT_NOPROGRESS, 1); + curl_easy_setopt(mCurl, CURLOPT_URL, link.c_str()); + curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, writeFunctionBinary); + curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, &data); + + return curl_easy_perform(mCurl); +} + +long CURLWrapper::longInfo(CURLINFO info) +{ + if (!mCurl) { + return 0; + } + + long value; + curl_easy_getinfo(mCurl, info, &value); + + return value; +} + +std::string CURLWrapper::stringInfo(CURLINFO info) +{ + if (!mCurl) { + return ""; + } + + char *value; + curl_easy_getinfo(mCurl, info, &value); + + return value ? value : ""; +} diff --git a/plugins/FeedReader/services/util/CURLWrapper.h b/plugins/FeedReader/services/util/CURLWrapper.h new file mode 100644 index 000000000..66ac68f53 --- /dev/null +++ b/plugins/FeedReader/services/util/CURLWrapper.h @@ -0,0 +1,50 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#ifndef CURLWRAPPER +#define CURLWRAPPER + +#include +#include +#include + +class CURLWrapper +{ +public: + CURLWrapper(const std::string &proxy); + ~CURLWrapper(); + + CURLcode downloadText(const std::string &link, std::string &data); + CURLcode downloadBinary(const std::string &link, std::vector &data); + + long responseCode() { return longInfo(CURLINFO_RESPONSE_CODE); } + std::string contentType() { return stringInfo(CURLINFO_CONTENT_TYPE); } + std::string effectiveUrl() { return stringInfo(CURLINFO_EFFECTIVE_URL); } + +protected: + long longInfo(CURLINFO info); + std::string stringInfo(CURLINFO info); + +private: + CURL *mCurl; +}; + +#endif From acaefada6566280a71e264e7fcdcb59131e84dd5 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sun, 12 Aug 2012 20:46:21 +0000 Subject: [PATCH 022/222] Got group retrieval working with gui and fixed subsequent bugs add p3distribsecurity mirror gxssecurity (does not have grp or msg verification implemented, but other methods are valid) git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5406 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/gxssecurity.cc | 280 ++++ libretroshare/src/gxs/gxssecurity.h | 132 ++ libretroshare/src/gxs/rsgenexchange.cc | 35 +- libretroshare/src/gxs/rsgenexchange.h | 10 +- libretroshare/src/gxs/rsgxsdataaccess.cc | 74 +- libretroshare/src/gxs/rsgxsdataaccess.h | 4 +- libretroshare/src/libretroshare.pro | 1354 ++++++++--------- libretroshare/src/serialiser/rsnxsitems.h | 2 +- .../src/services/p3photoserviceV2.cc | 6 - .../src/gui/PhotoShare/PhotoAddDialog.cpp | 5 - .../src/gui/PhotoShare/PhotoDialog.cpp | 23 +- .../src/gui/PhotoShare/PhotoDialog.h | 3 +- 12 files changed, 1166 insertions(+), 762 deletions(-) create mode 100644 libretroshare/src/gxs/gxssecurity.cc create mode 100644 libretroshare/src/gxs/gxssecurity.h diff --git a/libretroshare/src/gxs/gxssecurity.cc b/libretroshare/src/gxs/gxssecurity.cc new file mode 100644 index 000000000..3ba7d6164 --- /dev/null +++ b/libretroshare/src/gxs/gxssecurity.cc @@ -0,0 +1,280 @@ + +/* + * libretroshare/src/distrib: p3distribverify.cc + * + * + * Copyright 2008-2010 by Robert Fernie + * 2011 Christopher Evi-Parker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "gxssecurity.h" +#include "pqi/authgpg.h" +#include "retroshare/rspeers.h" + +GxsSecurity::GxsSecurity() +{ +} + +GxsSecurity::~GxsSecurity() +{ +} + +RSA *GxsSecurity::extractPublicKey(RsTlvSecurityKey& key) +{ + const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data; + long keylen = key.keyData.bin_len; + + /* extract admin key */ + RSA *rsakey = d2i_RSAPublicKey(NULL, &(keyptr), keylen); + + return rsakey; +} + + +bool GxsSecurity::validateNxsMsg(RsNxsMsg *msg) +{ + + return false; +} + + + +std::string GxsSecurity::getBinDataSign(void *data, int len) +{ + unsigned char *tmp = (unsigned char *) data; + + // copy first CERTSIGNLEN bytes... + if (len > CERTSIGNLEN) + { + len = CERTSIGNLEN; + } + + std::string id; + for(uint32_t i = 0; i < CERTSIGNLEN; i++) + { + rs_sprintf_append(id, "%02x", (uint16_t) (((uint8_t *) (tmp))[i])); + } + + return id; +} + + + +bool GxsSecurity::encrypt(void *& out, int & outlen, const void *in, int inlen, EVP_PKEY *privateKey) +{ + + +#ifdef DISTRIB_DEBUG + std::cerr << "GxsSecurity::encrypt() " << std::endl; +#endif + + RSA *rsa_publish_pub = NULL; + EVP_PKEY *public_key = NULL; + + RSA* rsa_publish = EVP_PKEY_get1_RSA(privateKey); + rsa_publish_pub = RSAPublicKey_dup(rsa_publish); + + + if(rsa_publish_pub != NULL){ + public_key = EVP_PKEY_new(); + EVP_PKEY_assign_RSA(public_key, rsa_publish_pub); + }else{ +#ifdef DISTRIB_DEBUG + std::cerr << "GxsSecurity(): Could not generate publish key " << grpId + << std::endl; +#endif + return false; + } + + EVP_CIPHER_CTX ctx; + int eklen, net_ekl; + unsigned char *ek; + unsigned char iv[EVP_MAX_IV_LENGTH]; + EVP_CIPHER_CTX_init(&ctx); + int out_currOffset = 0; + int out_offset = 0; + + int max_evp_key_size = EVP_PKEY_size(public_key); + ek = (unsigned char*)malloc(max_evp_key_size); + const EVP_CIPHER *cipher = EVP_aes_128_cbc(); + int cipher_block_size = EVP_CIPHER_block_size(cipher); + int size_net_ekl = sizeof(net_ekl); + + int max_outlen = inlen + cipher_block_size + EVP_MAX_IV_LENGTH + max_evp_key_size + size_net_ekl; + + // intialize context and send store encrypted cipher in ek + if(!EVP_SealInit(&ctx, EVP_aes_128_cbc(), &ek, &eklen, iv, &public_key, 1)) return false; + + // now assign memory to out accounting for data, and cipher block size, key length, and key length val + out = new unsigned char[inlen + cipher_block_size + size_net_ekl + eklen + EVP_MAX_IV_LENGTH]; + + net_ekl = htonl(eklen); + memcpy((unsigned char*)out + out_offset, &net_ekl, size_net_ekl); + out_offset += size_net_ekl; + + memcpy((unsigned char*)out + out_offset, ek, eklen); + out_offset += eklen; + + memcpy((unsigned char*)out + out_offset, iv, EVP_MAX_IV_LENGTH); + out_offset += EVP_MAX_IV_LENGTH; + + // now encrypt actual data + if(!EVP_SealUpdate(&ctx, (unsigned char*) out + out_offset, &out_currOffset, (unsigned char*) in, inlen)) return false; + + // move along to partial block space + out_offset += out_currOffset; + + // add padding + if(!EVP_SealFinal(&ctx, (unsigned char*) out + out_offset, &out_currOffset)) return false; + + // move to end + out_offset += out_currOffset; + + // make sure offset has not gone passed valid memory bounds + if(out_offset > max_outlen) return false; + + // free encrypted key data + free(ek); + + outlen = out_offset; + return true; + + delete[] ek; + +#ifdef DISTRIB_DEBUG + std::cerr << "GxsSecurity::encrypt() finished with outlen : " << outlen << std::endl; +#endif + + return true; +} + + +bool GxsSecurity::decrypt(void *& out, int & outlen, const void *in, int inlen, EVP_PKEY *privateKey) +{ + +#ifdef DISTRIB_DEBUG + std::cerr << "GxsSecurity::decrypt() " << std::endl; +#endif + + EVP_CIPHER_CTX ctx; + int eklen = 0, net_ekl = 0; + unsigned char *ek = NULL; + unsigned char iv[EVP_MAX_IV_LENGTH]; + ek = (unsigned char*)malloc(EVP_PKEY_size(privateKey)); + EVP_CIPHER_CTX_init(&ctx); + + int in_offset = 0, out_currOffset = 0; + int size_net_ekl = sizeof(net_ekl); + + memcpy(&net_ekl, (unsigned char*)in, size_net_ekl); + eklen = ntohl(net_ekl); + in_offset += size_net_ekl; + + memcpy(ek, (unsigned char*)in + in_offset, eklen); + in_offset += eklen; + + memcpy(iv, (unsigned char*)in + in_offset, EVP_MAX_IV_LENGTH); + in_offset += EVP_MAX_IV_LENGTH; + + const EVP_CIPHER* cipher = EVP_aes_128_cbc(); + + if(!EVP_OpenInit(&ctx, cipher, ek, eklen, iv, privateKey)) return false; + + out = new unsigned char[inlen - in_offset]; + + if(!EVP_OpenUpdate(&ctx, (unsigned char*) out, &out_currOffset, (unsigned char*)in + in_offset, inlen - in_offset)) return false; + + in_offset += out_currOffset; + outlen += out_currOffset; + + if(!EVP_OpenFinal(&ctx, (unsigned char*)out + out_currOffset, &out_currOffset)) return false; + + outlen += out_currOffset; + + free(ek); + + return true; +} + +std::string GxsSecurity::getRsaKeySign(RSA *pubkey) +{ + int len = BN_num_bytes(pubkey -> n); + unsigned char tmp[len]; + BN_bn2bin(pubkey -> n, tmp); + + // copy first CERTSIGNLEN bytes... + if (len > CERTSIGNLEN) + { + len = CERTSIGNLEN; + } + + std::string id; + for(uint32_t i = 0; i < CERTSIGNLEN; i++) + { + rs_sprintf_append(id, "%02x", (uint16_t) (((uint8_t *) (tmp))[i])); + } + + return id; +} + + +bool GxsSecurity::validateNxsGrp(RsNxsGrp *newGrp) +{ + +} + +void GxsSecurity::setRSAPublicKey(RsTlvSecurityKey & key, RSA *rsa_pub) +{ + unsigned char data[10240]; /* more than enough space */ + unsigned char *ptr = data; + int reqspace = i2d_RSAPublicKey(rsa_pub, &ptr); + + key.keyData.setBinData(data, reqspace); + + std::string keyId = getRsaKeySign(rsa_pub); + key.keyId = keyId; +} + + + +void GxsSecurity::setRSAPrivateKey(RsTlvSecurityKey & key, RSA *rsa_priv) +{ + unsigned char data[10240]; /* more than enough space */ + unsigned char *ptr = data; + int reqspace = i2d_RSAPrivateKey(rsa_priv, &ptr); + + key.keyData.setBinData(data, reqspace); + + std::string keyId = getRsaKeySign(rsa_priv); + key.keyId = keyId; +} + +RSA *GxsSecurity::extractPrivateKey(RsTlvSecurityKey & key) +{ + const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data; + long keylen = key.keyData.bin_len; + + /* extract admin key */ + RSA *rsakey = d2i_RSAPrivateKey(NULL, &(keyptr), keylen); + + return rsakey; +} + + diff --git a/libretroshare/src/gxs/gxssecurity.h b/libretroshare/src/gxs/gxssecurity.h new file mode 100644 index 000000000..600561262 --- /dev/null +++ b/libretroshare/src/gxs/gxssecurity.h @@ -0,0 +1,132 @@ +#ifndef GXSSECURITY_H +#define GXSSECURITY_H + +/* + * libretroshare/src/gxs: gxssecurity + * + * Security functions for Gxs + * + * Copyright 2008-2010 by Robert Fernie + * 2012 Christopher Evi-Parker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "serialiser/rstlvkeys.h" +#include "serialiser/rsnxsitems.h" + +#include +#include + + +/*! + * This contains functionality for performing security + * operations needed to validate data received in RsGenExchange + * Also has routine for creating security objects around msgs and groups + */ +class GxsSecurity { + +public: + + GxsSecurity(); + ~GxsSecurity(); + + /*! + * extracts the public key from an RsTlvSecurityKey + * @param key RsTlvSecurityKey to extract public RSA key from + * @return pointer to the public RSA key if successful, null otherwise + */ + static RSA *extractPublicKey(RsTlvSecurityKey &key); + + /*! + * extracts the public key from an RsTlvSecurityKey + * @param key RsTlvSecurityKey to extract private RSA key from + * @return pointer to the private RSA key if successful, null otherwise + */ + static RSA *extractPrivateKey(RsTlvSecurityKey &key); + + /*! + * stores the rsa public key in a RsTlvSecurityKey + * @param key RsTlvSecurityKey to store the public rsa key in + * @param rsa_pub + */ + static void setRSAPublicKey(RsTlvSecurityKey &key, RSA *rsa_pub); + + /*! + * stores the rsa private key in a RsTlvSecurityKey + * @param key stores the rsa private key in a RsTlvSecurityKey + * @param rsa_priv the rsa private key to store + */ + static void setRSAPrivateKey(RsTlvSecurityKey &key, RSA *rsa_priv); + + /*! + * extracts signature from RSA key + * @param pubkey + * @return signature of RSA key in hex format + */ + static std::string getRsaKeySign(RSA *pubkey); + + /*! + * extracts the signature and stores it in a string + * in hex format + * @param data + * @param len + * @return + */ + static std::string getBinDataSign(void *data, int len); + + /*! + * Encrypts data using envelope encryption (taken from open ssl's evp_sealinit ) + * only full publish key holders can encrypt data for given group + *@param out + *@param outlen + *@param in + *@param inlen + */ + static bool encrypt(void *&out, int &outlen, const void *in, int inlen, EVP_PKEY *privateKey); + + + /** + * Decrypts data using evelope decryption (taken from open ssl's evp_sealinit ) + * only full publish key holders can decrypt data for a group + * @param out where decrypted data is written to + * @param outlen + * @param in + * @param inlen + * @return false if encryption failed + */ + static bool decrypt(void *&out, int &outlen, const void *in, int inlen, EVP_PKEY *privateKey); + + /*! + * uses grp signature to check if group has been + * tampered with + * @param newGrp + * @return true if group valid false otherwise + */ + static bool validateNxsGrp(RsNxsGrp *newGrp); + + /*! + * uses groupinfo public key to verify signature of signed message + * @param info groupinfo for which msg is meant for + * @param msg + * @return false if verfication of signature is not passed + */ + static bool validateNxsMsg(RsNxsMsg *msg); +}; + +#endif // GXSSECURITY_H diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 5f809e1e7..9168a58e3 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -24,7 +24,13 @@ * */ +#include +#include +#include +#include + #include "rsgenexchange.h" +#include "gxssecurity.h" RsGenExchange::RsGenExchange(RsGeneralDataService *gds, RsNetworkExchangeService *ns, RsSerialType *serviceSerialiser, uint16_t servType) @@ -62,6 +68,30 @@ void RsGenExchange::tick() } +void RsGenExchange::createGroup(RsNxsGrp *grp) +{ + /* create Keys */ + RSA *rsa_admin = RSA_generate_key(2048, 65537, NULL, NULL); + RSA *rsa_admin_pub = RSAPublicKey_dup(rsa_admin); + + + /* set keys */ + RsTlvSecurityKey adminKey; + GxsSecurity::setRSAPublicKey(adminKey, rsa_admin_pub); + + adminKey.startTS = time(NULL); + adminKey.endTS = 0; /* no end */ + RsGxsGrpMetaData* meta = grp->metaData; + meta->keys.keys[adminKey.keyId] = adminKey; + meta->mGroupId = adminKey.keyId; + grp->grpId = meta->mGroupId; + + adminKey.TlvClear(); + + // free the private key for now, as it is not in use + RSA_free(rsa_admin); +} + bool RsGenExchange::getGroupList(const uint32_t &token, std::list &groupIds) { @@ -125,7 +155,7 @@ bool RsGenExchange::getMsgMeta(const uint32_t &token, return ok; } -bool RsGenExchange::getGroupData(const uint32_t &token, std::vector grpItem) +bool RsGenExchange::getGroupData(const uint32_t &token, std::vector& grpItem) { std::list nxsGrps; @@ -294,13 +324,16 @@ void RsGenExchange::publishGrps() char gData[size]; bool ok = mSerialiser->serialise(grpItem, gData, &size); + grp->grp.setBinData(gData, size); if(ok) { grp->metaData = new RsGxsGrpMetaData(); *(grp->metaData) = grpItem->meta; + createGroup(grp); ok = mDataAccess->addGroupData(grp); RsGxsGroupChange* gc = new RsGxsGroupChange(); + gc->grpIdList.push_back(grp->grpId); mNotifications.push_back(gc); } diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 55bc08622..6cb1ef7f6 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -143,7 +143,7 @@ protected: * @param token token to be redeemed for grpitem retrieval * @param grpItem the items to be retrieved for token are stored here */ - bool getGroupData(const uint32_t &token, std::vector grpItem); + bool getGroupData(const uint32_t &token, std::vector& grpItem); /*! * retrieves message data associated to a request token @@ -193,9 +193,7 @@ protected: virtual void notifyChanges(std::vector& changes) = 0; - void publishGrps(); - void publishMsgs(); private: @@ -205,6 +203,12 @@ private: void processRecvdGroups(); + void publishGrps(); + + void publishMsgs(); + + void createGroup(RsNxsGrp* grp); + private: RsMutex mGenMtx; diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index 41ab19f1b..a2c1fc4e3 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -57,7 +57,7 @@ const uint8_t RsTokenServiceV2::GXS_REQUEST_STATUS_DONE = 5; // ONCE ALL DATA RETRIEVED. RsGxsDataAccess::RsGxsDataAccess(RsGeneralDataService* ds) - : mDataStore(ds), mDataMutex("RsGxsDataAccess") + : mDataStore(ds), mDataMutex("RsGxsDataAccess"), mNextToken(0) { } @@ -217,6 +217,7 @@ void RsGxsDataAccess::storeRequest(GxsRequest* req) { RsStackMutex stack(mDataMutex); /****** LOCKED *****/ + req->status = GXS_REQUEST_STATUS_PENDING; mRequests[req->token] = req; return; @@ -263,20 +264,22 @@ bool RsGxsDataAccess::clearRequest(const uint32_t& token) bool RsGxsDataAccess::getGroupSummary(const uint32_t& token, std::list& groupInfo) { - GxsRequest* req = retrieveRequest(token); + RsStackMutex stack(mDataMutex); + + GxsRequest* req = locked_retrieveRequest(token); if(req == NULL){ std::cerr << "RsGxsDataAccess::getGroupSummary() Unable to retrieve group summary" << std::endl; return false; - }else if(req->token == GXS_REQUEST_STATUS_COMPLETE){ + }else if(req->status == GXS_REQUEST_STATUS_COMPLETE){ GroupMetaReq* gmreq = dynamic_cast(req); if(gmreq) { groupInfo = gmreq->mGroupMetaData; - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + locked_updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); }else{ std::cerr << "RsGxsDataAccess::getGroupSummary() Req found, failed caste" << std::endl; return false; @@ -291,21 +294,22 @@ bool RsGxsDataAccess::getGroupSummary(const uint32_t& token, std::list& grpData) { + RsStackMutex stack(mDataMutex); - GxsRequest* req = retrieveRequest(token); + GxsRequest* req = locked_retrieveRequest(token); if(req == NULL){ std::cerr << "RsGxsDataAccess::getGroupData() Unable to retrieve group data" << std::endl; return false; - }else if(req->token == GXS_REQUEST_STATUS_COMPLETE){ + }else if(req->status == GXS_REQUEST_STATUS_COMPLETE){ GroupDataReq* gmreq = dynamic_cast(req); if(gmreq) { grpData = gmreq->mGroupData; - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + locked_updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); }else{ std::cerr << "RsGxsDataAccess::getGroupData() Req found, failed caste" << std::endl; return false; @@ -320,20 +324,23 @@ bool RsGxsDataAccess::getGroupData(const uint32_t& token, std::list& bool RsGxsDataAccess::getMsgData(const uint32_t& token, NxsMsgDataResult& msgData) { - GxsRequest* req = retrieveRequest(token); + + RsStackMutex stack(mDataMutex); + + GxsRequest* req = locked_retrieveRequest(token); if(req == NULL){ std::cerr << "RsGxsDataAccess::getMsgData() Unable to retrieve group data" << std::endl; return false; - }else if(req->token == GXS_REQUEST_STATUS_COMPLETE){ + }else if(req->status == GXS_REQUEST_STATUS_COMPLETE){ MsgDataReq* mdreq = dynamic_cast(req); if(mdreq) { msgData = mdreq->mMsgData; - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + locked_updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); }else{ std::cerr << "RsGxsDataAccess::getMsgData() Req found, failed caste" << std::endl; return false; @@ -348,20 +355,23 @@ bool RsGxsDataAccess::getMsgData(const uint32_t& token, NxsMsgDataResult& msgDat bool RsGxsDataAccess::getMsgSummary(const uint32_t& token, GxsMsgMetaResult& msgInfo) { - GxsRequest* req = retrieveRequest(token); + + RsStackMutex stack(mDataMutex); + + GxsRequest* req = locked_retrieveRequest(token); if(req == NULL){ std::cerr << "RsGxsDataAccess::getMsgSummary() Unable to retrieve group data" << std::endl; return false; - }else if(req->token == GXS_REQUEST_STATUS_COMPLETE){ + }else if(req->status == GXS_REQUEST_STATUS_COMPLETE){ MsgMetaReq* mmreq = dynamic_cast(req); if(mmreq) { msgInfo = mmreq->mMsgMetaData; - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + locked_updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); }else{ std::cerr << "RsGxsDataAccess::getMsgSummary() Req found, failed caste" << std::endl; @@ -377,20 +387,22 @@ bool RsGxsDataAccess::getMsgSummary(const uint32_t& token, GxsMsgMetaResult& msg bool RsGxsDataAccess::getMsgList(const uint32_t& token, GxsMsgIdResult& msgIds) { - GxsRequest* req = retrieveRequest(token); + RsStackMutex stack(mDataMutex); + + GxsRequest* req = locked_retrieveRequest(token); if(req == NULL){ std::cerr << "RsGxsDataAccess::getMsgList() Unable to retrieve group data" << std::endl; return false; - }else if(req->token == GXS_REQUEST_STATUS_COMPLETE){ + }else if(req->status == GXS_REQUEST_STATUS_COMPLETE){ MsgIdReq* mireq = dynamic_cast(req); if(mireq) { msgIds = mireq->mMsgIdResult; - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + locked_updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); }else{ std::cerr << "RsGxsDataAccess::getMsgList() Req found, failed caste" << std::endl; @@ -406,21 +418,23 @@ bool RsGxsDataAccess::getMsgList(const uint32_t& token, GxsMsgIdResult& msgIds) bool RsGxsDataAccess::getGroupList(const uint32_t& token, std::list& groupIds) { - GxsRequest* req = retrieveRequest(token); + RsStackMutex stack(mDataMutex); + + GxsRequest* req = locked_retrieveRequest(token); if(req == NULL){ std::cerr << "RsGxsDataAccess::getGroupList() Unable to retrieve group data," "\nRequest does not exist" << std::endl; return false; - }else if(req->token == GXS_REQUEST_STATUS_COMPLETE){ + }else if(req->status == GXS_REQUEST_STATUS_COMPLETE){ GroupIdReq* gireq = dynamic_cast(req); if(gireq) { groupIds = gireq->mGroupIdResult; - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + locked_updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); }else{ std::cerr << "RsGxsDataAccess::getGroupList() Req found, failed caste" << std::endl; @@ -435,11 +449,9 @@ bool RsGxsDataAccess::getGroupList(const uint32_t& token, std::listtoken); } - else if (now - req->reqTime > MAX_REQUEST_AGE) + else if (false/*now - req->reqTime > MAX_REQUEST_AGE*/) { std::cerr << "RsGxsDataAccess::processrequests() Clearing Old Request Token: " << req->token; std::cerr << std::endl; @@ -551,13 +563,13 @@ bool RsGxsDataAccess::getGroupData(GroupDataReq* req) { std::map grpData; - mDataStore->retrieveNxsGrps(grpData, true, true); + bool ok = mDataStore->retrieveNxsGrps(grpData, true, true); std::map::iterator mit = grpData.begin(); for(; mit != grpData.end(); mit++) req->mGroupData.push_back(mit->second); - return true; + return ok; } bool RsGxsDataAccess::getGroupSummary(GroupMetaReq* req) @@ -862,11 +874,11 @@ bool RsGxsDataAccess::checkRequestStatus(const uint32_t& token, uint32_t& status, uint32_t& reqtype, uint32_t& anstype, time_t& ts) { - GxsRequest* req = retrieveRequest(token); - RsStackMutex stack(mDataMutex); - if(!req) + GxsRequest* req = locked_retrieveRequest(token); + + if(req == NULL) return false; anstype = req->ansType; @@ -911,12 +923,10 @@ void RsGxsDataAccess::tokenList(std::list& tokens) { } } -bool RsGxsDataAccess::updateRequestStatus(const uint32_t& token, +bool RsGxsDataAccess::locked_updateRequestStatus(const uint32_t& token, const uint32_t& status) { - RsStackMutex stack(mDataMutex); - - GxsRequest* req = retrieveRequest(token); + GxsRequest* req = locked_retrieveRequest(token); if(req) req->status = status; diff --git a/libretroshare/src/gxs/rsgxsdataaccess.h b/libretroshare/src/gxs/rsgxsdataaccess.h index 83177112a..94aea5095 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.h +++ b/libretroshare/src/gxs/rsgxsdataaccess.h @@ -191,7 +191,7 @@ private: * @param token the value of the token for the request object handle wanted * @return the request associated to this token */ - GxsRequest* retrieveRequest(const uint32_t& token); + GxsRequest* locked_retrieveRequest(const uint32_t& token); /*! * Add a gxs request to queue @@ -222,7 +222,7 @@ private: * @param status the status to set * @return */ - bool updateRequestStatus(const uint32_t &token, const uint32_t &status); + bool locked_updateRequestStatus(const uint32_t &token, const uint32_t &status); /*! * Use to query the status and other values of a given token diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 8c579dee9..43e24aedf 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -1,733 +1,671 @@ TEMPLATE = lib -#CONFIG += staticlib release -#CONFIG += staticlib testnetwork -CONFIG += staticlib bitdht + +# CONFIG += staticlib release +# CONFIG += staticlib testnetwork +CONFIG += staticlib \ + bitdht CONFIG -= qt TARGET = retroshare - -CONFIG += test_voip +CONFIG += test_voip # GXS Stuff. CONFIG += newcache CONFIG += newservices # Beware: All data of the stripped services are lost -DEFINES *= PQI_DISABLE_TUNNEL -#ENABLE_CACHE_OPT +DEFINES *= PQI_DISABLE_TUNNEL -profiling { - QMAKE_CXXFLAGS -= -fomit-frame-pointer - QMAKE_CXXFLAGS *= -pg -g -fno-omit-frame-pointer -} - -release { - # UDP and TUNNEL dont work anymore. - #DEFINES *= PQI_DISABLE_UDP +# ENABLE_CACHE_OPT +profiling { + QMAKE_CXXFLAGS -= -fomit-frame-pointer + QMAKE_CXXFLAGS *= -pg \ + -g \ + -fno-omit-frame-pointer } +release: +# UDP and TUNNEL dont work anymore. +# DEFINES *= PQI_DISABLE_UDP # treat warnings as error for better removing -#QMAKE_CFLAGS += -Werror -#QMAKE_CXXFLAGS += -Werror - -testnetwork { - # used in rsserver/rsinit.cc Enabled Port Restrictions, and makes Proxy Port next to Dht Port. - DEFINES *= LOCALNET_TESTING - - # used in tcponudp/udprelay.cc Debugging Info for Relays. - DEFINES *= DEBUG_UDP_RELAY - - # used in tcponudp/udpstunner.[h | cc] enables local stun (careful - modifies class variables). - DEFINES *= UDPSTUN_ALLOW_LOCALNET - - # used in pqi/p3linkmgr.cc prints out extra debug. - DEFINES *= LINKMGR_DEBUG_LINKTYPE - - # used in dht/connectstatebox to reduce connection times and display debug. - # DEFINES *= TESTING_PERIODS - # DEFINES *= DEBUG_CONNECTBOX - - QMAKE_CXXFLAGS -= -fomit-frame-pointer - QMAKE_CXXFLAGS -= -O2 - QMAKE_CXXFLAGS *= -g -fno-omit-frame-pointer - +# QMAKE_CFLAGS += -Werror +# QMAKE_CXXFLAGS += -Werror +testnetwork { + # used in rsserver/rsinit.cc Enabled Port Restrictions, and makes Proxy Port next to Dht Port. + DEFINES *= LOCALNET_TESTING + + # used in tcponudp/udprelay.cc Debugging Info for Relays. + DEFINES *= DEBUG_UDP_RELAY + + # used in tcponudp/udpstunner.[h | cc] enables local stun (careful - modifies class variables). + DEFINES *= UDPSTUN_ALLOW_LOCALNET + + # used in pqi/p3linkmgr.cc prints out extra debug. + DEFINES *= LINKMGR_DEBUG_LINKTYPE + + # used in dht/connectstatebox to reduce connection times and display debug. + # DEFINES *= TESTING_PERIODS + # DEFINES *= DEBUG_CONNECTBOX + QMAKE_CXXFLAGS -= -fomit-frame-pointer + QMAKE_CXXFLAGS -= -O2 + QMAKE_CXXFLAGS *= -g \ + -fno-omit-frame-pointer } - - CONFIG += debug -debug { -# DEFINES *= DEBUG -# DEFINES *= OPENDHT_DEBUG DHT_DEBUG CONN_DEBUG DEBUG_UDP_SORTER P3DISC_DEBUG DEBUG_UDP_LAYER FT_DEBUG EXTADDRSEARCH_DEBUG -# DEFINES *= CONTROL_DEBUG FT_DEBUG DEBUG_FTCHUNK P3TURTLE_DEBUG -# DEFINES *= P3TURTLE_DEBUG -# DEFINES *= NET_DEBUG -# DEFINES *= DISTRIB_DEBUG -# DEFINES *= P3TURTLE_DEBUG FT_DEBUG DEBUG_FTCHUNK MPLEX_DEBUG -# DEFINES *= STATUS_DEBUG SERV_DEBUG RSSERIAL_DEBUG #CONN_DEBUG - - QMAKE_CXXFLAGS -= -O2 -fomit-frame-pointer - QMAKE_CXXFLAGS *= -g -fno-omit-frame-pointer +debug { + # DEFINES *= DEBUG + # DEFINES *= OPENDHT_DEBUG DHT_DEBUG CONN_DEBUG DEBUG_UDP_SORTER P3DISC_DEBUG DEBUG_UDP_LAYER FT_DEBUG EXTADDRSEARCH_DEBUG + # DEFINES *= CONTROL_DEBUG FT_DEBUG DEBUG_FTCHUNK P3TURTLE_DEBUG + # DEFINES *= P3TURTLE_DEBUG + # DEFINES *= NET_DEBUG + # DEFINES *= DISTRIB_DEBUG + # DEFINES *= P3TURTLE_DEBUG FT_DEBUG DEBUG_FTCHUNK MPLEX_DEBUG + # DEFINES *= STATUS_DEBUG SERV_DEBUG RSSERIAL_DEBUG #CONN_DEBUG + QMAKE_CXXFLAGS -= -O2 \ + -fomit-frame-pointer + QMAKE_CXXFLAGS *= -g \ + -fno-omit-frame-pointer +} +bitdht { + HEADERS += dht/p3bitdht.h \ + dht/connectstatebox.h \ + dht/stunaddrassist.h + SOURCES += dht/p3bitdht.cc \ + dht/p3bitdht_interface.cc \ + dht/p3bitdht_peers.cc \ + dht/p3bitdht_peernet.cc \ + dht/p3bitdht_relay.cc \ + dht/connectstatebox.cc + HEADERS += tcponudp/udppeer.h \ + tcponudp/bio_tou.h \ + tcponudp/tcppacket.h \ + tcponudp/tcpstream.h \ + tcponudp/tou.h \ + tcponudp/udpstunner.h \ + tcponudp/udprelay.h + SOURCES += tcponudp/udppeer.cc \ + tcponudp/tcppacket.cc \ + tcponudp/tcpstream.cc \ + tcponudp/tou.cc \ + tcponudp/bss_tou.c \ + tcponudp/udpstunner.cc \ + tcponudp/udprelay.cc + + # These two aren't actually used (and don't compile) .... + # but could be useful later + # tcponudp/udpstunner.h \ + # tcponudp/udpstunner.cc \ + BITDHT_DIR = ../../libbitdht/src + INCLUDEPATH += . \ + $${BITDHT_DIR} + + # The next line if for compliance with debian packages. Keep it! + INCLUDEPATH += ../libbitdht + DEFINES *= RS_USE_BITDHT +} +test_bitdht { + # DISABLE TCP CONNECTIONS... + DEFINES *= P3CONNMGR_NO_TCP_CONNECTIONS + + # NO AUTO CONNECTIONS??? FOR TESTING DHT STATUS. + DEFINES *= P3CONNMGR_NO_AUTO_CONNECTION } -bitdht { - -HEADERS += dht/p3bitdht.h \ - dht/connectstatebox.h \ - dht/stunaddrassist.h - -SOURCES += dht/p3bitdht.cc \ - dht/p3bitdht_interface.cc \ - dht/p3bitdht_peers.cc \ - dht/p3bitdht_peernet.cc \ - dht/p3bitdht_relay.cc \ - dht/connectstatebox.cc - -HEADERS += tcponudp/udppeer.h \ - tcponudp/bio_tou.h \ - tcponudp/tcppacket.h \ - tcponudp/tcpstream.h \ - tcponudp/tou.h \ - tcponudp/udpstunner.h \ - tcponudp/udprelay.h \ - -SOURCES += tcponudp/udppeer.cc \ - tcponudp/tcppacket.cc \ - tcponudp/tcpstream.cc \ - tcponudp/tou.cc \ - tcponudp/bss_tou.c \ - tcponudp/udpstunner.cc \ - tcponudp/udprelay.cc \ - -# These two aren't actually used (and don't compile) .... -# but could be useful later -# -# tcponudp/udpstunner.h \ -# tcponudp/udpstunner.cc \ -# - - - BITDHT_DIR = ../../libbitdht/src - INCLUDEPATH += . $${BITDHT_DIR} - # The next line if for compliance with debian packages. Keep it! - INCLUDEPATH += ../libbitdht - DEFINES *= RS_USE_BITDHT +# ENABLED UDP NOW. +use_blogs { + HEADERS += services/p3blogs.h + SOURCES += services/p3blogs.cc + DEFINES *= RS_USE_BLOGS } - - - -test_bitdht { - # DISABLE TCP CONNECTIONS... - DEFINES *= P3CONNMGR_NO_TCP_CONNECTIONS - - # NO AUTO CONNECTIONS??? FOR TESTING DHT STATUS. - DEFINES *= P3CONNMGR_NO_AUTO_CONNECTION - - # ENABLED UDP NOW. -} - - - - -use_blogs { - - HEADERS += services/p3blogs.h - SOURCES += services/p3blogs.cc - - DEFINES *= RS_USE_BLOGS -} - - - -PUBLIC_HEADERS = retroshare/rsblogs.h \ - retroshare/rschannels.h \ - retroshare/rsdisc.h \ - retroshare/rsdistrib.h \ - retroshare/rsexpr.h \ - retroshare/rsfiles.h \ - retroshare/rsforums.h \ - retroshare/rshistory.h \ - retroshare/rsiface.h \ - retroshare/rsinit.h \ - retroshare/rsplugin.h \ - retroshare/rsloginhandler.h \ - retroshare/rsmsgs.h \ - retroshare/rsnotify.h \ - retroshare/rspeers.h \ - retroshare/rsrank.h \ - retroshare/rsstatus.h \ - retroshare/rsturtle.h \ - retroshare/rstypes.h \ - retroshare/rsdht.h \ - retroshare/rsdsdv.h \ - retroshare/rsconfig.h - +PUBLIC_HEADERS = retroshare/rsblogs.h \ + retroshare/rschannels.h \ + retroshare/rsdisc.h \ + retroshare/rsdistrib.h \ + retroshare/rsexpr.h \ + retroshare/rsfiles.h \ + retroshare/rsforums.h \ + retroshare/rshistory.h \ + retroshare/rsiface.h \ + retroshare/rsinit.h \ + retroshare/rsplugin.h \ + retroshare/rsloginhandler.h \ + retroshare/rsmsgs.h \ + retroshare/rsnotify.h \ + retroshare/rspeers.h \ + retroshare/rsrank.h \ + retroshare/rsstatus.h \ + retroshare/rsturtle.h \ + retroshare/rstypes.h \ + retroshare/rsdht.h \ + retroshare/rsdsdv.h \ + retroshare/rsconfig.h HEADERS += plugins/pluginmanager.h \ - plugins/dlfcn_win32.h \ - serialiser/rspluginitems.h - + plugins/dlfcn_win32.h \ + serialiser/rspluginitems.h HEADERS += $$PUBLIC_HEADERS # public headers to be... -HEADERS += retroshare/rsgame.h \ - retroshare/rsphoto.h +HEADERS += retroshare/rsgame.h \ + retroshare/rsphoto.h + +# ################################ Linux ########################################## +linux-*:isEmpty(PREFIX) { + PREFIX = /usr \ + } + isEmpty(INC_DIR) { + INC_DIR = $${PREFIX}/include/retroshare/ \ + } + isEmpty(LIB_DIR) { + LIB_DIR = $${PREFIX}/lib/ \ + } + + # These two lines fixe compilation on ubuntu natty. Probably a ubuntu packaging error. + INCLUDEPATH *= /usr/lib/x86_64-linux-gnu/glib-2.0/include/ + INCLUDEPATH *= /usr/lib/i386-linux-gnu/glib-2.0/include/ + OPENPGPSDK_DIR = ../../openpgpsdk/src + INCLUDEPATH *= $${OPENPGPSDK_DIR} \ + ../openpgpsdk + DESTDIR = lib + QMAKE_CXXFLAGS *= -Wall \ + -D_FILE_OFFSET_BITS=64 + QMAKE_CC = g++ + SSL_DIR = /usr/include/openssl + UPNP_DIR = /usr/include/upnp + INCLUDEPATH += . \ + $${SSL_DIR} \ + $${UPNP_DIR} + + # gpg files + system(which gpg-error-config >/dev/null 2>&1):INCLUDEPATH += $$system(gpg-error-config --cflags | sed -e "s/-I//g") + else:message(Could not find gpg-error-config on your system, assuming gpg-error.h is in /usr/include) + system(which gpgme-config >/dev/null 2>&1):INCLUDEPATH += $$system(gpgme-config --cflags | sed -e "s/-I//g") + else:message(Could not find gpgme-config on your system, assuming gpgme.h is in /usr/include) + + # libupnp implementation files + HEADERS += upnp/UPnPBase.h + SOURCES += upnp/UPnPBase.cpp + + # where to put the shared library itself + target.path = $$LIB_DIR + INSTALLS *= target + + # where to put the library's interface + include_rsiface.path = $${INC_DIR} + include_rsiface.files = $$PUBLIC_HEADERS + INSTALLS += include_rsiface + + # CONFIG += version_detail_bash_script + DEFINES *= UBUNTU + INCLUDEPATH += /usr/include/glib-2.0/ \ + /usr/lib/glib-2.0/include + LIBS *= -lgnome-keyring + + linux-g++:OBJECTS_DIR = temp/linux-g++/obj + linux-g++-64:OBJECTS_DIR = temp/linux-g++-64/obj + version_detail_bash_script { + QMAKE_EXTRA_TARGETS += write_version_detail + PRE_TARGETDEPS = write_version_detail + write_version_detail.commands = ./version_detail.sh + } + + # ################### Cross compilation for windows under Linux #################### + win32-x-g++ { + OBJECTS_DIR = temp/win32xgcc/obj + DESTDIR = lib.win32xgcc + DEFINES *= WINDOWS_SYS \ + WIN32 \ + WIN_CROSS_UBUNTU + QMAKE_CXXFLAGS *= -Wmissing-include-dirs + QMAKE_CC = i586-mingw32msvc-g++ + QMAKE_LIB = i586-mingw32msvc-ar + QMAKE_AR = i586-mingw32msvc-ar + DEFINES *= STATICLIB \ + WIN32 + + # miniupnp implementation files + HEADERS += upnp/upnputil.h + SOURCES += upnp/upnputil.c + SSL_DIR = ../../../../openssl + UPNPC_DIR = ../../../../miniupnpc-1.3 + GPG_ERROR_DIR = ../../../../libgpg-error-1.7 + GPGME_DIR = ../../../../gpgme-1.1.8 + INCLUDEPATH *= /usr/i586-mingw32msvc/include \ + ${HOME}/.wine/drive_c/pthreads/include/ + } + + # ################################ Windows ########################################## + win32 { + QMAKE_CC = g++ + OBJECTS_DIR = temp/obj + MOC_DIR = temp/moc + DEFINES *= WINDOWS_SYS \ + WIN32 \ + STATICLIB \ + MINGW + DEFINES *= MINIUPNPC_VERSION=13 + DESTDIR = lib + + # Switch on extra warnings + QMAKE_CFLAGS += -Wextra + QMAKE_CXXFLAGS += -Wextra + + # Switch off optimization for release version + QMAKE_CXXFLAGS_RELEASE -= -O2 + QMAKE_CXXFLAGS_RELEASE += -O0 + QMAKE_CFLAGS_RELEASE -= -O2 + QMAKE_CFLAGS_RELEASE += -O0 + + # Switch on optimization for debug version + # QMAKE_CXXFLAGS_DEBUG += -O2 + # QMAKE_CFLAGS_DEBUG += -O2 + DEFINES += USE_CMD_ARGS + + # miniupnp implementation files + HEADERS += upnp/upnputil.h + SOURCES += upnp/upnputil.c + UPNPC_DIR = ../../../miniupnpc-1.3 + PTHREADS_DIR = ../../../pthreads-w32-2-8-0-release + ZLIB_DIR = ../../../zlib-1.2.3 + SSL_DIR = ../../../openssl-1.0.1c + OPENPGPSDK_DIR = ../../openpgpsdk/src + INCLUDEPATH += . \ + $${SSL_DIR}/include \ + $${UPNPC_DIR} \ + $${PTHREADS_DIR} \ + $${ZLIB_DIR} \ + $${OPENPGPSDK_DIR} + newcache { + SQLITE_DIR = ../../../sqlite-autoconf-3071300 + INCLUDEPATH += . \ + $${SQLITE_DIR} + } + } + + # ################################ MacOSX ########################################## + mac { + QMAKE_CC = g++ + OBJECTS_DIR = temp/obj + MOC_DIR = temp/moc + + # DEFINES = WINDOWS_SYS WIN32 STATICLIB MINGW + # DEFINES *= MINIUPNPC_VERSION=13 + DESTDIR = lib + + # miniupnp implementation files + HEADERS += upnp/upnputil.h + SOURCES += upnp/upnputil.c + + # zeroconf disabled at the end of libretroshare.pro (but need the code) + CONFIG += zeroconf + CONFIG += zcnatassist + + # Beautiful Hack to fix 64bit file access. + QMAKE_CXXFLAGS *= -Dfseeko64=fseeko \ + -Dftello64=ftello \ + -Dfopen64=fopen \ + -Dvstatfs64=vstatfs + UPNPC_DIR = ../../../miniupnpc-1.0 + + # GPG_ERROR_DIR = ../../../../libgpg-error-1.7 + # GPGME_DIR = ../../../../gpgme-1.1.8 + OPENPGPSDK_DIR = ../../openpgpsdk/src + INCLUDEPATH += . \ + $${UPNPC_DIR} + INCLUDEPATH += $${OPENPGPSDK_DIR} + } + + # ../openpgpsdk + # INCLUDEPATH += . $${UPNPC_DIR} $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src + # ################################ FreeBSD ########################################## + freebsd-* { + INCLUDEPATH *= /usr/local/include/gpgme + INCLUDEPATH *= /usr/local/include/glib-2.0 + QMAKE_CXXFLAGS *= -Dfseeko64=fseeko \ + -Dftello64=ftello \ + -Dstat64=stat \ + -Dstatvfs64=statvfs \ + -Dfopen64=fopen + + # libupnp implementation files + HEADERS += upnp/UPnPBase.h + SOURCES += upnp/UPnPBase.cpp + DESTDIR = lib + } + + # ################################## COMMON stuff ################################## + HEADERS += dbase/cachestrapper.h \ + dbase/fimonitor.h \ + dbase/findex.h \ + dbase/fistore.h + + # HEADERS += dht/p3bitdht.h \ + HEADERS += ft/ftchunkmap.h \ + ft/ftcontroller.h \ + ft/ftdata.h \ + ft/ftdatamultiplex.h \ + ft/ftdbase.h \ + ft/ftextralist.h \ + ft/ftfilecreator.h \ + ft/ftfileprovider.h \ + ft/ftfilesearch.h \ + ft/ftsearch.h \ + ft/ftserver.h \ + ft/fttransfermodule.h + HEADERS += pqi/authssl.h \ + pqi/authgpg.h \ + pgp/pgphandler.h \ + pgp/pgpkeyutil.h \ + pqi/cleanupxpgp.h \ + pqi/p3cfgmgr.h \ + pqi/p3peermgr.h \ + pqi/p3linkmgr.h \ + pqi/p3netmgr.h \ + pqi/p3dhtmgr.h \ + pqi/p3notify.h \ + pqi/p3upnpmgr.h \ + pqi/pqiqos.h \ + pqi/pqi.h \ + pqi/pqi_base.h \ + pqi/pqiarchive.h \ + pqi/pqiassist.h \ + pqi/pqibin.h \ + pqi/pqihandler.h \ + pqi/pqihash.h \ + pqi/p3historymgr.h \ + pqi/pqiindic.h \ + pqi/pqiipset.h \ + pqi/pqilistener.h \ + pqi/pqiloopback.h \ + pqi/pqimonitor.h \ + pqi/pqinetwork.h \ + pqi/pqinotify.h \ + pqi/pqiperson.h \ + pqi/pqipersongrp.h \ + pqi/pqisecurity.h \ + pqi/pqiservice.h \ + pqi/pqissl.h \ + pqi/pqissllistener.h \ + pqi/pqisslpersongrp.h \ + pqi/pqissltunnel.h \ + pqi/pqissludp.h \ + pqi/pqistore.h \ + pqi/pqistreamer.h \ + pqi/pqiqosstreamer.h \ + pqi/sslfns.h \ + pqi/pqinetstatebox.h + HEADERS += rsserver/p3discovery.h \ + rsserver/p3face.h \ + rsserver/p3history.h \ + rsserver/p3msgs.h \ + rsserver/p3peers.h \ + rsserver/p3status.h \ + rsserver/p3serverconfig.h + HEADERS += serialiser/rsbaseitems.h \ + serialiser/rsbaseserial.h \ + serialiser/rsblogitems.h \ + serialiser/rschannelitems.h \ + serialiser/rsconfigitems.h \ + serialiser/rsdiscitems.h \ + serialiser/rsdistribitems.h \ + serialiser/rsforumitems.h \ + serialiser/rsgameitems.h \ + serialiser/rshistoryitems.h \ + serialiser/rsmsgitems.h \ + serialiser/rsserial.h \ + serialiser/rsserviceids.h \ + serialiser/rsserviceitems.h \ + serialiser/rsstatusitems.h \ + serialiser/rstlvaddrs.h \ + serialiser/rstlvbase.h \ + serialiser/rstlvkeys.h \ + serialiser/rstlvkvwide.h \ + serialiser/rstlvtypes.h \ + serialiser/rstlvutil.h \ + serialiser/rstlvdsdv.h \ + serialiser/rsdsdvitems.h \ + serialiser/rstlvbanlist.h \ + serialiser/rsbanlistitems.h \ + serialiser/rsbwctrlitems.h \ + serialiser/rstunnelitems.h + HEADERS += services/p3channels.h \ + services/p3chatservice.h \ + services/p3disc.h \ + services/p3forums.h \ + services/p3gamelauncher.h \ + services/p3gameservice.h \ + services/p3msgservice.h \ + services/p3service.h \ + services/p3statusservice.h \ + services/p3dsdv.h \ + services/p3banlist.h \ + services/p3bwctrl.h \ + services/p3tunnel.h + HEADERS += distrib/p3distrib.h \ + distrib/p3distribsecurity.h + + # services/p3blogs.h \ + HEADERS += turtle/p3turtle.h \ + turtle/rsturtleitem.h \ + turtle/turtletypes.h + HEADERS += upnp/upnphandler.h + HEADERS += util/folderiterator.h \ + util/rsdebug.h \ + util/smallobject.h \ + util/rsdir.h \ + util/rsdiscspace.h \ + util/rsnet.h \ + util/extaddrfinder.h \ + util/dnsresolver.h \ + util/rsprint.h \ + util/rsstring.h \ + util/rsthreads.h \ + util/rsversion.h \ + util/rswin.h \ + util/rsrandom.h \ + util/radix64.h \ + util/pugiconfig.h + SOURCES += dbase/cachestrapper.cc \ + dbase/fimonitor.cc \ + dbase/findex.cc \ + dbase/fistore.cc \ + dbase/rsexpr.cc + SOURCES += ft/ftchunkmap.cc \ + ft/ftcontroller.cc \ + ft/ftdata.cc \ + ft/ftdatamultiplex.cc \ + ft/ftdbase.cc \ + ft/ftextralist.cc \ + ft/ftfilecreator.cc \ + ft/ftfileprovider.cc \ + ft/ftfilesearch.cc \ + ft/ftserver.cc \ + ft/fttransfermodule.cc + SOURCES += pqi/authgpg.cc \ + pqi/authssl.cc \ + pgp/pgphandler.cc \ + pgp/pgpkeyutil.cc \ + pqi/cleanupxpgp.cc \ + pqi/p3cfgmgr.cc \ + pqi/p3peermgr.cc \ + pqi/p3linkmgr.cc \ + pqi/p3netmgr.cc \ + pqi/p3dhtmgr.cc \ + pqi/p3notify.cc \ + pqi/pqiqos.cc \ + pqi/pqiarchive.cc \ + pqi/pqibin.cc \ + pqi/pqihandler.cc \ + pqi/p3historymgr.cc \ + pqi/pqiipset.cc \ + pqi/pqiloopback.cc \ + pqi/pqimonitor.cc \ + pqi/pqinetwork.cc \ + pqi/pqiperson.cc \ + pqi/pqipersongrp.cc \ + pqi/pqisecurity.cc \ + pqi/pqiservice.cc \ + pqi/pqissl.cc \ + pqi/pqissllistener.cc \ + pqi/pqisslpersongrp.cc \ + pqi/pqissltunnel.cc \ + pqi/pqissludp.cc \ + pqi/pqistore.cc \ + pqi/pqistreamer.cc \ + pqi/pqiqosstreamer.cc \ + pqi/sslfns.cc \ + pqi/pqinetstatebox.cc + SOURCES += rsserver/p3discovery.cc \ + rsserver/p3face-config.cc \ + rsserver/p3face-msgs.cc \ + rsserver/p3face-server.cc \ + rsserver/p3history.cc \ + rsserver/p3msgs.cc \ + rsserver/p3peers.cc \ + rsserver/p3status.cc \ + rsserver/rsiface.cc \ + rsserver/rsinit.cc \ + rsserver/rsloginhandler.cc \ + rsserver/rstypes.cc \ + rsserver/p3serverconfig.cc + SOURCES += plugins/pluginmanager.cc \ + plugins/dlfcn_win32.cc \ + serialiser/rspluginitems.cc + SOURCES += serialiser/rsbaseitems.cc \ + serialiser/rsbaseserial.cc \ + serialiser/rsblogitems.cc \ + serialiser/rschannelitems.cc \ + serialiser/rsconfigitems.cc \ + serialiser/rsdiscitems.cc \ + serialiser/rsdistribitems.cc \ + serialiser/rsforumitems.cc \ + serialiser/rsgameitems.cc \ + serialiser/rshistoryitems.cc \ + serialiser/rsmsgitems.cc \ + serialiser/rsserial.cc \ + serialiser/rsstatusitems.cc \ + serialiser/rstlvaddrs.cc \ + serialiser/rstlvbase.cc \ + serialiser/rstlvfileitem.cc \ + serialiser/rstlvimage.cc \ + serialiser/rstlvkeys.cc \ + serialiser/rstlvkvwide.cc \ + serialiser/rstlvtypes.cc \ + serialiser/rstlvutil.cc \ + serialiser/rstlvdsdv.cc \ + serialiser/rsdsdvitems.cc \ + serialiser/rstlvbanlist.cc \ + serialiser/rsbanlistitems.cc \ + serialiser/rsbwctrlitems.cc \ + serialiser/rstunnelitems.cc + SOURCES += services/p3channels.cc \ + services/p3chatservice.cc \ + services/p3disc.cc \ + services/p3forums.cc \ + services/p3gamelauncher.cc \ + services/p3msgservice.cc \ + services/p3service.cc \ + services/p3statusservice.cc \ + services/p3dsdv.cc \ + services/p3banlist.cc \ + services/p3bwctrl.cc + + # removed because getPeer() doesn t exist services/p3tunnel.cc + SOURCES += distrib/p3distrib.cc \ + distrib/p3distribsecurity.cc + SOURCES += turtle/p3turtle.cc \ + turtle/rsturtleitem.cc + + # turtle/turtlerouting.cc \ + # turtle/turtlesearch.cc \ + # turtle/turtletunnels.cc + SOURCES += upnp/upnphandler.cc + SOURCES += util/folderiterator.cc \ + util/rsdebug.cc \ + util/smallobject.cc \ + util/rsdir.cc \ + util/rsdiscspace.cc \ + util/rsnet.cc \ + util/extaddrfinder.cc \ + util/dnsresolver.cc \ + util/rsprint.cc \ + util/rsstring.cc \ + util/rsthreads.cc \ + util/rsversion.cc \ + util/rswin.cc \ + util/rsrandom.cc + zeroconf { + HEADERS += zeroconf/p3zeroconf.h + SOURCES += zeroconf/p3zeroconf.cc + } + + # Disable Zeroconf (we still need the code for zcnatassist + # DEFINES *= RS_ENABLE_ZEROCONF + # This is seperated from the above for windows/linux platforms. + # It is acceptable to build in zeroconf and have it not work, + # but unacceptable to rely on Apple's libraries for Upnp when we have alternatives. ' + zcnatassist { + HEADERS += zeroconf/p3zcnatassist.h + SOURCES += zeroconf/p3zcnatassist.cc + DEFINES *= RS_ENABLE_ZCNATASSIST + } + + # new gxs cache system + newcache { + HEADERS += serialiser/rsnxsitems.h \ + gxs/rsgds.h \ + gxs/rsgxs.h \ + gxs/rsdataservice.h \ + gxs/rsgxsnetservice.h \ + gxs/rsgxsflags.h \ + gxs/rsgenexchange.h \ + gxs/rsnxsobserver.h \ + gxs/rsgxsdata.h \ + gxs/rstokenservice.h \ + gxs/rsgxsdataaccess.h \ + retroshare/rsgxsservice.h \ + serialiser/rsgxsitems.h \ + serialiser/rsphotov2items.h \ + util/retrodb.h \ + gxs/gxscoreserver.h \ + gxs/gxssecurity.h + SOURCES += serialiser/rsnxsitems.cc \ + gxs/rsdataservice.cc \ + gxs/rsgenexchange.cc \ + gxs/rsgxsnetservice.cc \ + gxs/rsgxsdata.cc \ + serialiser/rsgxsitems.cc \ + services/p3photoserviceV2.cc \ + gxs/rsgxsdataaccess.cc \ + serialiser/rsphotov2items.cc \ + util/retrodb.cc \ + gxs/gxscoreserver.cc \ + gxs/gxssecurity.cc + } + newservices { + HEADERS += services/p3photoservice.h \ + serialiser/rsphotoitems.h \ + retroshare/rsphoto.h \ + services/p3gxsservice.h \ + retroshare/rsidentity.h \ + services/p3wikiservice.h \ + retroshare/rswiki.h \ + retroshare/rswire.h \ + services/p3wire.h \ + services/p3idservice.h \ + retroshare/rsforumsv2.h \ + services/p3forumsv2.h \ + retroshare/rsposted.h \ + services/p3posted.h \ + services/p3photoserviceV2.h \ + retroshare/rsphotoV2.h + SOURCES += services/p3photoservice.cc \ + serialiser/rsphotoitems.cc \ + services/p3gxsservice.cc \ + services/p3wikiservice.cc \ + services/p3wire.cc \ + services/p3idservice.cc \ + services/p3forumsv2.cc \ + services/p3posted.cc + } -################################# Linux ########################################## -linux-* { - isEmpty(PREFIX) { PREFIX = /usr } - isEmpty(INC_DIR) { INC_DIR = $${PREFIX}/include/retroshare/ } - isEmpty(LIB_DIR) { LIB_DIR = $${PREFIX}/lib/ } - - # These two lines fixe compilation on ubuntu natty. Probably a ubuntu packaging error. - INCLUDEPATH *= /usr/lib/x86_64-linux-gnu/glib-2.0/include/ - INCLUDEPATH *= /usr/lib/i386-linux-gnu/glib-2.0/include/ - - OPENPGPSDK_DIR = ../../openpgpsdk/src - INCLUDEPATH *= $${OPENPGPSDK_DIR} ../openpgpsdk - - DESTDIR = lib - QMAKE_CXXFLAGS *= -Wall -D_FILE_OFFSET_BITS=64 - QMAKE_CC = g++ - - SSL_DIR = /usr/include/openssl - UPNP_DIR = /usr/include/upnp - INCLUDEPATH += . $${SSL_DIR} $${UPNP_DIR} - - #gpg files - system(which gpg-error-config >/dev/null 2>&1) { - INCLUDEPATH += $$system(gpg-error-config --cflags | sed -e "s/-I//g") - } else { - message(Could not find gpg-error-config on your system, assuming gpg-error.h is in /usr/include) - } - system(which gpgme-config >/dev/null 2>&1) { - INCLUDEPATH += $$system(gpgme-config --cflags | sed -e "s/-I//g") - } else { - message(Could not find gpgme-config on your system, assuming gpgme.h is in /usr/include) - } - - #libupnp implementation files - HEADERS += upnp/UPnPBase.h - SOURCES += upnp/UPnPBase.cpp - - # where to put the shared library itself - target.path = $$LIB_DIR - INSTALLS *= target - - # where to put the library's interface - include_rsiface.path = $${INC_DIR} - include_rsiface.files = $$PUBLIC_HEADERS - INSTALLS += include_rsiface - - #CONFIG += version_detail_bash_script - - DEFINES *= UBUNTU - INCLUDEPATH += /usr/include/glib-2.0/ /usr/lib/glib-2.0/include - LIBS *= -lgnome-keyring -} - -linux-g++ { - OBJECTS_DIR = temp/linux-g++/obj -} - -linux-g++-64 { - OBJECTS_DIR = temp/linux-g++-64/obj -} - -version_detail_bash_script { - QMAKE_EXTRA_TARGETS += write_version_detail - PRE_TARGETDEPS = write_version_detail - write_version_detail.commands = ./version_detail.sh -} - -#################### Cross compilation for windows under Linux #################### - -win32-x-g++ { - OBJECTS_DIR = temp/win32xgcc/obj - DESTDIR = lib.win32xgcc - DEFINES *= WINDOWS_SYS WIN32 WIN_CROSS_UBUNTU - QMAKE_CXXFLAGS *= -Wmissing-include-dirs - QMAKE_CC = i586-mingw32msvc-g++ - QMAKE_LIB = i586-mingw32msvc-ar - QMAKE_AR = i586-mingw32msvc-ar - DEFINES *= STATICLIB WIN32 - - #miniupnp implementation files - HEADERS += upnp/upnputil.h - SOURCES += upnp/upnputil.c - - SSL_DIR=../../../../openssl - UPNPC_DIR = ../../../../miniupnpc-1.3 - GPG_ERROR_DIR = ../../../../libgpg-error-1.7 - GPGME_DIR = ../../../../gpgme-1.1.8 - - INCLUDEPATH *= /usr/i586-mingw32msvc/include ${HOME}/.wine/drive_c/pthreads/include/ -} -################################# Windows ########################################## - - -win32 { - QMAKE_CC = g++ - OBJECTS_DIR = temp/obj - MOC_DIR = temp/moc - DEFINES *= WINDOWS_SYS WIN32 STATICLIB MINGW - DEFINES *= MINIUPNPC_VERSION=13 - DESTDIR = lib - - # Switch on extra warnings - QMAKE_CFLAGS += -Wextra - QMAKE_CXXFLAGS += -Wextra - - # Switch off optimization for release version - QMAKE_CXXFLAGS_RELEASE -= -O2 - QMAKE_CXXFLAGS_RELEASE += -O0 - QMAKE_CFLAGS_RELEASE -= -O2 - QMAKE_CFLAGS_RELEASE += -O0 - - # Switch on optimization for debug version - #QMAKE_CXXFLAGS_DEBUG += -O2 - #QMAKE_CFLAGS_DEBUG += -O2 - - DEFINES += USE_CMD_ARGS - - #miniupnp implementation files - HEADERS += upnp/upnputil.h - SOURCES += upnp/upnputil.c - - UPNPC_DIR = ../../../miniupnpc-1.3 - - PTHREADS_DIR = ../../../pthreads-w32-2-8-0-release - ZLIB_DIR = ../../../zlib-1.2.3 - SSL_DIR = ../../../openssl-1.0.1c - OPENPGPSDK_DIR = ../../openpgpsdk/src - - INCLUDEPATH += . $${SSL_DIR}/include $${UPNPC_DIR} $${PTHREADS_DIR} $${ZLIB_DIR} $${OPENPGPSDK_DIR} - - newcache { - SQLITE_DIR = ../../../sqlite-autoconf-3071300 - INCLUDEPATH += . $${SQLITE_DIR} - } -} - - -################################# MacOSX ########################################## - -mac { - QMAKE_CC = g++ - OBJECTS_DIR = temp/obj - MOC_DIR = temp/moc - #DEFINES = WINDOWS_SYS WIN32 STATICLIB MINGW - #DEFINES *= MINIUPNPC_VERSION=13 - DESTDIR = lib - - #miniupnp implementation files - HEADERS += upnp/upnputil.h - SOURCES += upnp/upnputil.c - - # zeroconf disabled at the end of libretroshare.pro (but need the code) - CONFIG += zeroconf - CONFIG += zcnatassist - - # Beautiful Hack to fix 64bit file access. - QMAKE_CXXFLAGS *= -Dfseeko64=fseeko -Dftello64=ftello -Dfopen64=fopen -Dvstatfs64=vstatfs - - UPNPC_DIR = ../../../miniupnpc-1.0 - #GPG_ERROR_DIR = ../../../../libgpg-error-1.7 - #GPGME_DIR = ../../../../gpgme-1.1.8 - - OPENPGPSDK_DIR = ../../openpgpsdk/src - - INCLUDEPATH += . $${UPNPC_DIR} - INCLUDEPATH += $${OPENPGPSDK_DIR} - - #../openpgpsdk - #INCLUDEPATH += . $${UPNPC_DIR} $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src -} - -################################# FreeBSD ########################################## - -freebsd-* { - INCLUDEPATH *= /usr/local/include/gpgme - INCLUDEPATH *= /usr/local/include/glib-2.0 - - QMAKE_CXXFLAGS *= -Dfseeko64=fseeko -Dftello64=ftello -Dstat64=stat -Dstatvfs64=statvfs -Dfopen64=fopen - - #libupnp implementation files - HEADERS += upnp/UPnPBase.h - SOURCES += upnp/UPnPBase.cpp - DESTDIR = lib -} - -################################### COMMON stuff ################################## - -HEADERS += dbase/cachestrapper.h \ - dbase/fimonitor.h \ - dbase/findex.h \ - dbase/fistore.h - -#HEADERS += dht/p3bitdht.h \ - -HEADERS += ft/ftchunkmap.h \ - ft/ftcontroller.h \ - ft/ftdata.h \ - ft/ftdatamultiplex.h \ - ft/ftdbase.h \ - ft/ftextralist.h \ - ft/ftfilecreator.h \ - ft/ftfileprovider.h \ - ft/ftfilesearch.h \ - ft/ftsearch.h \ - ft/ftserver.h \ - ft/fttransfermodule.h - -HEADERS += pqi/authssl.h \ - pqi/authgpg.h \ - pgp/pgphandler.h \ - pgp/pgpkeyutil.h \ - pqi/cleanupxpgp.h \ - pqi/p3cfgmgr.h \ - pqi/p3peermgr.h \ - pqi/p3linkmgr.h \ - pqi/p3netmgr.h \ - pqi/p3dhtmgr.h \ - pqi/p3notify.h \ - pqi/p3upnpmgr.h \ - pqi/pqiqos.h \ - pqi/pqi.h \ - pqi/pqi_base.h \ - pqi/pqiarchive.h \ - pqi/pqiassist.h \ - pqi/pqibin.h \ - pqi/pqihandler.h \ - pqi/pqihash.h \ - pqi/p3historymgr.h \ - pqi/pqiindic.h \ - pqi/pqiipset.h \ - pqi/pqilistener.h \ - pqi/pqiloopback.h \ - pqi/pqimonitor.h \ - pqi/pqinetwork.h \ - pqi/pqinotify.h \ - pqi/pqiperson.h \ - pqi/pqipersongrp.h \ - pqi/pqisecurity.h \ - pqi/pqiservice.h \ - pqi/pqissl.h \ - pqi/pqissllistener.h \ - pqi/pqisslpersongrp.h \ - pqi/pqissltunnel.h \ - pqi/pqissludp.h \ - pqi/pqistore.h \ - pqi/pqistreamer.h \ - pqi/pqiqosstreamer.h \ - pqi/sslfns.h \ - pqi/pqinetstatebox.h - -HEADERS += rsserver/p3discovery.h \ - rsserver/p3face.h \ - rsserver/p3history.h \ - rsserver/p3msgs.h \ - rsserver/p3peers.h \ - rsserver/p3status.h \ - rsserver/p3serverconfig.h - -HEADERS += serialiser/rsbaseitems.h \ - serialiser/rsbaseserial.h \ - serialiser/rsblogitems.h \ - serialiser/rschannelitems.h \ - serialiser/rsconfigitems.h \ - serialiser/rsdiscitems.h \ - serialiser/rsdistribitems.h \ - serialiser/rsforumitems.h \ - serialiser/rsgameitems.h \ - serialiser/rshistoryitems.h \ - serialiser/rsmsgitems.h \ - serialiser/rsserial.h \ - serialiser/rsserviceids.h \ - serialiser/rsserviceitems.h \ - serialiser/rsstatusitems.h \ - serialiser/rstlvaddrs.h \ - serialiser/rstlvbase.h \ - serialiser/rstlvkeys.h \ - serialiser/rstlvkvwide.h \ - serialiser/rstlvtypes.h \ - serialiser/rstlvutil.h \ - serialiser/rstlvdsdv.h \ - serialiser/rsdsdvitems.h \ - serialiser/rstlvbanlist.h \ - serialiser/rsbanlistitems.h \ - serialiser/rsbwctrlitems.h \ - serialiser/rstunnelitems.h - -HEADERS += services/p3channels.h \ - services/p3chatservice.h \ - services/p3disc.h \ - services/p3forums.h \ - services/p3gamelauncher.h \ - services/p3gameservice.h \ - services/p3msgservice.h \ - services/p3service.h \ - services/p3statusservice.h \ - services/p3dsdv.h \ - services/p3banlist.h \ - services/p3bwctrl.h \ - services/p3tunnel.h - -HEADERS += distrib/p3distrib.h \ - distrib/p3distribsecurity.h -# services/p3blogs.h \ - -HEADERS += turtle/p3turtle.h \ - turtle/rsturtleitem.h \ - turtle/turtletypes.h - -HEADERS += upnp/upnphandler.h - -HEADERS += util/folderiterator.h \ - util/rsdebug.h \ - util/smallobject.h \ - util/rsdir.h \ - util/rsdiscspace.h \ - util/rsnet.h \ - util/extaddrfinder.h \ - util/dnsresolver.h \ - util/rsprint.h \ - util/rsstring.h \ - util/rsthreads.h \ - util/rsversion.h \ - util/rswin.h \ - util/rsrandom.h \ - util/radix64.h \ - util/pugiconfig.h \ - -SOURCES += dbase/cachestrapper.cc \ - dbase/fimonitor.cc \ - dbase/findex.cc \ - dbase/fistore.cc \ - dbase/rsexpr.cc - - -SOURCES += ft/ftchunkmap.cc \ - ft/ftcontroller.cc \ - ft/ftdata.cc \ - ft/ftdatamultiplex.cc \ - ft/ftdbase.cc \ - ft/ftextralist.cc \ - ft/ftfilecreator.cc \ - ft/ftfileprovider.cc \ - ft/ftfilesearch.cc \ - ft/ftserver.cc \ - ft/fttransfermodule.cc \ - -SOURCES += pqi/authgpg.cc \ - pqi/authssl.cc \ - pgp/pgphandler.cc \ - pgp/pgpkeyutil.cc \ - pqi/cleanupxpgp.cc \ - pqi/p3cfgmgr.cc \ - pqi/p3peermgr.cc \ - pqi/p3linkmgr.cc \ - pqi/p3netmgr.cc \ - pqi/p3dhtmgr.cc \ - pqi/p3notify.cc \ - pqi/pqiqos.cc \ - pqi/pqiarchive.cc \ - pqi/pqibin.cc \ - pqi/pqihandler.cc \ - pqi/p3historymgr.cc \ - pqi/pqiipset.cc \ - pqi/pqiloopback.cc \ - pqi/pqimonitor.cc \ - pqi/pqinetwork.cc \ - pqi/pqiperson.cc \ - pqi/pqipersongrp.cc \ - pqi/pqisecurity.cc \ - pqi/pqiservice.cc \ - pqi/pqissl.cc \ - pqi/pqissllistener.cc \ - pqi/pqisslpersongrp.cc \ - pqi/pqissltunnel.cc \ - pqi/pqissludp.cc \ - pqi/pqistore.cc \ - pqi/pqistreamer.cc \ - pqi/pqiqosstreamer.cc \ - pqi/sslfns.cc \ - pqi/pqinetstatebox.cc - -SOURCES += rsserver/p3discovery.cc \ - rsserver/p3face-config.cc \ - rsserver/p3face-msgs.cc \ - rsserver/p3face-server.cc \ - rsserver/p3history.cc \ - rsserver/p3msgs.cc \ - rsserver/p3peers.cc \ - rsserver/p3status.cc \ - rsserver/rsiface.cc \ - rsserver/rsinit.cc \ - rsserver/rsloginhandler.cc \ - rsserver/rstypes.cc \ - rsserver/p3serverconfig.cc - -SOURCES += plugins/pluginmanager.cc \ - plugins/dlfcn_win32.cc \ - serialiser/rspluginitems.cc - -SOURCES += serialiser/rsbaseitems.cc \ - serialiser/rsbaseserial.cc \ - serialiser/rsblogitems.cc \ - serialiser/rschannelitems.cc \ - serialiser/rsconfigitems.cc \ - serialiser/rsdiscitems.cc \ - serialiser/rsdistribitems.cc \ - serialiser/rsforumitems.cc \ - serialiser/rsgameitems.cc \ - serialiser/rshistoryitems.cc \ - serialiser/rsmsgitems.cc \ - serialiser/rsserial.cc \ - serialiser/rsstatusitems.cc \ - serialiser/rstlvaddrs.cc \ - serialiser/rstlvbase.cc \ - serialiser/rstlvfileitem.cc \ - serialiser/rstlvimage.cc \ - serialiser/rstlvkeys.cc \ - serialiser/rstlvkvwide.cc \ - serialiser/rstlvtypes.cc \ - serialiser/rstlvutil.cc \ - serialiser/rstlvdsdv.cc \ - serialiser/rsdsdvitems.cc \ - serialiser/rstlvbanlist.cc \ - serialiser/rsbanlistitems.cc \ - serialiser/rsbwctrlitems.cc \ - serialiser/rstunnelitems.cc - -SOURCES += services/p3channels.cc \ - services/p3chatservice.cc \ - services/p3disc.cc \ - services/p3forums.cc \ - services/p3gamelauncher.cc \ - services/p3msgservice.cc \ - services/p3service.cc \ - services/p3statusservice.cc \ - services/p3dsdv.cc \ - services/p3banlist.cc \ - services/p3bwctrl.cc \ - -# removed because getPeer() doesn t exist services/p3tunnel.cc - -SOURCES += distrib/p3distrib.cc \ - distrib/p3distribsecurity.cc - -SOURCES += turtle/p3turtle.cc \ - turtle/rsturtleitem.cc -# turtle/turtlerouting.cc \ -# turtle/turtlesearch.cc \ -# turtle/turtletunnels.cc - -SOURCES += upnp/upnphandler.cc - -SOURCES += util/folderiterator.cc \ - util/rsdebug.cc \ - util/smallobject.cc \ - util/rsdir.cc \ - util/rsdiscspace.cc \ - util/rsnet.cc \ - util/extaddrfinder.cc \ - util/dnsresolver.cc \ - util/rsprint.cc \ - util/rsstring.cc \ - util/rsthreads.cc \ - util/rsversion.cc \ - util/rswin.cc \ - util/rsrandom.cc \ - -zeroconf { - -HEADERS += zeroconf/p3zeroconf.h \ - -SOURCES += zeroconf/p3zeroconf.cc \ - -# Disable Zeroconf (we still need the code for zcnatassist -# DEFINES *= RS_ENABLE_ZEROCONF - -} - -# This is seperated from the above for windows/linux platforms. -# It is acceptable to build in zeroconf and have it not work, -# but unacceptable to rely on Apple's libraries for Upnp when we have alternatives. ' - -zcnatassist { - -HEADERS += zeroconf/p3zcnatassist.h \ - -SOURCES += zeroconf/p3zcnatassist.cc \ - - DEFINES *= RS_ENABLE_ZCNATASSIST - -} - - # new gxs cache system -newcache { - -HEADERS += serialiser/rsnxsitems.h \ - gxs/rsgds.h \ - gxs/rsgxs.h \ - gxs/rsdataservice.h \ - gxs/rsgxsnetservice.h \ - gxs/rsgxsflags.h \ - gxs/rsgenexchange.h \ - gxs/rsnxsobserver.h \ - gxs/rsgxsdata.h \ - gxs/rstokenservice.h \ - gxs/rsgxsdataaccess.h \ - retroshare/rsgxsservice.h \ - serialiser/rsgxsitems.h \ - serialiser/rsphotov2items.h \ - util/retrodb.h \ - gxs/gxscoreserver.h - -SOURCES += serialiser/rsnxsitems.cc \ - gxs/rsdataservice.cc \ - gxs/rsgenexchange.cc \ - gxs/rsgxsnetservice.cc \ - gxs/rsgxsdata.cc \ - serialiser/rsgxsitems.cc \ - services/p3photoserviceV2.cc \ - gxs/rsgxsdataaccess.cc \ - serialiser/rsphotov2items.cc \ - util/retrodb.cc \ - gxs/gxscoreserver.cc -} - - - -newservices { - -HEADERS += services/p3photoservice.h \ - serialiser/rsphotoitems.h \ - retroshare/rsphoto.h \ - services/p3gxsservice.h \ - retroshare/rsidentity.h \ - services/p3wikiservice.h \ - retroshare/rswiki.h \ - retroshare/rswire.h \ - services/p3wire.h \ - services/p3idservice.h \ - retroshare/rsforumsv2.h \ - services/p3forumsv2.h \ - retroshare/rsposted.h \ - services/p3posted.h \ - services/p3photoserviceV2.h \ - retroshare/rsphotoV2.h \ - - -SOURCES += services/p3photoservice.cc \ - serialiser/rsphotoitems.cc \ - services/p3gxsservice.cc \ - services/p3wikiservice.cc \ - services/p3wire.cc \ - services/p3idservice.cc \ - services/p3forumsv2.cc \ - services/p3posted.cc \ - -# Other Old Code. -# rsserver/p3photo.cc \ -} diff --git a/libretroshare/src/serialiser/rsnxsitems.h b/libretroshare/src/serialiser/rsnxsitems.h index 629468b89..37a4fffe8 100644 --- a/libretroshare/src/serialiser/rsnxsitems.h +++ b/libretroshare/src/serialiser/rsnxsitems.h @@ -196,7 +196,7 @@ public: RsTlvBinaryData grp; /// actual group data /*! - * This should contains all the data + * This should contains all data * which is not specific to the Gxs service data */ RsTlvBinaryData meta; diff --git a/libretroshare/src/services/p3photoserviceV2.cc b/libretroshare/src/services/p3photoserviceV2.cc index e8c747b88..392aeb6e9 100644 --- a/libretroshare/src/services/p3photoserviceV2.cc +++ b/libretroshare/src/services/p3photoserviceV2.cc @@ -13,12 +13,6 @@ bool p3PhotoServiceV2::updated() { bool changed = (!mGroupChange.empty() || !mMsgChange.empty()); - std::list gL; - std::map > msgs; - - groupsChanged(gL); - msgsChanged(msgs); - return changed; } diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp index 9dc756666..2fe80a10e 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp @@ -331,12 +331,8 @@ void PhotoAddDialog::publishAlbum() std::cerr << "PhotoAddDialog::publishAlbum() New Album Mode Submitting....."; std::cerr << std::endl; - uint32_t token; rsPhotoV2->submitAlbumDetails(album); - // tell tokenQueue to expect results from submission. - mPhotoQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_SUMMARY, 0); - } @@ -408,7 +404,6 @@ void PhotoAddDialog::publishPhotos(std::string albumId) std::cerr << "PhotoAddDialog::publishAlbum() Photo(" << i << ") "; - uint32_t token; if (isNewPhoto) { std::cerr << "Is a New Photo"; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index ddea51908..2acd19032 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -145,7 +145,15 @@ void PhotoDialog::checkUpdate() if (rsPhotoV2->updated()) { //insertAlbums(); - requestAlbumList(); + std::list grpIds; + rsPhotoV2->groupsChanged(grpIds); + if(!grpIds.empty()) + requestAlbumList(grpIds); + + GxsMsgIdResult res; + rsPhotoV2->msgsChanged(res); + if(!res.empty()) + requestPhotoList(res); } return; @@ -427,15 +435,23 @@ void PhotoDialog::deletePhotoItem(PhotoItem *item, uint32_t type) /**************************** Request / Response Filling of Data ************************/ -void PhotoDialog::requestAlbumList() +void PhotoDialog::requestAlbumList(std::list& ids) { - std::list ids; RsTokReqOptionsV2 opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; uint32_t token; mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, ids, 0); } +void PhotoDialog::requestPhotoList(GxsMsgReq& req) +{ + RsTokReqOptionsV2 opts; + uint32_t token; + mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, req, 0); + return; +} + void PhotoDialog::loadAlbumList(const uint32_t &token) { @@ -461,6 +477,7 @@ void PhotoDialog::requestAlbumData(std::list &ids) { RsTokReqOptionsV2 opts; uint32_t token; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, 0); } diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h index 339901c2e..0fc7575f8 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h @@ -58,8 +58,9 @@ private slots: private: /* Request Response Functions for loading data */ - void requestAlbumList(); + void requestAlbumList(std::list& ids); void requestAlbumData(std::list &ids); + void requestPhotoList(GxsMsgReq &albumIds); void requestPhotoList(const std::string &albumId); void requestPhotoData(GxsMsgReq &photoIds); From f51af0d4de170fb884e5aa74fabcf4b4dbe410a8 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Mon, 13 Aug 2012 21:35:11 +0000 Subject: [PATCH 023/222] FeedReader plugin: - added new classes for XML/HTML parse and modify - added basic error handling - added new GUI for a preview and a tree to show the structure of the page (will be continued) git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5412 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- plugins/FeedReader/FeedReader.pro | 17 +- plugins/FeedReader/gui/AddFeedDialog.cpp | 79 ++- plugins/FeedReader/gui/AddFeedDialog.h | 9 +- plugins/FeedReader/gui/AddFeedDialog.ui | 7 + plugins/FeedReader/gui/FeedReaderDialog.cpp | 38 +- plugins/FeedReader/gui/FeedReaderDialog.h | 6 +- .../FeedReader/gui/FeedReaderStringDefs.cpp | 130 +++++ plugins/FeedReader/gui/FeedReaderStringDefs.h | 39 ++ plugins/FeedReader/gui/PreviewFeedDialog.cpp | 427 ++++++++++++++++ plugins/FeedReader/gui/PreviewFeedDialog.h | 89 ++++ plugins/FeedReader/gui/PreviewFeedDialog.ui | 314 ++++++++++++ plugins/FeedReader/interface/rsFeedReader.h | 72 +-- plugins/FeedReader/services/p3FeedReader.cc | 470 ++++++++++++------ plugins/FeedReader/services/p3FeedReader.h | 53 +- .../FeedReader/services/p3FeedReaderThread.cc | 254 +++------- .../FeedReader/services/p3FeedReaderThread.h | 9 +- .../FeedReader/services/rsFeedReaderItems.cc | 5 +- .../FeedReader/services/rsFeedReaderItems.h | 49 +- .../CURLWrapper.cc => util/CURLWrapper.cpp} | 0 .../{services => }/util/CURLWrapper.h | 0 plugins/FeedReader/util/HTMLWrapper.cpp | 60 +++ plugins/FeedReader/util/HTMLWrapper.h | 36 ++ plugins/FeedReader/util/XMLWrapper.cpp | 245 +++++++++ plugins/FeedReader/util/XMLWrapper.h | 60 +++ 24 files changed, 1959 insertions(+), 509 deletions(-) create mode 100644 plugins/FeedReader/gui/FeedReaderStringDefs.cpp create mode 100644 plugins/FeedReader/gui/FeedReaderStringDefs.h create mode 100644 plugins/FeedReader/gui/PreviewFeedDialog.cpp create mode 100644 plugins/FeedReader/gui/PreviewFeedDialog.h create mode 100644 plugins/FeedReader/gui/PreviewFeedDialog.ui rename plugins/FeedReader/{services/util/CURLWrapper.cc => util/CURLWrapper.cpp} (100%) rename plugins/FeedReader/{services => }/util/CURLWrapper.h (100%) create mode 100644 plugins/FeedReader/util/HTMLWrapper.cpp create mode 100644 plugins/FeedReader/util/HTMLWrapper.h create mode 100644 plugins/FeedReader/util/XMLWrapper.cpp create mode 100644 plugins/FeedReader/util/XMLWrapper.h diff --git a/plugins/FeedReader/FeedReader.pro b/plugins/FeedReader/FeedReader.pro index 769797a66..3974acbae 100644 --- a/plugins/FeedReader/FeedReader.pro +++ b/plugins/FeedReader/FeedReader.pro @@ -6,25 +6,34 @@ SOURCES = FeedReaderPlugin.cpp \ services/p3FeedReader.cc \ services/p3FeedReaderThread.cc \ services/rsFeedReaderItems.cc \ - services/util/CURLWrapper.cc \ gui/FeedReaderDialog.cpp \ gui/AddFeedDialog.cpp \ + gui/PreviewFeedDialog.cpp \ gui/FeedReaderNotify.cpp \ - gui/FeedReaderConfig.cpp + gui/FeedReaderConfig.cpp \ + gui/FeedReaderStringDefs.cpp \ + util/CURLWrapper.cpp \ + util/XMLWrapper.cpp \ + util/HTMLWrapper.cpp HEADERS = FeedReaderPlugin.h \ interface/rsFeedReader.h \ services/p3FeedReader.h \ services/p3FeedReaderThread.h \ services/rsFeedReaderItems.h \ - services/util/CURLWrapper.h \ gui/FeedReaderDialog.h \ gui/AddFeedDialog.h \ + gui/PreviewFeedDialog.h \ gui/FeedReaderNotify.h \ - gui/FeedReaderConfig.h + gui/FeedReaderConfig.h \ + gui/FeedReaderStringDefs.h \ + util/CURLWrapper.h \ + util/XMLWrapper.h \ + util/HTMLWrapper.h FORMS = gui/FeedReaderDialog.ui \ gui/AddFeedDialog.ui \ + gui/PreviewFeedDialog.ui \ gui/FeedReaderConfig.ui TARGET = FeedReader diff --git a/plugins/FeedReader/gui/AddFeedDialog.cpp b/plugins/FeedReader/gui/AddFeedDialog.cpp index ac0b6106d..f4f4064b1 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.cpp +++ b/plugins/FeedReader/gui/AddFeedDialog.cpp @@ -25,6 +25,9 @@ #include "AddFeedDialog.h" #include "ui_AddFeedDialog.h" +#include "PreviewFeedDialog.h" +#include "FeedReaderStringDefs.h" + #include "retroshare/rsforums.h" bool sortForumInfo(const ForumInfo& info1, const ForumInfo& info2) @@ -32,8 +35,8 @@ bool sortForumInfo(const ForumInfo& info1, const ForumInfo& info2) return QString::fromStdWString(info1.forumName).compare(QString::fromStdWString(info2.forumName), Qt::CaseInsensitive); } -AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, QWidget *parent) - : QDialog(parent), mFeedReader(feedReader), ui(new Ui::AddFeedDialog) +AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, QWidget *parent) + : QDialog(parent), mFeedReader(feedReader), mNotify(notify), ui(new Ui::AddFeedDialog) { ui->setupUi(this); @@ -45,6 +48,7 @@ AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, QWidget *parent) connect(ui->useStandardUpdateInterval, SIGNAL(toggled(bool)), this, SLOT(useStandardUpdateIntervalToggled())); connect(ui->useStandardProxyCheckBox, SIGNAL(toggled(bool)), this, SLOT(useStandardProxyToggled())); connect(ui->typeForumRadio, SIGNAL(toggled(bool)), this, SLOT(typeForumToggled())); + connect(ui->previewButton, SIGNAL(clicked()), this, SLOT(preview())); /* currently only for loacl feeds */ connect(ui->saveCompletePageCheckBox, SIGNAL(toggled(bool)), this, SLOT(denyForumToggled())); @@ -149,6 +153,9 @@ void AddFeedDialog::validate() if (ui->nameLineEdit->text().isEmpty() && !ui->useInfoFromFeedCheckBox->isChecked()) { ok = false; } + + ui->previewButton->setEnabled(ok); + if (!ui->typeLocalRadio->isChecked() && !ui->typeForumRadio->isChecked()) { ok = false; } @@ -156,38 +163,6 @@ void AddFeedDialog::validate() ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(ok); } -bool AddFeedDialog::showError(QWidget *parent, RsFeedAddResult result, const QString &title, const QString &text) -{ - QString error; - - switch (result) { - case RS_FEED_ADD_RESULT_SUCCESS: - /* no error */ - return false; - case RS_FEED_ADD_RESULT_FEED_NOT_FOUND: - error = tr("Feed not found."); - break; - case RS_FEED_ADD_RESULT_PARENT_NOT_FOUND: - error = tr("Parent not found."); - break; - case RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER: - error = tr("Parent is no folder."); - break; - case RS_FEED_ADD_RESULT_FEED_IS_FOLDER: - error = tr("Feed is a folder."); - break; - case RS_FEED_ADD_RESULT_FEED_IS_NO_FOLDER: - error = tr("Feed is no folder."); - break; - default: - error = tr("Unknown error occured."); - } - - QMessageBox::critical(parent, title, text + "\n" + error); - - return true; -} - void AddFeedDialog::setParent(const std::string &parentId) { mParentId = parentId; @@ -264,16 +239,8 @@ bool AddFeedDialog::fillFeed(const std::string &feedId) return true; } -void AddFeedDialog::createFeed() +void AddFeedDialog::getFeedInfo(FeedInfo &feedInfo) { - FeedInfo feedInfo; - if (!mFeedId.empty()) { - if (!mFeedReader->getFeedInfo(mFeedId, feedInfo)) { - QMessageBox::critical(this, tr("Edit feed"), tr("Can't edit feed. Feed does not exist.")); - return; - } - } - feedInfo.parentId = mParentId; feedInfo.name = ui->nameLineEdit->text().toUtf8().constData(); @@ -307,19 +274,41 @@ void AddFeedDialog::createFeed() feedInfo.flag.standardStorageTime = ui->useStandardStorageTimeCheckBox->isChecked(); feedInfo.storageTime = ui->storageTimeSpinBox->value() * 60 *60 * 24; +} + +void AddFeedDialog::createFeed() +{ + FeedInfo feedInfo; + if (!mFeedId.empty()) { + if (!mFeedReader->getFeedInfo(mFeedId, feedInfo)) { + QMessageBox::critical(this, tr("Edit feed"), tr("Can't edit feed. Feed does not exist.")); + return; + } + } + + getFeedInfo(feedInfo); if (mFeedId.empty()) { /* add new feed */ RsFeedAddResult result = mFeedReader->addFeed(feedInfo, mFeedId); - if (showError(this, result, tr("Create feed"), tr("Cannot create feed."))) { + if (FeedReaderStringDefs::showError(this, result, tr("Create feed"), tr("Cannot create feed."))) { return; } } else { RsFeedAddResult result = mFeedReader->setFeed(mFeedId, feedInfo); - if (showError(this, result, tr("Edit feed"), tr("Cannot change feed."))) { + if (FeedReaderStringDefs::showError(this, result, tr("Edit feed"), tr("Cannot change feed."))) { return; } } close(); } + +void AddFeedDialog::preview() +{ + FeedInfo feedInfo; + getFeedInfo(feedInfo); + + PreviewFeedDialog dialog(mFeedReader, mNotify, feedInfo, this); + dialog.exec(); +} diff --git a/plugins/FeedReader/gui/AddFeedDialog.h b/plugins/FeedReader/gui/AddFeedDialog.h index f08d64611..92841c93b 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.h +++ b/plugins/FeedReader/gui/AddFeedDialog.h @@ -30,17 +30,16 @@ class AddFeedDialog; } class RsFeedReader; +class FeedReaderNotify; class AddFeedDialog : public QDialog { Q_OBJECT public: - AddFeedDialog(RsFeedReader *feedReader, QWidget *parent); + AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, QWidget *parent); ~AddFeedDialog(); - static bool showError(QWidget *parent, RsFeedAddResult result, const QString &title, const QString &text); - void setParent(const std::string &parentId); bool fillFeed(const std::string &feedId); @@ -53,9 +52,13 @@ private slots: void denyForumToggled(); void validate(); void createFeed(); + void preview(); private: + void getFeedInfo(FeedInfo &feedInfo); + RsFeedReader *mFeedReader; + FeedReaderNotify *mNotify; std::string mFeedId; std::string mParentId; diff --git a/plugins/FeedReader/gui/AddFeedDialog.ui b/plugins/FeedReader/gui/AddFeedDialog.ui index b09be53a8..a6a4cea84 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.ui +++ b/plugins/FeedReader/gui/AddFeedDialog.ui @@ -278,6 +278,13 @@ p, li { white-space: pre-wrap; } + + + + Preview + + + diff --git a/plugins/FeedReader/gui/FeedReaderDialog.cpp b/plugins/FeedReader/gui/FeedReaderDialog.cpp index ef4438e1a..7d72a6b23 100644 --- a/plugins/FeedReader/gui/FeedReaderDialog.cpp +++ b/plugins/FeedReader/gui/FeedReaderDialog.cpp @@ -33,9 +33,11 @@ #include "ui_FeedReaderDialog.h" #include "FeedReaderNotify.h" #include "AddFeedDialog.h" +#include "FeedReaderStringDefs.h" #include "gui/common/RSTreeWidgetItem.h" #include "util/HandleRichText.h" #include "gui/settings/rsharesettings.h" + #include "interface/rsFeedReader.h" #include "retroshare/rsiface.h" @@ -513,7 +515,6 @@ void FeedReaderDialog::calculateFeedItems() void FeedReaderDialog::updateFeedItem(QTreeWidgetItem *item, FeedInfo &info) { - QString workState; QIcon icon; if (info.flag.folder) { @@ -532,26 +533,9 @@ void FeedReaderDialog::updateFeedItem(QTreeWidgetItem *item, FeedInfo &info) item->setData(COLUMN_FEED_DATA, ROLE_FEED_ICON, icon); - switch (info.workstate) { - case FeedInfo::WAITING: - break; - case FeedInfo::WAITING_TO_DOWNLOAD: - workState = tr("waiting for download"); - break; - case FeedInfo::DOWNLOADING: - workState = tr("downloading"); - break; - case FeedInfo::WAITING_TO_PROCESS: - workState = tr("waiting for process"); - break; - case FeedInfo::PROCESSING: - workState = tr("processing"); - break; - } - QString name = QString::fromUtf8(info.name.c_str()); item->setData(COLUMN_FEED_DATA, ROLE_FEED_NAME, name.isEmpty() ? tr("No name") : name); - item->setData(COLUMN_FEED_DATA, ROLE_FEED_WORKSTATE, workState); + item->setData(COLUMN_FEED_DATA, ROLE_FEED_WORKSTATE, FeedReaderStringDefs::workState(info.workstate)); uint32_t unreadCount; mFeedReader->getMessageCount(info.feedId, NULL, NULL, &unreadCount); @@ -562,8 +546,8 @@ void FeedReaderDialog::updateFeedItem(QTreeWidgetItem *item, FeedInfo &info) item->setData(COLUMN_FEED_DATA, ROLE_FEED_ID, QString::fromStdString(info.feedId)); item->setData(COLUMN_FEED_DATA, ROLE_FEED_FOLDER, info.flag.folder); item->setData(COLUMN_FEED_DATA, ROLE_FEED_DEACTIVATED, info.flag.deactivated); - item->setData(COLUMN_FEED_DATA, ROLE_FEED_ERROR, info.error); - item->setToolTip(COLUMN_FEED_NAME, info.error ? QString::fromUtf8(info.errorString.c_str()) : ""); + item->setData(COLUMN_FEED_DATA, ROLE_FEED_ERROR, (bool) (info.errorState != RS_FEED_ERRORSTATE_OK)); + item->setToolTip(COLUMN_FEED_NAME, (info.errorState != RS_FEED_ERRORSTATE_OK) ? FeedReaderStringDefs::errorString(info) : ""); } void FeedReaderDialog::updateMsgs(const std::string &feedId) @@ -689,6 +673,10 @@ void FeedReaderDialog::feedChanged(const QString &feedId, int type) if (!mFeedReader->getFeedInfo(feedId.toStdString(), feedInfo)) { return; } + + if (feedInfo.flag.preview) { + return; + } } if (type == NOTIFY_TYPE_MOD || type == NOTIFY_TYPE_DEL) { @@ -950,13 +938,13 @@ void FeedReaderDialog::newFolder() if (dialog.exec() == QDialog::Accepted && !dialog.textValue().isEmpty()) { std::string feedId; RsFeedAddResult result = mFeedReader->addFolder(currentFeedId(), dialog.textValue().toUtf8().constData(), feedId); - AddFeedDialog::showError(this, result, tr("Create folder"), tr("Cannot create folder.")); + FeedReaderStringDefs::showError(this, result, tr("Create folder"), tr("Cannot create folder.")); } } void FeedReaderDialog::newFeed() { - AddFeedDialog dialog(mFeedReader, this); + AddFeedDialog dialog(mFeedReader, mNotify, this); dialog.setParent(currentFeedId()); dialog.exec(); } @@ -1003,10 +991,10 @@ void FeedReaderDialog::editFeed() if (dialog.exec() == QDialog::Accepted && !dialog.textValue().isEmpty()) { RsFeedAddResult result = mFeedReader->setFolder(feedId, dialog.textValue().toUtf8().constData()); - AddFeedDialog::showError(this, result, tr("Create folder"), tr("Cannot create folder.")); + FeedReaderStringDefs::showError(this, result, tr("Create folder"), tr("Cannot create folder.")); } } else { - AddFeedDialog dialog(mFeedReader, this); + AddFeedDialog dialog(mFeedReader, mNotify, this); if (!dialog.fillFeed(feedId)) { return; } diff --git a/plugins/FeedReader/gui/FeedReaderDialog.h b/plugins/FeedReader/gui/FeedReaderDialog.h index 7eae19f3e..e60f218cb 100644 --- a/plugins/FeedReader/gui/FeedReaderDialog.h +++ b/plugins/FeedReader/gui/FeedReaderDialog.h @@ -47,9 +47,9 @@ protected: bool eventFilter(QObject *obj, QEvent *ev); private slots: - void feedTreeCustomPopupMenu(QPoint point); - void msgTreeCustomPopupMenu(QPoint point); - void feedItemChanged(QTreeWidgetItem *item); + void feedTreeCustomPopupMenu(QPoint point); + void msgTreeCustomPopupMenu(QPoint point); + void feedItemChanged(QTreeWidgetItem *item); void msgItemChanged(); void msgItemClicked(QTreeWidgetItem *item, int column); void filterColumnChanged(); diff --git a/plugins/FeedReader/gui/FeedReaderStringDefs.cpp b/plugins/FeedReader/gui/FeedReaderStringDefs.cpp new file mode 100644 index 000000000..37dc1dc78 --- /dev/null +++ b/plugins/FeedReader/gui/FeedReaderStringDefs.cpp @@ -0,0 +1,130 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include +#include + +#include "FeedReaderStringDefs.h" + +bool FeedReaderStringDefs::showError(QWidget *parent, RsFeedAddResult result, const QString &title, const QString &text) +{ + QString error; + + switch (result) { + case RS_FEED_ADD_RESULT_SUCCESS: + /* no error */ + return false; + case RS_FEED_ADD_RESULT_FEED_NOT_FOUND: + error = QApplication::translate("FeedReaderStringDefs", "Feed not found."); + break; + case RS_FEED_ADD_RESULT_PARENT_NOT_FOUND: + error = QApplication::translate("FeedReaderStringDefs", "Parent not found."); + break; + case RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER: + error = QApplication::translate("FeedReaderStringDefs", "Parent is no folder."); + break; + case RS_FEED_ADD_RESULT_FEED_IS_FOLDER: + error = QApplication::translate("FeedReaderStringDefs", "Feed is a folder."); + break; + case RS_FEED_ADD_RESULT_FEED_IS_NO_FOLDER: + error = QApplication::translate("FeedReaderStringDefs", "Feed is no folder."); + break; + default: + error = QApplication::translate("FeedReaderStringDefs", "Unknown error occured."); + } + + QMessageBox::critical(parent, title, text + "\n" + error); + + return true; +} + +QString FeedReaderStringDefs::workState(FeedInfo::WorkState state) +{ + switch (state) { + case FeedInfo::WAITING: + return ""; + case FeedInfo::WAITING_TO_DOWNLOAD: + return QApplication::translate("FeedReaderStringDefs", "Waiting for download"); + case FeedInfo::DOWNLOADING: + return QApplication::translate("FeedReaderStringDefs", "Downloading"); + case FeedInfo::WAITING_TO_PROCESS: + return QApplication::translate("FeedReaderStringDefs", "Waiting for process"); + case FeedInfo::PROCESSING: + return QApplication::translate("FeedReaderStringDefs", "Processing"); + } + + return ""; +} + +QString FeedReaderStringDefs::errorString(const FeedInfo &feedInfo) +{ + QString errorState; + switch (feedInfo.errorState) { + case RS_FEED_ERRORSTATE_OK: + break; + + /* download */ + case RS_FEED_ERRORSTATE_DOWNLOAD_INTERNAL_ERROR: + errorState = QApplication::translate("FeedReaderStringDefs", "Internal download error"); + break; + case RS_FEED_ERRORSTATE_DOWNLOAD_ERROR: + errorState = QApplication::translate("FeedReaderStringDefs", "Download error"); + break; + case RS_FEED_ERRORSTATE_DOWNLOAD_UNKNOWN_CONTENT_TYPE: + errorState = QApplication::translate("FeedReaderStringDefs", "Unknown content type"); + break; + case RS_FEED_ERRORSTATE_DOWNLOAD_NOT_FOUND: + errorState = QApplication::translate("FeedReaderStringDefs", "Download not found"); + break; + case RS_FEED_ERRORSTATE_DOWNLOAD_UNKOWN_RESPONSE_CODE: + errorState = QApplication::translate("FeedReaderStringDefs", "Unknown response code"); + break; + + /* process */ + case RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR: + errorState = QApplication::translate("FeedReaderStringDefs", "Internal process error"); + break; + case RS_FEED_ERRORSTATE_PROCESS_UNKNOWN_FORMAT: + errorState = QApplication::translate("FeedReaderStringDefs", "Unknown XML format"); + break; + case RS_FEED_ERRORSTATE_PROCESS_FORUM_CREATE: + errorState = QApplication::translate("FeedReaderStringDefs", "Can't create forum"); + break; + case RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_FOUND: + errorState = QApplication::translate("FeedReaderStringDefs", "Forum not found"); + break; + case RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_ADMIN: + errorState = QApplication::translate("FeedReaderStringDefs", "You are not admin of the forum"); + break; + case RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_ANONYMOUS: + errorState = QApplication::translate("FeedReaderStringDefs", "The forum is no anonymous forum"); + break; + + default: + errorState = QApplication::translate("FeedReaderStringDefs", "Unknown error"); + } + + if (!feedInfo.errorString.empty()) { + errorState += QString(" (%1)").arg(QString::fromUtf8(feedInfo.errorString.c_str())); + } + + return errorState; +} diff --git a/plugins/FeedReader/gui/FeedReaderStringDefs.h b/plugins/FeedReader/gui/FeedReaderStringDefs.h new file mode 100644 index 000000000..d94103cfc --- /dev/null +++ b/plugins/FeedReader/gui/FeedReaderStringDefs.h @@ -0,0 +1,39 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#ifndef FEEDREADER_STRINGDEFS_H +#define FEEDREADER_STRINGDEFS_H + +#include + +#include "interface/rsFeedReader.h" + +class QWidget; + +class FeedReaderStringDefs +{ +public: + static bool showError(QWidget *parent, RsFeedAddResult result, const QString &title, const QString &text); + static QString workState(FeedInfo::WorkState state); + static QString errorString(const FeedInfo &feedInfo); +}; + +#endif diff --git a/plugins/FeedReader/gui/PreviewFeedDialog.cpp b/plugins/FeedReader/gui/PreviewFeedDialog.cpp new file mode 100644 index 000000000..76bd2c7da --- /dev/null +++ b/plugins/FeedReader/gui/PreviewFeedDialog.cpp @@ -0,0 +1,427 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include + +#include "PreviewFeedDialog.h" +#include "ui_PreviewFeedDialog.h" +#include "FeedReaderNotify.h" +#include "FeedReaderStringDefs.h" +#include "util/HandleRichText.h" + +#include "interface/rsFeedReader.h" +#include "retroshare/rsiface.h" +#include "util/HTMLWrapper.h" + +#include + +// not yet functional +//PreviewItemDelegate::PreviewItemDelegate(QTreeWidget *parent) : QItemDelegate(parent) +//{ +// connect(parent->header(), SIGNAL(sectionResized(int,int,int)), SLOT(sectionResized(int,int,int))); +//} + +//void PreviewItemDelegate::sectionResized(int logicalIndex, int /*oldSize*/, int /*newSize*/) +//{ +// QHeaderView *header = dynamic_cast(sender()); +// if (header) { +// QTreeWidget *treeWidget = dynamic_cast(header->parent()); +// if (treeWidget) { +// QModelIndex index = treeWidget->model()->index(0, logicalIndex, QModelIndex()); +// emit sizeHintChanged(index); +// } +// } +//} + +//void PreviewItemDelegate::drawDisplay(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, const QString &text) const +//{ +// QPen pen(painter->pen()); +// QFont font(painter->font()); +// QPalette::ColorGroup colorgroup(option.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled); + +// QTextOption textOption; +// textOption.setWrapMode(QTextOption::WrapAnywhere); +// textOption.setAlignment(option.displayAlignment); + +// QRect textRect = rect.adjusted(5, 0, -5, 0); // remove width padding +// textRect.setTop(qMin(rect.top(), option.rect.top())); +// textRect.setHeight(qMax(rect.height(), option.rect.height())); + +// if (option.state & QStyle::State_Selected) { +// painter->fillRect(rect, option.palette.brush(colorgroup, QPalette::Highlight)); +// painter->setPen(option.palette.color(colorgroup, QPalette::HighlightedText)); +// } else { +// painter->setPen(option.palette.color(colorgroup, QPalette::Text)); +// } + +// if (option.state & QStyle::State_Editing) { +// painter->save(); +// painter->setPen(option.palette.color(colorgroup, QPalette::Text)); +// painter->drawRect(rect.adjusted( 0, 0, -1, -1)); +// painter->restore(); +// } + +// painter->setFont(option.font); +// painter->drawText(textRect, text, textOption); + +// // reset painter +// painter->setFont(font); +// painter->setPen(pen); +//} + +//void PreviewItemDelegate::drawFocus(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect) const +//{ +// if (option.state & QStyle::State_HasFocus) { +// QRect textRect(rect); +// textRect.setTop(qMin(rect.top(), option.rect.top())); +// textRect.setHeight(qMax(rect.height(), option.rect.height())); + +// QStyleOptionFocusRect optionFocusRect; +// optionFocusRect.QStyleOption::operator=(option); +// optionFocusRect.rect = textRect; +// optionFocusRect.state |= QStyle::State_KeyboardFocusChange; +// QPalette::ColorGroup colorgroup = (option.state & QStyle::State_Enabled) ? QPalette::Normal : QPalette::Disabled; +// optionFocusRect.backgroundColor = option.palette.color(colorgroup, (option.state & QStyle::State_Selected) ? QPalette::Highlight : QPalette::Background); +// QApplication::style()->drawPrimitive(QStyle::PE_FrameFocusRect, &optionFocusRect, painter); +// } +//} + +//QSize PreviewItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +//{ +//// static bool inSizeHint = false; + +//// if (inSizeHint) { +//// return QSize(); +//// } +//// inSizeHint = true; + +// //d->viewport->width() +// QSize size = QItemDelegate::sizeHint(option, index); +// size.setHeight(50); + +//// QTreeWidget *treeWidget = dynamic_cast(parent()); +//// if (treeWidget) { +//// size.setWidth(treeWidget->header()->sectionSize(index.column())); + +//// QString text = index.data(Qt::DisplayRole).toString(); +//// QRect displayRect = textRectangle(NULL, QRect(0, 0, size.width(), size.height()), option.font, text); +//// QRect displayRect = treeWidget->visualRect(index); +//// int width = treeWidget->columnWidth(index.column()); +//// int height = option.fontMetrics.boundingRect(QRect(0, 0, size.width(), 0), Qt::TextWrapAnywhere | Qt::TextLongestVariant, text).height(); + +//// if (height > size.height()) { +//// size.setHeight(height); +//// } +//// } + +//// inSizeHint = false; + +// return size; +//} + +PreviewFeedDialog::PreviewFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, const FeedInfo &feedInfo, QWidget *parent) : + QDialog(parent), mFeedReader(feedReader), mNotify(notify), ui(new Ui::PreviewFeedDialog) +{ + ui->setupUi(this); + + ui->feedNameLabel->clear(); + ui->feedInfoLabel->clear(); + + /* connect signals */ + connect(ui->previousPushButton, SIGNAL(clicked()), this, SLOT(previousMsg())); + connect(ui->nextPushButton, SIGNAL(clicked()), this, SLOT(nextMsg())); + connect(ui->documentButton, SIGNAL(toggled(bool)), this, SLOT(showDocumentFrame(bool))); + + connect(mNotify, SIGNAL(notifyFeedChanged(QString,int)), this, SLOT(feedChanged(QString,int))); + connect(mNotify, SIGNAL(notifyMsgChanged(QString,QString,int)), this, SLOT(msgChanged(QString,QString,int))); + +// ui->documentTreeWidget->setItemDelegate(new PreviewItemDelegate(ui->documentTreeWidget)); + showDocumentFrame(false); + + if (!mFeedReader->addPreviewFeed(feedInfo, mFeedId)) { + setInfo(tr("Cannot create preview")); + } + + updateMsgCount(); +} + +PreviewFeedDialog::~PreviewFeedDialog() +{ + disconnect(mNotify); + disconnect(mNotify); + + if (!mFeedId.empty()) { + mFeedReader->removeFeed(mFeedId); + } + + delete ui; +} + +void PreviewFeedDialog::feedChanged(const QString &feedId, int type) +{ + if (feedId.isEmpty()) { + return; + } + + if (feedId.toStdString() != mFeedId) { + return; + } + + if (type == NOTIFY_TYPE_DEL) { + /* feed deleted */ + mFeedId.clear(); + return; + } + + if (type == NOTIFY_TYPE_ADD || type == NOTIFY_TYPE_MOD) { + FeedInfo feedInfo; + if (!mFeedReader->getFeedInfo(mFeedId, feedInfo)) { + return; + } + fillFeedInfo(feedInfo); + } +} + +void PreviewFeedDialog::msgChanged(const QString &feedId, const QString &msgId, int type) +{ + if (feedId.isEmpty() || msgId.isEmpty()) { + return; + } + + if (feedId.toStdString() != mFeedId) { + return; + } + + switch (type) { + case NOTIFY_TYPE_ADD: + if (mMsgId.empty()) { + mMsgId = msgId.toStdString(); + updateMsg(); + } + break; + case NOTIFY_TYPE_MOD: + if (mMsgId == msgId.toStdString()) { + updateMsg(); + } + break; + case NOTIFY_TYPE_DEL: + if (mMsgId == msgId.toStdString()) { + std::list::iterator it = std::find(mMsgIds.begin(), mMsgIds.end(), mMsgId); + if (it != mMsgIds.end()) { + ++it; + if (it != mMsgIds.end()) { + mMsgId = *it; + } else { + --it; + if (it != mMsgIds.begin()) { + --it; + mMsgId = *it; + } else { + mMsgId.clear(); + } + } + updateMsg(); + } + } + break; + } + + /* calculate message count */ + mMsgIds.clear(); + mFeedReader->getFeedMsgIdList(mFeedId, mMsgIds); + + updateMsgCount(); +} + +void PreviewFeedDialog::showDocumentFrame(bool show) +{ + ui->documentFrame->setVisible(show); + ui->documentButton->setChecked(show); + + if (show) { + ui->documentButton->setToolTip(tr("Hide tree")); + ui->documentButton->setIcon(QIcon(":images/hide_toolbox_frame.png")); + + fillDocumentTree(); + } else { + ui->documentButton->setToolTip(tr("Show tree")); + ui->documentButton->setIcon(QIcon(":images/show_toolbox_frame.png")); + } +} + +int PreviewFeedDialog::getMsgPos() +{ + int pos = -1; + std::list::iterator it; + for (it = mMsgIds.begin(); it != mMsgIds.end(); ++it) { + ++pos; + if (*it == mMsgId) { + break; + } + } + + return pos; +} + +void PreviewFeedDialog::setInfo(const QString &info) +{ + ui->feedInfoLabel->setText(info); + + ui->infoLabel->setVisible(!info.isEmpty()); + ui->feedInfoLabel->setVisible(!info.isEmpty()); +} + +void PreviewFeedDialog::fillFeedInfo(const FeedInfo &feedInfo) +{ + QString name = feedInfo.name.empty() ? tr("No name") : QString::fromUtf8(feedInfo.name.c_str()); + + QString workState = FeedReaderStringDefs::workState(feedInfo.workstate); + if (!workState.isEmpty()) { + name += QString(" (%1)").arg(workState); + } + ui->feedNameLabel->setText(name); + + setInfo(FeedReaderStringDefs::errorString(feedInfo)); +} + +void PreviewFeedDialog::previousMsg() +{ + std::list::iterator it = std::find(mMsgIds.begin(), mMsgIds.end(), mMsgId); + if (it != mMsgIds.end()) { + if (it != mMsgIds.begin()) { + --it; + mMsgId = *it; + updateMsg(); + updateMsgCount(); + } + } +} + +void PreviewFeedDialog::nextMsg() +{ + std::list::iterator it = std::find(mMsgIds.begin(), mMsgIds.end(), mMsgId); + if (it != mMsgIds.end()) { + ++it; + if (it != mMsgIds.end()) { + mMsgId = *it; + updateMsg(); + updateMsgCount(); + } + } +} + +void PreviewFeedDialog::updateMsgCount() +{ + int pos = getMsgPos(); + ui->messageCountLabel->setText(QString("%1/%2").arg(pos + 1).arg(mMsgIds.size())); + + ui->previousPushButton->setEnabled(pos > 0); + ui->nextPushButton->setEnabled(pos + 1 < (int) mMsgIds.size()); +} + +void PreviewFeedDialog::updateMsg() +{ + FeedMsgInfo msgInfo; + if (mMsgId.empty() || !mFeedReader->getMsgInfo(mFeedId, mMsgId, msgInfo)) { + ui->msgTitle->clear(); + ui->msgText->clear(); + mDescription.clear(); + return; + } + + mDescription = msgInfo.description; + QString msgTxt = RsHtml().formatText(ui->msgText->document(), QString::fromUtf8(mDescription.c_str()), RSHTML_FORMATTEXT_EMBED_LINKS); + + ui->msgText->setHtml(msgTxt); + ui->msgTitle->setText(QString::fromUtf8(msgInfo.title.c_str())); + + ui->documentTreeWidget->clear(); + fillDocumentTree(); +} + +static void examineChildElements(QTreeWidget *treeWidget, HTMLWrapper &html, xmlNodePtr node, QTreeWidgetItem *parentItem) +{ + QTreeWidgetItem *item = new QTreeWidgetItem; + QString text; + if (node->type == XML_ELEMENT_NODE) { + text = QString("<%1 ").arg(QString::fromUtf8(html.nodeName(node).c_str())); + + for (xmlAttrPtr attr = node->properties; attr; attr = attr->next) { + QString value = QString::fromUtf8(html.getAttr(node, attr).c_str()); + if (value.length() > 100) { + value = value.left(100) + "..."; + } + text += QString("%1=\"%2\" ").arg(QString::fromUtf8(html.attrName(attr).c_str()), value); + } + text = text.trimmed() + ">"; + } else { + std::string content; + if (html.getContent(node, content)) { + text = QString::fromUtf8(content.c_str()); + } else { + text = QApplication::translate("PreviewFeedDialog", "Error getting content"); + } + } + item->setText(0, text); + parentItem->addChild(item); + +// QLabel *label = new QLabel(text); +// label->setTextFormat(Qt::PlainText); +// label->setWordWrap(true); +// treeWidget->setItemWidget(item, 0, label); + + item->setExpanded(true); + + for (xmlNodePtr child = node->children; child; child = child->next) { + examineChildElements(treeWidget, html, child, item); + } +} + +void PreviewFeedDialog::fillDocumentTree() +{ + if (!ui->documentTreeWidget->isVisible()) { + return; + } + + if (ui->documentTreeWidget->topLevelItemCount() > 0) { + return; + } + + if (mDescription.empty()) { + return; + } + + HTMLWrapper html; + if (!html.readHTML(mDescription.c_str(), "")) { + QTreeWidgetItem *item = new QTreeWidgetItem; + item->setText(0, tr("Error parsing document")); + ui->documentTreeWidget->addTopLevelItem(item); + + return; + } + + xmlNodePtr root = html.getRootElement(); + if (!root) { + return; + } + + examineChildElements(ui->documentTreeWidget, html, root, ui->documentTreeWidget->invisibleRootItem()); +} diff --git a/plugins/FeedReader/gui/PreviewFeedDialog.h b/plugins/FeedReader/gui/PreviewFeedDialog.h new file mode 100644 index 000000000..a801577bc --- /dev/null +++ b/plugins/FeedReader/gui/PreviewFeedDialog.h @@ -0,0 +1,89 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#ifndef PREVIEWFEEDDIALOG_H +#define PREVIEWFEEDDIALOG_H + +#include +#include + +namespace Ui { +class PreviewFeedDialog; +} + +class QTreeWidget; +class RsFeedReader; +class FeedReaderNotify; +class FeedInfo; + +// not yet functional +//class PreviewItemDelegate : public QItemDelegate +//{ +// Q_OBJECT + +//public: +// PreviewItemDelegate(QTreeWidget *parent); + +//private slots: +// void sectionResized(int logicalIndex, int oldSize, int newSize); + +//protected: +// virtual void drawDisplay(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, const QString &text) const; +// virtual void drawFocus(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect) const; +// virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; +//}; + +class PreviewFeedDialog : public QDialog +{ + Q_OBJECT + +public: + PreviewFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, const FeedInfo &feedInfo, QWidget *parent = 0); + ~PreviewFeedDialog(); + +private slots: + void previousMsg(); + void nextMsg(); + void showDocumentFrame(bool show); + + /* FeedReaderNotify */ + void feedChanged(const QString &feedId, int type); + void msgChanged(const QString &feedId, const QString &msgId, int type); + +private: + int getMsgPos(); + void setInfo(const QString &info); + void fillFeedInfo(const FeedInfo &feedInfo); + void updateMsgCount(); + void updateMsg(); + void fillDocumentTree(); + + RsFeedReader *mFeedReader; + FeedReaderNotify *mNotify; + std::string mFeedId; + std::string mMsgId; + std::list mMsgIds; + std::string mDescription; + + Ui::PreviewFeedDialog *ui; +}; + +#endif // PREVIEWFEEDDIALOG_H diff --git a/plugins/FeedReader/gui/PreviewFeedDialog.ui b/plugins/FeedReader/gui/PreviewFeedDialog.ui new file mode 100644 index 000000000..9b5d92570 --- /dev/null +++ b/plugins/FeedReader/gui/PreviewFeedDialog.ui @@ -0,0 +1,314 @@ + + + PreviewFeedDialog + + + + 0 + 0 + 500 + 350 + + + + Preview + + + true + + + + 0 + + + + + + + + 0 + 0 + + + + Name: + + + + + + + Feed name + + + true + + + + + + + Information: + + + + + + + Information + + + true + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Previous + + + + + + + + 0 + 0 + + + + 0/0 + + + + + + + + 0 + 0 + + + + Next + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + 0 + 0 + + + + Titel: + + + + + + + + 0 + 24 + + + + QLabel#msgTitle{ +border: 2px solid #CCCCCC; +border-radius: 6px; +background: white;} + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + + + 0 + + + + + + + + 14 + 31 + + + + + 14 + 31 + + + + + + + + 16 + 31 + + + + true + + + + + + + Qt::Vertical + + + + 12 + 329 + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + + + true + + + false + + + + 1 + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + PreviewFeedDialog + accept() + + + 258 + 339 + + + 157 + 274 + + + + + buttonBox + rejected() + PreviewFeedDialog + reject() + + + 326 + 339 + + + 286 + 274 + + + + + diff --git a/plugins/FeedReader/interface/rsFeedReader.h b/plugins/FeedReader/interface/rsFeedReader.h index 42be3e148..4ea33cac4 100644 --- a/plugins/FeedReader/interface/rsFeedReader.h +++ b/plugins/FeedReader/interface/rsFeedReader.h @@ -26,6 +26,26 @@ #include #include +enum RsFeedReaderErrorState { + RS_FEED_ERRORSTATE_OK = 0, + + /* download */ + RS_FEED_ERRORSTATE_DOWNLOAD_INTERNAL_ERROR = 1, + RS_FEED_ERRORSTATE_DOWNLOAD_ERROR = 2, + RS_FEED_ERRORSTATE_DOWNLOAD_UNKNOWN_CONTENT_TYPE = 3, + RS_FEED_ERRORSTATE_DOWNLOAD_NOT_FOUND = 4, + RS_FEED_ERRORSTATE_DOWNLOAD_UNKOWN_RESPONSE_CODE = 5, + + /* process */ + RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR = 50, + RS_FEED_ERRORSTATE_PROCESS_UNKNOWN_FORMAT = 51, + RS_FEED_ERRORSTATE_PROCESS_FORUM_CREATE = 100, + RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_FOUND = 101, + RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_ADMIN = 102, + RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_ANONYMOUS = 103 +}; + + class RsFeedReader; extern RsFeedReader *rsFeedReader; @@ -58,7 +78,7 @@ public: updateInterval = 0; lastUpdate = 0; storageTime = 0; - error = false; + errorState = RS_FEED_ERRORSTATE_OK; flag.folder = false; flag.infoFromFeed = false; flag.standardStorageTime = false; @@ -70,25 +90,26 @@ public: flag.updateForumInfo = false; flag.embedImages = false; flag.saveCompletePage = false; + flag.preview = false; } - std::string feedId; - std::string parentId; - std::string url; - std::string name; - std::string description; - std::string icon; - std::string user; - std::string password; - std::string proxyAddress; - uint16_t proxyPort; - uint32_t updateInterval; - time_t lastUpdate; - uint32_t storageTime; - std::string forumId; - WorkState workstate; - bool error; - std::string errorString; + std::string feedId; + std::string parentId; + std::string url; + std::string name; + std::string description; + std::string icon; + std::string user; + std::string password; + std::string proxyAddress; + uint16_t proxyPort; + uint32_t updateInterval; + time_t lastUpdate; + uint32_t storageTime; + std::string forumId; + WorkState workstate; + RsFeedReaderErrorState errorState; + std::string errorString; struct { bool folder : 1; @@ -102,6 +123,7 @@ public: bool updateForumInfo : 1; bool embedImages : 1; bool saveCompletePage : 1; + bool preview : 1; } flag; }; @@ -159,6 +181,7 @@ public: virtual RsFeedAddResult addFeed(const FeedInfo &feedInfo, std::string &feedId) = 0; virtual RsFeedAddResult setFeed(const std::string &feedId, const FeedInfo &feedInfo) = 0; virtual bool removeFeed(const std::string &feedId) = 0; + virtual bool addPreviewFeed(const FeedInfo &feedInfo, std::string &feedId) = 0; virtual void getFeedList(const std::string &parentId, std::list &feedInfos) = 0; virtual bool getFeedInfo(const std::string &feedId, FeedInfo &feedInfo) = 0; virtual bool getMsgInfo(const std::string &feedId, const std::string &msgId, FeedMsgInfo &msgInfo) = 0; @@ -166,20 +189,9 @@ public: virtual bool removeMsgs(const std::string &feedId, const std::list &msgIds) = 0; virtual bool getMessageCount(const std::string &feedId, uint32_t *msgCount, uint32_t *newCount, uint32_t *unreadCount) = 0; virtual bool getFeedMsgList(const std::string &feedId, std::list &msgInfos) = 0; + virtual bool getFeedMsgIdList(const std::string &feedId, std::list &msgIds) = 0; virtual bool processFeed(const std::string &feedId) = 0; virtual bool setMessageRead(const std::string &feedId, const std::string &msgId, bool read) = 0; - - /* get Ids */ -// virtual uint32_t getRankingsCount() = 0; -// virtual float getMaxRank() = 0; -// virtual bool getRankings(uint32_t first, uint32_t count, std::list &rids) = 0; -// virtual bool getRankDetails(std::string rid, RsRankDetails &details) = 0; - - /* Add New Comment / Msg */ -// virtual std::string newRankMsg(std::wstring link, std::wstring title, std::wstring comment, int32_t score) = 0; -// virtual bool updateComment(std::string rid, std::wstring comment, int32_t score) = 0; - -// virtual std::string anonRankMsg(std::string rid, std::wstring link, std::wstring title) = 0; }; #endif diff --git a/plugins/FeedReader/services/p3FeedReader.cc b/plugins/FeedReader/services/p3FeedReader.cc index 76b16ea65..6aaad1003 100644 --- a/plugins/FeedReader/services/p3FeedReader.cc +++ b/plugins/FeedReader/services/p3FeedReader.cc @@ -38,10 +38,12 @@ RsFeedReader *rsFeedReader = NULL; p3FeedReader::p3FeedReader(RsPluginHandler* pgHandler) : RsPQIService(RS_PKT_TYPE_FEEDREADER_CONFIG, CONFIG_TYPE_FEEDREADER, 5, pgHandler), - mFeedReaderMtx("p3FeedReader"), mDownloadMutex("p3FeedReaderDownload"), mProcessMutex("p3FeedReaderProcess") + mFeedReaderMtx("p3FeedReader"), mDownloadMutex("p3FeedReaderDownload"), mProcessMutex("p3FeedReaderProcess"), mPreviewMutex("p3FeedReaderPreview") { mNextFeedId = 1; mNextMsgId = 1; + mNextPreviewFeedId = -1; // use negative values + mNextPreviewMsgId = -1; // use negative values mStandardUpdateInterval = 60 * 60; // 60 minutes mStandardStorageTime = 30 * 60 * 60 * 24; // 30 days mStandardUseProxy = false; @@ -49,13 +51,16 @@ p3FeedReader::p3FeedReader(RsPluginHandler* pgHandler) mLastClean = 0; mNotify = NULL; + mPreviewDownloadThread = NULL; + mPreviewProcessThread = NULL; + /* start download thread */ - p3FeedReaderThread *frt = new p3FeedReaderThread(this, p3FeedReaderThread::DOWNLOAD); + p3FeedReaderThread *frt = new p3FeedReaderThread(this, p3FeedReaderThread::DOWNLOAD, ""); mThreads.push_back(frt); frt->start(); /* start process thread */ - frt = new p3FeedReaderThread(this, p3FeedReaderThread::PROCESS); + frt = new p3FeedReaderThread(this, p3FeedReaderThread::PROCESS, ""); mThreads.push_back(frt); frt->start(); } @@ -80,7 +85,7 @@ static void feedToInfo(const RsFeedReaderFeed *feed, FeedInfo &info) info.lastUpdate = feed->lastUpdate; info.forumId = feed->forumId; info.storageTime = feed->storageTime; - info.error = (feed->errorState != RS_FEED_ERRORSTATE_OK); // currently only as bool + info.errorState = feed->errorState; info.errorString = feed->errorString; info.flag.folder = (feed->flag & RS_FEED_FLAG_FOLDER); @@ -95,6 +100,8 @@ static void feedToInfo(const RsFeedReaderFeed *feed, FeedInfo &info) info.flag.embedImages = (feed->flag & RS_FEED_FLAG_EMBED_IMAGES); info.flag.saveCompletePage = (feed->flag & RS_FEED_FLAG_SAVE_COMPLETE_PAGE); + info.flag.preview = feed->preview; + switch (feed->workstate) { case RsFeedReaderFeed::WAITING: info.workstate = FeedInfo::WAITING; @@ -134,6 +141,8 @@ static void infoToFeed(const FeedInfo &info, RsFeedReaderFeed *feed, bool add) feed->forumId = info.forumId; } +// feed->preview = info.flag.preview; + uint32_t oldFlag = feed->flag; feed->flag = 0; if (info.flag.infoFromFeed) { @@ -199,12 +208,14 @@ void p3FeedReader::setNotify(RsFeedReaderNotify *notify) uint32_t p3FeedReader::getStandardStorageTime() { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + return mStandardStorageTime; } void p3FeedReader::setStandardStorageTime(uint32_t storageTime) { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + if (mStandardStorageTime != storageTime) { mStandardStorageTime = storageTime; IndicateConfigChanged(); @@ -214,12 +225,14 @@ void p3FeedReader::setStandardStorageTime(uint32_t storageTime) uint32_t p3FeedReader::getStandardUpdateInterval() { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + return mStandardUpdateInterval; } void p3FeedReader::setStandardUpdateInterval(uint32_t updateInterval) { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + if (mStandardUpdateInterval != updateInterval) { mStandardUpdateInterval = updateInterval; IndicateConfigChanged(); @@ -229,14 +242,17 @@ void p3FeedReader::setStandardUpdateInterval(uint32_t updateInterval) bool p3FeedReader::getStandardProxy(std::string &proxyAddress, uint16_t &proxyPort) { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + proxyAddress = mStandardProxyAddress; proxyPort = mStandardProxyPort; + return mStandardUseProxy; } void p3FeedReader::setStandardProxy(bool useProxy, const std::string &proxyAddress, uint16_t proxyPort) { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + if (useProxy != mStandardUseProxy || proxyAddress != mStandardProxyAddress || proxyPort != mStandardProxyPort) { mStandardProxyAddress = proxyAddress; mStandardProxyPort = proxyPort; @@ -247,12 +263,37 @@ void p3FeedReader::setStandardProxy(bool useProxy, const std::string &proxyAddre void p3FeedReader::stop() { - /* stop threads */ - std::list::iterator it; - for (it = mThreads.begin(); it != mThreads.end(); ++it) { - (*it)->join(); + { + RsStackMutex stack(mPreviewMutex); /******* LOCK STACK MUTEX *********/ + + stopPreviewThreads_locked(); + } + + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + /* stop threads */ + std::list::iterator it; + for (it = mThreads.begin(); it != mThreads.end(); ++it) { + (*it)->join(); + delete(*it); + } + mThreads.clear(); + } +} + +void p3FeedReader::stopPreviewThreads_locked() +{ + if (mPreviewDownloadThread) { + mPreviewDownloadThread->join(); + delete mPreviewDownloadThread; + mPreviewDownloadThread = NULL; + } + if (mPreviewProcessThread) { + mPreviewProcessThread->join(); + delete mPreviewProcessThread; + mPreviewProcessThread = NULL; } - mThreads.clear(); } RsFeedAddResult p3FeedReader::addFolder(const std::string parentId, const std::string &name, std::string &feedId) @@ -481,6 +522,8 @@ void p3FeedReader::deleteAllMsgs_locked(RsFeedReaderFeed *fi) bool p3FeedReader::removeFeed(const std::string &feedId) { std::list removedFeedIds; + bool changed = false; + bool preview = false; { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -497,6 +540,8 @@ bool p3FeedReader::removeFeed(const std::string &feedId) RsFeedReaderFeed *fi = feedIt->second; mFeeds.erase(feedIt); + changed = !fi->preview; + preview = fi->preview; if (fi->flag & RS_FEED_FLAG_FOLDER) { std::list feedIds; @@ -534,7 +579,18 @@ bool p3FeedReader::removeFeed(const std::string &feedId) delete(fi); } - IndicateConfigChanged(); + if (changed) { + IndicateConfigChanged(); + } + + if (preview) { + RsStackMutex stack(mPreviewMutex); /******* LOCK STACK MUTEX *********/ + + /* only check download thread */ + if (mPreviewDownloadThread && mPreviewDownloadThread->getFeedId() == feedId) { + stopPreviewThreads_locked(); + } + } if (mNotify) { /* only notify remove of feed */ @@ -547,6 +603,63 @@ bool p3FeedReader::removeFeed(const std::string &feedId) return true; } +bool p3FeedReader::addPreviewFeed(const FeedInfo &feedInfo, std::string &feedId) +{ + { + RsStackMutex stack(mPreviewMutex); /******* LOCK STACK MUTEX *********/ + + stopPreviewThreads_locked(); + } + + feedId.clear(); + + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::addPreviewFeed - add feed " << feedInfo.name << ", url " << feedInfo.url << std::endl; +#endif + + RsFeedReaderFeed *fi = new RsFeedReaderFeed; + infoToFeed(feedInfo, fi, true); + rs_sprintf(fi->feedId, "preview%d", mNextPreviewFeedId--); + fi->preview = true; + + /* process feed */ + fi->workstate = RsFeedReaderFeed::WAITING_TO_DOWNLOAD; + fi->content.clear(); + + /* clear not needed members */ + fi->parentId.clear(); + fi->updateInterval = 0; + fi->lastUpdate = 0; + fi->forumId.clear(); + fi->storageTime = 0; + + mFeeds[fi->feedId] = fi; + + feedId = fi->feedId; + } + + if (mNotify) { + mNotify->feedChanged(feedId, NOTIFY_TYPE_ADD); + } + + { + RsStackMutex stack(mPreviewMutex); /******* LOCK STACK MUTEX *********/ + + /* start download thread for preview */ + mPreviewDownloadThread = new p3FeedReaderThread(this, p3FeedReaderThread::DOWNLOAD, feedId); + mPreviewDownloadThread->start(); + + /* start process thread for preview */ + mPreviewProcessThread = new p3FeedReaderThread(this, p3FeedReaderThread::PROCESS, feedId); + mPreviewProcessThread->start(); + } + + return true; +} + void p3FeedReader::getFeedList(const std::string &parentId, std::list &feedInfos) { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -555,6 +668,10 @@ void p3FeedReader::getFeedList(const std::string &parentId, std::list for (feedIt = mFeeds.begin(); feedIt != mFeeds.end(); ++feedIt) { RsFeedReaderFeed *fi = feedIt->second; + if (fi->preview) { + continue; + } + if (fi->parentId == parentId) { FeedInfo feedInfo; feedToInfo(fi, feedInfo); @@ -610,6 +727,8 @@ bool p3FeedReader::getMsgInfo(const std::string &feedId, const std::string &msgI bool p3FeedReader::removeMsg(const std::string &feedId, const std::string &msgId) { + bool changed = false; + { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -622,6 +741,7 @@ bool p3FeedReader::removeMsg(const std::string &feedId, const std::string &msgId } RsFeedReaderFeed *fi = feedIt->second; + changed = !fi->preview; std::map::iterator msgIt; msgIt = fi->mMsgs.find(msgId); @@ -635,7 +755,10 @@ bool p3FeedReader::removeMsg(const std::string &feedId, const std::string &msgId msgIt->second->flag |= RS_FEEDMSG_FLAG_DELETED; } - IndicateConfigChanged(); + if (changed) { + IndicateConfigChanged(); + } + if (mNotify) { mNotify->feedChanged(feedId, NOTIFY_TYPE_MOD); mNotify->msgChanged(feedId, msgId, NOTIFY_TYPE_DEL); @@ -647,6 +770,7 @@ bool p3FeedReader::removeMsg(const std::string &feedId, const std::string &msgId bool p3FeedReader::removeMsgs(const std::string &feedId, const std::list &msgIds) { std::list removedMsgs; + bool changed = false; { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -660,6 +784,7 @@ bool p3FeedReader::removeMsgs(const std::string &feedId, const std::listsecond; + changed = !fi->preview; std::list::const_iterator idIt; for (idIt = msgIds.begin(); idIt != msgIds.end(); ++idIt) { @@ -678,6 +803,10 @@ bool p3FeedReader::removeMsgs(const std::string &feedId, const std::listfeedChanged(feedId, NOTIFY_TYPE_MOD); @@ -758,8 +887,41 @@ bool p3FeedReader::getFeedMsgList(const std::string &feedId, std::list &msgIds) +{ + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + std::map::iterator feedIt = mFeeds.find(feedId); + if (feedIt == mFeeds.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::getFeedMsgList - feed " << feedId << " not found" << std::endl; +#endif + return false; + } + + RsFeedReaderFeed *fi = feedIt->second; + + std::map::iterator msgIt; + for (msgIt = fi->mMsgs.begin(); msgIt != fi->mMsgs.end(); ++msgIt) { + RsFeedReaderMsg *mi = msgIt->second; + + if (mi->flag & RS_FEEDMSG_FLAG_DELETED) { + continue; + } + + msgIds.push_back(mi->msgId); + } + + return true; +} + static bool canProcessFeed(RsFeedReaderFeed *fi) { + if (fi->preview) { + /* preview feed */ + return false; + } + if (fi->flag & RS_FEED_FLAG_DEACTIVATED) { /* deactivated */ return false; @@ -939,6 +1101,7 @@ int p3FeedReader::tick() /* clean feeds */ cleanFeeds(); + /* check feeds for update interval */ time_t currentTime = time(NULL); std::list feedToDownload; std::map::iterator feedIt; @@ -1105,6 +1268,9 @@ bool p3FeedReader::saveList(bool &cleanup, std::list & saveData) std::map::iterator it1; for (it1 = mFeeds.begin(); it1 != mFeeds.end(); ++it1) { RsFeedReaderFeed *fi = it1->second; + if (fi->preview) { + continue; + } saveData.push_back(fi); std::map::iterator it2; @@ -1227,11 +1393,11 @@ bool p3FeedReader::loadList(std::list& load) /****************************** internal ***********************************/ /***************************************************************************/ -bool p3FeedReader::getFeedToDownload(RsFeedReaderFeed &feed) +bool p3FeedReader::getFeedToDownload(RsFeedReaderFeed &feed, const std::string &neededFeedId) { - std::string feedId; + std::string feedId = neededFeedId; - { + if (feedId.empty()) { RsStackMutex stack(mDownloadMutex); /******* LOCK STACK MUTEX *********/ if (mDownloadFeeds.empty()) { @@ -1257,6 +1423,7 @@ bool p3FeedReader::getFeedToDownload(RsFeedReaderFeed &feed) return false; } + /* check state */ if (it->second->workstate != RsFeedReaderFeed::WAITING_TO_DOWNLOAD) { std::cerr << "p3FeedReader::getFeedToDownload - feed in wrong work state for download " << it->second->workstate << std::endl; return false; @@ -1282,6 +1449,8 @@ bool p3FeedReader::getFeedToDownload(RsFeedReaderFeed &feed) void p3FeedReader::onDownloadSuccess(const std::string &feedId, const std::string &content, std::string &icon) { + bool preview; + { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -1298,11 +1467,14 @@ void p3FeedReader::onDownloadSuccess(const std::string &feedId, const std::strin RsFeedReaderFeed *fi = it->second; fi->workstate = RsFeedReaderFeed::WAITING_TO_PROCESS; fi->content = content; + preview = fi->preview; if (fi->icon != icon) { fi->icon = icon; - IndicateConfigChanged(); + if (!preview) { + IndicateConfigChanged(); + } } #ifdef FEEDREADER_DEBUG @@ -1310,7 +1482,7 @@ void p3FeedReader::onDownloadSuccess(const std::string &feedId, const std::strin #endif } - { + if (!preview) { RsStackMutex stack(mProcessMutex); /******* LOCK STACK MUTEX *********/ if (std::find(mProcessFeeds.begin(), mProcessFeeds.end(), feedId) == mProcessFeeds.end()) { @@ -1324,7 +1496,7 @@ void p3FeedReader::onDownloadSuccess(const std::string &feedId, const std::strin } } -void p3FeedReader::onDownloadError(const std::string &feedId, p3FeedReaderThread::DownloadResult result, const std::string &error) +void p3FeedReader::onDownloadError(const std::string &feedId, p3FeedReaderThread::DownloadResult result, const std::string &errorString) { { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -1344,7 +1516,6 @@ void p3FeedReader::onDownloadError(const std::string &feedId, p3FeedReaderThread fi->lastUpdate = time(NULL); fi->content.clear(); - long todo; // sort error codes switch (result) { case p3FeedReaderThread::DOWNLOAD_SUCCESS: /* this should not happen */ @@ -1354,9 +1525,6 @@ void p3FeedReader::onDownloadError(const std::string &feedId, p3FeedReaderThread case p3FeedReaderThread::DOWNLOAD_ERROR: fi->errorState = RS_FEED_ERRORSTATE_DOWNLOAD_ERROR; break; - case p3FeedReaderThread::DOWNLOAD_INTERNAL_ERROR: - fi->errorState = RS_FEED_ERRORSTATE_DOWNLOAD_INTERNAL_ERROR; - break; case p3FeedReaderThread::DOWNLOAD_UNKNOWN_CONTENT_TYPE: fi->errorState = RS_FEED_ERRORSTATE_DOWNLOAD_UNKNOWN_CONTENT_TYPE; break; @@ -1370,13 +1538,15 @@ void p3FeedReader::onDownloadError(const std::string &feedId, p3FeedReaderThread fi->errorState = RS_FEED_ERRORSTATE_DOWNLOAD_INTERNAL_ERROR; } - fi->errorString = error; + fi->errorString = errorString; #ifdef FEEDREADER_DEBUG - std::cerr << "p3FeedReader::onDownloadError - feed " << fi->feedId << " (" << fi->name << ") error download, result = " << result << ", errorState = " << fi->errorState << ", error = " << error << std::endl; + std::cerr << "p3FeedReader::onDownloadError - feed " << fi->feedId << " (" << fi->name << ") error download, result = " << result << ", errorState = " << fi->errorState << ", error = " << errorString << std::endl; #endif - IndicateConfigChanged(); + if (!fi->preview) { + IndicateConfigChanged(); + } } if (mNotify) { @@ -1384,11 +1554,11 @@ void p3FeedReader::onDownloadError(const std::string &feedId, p3FeedReaderThread } } -bool p3FeedReader::getFeedToProcess(RsFeedReaderFeed &feed) +bool p3FeedReader::getFeedToProcess(RsFeedReaderFeed &feed, const std::string &neededFeedId) { - std::string feedId; + std::string feedId = neededFeedId; - { + if (feedId.empty()) { RsStackMutex stack(mProcessMutex); /******* LOCK STACK MUTEX *********/ if (mProcessFeeds.empty()) { @@ -1414,13 +1584,13 @@ bool p3FeedReader::getFeedToProcess(RsFeedReaderFeed &feed) return false; } - if (it->second->workstate != RsFeedReaderFeed::WAITING_TO_PROCESS) { - std::cerr << "p3FeedReader::getFeedToProcess - feed in wrong state for process " << it->second->workstate << std::endl; + RsFeedReaderFeed *fi = it->second; + + if (fi->workstate != RsFeedReaderFeed::WAITING_TO_PROCESS) { + std::cerr << "p3FeedReader::getFeedToProcess - feed in wrong state for process " << fi->workstate << std::endl; return false; } - RsFeedReaderFeed *fi = it->second; - /* set state to processing */ fi->workstate = RsFeedReaderFeed::PROCESSING; fi->errorState = RS_FEED_ERRORSTATE_OK; @@ -1430,7 +1600,7 @@ bool p3FeedReader::getFeedToProcess(RsFeedReaderFeed &feed) feed = *fi; #ifdef FEEDREADER_DEBUG - std::cerr << "p3FeedReader::getFeedToProcess - feed " << it->second->feedId << " (" << it->second->name << ") is starting to process" << std::endl; + std::cerr << "p3FeedReader::getFeedToProcess - feed " << fi->feedId << " (" << fi->name << ") is starting to process" << std::endl; #endif } @@ -1447,8 +1617,6 @@ bool p3FeedReader::onProcessSuccess_filterMsg(const std::string &feedId, std::li std::cerr << "p3FeedReader::onProcessSuccess_filterMsg - feed " << feedId << " got " << msgs.size() << " messages" << std::endl; #endif - bool result = true; - { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -1463,10 +1631,67 @@ bool p3FeedReader::onProcessSuccess_filterMsg(const std::string &feedId, std::li } RsFeedReaderFeed *fi = it->second; - bool forum = (fi->flag & RS_FEED_FLAG_FORUM); - uint32_t errorState = RS_FEED_ERRORSTATE_OK; - if (forum) { + std::list::iterator newMsgIt; + for (newMsgIt = msgs.begin(); newMsgIt != msgs.end(); ) { + RsFeedReaderMsg *miNew = *newMsgIt; + /* search for existing msg */ + std::map::iterator msgIt; + for (msgIt = fi->mMsgs.begin(); msgIt != fi->mMsgs.end(); ++msgIt) { + RsFeedReaderMsg *mi = msgIt->second; + if (mi->title == miNew->title && mi->link == miNew->link && mi->author == miNew->author) { + /* msg exist */ + break; + } + } + if (msgIt != fi->mMsgs.end()) { + /* msg exists */ + delete(miNew); + newMsgIt = msgs.erase(newMsgIt); + } else { + ++newMsgIt; + } + } + + fi->content.clear(); + fi->errorString.clear(); + + if (!fi->preview) { + IndicateConfigChanged(); + } + } + + return true; +} + +void p3FeedReader::onProcessSuccess_addMsgs(const std::string &feedId, bool result, std::list &msgs, bool single) +{ +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - feed " << feedId << " got " << msgs.size() << " messages" << std::endl; +#endif + + std::list addedMsgs; + std::string forumId; + std::list forumMsgs; + + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + + /* find feed */ + std::map::iterator it = mFeeds.find(feedId); + if (it == mFeeds.end()) { + /* feed not found */ +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - feed " << feedId << " not found" << std::endl; +#endif + return; + } + + RsFeedReaderFeed *fi = it->second; + bool forum = (fi->flag & RS_FEED_FLAG_FORUM) && !fi->preview; + RsFeedReaderErrorState errorState = RS_FEED_ERRORSTATE_OK; + + if (result && forum && !msgs.empty()) { if (fi->forumId.empty()) { /* create new forum */ std::wstring forumName; @@ -1491,14 +1716,15 @@ bool p3FeedReader::onProcessSuccess_filterMsg(const std::string &feedId, std::li librs::util::ConvertUtf8ToUtf16(fi->description, forumDescription); /* create anonymous public forum */ fi->forumId = rsForums->createForum(forumName, forumDescription, RS_DISTRIB_PUBLIC | RS_DISTRIB_AUTHEN_ANON); + forumId = fi->forumId; if (fi->forumId.empty()) { - errorState = RS_FEED_ERRORSTATE_FORUM_CREATE; + errorState = RS_FEED_ERRORSTATE_PROCESS_FORUM_CREATE; #ifdef FEEDREADER_DEBUG - std::cerr << "p3FeedReader::onProcessSuccess_filterMsg - can't create forum for feed " << feedId << " (" << it->second->name << ") - ignore all messages" << std::endl; + std::cerr << "p3FeedReader::onProcessSuccess_filterMsg - can't create forum for feed " << feedId << " (" << fi->name << ") - ignore all messages" << std::endl; } else { - std::cerr << "p3FeedReader::onProcessSuccess_filterMsg - forum " << forumId << " (" << fi->name << ") created" << std::endl; + std::cerr << "p3FeedReader::onProcessSuccess_filterMsg - forum " << fi->forumId << " (" << fi->name << ") created" << std::endl; #endif } } else { @@ -1506,129 +1732,66 @@ bool p3FeedReader::onProcessSuccess_filterMsg(const std::string &feedId, std::li ForumInfo forumInfo; if (rsForums->getForumInfo(fi->forumId, forumInfo)) { if ((forumInfo.subscribeFlags & RS_DISTRIB_ADMIN) == 0) { - errorState = RS_FEED_ERRORSTATE_FORUM_NO_ADMIN; + errorState = RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_ADMIN; } else if ((forumInfo.forumFlags & RS_DISTRIB_AUTHEN_REQ) || (forumInfo.forumFlags & RS_DISTRIB_AUTHEN_ANON) == 0) { - errorState = RS_FEED_ERRORSTATE_FORUM_NO_ANONYMOUS_FORUM; + errorState = RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_ANONYMOUS; + } else { + forumId = fi->forumId; } } else { - errorState = RS_FEED_ERRORSTATE_FORUM_NOT_FOUND; + errorState = RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_FOUND; } } } /* process msgs */ if (errorState == RS_FEED_ERRORSTATE_OK) { - std::list::iterator newMsgIt; - for (newMsgIt = msgs.begin(); newMsgIt != msgs.end(); ) { - RsFeedReaderMsg *miNew = *newMsgIt; - /* search for existing msg */ - std::map::iterator msgIt; - for (msgIt = fi->mMsgs.begin(); msgIt != fi->mMsgs.end(); ++msgIt) { - RsFeedReaderMsg *mi = msgIt->second; - if (mi->title == miNew->title && mi->link == mi->link && mi->author == mi->author) { - /* msg exist */ - break; + /* process msgs */ +#ifdef FEEDREADER_DEBUG + uint32_t newMsgs = 0; +#endif + + if (result) { + std::list::iterator newMsgIt; + for (newMsgIt = msgs.begin(); newMsgIt != msgs.end(); ) { + RsFeedReaderMsg *miNew = *newMsgIt; + /* add new msg */ + if (fi->preview) { + rs_sprintf(miNew->msgId, "preview%d", mNextPreviewMsgId--); + } else { + rs_sprintf(miNew->msgId, "%lu", mNextMsgId++); } - } - if (msgIt != fi->mMsgs.end()) { - /* msg exists */ - delete(*newMsgIt); + if (forum) { + miNew->flag = RS_FEEDMSG_FLAG_DELETED; + forumMsgs.push_back(*miNew); +// miNew->description.clear(); + } else { + miNew->flag = RS_FEEDMSG_FLAG_NEW; + addedMsgs.push_back(miNew->msgId); + } + fi->mMsgs[miNew->msgId] = miNew; newMsgIt = msgs.erase(newMsgIt); - } else { - ++newMsgIt; + +#ifdef FEEDREADER_DEBUG + ++newMsgs; +#endif } - } - } else { - result = false; - } - - fi->content.clear(); - fi->errorState = errorState; - fi->errorString.clear(); - - IndicateConfigChanged(); - } - - if (mNotify) { - mNotify->feedChanged(feedId, NOTIFY_TYPE_MOD); - } - - return result; -} - -void p3FeedReader::onProcessSuccess_addMsgs(const std::string &feedId, bool result, std::list &msgs) -{ #ifdef FEEDREADER_DEBUG - std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - feed " << feedId << " got " << msgs.size() << " messages" << std::endl; -#endif - - std::list addedMsgs; - std::string forumId; - std::list forumMsgs; - - { - RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ - - /* find feed */ - std::map::iterator it = mFeeds.find(feedId); - if (it == mFeeds.end()) { - /* feed not found */ -#ifdef FEEDREADER_DEBUG - std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - feed " << feedId << " not found" << std::endl; -#endif - return; - } - - RsFeedReaderFeed *fi = it->second; - bool forum = (fi->flag & RS_FEED_FLAG_FORUM); - - if (forum) { - forumId = fi->forumId; - if (forumId.empty()) { - /* don't process messages without forum id */ - result = false; -#ifdef FEEDREADER_DEBUG - std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - feed " << fi->feedId << " (" << fi->name << ") don't process messages without forum id" << std::endl; + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - feed " << fi->feedId << " (" << fi->name << ") added " << newMsgs << "/" << msgs.size() << " messages" << std::endl; #endif } } - /* process msgs */ -#ifdef FEEDREADER_DEBUG - uint32_t newMsgs = 0; -#endif - - if (result) { - std::list::iterator newMsgIt; - for (newMsgIt = msgs.begin(); newMsgIt != msgs.end(); ) { - RsFeedReaderMsg *miNew = *newMsgIt; - /* add new msg */ - rs_sprintf(miNew->msgId, "%lu", mNextMsgId++); - if (forum) { - miNew->flag = RS_FEEDMSG_FLAG_DELETED; - forumMsgs.push_back(*miNew); -// miNew->description.clear(); - } else { - miNew->flag = RS_FEEDMSG_FLAG_NEW; - addedMsgs.push_back(miNew->msgId); - } - fi->mMsgs[miNew->msgId] = miNew; - newMsgIt = msgs.erase(newMsgIt); - -#ifdef FEEDREADER_DEBUG - ++newMsgs; -#endif - } -#ifdef FEEDREADER_DEBUG - std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - feed " << fi->feedId << " (" << fi->name << ") added " << newMsgs << "/" << msgs.size() << " messages" << std::endl; -#endif + if (!single) { + fi->workstate = RsFeedReaderFeed::WAITING; + fi->content.clear(); + fi->errorState = errorState; + fi->lastUpdate = time(NULL); } - fi->workstate = RsFeedReaderFeed::WAITING; - fi->content.clear(); - fi->lastUpdate = time(NULL); - - IndicateConfigChanged(); + if (!fi->preview) { + IndicateConfigChanged(); + } } if (!forumId.empty() && !forumMsgs.empty()) { @@ -1670,7 +1833,7 @@ void p3FeedReader::onProcessSuccess_addMsgs(const std::string &feedId, bool resu } } -void p3FeedReader::onProcessError(const std::string &feedId, p3FeedReaderThread::ProcessResult result) +void p3FeedReader::onProcessError(const std::string &feedId, p3FeedReaderThread::ProcessResult result, const std::string &errorString) { { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -1700,17 +1863,22 @@ void p3FeedReader::onProcessError(const std::string &feedId, p3FeedReaderThread: case p3FeedReaderThread::PROCESS_ERROR_INIT: fi->errorState = RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR; break; + case p3FeedReaderThread::PROCESS_UNKNOWN_FORMAT: + fi->errorState = RS_FEED_ERRORSTATE_PROCESS_UNKNOWN_FORMAT; + break; default: fi->errorState = RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR; } -// fi->errorString = error; + fi->errorString = errorString; #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::onProcessError - feed " << fi->feedId << " (" << fi->name << ") error process, result = " << result << ", errorState = " << fi->errorState << std::endl; #endif - IndicateConfigChanged(); + if (!fi->preview) { + IndicateConfigChanged(); + } } if (mNotify) { @@ -1721,6 +1889,7 @@ void p3FeedReader::onProcessError(const std::string &feedId, p3FeedReaderThread: void p3FeedReader::setFeedInfo(const std::string &feedId, const std::string &name, const std::string &description) { bool changed = false; + bool preview; std::string forumId; ForumInfo forumInfoNew; @@ -1738,6 +1907,7 @@ void p3FeedReader::setFeedInfo(const std::string &feedId, const std::string &nam } RsFeedReaderFeed *fi = it->second; + preview = fi->preview; if (fi->name != name) { #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::setFeedInfo - feed " << fi->feedId << " changed name from " << fi->name << " to " << name << std::endl; @@ -1753,7 +1923,7 @@ void p3FeedReader::setFeedInfo(const std::string &feedId, const std::string &nam changed = true; } - if ((fi->flag & RS_FEED_FLAG_FORUM) && (fi->flag & RS_FEED_FLAG_UPDATE_FORUM_INFO) && !fi->forumId.empty()) { + if ((fi->flag & RS_FEED_FLAG_FORUM) && (fi->flag & RS_FEED_FLAG_UPDATE_FORUM_INFO) && !fi->forumId.empty() && !preview) { /* change forum too */ forumId = fi->forumId; librs::util::ConvertUtf8ToUtf16(fi->name, forumInfoNew.forumName); @@ -1763,7 +1933,9 @@ void p3FeedReader::setFeedInfo(const std::string &feedId, const std::string &nam } if (changed) { - IndicateConfigChanged(); + if (!preview) { + IndicateConfigChanged(); + } if (mNotify) { mNotify->feedChanged(feedId, NOTIFY_TYPE_MOD); diff --git a/plugins/FeedReader/services/p3FeedReader.h b/plugins/FeedReader/services/p3FeedReader.h index e4525a65b..2bced3c0f 100644 --- a/plugins/FeedReader/services/p3FeedReader.h +++ b/plugins/FeedReader/services/p3FeedReader.h @@ -49,33 +49,35 @@ public: virtual bool getStandardProxy(std::string &proxyAddress, uint16_t &proxyPort); virtual void setStandardProxy(bool useProxy, const std::string &proxyAddress, uint16_t proxyPort); - virtual RsFeedAddResult addFolder(const std::string parentId, const std::string &name, std::string &feedId); - virtual RsFeedAddResult setFolder(const std::string &feedId, const std::string &name); - virtual RsFeedAddResult addFeed(const FeedInfo &feedInfo, std::string &feedId); - virtual RsFeedAddResult setFeed(const std::string &feedId, const FeedInfo &feedInfo); - virtual bool removeFeed(const std::string &feedId); - virtual void getFeedList(const std::string &parentId, std::list &feedInfos); - virtual bool getFeedInfo(const std::string &feedId, FeedInfo &feedInfo); - virtual bool getMsgInfo(const std::string &feedId, const std::string &msgId, FeedMsgInfo &msgInfo); - virtual bool removeMsg(const std::string &feedId, const std::string &msgId); - virtual bool removeMsgs(const std::string &feedId, const std::list &msgIds); - virtual bool getMessageCount(const std::string &feedId, uint32_t *msgCount, uint32_t *newCount, uint32_t *unreadCount); - virtual bool getFeedMsgList(const std::string &feedId, std::list &msgInfos); - virtual bool processFeed(const std::string &feedId); - virtual bool setMessageRead(const std::string &feedId, const std::string &msgId, bool read); + virtual RsFeedAddResult addFolder(const std::string parentId, const std::string &name, std::string &feedId); + virtual RsFeedAddResult setFolder(const std::string &feedId, const std::string &name); + virtual RsFeedAddResult addFeed(const FeedInfo &feedInfo, std::string &feedId); + virtual RsFeedAddResult setFeed(const std::string &feedId, const FeedInfo &feedInfo); + virtual bool removeFeed(const std::string &feedId); + virtual bool addPreviewFeed(const FeedInfo &feedInfo, std::string &feedId); + virtual void getFeedList(const std::string &parentId, std::list &feedInfos); + virtual bool getFeedInfo(const std::string &feedId, FeedInfo &feedInfo); + virtual bool getMsgInfo(const std::string &feedId, const std::string &msgId, FeedMsgInfo &msgInfo); + virtual bool removeMsg(const std::string &feedId, const std::string &msgId); + virtual bool removeMsgs(const std::string &feedId, const std::list &msgIds); + virtual bool getMessageCount(const std::string &feedId, uint32_t *msgCount, uint32_t *newCount, uint32_t *unreadCount); + virtual bool getFeedMsgList(const std::string &feedId, std::list &msgInfos); + virtual bool getFeedMsgIdList(const std::string &feedId, std::list &msgIds); + virtual bool processFeed(const std::string &feedId); + virtual bool setMessageRead(const std::string &feedId, const std::string &msgId, bool read); /****************** p3Service STUFF ******************/ virtual int tick(); /****************** internal STUFF *******************/ - bool getFeedToDownload(RsFeedReaderFeed &feed); + bool getFeedToDownload(RsFeedReaderFeed &feed, const std::string &neededFeedId); void onDownloadSuccess(const std::string &feedId, const std::string &content, std::string &icon); - void onDownloadError(const std::string &feedId, p3FeedReaderThread::DownloadResult result, const std::string &error); + void onDownloadError(const std::string &feedId, p3FeedReaderThread::DownloadResult result, const std::string &errorString); bool onProcessSuccess_filterMsg(const std::string &feedId, std::list &msgs); - void onProcessSuccess_addMsgs(const std::string &feedId, bool result, std::list &msgs); - void onProcessError(const std::string &feedId, p3FeedReaderThread::ProcessResult result); + void onProcessSuccess_addMsgs(const std::string &feedId, bool result, std::list &msgs, bool single); + void onProcessError(const std::string &feedId, p3FeedReaderThread::ProcessResult result, const std::string &errorString); - bool getFeedToProcess(RsFeedReaderFeed &feed); + bool getFeedToProcess(RsFeedReaderFeed &feed, const std::string &neededFeedId); void setFeedInfo(const std::string &feedId, const std::string &name, const std::string &description); @@ -89,14 +91,17 @@ protected: private: void cleanFeeds(); void deleteAllMsgs_locked(RsFeedReaderFeed *fi); + void stopPreviewThreads_locked(); - std::list mThreads; - uint32_t mNextFeedId; - uint32_t mNextMsgId; time_t mLastClean; RsFeedReaderNotify *mNotify; RsMutex mFeedReaderMtx; + std::list mThreads; + uint32_t mNextFeedId; + uint32_t mNextMsgId; + int32_t mNextPreviewFeedId; + int32_t mNextPreviewMsgId; uint32_t mStandardUpdateInterval; uint32_t mStandardStorageTime; bool mStandardUseProxy; @@ -109,6 +114,10 @@ private: RsMutex mProcessMutex; std::list mProcessFeeds; + + RsMutex mPreviewMutex; + p3FeedReaderThread *mPreviewDownloadThread; + p3FeedReaderThread *mPreviewProcessThread; }; #endif diff --git a/plugins/FeedReader/services/p3FeedReaderThread.cc b/plugins/FeedReader/services/p3FeedReaderThread.cc index b95589c01..4ee228951 100644 --- a/plugins/FeedReader/services/p3FeedReaderThread.cc +++ b/plugins/FeedReader/services/p3FeedReaderThread.cc @@ -23,10 +23,9 @@ #include "rsFeedReaderItems.h" #include "util/rsstring.h" #include "util/CURLWrapper.h" +#include "util/XMLWrapper.h" +#include "util/HTMLWrapper.h" -#include -#include -#include #include enum FeedFormat { FORMAT_RSS, FORMAT_RDF }; @@ -36,23 +35,13 @@ enum FeedFormat { FORMAT_RSS, FORMAT_RDF }; *********/ #define FEEDREADER_DEBUG -p3FeedReaderThread::p3FeedReaderThread(p3FeedReader *feedReader, Type type) : RsThread(), mFeedReader(feedReader), mType(type) +p3FeedReaderThread::p3FeedReaderThread(p3FeedReader *feedReader, Type type, const std::string &feedId) : + RsThread(), mFeedReader(feedReader), mType(type), mFeedId(feedId) { - if (type == PROCESS) { - mCharEncodingHandler = xmlFindCharEncodingHandler ("UTF8"); - - if (!mCharEncodingHandler) { - /* no encoding handler found */ - std::cerr << "p3FeedReaderThread::p3FeedReaderThread - no encoding handler found" << std::endl; - } - } else { - mCharEncodingHandler = NULL; - } } p3FeedReaderThread::~p3FeedReaderThread() { - xmlCharEncCloseFunc((xmlCharEncodingHandlerPtr) mCharEncodingHandler); } /***************************************************************************/ @@ -73,16 +62,16 @@ void p3FeedReaderThread::run() case DOWNLOAD: { RsFeedReaderFeed feed; - if (mFeedReader->getFeedToDownload(feed)) { + if (mFeedReader->getFeedToDownload(feed, mFeedId)) { std::string content; std::string icon; - std::string error; + std::string errorString; - DownloadResult result = download(feed, content, icon, error); + DownloadResult result = download(feed, content, icon, errorString); if (result == DOWNLOAD_SUCCESS) { mFeedReader->onDownloadSuccess(feed.feedId, content, icon); } else { - mFeedReader->onDownloadError(feed.feedId, result, error); + mFeedReader->onDownloadError(feed.feedId, result, errorString); } } } @@ -90,31 +79,48 @@ void p3FeedReaderThread::run() case PROCESS: { RsFeedReaderFeed feed; - if (mFeedReader->getFeedToProcess(feed)) { + if (mFeedReader->getFeedToProcess(feed, mFeedId)) { std::list msgs; - std::string error; + std::string errorString; std::list::iterator it; - ProcessResult result = process(feed, msgs, error); + ProcessResult result = process(feed, msgs, errorString); if (result == PROCESS_SUCCESS) { /* first, filter the messages */ bool result = mFeedReader->onProcessSuccess_filterMsg(feed.feedId, msgs); if (isRunning()) { if (result) { - long todo; // process new items /* second, process the descriptions */ - for (it = msgs.begin(); it != msgs.end(); ++it) { + for (it = msgs.begin(); it != msgs.end(); ) { RsFeedReaderMsg *mi = *it; processMsg(feed, mi); + + if (feed.preview) { + /* add every message */ + it = msgs.erase(it); + + std::list msgSingle; + msgSingle.push_back(mi); + mFeedReader->onProcessSuccess_addMsgs(feed.feedId, result, msgSingle, true); + + /* delete not accepted message */ + std::list::iterator it1; + for (it1 = msgSingle.begin(); it1 != msgSingle.end(); ++it1) { + delete (*it1); + } + } else { + ++it; + } } } /* third, add messages */ - mFeedReader->onProcessSuccess_addMsgs(feed.feedId, result, msgs); + mFeedReader->onProcessSuccess_addMsgs(feed.feedId, result, msgs, false); } } else { - mFeedReader->onProcessError(feed.feedId, result); + mFeedReader->onProcessError(feed.feedId, result, errorString); } + /* delete not accepted messages */ for (it = msgs.begin(); it != msgs.end(); ++it) { delete (*it); } @@ -299,70 +305,6 @@ p3FeedReaderThread::DownloadResult p3FeedReaderThread::download(const RsFeedRead /****************************** Process ************************************/ /***************************************************************************/ -static bool convertToString(xmlCharEncodingHandlerPtr charEncodingHandler, const xmlChar *xmlText, std::string &text) -{ - bool result = false; - - xmlBufferPtr in = xmlBufferCreateStatic((void*) xmlText, xmlStrlen(xmlText)); - xmlBufferPtr out = xmlBufferCreate(); - int ret = xmlCharEncOutFunc(charEncodingHandler, out, in); - if (ret >= 0) { - result = true; - text = (char*) xmlBufferContent(out); - } - - xmlBufferFree(in); - xmlBufferFree(out); - - return result; -} - -static bool convertFromString(xmlCharEncodingHandlerPtr charEncodingHandler, const char *text, xmlChar *&xmlText) -{ - bool result = false; - - xmlBufferPtr in = xmlBufferCreateStatic((void*) text, strlen(text)); - xmlBufferPtr out = xmlBufferCreate(); - int ret = xmlCharEncOutFunc(charEncodingHandler, out, in); - if (ret >= 0) { - result = true; - xmlText = xmlBufferDetach(out); - } - - xmlBufferFree(in); - xmlBufferFree(out); - - return result; -} - -static xmlNodePtr findNode(xmlNodePtr node, const char *name, bool children = false) -{ - if (node->name) { - if (xmlStrcasecmp (node->name, (xmlChar*) name) == 0) { - return node; - } - } - - xmlNodePtr nodeFound = NULL; - if (children) { - if (node->children) { - nodeFound = findNode(node->children, name, children); - if (nodeFound) { - return nodeFound; - } - } - } - - if (node->next) { - nodeFound = findNode(node->next, name, children); - if (nodeFound) { - return nodeFound; - } - } - - return NULL; -} - static xmlNodePtr getNextItem(FeedFormat feedFormat, xmlNodePtr channel, xmlNodePtr item) { if (!channel) { @@ -384,7 +326,7 @@ static xmlNodePtr getNextItem(FeedFormat feedFormat, xmlNodePtr channel, xmlNode item = item->next; } for (; item; item = item->next) { - if (item->type == XML_ELEMENT_NODE && xmlStrcasecmp (item->name, (xmlChar*) "item") == 0) { + if (item->type == XML_ELEMENT_NODE && xmlStrcasecmp(item->name, (const xmlChar*) "item") == 0) { break; } } @@ -392,70 +334,6 @@ static xmlNodePtr getNextItem(FeedFormat feedFormat, xmlNodePtr channel, xmlNode return item; } -static bool getChildText(/*xmlCharEncodingHandlerPtr*/ void *charEncodingHandler, xmlNodePtr node, const char *childName, std::string &text) -{ - if (node == NULL || node->children == NULL) { - return false; - } - - xmlNodePtr child = findNode(node->children, childName, true); - if (!child) { - return false; - } - - if (child->type != XML_ELEMENT_NODE) { - return false; - } - - if (!child->children) { - return false; - } - - if (child->children->type != XML_TEXT_NODE) { - return false; - } - - if (child->children->content) { - return convertToString((xmlCharEncodingHandlerPtr) charEncodingHandler, child->children->content, text); - } - - return true; -} - -static std::string xmlGetAttr(/*xmlCharEncodingHandlerPtr*/ void *charEncodingHandler, xmlNodePtr node, const char *name) -{ - if (!node || !name) { - return ""; - } - - std::string value; - - xmlChar *xmlValue = xmlGetProp(node, (const xmlChar*) name); - if (xmlValue) { - convertToString((xmlCharEncodingHandlerPtr) charEncodingHandler, xmlValue, value); - xmlFree(xmlValue); - } - - return value; -} - -static bool xmlSetAttr(/*xmlCharEncodingHandlerPtr*/ void *charEncodingHandler, xmlNodePtr node, const char *name, const char *value) -{ - if (!node || !name) { - return false; - } - - xmlChar *xmlValue = NULL; - if (!convertFromString((xmlCharEncodingHandlerPtr) charEncodingHandler, value, xmlValue)) { - return false; - } - - xmlAttrPtr xmlAttr = xmlSetProp (node, (const xmlChar*) name, xmlValue); - xmlFree(xmlValue); - - return xmlAttr != NULL; -} - static void splitString(std::string s, std::vector &v, const char d) { v.clear(); @@ -919,14 +797,14 @@ p3FeedReaderThread::ProcessResult p3FeedReaderThread::process(const RsFeedReader ProcessResult result = PROCESS_SUCCESS; - xmlDocPtr document = xmlReadDoc((const xmlChar*) feed.content.c_str(), "", NULL, XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_COMPACT | XML_PARSE_NOCDATA); - if (document) { - xmlNodePtr root = xmlDocGetRootElement(document); + XMLWrapper xml; + if (xml.readXML(feed.content.c_str())) { + xmlNodePtr root = xml.getRootElement(); if (root) { FeedFormat feedFormat; - if (xmlStrcmp (root->name, (xmlChar*) "rss") == 0) { + if (xmlStrcasecmp(root->name, (const xmlChar*) "rss") == 0) { feedFormat = FORMAT_RSS; - } else if (xmlStrcmp (root->name, (xmlChar*) "rdf") != 0) { + } else if (xmlStrcasecmp (root->name, (const xmlChar*) "rdf") != 0) { feedFormat = FORMAT_RDF; } else { result = PROCESS_UNKNOWN_FORMAT; @@ -934,18 +812,18 @@ p3FeedReaderThread::ProcessResult p3FeedReaderThread::process(const RsFeedReader } if (result == PROCESS_SUCCESS) { - xmlNodePtr channel = findNode(root->children, "channel"); + xmlNodePtr channel = xml.findNode(root->children, "channel"); if (channel) { /* import header info */ if (feed.flag & RS_FEED_FLAG_INFO_FROM_FEED) { std::string title; - if (getChildText(mCharEncodingHandler, channel, "title", title) && !title.empty()) { + if (xml.getChildText(channel, "title", title) && !title.empty()) { std::string::size_type p; while ((p = title.find_first_of("\r\n")) != std::string::npos) { title.erase(p, 1); } std::string description; - getChildText(mCharEncodingHandler, channel, "description", description); + xml.getChildText(channel, "description", description); mFeedReader->setFeedInfo(feed.feedId, title, description); } } @@ -958,7 +836,7 @@ p3FeedReaderThread::ProcessResult p3FeedReaderThread::process(const RsFeedReader } std::string title; - if (!getChildText(mCharEncodingHandler, node, "title", title) || title.empty()) { + if (!xml.getChildText(node, "title", title) || title.empty()) { continue; } @@ -974,8 +852,8 @@ p3FeedReaderThread::ProcessResult p3FeedReaderThread::process(const RsFeedReader item->title = title; /* try feedburner:origLink */ - if (!getChildText(mCharEncodingHandler, node, "origLink", item->link) || item->link.empty()) { - getChildText(mCharEncodingHandler, node, "link", item->link); + if (!xml.getChildText(node, "origLink", item->link) || item->link.empty()) { + xml.getChildText(node, "link", item->link); } long todo; // remove sid @@ -1002,15 +880,15 @@ p3FeedReaderThread::ProcessResult p3FeedReaderThread::process(const RsFeedReader // sLink.Delete (nSIDStart, nSIDEnd - nSIDStart); // } - getChildText(mCharEncodingHandler, node, "author", item->author); + xml.getChildText(node, "author", item->author); - getChildText(mCharEncodingHandler, node, "description", item->description); + xml.getChildText(node, "description", item->description); std::string pubDate; - if (getChildText(mCharEncodingHandler, node, "pubdate", pubDate)) { + if (xml.getChildText(node, "pubdate", pubDate)) { item->pubDate = parseRFC822Date(pubDate); } - if (getChildText(mCharEncodingHandler, node, "date", pubDate)) { + if (xml.getChildText(node, "date", pubDate)) { item->pubDate = parseISO8601Date (pubDate); } @@ -1030,8 +908,6 @@ p3FeedReaderThread::ProcessResult p3FeedReaderThread::process(const RsFeedReader result = PROCESS_UNKNOWN_FORMAT; error = "Can't read document"; } - - xmlFreeDoc(document); } else { result = PROCESS_ERROR_INIT; } @@ -1101,9 +977,9 @@ bool p3FeedReaderThread::processMsg(const RsFeedReaderFeed &feed, RsFeedReaderMs /* process description */ long todo; // encoding - htmlDocPtr document = htmlReadMemory(msg->description.c_str(), msg->description.length(), url.c_str(), "", HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING | HTML_PARSE_COMPACT); - if (document) { - xmlNodePtr root = xmlDocGetRootElement(document); + HTMLWrapper html; + if (html.readHTML(msg->description.c_str(), url.c_str())) { + xmlNodePtr root = html.getRootElement(); if (root) { /* process all children */ std::list parents; @@ -1118,12 +994,12 @@ bool p3FeedReaderThread::processMsg(const RsFeedReaderFeed &feed, RsFeedReaderMs if (node->type == XML_ELEMENT_NODE) { /* check for image */ - if (strcasecmp((char*) node->name, "img") == 0) { + if (xmlStrcasecmp(node->name, (const xmlChar*) "img") == 0) { bool removeImage = true; if (feed.flag & RS_FEED_FLAG_EMBED_IMAGES) { /* embed image */ - std::string src = xmlGetAttr(mCharEncodingHandler, node, "src"); + std::string src = html.getAttr(node, "src"); if (!src.empty()) { /* download image */ #ifdef FEEDREADER_DEBUG @@ -1139,7 +1015,7 @@ bool p3FeedReaderThread::processMsg(const RsFeedReaderFeed &feed, RsFeedReaderMs if (toBase64(data, base64)) { std::string imageBase64; rs_sprintf(imageBase64, "data:%s;base64,%s", contentType.c_str(), base64.c_str()); - if (xmlSetAttr(mCharEncodingHandler, node, "src", imageBase64.c_str())) { + if (html.setAttr(node, "src", imageBase64.c_str())) { removeImage = false; } } @@ -1163,26 +1039,20 @@ bool p3FeedReaderThread::processMsg(const RsFeedReaderFeed &feed, RsFeedReaderMs } } - xmlChar *html = NULL; - int htmlSize = 0; - htmlDocDumpMemoryFormat(document, &html, &htmlSize, 0); - if (html) { - convertToString((xmlCharEncodingHandlerPtr) mCharEncodingHandler, html, msg->description); - xmlFree(html); + if (isRunning()) { + if (!html.saveHTML(msg->description)) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot dump html" << std::endl; +#endif + result = false; + } } else { #ifdef FEEDREADER_DEBUG - std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot dump html" << std::endl; + std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") no root element" << std::endl; #endif result = false; } - } else { -#ifdef FEEDREADER_DEBUG - std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") no root element" << std::endl; -#endif - result = false; } - - xmlFreeDoc(document); } return result; diff --git a/plugins/FeedReader/services/p3FeedReaderThread.h b/plugins/FeedReader/services/p3FeedReaderThread.h index b405b8822..5da053fd0 100644 --- a/plugins/FeedReader/services/p3FeedReaderThread.h +++ b/plugins/FeedReader/services/p3FeedReaderThread.h @@ -43,8 +43,7 @@ public: DOWNLOAD_ERROR, DOWNLOAD_UNKNOWN_CONTENT_TYPE, DOWNLOAD_NOT_FOUND, - DOWNLOAD_UNKOWN_RESPONSE_CODE, - DOWNLOAD_INTERNAL_ERROR + DOWNLOAD_UNKOWN_RESPONSE_CODE }; enum ProcessResult { @@ -54,9 +53,11 @@ public: }; public: - p3FeedReaderThread(p3FeedReader *feedReader, Type type); + p3FeedReaderThread(p3FeedReader *feedReader, Type type, const std::string &feedId); virtual ~p3FeedReaderThread(); + std::string getFeedId() { return mFeedId; } + private: virtual void run(); @@ -68,7 +69,7 @@ private: p3FeedReader *mFeedReader; Type mType; - /*xmlCharEncodingHandlerPtr*/ void *mCharEncodingHandler; + std::string mFeedId; }; #endif diff --git a/plugins/FeedReader/services/rsFeedReaderItems.cc b/plugins/FeedReader/services/rsFeedReaderItems.cc index 8b6222994..2183ffcdd 100644 --- a/plugins/FeedReader/services/rsFeedReaderItems.cc +++ b/plugins/FeedReader/services/rsFeedReaderItems.cc @@ -50,6 +50,7 @@ void RsFeedReaderFeed::clear() errorState = RS_FEED_ERRORSTATE_OK; errorString.clear(); + preview = false; workstate = WAITING; content.clear(); } @@ -176,7 +177,9 @@ RsFeedReaderFeed *RsFeedReaderSerialiser::deserialiseFeed(void *data, uint32_t * ok &= getRawUInt32(data, rssize, &offset, &(item->storageTime)); ok &= getRawUInt32(data, rssize, &offset, &(item->flag)); ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_VALUE, item->forumId); - ok &= getRawUInt32(data, rssize, &offset, &(item->errorState)); + uint32_t errorState = 0; + ok &= getRawUInt32(data, rssize, &offset, &errorState); + item->errorState = (RsFeedReaderErrorState) errorState; ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_VALUE, item->errorString); if (offset != rssize) diff --git a/plugins/FeedReader/services/rsFeedReaderItems.h b/plugins/FeedReader/services/rsFeedReaderItems.h index 7f6703290..3a2e720c3 100644 --- a/plugins/FeedReader/services/rsFeedReaderItems.h +++ b/plugins/FeedReader/services/rsFeedReaderItems.h @@ -32,20 +32,6 @@ const uint8_t RS_PKT_SUBTYPE_FEEDREADER_MSG = 0x03; /**************************************************************************/ -#define RS_FEED_ERRORSTATE_OK 0 -#define RS_FEED_ERRORSTATE_DOWNLOAD_INTERNAL_ERROR 1 -#define RS_FEED_ERRORSTATE_DOWNLOAD_ERROR 2 -#define RS_FEED_ERRORSTATE_DOWNLOAD_UNKNOWN_CONTENT_TYPE 3 -#define RS_FEED_ERRORSTATE_DOWNLOAD_NOT_FOUND 4 -#define RS_FEED_ERRORSTATE_DOWNLOAD_UNKOWN_RESPONSE_CODE 5 - -#define RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR 50 - -#define RS_FEED_ERRORSTATE_FORUM_CREATE 100 -#define RS_FEED_ERRORSTATE_FORUM_NOT_FOUND 101 -#define RS_FEED_ERRORSTATE_FORUM_NO_ADMIN 102 -#define RS_FEED_ERRORSTATE_FORUM_NO_ANONYMOUS_FORUM 103 - #define RS_FEED_FLAG_FOLDER 0x001 #define RS_FEED_FLAG_INFO_FROM_FEED 0x002 #define RS_FEED_FLAG_STANDARD_STORAGE_TIME 0x004 @@ -76,25 +62,26 @@ public: virtual void clear(); virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); - std::string feedId; - std::string parentId; - std::string name; - std::string url; - std::string user; - std::string password; - std::string proxyAddress; - uint16_t proxyPort; - uint32_t updateInterval; - time_t lastUpdate; - uint32_t flag; // RS_FEED_FLAG_... - std::string forumId; - uint32_t storageTime; - std::string description; - std::string icon; - uint32_t errorState; - std::string errorString; + std::string feedId; + std::string parentId; + std::string name; + std::string url; + std::string user; + std::string password; + std::string proxyAddress; + uint16_t proxyPort; + uint32_t updateInterval; + time_t lastUpdate; + uint32_t flag; // RS_FEED_FLAG_... + std::string forumId; + uint32_t storageTime; + std::string description; + std::string icon; + RsFeedReaderErrorState errorState; + std::string errorString; /* Not Serialised */ + bool preview; WorkState workstate; std::string content; diff --git a/plugins/FeedReader/services/util/CURLWrapper.cc b/plugins/FeedReader/util/CURLWrapper.cpp similarity index 100% rename from plugins/FeedReader/services/util/CURLWrapper.cc rename to plugins/FeedReader/util/CURLWrapper.cpp diff --git a/plugins/FeedReader/services/util/CURLWrapper.h b/plugins/FeedReader/util/CURLWrapper.h similarity index 100% rename from plugins/FeedReader/services/util/CURLWrapper.h rename to plugins/FeedReader/util/CURLWrapper.h diff --git a/plugins/FeedReader/util/HTMLWrapper.cpp b/plugins/FeedReader/util/HTMLWrapper.cpp new file mode 100644 index 000000000..2722af72e --- /dev/null +++ b/plugins/FeedReader/util/HTMLWrapper.cpp @@ -0,0 +1,60 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include + +#include "HTMLWrapper.h" +#include + +HTMLWrapper::HTMLWrapper() : XMLWrapper() +{ +} + +bool HTMLWrapper::readHTML(const char *html, const char *url) +{ + cleanup(); + + mDocument = htmlReadMemory(html, strlen(html), url, "", HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING/* | HTML_PARSE_COMPACT*/); + if (mDocument) { + return true; + } + + return false; +} + +bool HTMLWrapper::saveHTML(std::string &html) +{ + if (!mDocument) { + return false; + } + + xmlChar *newHtml = NULL; + int newHtmlSize = 0; + htmlDocDumpMemoryFormat(mDocument, &newHtml, &newHtmlSize, 0); + if (newHtml) { + convertToString(newHtml, html); + xmlFree(newHtml); + + return true; + } + + return false; +} diff --git a/plugins/FeedReader/util/HTMLWrapper.h b/plugins/FeedReader/util/HTMLWrapper.h new file mode 100644 index 000000000..e93552da8 --- /dev/null +++ b/plugins/FeedReader/util/HTMLWrapper.h @@ -0,0 +1,36 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#ifndef HTMLWRAPPER +#define HTMLWRAPPER + +#include "XMLWrapper.h" + +class HTMLWrapper : public XMLWrapper +{ +public: + HTMLWrapper(); + + bool readHTML(const char *html, const char *url); + bool saveHTML(std::string &html); +}; + +#endif diff --git a/plugins/FeedReader/util/XMLWrapper.cpp b/plugins/FeedReader/util/XMLWrapper.cpp new file mode 100644 index 000000000..ddb5a02fc --- /dev/null +++ b/plugins/FeedReader/util/XMLWrapper.cpp @@ -0,0 +1,245 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include +#include + +#include "XMLWrapper.h" + +XMLWrapper::XMLWrapper() +{ + mDocument = NULL; + mCharEncodingHandler = xmlFindCharEncodingHandler ("UTF8"); + + if (!mCharEncodingHandler) { + /* no encoding handler found */ + std::cerr << "XMLWrapper::XMLWrapper - no encoding handler found" << std::endl; + } +} + +XMLWrapper::~XMLWrapper() +{ + cleanup(); + xmlCharEncCloseFunc(mCharEncodingHandler); +} + +void XMLWrapper::cleanup() +{ + if (mDocument) { + xmlFreeDoc(mDocument); + mDocument = NULL; + } +} + +bool XMLWrapper::convertToString(const xmlChar *xmlText, std::string &text) +{ + bool result = false; + + xmlBufferPtr in = xmlBufferCreateStatic((void*) xmlText, xmlStrlen(xmlText)); + xmlBufferPtr out = xmlBufferCreate(); + int ret = xmlCharEncOutFunc(mCharEncodingHandler, out, in); + if (ret >= 0) { + result = true; + text = (char*) xmlBufferContent(out); + } + + xmlBufferFree(in); + xmlBufferFree(out); + + return result; +} + +bool XMLWrapper::convertFromString(const char *text, xmlChar *&xmlText) +{ + bool result = false; + + xmlBufferPtr in = xmlBufferCreateStatic((void*) text, strlen(text)); + xmlBufferPtr out = xmlBufferCreate(); + int ret = xmlCharEncOutFunc(mCharEncodingHandler, out, in); + if (ret >= 0) { + result = true; + xmlText = xmlBufferDetach(out); + } + + xmlBufferFree(in); + xmlBufferFree(out); + + return result; +} + +xmlNodePtr XMLWrapper::getRootElement() +{ + if (mDocument) { + return xmlDocGetRootElement(mDocument); + } + + return NULL; +} + +bool XMLWrapper::readXML(const char *xml) +{ + cleanup(); + + mDocument = xmlReadDoc((const xmlChar*) xml, "", NULL, XML_PARSE_NOERROR | XML_PARSE_NOWARNING/* | XML_PARSE_COMPACT | XML_PARSE_NOCDATA*/); + if (mDocument) { + return true; + } + + return false; +} + +bool XMLWrapper::getContent(xmlNodePtr node, std::string &content) +{ + content.clear(); + + if (!node) { + return false; + } + + xmlChar *xmlContent = xmlNodeListGetString(mDocument, node, 1); + if (!xmlContent) { + return true; + } + + bool result = convertToString(xmlContent, content); + xmlFree(xmlContent); + + return result; +} + +std::string XMLWrapper::nodeName(xmlNodePtr node) +{ + std::string name; + + if (node) { + convertToString(node->name, name); + } + + return name; +} + +std::string XMLWrapper::attrName(xmlAttrPtr attr) +{ + std::string name; + + if (attr) { + convertToString(attr->name, name); + } + + return name; +} + +xmlNodePtr XMLWrapper::findNode(xmlNodePtr node, const char *name, bool children) +{ + if (node->name) { + if (xmlStrcasecmp(node->name, (xmlChar*) name) == 0) { + return node; + } + } + + xmlNodePtr nodeFound = NULL; + if (children) { + if (node->children) { + nodeFound = findNode(node->children, name, children); + if (nodeFound) { + return nodeFound; + } + } + } + + if (node->next) { + nodeFound = findNode(node->next, name, children); + if (nodeFound) { + return nodeFound; + } + } + + return NULL; +} + +bool XMLWrapper::getChildText(xmlNodePtr node, const char *childName, std::string &text) +{ + if (node == NULL || node->children == NULL) { + return false; + } + + xmlNodePtr child = findNode(node->children, childName, true); + if (!child) { + return false; + } + + if (child->type != XML_ELEMENT_NODE) { + return false; + } + + if (!child->children) { + return false; + } + + if (child->children->type != XML_TEXT_NODE) { + return false; + } + + if (child->children->content) { + return convertToString(child->children->content, text); + } + + return true; +} + +std::string XMLWrapper::getAttr(xmlNodePtr node, xmlAttrPtr attr) +{ + return getAttr(node, (const char*) attr->name); +} + +std::string XMLWrapper::getAttr(xmlNodePtr node, const char *name) +{ + if (!node || !name) { + return ""; + } + + std::string value; + + xmlChar *xmlValue = xmlGetProp(node, (const xmlChar*) name); + if (xmlValue) { + convertToString(xmlValue, value); + xmlFree(xmlValue); + } + + return value; +} + +bool XMLWrapper::setAttr(xmlNodePtr node, const char *name, const char *value) +{ + if (!node || !name) { + return false; + } + + xmlChar *xmlValue = NULL; + if (!convertFromString(value, xmlValue)) { + return false; + } + + xmlAttrPtr xmlAttr = xmlSetProp (node, (const xmlChar*) name, xmlValue); + xmlFree(xmlValue); + + return xmlAttr != NULL; +} diff --git a/plugins/FeedReader/util/XMLWrapper.h b/plugins/FeedReader/util/XMLWrapper.h new file mode 100644 index 000000000..8a896d44c --- /dev/null +++ b/plugins/FeedReader/util/XMLWrapper.h @@ -0,0 +1,60 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#ifndef XMLWRAPPER +#define XMLWRAPPER + +#include +#include + +class XMLWrapper +{ +public: + XMLWrapper(); + ~XMLWrapper(); + + void cleanup(); + + bool readXML(const char *xml); + + std::string nodeName(xmlNodePtr node); + std::string attrName(xmlAttrPtr attr); + + xmlNodePtr findNode(xmlNodePtr node, const char *name, bool children = false); + bool getChildText(xmlNodePtr node, const char *childName, std::string &text); + + bool getContent(xmlNodePtr node, std::string &content); + + std::string getAttr(xmlNodePtr node, xmlAttrPtr attr); + std::string getAttr(xmlNodePtr node, const char *name); + bool setAttr(xmlNodePtr node, const char *name, const char *value); + + xmlNodePtr getRootElement(); + +protected: + xmlDocPtr mDocument; + xmlCharEncodingHandlerPtr mCharEncodingHandler; + + bool convertToString(const xmlChar *xmlText, std::string &text); + bool convertFromString(const char *text, xmlChar *&xmlText); +}; + +#endif From 2c4a1bf6e44281689505d807a3c3fc02edae6439 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 16 Aug 2012 15:24:16 +0000 Subject: [PATCH 024/222] compatibility with libssh4 git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5433 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/ssh/rssshd.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/retroshare-nogui/src/ssh/rssshd.cc b/retroshare-nogui/src/ssh/rssshd.cc index 0d486d43f..a5d1cc6f0 100644 --- a/retroshare-nogui/src/ssh/rssshd.cc +++ b/retroshare-nogui/src/ssh/rssshd.cc @@ -32,7 +32,9 @@ RsSshd *rsSshd = NULL; // External Reference Variable. // NB: This must be called EARLY before all the threads are launched. RsSshd *RsSshd::InitRsSshd(std::string portStr, std::string rsakeyfile) { +#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0) ssh_threads_set_callbacks(ssh_threads_get_pthread()); +#endif ssh_init(); rsSshd = new RsSshd(portStr); @@ -321,10 +323,19 @@ int RsSshd::doEcho() char buf[2048]; do{ +#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0) i=ssh_channel_read(mChannel,buf, 2048, 0); +#else + i=channel_read(mChannel,buf, 2048, 0); +#endif if(i>0) { +#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0) ssh_channel_write(mChannel, buf, i); ssh_channel_write(mChannel, buf, i); +#else + channel_write(mChannel, buf, i); + channel_write(mChannel, buf, i); +#endif if (write(1,buf,i) < 0) { printf("error writing to buffer\n"); return 0; @@ -365,7 +376,11 @@ int RsSshd::doTermServer() while(okay) { char buf; +#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0) int size = ssh_channel_read_nonblocking(mChannel, &buf, 1, 0); +#else + int size = channel_read_nonblocking(mChannel, &buf, 1, 0); +#endif bool haveInput = (size > 0); std::string output; @@ -373,7 +388,11 @@ int RsSshd::doTermServer() if (output.size() > 0) { +#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0) ssh_channel_write(mChannel, output.c_str(), output.size()); +#else + channel_write(mChannel, output.c_str(), output.size()); +#endif } if (!haveInput) From 34ffb229e4790ef7676200c8e45969001c382229 Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 17 Aug 2012 14:22:53 +0000 Subject: [PATCH 025/222] fixed compilation with libssh4 git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5436 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/retroshare-nogui.pro | 5 +++-- retroshare-nogui/src/ssh/rssshd.cc | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/retroshare-nogui/src/retroshare-nogui.pro b/retroshare-nogui/src/retroshare-nogui.pro index c4822441a..0833bab5c 100644 --- a/retroshare-nogui/src/retroshare-nogui.pro +++ b/retroshare-nogui/src/retroshare-nogui.pro @@ -142,8 +142,9 @@ sshserver { # INCLUDEPATH += ../../../lib/libssh-0.5.2/include/ - LIBS += ../../../lib/libssh-0.5.2/build/src/libssh.a - LIBS += ../../../lib/libssh-0.5.2/build/src/threads/libssh_threads.a +# LIBS += ../../../lib/libssh-0.5.2/build/src/libssh.a +# LIBS += ../../../lib/libssh-0.5.2/build/src/threads/libssh_threads.a +LIBS *= -lssh HEADERS += ssh/rssshd.h SOURCES += ssh/rssshd.cc diff --git a/retroshare-nogui/src/ssh/rssshd.cc b/retroshare-nogui/src/ssh/rssshd.cc index a5d1cc6f0..b75c32e89 100644 --- a/retroshare-nogui/src/ssh/rssshd.cc +++ b/retroshare-nogui/src/ssh/rssshd.cc @@ -146,7 +146,11 @@ int RsSshd::listenConnect() return 0; } +#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0) if (ssh_handle_key_exchange(mSession)) +#else + if (ssh_accept(mSession)) +#endif { printf("ssh_handle_key_exchange: %s\n", ssh_get_error(mSession)); return 0; From 5425ab36b55ec6ee20d8766ebd1678b13a423bd4 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sat, 18 Aug 2012 10:01:35 +0000 Subject: [PATCH 026/222] laptop power supply dead, commiting, added tokens to submissions, got it working added generic service string to meta added msg and grp creation git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5439 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsdataservice.cc | 1 + libretroshare/src/gxs/rsgenexchange.cc | 216 +++++++++++++++--- libretroshare/src/gxs/rsgenexchange.h | 36 ++- libretroshare/src/gxs/rsgxsdata.cc | 11 + libretroshare/src/gxs/rsgxsdata.h | 4 +- libretroshare/src/gxs/rsgxsdataaccess.cc | 67 +++++- libretroshare/src/gxs/rsgxsdataaccess.h | 26 +++ libretroshare/src/retroshare/rsidentity.h | 1 + libretroshare/src/retroshare/rsphotoV2.h | 24 +- .../src/serialiser/rsphotov2items.cc | 1 - libretroshare/src/serialiser/rsphotov2items.h | 7 +- .../src/services/p3photoserviceV2.cc | 22 +- libretroshare/src/services/p3photoserviceV2.h | 22 +- .../src/gui/PhotoShare/PhotoAddDialog.cpp | 81 +++++-- .../src/gui/PhotoShare/PhotoAddDialog.h | 7 +- .../src/gui/PhotoShare/PhotoDialog.cpp | 45 +++- .../src/gui/PhotoShare/PhotoDialog.h | 3 +- retroshare-gui/src/util/TokenQueueV2.cpp | 2 +- retroshare-gui/src/util/TokenQueueV2.h | 1 + 19 files changed, 500 insertions(+), 77 deletions(-) diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index 23d64333c..cae3d1367 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -44,6 +44,7 @@ #define KEY_TIME_STAMP std::string("timeStamp") #define KEY_NXS_FLAGS std::string("flags") #define KEY_NXS_META std::string("meta") +#define KEY_NXS_SERV_STRING std::string("serv_str"); // grp table columns diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 9168a58e3..6e3e6abe8 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -63,33 +63,184 @@ void RsGenExchange::tick() publishMsgs(); - notifyChanges(mNotifications); - mNotifications.clear(); + notifyChanges(mNotifications); + mNotifications.clear(); } +bool RsGenExchange::acknowledgeTokenMsg(const uint32_t& token, + std::pair& msgId) +{ + RsStackMutex stack(mGenMtx); + + std::map >::iterator mit = + mMsgPublished.find(token); + + if(mit == mMsgPublished.end()) + return false; + + msgId = mit->second; + + // no dump token as client has ackowledged its completion + mDataAccess->disposeOfPublicToken(token); + + return true; +} + + + +bool RsGenExchange::acknowledgeTokenGrp(const uint32_t& token, + RsGxsGroupId& grpId) +{ + RsStackMutex stack(mGenMtx); + + std::map::iterator mit = + mGrpPublished.find(token); + + if(mit == mGrpPublished.end()) + return false; + + grpId = mit->second; + + // no dump token as client has ackowledged its completion + mDataAccess->disposeOfPublicToken(token); + + return true; +} + void RsGenExchange::createGroup(RsNxsGrp *grp) { /* create Keys */ + + // admin keys RSA *rsa_admin = RSA_generate_key(2048, 65537, NULL, NULL); RSA *rsa_admin_pub = RSAPublicKey_dup(rsa_admin); + // publish keys + RSA *rsa_publish = RSA_generate_key(2048, 65537, NULL, NULL); + RSA *rsa_publish_pub = RSAPublicKey_dup(rsa_admin); /* set keys */ - RsTlvSecurityKey adminKey; + RsTlvSecurityKey adminKey, privAdminKey; + + /* set publish keys */ + RsTlvSecurityKey pubKey, privPubKey; + GxsSecurity::setRSAPublicKey(adminKey, rsa_admin_pub); + GxsSecurity::setRSAPrivateKey(privAdminKey, rsa_admin); + + GxsSecurity::setRSAPublicKey(pubKey, rsa_publish_pub); + GxsSecurity::setRSAPrivateKey(privPubKey, rsa_publish); + + + // for now all public + adminKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_PUBLIC_ONLY; + privAdminKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL; + + // for now all public + pubKey.keyFlags = RSTLV_KEY_DISTRIB_PUBLIC | RSTLV_KEY_TYPE_PUBLIC_ONLY; + privPubKey.keyFlags = RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL; adminKey.startTS = time(NULL); adminKey.endTS = 0; /* no end */ RsGxsGrpMetaData* meta = grp->metaData; + + /* add keys to grp */ + meta->keys.keys[adminKey.keyId] = adminKey; + meta->keys.keys[privAdminKey.keyId] = privAdminKey; + meta->keys.keys[pubKey.keyId] = pubKey; + meta->keys.keys[privPubKey.keyId] = privPubKey; + meta->mGroupId = adminKey.keyId; grp->grpId = meta->mGroupId; adminKey.TlvClear(); + privAdminKey.TlvClear(); + privPubKey.TlvClear(); + pubKey.TlvClear(); // free the private key for now, as it is not in use RSA_free(rsa_admin); + RSA_free(rsa_admin_pub); + + RSA_free(rsa_publish); + RSA_free(rsa_publish_pub); +} + +bool RsGenExchange::createMessage(RsNxsMsg* msg) +{ + const RsGxsGroupId& id = msg->grpId; + + std::map metaMap; + + metaMap.insert(std::make_pair(id, (RsGxsGrpMetaData*)(NULL))); + mDataStore->retrieveGxsGrpMetaData(metaMap); + bool ok = true; + + if(!metaMap[id]) + { + return false; + } + else + { + + // get publish key + RsGxsGrpMetaData* meta = metaMap[id]; + + // public and shared is publish key + RsTlvSecurityKeySet& keys = meta->keys; + RsTlvSecurityKey* pubKey; + + std::map::iterator mit = + keys.keys.begin(), mit_end = keys.keys.end(); + bool pub_key_found = false; + for(; mit != mit_end; mit++) + { + + pub_key_found = mit->second.keyFlags & (RSTLV_KEY_TYPE_FULL | RSTLV_KEY_DISTRIB_PUBLIC); + + if(pub_key_found) + break; + } + + if(pub_key_found) + { + pubKey = &(mit->second); + RSA* rsa_pub = GxsSecurity::extractPrivateKey(*pubKey); + EVP_PKEY *key_pub = EVP_PKEY_new(); + EVP_PKEY_assign_RSA(key_pub, rsa_pub); + + /* calc and check signature */ + EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); + + ok = EVP_SignInit(mdctx, EVP_sha1()) == 1; + ok = EVP_SignUpdate(mdctx, msg->msg.bin_data, msg->msg.bin_len) == 1; + + unsigned int siglen = EVP_PKEY_size(key_pub); + unsigned char sigbuf[siglen]; + ok = EVP_SignFinal(mdctx, sigbuf, &siglen, key_pub) == 1; + + RsGxsMsgMetaData &meta = *(msg->metaData); + meta.pubSign.signData.setBinData(sigbuf, siglen); + meta.pubSign.keyId = pubKey->keyId; + + msg->metaData->mMsgId = msg->msgId = GxsSecurity::getBinDataSign(sigbuf, siglen); + + // clean up + EVP_MD_CTX_destroy(mdctx); + EVP_PKEY_free(key_pub); + RSA_free(rsa_pub); + } + else + { + ok = false; + } + + delete meta; + } + + return ok; } @@ -242,21 +393,25 @@ void RsGenExchange::notifyNewMessages(std::vector& messages) } -bool RsGenExchange::publishGroup(RsGxsGrpItem *grpItem) +bool RsGenExchange::publishGroup(uint32_t& token, RsGxsGrpItem *grpItem) { - RsStackMutex stack(mGenMtx); - mGrpsToPublish.push_back(grpItem); + RsStackMutex stack(mGenMtx); + + token = mDataAccess->generatePublicToken(); + mGrpsToPublish.insert(std::make_pair(token, grpItem)); return true; } -bool RsGenExchange::publishMsg(RsGxsMsgItem *msgItem) +bool RsGenExchange::publishMsg(uint32_t& token, RsGxsMsgItem *msgItem) { RsStackMutex stack(mGenMtx); - mMsgsToPublish.push_back(msgItem); + token = mDataAccess->generatePublicToken(); + mMsgsToPublish.insert(std::make_pair(token, msgItem)); + return true; } @@ -265,13 +420,13 @@ void RsGenExchange::publishMsgs() { RsStackMutex stack(mGenMtx); - std::vector::iterator vit = mMsgsToPublish.begin(); + std::map::iterator mit = mMsgsToPublish.begin(); - for(; vit != mMsgsToPublish.end(); ) + for(; mit != mMsgsToPublish.end(); ) { RsNxsMsg* msg = new RsNxsMsg(mServType); - RsGxsMsgItem* msgItem = *vit; + RsGxsMsgItem* msgItem = mit->second; uint32_t size = mSerialiser->size(msgItem); char mData[size]; bool ok = mSerialiser->serialise(msgItem, mData, &size); @@ -280,21 +435,21 @@ void RsGenExchange::publishMsgs() { msg->metaData = new RsGxsMsgMetaData(); *(msg->metaData) = msgItem->meta; - ok = mDataAccess->addMsgData(msg); + ok = createMessage(msg); if(ok) - { - RsGxsMsgChange* mc = new RsGxsMsgChange(); - mNotifications.push_back(mc); - } + ok = mDataAccess->addMsgData(msg); + + mMsgPublished.insert(std::make_pair(mit->first, std::make_pair(msg->grpId, msg->msgId))); } // if addition failed then delete nxs message if(!ok) { #ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::publishMsgs() failed to serialise msg " << std::endl; + std::cerr << "RsGenExchange::publishMsgs() failed to publish msg " << std::endl; #endif + mMsgPublished.insert(std::make_pair(mit->first, std::make_pair(RsGxsGroupId(""), RsGxsMessageId("")))); delete msg; continue; @@ -313,13 +468,13 @@ void RsGenExchange::publishGrps() RsStackMutex stack(mGenMtx); - std::vector::iterator vit = mGrpsToPublish.begin(); + std::map::iterator mit = mGrpsToPublish.begin(); - for(; vit != mGrpsToPublish.end();) + for(; mit != mGrpsToPublish.end(); mit++) { RsNxsGrp* grp = new RsNxsGrp(mServType); - RsGxsGrpItem* grpItem = *vit; + RsGxsGrpItem* grpItem = mit->second; uint32_t size = mSerialiser->size(grpItem); char gData[size]; @@ -330,11 +485,18 @@ void RsGenExchange::publishGrps() { grp->metaData = new RsGxsGrpMetaData(); *(grp->metaData) = grpItem->meta; - createGroup(grp); + createGroup(grp); + size = grp->metaData->serial_size(); + char mData[size]; + + ok = grp->metaData->serialise(mData, size); + grp->meta.setBinData(mData, size); + ok = mDataAccess->addGroupData(grp); - RsGxsGroupChange* gc = new RsGxsGroupChange(); - gc->grpIdList.push_back(grp->grpId); - mNotifications.push_back(gc); + + // add to published to allow acknowledgement + mGrpPublished.insert(std::make_pair(mit->first, grp->grpId)); + mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE); } if(!ok) @@ -344,12 +506,14 @@ void RsGenExchange::publishGrps() std::cerr << "RsGenExchange::publishGrps() failed to publish grp " << std::endl; #endif delete grp; + + // add to published to allow acknowledgement, grpid is empty as grp creation failed + mGrpPublished.insert(std::make_pair(mit->first, RsGxsGroupId(""))); + mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_STATUS_FAILED); continue; } delete grpItem; - - vit = mGrpsToPublish.erase(vit); } // clear grp list as we're done publishing them and entries diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 6cb1ef7f6..20a8407e5 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -152,6 +152,26 @@ protected: */ bool getMsgData(const uint32_t &token, GxsMsgDataMap& msgItems); +public: + + /*! + * This allows the client service to acknowledge that their msgs has + * been created/modified and retrieve the create/modified msg ids + * @param token the token related to modification/create request + * @param msgIds map of grpid->msgIds of message created/modified + * @return true if token exists false otherwise + */ + bool acknowledgeTokenMsg(const uint32_t& token, std::pair& msgId); + + /*! + * This allows the client service to acknowledge that their grps has + * been created/modified and retrieve the create/modified grp ids + * @param token the token related to modification/create request + * @param msgIds vector of ids of groups created/modified + * @return true if token exists false otherwise + */ + bool acknowledgeTokenGrp(const uint32_t& token, RsGxsGroupId& grpId); + protected: /** Modifications **/ @@ -161,20 +181,20 @@ protected: * If the item exists already this is simply versioned * This will induce a related change message * Ownership of item passes to this rsgenexchange + * @param token * @param grpItem - * @param */ - bool publishGroup(RsGxsGrpItem* grpItem); + bool publishGroup(uint32_t& token, RsGxsGrpItem* grpItem); /*! * Enables publication of a message item * If the item exists already this is simply versioned * This will induce a related a change message * Ownership of item passes to this rsgenexchange + * @param token * @param msgItem - * @return false if msg creation failed. */ - bool publishMsg(RsGxsMsgItem* msgItem); + bool publishMsg(uint32_t& token, RsGxsMsgItem* msgItem); protected: @@ -208,6 +228,7 @@ private: void publishMsgs(); void createGroup(RsNxsGrp* grp); + bool createMessage(RsNxsMsg* msg); private: @@ -220,8 +241,11 @@ private: std::vector mReceivedMsgs; std::vector mReceivedGrps; - std::vector mGrpsToPublish; - std::vector mMsgsToPublish; + std::map mGrpsToPublish; + std::map mMsgsToPublish; + + std::map > mMsgPublished; + std::map mGrpPublished; std::vector mNotifications; diff --git a/libretroshare/src/gxs/rsgxsdata.cc b/libretroshare/src/gxs/rsgxsdata.cc index 7c6e57b3d..33cb7d2b4 100644 --- a/libretroshare/src/gxs/rsgxsdata.cc +++ b/libretroshare/src/gxs/rsgxsdata.cc @@ -42,6 +42,8 @@ uint32_t RsGxsGrpMetaData::serial_size() s += 4; s += 4; s += GetTlvStringSize(mAuthorId); + s += GetTlvStringSize(mServiceString); + s += adminSign.TlvSize(); s += keys.TlvSize(); s += idSign.TlvSize(); @@ -55,6 +57,7 @@ void RsGxsGrpMetaData::clear(){ mOrigGrpId.clear(); mAuthorId.clear(); mGroupName.clear(); + mServiceString.clear(); mPublishTs = 0; mGroupFlags = 0; mPop = 0; @@ -98,6 +101,7 @@ bool RsGxsGrpMetaData::serialise(void *data, uint32_t &pktsize) ok &= setRawUInt32(data, tlvsize, &offset, mGroupFlags); ok &= setRawUInt32(data, tlvsize, &offset, mPublishTs); ok &= SetTlvString(data, tlvsize, &offset, 0, mAuthorId); + ok &= SetTlvString(data, tlvsize, &offset, 0, mServiceString); ok &= adminSign.SetTlv(data, tlvsize, &offset); ok &= keys.SetTlv(data, tlvsize, &offset); @@ -124,6 +128,7 @@ bool RsGxsGrpMetaData::deserialise(void *data, uint32_t &pktsize) ok &= getRawUInt32(data, pktsize, &offset, &mGroupFlags); ok &= getRawUInt32(data, pktsize, &offset, &mPublishTs); ok &= GetTlvString(data, pktsize, &offset, 0, mAuthorId); + ok &= GetTlvString(data, pktsize, &offset, 0, mServiceString); ok &= adminSign.GetTlv(data, pktsize, &offset); ok &= keys.GetTlv(data, pktsize, &offset); @@ -147,6 +152,7 @@ uint32_t RsGxsMsgMetaData::serial_size() s += GetTlvStringSize(mParentId); s += GetTlvStringSize(mOrigMsgId); s += GetTlvStringSize(mAuthorId); + s += GetTlvStringSize(mServiceString); s += pubSign.TlvSize(); s += idSign.TlvSize(); @@ -166,6 +172,7 @@ void RsGxsMsgMetaData::clear() mAuthorId.clear(); mOrigMsgId.clear(); mMsgName.clear(); + mServiceString.clear(); pubSign.TlvClear(); idSign.TlvClear(); @@ -205,6 +212,7 @@ bool RsGxsMsgMetaData::serialise(void *data, uint32_t *size) ok &= SetTlvString(data, *size, &offset, 0, mParentId); ok &= SetTlvString(data, *size, &offset, 0, mOrigMsgId); ok &= SetTlvString(data, *size, &offset, 0, mAuthorId); + ok &= SetTlvString(data, *size, &offset, 0, mServiceString); ok &= pubSign.SetTlv(data, *size, &offset); ok &= idSign.SetTlv(data, *size, &offset); @@ -233,6 +241,7 @@ bool RsGxsMsgMetaData::deserialise(void *data, uint32_t *size) ok &= GetTlvString(data, *size, &offset, 0, mParentId); ok &= GetTlvString(data, *size, &offset, 0, mOrigMsgId); ok &= GetTlvString(data, *size, &offset, 0, mAuthorId); + ok &= GetTlvString(data, *size, &offset, 0, mServiceString); ok &= pubSign.GetTlv(data, *size, &offset); ok &= idSign.GetTlv(data, *size, &offset); @@ -257,6 +266,7 @@ void RsGxsGrpMetaData::operator =(const RsGroupMetaData& rMeta) this->mPublishTs = rMeta.mPublishTs; this->mSubscribeFlags = rMeta.mSubscribeFlags; this->mGroupName = rMeta.mGroupName; + this->mServiceString = rMeta.mServiceString; } void RsGxsMsgMetaData::operator =(const RsMsgMetaData& rMeta) @@ -272,6 +282,7 @@ void RsGxsMsgMetaData::operator =(const RsMsgMetaData& rMeta) this->mParentId = rMeta.mParentId ; this->mPublishTs = rMeta.mPublishTs ; this->mThreadId = rMeta.mThreadId; + this->mServiceString = rMeta.mServiceString; } diff --git a/libretroshare/src/gxs/rsgxsdata.h b/libretroshare/src/gxs/rsgxsdata.h index 88f8d0241..084063b7f 100644 --- a/libretroshare/src/gxs/rsgxsdata.h +++ b/libretroshare/src/gxs/rsgxsdata.h @@ -64,7 +64,7 @@ public: RsTlvSecurityKeySet keys; RsTlvKeySignature idSign; - + std::string mServiceString; // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. @@ -103,6 +103,8 @@ public: RsTlvKeySignature pubSign; RsTlvKeySignature idSign; + std::string mServiceString; + std::string mMsgName; time_t mPublishTs; uint32_t mMsgFlags; // Whats this for? diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index a2c1fc4e3..1c73506b3 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -229,6 +229,14 @@ uint32_t RsGxsDataAccess::requestStatus(uint32_t token) uint32_t reqtype; uint32_t anstype; time_t ts; + + { + RsStackMutex stack(mDataMutex); + + // first check public tokens + if(mPublicToken.find(token) != mPublicToken.end()) + return mPublicToken[token]; + } checkRequestStatus(token, status, reqtype, anstype, ts); return status; @@ -911,7 +919,8 @@ bool RsGxsDataAccess::addMsgData(RsNxsMsg* msg) { -void RsGxsDataAccess::tokenList(std::list& tokens) { +void RsGxsDataAccess::tokenList(std::list& tokens) +{ RsStackMutex stack(mDataMutex); @@ -924,7 +933,8 @@ void RsGxsDataAccess::tokenList(std::list& tokens) { } bool RsGxsDataAccess::locked_updateRequestStatus(const uint32_t& token, - const uint32_t& status) { + const uint32_t& status) +{ GxsRequest* req = locked_retrieveRequest(token); @@ -936,6 +946,59 @@ bool RsGxsDataAccess::locked_updateRequestStatus(const uint32_t& token, return true; } +uint32_t RsGxsDataAccess::generatePublicToken() +{ + + uint32_t token; + generateToken(token); + + { + RsStackMutex stack(mDataMutex); + mPublicToken[token] = RsTokenServiceV2::GXS_REQUEST_STATUS_PENDING; + } + + return token; +} + + + +bool RsGxsDataAccess::updatePublicRequestStatus(const uint32_t& token, + const uint32_t& status) +{ + RsStackMutex stack(mDataMutex); + std::map::iterator mit = mPublicToken.find(token); + + if(mit != mPublicToken.end()) + { + mit->second = status; + } + else + { + return false; + } + + return true; +} + + + +bool RsGxsDataAccess::disposeOfPublicToken(const uint32_t& token) +{ + RsStackMutex stack(mDataMutex); + std::map::iterator mit = mPublicToken.find(token); + + if(mit != mPublicToken.end()) + { + mPublicToken.erase(mit); + } + else + { + return false; + } + + return true; +} + bool RsGxsDataAccess::checkMsgFilter(const RsTokReqOptionsV2& opts, const RsGxsMsgMetaData* meta) const { bool statusMatch = false; diff --git a/libretroshare/src/gxs/rsgxsdataaccess.h b/libretroshare/src/gxs/rsgxsdataaccess.h index 94aea5095..24c928dd2 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.h +++ b/libretroshare/src/gxs/rsgxsdataaccess.h @@ -104,6 +104,7 @@ public: /** E: RsTokenService **/ + public: /*! @@ -248,6 +249,30 @@ private: */ void cleanseMetaFilter(MsgMetaFilter& filter); +public: + + /*! + * Assigns a token value to passed integer + * The status of the token can still be queried from request status feature + * @param token is assigned a unique token value + */ + uint32_t generatePublicToken(); + + /*! + * Update + * @param token + * @param status + * @return false if token could not be found, true if token disposed of + */ + bool updatePublicRequestStatus(const uint32_t &token, const uint32_t &status); + + /*! + * This gets rid of a publicly issued token + * @param token + * @return false if token could not found, true if token disposed of + */ + bool disposeOfPublicToken(const uint32_t &token); + private: /* These perform the actual blocking retrieval of data */ @@ -318,6 +343,7 @@ private: RsGeneralDataService* mDataStore; uint32_t mNextToken; + std::map mPublicToken; std::map mRequests; RsMutex mDataMutex; diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index 8ae3a2550..8fb6df089 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -63,6 +63,7 @@ #define RS_TOKREQ_ANSTYPE_LIST 0x0001 #define RS_TOKREQ_ANSTYPE_SUMMARY 0x0002 #define RS_TOKREQ_ANSTYPE_DATA 0x0003 +#define RS_TOKREQ_ANSTYPE_ACK 0x0004 diff --git a/libretroshare/src/retroshare/rsphotoV2.h b/libretroshare/src/retroshare/rsphotoV2.h index 80ad2ca72..c7d1c0936 100644 --- a/libretroshare/src/retroshare/rsphotoV2.h +++ b/libretroshare/src/retroshare/rsphotoV2.h @@ -261,7 +261,7 @@ public: * @param album The album to be submitted * @return false if submission failed */ - virtual bool submitAlbumDetails(RsPhotoAlbum &album) = 0; + virtual bool submitAlbumDetails(uint32_t& token, RsPhotoAlbum &album) = 0; /*! * This RsGenExchange service will be alerted to this photo as \n @@ -270,7 +270,27 @@ public: * @param photo photo to submit * @return */ - virtual bool submitPhoto(RsPhotoPhoto &photo) = 0; + virtual bool submitPhoto(uint32_t& token, RsPhotoPhoto &photo) = 0; + + + /*! + * This allows the client service to acknowledge that their msgs has + * been created/modified and retrieve the create/modified msg ids + * @param token the token related to modification/create request + * @param msgIds map of grpid->msgIds of message created/modified + * @return true if token exists false otherwise + */ + virtual bool acknowledgeMsg(const uint32_t& token, std::pair& msgId) = 0; + + /*! + * This allows the client service to acknowledge that their grps has + * been created/modified and retrieve the create/modified grp ids + * @param token the token related to modification/create request + * @param msgIds vector of ids of groups created/modified + * @return true if token exists false otherwise + */ + virtual bool acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId) = 0; + }; diff --git a/libretroshare/src/serialiser/rsphotov2items.cc b/libretroshare/src/serialiser/rsphotov2items.cc index 4b64a363e..0bfa559f8 100644 --- a/libretroshare/src/serialiser/rsphotov2items.cc +++ b/libretroshare/src/serialiser/rsphotov2items.cc @@ -31,7 +31,6 @@ uint32_t RsGxsPhotoSerialiser::size(RsItem* item) { - RsGxsPhotoPhotoItem* ppItem = NULL; RsGxsPhotoAlbumItem* paItem = NULL; diff --git a/libretroshare/src/serialiser/rsphotov2items.h b/libretroshare/src/serialiser/rsphotov2items.h index 89cc9c4f9..b08571b5f 100644 --- a/libretroshare/src/serialiser/rsphotov2items.h +++ b/libretroshare/src/serialiser/rsphotov2items.h @@ -44,8 +44,9 @@ public: RsGxsPhotoAlbumItem(): RsGxsGrpItem(RS_SERVICE_TYPE_PHOTO, RS_PKT_SUBTYPE_PHOTO_ITEM) { return;} + virtual ~RsGxsPhotoAlbumItem() { return;} - virtual void clear(); + void clear(); std::ostream &print(std::ostream &out, uint16_t indent = 0); @@ -58,8 +59,8 @@ public: RsGxsPhotoPhotoItem(): RsGxsMsgItem(RS_SERVICE_TYPE_PHOTO, RS_PKT_SUBTYPE_PHOTO_SHOW_ITEM) {return; } - - virtual void clear(); + virtual ~RsGxsPhotoPhotoItem() { return;} + void clear(); std::ostream &print(std::ostream &out, uint16_t indent = 0); RsPhotoPhoto photo; }; diff --git a/libretroshare/src/services/p3photoserviceV2.cc b/libretroshare/src/services/p3photoserviceV2.cc index 392aeb6e9..5dc5e6af9 100644 --- a/libretroshare/src/services/p3photoserviceV2.cc +++ b/libretroshare/src/services/p3photoserviceV2.cc @@ -136,12 +136,12 @@ bool p3PhotoServiceV2::getPhoto(const uint32_t& token, PhotoResult& photos) } -bool p3PhotoServiceV2::submitAlbumDetails(RsPhotoAlbum& album) +bool p3PhotoServiceV2::submitAlbumDetails(uint32_t& token, RsPhotoAlbum& album) { RsGxsPhotoAlbumItem* albumItem = new RsGxsPhotoAlbumItem(); albumItem->album = album; albumItem->meta = album.mMeta; - return RsGenExchange::publishGroup(albumItem); + return RsGenExchange::publishGroup(token, albumItem); } @@ -170,13 +170,27 @@ void p3PhotoServiceV2::notifyChanges(std::vector& changes) } } -bool p3PhotoServiceV2::submitPhoto(RsPhotoPhoto& photo) +bool p3PhotoServiceV2::submitPhoto(uint32_t& token, RsPhotoPhoto& photo) { RsGxsPhotoPhotoItem* photoItem = new RsGxsPhotoPhotoItem(); photoItem->photo = photo; photoItem->meta = photo.mMeta; - return RsGenExchange::publishMsg(photoItem); + return RsGenExchange::publishMsg(token, photoItem); } +bool p3PhotoServiceV2::acknowledgeMsg(const uint32_t& token, + std::pair& msgId) +{ + return RsGenExchange::acknowledgeTokenMsg(token, msgId); +} + + +bool p3PhotoServiceV2::acknowledgeGrp(const uint32_t& token, + RsGxsGroupId& grpId) +{ + return RsGenExchange::acknowledgeTokenGrp(token, grpId); +} + + diff --git a/libretroshare/src/services/p3photoserviceV2.h b/libretroshare/src/services/p3photoserviceV2.h index e2057550c..50a597d3b 100644 --- a/libretroshare/src/services/p3photoserviceV2.h +++ b/libretroshare/src/services/p3photoserviceV2.h @@ -78,8 +78,26 @@ public: /** Modifications **/ - bool submitAlbumDetails(RsPhotoAlbum &album); - bool submitPhoto(RsPhotoPhoto &photo); + bool submitAlbumDetails(uint32_t& token, RsPhotoAlbum &album); + bool submitPhoto(uint32_t& token, RsPhotoPhoto &photo); + + /*! + * This allows the client service to acknowledge that their msgs has + * been created/modified and retrieve the create/modified msg ids + * @param token the token related to modification/create request + * @param msgIds map of grpid->msgIds of message created/modified + * @return true if token exists false otherwise + */ + bool acknowledgeMsg(const uint32_t& token, std::pair& msgId); + + /*! + * This allows the client service to acknowledge that their grps has + * been created/modified and retrieve the create/modified grp ids + * @param token the token related to modification/create request + * @param msgIds vector of ids of groups created/modified + * @return true if token exists false otherwise + */ + bool acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId); private: diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp index 2fe80a10e..b19645214 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp @@ -28,8 +28,8 @@ #include /** Constructor */ -PhotoAddDialog::PhotoAddDialog(QWidget *parent) -: QWidget(parent) +PhotoAddDialog::PhotoAddDialog(TokenQueueV2 *parentQueue, QWidget *parent) +: QWidget(parent), mParentQueue(parentQueue) { ui.setupUi(this); @@ -330,8 +330,9 @@ void PhotoAddDialog::publishAlbum() std::cerr << "PhotoAddDialog::publishAlbum() New Album Mode Submitting....."; std::cerr << std::endl; - - rsPhotoV2->submitAlbumDetails(album); + uint32_t token; + rsPhotoV2->submitAlbumDetails(token, album); + mPhotoQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, 0); } @@ -402,23 +403,14 @@ void PhotoAddDialog::publishPhotos(std::string albumId) /* save image to album path */ photo.path = "unknown"; - std::cerr << "PhotoAddDialog::publishAlbum() Photo(" << i << ") "; + uint32_t token; - if (isNewPhoto) - { - std::cerr << "Is a New Photo"; - rsPhotoV2->submitPhoto(photo); - } - else if (isModifiedPhoto) - { - std::cerr << "Is Updated"; - rsPhotoV2->submitPhoto(photo); - } - else - { - std::cerr << "Is Unchanged"; - } - std::cerr << std::endl; + std::cerr << "PhotoAddDialog::publishAlbum() Photo(" << i << ") "; + std::cerr << "Is Updated"; + + rsPhotoV2->submitPhoto(token, photo); + mPhotoQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); + std::cerr << std::endl; } clearDialog(); @@ -530,14 +522,14 @@ bool PhotoAddDialog::loadAlbumData(const uint32_t &token) RsPhotoAlbum& album = *vit; std::cerr << "PhotoAddDialog::loadAlbumData() AlbumId: " << album.mMeta.mGroupId << std::endl; - //updateAlbumDetails(album); + updateAlbumDetails(album); uint32_t token; std::list albumIds; albumIds.push_back(album.mMeta.mGroupId); req[album.mMeta.mGroupId] = std::vector(); - } + RsTokReqOptionsV2 opts; opts.mOptions = RS_TOKREQOPT_MSG_LATEST; uint32_t t; @@ -573,6 +565,48 @@ bool PhotoAddDialog::loadCreatedAlbum(const uint32_t &token) return true; } +void PhotoAddDialog::acknowledgeGroup(const uint32_t &token) +{ + RsGxsGroupId grpId; + rsPhotoV2->acknowledgeGrp(token, grpId); + + if(!grpId.empty()) + { + std::list grpIds; + grpIds.push_back(grpId); + + RsTokReqOptionsV2 opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + uint32_t reqToken; + + // request for self + mPhotoQueue->requestGroupInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); + + // also request for parent + mParentQueue->requestGroupInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); + } +} + +void PhotoAddDialog::acknowledgeMessage(const uint32_t &token) +{ + std::pair p; + rsPhotoV2->acknowledgeMsg(token, p); + + if(!p.first.empty()) + { + GxsMsgReq req; + std::vector v; + v.push_back(p.second); + req[p.first] = v; + RsTokReqOptionsV2 opts; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + uint32_t reqToken; + mPhotoQueue->requestMsgInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, req, 0); + + mParentQueue->requestMsgInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, req, 0); + } +} void PhotoAddDialog::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req) { @@ -593,6 +627,9 @@ void PhotoAddDialog::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 case RS_TOKREQ_ANSTYPE_SUMMARY: loadCreatedAlbum(req.mToken); break; + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgeGroup(req.mToken); + break; default: std::cerr << "PhotoAddDialog::loadRequest() ERROR: GROUP: INVALID ANS TYPE"; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.h b/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.h index c42bc4774..8e2b407b5 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.h @@ -36,7 +36,7 @@ class PhotoAddDialog : public QWidget, public TokenResponseV2 Q_OBJECT public: - PhotoAddDialog(QWidget *parent = 0); + PhotoAddDialog(TokenQueueV2 *parentQueue, QWidget *parent = 0); void loadAlbum(const std::string &albumId); virtual void loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req); @@ -66,7 +66,8 @@ private: bool loadPhotoData(const uint32_t &token); bool loadAlbumData(const uint32_t &token); bool loadCreatedAlbum(const uint32_t &token); - + void acknowledgeGroup(const uint32_t &token); + void acknowledgeMessage(const uint32_t &token); TokenQueueV2 *mPhotoQueue; protected: @@ -75,7 +76,7 @@ protected: RsPhotoAlbum mAlbumData; PhotoDetailsDialog *mPhotoDetails; Ui::PhotoAddDialog ui; - + TokenQueueV2* mParentQueue; }; #endif diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index 2acd19032..c11ce69c9 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -209,7 +209,7 @@ void PhotoDialog::OpenOrShowPhotoAddDialog() } else { - mAddDialog = new PhotoAddDialog(NULL); + mAddDialog = new PhotoAddDialog(mPhotoQueue, NULL); mAddDialog->show(); } mAddDialog->clearDialog(); @@ -437,7 +437,6 @@ void PhotoDialog::deletePhotoItem(PhotoItem *item, uint32_t type) void PhotoDialog::requestAlbumList(std::list& ids) { - RsTokReqOptionsV2 opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; uint32_t token; @@ -447,6 +446,7 @@ void PhotoDialog::requestAlbumList(std::list& ids) void PhotoDialog::requestPhotoList(GxsMsgReq& req) { RsTokReqOptionsV2 opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; uint32_t token; mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, req, 0); return; @@ -520,14 +520,47 @@ void PhotoDialog::requestPhotoList(const std::string &albumId) } +void PhotoDialog::acknowledgeGroup(const uint32_t &token) +{ + RsGxsGroupId grpId; + rsPhotoV2->acknowledgeGrp(token, grpId); + if(!grpId.empty()) + { + std::list grpIds; + grpIds.push_back(grpId); + + RsTokReqOptionsV2 opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + uint32_t reqToken; + mPhotoQueue->requestGroupInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); + } +} + +void PhotoDialog::acknowledgeMessage(const uint32_t &token) +{ + std::pair p; + rsPhotoV2->acknowledgeMsg(token, p); + + if(!p.first.empty()) + { + GxsMsgReq req; + std::vector v; + v.push_back(p.second); + req[p.first] = v; + RsTokReqOptionsV2 opts; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + uint32_t reqToken; + mPhotoQueue->requestMsgInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, req, 0); + } +} void PhotoDialog::loadPhotoList(const uint32_t &token) { std::cerr << "PhotoDialog::loadPhotoList()"; std::cerr << std::endl; - GxsMsgIdResult res; GxsMsgReq req; @@ -592,6 +625,9 @@ void PhotoDialog::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &r case RS_TOKREQ_ANSTYPE_DATA: loadAlbumData(req.mToken); break; + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgeGroup(req.mToken); + break; default: std::cerr << "PhotoDialog::loadRequest() ERROR: GROUP: INVALID ANS TYPE"; std::cerr << std::endl; @@ -604,6 +640,9 @@ void PhotoDialog::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &r case RS_TOKREQ_ANSTYPE_LIST: loadPhotoList(req.mToken); break; + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgeMessage(req.mToken); + break; //case RS_TOKREQ_ANSTYPE_DATA: // loadPhotoData(req.mToken); // break; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h index 0fc7575f8..ca808afaf 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h @@ -71,7 +71,8 @@ private: void loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req); - + void acknowledgeGroup(const uint32_t &token); + void acknowledgeMessage(const uint32_t &token); /* TODO: These functions must be filled in for proper filtering to work * and tied to the GUI input */ diff --git a/retroshare-gui/src/util/TokenQueueV2.cpp b/retroshare-gui/src/util/TokenQueueV2.cpp index 4dd444465..3450aa8ad 100644 --- a/retroshare-gui/src/util/TokenQueueV2.cpp +++ b/retroshare-gui/src/util/TokenQueueV2.cpp @@ -123,7 +123,7 @@ void TokenQueueV2::pollRequests() bool TokenQueueV2::checkForRequest(uint32_t token) { /* check token */ - return (COMPLETED_REQUEST == mService->requestStatus(token)); + return (RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE == mService->requestStatus(token)); } diff --git a/retroshare-gui/src/util/TokenQueueV2.h b/retroshare-gui/src/util/TokenQueueV2.h index aa85ac135..52a0e0e94 100644 --- a/retroshare-gui/src/util/TokenQueueV2.h +++ b/retroshare-gui/src/util/TokenQueueV2.h @@ -40,6 +40,7 @@ #define TOKENREQ_MSGINFO 2 #define TOKENREQ_MSGRELATEDINFO 3 + class TokenQueueV2; class TokenRequestV2 From c17460d1b12a5d8ff4773da38ee08447525ed3a6 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sun, 19 Aug 2012 22:15:37 +0000 Subject: [PATCH 027/222] Got message retrieval working for genexchange across gxs chain - fixed segv bugs for message retrieval and improved data service meta data retrieval - fixed compile for windows (exposed too many of rs internals in interface!) - fixed msg signing functionality and id creation with ssl - still need to complete photoservice gui and local meta change function git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5443 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsdataservice.cc | 181 ++++++++++++++---- libretroshare/src/gxs/rsdataservice.h | 22 ++- libretroshare/src/gxs/rsgds.h | 21 +- libretroshare/src/gxs/rsgenexchange.cc | 38 ++-- libretroshare/src/gxs/rsgxs.h | 4 +- libretroshare/src/gxs/rsgxsdata.cc | 5 +- libretroshare/src/gxs/rsgxsdata.h | 1 - libretroshare/src/gxs/rsgxsdataaccess.cc | 30 ++- libretroshare/src/gxs/rsgxsnetservice.cc | 6 +- libretroshare/src/gxs/rsgxsrequesttypes.h | 4 +- libretroshare/src/serialiser/rsgxsitems.h | 1 - .../src/serialiser/rsphotov2items.cc | 2 + .../src/services/p3photoserviceV2.cc | 5 +- .../src/gui/PhotoShare/PhotoAddDialog.cpp | 30 ++- .../src/gui/PhotoShare/PhotoDialog.cpp | 8 +- .../src/gui/PhotoShare/PhotoItem.cpp | 2 +- 16 files changed, 254 insertions(+), 106 deletions(-) diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index cae3d1367..fd9180444 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -44,7 +44,7 @@ #define KEY_TIME_STAMP std::string("timeStamp") #define KEY_NXS_FLAGS std::string("flags") #define KEY_NXS_META std::string("meta") -#define KEY_NXS_SERV_STRING std::string("serv_str"); +#define KEY_NXS_SERV_STRING std::string("serv_str") // grp table columns @@ -98,6 +98,7 @@ #define COL_GRP_NAME 11 #define COL_GRP_LAST_POST 12 #define COL_ORIG_GRP_ID 13 +#define COL_GRP_SERV_STRING 14 // msg col numbers #define COL_PUBLISH_SIGN 5 @@ -108,6 +109,7 @@ #define COL_PARENT_ID 10 #define COL_THREAD_ID 11 #define COL_MSG_NAME 12 +#define COL_MSG_SERV_STRING 13 // generic meta shared col numbers #define COL_GRP_ID 0 @@ -129,7 +131,7 @@ RsDataService::RsDataService(const std::string &serviceDir, const std::string &d msgMetaColumns.push_back(KEY_IDENTITY_SIGN); msgMetaColumns.push_back(KEY_NXS_IDENTITY); msgMetaColumns.push_back(KEY_PUBLISH_SIGN); msgMetaColumns.push_back(KEY_MSG_ID); msgMetaColumns.push_back(KEY_ORIG_MSG_ID); msgMetaColumns.push_back(KEY_MSG_STATUS); msgMetaColumns.push_back(KEY_CHILD_TS); msgMetaColumns.push_back(KEY_MSG_PARENT_ID); msgMetaColumns.push_back(KEY_MSG_THREAD_ID); - msgMetaColumns.push_back(KEY_MSG_NAME); + msgMetaColumns.push_back(KEY_MSG_NAME); msgMetaColumns.push_back(KEY_NXS_SERV_STRING); // for retrieving actual data msgColumns.push_back(KEY_GRP_ID); msgColumns.push_back(KEY_NXS_FILE); msgColumns.push_back(KEY_NXS_FILE_OFFSET); @@ -140,7 +142,7 @@ RsDataService::RsDataService(const std::string &serviceDir, const std::string &d grpMetaColumns.push_back(KEY_IDENTITY_SIGN); grpMetaColumns.push_back(KEY_NXS_IDENTITY); grpMetaColumns.push_back(KEY_ADMIN_SIGN); grpMetaColumns.push_back(KEY_KEY_SET); grpMetaColumns.push_back(KEY_GRP_SUBCR_FLAG); grpMetaColumns.push_back(KEY_GRP_POP); grpMetaColumns.push_back(KEY_MSG_COUNT); grpMetaColumns.push_back(KEY_GRP_STATUS); grpMetaColumns.push_back(KEY_GRP_NAME); - grpMetaColumns.push_back(KEY_GRP_LAST_POST); grpMetaColumns.push_back(KEY_ORIG_GRP_ID); + grpMetaColumns.push_back(KEY_GRP_LAST_POST); grpMetaColumns.push_back(KEY_ORIG_GRP_ID); grpMetaColumns.push_back(KEY_NXS_SERV_STRING); // for retrieving actual grp data grpColumns.push_back(KEY_GRP_ID); grpColumns.push_back(KEY_NXS_FILE); grpColumns.push_back(KEY_NXS_FILE_OFFSET); @@ -175,6 +177,7 @@ void RsDataService::initialise(){ KEY_MSG_THREAD_ID + " TEXT," + KEY_MSG_PARENT_ID + " TEXT,"+ KEY_MSG_NAME + " TEXT," + + KEY_NXS_SERV_STRING + " TEXT," + KEY_NXS_FILE_LEN + " INT);"); // create table for grp data @@ -195,6 +198,7 @@ void RsDataService::initialise(){ KEY_GRP_STATUS + " INT," + KEY_NXS_IDENTITY + " TEXT," + KEY_ORIG_GRP_ID + " TEXT," + + KEY_NXS_SERV_STRING + " TEXT," + KEY_NXS_FLAGS + " INT," + KEY_IDENTITY_SIGN + " BLOB);"); @@ -221,6 +225,7 @@ RsGxsGrpMetaData* RsDataService::getGrpMeta(RetroCursor &c) c.getString(COL_IDENTITY, grpMeta->mAuthorId); c.getString(COL_GRP_NAME, grpMeta->mGroupName); c.getString(COL_ORIG_GRP_ID, grpMeta->mOrigGrpId); + c.getString(COL_GRP_SERV_STRING, grpMeta->mServiceString); grpMeta->mPublishTs = c.getInt32(COL_TIME_STAMP); grpMeta->mGroupFlags = c.getInt32(COL_NXS_FLAGS); @@ -335,6 +340,7 @@ RsGxsMsgMetaData* RsDataService::getMsgMeta(RetroCursor &c) c.getString(COL_ORIG_MSG_ID, msgMeta->mOrigMsgId); c.getString(COL_IDENTITY, msgMeta->mAuthorId); c.getString(COL_MSG_NAME, msgMeta->mMsgName); + c.getString(COL_MSG_SERV_STRING, msgMeta->mServiceString); if(!msgMeta->mAuthorId.empty()){ offset = 0; @@ -447,6 +453,7 @@ int RsDataService::storeMessage(std::map &msg) cv.put(KEY_NXS_FILE_LEN, (int32_t)msgPtr->msg.TlvSize()); cv.put(KEY_MSG_ID, msgMetaPtr->mMsgId); cv.put(KEY_GRP_ID, msgMetaPtr->mGroupId); + cv.put(KEY_NXS_SERV_STRING, msgMetaPtr->mServiceString); char pubSignData[msgMetaPtr->pubSign.TlvSize()]; offset = 0; msgMetaPtr->pubSign.SetTlv(pubSignData, msgMetaPtr->pubSign.TlvSize(), &offset); @@ -522,6 +529,7 @@ int RsDataService::storeGroup(std::map &grp) cv.put(KEY_GRP_ID, grpPtr->grpId); cv.put(KEY_GRP_NAME, grpMetaPtr->mGroupName); cv.put(KEY_ORIG_GRP_ID, grpMetaPtr->mOrigGrpId); + cv.put(KEY_NXS_SERV_STRING, grpMetaPtr->mServiceString); cv.put(KEY_NXS_FLAGS, (int32_t)grpMetaPtr->mGroupFlags); cv.put(KEY_TIME_STAMP, (int32_t)grpMetaPtr->mPublishTs); @@ -580,7 +588,7 @@ int RsDataService::retrieveNxsGrps(std::map &grp, bool { std::vector grps; - retrieveGroups(c, grps, withMeta); + retrieveGroups(c, grps); std::vector::iterator vit = grps.begin(); for(; vit != grps.end(); vit++) @@ -618,10 +626,27 @@ int RsDataService::retrieveNxsGrps(std::map &grp, bool } } + if(withMeta) + { + std::map metaMap; + std::map::iterator mit = grp.begin(); + for(; mit != grp.end(); mit++) + metaMap.insert(std::make_pair(mit->first, (RsGxsGrpMetaData*)(NULL))); + + retrieveGxsGrpMetaData(metaMap); + + mit = grp.begin(); + for(; mit != grp.end(); mit++) + { + RsNxsGrp* grpPtr = grp[mit->first]; + grpPtr->metaData = metaMap[mit->first]; + } + } + return 1; } -void RsDataService::retrieveGroups(RetroCursor* c, std::vector& grps, bool withMeta){ +void RsDataService::retrieveGroups(RetroCursor* c, std::vector& grps){ if(c){ bool valid = c->moveToFirst(); @@ -632,12 +657,6 @@ void RsDataService::retrieveGroups(RetroCursor* c, std::vector& grps, // only add the latest grp info if(g) { - RsGxsGrpMetaData* meta; - - if(withMeta) - meta = getGrpMeta(*c); - - if(meta) g->metaData = meta; grps.push_back(g); } valid = c->moveToNext(); @@ -645,11 +664,13 @@ void RsDataService::retrieveGroups(RetroCursor* c, std::vector& grps, } } -int RsDataService::retrieveNxsMsgs(const GxsMsgReq &reqIds, GxsMsgResult &msg, bool cache) +int RsDataService::retrieveNxsMsgs(const GxsMsgReq &reqIds, GxsMsgResult &msg, bool cache, bool withMeta) { GxsMsgReq::const_iterator mit = reqIds.begin(); + GxsMsgReq metaReqIds;// collects metaReqIds if needed + for(; mit != reqIds.end(); mit++) { @@ -685,7 +706,75 @@ int RsDataService::retrieveNxsMsgs(const GxsMsgReq &reqIds, GxsMsgResult &msg, b msg[grpId] = msgSet; msgSet.clear(); + + if(withMeta) + { + std::vector msgIds; + + std::vector::iterator lit = msgSet.begin(), + lit_end = msgSet.end(); + + for(; lit != lit_end; lit++) + msgIds.push_back( (*lit)->msgId ); + + metaReqIds[grpId] = msgIds; + } } + + // tres expensive !? + if(withMeta) + { + + + GxsMsgMetaResult metaResult; + + // request with meta ids so there is no chance of + // a mem leak being left over + retrieveGxsMsgMetaData(metaReqIds, metaResult); + + GxsMsgResult::iterator mit2 = msg.begin(), mit2_end = msg.end(); + + for(; mit2 != mit2_end; mit2++) + { + const RsGxsGroupId& grpId = mit2->first; + std::vector& msgV = msg[grpId]; + std::vector::iterator lit = msgV.begin(), + lit_end = msgV.end(); + + // as retrieval only attempts to retrieve what was found this elimiates chance + // of a memory fault as all are assigned + for(; lit != lit_end; lit++) + { + std::vector& msgMetaV = metaResult[grpId]; + std::vector::iterator meta_lit = msgMetaV.begin(); + RsNxsMsg* msgPtr = *lit; + for(; meta_lit != msgMetaV.end(); ) + { + RsGxsMsgMetaData* meta = *meta_lit; + if(meta->mMsgId == msgPtr->msgId) + { + msgPtr->metaData = meta; + meta_lit = msgMetaV.erase(meta_lit); + }else{ + meta_lit++; + } + } + } + + std::vector& msgMetaV = metaResult[grpId]; + std::vector::iterator meta_lit; + + // clean up just in case, should not go in here + for(meta_lit = msgMetaV.begin(); meta_lit != + msgMetaV.end(); ) + { + RsGxsMsgMetaData* meta = *meta_lit; + delete meta; + } + } + } + + return 1; } void RsDataService::retrieveMessages(RetroCursor *c, std::vector &msgs) @@ -696,8 +785,6 @@ void RsDataService::retrieveMessages(RetroCursor *c, std::vector &ms if(m){ msgs.push_back(m);; - }else{ - delete m; } valid = c->moveToNext(); @@ -705,38 +792,60 @@ void RsDataService::retrieveMessages(RetroCursor *c, std::vector &ms return; } -int RsDataService::retrieveGxsMsgMetaData(const std::vector &grpIds, GxsMsgMetaResult &msgMeta) +int RsDataService::retrieveGxsMsgMetaData(GxsMsgReq& reqIds, GxsMsgMetaResult &msgMeta) { - std::vector::const_iterator vit = grpIds.begin(); + GxsMsgReq::iterator mit = reqIds.begin(); - for(; vit != grpIds.end(); vit++) + for(; mit != reqIds.end(); mit++) { - const std::string& grpId = *vit; - std::vector meta; + const std::string& grpId = mit->first; - RetroCursor* c = mDb->sqlQuery(MSG_TABLE_NAME, msgMetaColumns, "", KEY_GRP_ID+ "='" + grpId + "'"); + // if vector empty then request all messages + const std::vector& msgIdV = mit->second; + std::vector metaSet; - if(c) - { - bool valid = c->moveToFirst(); - while(valid){ - RsGxsMsgMetaData* m = getMsgMeta(*c); + if(msgIdV.empty()){ + RetroCursor* c = mDb->sqlQuery(MSG_TABLE_NAME, msgMetaColumns, KEY_GRP_ID+ "='" + grpId + "'", ""); - if(m){ - meta.push_back(m); - }else{ - delete m; - } - valid = c->moveToNext(); + retrieveMsgMeta(c, metaSet); + + }else{ + + // request each grp + std::vector::const_iterator sit = msgIdV.begin(); + + for(; sit!=msgIdV.end();sit++){ + const std::string& msgId = *sit; + RetroCursor* c = mDb->sqlQuery(MSG_TABLE_NAME, msgMetaColumns, KEY_GRP_ID+ "='" + grpId + + "' AND " + KEY_MSG_ID + "='" + msgId + "'", ""); + + retrieveMsgMeta(c, metaSet); } + } - msgMeta[grpId] = meta; + msgMeta[grpId] = metaSet; + } + + return 1; +} + +void RsDataService::retrieveMsgMeta(RetroCursor *c, std::vector &msgMeta) +{ + + if(c) + { + bool valid = c->moveToFirst(); + while(valid){ + RsGxsMsgMetaData* m = getMsgMeta(*c); + + if(m != NULL) + msgMeta.push_back(m); + + valid = c->moveToNext(); } delete c; - } - return 1; } int RsDataService::retrieveGxsGrpMetaData(std::map& grp) @@ -799,12 +908,12 @@ int RsDataService::removeGroups(const std::vector &grpIds) return 0; } -int RsDataService::updateGroupMetaData(GrpLocMetaData *meta) +int RsDataService::updateGroupMetaData(GrpLocMetaData &meta) { return 0; } -int RsDataService::updateMessageMetaData(MsgLocMetaData *metaData) +int RsDataService::updateMessageMetaData(MsgLocMetaData &metaData) { return 0; } diff --git a/libretroshare/src/gxs/rsdataservice.h b/libretroshare/src/gxs/rsdataservice.h index e7553683e..8af15dc4e 100644 --- a/libretroshare/src/gxs/rsdataservice.h +++ b/libretroshare/src/gxs/rsdataservice.h @@ -29,7 +29,6 @@ #include "gxs/rsgds.h" #include "util/retrodb.h" - class RsDataService : public RsGeneralDataService { public: @@ -44,7 +43,7 @@ public: * @param cache whether to store results of this retrieval in memory for faster later retrieval * @return error code */ - int retrieveNxsMsgs(const GxsMsgReq& reqIds, GxsMsgResult& msg, bool cache); + int retrieveNxsMsgs(const GxsMsgReq& reqIds, GxsMsgResult& msg, bool cache, bool withMeta = false); /*! * Retrieves groups, if empty, retrieves all grps, if map is not empty @@ -70,7 +69,7 @@ public: * @param cache whether to store retrieval in mem for faster later retrieval * @return error code */ - int retrieveGxsMsgMetaData(const std::vector& grpIds, GxsMsgMetaResult& msgMeta); + int retrieveGxsMsgMetaData(GxsMsgReq& reqIds, GxsMsgMetaResult& msgMeta); /*! * remove msgs in data store @@ -115,13 +114,13 @@ public: * @param metaData The meta data item to update * @return error code */ - int updateMessageMetaData(MsgLocMetaData* metaData); + int updateMessageMetaData(MsgLocMetaData& metaData); /*! * @param metaData The meta data item to update * @return error code */ - int updateGroupMetaData(GrpLocMetaData* meta); + int updateGroupMetaData(GrpLocMetaData& meta); /*! @@ -142,11 +141,18 @@ private: void retrieveMessages(RetroCursor* c, std::vector& msgs); /*! - * Retrieves all the msg results from a cursor + * Retrieves all the grp results from a cursor * @param c cursor to result set - * @param msgs messages retrieved from cursor are stored here + * @param grps groups retrieved from cursor are stored here */ - void retrieveGroups(RetroCursor* c, std::vector& grps, bool withMeta = false); + void retrieveGroups(RetroCursor* c, std::vector& grps); + + /*! + * Retrieves all the msg meta results from a cursor + * @param c cursor to result set + * @param metaSet message metadata retrieved from cursor are stored here + */ + void retrieveMsgMeta(RetroCursor* c, std::vector& msgMeta); /*! * extracts a msg meta item from a cursor at its diff --git a/libretroshare/src/gxs/rsgds.h b/libretroshare/src/gxs/rsgds.h index 1a34747c0..58212ee8d 100644 --- a/libretroshare/src/gxs/rsgds.h +++ b/libretroshare/src/gxs/rsgds.h @@ -36,6 +36,7 @@ #include "serialiser/rsnxsitems.h" #include "gxs/rsgxsdata.h" #include "rsgxs.h" +#include "util/retrodb.h" class RsGxsSearchModule { @@ -53,6 +54,9 @@ public: */ class MsgLocMetaData { +public: + RsGxsGrpMsgIdPair msgId; + ContentValue val; }; /*! @@ -61,11 +65,14 @@ class MsgLocMetaData { */ class GrpLocMetaData { +public: + RsGxsGroupId grpId; + ContentValue val; + }; -//typedef std::map > GxsMsgReq; // - -//typedef std::map > GxsMsgMetaResult; // +typedef std::map > NxsMsgDataResult; +typedef std::map > GxsMsgResult; // /*! * The main role of GDS is the preparation and handing out of messages requested from @@ -103,7 +110,7 @@ public: * @param cache whether to store results of this retrieval in memory for faster later retrieval * @return error code */ - virtual int retrieveNxsMsgs(const GxsMsgReq& reqIds, GxsMsgResult& msg, bool cache) = 0; + virtual int retrieveNxsMsgs(const GxsMsgReq& reqIds, GxsMsgResult& msg, bool cache, bool withMeta=false) = 0; /*! * Retrieves all groups stored @@ -130,7 +137,7 @@ public: * @param cache whether to store retrieval in mem for faster later retrieval * @return error code */ - virtual int retrieveGxsMsgMetaData(const std::vector& grpIds, GxsMsgMetaResult& msgMeta) = 0; + virtual int retrieveGxsMsgMetaData(GxsMsgReq& grpIds, GxsMsgMetaResult& msgMeta) = 0; /*! * remove msgs in data store listed in msgIds param @@ -174,12 +181,12 @@ public: /*! * @param metaData */ - virtual int updateMessageMetaData(MsgLocMetaData* metaData) = 0; + virtual int updateMessageMetaData(MsgLocMetaData& metaData) = 0; /*! * @param metaData */ - virtual int updateGroupMetaData(GrpLocMetaData* meta) = 0; + virtual int updateGroupMetaData(GrpLocMetaData& meta) = 0; /*! diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 6e3e6abe8..625e9843e 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include "rsgenexchange.h" #include "gxssecurity.h" @@ -177,6 +177,7 @@ bool RsGenExchange::createMessage(RsNxsMsg* msg) metaMap.insert(std::make_pair(id, (RsGxsGrpMetaData*)(NULL))); mDataStore->retrieveGxsGrpMetaData(metaMap); bool ok = true; + RSA* rsa_pub = NULL; if(!metaMap[id]) { @@ -198,8 +199,7 @@ bool RsGenExchange::createMessage(RsNxsMsg* msg) for(; mit != mit_end; mit++) { - pub_key_found = mit->second.keyFlags & (RSTLV_KEY_TYPE_FULL | RSTLV_KEY_DISTRIB_PUBLIC); - + pub_key_found = mit->second.keyFlags & (RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL); if(pub_key_found) break; } @@ -207,7 +207,7 @@ bool RsGenExchange::createMessage(RsNxsMsg* msg) if(pub_key_found) { pubKey = &(mit->second); - RSA* rsa_pub = GxsSecurity::extractPrivateKey(*pubKey); + rsa_pub = GxsSecurity::extractPrivateKey(*pubKey); EVP_PKEY *key_pub = EVP_PKEY_new(); EVP_PKEY_assign_RSA(key_pub, rsa_pub); @@ -229,8 +229,9 @@ bool RsGenExchange::createMessage(RsNxsMsg* msg) // clean up EVP_MD_CTX_destroy(mdctx); + //RSA_free(rsa_pub); EVP_PKEY_free(key_pub); - RSA_free(rsa_pub); + // no need to free rsa key as evp key is considered parent key by SSL } else { @@ -314,14 +315,15 @@ bool RsGenExchange::getGroupData(const uint32_t &token, std::vector::iterator lit = nxsGrps.begin(); - if(ok) + if(ok) { for(; lit != nxsGrps.end(); lit++) { RsTlvBinaryData& data = (*lit)->grp; RsItem* item = mSerialiser->deserialise(data.bin_data, &data.bin_len); - if(item != NULL){ + if(item != NULL) + { RsGxsGrpItem* gItem = dynamic_cast(item); gItem->meta = *((*lit)->metaData); grpItem.push_back(gItem); @@ -422,11 +424,14 @@ void RsGenExchange::publishMsgs() std::map::iterator mit = mMsgsToPublish.begin(); - for(; mit != mMsgsToPublish.end(); ) + for(; mit != mMsgsToPublish.end(); mit++) { RsNxsMsg* msg = new RsNxsMsg(mServType); RsGxsMsgItem* msgItem = mit->second; + + msg->grpId = msgItem->meta.mGroupId; + uint32_t size = mSerialiser->size(msgItem); char mData[size]; bool ok = mSerialiser->serialise(msgItem, mData, &size); @@ -434,13 +439,22 @@ void RsGenExchange::publishMsgs() if(ok) { msg->metaData = new RsGxsMsgMetaData(); + msg->msg.setBinData(mData, size); *(msg->metaData) = msgItem->meta; + size = msg->metaData->serial_size(); + char metaDataBuff[size]; + + msg->metaData->serialise(metaDataBuff, &size); + msg->meta.setBinData(metaDataBuff, size); + ok = createMessage(msg); if(ok) - ok = mDataAccess->addMsgData(msg); + ok = mDataAccess->addMsgData(msg); - mMsgPublished.insert(std::make_pair(mit->first, std::make_pair(msg->grpId, msg->msgId))); + // add to published to allow acknowledgement + mMsgPublished.insert(std::make_pair(mit->first, std::make_pair(msg->grpId, msg->msgId))); + mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE); } // if addition failed then delete nxs message @@ -488,7 +502,7 @@ void RsGenExchange::publishGrps() createGroup(grp); size = grp->metaData->serial_size(); char mData[size]; - + grp->metaData->mGroupId = grp->grpId; ok = grp->metaData->serialise(mData, size); grp->meta.setBinData(mData, size); @@ -520,6 +534,8 @@ void RsGenExchange::publishGrps() // are invalid mGrpsToPublish.clear(); } + + void RsGenExchange::processRecvdData() { } diff --git a/libretroshare/src/gxs/rsgxs.h b/libretroshare/src/gxs/rsgxs.h index c7d74eff1..14d3cce77 100644 --- a/libretroshare/src/gxs/rsgxs.h +++ b/libretroshare/src/gxs/rsgxs.h @@ -25,7 +25,7 @@ * */ -#include "serialiser/rsnxsitems.h" +#include "gxs/rsgxsdata.h" #include #include @@ -38,8 +38,6 @@ typedef std::map > GxsMsgReq; typedef std::map > GxsMsgIdResult; typedef std::map > GxsMsgMetaResult; -typedef std::map > NxsMsgDataResult; -typedef std::map > GxsMsgResult; // class RsGxsService { diff --git a/libretroshare/src/gxs/rsgxsdata.cc b/libretroshare/src/gxs/rsgxsdata.cc index 33cb7d2b4..dc5178605 100644 --- a/libretroshare/src/gxs/rsgxsdata.cc +++ b/libretroshare/src/gxs/rsgxsdata.cc @@ -26,6 +26,7 @@ #include "rsgxsdata.h" #include "serialiser/rsbaseserial.h" +#include "serialiser/rstlvbase.h" RsGxsGrpMetaData::RsGxsGrpMetaData() { @@ -283,6 +284,6 @@ void RsGxsMsgMetaData::operator =(const RsMsgMetaData& rMeta) this->mPublishTs = rMeta.mPublishTs ; this->mThreadId = rMeta.mThreadId; this->mServiceString = rMeta.mServiceString; -} - +} + diff --git a/libretroshare/src/gxs/rsgxsdata.h b/libretroshare/src/gxs/rsgxsdata.h index 084063b7f..a9d51be26 100644 --- a/libretroshare/src/gxs/rsgxsdata.h +++ b/libretroshare/src/gxs/rsgxsdata.h @@ -29,7 +29,6 @@ #include #include "serialiser/rsserial.h" -#include "serialiser/rstlvbase.h" #include "serialiser/rstlvtypes.h" #include "serialiser/rstlvkeys.h" #include "serialiser/rsgxsitems.h" diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index 1c73506b3..fd9b198c6 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -571,6 +571,15 @@ bool RsGxsDataAccess::getGroupData(GroupDataReq* req) { std::map grpData; + + std::list::iterator lit = req->mGroupIds.begin(), + lit_end = req->mGroupIds.end(); + + for(; lit != lit_end; lit++) + { + grpData[*lit] = NULL; + } + bool ok = mDataStore->retrieveNxsGrps(grpData, true, true); std::map::iterator mit = grpData.begin(); @@ -625,7 +634,7 @@ bool RsGxsDataAccess::getGroupList(GroupIdReq* req) bool RsGxsDataAccess::getMsgData(MsgDataReq* req) { GxsMsgResult result; - mDataStore->retrieveNxsMsgs(req->mMsgIds, result, true); + mDataStore->retrieveNxsMsgs(req->mMsgIds, result, true, true); req->mMsgData = result; return true; @@ -634,14 +643,8 @@ bool RsGxsDataAccess::getMsgData(MsgDataReq* req) bool RsGxsDataAccess::getMsgSummary(MsgMetaReq* req) { - GxsMsgMetaResult result; - std::vector groupIds; - GxsMsgReq::iterator mit = req->mMsgIds.begin(); - for(; mit != req->mMsgIds.end(); mit++) - groupIds.push_back(mit->first); - - mDataStore->retrieveGxsMsgMetaData(groupIds, result); - + GxsMsgMetaResult result; + mDataStore->retrieveGxsMsgMetaData(req->mMsgIds, result); req->mMsgMetaData = result; return true; @@ -649,18 +652,13 @@ bool RsGxsDataAccess::getMsgSummary(MsgMetaReq* req) bool RsGxsDataAccess::getMsgList(MsgIdReq* req) { - GxsMsgMetaResult result; - std::vector groupIds; - GxsMsgReq::iterator mit = req->mMsgIds.begin(); + GxsMsgMetaResult result; const RsTokReqOptionsV2& opts = req->Options; - for(; mit != req->mMsgIds.end(); mit++) - groupIds.push_back(mit->first); - { RsStackMutex stack(mDataMutex); - mDataStore->retrieveGxsMsgMetaData(groupIds, result); + mDataStore->retrieveGxsMsgMetaData(req->mMsgIds, result); } diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 80c6353aa..7c2a43a36 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -727,10 +727,10 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr) // get grp id for this transaction RsNxsSyncMsgItem* item = msgItemL.front(); const std::string& grpId = item->grpId; - std::vector grpIdV; - grpIdV.push_back(grpId); + GxsMsgReq reqIds; + reqIds[grpId] = std::vector(); GxsMsgMetaResult result; - mDataStore->retrieveGxsMsgMetaData(grpIdV, result); + mDataStore->retrieveGxsMsgMetaData(reqIds, result); std::vector &msgMetaV = result[grpId]; std::vector::const_iterator vit = msgMetaV.begin(); diff --git a/libretroshare/src/gxs/rsgxsrequesttypes.h b/libretroshare/src/gxs/rsgxsrequesttypes.h index 4ed5ede01..d5da446c5 100644 --- a/libretroshare/src/gxs/rsgxsrequesttypes.h +++ b/libretroshare/src/gxs/rsgxsrequesttypes.h @@ -26,6 +26,8 @@ * */ +#include "gxs/rsgds.h" + class GxsRequest { @@ -63,7 +65,7 @@ class GroupDataReq : public GxsRequest { public: - std::list mGroupIds; + std::list mGroupIds; std::list mGroupData; }; diff --git a/libretroshare/src/serialiser/rsgxsitems.h b/libretroshare/src/serialiser/rsgxsitems.h index a74c29c17..6bf98c703 100644 --- a/libretroshare/src/serialiser/rsgxsitems.h +++ b/libretroshare/src/serialiser/rsgxsitems.h @@ -28,7 +28,6 @@ #include "serialiser/rsserviceids.h" #include "serialiser/rsserial.h" -#include "serialiser/rstlvbase.h" #include "serialiser/rstlvtypes.h" #include "serialiser/rstlvkeys.h" diff --git a/libretroshare/src/serialiser/rsphotov2items.cc b/libretroshare/src/serialiser/rsphotov2items.cc index 0bfa559f8..ac153ecba 100644 --- a/libretroshare/src/serialiser/rsphotov2items.cc +++ b/libretroshare/src/serialiser/rsphotov2items.cc @@ -25,6 +25,8 @@ #include "rsphotov2items.h" +#include "serialiser/rstlvbase.h" +#include #define GXS_PHOTO_SERIAL_DEBUG diff --git a/libretroshare/src/services/p3photoserviceV2.cc b/libretroshare/src/services/p3photoserviceV2.cc index 5dc5e6af9..4fa74163d 100644 --- a/libretroshare/src/services/p3photoserviceV2.cc +++ b/libretroshare/src/services/p3photoserviceV2.cc @@ -89,6 +89,7 @@ bool p3PhotoServiceV2::getAlbum(const uint32_t& token, std::vector { RsGxsPhotoAlbumItem* item = dynamic_cast(*vit); RsPhotoAlbum album = item->album; + item->album.mMeta = item->meta; album.mMeta = item->album.mMeta; delete item; albums.push_back(album); @@ -183,14 +184,14 @@ bool p3PhotoServiceV2::acknowledgeMsg(const uint32_t& token, std::pair& msgId) { return RsGenExchange::acknowledgeTokenMsg(token, msgId); -} +} bool p3PhotoServiceV2::acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId) { return RsGenExchange::acknowledgeTokenGrp(token, grpId); -} +} diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp index b19645214..eaab5a088 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp @@ -304,11 +304,11 @@ void PhotoAddDialog::publishAlbum() album.mShareOptions.mCommentMode = 0; album.mShareOptions.mResizeMode = 0; - //album.mMeta.mGroupName = ui.lineEdit_Title->text().toStdString(); - //album.mCategory = "Unknown"; - //album.mCaption = ui.lineEdit_Caption->text().toStdString(); - //album.mWhere = ui.lineEdit_Where->text().toStdString(); - //album.mWhen = ui.lineEdit_When->text().toStdString(); + album.mMeta.mGroupName = ui.lineEdit_Title->text().toStdString(); + album.mCategory = "Unknown"; + album.mCaption = ui.lineEdit_Caption->text().toStdString(); + album.mWhere = ui.lineEdit_Where->text().toStdString(); + album.mWhen = ui.lineEdit_When->text().toStdString(); /* grab the image from the AlbumDrop */ if (ui.AlbumDrop->getPhotoCount() > 0) @@ -325,6 +325,7 @@ void PhotoAddDialog::publishAlbum() /* call publishPhotos directly */ publishPhotos(album.mMeta.mGroupId); + return; } @@ -469,9 +470,8 @@ void PhotoAddDialog::loadAlbum(const std::string &albumId) albumIds.push_back(albumId); // We need both Album and Photo Data. - + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, albumIds, 0); - } @@ -636,8 +636,20 @@ void PhotoAddDialog::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 } break; case TOKENREQ_MSGINFO: - loadPhotoData(req.mToken); - break; + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_DATA: + loadPhotoData(req.mToken); + break; + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgeMessage(req.mToken); + break; + default: + std::cerr << "PhotoAddDialog::loadRequest() ERROR: MESSAGE: INVALID ANS TYPE"; + std::cerr << std::endl; + + } + break; default: std::cerr << "PhotoAddDialog::loadRequest() ERROR: INVALID TYPE"; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index c11ce69c9..f54108550 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -487,8 +487,6 @@ bool PhotoDialog::loadAlbumData(const uint32_t &token) std::cerr << "PhotoDialog::loadAlbumData()"; std::cerr << std::endl; - clearAlbums(); - std::vector albums; rsPhotoV2->getAlbum(token, albums); @@ -643,9 +641,9 @@ void PhotoDialog::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &r case RS_TOKREQ_ANSTYPE_ACK: acknowledgeMessage(req.mToken); break; - //case RS_TOKREQ_ANSTYPE_DATA: - // loadPhotoData(req.mToken); - // break; + case RS_TOKREQ_ANSTYPE_DATA: + loadPhotoData(req.mToken); + break; default: std::cerr << "PhotoDialog::loadRequest() ERROR: MSG: INVALID ANS TYPE"; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp index b7fefd435..1553dad7b 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp @@ -141,7 +141,7 @@ void PhotoItem::updateText() if (mAlbumDetails.mSetFlags & RSPHOTO_FLAGS_ATTRIB_AUTHOR) { // This needs to be fixed!! TODO - fromLabel->setText(QString::fromStdString(mAlbumDetails.mMeta.mGroupId)); + fromLabel->setText(QString::fromStdString(mAlbumDetails.mPhotographer)); } if (mAlbumDetails.mSetFlags & RSPHOTO_FLAGS_ATTRIB_WHERE) From bb10b6b4007a3e91b30d16f27caaeb8c86b65e0c Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 20 Aug 2012 14:59:41 +0000 Subject: [PATCH 028/222] Added first version of RPC system for external control of retroshare-nogui. The protocol message format is as follows: [HEADER: 16 bytes: 4 x Network Order uint32_t][ VARIABLE LENGTH BODY ] [ MAGIC_CODE ] [ MSG_ID ] [ REQ_ID ] [ BODY_SIZE ] [ ........ BODY ......... ] MagicCode = 0x137f0001 ... this will be incremented for new versions of the protocol. MsgID = Corresponds to the format of the Body. ReqID = Generated by Requester, Returned in Response, make sure its unique. (undefined behaviour for duplicates) BodySize = Byte Length of Body. The Body will consist of a protobuf encoded message. For the moment, the RPC server just ECHOs the request back to the sender - for testing purposes. Usage: * Create SSH connection to retroshare-nogui. * Create Request Message(s), and send over SSH channel - You can send as meny requests as you want. * They will processed, and responses sent back (potentially in an arbitary order). Specific Changes here: * Modified rssshd to support arbitary recv/send applications. (interface is RpcComms). * Added rpc directory, with server, setup and echo service. * Modified Menu System to use the new interface to rssshd * Wrote new matching interface for Terminal Usage. - NOTE: Strange BUG in Terminal version.... causes stderr to disappear. TODO. * Added -C commandline option to switch on RPC system. This is the first version - so I expect there will be bugs. Please report for a prompt fix! git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5444 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/menu/menu.cc | 99 +++++++- retroshare-nogui/src/menu/menu.h | 56 ++++- retroshare-nogui/src/menu/menus.cc | 22 ++ retroshare-nogui/src/menu/menus.h | 22 ++ retroshare-nogui/src/menu/stdiocomms.cc | 171 +++++++++++++ retroshare-nogui/src/menu/stdiocomms.h | 57 +++++ retroshare-nogui/src/retroshare-nogui.pro | 28 ++- retroshare-nogui/src/retroshare.cc | 54 +++- retroshare-nogui/src/rpc/rpc.cc | 289 ++++++++++++++++++++++ retroshare-nogui/src/rpc/rpc.h | 71 ++++++ retroshare-nogui/src/rpc/rpcecho.cc | 40 +++ retroshare-nogui/src/rpc/rpcecho.h | 38 +++ retroshare-nogui/src/rpc/rpcserver.cc | 227 +++++++++++++++++ retroshare-nogui/src/rpc/rpcserver.h | 110 ++++++++ retroshare-nogui/src/rpc/rpcsetup.cc | 43 ++++ retroshare-nogui/src/rpc/rpcsetup.h | 34 +++ retroshare-nogui/src/rpcsystem.h | 61 +++++ retroshare-nogui/src/rstermserver.h | 13 - retroshare-nogui/src/ssh/rssshd.cc | 202 +++++++++++++-- retroshare-nogui/src/ssh/rssshd.h | 47 ++-- 20 files changed, 1612 insertions(+), 72 deletions(-) create mode 100644 retroshare-nogui/src/menu/stdiocomms.cc create mode 100644 retroshare-nogui/src/menu/stdiocomms.h create mode 100644 retroshare-nogui/src/rpc/rpc.cc create mode 100644 retroshare-nogui/src/rpc/rpc.h create mode 100644 retroshare-nogui/src/rpc/rpcecho.cc create mode 100644 retroshare-nogui/src/rpc/rpcecho.h create mode 100644 retroshare-nogui/src/rpc/rpcserver.cc create mode 100644 retroshare-nogui/src/rpc/rpcserver.h create mode 100644 retroshare-nogui/src/rpc/rpcsetup.cc create mode 100644 retroshare-nogui/src/rpc/rpcsetup.h create mode 100644 retroshare-nogui/src/rpcsystem.h delete mode 100644 retroshare-nogui/src/rstermserver.h diff --git a/retroshare-nogui/src/menu/menu.cc b/retroshare-nogui/src/menu/menu.cc index 504558837..bfe55e048 100644 --- a/retroshare-nogui/src/menu/menu.cc +++ b/retroshare-nogui/src/menu/menu.cc @@ -1,3 +1,25 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ #include "menu/menu.h" #include @@ -8,6 +30,8 @@ #include "util/rsstring.h" +#define MENU_DEBUG 1 + /********************************************************** * Menu Base Interface. */ @@ -18,29 +42,89 @@ void MenuInterface::reset() mBase->reset(); mCurrentMenu = mBase; mInputRequired = false; + mUpdateTime = 0; } -int MenuInterface::tick(bool haveInput, char keypress, std::string &output) + + +int MenuInterface::tick() { - if (!haveInput) +#ifdef MENU_DEBUG + std::cerr << "MenuInterface::tick()"; + std::cerr << std::endl; +#endif // MENU_DEBUG + + /* try to read a char */ + bool haveInput = false; + uint8_t keypress; + std::string output; + + int read = mComms->recv(&keypress, 1); +#ifdef MENU_DEBUG + std::cerr << "MenuInterface::tick() read " << read << " bytes"; + std::cerr << std::endl; +#endif // MENU_DEBUG + + if (read == 0) { + haveInput = false; /* make a harmless key */ keypress = ' '; } - - if ((mInputRequired) && (!haveInput)) + else if (read == 1) { - return 1; + haveInput = true; + } + else + { + /* error, NON BLOCKING is handled by recv returning 0 */ + mComms->error("Bad Input"); + return -1; + } + + + /**** Main logic bit ****/ + /**** slow down the updates / refresh ****/ + + time_t now = time(NULL); +#define UPDATE_TIME 5 + if (!haveInput) + { + // If Input is Required, + if (mInputRequired) + { + std::cerr << "MenuInterface::tick() No Input & Required-No Output"; + std::cerr << std::endl; + return 0; + } + + // Output will just almost the same, so occasionally. + if (now < mUpdateTime + UPDATE_TIME) + { + std::cerr << "MenuInterface::tick() No Input-Slow Update"; + std::cerr << std::endl; + return 0; + } + + std::cerr << "MenuInterface::tick() No Input - but doing update."; + std::cerr << std::endl; } uint32_t rt = process(keypress, mDrawFlags, output); mInputRequired = (rt == MENU_PROCESS_NEEDDATA); + mUpdateTime = now; if (rt == MENU_PROCESS_QUIT) { return -1; } - return 1; + + if (output.size() > 0) + { + mComms->send(output); + } + + return (haveInput); } @@ -168,6 +252,9 @@ uint32_t MenuInterface::process(char key, uint32_t drawFlags, std::string &buffe return MENU_PROCESS_NONE; } + + + uint32_t MenuInterface::drawHeader(uint32_t drawFlags, std::string &buffer) { buffer += "=======================================================\r\n"; diff --git a/retroshare-nogui/src/menu/menu.h b/retroshare-nogui/src/menu/menu.h index 4d10c762a..0feaec1b5 100644 --- a/retroshare-nogui/src/menu/menu.h +++ b/retroshare-nogui/src/menu/menu.h @@ -1,3 +1,28 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + + + #ifndef RSNOGUI_MENU_H #define RSNOGUI_MENU_H @@ -7,7 +32,7 @@ #include #include -#include "rstermserver.h" // generic processing command. +#include "rpcsystem.h" // generic processing command. #define MENU_PROCESS_MASK 0x0fff @@ -172,7 +197,7 @@ protected: }; - +#if 0 class MenuInterface: public RsTermServer { public: @@ -193,5 +218,32 @@ private: bool mInputRequired; }; +#endif + + +class MenuInterface: public RpcSystem +{ +public: + + MenuInterface(RpcComms *c, Menu *b, uint32_t drawFlags) + :mComms(c), mCurrentMenu(b), mBase(b), mDrawFlags(drawFlags), mInputRequired(false) { return; } + + uint32_t process(char key, uint32_t drawFlags, std::string &buffer); + uint32_t drawHeader(uint32_t drawFlags, std::string &buffer); + + // RsSystem Interface. + virtual void reset(); + virtual int tick(); + + +private: + RpcComms *mComms; + Menu *mCurrentMenu; + Menu *mBase; + uint32_t mDrawFlags; + bool mInputRequired; + time_t mUpdateTime; +}; + #endif diff --git a/retroshare-nogui/src/menu/menus.cc b/retroshare-nogui/src/menu/menus.cc index f783abc66..1613228be 100644 --- a/retroshare-nogui/src/menu/menus.cc +++ b/retroshare-nogui/src/menu/menus.cc @@ -1,3 +1,25 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ #include #include diff --git a/retroshare-nogui/src/menu/menus.h b/retroshare-nogui/src/menu/menus.h index 44806a013..b276eda57 100644 --- a/retroshare-nogui/src/menu/menus.h +++ b/retroshare-nogui/src/menu/menus.h @@ -1,3 +1,25 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ #include "menu/menu.h" #include diff --git a/retroshare-nogui/src/menu/stdiocomms.cc b/retroshare-nogui/src/menu/stdiocomms.cc new file mode 100644 index 000000000..08d1abb76 --- /dev/null +++ b/retroshare-nogui/src/menu/stdiocomms.cc @@ -0,0 +1,171 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "menu/stdiocomms.h" + +#include +#include +#include +#include +#include + + +StdioComms::StdioComms(int infd, int outfd) + :mIn(infd), mOut(outfd) +{ +#if 1 +// THIS Code is strange... +// It seems to mess up stderr. +// But if you redirect it -> is comes out fine. Very Weird. +// HELP!!! + + std::cerr << "StdioComms() STDERR msg 0"; + std::cerr << std::endl; + const int fcflags = fcntl(mIn,F_GETFL); + if (fcflags < 0) + { + std::cerr << "StdioComms() ERROR getting fcntl FLAGS"; + std::cerr << std::endl; + exit(1); + } + if (fcntl(mIn,F_SETFL,fcflags | O_NONBLOCK) <0) + { + std::cerr << "StdioComms() ERROR setting fcntl FLAGS"; + std::cerr << std::endl; + exit(1); + } + std::cerr << "StdioComms() STDERR msg 1"; + std::cerr << std::endl; +#endif +} + + +int StdioComms::isOkay() +{ + return 1; +} + + +int StdioComms::error(std::string msg) +{ + std::cerr << "StdioComms::error(" << msg << ")"; + std::cerr << std::endl; + return 1; +} + + + +int StdioComms::recv_ready() +{ + /* should be proper poll / select! - but we don't use this at the moment */ + return 1; +} + + +int StdioComms::recv(uint8_t *buffer, int bytes) +{ + int size = read(mIn, buffer, bytes); + std::cerr << "StdioComms::recv() returned: " << size; + std::cerr << std::endl; + + if (size == -1) + { + std::cerr << "StdioComms::recv() ERROR: " << errno; + std::cerr << std::endl; + if (errno == EAGAIN) + { + return 0; // OKAY; + } + } + + return size; +} + + +int StdioComms::recv(std::string &buffer, int bytes) +{ + uint8_t tmpbuffer[bytes]; + int size = read(mIn, tmpbuffer, bytes); + for(int i = 0; i < size; i++) + { + buffer += tmpbuffer[i]; + } + return size; +} + + // these make it easier... +int StdioComms::recv_blocking(uint8_t *buffer, int bytes) +{ + int totalread = 0; + while(totalread < bytes) + { + int size = read(mIn, &(buffer[totalread]), bytes - totalread); + if (size < 0) + { + if (totalread) + break; // partial read. + else + return size; // error. + } + totalread += size; + usleep(1000); // minisleep - so we don't 100% CPU. + std::cerr << "StdioComms::recv_blocking() read so far: " << size; + std::cerr << " / " << totalread; + std::cerr << std::endl; + } + return totalread; +} + + +int StdioComms::recv_blocking(std::string &buffer, int bytes) +{ + uint8_t tmpbuffer[bytes]; + int size = recv_blocking(tmpbuffer, bytes); + + if (size < 0) + return size; // error. + + for(int i = 0; i < size; i++) + buffer += tmpbuffer[i]; + + return size; +} + + +int StdioComms::send(uint8_t *buffer, int bytes) +{ + write(mOut, buffer, bytes); + return bytes; +} + + +int StdioComms::send(const std::string &output) +{ + if (output.size() > 0) + { + write(mOut, output.c_str(), output.size()); + } + return output.size(); +} + + diff --git a/retroshare-nogui/src/menu/stdiocomms.h b/retroshare-nogui/src/menu/stdiocomms.h new file mode 100644 index 000000000..bad510d6c --- /dev/null +++ b/retroshare-nogui/src/menu/stdiocomms.h @@ -0,0 +1,57 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + + + +#ifndef RS_STDIO_COMMS_H +#define RS_STDIO_COMMS_H + +#include "rpcsystem.h" + + + +class StdioComms: public RpcComms +{ +public: + StdioComms(int infd, int outfd); + + virtual int isOkay(); + virtual int error(std::string msg); + + virtual int recv_ready(); + virtual int recv(uint8_t *buffer, int bytes); + virtual int recv(std::string &buffer, int bytes); + + // these make it easier... + virtual int recv_blocking(uint8_t *buffer, int bytes); + virtual int recv_blocking(std::string &buffer, int bytes); + + virtual int send(uint8_t *buffer, int bytes); + virtual int send(const std::string &buffer); + +private: + int mIn, mOut; +}; + +#endif + diff --git a/retroshare-nogui/src/retroshare-nogui.pro b/retroshare-nogui/src/retroshare-nogui.pro index 0833bab5c..28621ebe0 100644 --- a/retroshare-nogui/src/retroshare-nogui.pro +++ b/retroshare-nogui/src/retroshare-nogui.pro @@ -142,18 +142,38 @@ sshserver { # INCLUDEPATH += ../../../lib/libssh-0.5.2/include/ -# LIBS += ../../../lib/libssh-0.5.2/build/src/libssh.a -# LIBS += ../../../lib/libssh-0.5.2/build/src/threads/libssh_threads.a -LIBS *= -lssh + LIBS += ../../../lib/libssh-0.5.2/build/src/libssh.a + LIBS += ../../../lib/libssh-0.5.2/build/src/threads/libssh_threads.a + #LIBS += -lssh + #LIBS += -lssh_threads HEADERS += ssh/rssshd.h SOURCES += ssh/rssshd.cc + # For the Menu System HEADERS += menu/menu.h \ menu/menus.h \ - rstermserver.h \ + menu/stdiocomms.h \ SOURCES += menu/menu.cc \ menu/menus.cc \ + menu/stdiocomms.cc \ + + # For the RPC System + HEADERS += rpc/rpc.h \ + rpc/rpcserver.h \ + rpc/rpcsetup.h \ + rpc/rpcecho.h \ + rpcsystem.h \ + + SOURCES += rpc/rpc.cc \ + rpc/rpcserver.cc \ + rpc/rpcsetup.cc \ + rpc/rpcecho.cc \ + + # Actual protocol files to go here... + #HEADERS += rpc/proto/rpcecho.h \ + + #SOURCES += rpc/proto/rpcecho.cc \ DEFINES *= RS_SSH_SERVER } diff --git a/retroshare-nogui/src/retroshare.cc b/retroshare-nogui/src/retroshare.cc index 917511cce..b741966c6 100644 --- a/retroshare-nogui/src/retroshare.cc +++ b/retroshare-nogui/src/retroshare.cc @@ -44,7 +44,9 @@ #include "ssh/rssshd.h" #include "menu/menus.h" -#include "menu/menutest.h" +#include "menu/stdiocomms.h" + +#include "rpc/rpcsetup.h" #endif @@ -94,6 +96,7 @@ int main(int argc, char **argv) // set user/password for SSH. -L "user:pwdhash" // accept RSA Key Auth. -K "RsaPubKeyFile" // Terminal mode. -T + bool enableRpc = false; bool enableSsh = false; bool enableSshHtml = false; bool enableSshPwd = false; @@ -105,10 +108,14 @@ int main(int argc, char **argv) std::string sshRsaFile = ""; std::string sshPortStr = "7022"; - while((c = getopt(argc, argv,"hTL:P:K:GS::")) != -1) + while((c = getopt(argc, argv,"ChTL:P:K:GS::")) != -1) { switch(c) { + case 'C': + enableRpc = true; + strictCheck = false; + break; case 'S': enableSsh = true; if (optarg) @@ -153,6 +160,7 @@ int main(int argc, char **argv) std::cerr << "\t-S [port] Enable SSH Server, optionally specify port" << std::endl; std::cerr << "\t-L Specify SSH login user (default:user)" << std::endl; std::cerr << "\t-P Enable SSH login via Password" << std::endl; + std::cerr << "\t-C Enable RPC Protocol (requires -S too)" << std::endl; //std::cerr << "\t-K [rsapubkeyfile] Enable SSH login via RSA key" << std::endl; //std::cerr << "\t NB: Two Factor Auth, specify both -P & -K" << std::endl; std::cerr << std::endl; @@ -247,6 +255,13 @@ int main(int argc, char **argv) exit(1); } + if (enableRpc && (!enableSsh)) + { + std::cerr << "ERROR: RPC Mode (-C) requires SSH Server (-S) enabled"; + std::cerr << std::endl; + exit(1); + } + /* parse -S, -L & -K parameters */ if (enableSshRsa) @@ -364,26 +379,39 @@ int main(int argc, char **argv) #ifdef RS_SSH_SERVER uint32_t baseDrawFlags = 0; if (enableSshHtml) + { baseDrawFlags = MENU_DRAW_FLAGS_HTML; + } if (enableSsh) { - /* create menu system for SSH */ - Menu *baseMenu = CreateMenuStructure(notify); - MenuInterface *menuInterface = new MenuInterface(baseMenu, baseDrawFlags | MENU_DRAW_FLAGS_ECHO); - ssh->setTermServer(menuInterface); + if (enableRpc) + { + /* Build RPC Server */ + RpcMediator *med = CreateRpcSystem(ssh); + ssh->setRpcSystem(med); + ssh->setSleepPeriods(0.01, 0.1); + } + else + { + /* create menu system for SSH */ + Menu *baseMenu = CreateMenuStructure(notify); + MenuInterface *menuInterface = new MenuInterface(ssh, baseMenu, baseDrawFlags | MENU_DRAW_FLAGS_ECHO); + ssh->setRpcSystem(menuInterface); + ssh->setSleepPeriods(0.2, 1); + } ssh->start(); } - //MenuTest *menuTerminal = NULL; - RsConsole *menuTerminal = NULL; + MenuInterface *terminalMenu = NULL; if (enableTerminal) { /* Terminal Version */ + RpcComms *stdioComms = new StdioComms(fileno(stdin), fileno(stdout)); Menu *baseMenu = CreateMenuStructure(notify); - MenuInterface *menuInterface = new MenuInterface(baseMenu, baseDrawFlags | MENU_DRAW_FLAGS_NOQUIT); - menuTerminal = new RsConsole(menuInterface, fileno(stdin), fileno(stdout)); + terminalMenu = new MenuInterface(stdioComms, baseMenu, baseDrawFlags | MENU_DRAW_FLAGS_NOQUIT); + //menuTerminal = new RsConsole(menuInterface, fileno(stdin), fileno(stdout)); } @@ -400,9 +428,9 @@ int main(int argc, char **argv) int rt = 0; #ifdef RS_SSH_SERVER - if (menuTerminal) + if (terminalMenu) { - rt = menuTerminal->tick(); + rt = terminalMenu->tick(); } #endif @@ -417,6 +445,8 @@ int main(int argc, char **argv) #endif } + usleep(1000); + } return 1; } diff --git a/retroshare-nogui/src/rpc/rpc.cc b/retroshare-nogui/src/rpc/rpc.cc new file mode 100644 index 000000000..368baf22e --- /dev/null +++ b/retroshare-nogui/src/rpc/rpc.cc @@ -0,0 +1,289 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "rpc/rpc.h" +#include "rpc/rpcserver.h" + +// This one is inside libretroshare (BAD)!!! +#include "serialiser/rsbaseserial.h" + +#include + +const uint32_t kMsgHeaderSize = 16; +const uint32_t kMsgMagicCode = 0x137f0001; // Arbitary + 0x0001 + +RpcMediator::RpcMediator(RpcComms *c) + :mComms(c), mServer(NULL) +{ + return; +} + +void RpcMediator::reset() +{ + mServer->reset(); +} + + +int RpcMediator::tick() +{ + bool worked = false; + if (recv()) + { + worked = true; + } + + if (mServer->checkPending()) + { + worked = true; + } + + if (worked) + return 1; + else + return 0; + return 0; +} + + +int RpcMediator::recv() +{ + int recvd = 0; + while(recv_msg()) + { + recvd = 1; + } + return recvd; +} + + +int RpcMediator::recv_msg() +{ + /* nothing in here needs a Mutex... */ + + if (!mComms->recv_ready()) + { + return 0; + } + + std::cerr << "RpcMediator::recv_msg() Data Ready"; + std::cerr << std::endl; + + /* read in data */ + uint8_t buffer[kMsgHeaderSize]; + uint32_t bufsize = kMsgHeaderSize; + uint32_t msg_id; + uint32_t req_id; + uint32_t msg_size; + std::string msg_body; + + std::cerr << "RpcMediator::recv_msg() get Header: " << bufsize; + std::cerr << " bytes" << std::endl; + + int read = mComms->recv_blocking(buffer, bufsize); + if (read != bufsize) + { + /* error */ + std::cerr << "RpcMediator::recv_msg() Error Reading Header: " << bufsize; + std::cerr << " bytes" << std::endl; + + mComms->error("Failed to Recv Header"); + return 0; + } + + if (!MsgPacker::deserialiseHeader(msg_id, req_id, msg_size, buffer, bufsize)) + { + /* error */ + std::cerr << "RpcMediator::recv_msg() Error Deserialising Header"; + std::cerr << std::endl; + + mComms->error("Failed to Deserialise Header"); + return 0; + } + + std::cerr << "RpcMediator::recv_msg() MsgId: " << msg_id; + std::cerr << " ReqId: " << req_id; + std::cerr << std::endl; + + std::cerr << "RpcMediator::recv_msg() get Body: " << msg_size; + std::cerr << " bytes" << std::endl; + + /* grab real size */ + read = mComms->recv_blocking(msg_body, msg_size); + if (read != msg_size) + { + /* error */ + std::cerr << "RpcMediator::recv_msg() Error Reading Body: " << bufsize; + std::cerr << " bytes" << std::endl; + + mComms->error("Failed to Recv MsgBody"); + return 0; + } + mServer->processMsg(msg_id, req_id, msg_body); + + return 1; +} + + +int RpcMediator::send(uint32_t msg_id, uint32_t req_id, const std::string &msg) + +{ + std::cerr << "RpcMediator::send(" << msg_id << "," << req_id << ", len("; + std::cerr << msg.size() << "))"; + std::cerr << std::endl; + + uint8_t buffer[kMsgHeaderSize]; + uint32_t bufsize = kMsgHeaderSize; + uint32_t msg_size = msg.size(); + + bool okay = MsgPacker::serialiseHeader(msg_id, req_id, msg_size, buffer, bufsize); + if (!okay) + { + std::cerr << "RpcMediator::send() SerialiseHeader Failed"; + std::cerr << std::endl; + /* error */ + return 0; + } + + if (!mComms->send(buffer, bufsize)) + { + std::cerr << "RpcMediator::send() Send Header Failed"; + std::cerr << std::endl; + /* error */ + mComms->error("Failed to Send Header"); + return 0; + } + + /* now send the body */ + if (!mComms->send(msg)) + { + std::cerr << "RpcMediator::send() Send Body Failed"; + std::cerr << std::endl; + /* error */ + mComms->error("Failed to Send Msg"); + return 0; + } + return 1; +} + + + + +/* Msg Packing */ +int MsgPacker::headersize() +{ + return kMsgHeaderSize; +} + +#if 0 +int MsgPacker::msgsize(Message *msg) +{ + /* */ + return 0; +} + +int MsgPacker::pktsize(Message *msg) +{ + /* */ + return headersize() + msgsize(); +} +#endif + +bool MsgPacker::serialiseHeader(uint32_t msg_id, uint32_t req_id, uint32_t msg_size, uint8_t *buffer, uint32_t bufsize) +{ + /* check size */ + if (bufsize < kMsgHeaderSize) + { + return false; + } + + /* pack the data (using libretroshare serialiser for now */ + void *data = buffer; + uint32_t offset = 0; + uint32_t size = bufsize; + + bool ok = true; + + /* 4 x uint32_t for header */ + ok &= setRawUInt32(data, size, &offset, kMsgMagicCode); + ok &= setRawUInt32(data, size, &offset, msg_id); + ok &= setRawUInt32(data, size, &offset, req_id); + ok &= setRawUInt32(data, size, &offset, msg_size); + + return ok; +} + + +bool MsgPacker::deserialiseHeader(uint32_t &msg_id, uint32_t &req_id, uint32_t &msg_size, uint8_t *buffer, uint32_t bufsize) +{ + /* check size */ + if (bufsize < kMsgHeaderSize) + { + return false; + } + + /* pack the data (using libretroshare serialiser for now */ + void *data = buffer; + uint32_t offset = 0; + uint32_t size = bufsize; + uint32_t magic_code; + + bool ok = true; + + /* 4 x uint32_t for header */ + ok &= getRawUInt32(data, size, &offset, &magic_code); + if (!ok) + { + std::cerr << "Failed to deserialise uint32_t(0)"; + std::cerr << std::endl; + } + ok &= getRawUInt32(data, size, &offset, &msg_id); + if (!ok) + { + std::cerr << "Failed to deserialise uint32_t(1)"; + std::cerr << std::endl; + } + ok &= getRawUInt32(data, size, &offset, &req_id); + if (!ok) + { + std::cerr << "Failed to deserialise uint32_t(2)"; + std::cerr << std::endl; + } + ok &= getRawUInt32(data, size, &offset, &msg_size); + if (!ok) + { + std::cerr << "Failed to deserialise uint32_t(3)"; + std::cerr << std::endl; + } + + ok &= (magic_code == kMsgMagicCode); + if (!ok) + { + std::cerr << "Failed to Match MagicCode"; + std::cerr << std::endl; + } + + return ok; +} + + + diff --git a/retroshare-nogui/src/rpc/rpc.h b/retroshare-nogui/src/rpc/rpc.h new file mode 100644 index 000000000..ff1817cd1 --- /dev/null +++ b/retroshare-nogui/src/rpc/rpc.h @@ -0,0 +1,71 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#ifndef RPC_MEDIATOR_H +#define RPC_MEDIATOR_H + +/* + * Interface between RpcServer and RpcComms. + */ + +#include +#include + +#include "rpcsystem.h" + +class RpcServer; + +class RpcMediator: public RpcSystem +{ +public: + + RpcMediator(RpcComms *c); + void setRpcServer(RpcServer *s) { mServer = s; } /* Must only be called during setup */ + + // Overloaded from RpcSystem. +virtual void reset(); +virtual int tick(); + + int recv(); + int recv_msg(); + int send(uint32_t msg_id, uint32_t req_id, const std::string &msg); + +private: + RpcComms *mComms; + RpcServer *mServer; + +}; + + +/* Msg Packing */ +class MsgPacker +{ +public: + static int headersize(); + static bool serialiseHeader(uint32_t msg_id, uint32_t req_id, uint32_t msg_size, uint8_t *buffer, uint32_t bufsize); + static bool deserialiseHeader(uint32_t &msg_id, uint32_t &req_id, uint32_t &msg_size, uint8_t *buffer, uint32_t bufsize); +}; + + + +#endif /* RPC_MEDIATOR_H */ diff --git a/retroshare-nogui/src/rpc/rpcecho.cc b/retroshare-nogui/src/rpc/rpcecho.cc new file mode 100644 index 000000000..ff01ccaf8 --- /dev/null +++ b/retroshare-nogui/src/rpc/rpcecho.cc @@ -0,0 +1,40 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "rpc/rpcecho.h" + +RpcEcho::RpcEcho(uint32_t serviceId) +:RpcQueueService(serviceId) +{ + return; +} + +int RpcEcho::processMsg(uint32_t msg_id, uint32_t req_id, const std::string &msg) +{ + /* */ + queueResponse(msg_id, req_id, msg); + return 1; +} + + + diff --git a/retroshare-nogui/src/rpc/rpcecho.h b/retroshare-nogui/src/rpc/rpcecho.h new file mode 100644 index 000000000..a72871382 --- /dev/null +++ b/retroshare-nogui/src/rpc/rpcecho.h @@ -0,0 +1,38 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + + +#ifndef RS_RPC_ECHO_H +#define RS_RPC_ECHO_H + +#include "rpc/rpcserver.h" + +class RpcEcho: public RpcQueueService +{ +public: + RpcEcho(uint32_t serviceId); + virtual int processMsg(uint32_t msgId, uint32_t req_id, const std::string &msg); +}; + + +#endif /* RS_RPC_ECHO_H */ diff --git a/retroshare-nogui/src/rpc/rpcserver.cc b/retroshare-nogui/src/rpc/rpcserver.cc new file mode 100644 index 000000000..3392eaffa --- /dev/null +++ b/retroshare-nogui/src/rpc/rpcserver.cc @@ -0,0 +1,227 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "rpc/rpcserver.h" + +#include "rpc/rpc.h" + +#include + +RpcServer::RpcServer(RpcMediator *med) + :mMediator(med), mRpcMtx("RpcMtx") +{ + +} + +void RpcServer::reset() +{ + std::cerr << "RpcServer::reset()" << std::endl; + { + RsStackMutex stack(mRpcMtx); /********** LOCKED MUTEX ***************/ + + std::list::iterator it; + for(it = mAllServices.begin(); it != mAllServices.end(); it++) + { + /* in mutex, but should be okay */ + (*it)->reset(); + } + + // clear existing queue. + mRpcQueue.clear(); + } + + return; +} + + +int RpcServer::addService(RpcService *service) +{ + RsStackMutex stack(mRpcMtx); /********** LOCKED MUTEX ***************/ + + mAllServices.push_back(service); + + return 1; +} + + +int RpcServer::processMsg(uint32_t msg_id, uint32_t req_id, const std::string &msg) +{ + std::cerr << "RpcServer::processMsg(" << msg_id << "," << req_id; + std::cerr << ", len(" << msg.size() << "))" << std::endl; + { + RsStackMutex stack(mRpcMtx); /********** LOCKED MUTEX ***************/ + + std::list::iterator it; + for(it = mAllServices.begin(); it != mAllServices.end(); it++) + { + int rt = (*it)->processMsg(msg_id, req_id, msg); + if (!rt) + continue; + + /* remember request */ + queueRequest_locked(msg_id, req_id, (*it)); + return 1; + } + } + + std::cerr << "RpcServer::processMsg() No service to accepted it - discard"; + std::cerr << std::endl; + return 0; +} + +int RpcServer::queueRequest_locked(uint32_t /* msgId */, uint32_t req_id, RpcService *service) +{ + std::cerr << "RpcServer::queueRequest_locked() req_id: " << req_id; + std::cerr << std::endl; + + RpcQueuedObj obj; + obj.mReqId = req_id; + obj.mService = service; + + mRpcQueue.push_back(obj); + + return 1; +} + + +bool RpcServer::checkPending() +{ + std::list msgsToSend; + bool someRemaining = false; + bool someToSend = false; + + { + RsStackMutex stack(mRpcMtx); /********** LOCKED MUTEX ***************/ + + std::list::iterator it; + for(it = mRpcQueue.begin(); it != mRpcQueue.end();) + { + uint32_t out_msg_id = 0; + uint32_t out_req_id = it->mReqId; + std::string out_msg; + if (it->mService->getResponse(out_msg_id, out_req_id, out_msg)) + { + std::cerr << "RpcServer::checkPending() Response: ("; + std::cerr << out_msg_id << "," << out_req_id; + std::cerr << ", len(" << out_msg.size() << "))"; + std::cerr << std::endl; + + /* store and send after queue is processed */ + RpcQueuedMsg msg; + msg.mMsgId = out_msg_id; + msg.mReqId = out_req_id; + msg.mMsg = out_msg; + + msgsToSend.push_back(msg); + + it = mRpcQueue.erase(it); + someToSend = true; + } + else + { + it++; + someRemaining = true; + } + } + } + + if (someToSend) + { + sendQueuedMsgs(msgsToSend); + } + + return someRemaining; +} + +bool RpcServer::sendQueuedMsgs(std::list &msgs) +{ + /* No need for lock, as mOut is the only accessed item - and that has own protection */ + + std::cerr << "RpcServer::sendQueuedMsg() " << msgs.size() << " to send"; + std::cerr << std::endl; + + std::list::iterator it; + for (it = msgs.begin(); it != msgs.end(); it++) + { + mMediator->send(it->mMsgId, it->mReqId, it->mMsg); + } + return true; +} + + + + + + + +RpcQueueService::RpcQueueService(uint32_t serviceId) +:RpcService(serviceId), mQueueMtx("RpcQueueService") +{ + return; +} + + +void RpcQueueService::reset() +{ + RsStackMutex stack(mQueueMtx); /********** LOCKED MUTEX ***************/ + + // clear existing queue. + mResponses.clear(); + return; +} + +int RpcQueueService::getResponse(uint32_t &msg_id, uint32_t &req_id, std::string &msg) +{ + RsStackMutex stack(mQueueMtx); /********** LOCKED MUTEX ***************/ + + std::map::iterator it; + + it = mResponses.find(req_id); + if (it == mResponses.end()) + { + return 0; + } + + msg_id = it->second.mMsgId; + msg = it->second.mMsg; + + mResponses.erase(it); + + return 1; +} + +int RpcQueueService::queueResponse(uint32_t msg_id, uint32_t req_id, const std::string &msg) +{ + RsStackMutex stack(mQueueMtx); /********** LOCKED MUTEX ***************/ + + RpcQueuedMsg qmsg; + qmsg.mMsgId = msg_id; + qmsg.mReqId = req_id; + qmsg.mMsg = msg; + + mResponses[req_id] = qmsg; + + return 1; +} + + diff --git a/retroshare-nogui/src/rpc/rpcserver.h b/retroshare-nogui/src/rpc/rpcserver.h new file mode 100644 index 000000000..061ad7842 --- /dev/null +++ b/retroshare-nogui/src/rpc/rpcserver.h @@ -0,0 +1,110 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + + +#ifndef RS_RPC_SERVER_H +#define RS_RPC_SERVER_H + +#include +#include +#include +#include + +#include "util/rsthreads.h" + +/*** This can be overloaded for plugins + * Also allows a natural seperation of the full interface into sections. + */ + +class RpcQueuedMsg +{ +public: + uint32_t mMsgId; + uint32_t mReqId; + std::string mMsg; +}; + + +class RpcService +{ +public: + RpcService(uint32_t /* serviceId */ ) { return; } + virtual void reset() { return; } + virtual int msgsAccepted(std::list & /* msgIds */) { return 0; } /* not used at the moment */ + virtual int processMsg(uint32_t msgId, uint32_t req_id, const std::string &msg) = 0; /* returns 0 - not handled, > 0, accepted */ + virtual int getResponse(uint32_t &msgId, uint32_t &req_id, std::string &msg) = 0; /* 0 - not ready, > 0 heres the response */ +}; + + +/* Implements a Queue for quick implementation of Instant Response Services */ +class RpcQueueService: public RpcService +{ +public: + RpcQueueService(uint32_t serviceId); +virtual void reset(); +virtual int getResponse(uint32_t &msgId, uint32_t &req_id, std::string &msg); + +protected: + int queueResponse(uint32_t msgId, uint32_t req_id, const std::string &msg); +private: + RsMutex mQueueMtx; + std::map mResponses; +}; + + +/* For Tracking responses */ +class RpcQueuedObj +{ +public: + uint32_t mReqId; + RpcService *mService; +}; + + +class RpcMediator; + +class RpcServer +{ + +public: + RpcServer(RpcMediator *med); + int addService(RpcService *service); + int processMsg(uint32_t msgId, uint32_t req_id, const std::string &msg); + bool checkPending(); + + void reset(); + +private: + bool sendQueuedMsgs(std::list &msgs); + int queueRequest_locked(uint32_t msgId, uint32_t req_id, RpcService *service); + + RpcMediator *mMediator; + + RsMutex mRpcMtx; + + std::list mRpcQueue; + std::list mAllServices; +}; + + +#endif /* RS_RPC_SERVER_H */ diff --git a/retroshare-nogui/src/rpc/rpcsetup.cc b/retroshare-nogui/src/rpc/rpcsetup.cc new file mode 100644 index 000000000..38b8a9c5b --- /dev/null +++ b/retroshare-nogui/src/rpc/rpcsetup.cc @@ -0,0 +1,43 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "rpc/rpcsetup.h" +#include "rpc/rpcserver.h" + +#include "rpc/rpcecho.h" + + +RpcMediator *CreateRpcSystem(RpcComms *comms) +{ + RpcMediator *med = new RpcMediator(comms); + RpcServer *server = new RpcServer(med); + + /* add services */ + RpcEcho *echo = new RpcEcho(1); + server->addService(echo); + + med->setRpcServer(server); + + return med; +} + diff --git a/retroshare-nogui/src/rpc/rpcsetup.h b/retroshare-nogui/src/rpc/rpcsetup.h new file mode 100644 index 000000000..4d847f089 --- /dev/null +++ b/retroshare-nogui/src/rpc/rpcsetup.h @@ -0,0 +1,34 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + + +#ifndef RPC_SETUP_H +#define RPC_SETUP_H + + +#include "rpc/rpc.h" + +RpcMediator *CreateRpcSystem(RpcComms *comms); + +#endif + diff --git a/retroshare-nogui/src/rpcsystem.h b/retroshare-nogui/src/rpcsystem.h new file mode 100644 index 000000000..db81d5702 --- /dev/null +++ b/retroshare-nogui/src/rpcsystem.h @@ -0,0 +1,61 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + + +#ifndef RS_RPC_SYSTEM_H +#define RS_RPC_SYSTEM_H + +#include +#include + +class RpcComms +{ +public: + virtual int isOkay() = 0; + virtual int error(std::string msg) = 0; + + virtual int recv_ready() = 0; + virtual int recv(uint8_t *buffer, int bytes) = 0; + virtual int recv(std::string &buffer, int bytes) = 0; + + // these make it easier... + virtual int recv_blocking(uint8_t *buffer, int bytes) = 0; + virtual int recv_blocking(std::string &buffer, int bytes) = 0; + + virtual int send(uint8_t *buffer, int bytes) = 0; + virtual int send(const std::string &buffer) = 0; + + virtual int setSleepPeriods(float /* busy */, float /* idle */) { return 0; } +}; + + +class RpcSystem +{ +public: + /* this must be regularly ticked to update the display */ + virtual void reset() = 0; + virtual int tick() = 0; +}; + + +#endif // RS_RPC_SERVER_H diff --git a/retroshare-nogui/src/rstermserver.h b/retroshare-nogui/src/rstermserver.h deleted file mode 100644 index 2658e8c93..000000000 --- a/retroshare-nogui/src/rstermserver.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef RS_TERM_SERVER_H -#define RS_TERM_SERVER_H - -class RsTermServer -{ -public: - /* this must be regularly ticked to update the display */ - virtual void reset() = 0; - virtual int tick(bool haveInput, char keypress, std::string &output) = 0; -}; - - -#endif // RS_TERM_SERVER_H diff --git a/retroshare-nogui/src/ssh/rssshd.cc b/retroshare-nogui/src/ssh/rssshd.cc index b75c32e89..195d85af0 100644 --- a/retroshare-nogui/src/ssh/rssshd.cc +++ b/retroshare-nogui/src/ssh/rssshd.cc @@ -26,6 +26,8 @@ clients must be made or how a client should react. #define RSSSHD_STATE_NULL 0 #define RSSSHD_STATE_INIT_OK 1 +#define RSSSHD_STATE_CONNECTED 2 +#define RSSSHD_STATE_ERROR 3 RsSshd *rsSshd = NULL; // External Reference Variable. @@ -54,8 +56,9 @@ RsSshd::RsSshd(std::string portStr) mState = RSSSHD_STATE_NULL; mBindState = 0; - mTermServer = NULL; + mRpcSystem = NULL; + setSleepPeriods(0.01, 0.1); return; } @@ -104,6 +107,7 @@ void RsSshd::run() std::cerr << "RsSshd::run() setup mSession => interactive"; std::cerr << std::endl; + mState = RSSSHD_STATE_CONNECTED; interactive(); } else @@ -195,7 +199,7 @@ int RsSshd::interactive() std::cerr << "RsSshd::interactive()"; std::cerr << std::endl; - doTermServer(); + doRpcSystem(); //doEcho(); return 1; } @@ -318,7 +322,36 @@ int RsSshd::setupShell() return 1; } +// CLEANUP +int RsSshd::cleanupSession() +{ + std::cerr << "RsSshd::cleanupSession()"; + std::cerr << std::endl; + ssh_disconnect(mSession); + ssh_free(mSession); + return 1; +} + + +int RsSshd::cleanupAll() +{ + std::cerr << "RsSshd::cleanupAll()"; + std::cerr << std::endl; + + cleanupSession(); + if (mBindState) + { + ssh_bind_free(mBind); + mBindState = 0; + } + ssh_finalize(); + return 1; +} + + + +// Various Operating Modes. int RsSshd::doEcho() { std::cerr << "RsSshd::doEcho()"; @@ -354,13 +387,14 @@ int RsSshd::doEcho() } -int RsSshd::setTermServer(RsTermServer *s) +int RsSshd::setRpcSystem(RpcSystem *s) { - mTermServer = s; + mRpcSystem = s; return 1; } +#if 0 int RsSshd::doTermServer() { @@ -422,33 +456,161 @@ int RsSshd::doTermServer() return 1; } +#endif -int RsSshd::cleanupSession() + +int RsSshd::doRpcSystem() { - std::cerr << "RsSshd::cleanupSession()"; + std::cerr << "RsSshd::doRpcSystem()"; std::cerr << std::endl; - ssh_disconnect(mSession); - ssh_free(mSession); - return 1; + if (!mRpcSystem) + { + std::cerr << "RsSshd::doRpcSystem() ERROR Not Set"; + std::cerr << std::endl; + return 0; + } + + mRpcSystem->reset(); // clear everything for new user. + + bool okay = true; + while(okay) + { + int rt = mRpcSystem->tick(); + if (rt) + { + // Working - so small sleep, + usleep(mBusyUSleep); + } + else + { + // No work cycle, longer break. + usleep(mIdleUSleep); + } + + if (rt < 0) + { + okay = false; // exit. + } + + if (!isOkay()) + { + okay = false; + } + } + + std::cerr << "RsSshd::doRpcSystem() Finished"; + std::cerr << std::endl; + + return 1; +} + +// RpcComms Interface.... +int RsSshd::isOkay() +{ + return (mState == RSSSHD_STATE_CONNECTED); } -int RsSshd::cleanupAll() +int RsSshd::error(std::string msg) { - std::cerr << "RsSshd::cleanupAll()"; + std::cerr << "RsSshd::error(" << msg << ")"; std::cerr << std::endl; - cleanupSession(); - if (mBindState) - { - ssh_bind_free(mBind); - mBindState = 0; - } - ssh_finalize(); - return 1; + mState = RSSSHD_STATE_ERROR; + return 1; } + +int RsSshd::recv_ready() +{ + int bytes = ssh_channel_poll(mChannel, 0); + return bytes; +} + + +int RsSshd::recv(uint8_t *buffer, int bytes) +{ +#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0) + int size = ssh_channel_read_nonblocking(mChannel, buffer, bytes, 0); +#else + int size = channel_read_nonblocking(mChannel, buffer, bytes, 0); +#endif + return size; +} + + +int RsSshd::recv(std::string &buffer, int bytes) +{ + char input[bytes]; +#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0) + int size = ssh_channel_read_nonblocking(mChannel, input, bytes, 0); +#else + int size = channel_read_nonblocking(mChannel, input, bytes, 0); +#endif + for(int i = 0; i < size; i++) + { + buffer += input[i]; + } + return size; +} + + +int RsSshd::recv_blocking(uint8_t *buffer, int bytes) +{ +#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0) + int size = ssh_channel_read(mChannel, buffer, bytes, 0); +#else + int size = channel_read(mChannel, buffer, bytes, 0); +#endif + return size; +} + + +int RsSshd::recv_blocking(std::string &buffer, int bytes) +{ + char input[bytes]; +#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0) + int size = ssh_channel_read(mChannel, input, bytes, 0); +#else + int size = channel_read(mChannel, input, bytes, 0); +#endif + for(int i = 0; i < size; i++) + { + buffer += input[i]; + } + return size; +} + +int RsSshd::send(uint8_t *buffer, int bytes) +{ +#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0) + ssh_channel_write(mChannel, buffer, bytes); +#else + channel_write(mChannel, buffer, bytes); +#endif + return 1; +} + +int RsSshd::send(const std::string &buffer) +{ +#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0) + ssh_channel_write(mChannel, buffer.c_str(), buffer.size()); +#else + channel_write(mChannel, buffer.c_str(), buffer.size()); +#endif + return 1; +} + +int RsSshd::setSleepPeriods(float busy, float idle) +{ + mBusyUSleep = busy * 1000000; + mIdleUSleep = idle * 1000000; + return 1; +} + + + /***********************************************************************************/ /* PASSWORDS */ /***********************************************************************************/ @@ -682,7 +844,7 @@ int CheckPasswordHash(std::string pwdHashRadix64, std::string password) char *buf = NULL; size_t len = 1024; Radix64::decode(pwdHashRadix64, buf, len); - for(int i = 0; (i < len) && (i < 1024); i++) + for(unsigned int i = 0; (i < len) && (i < 1024); i++) { output[i] = buf[i]; } diff --git a/retroshare-nogui/src/ssh/rssshd.h b/retroshare-nogui/src/ssh/rssshd.h index ef2be2709..2f0a87d36 100644 --- a/retroshare-nogui/src/ssh/rssshd.h +++ b/retroshare-nogui/src/ssh/rssshd.h @@ -34,7 +34,7 @@ clients must be made or how a client should react. #include #include -#include "rstermserver.h" +#include "rpcsystem.h" #ifndef KEYS_FOLDER #ifdef _WIN32 @@ -66,24 +66,36 @@ int CheckPasswordHash(std::string pwdHashRadix64, std::string password); int GeneratePasswordHash(std::string saltBin, std::string password, std::string &pwdHashRadix64); int GenerateSalt(std::string &saltBin); -class RsSshd: public RsThread +class RsSshd: public RsThread, public RpcComms { public: -int adduserpwdhash(std::string username, std::string hash); -#ifdef ALLOW_CLEARPWDS -int adduser(std::string username, std::string password); -#endif // ALLOW_CLEARPWDS - - - -virtual void run(); /* overloaded from RsThread => called once the thread is started */ - // NB: This must be called EARLY before all the threads are launched. static RsSshd *InitRsSshd(std::string portstr, std::string rsakeyfile); - // Terminal Handling! -int setTermServer(RsTermServer *s); + + // Interface. +int setRpcSystem(RpcSystem *s); +int adduserpwdhash(std::string username, std::string hash); + + // RsThreads Interface. + virtual void run(); /* called once the thread is started */ + + // RsComms Interface. + virtual int isOkay(); + virtual int error(std::string msg); + + virtual int recv_ready(); + + virtual int recv(uint8_t *buffer, int bytes); + virtual int recv(std::string &buffer, int bytes); + virtual int recv_blocking(uint8_t *buffer, int bytes); + virtual int recv_blocking(std::string &buffer, int bytes); + + virtual int send(uint8_t *buffer, int bytes); + virtual int send(const std::string &buffer); + + virtual int setSleepPeriods(float busy, float idle); private: RsSshd(std::string portStr); /* private constructor => so can only create with */ @@ -102,7 +114,8 @@ int setupShell(); int doEcho(); // Terminal Handling! -int doTermServer(); +//int doTermServer(); +int doRpcSystem(); int cleanupSession(); int cleanupAll(); @@ -117,6 +130,9 @@ int auth_password_basic(char *name, char *pwd); // DATA. RsMutex mSshMtx; + + uint32_t mBusyUSleep; + uint32_t mIdleUSleep; uint32_t mState; uint32_t mBindState; @@ -126,7 +142,8 @@ int auth_password_basic(char *name, char *pwd); ssh_bind mBind; ssh_channel mChannel; - RsTermServer *mTermServer; + RpcSystem *mRpcSystem; + #ifdef ALLOW_CLEARPWDS std::map mPasswords; #endif // ALLOW_CLEARPWDS From 8a7c011c5d63aeddc13d68db8f8bf071defb4f2e Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 20 Aug 2012 18:59:13 +0000 Subject: [PATCH 029/222] Added Directory structure for new rsctrl protocol. * see NOTES.txt for how to implement it. * protobuf definitions are in rsctrl/src/definition This does not compile yet, and just early thoughts. Suggestions and help developing this are welcome. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5445 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- rsctrl/src/NOTES.txt | 60 +++++++++++++++++ rsctrl/src/definition/base.proto | 61 +++++++++++++++++ rsctrl/src/definition/peers.proto | 106 ++++++++++++++++++++++++++++++ 3 files changed, 227 insertions(+) create mode 100644 rsctrl/src/NOTES.txt create mode 100644 rsctrl/src/definition/base.proto create mode 100644 rsctrl/src/definition/peers.proto diff --git a/rsctrl/src/NOTES.txt b/rsctrl/src/NOTES.txt new file mode 100644 index 000000000..a06f35ce2 --- /dev/null +++ b/rsctrl/src/NOTES.txt @@ -0,0 +1,60 @@ + +This document proposes the finer details of how to communicate with RS, +using SSH and protobuf classes. +========================================================================== + +Message Format +==================== + +Protobuf serialisation does not identify Message Types or Message Size. +So we need to have an encapsulation header system + +These headers describe the actual message via a MsgId and MsgSize. +Care must be taken to ensure these IDS are correct, as this is NOT enforced +by protobuf, and will lead to incorrect deserialisation! + +In Each .proto there is a list of MsgIds as an ENUM. + +The protocol message format is as follows: + [HEADER: 16 bytes: 4 x Network Order uint32_t][ VARIABLE LENGTH BODY ] + + [ MAGIC_CODE ] [ MSG_ID ] [ REQ_ID ] [ BODY_SIZE ] [ ..... BODY ..... ] + MagicCode = 0x137f0001. will be incremented for new versions of the protocol. + MsgID = Corresponds to the format of the Body. + ReqID = Generated by Requester, Returned in Response, + make sure its unique. (undefined behaviour for duplicates) + BodySize = Byte Length of Body. + + The Body will consist of a protobuf encoded message. + + +Usage +================= + * Create SSH connection to retroshare-nogui. + * Create Request Message(s), and send over SSH channel - You can send as meny requests as you want. + * They will processed, and responses sent back (potentially in an arbitary order). + +MsgIDs +================= +In Each .proto there is a list of MsgIds as an ENUM. + +0x00 XX XX xx => Reserved for libretroshare Requests. (XX - area, xxxx specific msg) +0x01 XX XX xx => Reserved for libretroshare Responses + +eg. 0x00 (fa bc) [01] -> Request, 0x01 (fa bc) [01/02/03] -> responses + +0x10 YY YY yy => Extensions for project YY (16k), with sub commands yy (256) +0x11 YY YY yy + +... if we run out of YY's will use 0x20 etc. + + +Extensions +================= + +These are welcome and encouraged. +We just need to make sure that MsgIDs don't clash. + + + + diff --git a/rsctrl/src/definition/base.proto b/rsctrl/src/definition/base.proto new file mode 100644 index 000000000..076bfe06a --- /dev/null +++ b/rsctrl/src/definition/base.proto @@ -0,0 +1,61 @@ +package rsctrl.base: + +/////////////////////////////////////////////////////////////// +// These are basic Messages, which are used as building blocks +// throughout the rest of the interface. +// They should not be sent RAW, but should be wrapped in another msg. +/////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////// +// Basic Status Response, should be in all responses + +message Status { + enum StatusCode { + FAILED = 0; + INVALID_QUERY = 1; + SUCCESS = 2; + READMSG = 3; + } + required StatusCode code = 1; + optional string msg = 2; +} + +/////////////////////////////////////////////////////////////// +// Peer structures, mainly rsctrl.peers related. + +message Location { + required string ssl_id = 1; + required string location = 2; + + required string localaddr = 3; + required string extaddr = 4; +} + +message Person { + required string gpg_id = 1; + required string name = 2; + + repeated Location locations = 3; +} + +/////////////////////////////////////////////////////////////// +// File structures, mainly rsctrl.files related. + +message File { + required string name = 1; + required string hash = 2; + required int64 size = 3; + + optional string path = 4; + optional string avail = 5; + +} + +message Dir { + required string name = 1; + required string path = 2; + + repeated Dir subdirs = 3; + repeated File files = 4; +} + diff --git a/rsctrl/src/definition/peers.proto b/rsctrl/src/definition/peers.proto new file mode 100644 index 000000000..8f0539f0a --- /dev/null +++ b/rsctrl/src/definition/peers.proto @@ -0,0 +1,106 @@ +package rsctrl.peers: +/////////////////////////////////////////////////////////////// +// Access, and Control your Friends / Peers and related Settings. +/////////////////////////////////////////////////////////////// + +enum ExtensionId { BASE = 0; } +enum PackageId { PEERS = 1; } + +enum RequestMsgIds { + RequestPeers = 1; + RequestAddPeer = 2; + RequestModifyPeer = 2; +} + +enum ResponseMsgIds { + ResponsePeerList = 1; + ResponseAddPeer = 2; + ResponseModifyPeer = 2; +} + +/////////////////////////////////////////////////////////////// + +// REQUEST: RequestPeers +message RequestPeers { + + // About Who? + enum SetOption { + LISTED = 1; + ONLINE = 2; + FRIENDS = 3; + VALID = 4; + ALL = 5; + } + + // What do you want? + enum InfoOption { + NAMEONLY = 1; + BASIC = 2; + LOCATION = 3; + ALL = 4; + } + + required SetOption set = 1; + required InfoOption info = 2; + repeated string gpg_ids = 3; +} + + +// RESPONSE: ResponsePeerList +message ResponsePeerList { + required rsctrl.base.Status status = 1; + repeated rsctrl.base.Person peers = 2; +} + +/////////////////////////////////////////////////////////////// + +// REQUEST: RequestAddPeer +message RequestAddPeer { + + enum AddCmd { + NOOP = 0; // No op. + ADD = 1; // Add existing from gpg_id. + REMOVE = 2; // Remove existing from gpg_id. + IMPORT = 3; // Import from cert, with gpg_id. + EXAMINE = 4; // Examine cert, but no action. + } + + required string gpg_id = 1; + required AddCmd cmd = 2; + optional string cert = 3; +} + +// RESPONSE: ResponseAddPeer +message ResponseAddPeer { + required rsctrl.base.Status status = 1; + repeated rsctrl.base.Person peers = 2; +} + +/////////////////////////////////////////////////////////////// + +// REQUEST: RequestModifyPeer +message RequestModifyPeer { + + enum ModCmd { + NOOP = 0; + ADDRESS = 1; + DYNDNS = 2; + //SOMETHING_ELSE = 0x0000010; + //SOMETHING_ELSE = 0x0000020; + //SOMETHING_ELSE = 0x0000040; + //SOMETHING_ELSE = 0x0000080; + } + + required ModCmd cmd = 1; + //required int64 cmd = 1; // Could we OR the Cmds together? + repeated rsctrl.base.Person peers = 2; +} + +// RESPONSE: ResponseModifyPeer +message ResponseModifyPeer { + required rsctrl.base.Status status = 1; + repeated rsctrl.base.Person peers = 2; +} + +/////////////////////////////////////////////////////////////// + From 6dd18eea464477db1fb05f23de98c6618190b45e Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Tue, 21 Aug 2012 21:32:07 +0000 Subject: [PATCH 030/222] seperated content value from retrodb added local meta changing fucntionality to gxs also added msgrelated info id retrieval to tokeservice git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5452 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsdataservice.cc | 16 +- libretroshare/src/gxs/rsgds.h | 14 + libretroshare/src/gxs/rsgenexchange.cc | 155 ++++++- libretroshare/src/gxs/rsgenexchange.h | 40 +- libretroshare/src/gxs/rsgxsdataaccess.cc | 433 ++++++++++-------- libretroshare/src/gxs/rsgxsdataaccess.h | 55 +-- libretroshare/src/gxs/rsgxsrequesttypes.h | 8 + libretroshare/src/gxs/rstokenservice.h | 42 +- .../src/services/p3photoserviceV2.cc | 6 +- libretroshare/src/util/contentvalue.cc | 311 +++++++++++++ libretroshare/src/util/contentvalue.h | 183 ++++++++ libretroshare/src/util/retrodb.cc | 314 +------------ libretroshare/src/util/retrodb.h | 152 +----- 13 files changed, 983 insertions(+), 746 deletions(-) create mode 100644 libretroshare/src/util/contentvalue.cc create mode 100644 libretroshare/src/util/contentvalue.h diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index fd9180444..a362f3bda 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -120,6 +120,14 @@ #define RS_DATA_SERVICE_DEBUG +const std::string RsGeneralDataService::GRP_META_SERV_STRING = KEY_NXS_SERV_STRING; +const std::string RsGeneralDataService::GRP_META_STATUS = KEY_GRP_STATUS; +const std::string RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG = KEY_GRP_SUBCR_FLAG; + +const std::string RsGeneralDataService::MSG_META_SERV_STRING = KEY_NXS_SERV_STRING; +const std::string RsGeneralDataService::MSG_META_STATUS = KEY_MSG_STATUS; + + RsDataService::RsDataService(const std::string &serviceDir, const std::string &dbName, uint16_t serviceType, RsGxsSearchModule *mod) : RsGeneralDataService(), mServiceDir(serviceDir), mDbName(mServiceDir + "/" + dbName), mServType(serviceType){ @@ -910,12 +918,16 @@ int RsDataService::removeGroups(const std::vector &grpIds) int RsDataService::updateGroupMetaData(GrpLocMetaData &meta) { - return 0; + RsGxsGroupId& grpId = meta.grpId; + return mDb->sqlUpdate(GRP_TABLE_NAME, KEY_GRP_ID+ "='" + grpId + "'", meta.val) ? 1 : 0; } int RsDataService::updateMessageMetaData(MsgLocMetaData &metaData) { - return 0; + RsGxsGroupId& grpId = metaData.msgId.first; + RsGxsMessageId& msgId = metaData.msgId.second; + return mDb->sqlUpdate(MSG_TABLE_NAME, KEY_GRP_ID+ "='" + grpId + + "' AND " + KEY_MSG_ID + "='" + msgId + "'", metaData.val) ? 1 : 0; } diff --git a/libretroshare/src/gxs/rsgds.h b/libretroshare/src/gxs/rsgds.h index 58212ee8d..428a0be69 100644 --- a/libretroshare/src/gxs/rsgds.h +++ b/libretroshare/src/gxs/rsgds.h @@ -55,6 +55,8 @@ public: class MsgLocMetaData { public: + MsgLocMetaData(const MsgLocMetaData& meta){ msgId = meta.msgId; val = meta.val;} + MsgLocMetaData() {} RsGxsGrpMsgIdPair msgId; ContentValue val; }; @@ -66,6 +68,8 @@ public: class GrpLocMetaData { public: + GrpLocMetaData(const GrpLocMetaData& meta){ grpId = meta.grpId; val = meta.val;} + GrpLocMetaData(){} RsGxsGroupId grpId; ContentValue val; @@ -98,6 +102,16 @@ typedef std::map > GxsMsgResult; // & msgId) + RsGxsGrpMsgIdPair& msgId) { RsStackMutex stack(mGenMtx); - std::map >::iterator mit = - mMsgPublished.find(token); + std::map::iterator mit = + mMsgNotify.find(token); - if(mit == mMsgPublished.end()) - return false; + if(mit == mMsgNotify.end()) + { + return false; + } - msgId = mit->second; - // no dump token as client has ackowledged its completion - mDataAccess->disposeOfPublicToken(token); + msgId = mit->second; + + // no dump token as client has ackowledged its completion + mDataAccess->disposeOfPublicToken(token); return true; } @@ -95,9 +103,9 @@ bool RsGenExchange::acknowledgeTokenGrp(const uint32_t& token, RsStackMutex stack(mGenMtx); std::map::iterator mit = - mGrpPublished.find(token); + mGrpNotify.find(token); - if(mit == mGrpPublished.end()) + if(mit == mGrpNotify.end()) return false; grpId = mit->second; @@ -395,28 +403,131 @@ void RsGenExchange::notifyNewMessages(std::vector& messages) } -bool RsGenExchange::publishGroup(uint32_t& token, RsGxsGrpItem *grpItem) +void RsGenExchange::publishGroup(uint32_t& token, RsGxsGrpItem *grpItem) { RsStackMutex stack(mGenMtx); token = mDataAccess->generatePublicToken(); mGrpsToPublish.insert(std::make_pair(token, grpItem)); - - return true; } -bool RsGenExchange::publishMsg(uint32_t& token, RsGxsMsgItem *msgItem) +void RsGenExchange::publishMsg(uint32_t& token, RsGxsMsgItem *msgItem) +{ + RsStackMutex stack(mGenMtx); + + token = mDataAccess->generatePublicToken(); + mMsgsToPublish.insert(std::make_pair(token, msgItem)); +} + +void RsGenExchange::setGroupSubscribeFlag(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& flag) +{ + RsStackMutex stack(mGenMtx); + token = mDataAccess->generatePublicToken(); + + GrpLocMetaData g; + g.grpId = grpId; + g.val.put(RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG, (int32_t)flag); + mGrpLocMetaMap.insert(std::make_pair(token, g)); +} + +void RsGenExchange::setGroupStatusFlag(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status) +{ + RsStackMutex stack(mGenMtx); + token = mDataAccess->generatePublicToken(); + + GrpLocMetaData g; + g.grpId = grpId; + g.val.put(RsGeneralDataService::GRP_META_STATUS, (int32_t)status); + mGrpLocMetaMap.insert(std::make_pair(token, g)); +} + + +void RsGenExchange::setGroupServiceString(uint32_t& token, const RsGxsGroupId& grpId, const std::string& servString) +{ + RsStackMutex stack(mGenMtx); + token = mDataAccess->generatePublicToken(); + + GrpLocMetaData g; + g.grpId = grpId; + g.val.put(RsGeneralDataService::GRP_META_SERV_STRING, servString); + mGrpLocMetaMap.insert(std::make_pair(token, g)); +} + +void RsGenExchange::setMsgStatusFlag(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const uint32_t& status) +{ + RsStackMutex stack(mGenMtx); + token = mDataAccess->generatePublicToken(); + + MsgLocMetaData m; + m.val.put(RsGeneralDataService::MSG_META_STATUS, (int32_t)status); + m.msgId = msgId; + mMsgLocMetaMap.insert(std::make_pair(token, m)); +} + +void RsGenExchange::setMsgServiceString(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const std::string& servString ) +{ + RsStackMutex stack(mGenMtx); + token = mDataAccess->generatePublicToken(); + + MsgLocMetaData m; + m.val.put(RsGeneralDataService::MSG_META_SERV_STRING, servString); + m.msgId = msgId; + mMsgLocMetaMap.insert(std::make_pair(token, m)); +} + +void RsGenExchange::processMsgMetaChanges() { - RsStackMutex stack(mGenMtx); + RsStackMutex stack(mGenMtx); - token = mDataAccess->generatePublicToken(); - mMsgsToPublish.insert(std::make_pair(token, msgItem)); + std::map::iterator mit = mMsgLocMetaMap.begin(), + mit_end = mMsgLocMetaMap.end(); - return true; + for(; mit != mit_end; mit++) + { + MsgLocMetaData& m = mit->second; + bool ok = mDataStore->updateMessageMetaData(m) == 1; + uint32_t token = mit->first; + + if(ok) + { + mDataAccess->updatePublicRequestStatus(token, RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE); + }else + { + mDataAccess->updatePublicRequestStatus(token, RsTokenServiceV2::GXS_REQUEST_STATUS_FAILED); + } + mMsgNotify.insert(std::make_pair(token, m.msgId)); + } + + mMsgLocMetaMap.clear(); } +void RsGenExchange::processGrpMetaChanges() +{ + RsStackMutex stack(mGenMtx); + + std::map::iterator mit = mGrpLocMetaMap.begin(), + mit_end = mGrpLocMetaMap.end(); + + for(; mit != mit_end; mit++) + { + GrpLocMetaData& g = mit->second; + uint32_t token = mit->first; + bool ok = mDataStore->updateGroupMetaData(g) == 1; + + if(ok) + { + mDataAccess->updatePublicRequestStatus(token, RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE); + }else + { + mDataAccess->updatePublicRequestStatus(token, RsTokenServiceV2::GXS_REQUEST_STATUS_FAILED); + } + mGrpNotify.insert(std::make_pair(token, g.grpId)); + } + + mGrpLocMetaMap.clear(); +} void RsGenExchange::publishMsgs() { @@ -453,7 +564,7 @@ void RsGenExchange::publishMsgs() ok = mDataAccess->addMsgData(msg); // add to published to allow acknowledgement - mMsgPublished.insert(std::make_pair(mit->first, std::make_pair(msg->grpId, msg->msgId))); + mMsgNotify.insert(std::make_pair(mit->first, std::make_pair(msg->grpId, msg->msgId))); mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE); } @@ -463,7 +574,7 @@ void RsGenExchange::publishMsgs() #ifdef GEN_EXCH_DEBUG std::cerr << "RsGenExchange::publishMsgs() failed to publish msg " << std::endl; #endif - mMsgPublished.insert(std::make_pair(mit->first, std::make_pair(RsGxsGroupId(""), RsGxsMessageId("")))); + mMsgNotify.insert(std::make_pair(mit->first, std::make_pair(RsGxsGroupId(""), RsGxsMessageId("")))); delete msg; continue; @@ -509,7 +620,7 @@ void RsGenExchange::publishGrps() ok = mDataAccess->addGroupData(grp); // add to published to allow acknowledgement - mGrpPublished.insert(std::make_pair(mit->first, grp->grpId)); + mGrpNotify.insert(std::make_pair(mit->first, grp->grpId)); mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE); } @@ -522,7 +633,7 @@ void RsGenExchange::publishGrps() delete grp; // add to published to allow acknowledgement, grpid is empty as grp creation failed - mGrpPublished.insert(std::make_pair(mit->first, RsGxsGroupId(""))); + mGrpNotify.insert(std::make_pair(mit->first, RsGxsGroupId(""))); mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_STATUS_FAILED); continue; } diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 20a8407e5..cf433dbaa 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -161,7 +161,7 @@ public: * @param msgIds map of grpid->msgIds of message created/modified * @return true if token exists false otherwise */ - bool acknowledgeTokenMsg(const uint32_t& token, std::pair& msgId); + bool acknowledgeTokenMsg(const uint32_t& token, RsGxsGrpMsgIdPair& msgId); /*! * This allows the client service to acknowledge that their grps has @@ -184,7 +184,7 @@ protected: * @param token * @param grpItem */ - bool publishGroup(uint32_t& token, RsGxsGrpItem* grpItem); + void publishGroup(uint32_t& token, RsGxsGrpItem* grpItem); /*! * Enables publication of a message item @@ -194,7 +194,23 @@ protected: * @param token * @param msgItem */ - bool publishMsg(uint32_t& token, RsGxsMsgItem* msgItem); + void publishMsg(uint32_t& token, RsGxsMsgItem* msgItem); + + /*! + * sets the group subscribe flag + * @param token this is set to token value associated to this request + * @param + */ + void setGroupSubscribeFlag(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status); + + void setGroupStatusFlag(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status); + + void setGroupServiceString(uint32_t& token, const RsGxsGroupId& grpId, const std::string& servString); + + void setMsgStatusFlag(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const uint32_t& status); + + void setMsgServiceString(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const std::string& servString ); + protected: @@ -227,6 +243,16 @@ private: void publishMsgs(); + /*! + * processes msg local meta changes + */ + void processMsgMetaChanges(); + + /*! + * Processes group local meta changes + */ + void processGrpMetaChanges(); + void createGroup(RsNxsGrp* grp); bool createMessage(RsNxsMsg* msg); @@ -244,8 +270,12 @@ private: std::map mGrpsToPublish; std::map mMsgsToPublish; - std::map > mMsgPublished; - std::map mGrpPublished; + std::map mMsgNotify; + std::map mGrpNotify; + + // for loc meta changes + std::map mGrpLocMetaMap; + std::map mMsgLocMetaMap; std::vector mNotifications; diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index fd9b198c6..e72035217 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -153,58 +153,22 @@ bool RsGxsDataAccess::requestMsgInfo(uint32_t &token, uint32_t ansType, return true; } -bool RsGxsDataAccess::requestSetGroupSubscribeFlags(uint32_t& token, const RsGxsGroupId &grpId, uint32_t subscribeFlags, - uint32_t subscribeMask) + +bool RsGxsDataAccess::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq& msgIds) { - generateToken(token); + MsgRelatedInfoReq* req = new MsgRelatedInfoReq(); + req->mMsgIds = msgIds; - GroupSetFlagReq* req = new GroupSetFlagReq(); + generateToken(token); - req->flag = subscribeFlags; - req->flagMask = subscribeMask; - req->grpId = grpId; + setReq(req, token, ansType, opts); + storeRequest(req); - std::cerr << "RsGxsDataAccess::requestSetGroupSubscribeFlags() gets Token: " << token << std::endl; - storeRequest(req); - return false; + return true; } -bool RsGxsDataAccess::requestSetGroupStatus(uint32_t& token, const RsGxsGroupId& grpId, uint32_t status, uint32_t statusMask) -{ - - generateToken(token); - - GroupSetFlagReq* req = new GroupSetFlagReq(); - - req->flag = status; - req->flagMask = statusMask; - req->grpId = grpId; - - std::cerr << "RsGxsDataAccess::requestSetGroupStatus() gets Token: " << token << std::endl; - storeRequest(req); - - return true; -} - -bool RsGxsDataAccess::requestSetMessageStatus(uint32_t& token, const RsGxsGrpMsgIdPair &msgId, uint32_t status, - uint32_t statusMask) -{ - - generateToken(token); - - MessageSetFlagReq* req = new MessageSetFlagReq(); - - req->flag = status; - req->flagMask = statusMask; - req->msgId = msgId; - - std::cerr << "RsGxsDataAccess::requestSetGroupStatus() gets Token: " << token << std::endl; - storeRequest(req); - - return true; -} void RsGxsDataAccess::setReq(GxsRequest* req, const uint32_t& token, const uint32_t& ansType, const RsTokReqOptionsV2& opts) const { @@ -424,6 +388,37 @@ bool RsGxsDataAccess::getMsgList(const uint32_t& token, GxsMsgIdResult& msgIds) return true; } +bool RsGxsDataAccess::getMsgRelatedInfo(const uint32_t &token, GxsMsgIdResult &msgIds) +{ + RsStackMutex stack(mDataMutex); + + GxsRequest* req = locked_retrieveRequest(token); + + if(req == NULL){ + + std::cerr << "RsGxsDataAccess::getMsgRelatedInfo() Unable to retrieve group data" << std::endl; + return false; + }else if(req->status == GXS_REQUEST_STATUS_COMPLETE){ + + MsgRelatedInfoReq* mrireq = dynamic_cast(req); + + if(mrireq) + { + msgIds = mrireq->mMsgIdResult; + locked_updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + + }else{ + std::cerr << "RsGxsDataAccess::::getMsgRelatedInfo() Req found, failed caste" << std::endl; + return false; + } + }else{ + std::cerr << "RsGxsDataAccess::::getMsgRelatedInfo() Req not ready" << std::endl; + return false; + } + + return true; +} + bool RsGxsDataAccess::getGroupList(const uint32_t& token, std::list& groupIds) { RsStackMutex stack(mDataMutex); @@ -488,6 +483,7 @@ void RsGxsDataAccess::processRequests() MsgMetaReq* mmr; MsgDataReq* mdr; MsgIdReq* mir; + MsgRelatedInfoReq* mri; for(it = mRequests.begin(); it != mRequests.end(); it++) { @@ -527,6 +523,10 @@ void RsGxsDataAccess::processRequests() { getMsgList(mir); } + else if((mri = dynamic_cast(req)) != NULL) + { + getMsgRelatedInfo(mri); + } else { #ifdef GXSDATA_SERVE_DEBUG @@ -569,7 +569,6 @@ void RsGxsDataAccess::processRequests() bool RsGxsDataAccess::getGroupData(GroupDataReq* req) { - std::map grpData; std::list::iterator lit = req->mGroupIds.begin(), @@ -650,170 +649,200 @@ bool RsGxsDataAccess::getMsgSummary(MsgMetaReq* req) return true; } + +bool RsGxsDataAccess::getMsgRelatedInfo(MsgRelatedInfoReq* req) +{ + GxsMsgMetaResult result; + + const RsTokReqOptionsV2& opts = req->Options; + + { + RsStackMutex stack(mDataMutex); + mDataStore->retrieveGxsMsgMetaData(req->mMsgIds, result); + } + + + /* CASEs this handles. + * Input is groupList + Flags. + * 1) No Flags => All Messages in those Groups. + * + */ + std::cerr << "RsGxsDataAccess::getMsgList()"; + std::cerr << std::endl; + + + bool onlyOrigMsgs = false; + bool onlyLatestMsgs = false; + bool onlyThreadHeadMsgs = false; + + // Can only choose one of these two. + if (opts.mOptions & RS_TOKREQOPT_MSG_ORIGMSG) + { + std::cerr << "RsGxsDataAccess::getMsgList() MSG_ORIGMSG"; + std::cerr << std::endl; + onlyOrigMsgs = true; + } + else if (opts.mOptions & RS_TOKREQOPT_MSG_LATEST) + { + std::cerr << "RsGxsDataAccess::getMsgList() MSG_LATEST"; + std::cerr << std::endl; + onlyLatestMsgs = true; + } + + if (opts.mOptions & RS_TOKREQOPT_MSG_THREAD) + { + std::cerr << "RsGxsDataAccess::getMsgList() MSG_THREAD"; + std::cerr << std::endl; + onlyThreadHeadMsgs = true; + } + + GxsMsgMetaResult::iterator meta_it; + MsgMetaFilter metaFilter; + + for(meta_it = result.begin(); meta_it != result.end(); meta_it++) + { + const RsGxsGroupId& grpId = meta_it->first; + + metaFilter[grpId] = std::map(); + + const std::vector& metaV = meta_it->second; + if (onlyLatestMsgs) // THIS ONE IS HARD -> LOTS OF COMP. + { + std::vector::const_iterator vit = metaV.begin(); + + + // RUN THROUGH ALL MSGS... in map origId -> TS. + std::map > origMsgTs; + std::map >::iterator oit; + + for(; vit != metaV.end(); vit++) + { + RsGxsMsgMetaData* msgMeta = *vit; + + /* if we are grabbing thread Head... then parentId == empty. */ + if (onlyThreadHeadMsgs) + { + if (!(msgMeta->mParentId.empty())) + { + continue; + } + } + + + oit = origMsgTs.find(msgMeta->mOrigMsgId); + bool addMsg = false; + if (oit == origMsgTs.end()) + { + std::cerr << "RsGxsDataAccess::getMsgList() Found New OrigMsgId: "; + std::cerr << msgMeta->mOrigMsgId; + std::cerr << " MsgId: " << msgMeta->mMsgId; + std::cerr << " TS: " << msgMeta->mPublishTs; + std::cerr << std::endl; + + addMsg = true; + } + // check timestamps. + else if (oit->second.second < msgMeta->mPublishTs) + { + std::cerr << "RsGxsDataAccess::getMsgList() Found Later Msg. OrigMsgId: "; + std::cerr << msgMeta->mOrigMsgId; + std::cerr << " MsgId: " << msgMeta->mMsgId; + std::cerr << " TS: " << msgMeta->mPublishTs; + + addMsg = true; + } + + if (addMsg) + { + // add as latest. (overwriting if necessary) + origMsgTs[msgMeta->mOrigMsgId] = std::make_pair(msgMeta->mMsgId, msgMeta->mPublishTs); + metaFilter[grpId].insert(std::make_pair(msgMeta->mMsgId, msgMeta)); + } + } + + // Add the discovered Latest Msgs. + for(oit = origMsgTs.begin(); oit != origMsgTs.end(); oit++) + { + req->mMsgIdResult[grpId].push_back(oit->second.first); + + } + + } + else // ALL OTHER CASES. + { + std::vector::const_iterator vit = metaV.begin(); + + for(; vit != metaV.end(); vit++) + { + RsGxsMsgMetaData* msgMeta = *vit; + bool add = false; + + /* if we are grabbing thread Head... then parentId == empty. */ + if (onlyThreadHeadMsgs) + { + if (!(msgMeta->mParentId.empty())) + { + continue; + } + } + + + if (onlyOrigMsgs) + { + if (msgMeta->mMsgId == msgMeta->mOrigMsgId) + { + add = true; + } + } + else + { + add = true; + } + + if (add) + { + req->mMsgIdResult[grpId].push_back(msgMeta->mMsgId); + } + + } + } + } + + filterMsgList(req->mMsgIdResult, opts, metaFilter); + + // delete the data + cleanseMetaFilter(metaFilter); + + return true; +} + bool RsGxsDataAccess::getMsgList(MsgIdReq* req) { - GxsMsgMetaResult result; - const RsTokReqOptionsV2& opts = req->Options; + GxsMsgMetaResult result; - { - RsStackMutex stack(mDataMutex); - mDataStore->retrieveGxsMsgMetaData(req->mMsgIds, result); - } + { + RsStackMutex stack(mDataMutex); + mDataStore->retrieveGxsMsgMetaData(req->mMsgIds, result); + } + GxsMsgMetaResult::iterator mit = result.begin(), mit_end = result.end(); - /* CASEs this handles. - * Input is groupList + Flags. - * 1) No Flags => All Messages in those Groups. - * - */ - std::cerr << "RsGxsDataAccess::getMsgList()"; - std::cerr << std::endl; + for(; mit != mit_end; mit++) + { + const RsGxsGroupId grpId = mit->first; + std::vector& metaV = mit->second; + std::vector::iterator vit = metaV.begin(), + vit_end = metaV.end(); - - bool onlyOrigMsgs = false; - bool onlyLatestMsgs = false; - bool onlyThreadHeadMsgs = false; - - // Can only choose one of these two. - if (opts.mOptions & RS_TOKREQOPT_MSG_ORIGMSG) - { - std::cerr << "RsGxsDataAccess::getMsgList() MSG_ORIGMSG"; - std::cerr << std::endl; - onlyOrigMsgs = true; - } - else if (opts.mOptions & RS_TOKREQOPT_MSG_LATEST) - { - std::cerr << "RsGxsDataAccess::getMsgList() MSG_LATEST"; - std::cerr << std::endl; - onlyLatestMsgs = true; - } - - if (opts.mOptions & RS_TOKREQOPT_MSG_THREAD) - { - std::cerr << "RsGxsDataAccess::getMsgList() MSG_THREAD"; - std::cerr << std::endl; - onlyThreadHeadMsgs = true; - } - - GxsMsgMetaResult::iterator meta_it; - MsgMetaFilter metaFilter; - - for(meta_it = result.begin(); meta_it != result.end(); meta_it++) - { - const RsGxsGroupId& grpId = meta_it->first; - - metaFilter[grpId] = std::map(); - - const std::vector& metaV = meta_it->second; - if (onlyLatestMsgs) // THIS ONE IS HARD -> LOTS OF COMP. - { - std::vector::const_iterator vit = metaV.begin(); - - - // RUN THROUGH ALL MSGS... in map origId -> TS. - std::map > origMsgTs; - std::map >::iterator oit; - - for(; vit != metaV.end(); vit++) - { - RsGxsMsgMetaData* msgMeta = *vit; - - /* if we are grabbing thread Head... then parentId == empty. */ - if (onlyThreadHeadMsgs) - { - if (!(msgMeta->mParentId.empty())) - { - continue; - } - } - - - oit = origMsgTs.find(msgMeta->mOrigMsgId); - bool addMsg = false; - if (oit == origMsgTs.end()) - { - std::cerr << "RsGxsDataAccess::getMsgList() Found New OrigMsgId: "; - std::cerr << msgMeta->mOrigMsgId; - std::cerr << " MsgId: " << msgMeta->mMsgId; - std::cerr << " TS: " << msgMeta->mPublishTs; - std::cerr << std::endl; - - addMsg = true; - } - // check timestamps. - else if (oit->second.second < msgMeta->mPublishTs) - { - std::cerr << "RsGxsDataAccess::getMsgList() Found Later Msg. OrigMsgId: "; - std::cerr << msgMeta->mOrigMsgId; - std::cerr << " MsgId: " << msgMeta->mMsgId; - std::cerr << " TS: " << msgMeta->mPublishTs; - - addMsg = true; - } - - if (addMsg) - { - // add as latest. (overwriting if necessary) - origMsgTs[msgMeta->mOrigMsgId] = std::make_pair(msgMeta->mMsgId, msgMeta->mPublishTs); - metaFilter[grpId].insert(std::make_pair(msgMeta->mMsgId, msgMeta)); - } - } - - // Add the discovered Latest Msgs. - for(oit = origMsgTs.begin(); oit != origMsgTs.end(); oit++) - { - req->mMsgIds[grpId].push_back(oit->second.first); - - } - - } - else // ALL OTHER CASES. - { - std::vector::const_iterator vit = metaV.begin(); - - for(; vit != metaV.end(); vit++) - { - RsGxsMsgMetaData* msgMeta = *vit; - bool add = false; - - /* if we are grabbing thread Head... then parentId == empty. */ - if (onlyThreadHeadMsgs) - { - if (!(msgMeta->mParentId.empty())) - { - continue; - } - } - - - if (onlyOrigMsgs) - { - if (msgMeta->mMsgId == msgMeta->mOrigMsgId) - { - add = true; - } - } - else - { - add = true; - } - - if (add) - { - req->mMsgIdResult[grpId].push_back(msgMeta->mMsgId); - } - - } - } - } - - filterMsgList(req->mMsgIdResult, opts, metaFilter); - - // delete the data - cleanseMetaFilter(metaFilter); - - return true; + for(; vit != vit_end; vit++) + { + RsGxsMsgMetaData* meta = *vit; + req->mMsgIdResult[grpId].push_back(meta->mMsgId); + delete meta; // discard meta data mem + } + } + return true; } void RsGxsDataAccess::cleanseMetaFilter(MsgMetaFilter& filter) diff --git a/libretroshare/src/gxs/rsgxsdataaccess.h b/libretroshare/src/gxs/rsgxsdataaccess.h index 24c928dd2..f67a25ec1 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.h +++ b/libretroshare/src/gxs/rsgxsdataaccess.h @@ -64,36 +64,14 @@ public: bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq&); /*! - * This sets the status of the message - * @param msgId the message id to set status for - * @param status status - * @param statusMask the mask for the settings targetted - * @return true if request made successfully, false otherwise + * For requesting msgs related to a given msg id within a group + * @param token The token returned for the request + * @param ansType The type of result wanted + * @param opts Additional option that affect outcome of request. Please see specific services, for valid values + * @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs + * @return true if request successful false otherwise */ - bool requestSetMessageStatus(uint32_t &token, const RsGxsGrpMsgIdPair &msgId, - const uint32_t status, const uint32_t statusMask); - - /*! - * - * @param token - * @param grpId - * @param status - * @param statusMask - * @return true if request made successfully, false otherwise - */ - bool requestSetGroupStatus(uint32_t &token, const RsGxsGroupId &grpId, const uint32_t status, - const uint32_t statusMask); - - /*! - * Use request status to find out if successfully set - * @param groupId - * @param subscribeFlags - * @param subscribeMask - * @return true if request made successfully, false otherwise - */ - bool requestSetGroupSubscribeFlags(uint32_t& token, const RsGxsGroupId &groupId, uint32_t subscribeFlags, - uint32_t subscribeMask); - + bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq&); /* Poll */ uint32_t requestStatus(const uint32_t token); @@ -103,8 +81,6 @@ public: /** E: RsTokenService **/ - - public: /*! @@ -177,6 +153,14 @@ public: */ bool getMsgData(const uint32_t &token, NxsMsgDataResult& msgData); + /*! + * + * @param token request token to be redeemed + * @param msgIds + * @return false if data cannot be found for token + */ + bool getMsgRelatedInfo(const uint32_t &token, GxsMsgIdResult &msgIds); + private: /** helper functions to implement token service **/ @@ -321,6 +305,15 @@ private: */ bool getMsgData(MsgDataReq* req); + + /*! + * Attempts to retrieve messages related to msgIds of associated equest + * @param token request token to be redeemed + * @param msgIds + * @return false if data cannot be found for token + */ + bool getMsgRelatedInfo(MsgRelatedInfoReq* req); + /*! * This filter msgs based of options supplied (at the moment just status masks) * @param msgIds The msgsIds to filter diff --git a/libretroshare/src/gxs/rsgxsrequesttypes.h b/libretroshare/src/gxs/rsgxsrequesttypes.h index d5da446c5..5536a4d6d 100644 --- a/libretroshare/src/gxs/rsgxsrequesttypes.h +++ b/libretroshare/src/gxs/rsgxsrequesttypes.h @@ -95,6 +95,14 @@ public: NxsMsgDataResult mMsgData; }; +class MsgRelatedInfoReq : public GxsRequest +{ + +public: + GxsMsgReq mMsgIds; + GxsMsgIdResult mMsgIdResult; +}; + class GroupSetFlagReq : public GxsRequest { public: diff --git a/libretroshare/src/gxs/rstokenservice.h b/libretroshare/src/gxs/rstokenservice.h index 4d4dc1843..d0e562dc6 100644 --- a/libretroshare/src/gxs/rstokenservice.h +++ b/libretroshare/src/gxs/rstokenservice.h @@ -132,46 +132,20 @@ public: * @param ansType The type of result wanted * @param opts Additional option that affect outcome of request. Please see specific services, for valid values * @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs - * @return + * @return true if request successful false otherwise */ virtual bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq& msgIds) = 0; - - /*! - * This sets the status of the message - * @param msgId the message id to set status for - * @param status status - * @param statusMask the mask for the settings targetted - * @return true if request made successfully, false otherwise + * For requesting msgs related to a given msg id within a group + * @param token The token returned for the request + * @param ansType The type of result wanted + * @param opts Additional option that affect outcome of request. Please see specific services, for valid values + * @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs + * @return true if request successful false otherwise */ - virtual bool requestSetMessageStatus(uint32_t &token, const RsGxsGrpMsgIdPair &msgId, - const uint32_t status, const uint32_t statusMask) = 0; + virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq& msgIds) = 0; - /*! - * Set the status of a group given by group Id - * @param token The token returned for this request - * @param grpId The Id of the group to apply status change to - * @param status The status to apply - * @param statusMask The status mask (target particular type of status) - * @return true if request made successfully, false otherwise - */ - virtual bool requestSetGroupStatus(uint32_t &token, const RsGxsGroupId &grpId, const uint32_t status, - const uint32_t statusMask) = 0; - - /*! - * Use request status to find out if successfully set - * @param groupId - * @param subscribeFlags - * @param subscribeMask - * @return true if request made successfully, false otherwise - */ - virtual bool requestSetGroupSubscribeFlags(uint32_t& token, const RsGxsGroupId &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) = 0; - - - // (FUTURE WORK). - //virtual bool groupRestoreKeys(const std::string &groupId) = 0; - //virtual bool groupShareKeys(const std::string &groupId, std::list& peers) = 0; /* Poll */ diff --git a/libretroshare/src/services/p3photoserviceV2.cc b/libretroshare/src/services/p3photoserviceV2.cc index 4fa74163d..a460ff3b7 100644 --- a/libretroshare/src/services/p3photoserviceV2.cc +++ b/libretroshare/src/services/p3photoserviceV2.cc @@ -142,7 +142,8 @@ bool p3PhotoServiceV2::submitAlbumDetails(uint32_t& token, RsPhotoAlbum& album) RsGxsPhotoAlbumItem* albumItem = new RsGxsPhotoAlbumItem(); albumItem->album = album; albumItem->meta = album.mMeta; - return RsGenExchange::publishGroup(token, albumItem); + RsGenExchange::publishGroup(token, albumItem); + return true; } @@ -177,7 +178,8 @@ bool p3PhotoServiceV2::submitPhoto(uint32_t& token, RsPhotoPhoto& photo) photoItem->photo = photo; photoItem->meta = photo.mMeta; - return RsGenExchange::publishMsg(token, photoItem); + RsGenExchange::publishMsg(token, photoItem); + return true; } bool p3PhotoServiceV2::acknowledgeMsg(const uint32_t& token, diff --git a/libretroshare/src/util/contentvalue.cc b/libretroshare/src/util/contentvalue.cc new file mode 100644 index 000000000..58f237cf7 --- /dev/null +++ b/libretroshare/src/util/contentvalue.cc @@ -0,0 +1,311 @@ + +/* + * util/contentvalue.cc, key val container + * + * Copyright 2012 Christopher Evi-Parker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include +#include + +#include "contentvalue.h" + + + + +const uint8_t ContentValue::BOOL_TYPE = 1; +const uint8_t ContentValue::DATA_TYPE = 2; +const uint8_t ContentValue::STRING_TYPE = 3; +const uint8_t ContentValue::DOUBLE_TYPE = 4; +const uint8_t ContentValue::INT32_TYPE = 5; +const uint8_t ContentValue::INT64_TYPE = 6; + + +/**************** content value implementation ******************/ + +typedef std::pair KeyTypePair; + +ContentValue::ContentValue(){ + +} + +ContentValue::~ContentValue(){ + // release resources held in data + clearData(); +} + +ContentValue::ContentValue(ContentValue &from){ + + std::map keyTypeMap; + from.getKeyTypeMap(keyTypeMap); + std::map::const_iterator cit = + keyTypeMap.begin(); + + uint8_t type = 0; + std::string currKey; + std::string val = ""; + char *src = NULL; + uint32_t data_len = 0; + + for(; cit != keyTypeMap.end(); cit++){ + + type = cit->second; + currKey = cit->first; + + switch(type){ + + case INT32_TYPE: + { + int32_t value; + from.getAsInt32(currKey, value); + put(currKey, value); + break; + } + case INT64_TYPE: + { + int64_t value; + from.getAsInt64(currKey, value); + put(currKey, value); + break; + } + case STRING_TYPE: + { + from.getAsString(currKey, val); + put(currKey, val); + break; + } + case BOOL_TYPE: + { + bool value; + from.getAsBool(currKey, value); + put(currKey, value); + break; + } + case DATA_TYPE: + { + from.getAsData(currKey, data_len, src); + put(currKey, data_len, src); + break; + } + case DOUBLE_TYPE: + double value; + from.getAsDouble(currKey, value); + put(currKey, value); + break; + default: + std::cerr << "ContentValue::ContentValue(ContentValue &from):" + << "Error! Unrecognised data type!" << std::endl; + } + } +} + +void ContentValue::put(const std::string &key, bool value){ + + if(mKvSet.find(key) != mKvSet.end()) + removeKeyValue(key); + + mKvSet.insert(KeyTypePair(key, BOOL_TYPE)); + mKvBool.insert(std::pair(key, value)); +} + +void ContentValue::put(const std::string &key, const std::string &value){ + + if(mKvSet.find(key) != mKvSet.end()) + removeKeyValue(key); + + mKvSet.insert(KeyTypePair(key, STRING_TYPE)); + mKvString.insert(std::pair(key, value)); +} + +void ContentValue::put(const std::string &key, double value){ + + if(mKvSet.find(key) != mKvSet.end()) + removeKeyValue(key); + + mKvSet.insert(KeyTypePair(key,DOUBLE_TYPE)); + mKvDouble.insert(std::pair(key, value)); +} + +void ContentValue::put(const std::string &key, int32_t value){ + + if(mKvSet.find(key) != mKvSet.end()) + removeKeyValue(key); + + mKvSet.insert(KeyTypePair(key, INT32_TYPE)); + mKvInt32.insert(std::pair(key, value)); +} + +void ContentValue::put(const std::string &key, int64_t value){ + + if(mKvSet.find(key) != mKvSet.end()) + removeKeyValue(key); + + mKvSet.insert(KeyTypePair(key, INT64_TYPE)); + mKvInt64.insert(std::pair(key, value)); +} + +void ContentValue::put(const std::string &key, uint32_t len, const char* value){ + + + // release memory from old key value if key + // exists + if(mKvSet.find(key) != mKvSet.end()) { + removeKeyValue(key); + } + + mKvSet.insert(KeyTypePair(key, DATA_TYPE)); + char* dest = NULL; + + // len is zero then just put a NULL entry + if(len != 0){ + dest = new char[len]; + memcpy(dest, value, len); + } + + mKvData.insert(std::pair > + (key, std::pair(len, dest))); +} + +bool ContentValue::getAsBool(const std::string &key, bool& value) const{ + + std::map::const_iterator it; + if((it = mKvBool.find(key)) == mKvBool.end()) + return false; + + value = it->second; + return true; +} + +bool ContentValue::getAsInt32(const std::string &key, int32_t& value) const{ + + std::map::const_iterator it; + if((it = mKvInt32.find(key)) == mKvInt32.end()) + return false; + + value = it->second; + return true; +} + +bool ContentValue::getAsInt64(const std::string &key, int64_t& value) const{ + + std::map::const_iterator it; + if((it = mKvInt64.find(key)) == mKvInt64.end()) + return false; + + value = it->second; + return true; +} + +bool ContentValue::getAsString(const std::string &key, std::string &value) const{ + + std::map::const_iterator it; + if((it = mKvString.find(key)) == mKvString.end()) + return false; + + value = it->second; + return true; +} + +bool ContentValue::getAsData(const std::string& key, uint32_t &len, char*& value) const{ + + std::map >::const_iterator it; + if((it = mKvData.find(key)) == mKvData.end()) + return false; + + const std::pair &kvRef = it->second; + + len = kvRef.first; + value = kvRef.second; + return true; +} + +bool ContentValue::getAsDouble(const std::string &key, double& value) const{ + + std::map::const_iterator it; + if((it = mKvDouble.find(key)) == mKvDouble.end()) + return false; + + value = it->second; + return true; +} + +bool ContentValue::removeKeyValue(const std::string &key){ + + std::map::iterator mit; + + if((mit = mKvSet.find(key)) == mKvSet.end()) + return false; + + if(mit->second == BOOL_TYPE) + mKvBool.erase(key); + + if(mit->second == INT64_TYPE) + mKvInt64.erase(key); + + if(mit->second == DATA_TYPE){ + delete[] (mKvData[key].second); + mKvData.erase(key); + } + + if(mit->second == DOUBLE_TYPE) + mKvDouble.erase(key); + + if(mit->second == STRING_TYPE) + mKvString.erase(key); + + if(mit->second == INT32_TYPE) + mKvInt32.erase(key); + + + mKvSet.erase(key); + return true; +} + + +void ContentValue::getKeyTypeMap(std::map &keySet) const { + keySet = mKvSet; +} + +void ContentValue::clear(){ + mKvSet.clear(); + mKvBool.clear(); + mKvDouble.clear(); + mKvString.clear(); + mKvInt32.clear(); + mKvInt64.clear(); + clearData(); +} + +void ContentValue::clearData(){ + + std::map >::iterator + mit = mKvData.begin(); + + for(; mit != mKvData.end(); mit++){ + + if(mit->second.first != 0) + delete[] (mit->second.second); + } + + mKvData.clear(); +} + + + diff --git a/libretroshare/src/util/contentvalue.h b/libretroshare/src/util/contentvalue.h new file mode 100644 index 000000000..50b12af48 --- /dev/null +++ b/libretroshare/src/util/contentvalue.h @@ -0,0 +1,183 @@ +#ifndef CONTENTVALUE_H +#define CONTENTVALUE_H + +/* + * util/contentvalue.h, key val container + * + * Copyright 2012 Christopher Evi-Parker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include +#include +#include + +/*! + * @brief Convenience container for making additions to databases + * This class provides a means of holding column values to insert into a database + */ +class ContentValue { + +public: + + static const uint8_t INT32_TYPE; + static const uint8_t INT64_TYPE; + static const uint8_t DOUBLE_TYPE; + static const uint8_t STRING_TYPE; + static const uint8_t DATA_TYPE; + static const uint8_t BOOL_TYPE; + + ContentValue(); + + /*! + * copy constructor that copys the key value set from another \n + * ContentValue object to this one + * makes a deep copy of raw data + * @param from ContentValue instance to copy key value set from + */ + ContentValue(ContentValue& from); + + /*! + * + * + * + */ + ~ContentValue(); + + /*! + * Adds a value to the set + * @param key the name of the value to put + * @param value the data for the value to put + * @warning cast string literals explicitly as string, observed string literal \n + * being casted to bool instead e.g. string("hello") rather than "hello" + */ + void put(const std::string& key, const std::string& value); + + /*! + * Adds a value to the set + * @param key the name of the value to put + * @param value the data for the value to put + */ + void put(const std::string& key, bool value); + + /*! + * Adds a value to the set + * @param key the name of the value to put + * @param value the data for the value to put + */ + void put(const std::string& key, int64_t value); + + /*! + * Adds a value to the set + * @param key the name of the value to put + * @param value the data for the value to put + */ + void put(const std::string& key, int32_t value); + + /*! + * Adds a value to the set + * @param key the name of the value to put + * @param value the data for the value to put + */ + void put(const std::string& key, double value); + + /*! + * Adds a value to the set + * @param key the name of the value to put + * @param value the data for the value to put + */ + void put(const std::string& key, uint32_t len, const char* value); + + + /*! + * get value as 32 bit signed integer + * @param key the value to get + */ + bool getAsInt32(const std::string& key, int32_t& value) const; + + /*! + * get value as 64 bit signed integer + * @param key the value to get + */ + bool getAsInt64(const std::string& key, int64_t& value) const; + + /*! + * get value as bool + * @param key the value to get + */ + bool getAsBool(const std::string& key, bool& value) const; + + /*! + * get as value double + * @param key the value to get + */ + bool getAsDouble(const std::string& key, double& value) const; + + /*! + * get as value as string + * @param key the value to get + * @param value the data retrieved + */ + bool getAsString(const std::string& key, std::string& value) const; + + /*! + * get as value as raw data + * @warning Deep copy of data reference should be made, if this instance ContentValue \n + * is destroyed pointer returned (value) is pointing to invalid memory + * @param key the value to get + */ + bool getAsData(const std::string&, uint32_t& len, char*& value) const; + + /*! + * @param keySet the is set with key to type pairs contained in the ContentValue instance + */ + void getKeyTypeMap(std::map& keySet) const; + + /*! + * @param key the key of the key value pair to remove + * @return true if key was found and removed, false otherwise + */ + bool removeKeyValue(const std::string& key); + + /*! + * clears this data structure of all its key value pairs held + */ + void clear(); + +private: + + /*! + * release memory resource associated with mKvData + */ + void clearData(); + +private: + + std::map mKvInt32; + std::map mKvInt64; + std::map mKvDouble; + std::map mKvString; + std::map > mKvData; + std::map mKvBool; + + std::map mKvSet; + +}; + +#endif // CONTENTVALUE_H diff --git a/libretroshare/src/util/retrodb.cc b/libretroshare/src/util/retrodb.cc index 3af1e67aa..d5b2964ca 100644 --- a/libretroshare/src/util/retrodb.cc +++ b/libretroshare/src/util/retrodb.cc @@ -32,6 +32,8 @@ //#define RETRODB_DEBUG + + void free_blob(void* dat){ char* c = (char*) dat; @@ -40,13 +42,6 @@ void free_blob(void* dat){ } -const uint8_t ContentValue::BOOL_TYPE = 1; -const uint8_t ContentValue::DATA_TYPE = 2; -const uint8_t ContentValue::STRING_TYPE = 3; -const uint8_t ContentValue::DOUBLE_TYPE = 4; -const uint8_t ContentValue::INT32_TYPE = 5; -const uint8_t ContentValue::INT64_TYPE = 6; - const int RetroDb::OPEN_READONLY = SQLITE_OPEN_READONLY; const int RetroDb::OPEN_READWRITE = SQLITE_OPEN_READWRITE; const int RetroDb::OPEN_READWRITE_CREATE = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; @@ -234,9 +229,9 @@ bool RetroDb::sqlInsert(const std::string &table, const std::string& nullColumnH uint8_t type = mit->second; std::string key = mit->first; - switch(type){ - case ContentValue::BOOL_TYPE: + + if(ContentValue::BOOL_TYPE == type) { bool value; cv.getAsBool(key, value); @@ -244,7 +239,7 @@ bool RetroDb::sqlInsert(const std::string &table, const std::string& nullColumnH qValues += oStrStream.str(); break; } - case ContentValue::DOUBLE_TYPE: + else if( ContentValue::DOUBLE_TYPE == type) { double value; cv.getAsDouble(key, value); @@ -252,7 +247,7 @@ bool RetroDb::sqlInsert(const std::string &table, const std::string& nullColumnH qValues += oStrStream.str(); break; } - case ContentValue::DATA_TYPE: + else if( ContentValue::DATA_TYPE == type) { char* value; uint32_t len; @@ -265,14 +260,14 @@ bool RetroDb::sqlInsert(const std::string &table, const std::string& nullColumnH qValues += "?"; // parameter break; } - case ContentValue::STRING_TYPE: + else if ( ContentValue::STRING_TYPE == type) { std::string value; cv.getAsString(key, value); qValues += "'" + value +"'"; break; } - case ContentValue::INT32_TYPE: + else if ( ContentValue::INT32_TYPE == type) { int32_t value; cv.getAsInt32(key, value); @@ -280,7 +275,7 @@ bool RetroDb::sqlInsert(const std::string &table, const std::string& nullColumnH qValues += oStrStream.str(); break; } - case ContentValue::INT64_TYPE: + else if( ContentValue::INT64_TYPE == type) { int64_t value; cv.getAsInt64(key, value); @@ -288,7 +283,7 @@ bool RetroDb::sqlInsert(const std::string &table, const std::string& nullColumnH qValues += oStrStream.str(); break; } - } + mit++; if(mit != keyTypeMap.end()){ // add comma if more columns left @@ -419,9 +414,7 @@ bool RetroDb::sqlUpdate(const std::string &tableName, std::string whereClause, c uint8_t type = mit->second; std::string key = mit->first; - switch(type){ - - case ContentValue::BOOL_TYPE: + if( ContentValue::BOOL_TYPE == type) { bool value; cv.getAsBool(key, value); @@ -429,7 +422,7 @@ bool RetroDb::sqlUpdate(const std::string &tableName, std::string whereClause, c qValues += key + "='" + oStrStream.str(); break; } - case ContentValue::DOUBLE_TYPE: + else if( ContentValue::DOUBLE_TYPE == type) { double value; cv.getAsDouble(key, value); @@ -437,7 +430,7 @@ bool RetroDb::sqlUpdate(const std::string &tableName, std::string whereClause, c qValues += key + "='" + oStrStream.str(); break; } - case ContentValue::DATA_TYPE: + else if( ContentValue::DATA_TYPE == type) { char* value; uint32_t len; @@ -446,14 +439,14 @@ bool RetroDb::sqlUpdate(const std::string &tableName, std::string whereClause, c qValues += key + "='" + oStrStream.str() + "' "; break; } - case ContentValue::STRING_TYPE: + else if( ContentValue::STRING_TYPE == type) { std::string value; cv.getAsString(key, value); qValues += key + "='" + value + "' "; break; } - case ContentValue::INT32_TYPE: + else if( ContentValue::INT32_TYPE == type) { int32_t value; cv.getAsInt32(key, value); @@ -461,7 +454,7 @@ bool RetroDb::sqlUpdate(const std::string &tableName, std::string whereClause, c qValues += key + "='" + oStrStream.str() + "' "; break; } - case ContentValue::INT64_TYPE: + else if( ContentValue::INT64_TYPE == type) { int64_t value; cv.getAsInt64(key, value); @@ -469,7 +462,7 @@ bool RetroDb::sqlUpdate(const std::string &tableName, std::string whereClause, c qValues += key + "='" + oStrStream.str() + "' "; break; } - } + mit++; if(mit != keyTypeMap.end()){ // add comma if more columns left @@ -715,276 +708,3 @@ const void* RetroCursor::getData(int columnIndex, uint32_t &datSize){ } - - -/**************** content value implementation ******************/ - -typedef std::pair KeyTypePair; - -ContentValue::ContentValue(){ - -} - -ContentValue::~ContentValue(){ - // release resources held in data - clearData(); -} - -ContentValue::ContentValue(ContentValue &from){ - - std::map keyTypeMap; - from.getKeyTypeMap(keyTypeMap); - std::map::const_iterator cit = - keyTypeMap.begin(); - - uint8_t type = 0; - std::string currKey; - std::string val = ""; - char *src = NULL; - uint32_t data_len = 0; - - for(; cit != keyTypeMap.end(); cit++){ - - type = cit->second; - currKey = cit->first; - - switch(type){ - - case INT32_TYPE: - { - int32_t value; - from.getAsInt32(currKey, value); - put(currKey, value); - break; - } - case INT64_TYPE: - { - int64_t value; - from.getAsInt64(currKey, value); - put(currKey, value); - break; - } - case STRING_TYPE: - { - from.getAsString(currKey, val); - put(currKey, val); - break; - } - case BOOL_TYPE: - { - bool value; - from.getAsBool(currKey, value); - put(currKey, value); - break; - } - case DATA_TYPE: - { - from.getAsData(currKey, data_len, src); - put(currKey, data_len, src); - break; - } - case DOUBLE_TYPE: - double value; - from.getAsDouble(currKey, value); - put(currKey, value); - break; - default: - std::cerr << "ContentValue::ContentValue(ContentValue &from):" - << "Error! Unrecognised data type!" << std::endl; - } - } -} - -void ContentValue::put(const std::string &key, bool value){ - - if(mKvSet.find(key) != mKvSet.end()) - removeKeyValue(key); - - mKvSet.insert(KeyTypePair(key, BOOL_TYPE)); - mKvBool.insert(std::pair(key, value)); -} - -void ContentValue::put(const std::string &key, const std::string &value){ - - if(mKvSet.find(key) != mKvSet.end()) - removeKeyValue(key); - - mKvSet.insert(KeyTypePair(key, STRING_TYPE)); - mKvString.insert(std::pair(key, value)); -} - -void ContentValue::put(const std::string &key, double value){ - - if(mKvSet.find(key) != mKvSet.end()) - removeKeyValue(key); - - mKvSet.insert(KeyTypePair(key,DOUBLE_TYPE)); - mKvDouble.insert(std::pair(key, value)); -} - -void ContentValue::put(const std::string &key, int32_t value){ - - if(mKvSet.find(key) != mKvSet.end()) - removeKeyValue(key); - - mKvSet.insert(KeyTypePair(key, INT32_TYPE)); - mKvInt32.insert(std::pair(key, value)); -} - -void ContentValue::put(const std::string &key, int64_t value){ - - if(mKvSet.find(key) != mKvSet.end()) - removeKeyValue(key); - - mKvSet.insert(KeyTypePair(key, INT64_TYPE)); - mKvInt64.insert(std::pair(key, value)); -} - -void ContentValue::put(const std::string &key, uint32_t len, const char* value){ - - - // release memory from old key value if key - // exists - if(mKvSet.find(key) != mKvSet.end()) { - removeKeyValue(key); - } - - mKvSet.insert(KeyTypePair(key, DATA_TYPE)); - char* dest = NULL; - - // len is zero then just put a NULL entry - if(len != 0){ - dest = new char[len]; - memcpy(dest, value, len); - } - - mKvData.insert(std::pair > - (key, std::pair(len, dest))); -} - -bool ContentValue::getAsBool(const std::string &key, bool& value) const{ - - std::map::const_iterator it; - if((it = mKvBool.find(key)) == mKvBool.end()) - return false; - - value = it->second; - return true; -} - -bool ContentValue::getAsInt32(const std::string &key, int32_t& value) const{ - - std::map::const_iterator it; - if((it = mKvInt32.find(key)) == mKvInt32.end()) - return false; - - value = it->second; - return true; -} - -bool ContentValue::getAsInt64(const std::string &key, int64_t& value) const{ - - std::map::const_iterator it; - if((it = mKvInt64.find(key)) == mKvInt64.end()) - return false; - - value = it->second; - return true; -} - -bool ContentValue::getAsString(const std::string &key, std::string &value) const{ - - std::map::const_iterator it; - if((it = mKvString.find(key)) == mKvString.end()) - return false; - - value = it->second; - return true; -} - -bool ContentValue::getAsData(const std::string& key, uint32_t &len, char*& value) const{ - - std::map >::const_iterator it; - if((it = mKvData.find(key)) == mKvData.end()) - return false; - - const std::pair &kvRef = it->second; - - len = kvRef.first; - value = kvRef.second; - return true; -} - -bool ContentValue::getAsDouble(const std::string &key, double& value) const{ - - std::map::const_iterator it; - if((it = mKvDouble.find(key)) == mKvDouble.end()) - return false; - - value = it->second; - return true; -} - -bool ContentValue::removeKeyValue(const std::string &key){ - - std::map::iterator mit; - - if((mit = mKvSet.find(key)) == mKvSet.end()) - return false; - - if(mit->second == BOOL_TYPE) - mKvBool.erase(key); - - if(mit->second == INT64_TYPE) - mKvInt64.erase(key); - - if(mit->second == DATA_TYPE){ - delete[] (mKvData[key].second); - mKvData.erase(key); - } - - if(mit->second == DOUBLE_TYPE) - mKvDouble.erase(key); - - if(mit->second == STRING_TYPE) - mKvString.erase(key); - - if(mit->second == INT32_TYPE) - mKvInt32.erase(key); - - - mKvSet.erase(key); - return true; -} - - -void ContentValue::getKeyTypeMap(std::map &keySet) const { - keySet = mKvSet; -} - -void ContentValue::clear(){ - mKvSet.clear(); - mKvBool.clear(); - mKvDouble.clear(); - mKvString.clear(); - mKvInt32.clear(); - mKvInt64.clear(); - clearData(); -} - -void ContentValue::clearData(){ - - std::map >::iterator - mit = mKvData.begin(); - - for(; mit != mKvData.end(); mit++){ - - if(mit->second.first != 0) - delete[] (mit->second.second); - } - - mKvData.clear(); -} - - - diff --git a/libretroshare/src/util/retrodb.h b/libretroshare/src/util/retrodb.h index d1e773357..38706547f 100644 --- a/libretroshare/src/util/retrodb.h +++ b/libretroshare/src/util/retrodb.h @@ -31,8 +31,8 @@ #include #include +#include "contentvalue.h" -class ContentValue; class RetroCursor; /*! @@ -288,157 +288,7 @@ private: }; -/*! - * @brief Convenience container for making additions to databases - * This class provides a means of holding column values to insert into a database - */ -class ContentValue { -public: - - static const uint8_t INT32_TYPE; - static const uint8_t INT64_TYPE; - static const uint8_t DOUBLE_TYPE; - static const uint8_t STRING_TYPE; - static const uint8_t DATA_TYPE; - static const uint8_t BOOL_TYPE; - - ContentValue(); - - /*! - * copy constructor that copys the key value set from another \n - * ContentValue object to this one - * makes a deep copy of raw data - * @param from ContentValue instance to copy key value set from - */ - ContentValue(ContentValue& from); - - /*! - * - * - * - */ - ~ContentValue(); - - /*! - * Adds a value to the set - * @param key the name of the value to put - * @param value the data for the value to put - * @warning cast string literals explicitly as string, observed string literal \n - * being casted to bool instead e.g. string("hello") rather than "hello" - */ - void put(const std::string& key, const std::string& value); - - /*! - * Adds a value to the set - * @param key the name of the value to put - * @param value the data for the value to put - */ - void put(const std::string& key, bool value); - - /*! - * Adds a value to the set - * @param key the name of the value to put - * @param value the data for the value to put - */ - void put(const std::string& key, int64_t value); - - /*! - * Adds a value to the set - * @param key the name of the value to put - * @param value the data for the value to put - */ - void put(const std::string& key, int32_t value); - - /*! - * Adds a value to the set - * @param key the name of the value to put - * @param value the data for the value to put - */ - void put(const std::string& key, double value); - - /*! - * Adds a value to the set - * @param key the name of the value to put - * @param value the data for the value to put - */ - void put(const std::string& key, uint32_t len, const char* value); - - - /*! - * get value as 32 bit signed integer - * @param key the value to get - */ - bool getAsInt32(const std::string& key, int32_t& value) const; - - /*! - * get value as 64 bit signed integer - * @param key the value to get - */ - bool getAsInt64(const std::string& key, int64_t& value) const; - - /*! - * get value as bool - * @param key the value to get - */ - bool getAsBool(const std::string& key, bool& value) const; - - /*! - * get as value double - * @param key the value to get - */ - bool getAsDouble(const std::string& key, double& value) const; - - /*! - * get as value as string - * @param key the value to get - * @param value the data retrieved - */ - bool getAsString(const std::string& key, std::string& value) const; - - /*! - * get as value as raw data - * @warning Deep copy of data reference should be made, if this instance ContentValue \n - * is destroyed pointer returned (value) is pointing to invalid memory - * @param key the value to get - */ - bool getAsData(const std::string&, uint32_t& len, char*& value) const; - - /*! - * @param keySet the is set with key to type pairs contained in the ContentValue instance - */ - void getKeyTypeMap(std::map& keySet) const; - - /*! - * @param key the key of the key value pair to remove - * @return true if key was found and removed, false otherwise - */ - bool removeKeyValue(const std::string& key); - - /*! - * clears this data structure of all its key value pairs held - */ - void clear(); - -private: - - /*! - * release memory resource associated with mKvData - */ - void clearData(); - -private: - - std::map mKvInt32; - std::map mKvInt64; - std::map mKvDouble; - std::map mKvString; - std::map > mKvData; - std::map mKvBool; - - std::map mKvSet; - -}; #endif // RSSQLITE_H From 0d9a74d5b64957e04ef7c1325e756eb9ccc93cdc Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Tue, 21 Aug 2012 22:31:44 +0000 Subject: [PATCH 031/222] added contentvalue src in pro file git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5453 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/libretroshare.pro | 356 +++++++++++++--------------- 1 file changed, 163 insertions(+), 193 deletions(-) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 43e24aedf..5a7277aa7 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -1,211 +1,176 @@ TEMPLATE = lib - -# CONFIG += staticlib release -# CONFIG += staticlib testnetwork -CONFIG += staticlib \ - bitdht +#CONFIG += staticlib release +#CONFIG += staticlib testnetwork +CONFIG += staticlib bitdht newcache newservices CONFIG -= qt TARGET = retroshare +#DEFINES += RSSERIAL_DEBUG CONFIG += test_voip -# GXS Stuff. -CONFIG += newcache -CONFIG += newservices - # Beware: All data of the stripped services are lost +#CONFIG += minimal DEFINES *= PQI_DISABLE_TUNNEL +#ENABLE_CACHE_OPT -# ENABLE_CACHE_OPT -profiling { - QMAKE_CXXFLAGS -= -fomit-frame-pointer - QMAKE_CXXFLAGS *= -pg \ - -g \ - -fno-omit-frame-pointer -} -release: +minimal { + CONFIG -= use_blogs -# UDP and TUNNEL dont work anymore. -# DEFINES *= PQI_DISABLE_UDP -# treat warnings as error for better removing -# QMAKE_CFLAGS += -Werror -# QMAKE_CXXFLAGS += -Werror -testnetwork { - # used in rsserver/rsinit.cc Enabled Port Restrictions, and makes Proxy Port next to Dht Port. - DEFINES *= LOCALNET_TESTING - - # used in tcponudp/udprelay.cc Debugging Info for Relays. - DEFINES *= DEBUG_UDP_RELAY - - # used in tcponudp/udpstunner.[h | cc] enables local stun (careful - modifies class variables). - DEFINES *= UDPSTUN_ALLOW_LOCALNET - - # used in pqi/p3linkmgr.cc prints out extra debug. - DEFINES *= LINKMGR_DEBUG_LINKTYPE - - # used in dht/connectstatebox to reduce connection times and display debug. - # DEFINES *= TESTING_PERIODS - # DEFINES *= DEBUG_CONNECTBOX - QMAKE_CXXFLAGS -= -fomit-frame-pointer - QMAKE_CXXFLAGS -= -O2 - QMAKE_CXXFLAGS *= -g \ - -fno-omit-frame-pointer + DEFINES += MINIMAL_LIBRS } + +profiling { + QMAKE_CXXFLAGS -= -fomit-frame-pointer + QMAKE_CXXFLAGS *= -pg -g -fno-omit-frame-pointer +} + +release { + # UDP and TUNNEL dont work anymore. + #DEFINES *= PQI_DISABLE_UDP +} + + + +testnetwork { + #DEFINES *= PQI_DISABLE_UDP + DEFINES *= PQI_DISABLE_TUNNEL + + # DEFINES *= AUTHSSL_DEBUG GPG_DEBUG + # DEFINES *= CONN_DEBUG + # DEFINES *= P3DISC_DEBUG + + # DEFINES *= PGRP_DEBUG + # DEFINES *= PERSON_DEBUG + + #DEFINES *= DEBUG_UDP_SORTER DEBUG_UDP_LAYER EXTADDRSEARCH_DEBUG + + QMAKE_CXXFLAGS -= -fomit-frame-pointer + QMAKE_CXXFLAGS -= -O2 + QMAKE_CXXFLAGS *= -g -fno-omit-frame-pointer +} + + CONFIG += debug -debug { - # DEFINES *= DEBUG - # DEFINES *= OPENDHT_DEBUG DHT_DEBUG CONN_DEBUG DEBUG_UDP_SORTER P3DISC_DEBUG DEBUG_UDP_LAYER FT_DEBUG EXTADDRSEARCH_DEBUG - # DEFINES *= CONTROL_DEBUG FT_DEBUG DEBUG_FTCHUNK P3TURTLE_DEBUG - # DEFINES *= P3TURTLE_DEBUG - # DEFINES *= NET_DEBUG - # DEFINES *= DISTRIB_DEBUG - # DEFINES *= P3TURTLE_DEBUG FT_DEBUG DEBUG_FTCHUNK MPLEX_DEBUG - # DEFINES *= STATUS_DEBUG SERV_DEBUG RSSERIAL_DEBUG #CONN_DEBUG - QMAKE_CXXFLAGS -= -O2 \ - -fomit-frame-pointer - QMAKE_CXXFLAGS *= -g \ - -fno-omit-frame-pointer -} -bitdht { - HEADERS += dht/p3bitdht.h \ - dht/connectstatebox.h \ - dht/stunaddrassist.h - SOURCES += dht/p3bitdht.cc \ - dht/p3bitdht_interface.cc \ - dht/p3bitdht_peers.cc \ - dht/p3bitdht_peernet.cc \ - dht/p3bitdht_relay.cc \ - dht/connectstatebox.cc - HEADERS += tcponudp/udppeer.h \ - tcponudp/bio_tou.h \ - tcponudp/tcppacket.h \ - tcponudp/tcpstream.h \ - tcponudp/tou.h \ - tcponudp/udpstunner.h \ - tcponudp/udprelay.h - SOURCES += tcponudp/udppeer.cc \ - tcponudp/tcppacket.cc \ - tcponudp/tcpstream.cc \ - tcponudp/tou.cc \ - tcponudp/bss_tou.c \ - tcponudp/udpstunner.cc \ - tcponudp/udprelay.cc - - # These two aren't actually used (and don't compile) .... - # but could be useful later - # tcponudp/udpstunner.h \ - # tcponudp/udpstunner.cc \ - BITDHT_DIR = ../../libbitdht/src - INCLUDEPATH += . \ - $${BITDHT_DIR} - - # The next line if for compliance with debian packages. Keep it! - INCLUDEPATH += ../libbitdht - DEFINES *= RS_USE_BITDHT -} -test_bitdht { - # DISABLE TCP CONNECTIONS... - DEFINES *= P3CONNMGR_NO_TCP_CONNECTIONS - - # NO AUTO CONNECTIONS??? FOR TESTING DHT STATUS. - DEFINES *= P3CONNMGR_NO_AUTO_CONNECTION +debug { +# DEFINES *= DEBUG +# DEFINES *= OPENDHT_DEBUG DHT_DEBUG CONN_DEBUG DEBUG_UDP_SORTER P3DISC_DEBUG DEBUG_UDP_LAYER FT_DEBUG EXTADDRSEARCH_DEBUG +# DEFINES *= CONTROL_DEBUG FT_DEBUG DEBUG_FTCHUNK P3TURTLE_DEBUG +# DEFINES *= P3TURTLE_DEBUG +# DEFINES *= NET_DEBUG +# DEFINES *= DISTRIB_DEBUG +# DEFINES *= P3TURTLE_DEBUG FT_DEBUG DEBUG_FTCHUNK MPLEX_DEBUG +# DEFINES *= STATUS_DEBUG SERV_DEBUG RSSERIAL_DEBUG #CONN_DEBUG + + QMAKE_CXXFLAGS -= -O2 -fomit-frame-pointer + QMAKE_CXXFLAGS *= -g -fno-omit-frame-pointer } -# ENABLED UDP NOW. -use_blogs { - HEADERS += services/p3blogs.h - SOURCES += services/p3blogs.cc - DEFINES *= RS_USE_BLOGS +bitdht { + +HEADERS += dht/p3bitdht.h \ + dht/connectstatebox.h \ + dht/stunaddrassist.h + +SOURCES += dht/p3bitdht.cc \ + dht/p3bitdht_interface.cc \ + dht/p3bitdht_peers.cc \ + dht/p3bitdht_peernet.cc \ + dht/p3bitdht_relay.cc \ + dht/connectstatebox.cc + +HEADERS += tcponudp/udppeer.h \ + tcponudp/bio_tou.h \ + tcponudp/tcppacket.h \ + tcponudp/tcpstream.h \ + tcponudp/tou.h \ + tcponudp/udpstunner.h \ + tcponudp/udprelay.h \ + +SOURCES += tcponudp/udppeer.cc \ + tcponudp/tcppacket.cc \ + tcponudp/tcpstream.cc \ + tcponudp/tou.cc \ + tcponudp/bss_tou.c \ + tcponudp/udpstunner.cc \ + tcponudp/udprelay.cc \ + +# These two aren't actually used (and don't compile) .... +# but could be useful later +# +# tcponudp/udpstunner.h \ +# tcponudp/udpstunner.cc \ +# + + + BITDHT_DIR = ../../libbitdht/src + INCLUDEPATH += . $${BITDHT_DIR} + # The next line if for compliance with debian packages. Keep it! + INCLUDEPATH += ../libbitdht + DEFINES *= RS_USE_BITDHT } -PUBLIC_HEADERS = retroshare/rsblogs.h \ - retroshare/rschannels.h \ - retroshare/rsdisc.h \ - retroshare/rsdistrib.h \ - retroshare/rsexpr.h \ - retroshare/rsfiles.h \ - retroshare/rsforums.h \ - retroshare/rshistory.h \ - retroshare/rsiface.h \ - retroshare/rsinit.h \ - retroshare/rsplugin.h \ - retroshare/rsloginhandler.h \ - retroshare/rsmsgs.h \ - retroshare/rsnotify.h \ - retroshare/rspeers.h \ - retroshare/rsrank.h \ - retroshare/rsstatus.h \ - retroshare/rsturtle.h \ - retroshare/rstypes.h \ - retroshare/rsdht.h \ - retroshare/rsdsdv.h \ - retroshare/rsconfig.h + + + +test_bitdht { + # DISABLE TCP CONNECTIONS... + DEFINES *= P3CONNMGR_NO_TCP_CONNECTIONS + + # NO AUTO CONNECTIONS??? FOR TESTING DHT STATUS. + DEFINES *= P3CONNMGR_NO_AUTO_CONNECTION + + # ENABLED UDP NOW. +} + + + + +use_blogs { + + HEADERS += services/p3blogs.h + SOURCES += services/p3blogs.cc + + DEFINES *= RS_USE_BLOGS +} + + + +PUBLIC_HEADERS = retroshare/rsblogs.h \ + retroshare/rschannels.h \ + retroshare/rsdisc.h \ + retroshare/rsdistrib.h \ + retroshare/rsexpr.h \ + retroshare/rsfiles.h \ + retroshare/rsforums.h \ + retroshare/rshistory.h \ + retroshare/rsiface.h \ + retroshare/rsinit.h \ + retroshare/rsplugin.h \ + retroshare/rsloginhandler.h \ + retroshare/rsmsgs.h \ + retroshare/rsnotify.h \ + retroshare/rspeers.h \ + retroshare/rsrank.h \ + retroshare/rsstatus.h \ + retroshare/rsturtle.h \ + retroshare/rstypes.h \ + retroshare/rsdht.h \ + retroshare/rsdsdv.h \ + retroshare/rsconfig.h + HEADERS += plugins/pluginmanager.h \ - plugins/dlfcn_win32.h \ - serialiser/rspluginitems.h + plugins/dlfcn_win32.h \ + serialiser/rspluginitems.h + + + HEADERS += $$PUBLIC_HEADERS # public headers to be... -HEADERS += retroshare/rsgame.h \ - retroshare/rsphoto.h +HEADERS += retroshare/rsgame.h \ + retroshare/rsphoto.h + # ################################ Linux ########################################## -linux-*:isEmpty(PREFIX) { - PREFIX = /usr \ - } - isEmpty(INC_DIR) { - INC_DIR = $${PREFIX}/include/retroshare/ \ - } - isEmpty(LIB_DIR) { - LIB_DIR = $${PREFIX}/lib/ \ - } - - # These two lines fixe compilation on ubuntu natty. Probably a ubuntu packaging error. - INCLUDEPATH *= /usr/lib/x86_64-linux-gnu/glib-2.0/include/ - INCLUDEPATH *= /usr/lib/i386-linux-gnu/glib-2.0/include/ - OPENPGPSDK_DIR = ../../openpgpsdk/src - INCLUDEPATH *= $${OPENPGPSDK_DIR} \ - ../openpgpsdk - DESTDIR = lib - QMAKE_CXXFLAGS *= -Wall \ - -D_FILE_OFFSET_BITS=64 - QMAKE_CC = g++ - SSL_DIR = /usr/include/openssl - UPNP_DIR = /usr/include/upnp - INCLUDEPATH += . \ - $${SSL_DIR} \ - $${UPNP_DIR} - - # gpg files - system(which gpg-error-config >/dev/null 2>&1):INCLUDEPATH += $$system(gpg-error-config --cflags | sed -e "s/-I//g") - else:message(Could not find gpg-error-config on your system, assuming gpg-error.h is in /usr/include) - system(which gpgme-config >/dev/null 2>&1):INCLUDEPATH += $$system(gpgme-config --cflags | sed -e "s/-I//g") - else:message(Could not find gpgme-config on your system, assuming gpgme.h is in /usr/include) - - # libupnp implementation files - HEADERS += upnp/UPnPBase.h - SOURCES += upnp/UPnPBase.cpp - - # where to put the shared library itself - target.path = $$LIB_DIR - INSTALLS *= target - - # where to put the library's interface - include_rsiface.path = $${INC_DIR} - include_rsiface.files = $$PUBLIC_HEADERS - INSTALLS += include_rsiface - - # CONFIG += version_detail_bash_script - DEFINES *= UBUNTU - INCLUDEPATH += /usr/include/glib-2.0/ \ - /usr/lib/glib-2.0/include - LIBS *= -lgnome-keyring - linux-g++:OBJECTS_DIR = temp/linux-g++/obj - linux-g++-64:OBJECTS_DIR = temp/linux-g++-64/obj - version_detail_bash_script { - QMAKE_EXTRA_TARGETS += write_version_detail - PRE_TARGETDEPS = write_version_detail - write_version_detail.commands = ./version_detail.sh - } # ################### Cross compilation for windows under Linux #################### win32-x-g++ { @@ -262,11 +227,14 @@ linux-*:isEmpty(PREFIX) { # miniupnp implementation files HEADERS += upnp/upnputil.h SOURCES += upnp/upnputil.c - UPNPC_DIR = ../../../miniupnpc-1.3 - PTHREADS_DIR = ../../../pthreads-w32-2-8-0-release - ZLIB_DIR = ../../../zlib-1.2.3 - SSL_DIR = ../../../openssl-1.0.1c - OPENPGPSDK_DIR = ../../openpgpsdk/src + UPNPC_DIR = ../../../lib/miniupnpc-1.3 + GPG_ERROR_DIR = ../../../lib/libgpg-error-1.7 + GPGME_DIR = ../../../lib/gpgme-1.1.8 + + PTHREADS_DIR = ../../../lib/pthreads-w32-2-8-0-release + ZLIB_DIR = ../../../lib/zlib-1.2.7 + SSL_DIR = ../../../OpenSSL + OPENPGPSDK_DIR = ../../openpgpsdk/src INCLUDEPATH += . \ $${SSL_DIR}/include \ $${UPNPC_DIR} \ @@ -274,7 +242,7 @@ linux-*:isEmpty(PREFIX) { $${ZLIB_DIR} \ $${OPENPGPSDK_DIR} newcache { - SQLITE_DIR = ../../../sqlite-autoconf-3071300 + SQLITE_DIR = ../../../../Libraries/sqlite/sqlite-autoconf-3070900 INCLUDEPATH += . \ $${SQLITE_DIR} } @@ -625,6 +593,7 @@ linux-*:isEmpty(PREFIX) { serialiser/rsgxsitems.h \ serialiser/rsphotov2items.h \ util/retrodb.h \ + util/contentvalue.h \ gxs/gxscoreserver.h \ gxs/gxssecurity.h SOURCES += serialiser/rsnxsitems.cc \ @@ -637,6 +606,7 @@ linux-*:isEmpty(PREFIX) { gxs/rsgxsdataaccess.cc \ serialiser/rsphotov2items.cc \ util/retrodb.cc \ + util/contentvalue.cc \ gxs/gxscoreserver.cc \ gxs/gxssecurity.cc } From 9a24b16226f8345f1e0d388cf46bf1bd96ae482f Mon Sep 17 00:00:00 2001 From: drbob Date: Thu, 23 Aug 2012 13:52:37 +0000 Subject: [PATCH 032/222] Adding Ralf's patch to add Shared Directory control to SSH Menu Interface. * Adds Shared Dir SubMenu with Add, Toggle Flags, Remove Shared Dir Commands. I tweaked it a bit: * Changes the Add Command to not use std::stringstream (as Windows don't like it!) * Added Check that the directory exists. * Changed Virtual Folder name to the top directory from the path. Still to do on the SubMenu; * Listing should be updated if a Share is Added/Removed. * Descriptions are too long, should be changed to short descriptions: Add Share, Toggle Browsable, etc. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5459 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/menu/menus.cc | 216 ++++++++++++++++++++++++++++- retroshare-nogui/src/menu/menus.h | 50 +++++++ 2 files changed, 262 insertions(+), 4 deletions(-) diff --git a/retroshare-nogui/src/menu/menus.cc b/retroshare-nogui/src/menu/menus.cc index 1613228be..fc3b95105 100644 --- a/retroshare-nogui/src/menu/menus.cc +++ b/retroshare-nogui/src/menu/menus.cc @@ -25,6 +25,7 @@ #include #include #include "util/rsstring.h" +#include "util/rsdir.h" #include "menu/menus.h" @@ -45,17 +46,24 @@ #define MENU_SEARCH_KEY_VIEW 'v' #define MENU_SEARCH_KEY_DOWNLOAD 'g' -#define MENU_FRIENDS_KEY_ADD 'a' -#define MENU_FRIENDS_KEY_VIEW 'v' -#define MENU_FRIENDS_KEY_REMOVE 'd' -#define MENU_FRIENDS_KEY_CHAT 'c' +#define MENU_FORUMS_KEY_ADD 'a' +#define MENU_FORUMS_KEY_VIEW 'v' +#define MENU_FORUMS_KEY_REMOVE 'd' +#define MENU_FORUMS_KEY_CHAT 'c' +#define MENU_SHARED_KEY_EXPAND 'e' +#define MENU_SHARED_KEY_UNSHARE 's' +#define MENU_SHARED_KEY_ADD 'a' +#define MENU_SHARED_KEY_PUBLIC 'c' +#define MENU_SHARED_KEY_BROWSABLE 'b' #define MENU_TOPLEVEL_KEY_FRIENDS 'f' #define MENU_TOPLEVEL_KEY_NETWORK 'w' #define MENU_TOPLEVEL_KEY_TRANSFER 'd' #define MENU_TOPLEVEL_KEY_SEARCH 's' #define MENU_TOPLEVEL_KEY_FORUMS 'o' +#define MENU_TOPLEVEL_KEY_SHARED 'k' //If you know of a key which fits better, just change it ;-) +#define MENU_TOPLEVEL_KEY_UPLOADS 'e' Menu *CreateMenuStructure(NotifyTxt *notify) @@ -88,6 +96,12 @@ Menu *CreateMenuStructure(NotifyTxt *notify) //forums->addMenuItem(MENU_FRIENDS_KEY_REMOVE, new MenuOpFriendsRemove()); //forums->addMenuItem(MENU_FRIENDS_KEY_CHAT, new MenuOpFriendsChat()); + // Shared folders Menu + MenuList *shared = new MenuListShared(); + shared->addMenuItem(MENU_SHARED_KEY_ADD , new MenuListSharedAddShare()); + shared->addMenuItem(MENU_SHARED_KEY_UNSHARE , new MenuListSharedUnshare()); + shared->addMenuItem(MENU_SHARED_KEY_PUBLIC , new MenuListSharedTogglePublic()); + shared->addMenuItem(MENU_SHARED_KEY_BROWSABLE , new MenuListSharedToggleBrowsable()); /* Top Level Menu */ Menu *tlm = new Menu("Top Level Menu"); @@ -97,6 +111,7 @@ Menu *CreateMenuStructure(NotifyTxt *notify) tlm->addMenuItem(MENU_TOPLEVEL_KEY_TRANSFER, transfers); tlm->addMenuItem(MENU_TOPLEVEL_KEY_SEARCH, search); //tlm->addMenuItem(MENU_TOPLEVEL_KEY_FORUMS, forums); + tlm->addMenuItem(MENU_TOPLEVEL_KEY_SHARED, shared); return tlm; } @@ -603,5 +618,198 @@ uint32_t MenuOpForumMsgWrite::op_twokeys(std::string parentkey, std::string key) return MENU_OP_INSTANT; } +/************ + * Shared folders Menu + */ +uint32_t MenuListShared::op() +{ + MenuList::op(); + + mList.clear(); + std::list dirs; + rsFiles->getSharedDirectories(dirs); + std::list::iterator it; + for(it = dirs.begin(); it != dirs.end(); it++) + { + mList.push_back ((*it).virtualname) ; + } + + return MENU_OP_SUBMENU; +} + +int MenuListShared::getEntryDesc(int idx, std::string &desc) +{ + std::list dirs; + rsFiles->getSharedDirectories(dirs); + std::list::iterator it; + std::string shareflag; + unsigned int i=0; + for (it = dirs.begin(); (i < idx) && (it != dirs.end()); it++, i++); + if (it != dirs.end()) + { + if (it->shareflags == (RS_FILE_HINTS_BROWSABLE | RS_FILE_HINTS_NETWORK_WIDE)) + shareflag = "networkwide - browsable"; + else if ((it->shareflags & RS_FILE_HINTS_BROWSABLE) == RS_FILE_HINTS_BROWSABLE) + shareflag = "private - browsable"; + else if ((it->shareflags & RS_FILE_HINTS_NETWORK_WIDE) == RS_FILE_HINTS_NETWORK_WIDE) + shareflag = "networkwide - anonymous"; + else + shareflag = "not shared"; + + rs_sprintf(desc, "Path: %s Share Type:%s", it->filename.c_str(), shareflag.c_str()); + return MENU_ENTRY_OKAY; + } + return MENU_ENTRY_NONE; +} + +int MenuListShared::unshareSelected() +{ + if (mSelectIdx < 0) + { + std::cout << "MenuListSearchList::unshareSelected() Invalid Selection"; + std::cout << std::endl; + return MENU_ENTRY_NONE; + } + std::list dirs; + rsFiles->getSharedDirectories(dirs); + std::list::iterator it; + unsigned int i=0; + for (it = dirs.begin(); (i < mSelectIdx) && (it != dirs.end()); it++, i++); + if (it != dirs.end()) + { + rsFiles->removeSharedDirectory(it->filename); + return MENU_ENTRY_OKAY; + } + return MENU_ENTRY_NONE; +} + +int MenuListShared::toggleFlagSelected(uint32_t shareflags) +{ + if (mSelectIdx < 0) + { + std::cout << "MenuListSearchList::unshareSelected() Invalid Selection"; + std::cout << std::endl; + return MENU_ENTRY_NONE; + } + std::list dirs; + rsFiles->getSharedDirectories(dirs); + std::list::iterator it; + unsigned int i=0; + for (it = dirs.begin(); (i < mSelectIdx) && (it != dirs.end()); it++, i++); + if (it != dirs.end()) + { + if((it->shareflags & shareflags) == shareflags) + { + it->shareflags = it->shareflags & ~shareflags; //disable shareflags + rsFiles->updateShareFlags(*it); + } else + { + it->shareflags = it->shareflags | shareflags; //anable shareflags + rsFiles->updateShareFlags(*it); + } + return MENU_ENTRY_OKAY; + } + return MENU_ENTRY_NONE; +} + +uint32_t MenuListSharedUnshare::op_basic(std::string key) +{ + Menu* p = parent(); + MenuListShared *mls = dynamic_cast(p); + if (!mls) + { + std::cout << "MenuListShared::op_basic() ERROR"; + std::cout << std::endl; + return MENU_OP_ERROR; + } + + mls->unshareSelected(); + + return MENU_OP_INSTANT; +} + +uint32_t MenuListSharedTogglePublic::op_basic(std::string key) +{ + Menu* p = parent(); + MenuListShared *mls = dynamic_cast(p); + if (!mls) + { + std::cout << "MenuListShared::op_basic() ERROR"; + std::cout << std::endl; + return MENU_OP_ERROR; + } + + mls->toggleFlagSelected(RS_FILE_HINTS_NETWORK_WIDE); + + return MENU_OP_INSTANT; +} + +uint32_t MenuListSharedToggleBrowsable::op_basic(std::string key) +{ + Menu* p = parent(); + MenuListShared *mls = dynamic_cast(p); + if (!mls) + { + std::cout << "MenuListShared::op_basic() ERROR"; + std::cout << std::endl; + return MENU_OP_ERROR; + } + + mls->toggleFlagSelected(RS_FILE_HINTS_BROWSABLE); + + return MENU_OP_INSTANT; +} + +uint32_t MenuListSharedAddShare::drawPage(uint32_t drawFlags, std::string &buffer) +{ + buffer += "Enter New path 'path' 'virtualfolder' > "; + return 1; +} + + + +uint32_t MenuListSharedAddShare::process_lines(std::string input) +{ + /* launch search */ + if (input.size() < 4) + { + std::cout << "MenuOpSearchNew::process_lines() ERROR Input too small"; + std::cout << std::endl; + return MENU_PROCESS_ERROR; + } + + std::string dir = input.substr(0, input.size() - 1); // remove \n. + + // check that the directory exists! + if (!RsDirUtil::checkDirectory(dir)) + { + std::cout << "MenuOpSearchNew::process_lines() ERROR Directory doesn't exist"; + std::cout << std::endl; + return MENU_PROCESS_ERROR; + } + + // extract top level as the virtual name. + std::string topdir = RsDirUtil::getTopDir(input); + if (topdir.size() < 1) + { + std::cout << "MenuOpSearchNew::process_lines() ERROR TopDir is invalid"; + std::cout << std::endl; + return MENU_PROCESS_ERROR; + } + + SharedDirInfo shareddir; + shareddir.filename = dir; + shareddir.virtualname = topdir; + shareddir.shareflags = 0x0; + + if (!rsFiles->addSharedDirectory(shareddir)) + { + std::cout << "MenuOpSearchNew::process_lines() ERROR Adding SharedDir"; + std::cout << std::endl; + return MENU_PROCESS_ERROR; + } + + return MENU_PROCESS_DONE; +} diff --git a/retroshare-nogui/src/menu/menus.h b/retroshare-nogui/src/menu/menus.h index b276eda57..53ed00a46 100644 --- a/retroshare-nogui/src/menu/menus.h +++ b/retroshare-nogui/src/menu/menus.h @@ -291,4 +291,54 @@ class MenuOpForumMsgWrite: public MenuOpTwoKeys virtual uint32_t op_twokeys(std::string parentkey, std::string key); }; +/************ + * Shared folders Menu + */ + + +class MenuListShared: public MenuList +{ + public: + + MenuListShared() :MenuList("My Shared Directories") { return; } + virtual uint32_t op(); + int getEntryDesc(int idx, std::string &desc); + int unshareSelected(); + int toggleFlagSelected(uint32_t shareflags); +}; + + + +class MenuListSharedUnshare: public MenuOpBasicKey +{ + public: + + MenuListSharedUnshare() :MenuOpBasicKey("Stop Sharing Selected") { return; } + virtual uint32_t op_basic(std::string key); +}; + +class MenuListSharedTogglePublic: public MenuOpBasicKey +{ + public: + + MenuListSharedTogglePublic() :MenuOpBasicKey("Enable/Disable Networkwide Sharing") { return; } + virtual uint32_t op_basic(std::string key); +}; + +class MenuListSharedToggleBrowsable: public MenuOpBasicKey +{ + public: + + MenuListSharedToggleBrowsable() :MenuOpBasicKey("Enable/Disable Browsing Of Selected") { return; } + virtual uint32_t op_basic(std::string key); +}; + +class MenuListSharedAddShare: public MenuOpLineInput +{ + public: + + MenuListSharedAddShare() :MenuOpLineInput("Add new Share") { return; } + virtual uint32_t process_lines(std::string input); + virtual uint32_t drawPage(uint32_t drawFlags, std::string &buffer); +}; From ccb43660a8ad3f9ce125ae7f522042f2783e9d52 Mon Sep 17 00:00:00 2001 From: drbob Date: Thu, 23 Aug 2012 14:04:01 +0000 Subject: [PATCH 033/222] First bits of the RPC Protobuf Service. Doesn't compile yet - this is just a check-point checkin. * Added generated protobuf code in proto/gencc * Added rpcprotopeers.h : Interface for getting/modifying peer information. * Added Stuff to .pro file. (disabled at the moment) * tweaked update times for SSH Menu, as they were too slow. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5460 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/retroshare-nogui.pro | 23 +- retroshare-nogui/src/retroshare.cc | 2 +- .../src/rpc/proto/gencc/NOTES.txt | 4 + .../src/rpc/proto/gencc/base.pb.cc | 2044 ++++++++++++++++ .../src/rpc/proto/gencc/base.pb.h | 1608 +++++++++++++ .../src/rpc/proto/gencc/peers.pb.cc | 2101 +++++++++++++++++ .../src/rpc/proto/gencc/peers.pb.h | 1427 +++++++++++ .../src/rpc/proto/rpcprotopeers.cc | 255 ++ .../src/rpc/proto/rpcprotopeers.h | 43 + 9 files changed, 7505 insertions(+), 2 deletions(-) create mode 100644 retroshare-nogui/src/rpc/proto/gencc/NOTES.txt create mode 100644 retroshare-nogui/src/rpc/proto/gencc/base.pb.cc create mode 100644 retroshare-nogui/src/rpc/proto/gencc/base.pb.h create mode 100644 retroshare-nogui/src/rpc/proto/gencc/peers.pb.cc create mode 100644 retroshare-nogui/src/rpc/proto/gencc/peers.pb.h create mode 100644 retroshare-nogui/src/rpc/proto/rpcprotopeers.cc create mode 100644 retroshare-nogui/src/rpc/proto/rpcprotopeers.h diff --git a/retroshare-nogui/src/retroshare-nogui.pro b/retroshare-nogui/src/retroshare-nogui.pro index 28621ebe0..d56e5c1e5 100644 --- a/retroshare-nogui/src/retroshare-nogui.pro +++ b/retroshare-nogui/src/retroshare-nogui.pro @@ -124,6 +124,7 @@ introserver { DEFINES *= RS_INTRO_SERVER } + sshserver { # This Requires libssh-0.5.* to compile. # Modify path below to point at it. @@ -176,9 +177,29 @@ sshserver { #SOURCES += rpc/proto/rpcecho.cc \ DEFINES *= RS_SSH_SERVER + + # Include Protobuf classes. + #CONFIG += protorpc +} + +protorpc { + # Proto Services + HEADERS += rpc/proto/rpcprotopeers.h \ + + SOURCES += rpc/proto/rpcprotopeers.cc \ + + # Generated ProtoBuf Code the RPC System + HEADERS += rpc/proto/gencc/base.pb.h \ + rpc/proto/gencc/peers.pb.h \ + + SOURCES += rpc/proto/gencc/base.pb.cc \ + rpc/proto/gencc/peers.pb.cc \ + + QMAKE_CFLAGS += -pthread + QMAKE_CXXFLAGS += -pthread + LIBS += -lprotobuf } - diff --git a/retroshare-nogui/src/retroshare.cc b/retroshare-nogui/src/retroshare.cc index b741966c6..36fd0172e 100644 --- a/retroshare-nogui/src/retroshare.cc +++ b/retroshare-nogui/src/retroshare.cc @@ -398,7 +398,7 @@ int main(int argc, char **argv) Menu *baseMenu = CreateMenuStructure(notify); MenuInterface *menuInterface = new MenuInterface(ssh, baseMenu, baseDrawFlags | MENU_DRAW_FLAGS_ECHO); ssh->setRpcSystem(menuInterface); - ssh->setSleepPeriods(0.2, 1); + ssh->setSleepPeriods(0.05, 0.5); } ssh->start(); diff --git a/retroshare-nogui/src/rpc/proto/gencc/NOTES.txt b/retroshare-nogui/src/rpc/proto/gencc/NOTES.txt new file mode 100644 index 000000000..cdd79634d --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/gencc/NOTES.txt @@ -0,0 +1,4 @@ + +The files in this directory are auto generated by protobuf's protoc. +Don't add any other files in here!. + diff --git a/retroshare-nogui/src/rpc/proto/gencc/base.pb.cc b/retroshare-nogui/src/rpc/proto/gencc/base.pb.cc new file mode 100644 index 000000000..0a2821fa2 --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/gencc/base.pb.cc @@ -0,0 +1,2044 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "base.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace rsctrl { +namespace base { + +namespace { + +const ::google::protobuf::Descriptor* Status_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Status_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* Status_StatusCode_descriptor_ = NULL; +const ::google::protobuf::Descriptor* Location_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Location_reflection_ = NULL; +const ::google::protobuf::Descriptor* Person_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Person_reflection_ = NULL; +const ::google::protobuf::Descriptor* File_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + File_reflection_ = NULL; +const ::google::protobuf::Descriptor* Dir_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Dir_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_base_2eproto() { + protobuf_AddDesc_base_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "base.proto"); + GOOGLE_CHECK(file != NULL); + Status_descriptor_ = file->message_type(0); + static const int Status_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Status, code_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Status, msg_), + }; + Status_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + Status_descriptor_, + Status::default_instance_, + Status_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Status, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Status, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(Status)); + Status_StatusCode_descriptor_ = Status_descriptor_->enum_type(0); + Location_descriptor_ = file->message_type(1); + static const int Location_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Location, ssl_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Location, location_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Location, localaddr_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Location, extaddr_), + }; + Location_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + Location_descriptor_, + Location::default_instance_, + Location_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Location, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Location, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(Location)); + Person_descriptor_ = file->message_type(2); + static const int Person_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Person, gpg_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Person, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Person, locations_), + }; + Person_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + Person_descriptor_, + Person::default_instance_, + Person_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Person, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Person, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(Person)); + File_descriptor_ = file->message_type(3); + static const int File_offsets_[5] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, hash_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, size_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, avail_), + }; + File_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + File_descriptor_, + File::default_instance_, + File_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(File)); + Dir_descriptor_ = file->message_type(4); + static const int Dir_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Dir, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Dir, path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Dir, subdirs_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Dir, files_), + }; + Dir_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + Dir_descriptor_, + Dir::default_instance_, + Dir_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Dir, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Dir, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(Dir)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_base_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Status_descriptor_, &Status::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Location_descriptor_, &Location::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Person_descriptor_, &Person::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + File_descriptor_, &File::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Dir_descriptor_, &Dir::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_base_2eproto() { + delete Status::default_instance_; + delete Status_reflection_; + delete Location::default_instance_; + delete Location_reflection_; + delete Person::default_instance_; + delete Person_reflection_; + delete File::default_instance_; + delete File_reflection_; + delete Dir::default_instance_; + delete Dir_reflection_; +} + +void protobuf_AddDesc_base_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\nbase.proto\022\013rsctrl.base\"\212\001\n\006Status\022,\n\004" + "code\030\001 \002(\0162\036.rsctrl.base.Status.StatusCo" + "de\022\013\n\003msg\030\002 \001(\t\"E\n\nStatusCode\022\n\n\006FAILED\020" + "\000\022\021\n\rINVALID_QUERY\020\001\022\013\n\007SUCCESS\020\002\022\013\n\007REA" + "DMSG\020\003\"P\n\010Location\022\016\n\006ssl_id\030\001 \002(\t\022\020\n\010lo" + "cation\030\002 \002(\t\022\021\n\tlocaladdr\030\003 \002(\t\022\017\n\007extad" + "dr\030\004 \002(\t\"P\n\006Person\022\016\n\006gpg_id\030\001 \002(\t\022\014\n\004na" + "me\030\002 \002(\t\022(\n\tlocations\030\003 \003(\0132\025.rsctrl.bas" + "e.Location\"M\n\004File\022\014\n\004name\030\001 \002(\t\022\014\n\004hash" + "\030\002 \002(\t\022\014\n\004size\030\003 \002(\003\022\014\n\004path\030\004 \001(\t\022\r\n\005av" + "ail\030\005 \001(\t\"f\n\003Dir\022\014\n\004name\030\001 \002(\t\022\014\n\004path\030\002" + " \002(\t\022!\n\007subdirs\030\003 \003(\0132\020.rsctrl.base.Dir\022" + " \n\005files\030\004 \003(\0132\021.rsctrl.base.File", 513); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "base.proto", &protobuf_RegisterTypes); + Status::default_instance_ = new Status(); + Location::default_instance_ = new Location(); + Person::default_instance_ = new Person(); + File::default_instance_ = new File(); + Dir::default_instance_ = new Dir(); + Status::default_instance_->InitAsDefaultInstance(); + Location::default_instance_->InitAsDefaultInstance(); + Person::default_instance_->InitAsDefaultInstance(); + File::default_instance_->InitAsDefaultInstance(); + Dir::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_base_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_base_2eproto { + StaticDescriptorInitializer_base_2eproto() { + protobuf_AddDesc_base_2eproto(); + } +} static_descriptor_initializer_base_2eproto_; + + +// =================================================================== + +const ::google::protobuf::EnumDescriptor* Status_StatusCode_descriptor() { + protobuf_AssignDescriptorsOnce(); + return Status_StatusCode_descriptor_; +} +bool Status_StatusCode_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + case 3: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const Status_StatusCode Status::FAILED; +const Status_StatusCode Status::INVALID_QUERY; +const Status_StatusCode Status::SUCCESS; +const Status_StatusCode Status::READMSG; +const Status_StatusCode Status::StatusCode_MIN; +const Status_StatusCode Status::StatusCode_MAX; +const int Status::StatusCode_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int Status::kCodeFieldNumber; +const int Status::kMsgFieldNumber; +#endif // !_MSC_VER + +Status::Status() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void Status::InitAsDefaultInstance() { +} + +Status::Status(const Status& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void Status::SharedCtor() { + _cached_size_ = 0; + code_ = 0; + msg_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Status::~Status() { + SharedDtor(); +} + +void Status::SharedDtor() { + if (msg_ != &::google::protobuf::internal::kEmptyString) { + delete msg_; + } + if (this != default_instance_) { + } +} + +void Status::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Status::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Status_descriptor_; +} + +const Status& Status::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_base_2eproto(); return *default_instance_; +} + +Status* Status::default_instance_ = NULL; + +Status* Status::New() const { + return new Status; +} + +void Status::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + code_ = 0; + if (has_msg()) { + if (msg_ != &::google::protobuf::internal::kEmptyString) { + msg_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool Status::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.base.Status.StatusCode code = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::rsctrl::base::Status_StatusCode_IsValid(value)) { + set_code(static_cast< ::rsctrl::base::Status_StatusCode >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_msg; + break; + } + + // optional string msg = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_msg: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_msg())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->msg().data(), this->msg().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void Status::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.base.Status.StatusCode code = 1; + if (has_code()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->code(), output); + } + + // optional string msg = 2; + if (has_msg()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->msg().data(), this->msg().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->msg(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* Status::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.base.Status.StatusCode code = 1; + if (has_code()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->code(), target); + } + + // optional string msg = 2; + if (has_msg()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->msg().data(), this->msg().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->msg(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int Status::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.base.Status.StatusCode code = 1; + if (has_code()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->code()); + } + + // optional string msg = 2; + if (has_msg()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->msg()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Status::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const Status* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Status::MergeFrom(const Status& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_code()) { + set_code(from.code()); + } + if (from.has_msg()) { + set_msg(from.msg()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void Status::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Status::CopyFrom(const Status& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Status::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void Status::Swap(Status* other) { + if (other != this) { + std::swap(code_, other->code_); + std::swap(msg_, other->msg_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata Status::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Status_descriptor_; + metadata.reflection = Status_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int Location::kSslIdFieldNumber; +const int Location::kLocationFieldNumber; +const int Location::kLocaladdrFieldNumber; +const int Location::kExtaddrFieldNumber; +#endif // !_MSC_VER + +Location::Location() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void Location::InitAsDefaultInstance() { +} + +Location::Location(const Location& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void Location::SharedCtor() { + _cached_size_ = 0; + ssl_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + location_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + localaddr_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + extaddr_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Location::~Location() { + SharedDtor(); +} + +void Location::SharedDtor() { + if (ssl_id_ != &::google::protobuf::internal::kEmptyString) { + delete ssl_id_; + } + if (location_ != &::google::protobuf::internal::kEmptyString) { + delete location_; + } + if (localaddr_ != &::google::protobuf::internal::kEmptyString) { + delete localaddr_; + } + if (extaddr_ != &::google::protobuf::internal::kEmptyString) { + delete extaddr_; + } + if (this != default_instance_) { + } +} + +void Location::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Location::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Location_descriptor_; +} + +const Location& Location::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_base_2eproto(); return *default_instance_; +} + +Location* Location::default_instance_ = NULL; + +Location* Location::New() const { + return new Location; +} + +void Location::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_ssl_id()) { + if (ssl_id_ != &::google::protobuf::internal::kEmptyString) { + ssl_id_->clear(); + } + } + if (has_location()) { + if (location_ != &::google::protobuf::internal::kEmptyString) { + location_->clear(); + } + } + if (has_localaddr()) { + if (localaddr_ != &::google::protobuf::internal::kEmptyString) { + localaddr_->clear(); + } + } + if (has_extaddr()) { + if (extaddr_ != &::google::protobuf::internal::kEmptyString) { + extaddr_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool Location::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string ssl_id = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_ssl_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->ssl_id().data(), this->ssl_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_location; + break; + } + + // required string location = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_location: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_location())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->location().data(), this->location().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_localaddr; + break; + } + + // required string localaddr = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_localaddr: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_localaddr())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->localaddr().data(), this->localaddr().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_extaddr; + break; + } + + // required string extaddr = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_extaddr: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_extaddr())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->extaddr().data(), this->extaddr().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void Location::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string ssl_id = 1; + if (has_ssl_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->ssl_id().data(), this->ssl_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->ssl_id(), output); + } + + // required string location = 2; + if (has_location()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->location().data(), this->location().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->location(), output); + } + + // required string localaddr = 3; + if (has_localaddr()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->localaddr().data(), this->localaddr().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->localaddr(), output); + } + + // required string extaddr = 4; + if (has_extaddr()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->extaddr().data(), this->extaddr().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 4, this->extaddr(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* Location::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string ssl_id = 1; + if (has_ssl_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->ssl_id().data(), this->ssl_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->ssl_id(), target); + } + + // required string location = 2; + if (has_location()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->location().data(), this->location().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->location(), target); + } + + // required string localaddr = 3; + if (has_localaddr()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->localaddr().data(), this->localaddr().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->localaddr(), target); + } + + // required string extaddr = 4; + if (has_extaddr()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->extaddr().data(), this->extaddr().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 4, this->extaddr(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int Location::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string ssl_id = 1; + if (has_ssl_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->ssl_id()); + } + + // required string location = 2; + if (has_location()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->location()); + } + + // required string localaddr = 3; + if (has_localaddr()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->localaddr()); + } + + // required string extaddr = 4; + if (has_extaddr()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->extaddr()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Location::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const Location* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Location::MergeFrom(const Location& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_ssl_id()) { + set_ssl_id(from.ssl_id()); + } + if (from.has_location()) { + set_location(from.location()); + } + if (from.has_localaddr()) { + set_localaddr(from.localaddr()); + } + if (from.has_extaddr()) { + set_extaddr(from.extaddr()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void Location::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Location::CopyFrom(const Location& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Location::IsInitialized() const { + if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false; + + return true; +} + +void Location::Swap(Location* other) { + if (other != this) { + std::swap(ssl_id_, other->ssl_id_); + std::swap(location_, other->location_); + std::swap(localaddr_, other->localaddr_); + std::swap(extaddr_, other->extaddr_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata Location::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Location_descriptor_; + metadata.reflection = Location_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int Person::kGpgIdFieldNumber; +const int Person::kNameFieldNumber; +const int Person::kLocationsFieldNumber; +#endif // !_MSC_VER + +Person::Person() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void Person::InitAsDefaultInstance() { +} + +Person::Person(const Person& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void Person::SharedCtor() { + _cached_size_ = 0; + gpg_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Person::~Person() { + SharedDtor(); +} + +void Person::SharedDtor() { + if (gpg_id_ != &::google::protobuf::internal::kEmptyString) { + delete gpg_id_; + } + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (this != default_instance_) { + } +} + +void Person::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Person::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Person_descriptor_; +} + +const Person& Person::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_base_2eproto(); return *default_instance_; +} + +Person* Person::default_instance_ = NULL; + +Person* Person::New() const { + return new Person; +} + +void Person::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_gpg_id()) { + if (gpg_id_ != &::google::protobuf::internal::kEmptyString) { + gpg_id_->clear(); + } + } + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + } + locations_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool Person::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string gpg_id = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_gpg_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->gpg_id().data(), this->gpg_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_name; + break; + } + + // required string name = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_locations; + break; + } + + // repeated .rsctrl.base.Location locations = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_locations: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_locations())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_locations; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void Person::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string gpg_id = 1; + if (has_gpg_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->gpg_id().data(), this->gpg_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->gpg_id(), output); + } + + // required string name = 2; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->name(), output); + } + + // repeated .rsctrl.base.Location locations = 3; + for (int i = 0; i < this->locations_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->locations(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* Person::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string gpg_id = 1; + if (has_gpg_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->gpg_id().data(), this->gpg_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->gpg_id(), target); + } + + // required string name = 2; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->name(), target); + } + + // repeated .rsctrl.base.Location locations = 3; + for (int i = 0; i < this->locations_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->locations(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int Person::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string gpg_id = 1; + if (has_gpg_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->gpg_id()); + } + + // required string name = 2; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + } + // repeated .rsctrl.base.Location locations = 3; + total_size += 1 * this->locations_size(); + for (int i = 0; i < this->locations_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->locations(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Person::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const Person* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Person::MergeFrom(const Person& from) { + GOOGLE_CHECK_NE(&from, this); + locations_.MergeFrom(from.locations_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_gpg_id()) { + set_gpg_id(from.gpg_id()); + } + if (from.has_name()) { + set_name(from.name()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void Person::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Person::CopyFrom(const Person& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Person::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + for (int i = 0; i < locations_size(); i++) { + if (!this->locations(i).IsInitialized()) return false; + } + return true; +} + +void Person::Swap(Person* other) { + if (other != this) { + std::swap(gpg_id_, other->gpg_id_); + std::swap(name_, other->name_); + locations_.Swap(&other->locations_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata Person::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Person_descriptor_; + metadata.reflection = Person_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int File::kNameFieldNumber; +const int File::kHashFieldNumber; +const int File::kSizeFieldNumber; +const int File::kPathFieldNumber; +const int File::kAvailFieldNumber; +#endif // !_MSC_VER + +File::File() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void File::InitAsDefaultInstance() { +} + +File::File(const File& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void File::SharedCtor() { + _cached_size_ = 0; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + hash_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + size_ = GOOGLE_LONGLONG(0); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + avail_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +File::~File() { + SharedDtor(); +} + +void File::SharedDtor() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (hash_ != &::google::protobuf::internal::kEmptyString) { + delete hash_; + } + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (avail_ != &::google::protobuf::internal::kEmptyString) { + delete avail_; + } + if (this != default_instance_) { + } +} + +void File::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* File::descriptor() { + protobuf_AssignDescriptorsOnce(); + return File_descriptor_; +} + +const File& File::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_base_2eproto(); return *default_instance_; +} + +File* File::default_instance_ = NULL; + +File* File::New() const { + return new File; +} + +void File::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + if (has_hash()) { + if (hash_ != &::google::protobuf::internal::kEmptyString) { + hash_->clear(); + } + } + size_ = GOOGLE_LONGLONG(0); + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + if (has_avail()) { + if (avail_ != &::google::protobuf::internal::kEmptyString) { + avail_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool File::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_hash; + break; + } + + // required string hash = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_hash: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_hash())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->hash().data(), this->hash().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(24)) goto parse_size; + break; + } + + // required int64 size = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_size: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &size_))); + set_has_size(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_path; + break; + } + + // optional string path = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(42)) goto parse_avail; + break; + } + + // optional string avail = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_avail: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_avail())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->avail().data(), this->avail().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void File::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); + } + + // required string hash = 2; + if (has_hash()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->hash().data(), this->hash().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->hash(), output); + } + + // required int64 size = 3; + if (has_size()) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(3, this->size(), output); + } + + // optional string path = 4; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 4, this->path(), output); + } + + // optional string avail = 5; + if (has_avail()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->avail().data(), this->avail().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 5, this->avail(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* File::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // required string hash = 2; + if (has_hash()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->hash().data(), this->hash().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->hash(), target); + } + + // required int64 size = 3; + if (has_size()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(3, this->size(), target); + } + + // optional string path = 4; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 4, this->path(), target); + } + + // optional string avail = 5; + if (has_avail()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->avail().data(), this->avail().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 5, this->avail(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int File::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string name = 1; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // required string hash = 2; + if (has_hash()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->hash()); + } + + // required int64 size = 3; + if (has_size()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->size()); + } + + // optional string path = 4; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + // optional string avail = 5; + if (has_avail()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->avail()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void File::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const File* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void File::MergeFrom(const File& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_name()) { + set_name(from.name()); + } + if (from.has_hash()) { + set_hash(from.hash()); + } + if (from.has_size()) { + set_size(from.size()); + } + if (from.has_path()) { + set_path(from.path()); + } + if (from.has_avail()) { + set_avail(from.avail()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void File::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void File::CopyFrom(const File& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool File::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void File::Swap(File* other) { + if (other != this) { + std::swap(name_, other->name_); + std::swap(hash_, other->hash_); + std::swap(size_, other->size_); + std::swap(path_, other->path_); + std::swap(avail_, other->avail_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata File::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = File_descriptor_; + metadata.reflection = File_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int Dir::kNameFieldNumber; +const int Dir::kPathFieldNumber; +const int Dir::kSubdirsFieldNumber; +const int Dir::kFilesFieldNumber; +#endif // !_MSC_VER + +Dir::Dir() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void Dir::InitAsDefaultInstance() { +} + +Dir::Dir(const Dir& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void Dir::SharedCtor() { + _cached_size_ = 0; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Dir::~Dir() { + SharedDtor(); +} + +void Dir::SharedDtor() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (this != default_instance_) { + } +} + +void Dir::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Dir::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Dir_descriptor_; +} + +const Dir& Dir::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_base_2eproto(); return *default_instance_; +} + +Dir* Dir::default_instance_ = NULL; + +Dir* Dir::New() const { + return new Dir; +} + +void Dir::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + } + subdirs_.Clear(); + files_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool Dir::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_path; + break; + } + + // required string path = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_subdirs; + break; + } + + // repeated .rsctrl.base.Dir subdirs = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_subdirs: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_subdirs())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_subdirs; + if (input->ExpectTag(34)) goto parse_files; + break; + } + + // repeated .rsctrl.base.File files = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_files: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_files())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_files; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void Dir::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->name(), output); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->path(), output); + } + + // repeated .rsctrl.base.Dir subdirs = 3; + for (int i = 0; i < this->subdirs_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->subdirs(i), output); + } + + // repeated .rsctrl.base.File files = 4; + for (int i = 0; i < this->files_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 4, this->files(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* Dir::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string name = 1; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // required string path = 2; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->path(), target); + } + + // repeated .rsctrl.base.Dir subdirs = 3; + for (int i = 0; i < this->subdirs_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->subdirs(i), target); + } + + // repeated .rsctrl.base.File files = 4; + for (int i = 0; i < this->files_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 4, this->files(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int Dir::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string name = 1; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // required string path = 2; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + } + // repeated .rsctrl.base.Dir subdirs = 3; + total_size += 1 * this->subdirs_size(); + for (int i = 0; i < this->subdirs_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->subdirs(i)); + } + + // repeated .rsctrl.base.File files = 4; + total_size += 1 * this->files_size(); + for (int i = 0; i < this->files_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->files(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Dir::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const Dir* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Dir::MergeFrom(const Dir& from) { + GOOGLE_CHECK_NE(&from, this); + subdirs_.MergeFrom(from.subdirs_); + files_.MergeFrom(from.files_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_name()) { + set_name(from.name()); + } + if (from.has_path()) { + set_path(from.path()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void Dir::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Dir::CopyFrom(const Dir& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Dir::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + for (int i = 0; i < subdirs_size(); i++) { + if (!this->subdirs(i).IsInitialized()) return false; + } + for (int i = 0; i < files_size(); i++) { + if (!this->files(i).IsInitialized()) return false; + } + return true; +} + +void Dir::Swap(Dir* other) { + if (other != this) { + std::swap(name_, other->name_); + std::swap(path_, other->path_); + subdirs_.Swap(&other->subdirs_); + files_.Swap(&other->files_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata Dir::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Dir_descriptor_; + metadata.reflection = Dir_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace base +} // namespace rsctrl + +// @@protoc_insertion_point(global_scope) diff --git a/retroshare-nogui/src/rpc/proto/gencc/base.pb.h b/retroshare-nogui/src/rpc/proto/gencc/base.pb.h new file mode 100644 index 000000000..d1819b91b --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/gencc/base.pb.h @@ -0,0 +1,1608 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: base.proto + +#ifndef PROTOBUF_base_2eproto__INCLUDED +#define PROTOBUF_base_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2004000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2004001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace rsctrl { +namespace base { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_base_2eproto(); +void protobuf_AssignDesc_base_2eproto(); +void protobuf_ShutdownFile_base_2eproto(); + +class Status; +class Location; +class Person; +class File; +class Dir; + +enum Status_StatusCode { + Status_StatusCode_FAILED = 0, + Status_StatusCode_INVALID_QUERY = 1, + Status_StatusCode_SUCCESS = 2, + Status_StatusCode_READMSG = 3 +}; +bool Status_StatusCode_IsValid(int value); +const Status_StatusCode Status_StatusCode_StatusCode_MIN = Status_StatusCode_FAILED; +const Status_StatusCode Status_StatusCode_StatusCode_MAX = Status_StatusCode_READMSG; +const int Status_StatusCode_StatusCode_ARRAYSIZE = Status_StatusCode_StatusCode_MAX + 1; + +const ::google::protobuf::EnumDescriptor* Status_StatusCode_descriptor(); +inline const ::std::string& Status_StatusCode_Name(Status_StatusCode value) { + return ::google::protobuf::internal::NameOfEnum( + Status_StatusCode_descriptor(), value); +} +inline bool Status_StatusCode_Parse( + const ::std::string& name, Status_StatusCode* value) { + return ::google::protobuf::internal::ParseNamedEnum( + Status_StatusCode_descriptor(), name, value); +} +// =================================================================== + +class Status : public ::google::protobuf::Message { + public: + Status(); + virtual ~Status(); + + Status(const Status& from); + + inline Status& operator=(const Status& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Status& default_instance(); + + void Swap(Status* other); + + // implements Message ---------------------------------------------- + + Status* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Status& from); + void MergeFrom(const Status& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef Status_StatusCode StatusCode; + static const StatusCode FAILED = Status_StatusCode_FAILED; + static const StatusCode INVALID_QUERY = Status_StatusCode_INVALID_QUERY; + static const StatusCode SUCCESS = Status_StatusCode_SUCCESS; + static const StatusCode READMSG = Status_StatusCode_READMSG; + static inline bool StatusCode_IsValid(int value) { + return Status_StatusCode_IsValid(value); + } + static const StatusCode StatusCode_MIN = + Status_StatusCode_StatusCode_MIN; + static const StatusCode StatusCode_MAX = + Status_StatusCode_StatusCode_MAX; + static const int StatusCode_ARRAYSIZE = + Status_StatusCode_StatusCode_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + StatusCode_descriptor() { + return Status_StatusCode_descriptor(); + } + static inline const ::std::string& StatusCode_Name(StatusCode value) { + return Status_StatusCode_Name(value); + } + static inline bool StatusCode_Parse(const ::std::string& name, + StatusCode* value) { + return Status_StatusCode_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // required .rsctrl.base.Status.StatusCode code = 1; + inline bool has_code() const; + inline void clear_code(); + static const int kCodeFieldNumber = 1; + inline ::rsctrl::base::Status_StatusCode code() const; + inline void set_code(::rsctrl::base::Status_StatusCode value); + + // optional string msg = 2; + inline bool has_msg() const; + inline void clear_msg(); + static const int kMsgFieldNumber = 2; + inline const ::std::string& msg() const; + inline void set_msg(const ::std::string& value); + inline void set_msg(const char* value); + inline void set_msg(const char* value, size_t size); + inline ::std::string* mutable_msg(); + inline ::std::string* release_msg(); + + // @@protoc_insertion_point(class_scope:rsctrl.base.Status) + private: + inline void set_has_code(); + inline void clear_has_code(); + inline void set_has_msg(); + inline void clear_has_msg(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* msg_; + int code_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_base_2eproto(); + friend void protobuf_AssignDesc_base_2eproto(); + friend void protobuf_ShutdownFile_base_2eproto(); + + void InitAsDefaultInstance(); + static Status* default_instance_; +}; +// ------------------------------------------------------------------- + +class Location : public ::google::protobuf::Message { + public: + Location(); + virtual ~Location(); + + Location(const Location& from); + + inline Location& operator=(const Location& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Location& default_instance(); + + void Swap(Location* other); + + // implements Message ---------------------------------------------- + + Location* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Location& from); + void MergeFrom(const Location& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string ssl_id = 1; + inline bool has_ssl_id() const; + inline void clear_ssl_id(); + static const int kSslIdFieldNumber = 1; + inline const ::std::string& ssl_id() const; + inline void set_ssl_id(const ::std::string& value); + inline void set_ssl_id(const char* value); + inline void set_ssl_id(const char* value, size_t size); + inline ::std::string* mutable_ssl_id(); + inline ::std::string* release_ssl_id(); + + // required string location = 2; + inline bool has_location() const; + inline void clear_location(); + static const int kLocationFieldNumber = 2; + inline const ::std::string& location() const; + inline void set_location(const ::std::string& value); + inline void set_location(const char* value); + inline void set_location(const char* value, size_t size); + inline ::std::string* mutable_location(); + inline ::std::string* release_location(); + + // required string localaddr = 3; + inline bool has_localaddr() const; + inline void clear_localaddr(); + static const int kLocaladdrFieldNumber = 3; + inline const ::std::string& localaddr() const; + inline void set_localaddr(const ::std::string& value); + inline void set_localaddr(const char* value); + inline void set_localaddr(const char* value, size_t size); + inline ::std::string* mutable_localaddr(); + inline ::std::string* release_localaddr(); + + // required string extaddr = 4; + inline bool has_extaddr() const; + inline void clear_extaddr(); + static const int kExtaddrFieldNumber = 4; + inline const ::std::string& extaddr() const; + inline void set_extaddr(const ::std::string& value); + inline void set_extaddr(const char* value); + inline void set_extaddr(const char* value, size_t size); + inline ::std::string* mutable_extaddr(); + inline ::std::string* release_extaddr(); + + // @@protoc_insertion_point(class_scope:rsctrl.base.Location) + private: + inline void set_has_ssl_id(); + inline void clear_has_ssl_id(); + inline void set_has_location(); + inline void clear_has_location(); + inline void set_has_localaddr(); + inline void clear_has_localaddr(); + inline void set_has_extaddr(); + inline void clear_has_extaddr(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* ssl_id_; + ::std::string* location_; + ::std::string* localaddr_; + ::std::string* extaddr_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_base_2eproto(); + friend void protobuf_AssignDesc_base_2eproto(); + friend void protobuf_ShutdownFile_base_2eproto(); + + void InitAsDefaultInstance(); + static Location* default_instance_; +}; +// ------------------------------------------------------------------- + +class Person : public ::google::protobuf::Message { + public: + Person(); + virtual ~Person(); + + Person(const Person& from); + + inline Person& operator=(const Person& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Person& default_instance(); + + void Swap(Person* other); + + // implements Message ---------------------------------------------- + + Person* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Person& from); + void MergeFrom(const Person& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string gpg_id = 1; + inline bool has_gpg_id() const; + inline void clear_gpg_id(); + static const int kGpgIdFieldNumber = 1; + inline const ::std::string& gpg_id() const; + inline void set_gpg_id(const ::std::string& value); + inline void set_gpg_id(const char* value); + inline void set_gpg_id(const char* value, size_t size); + inline ::std::string* mutable_gpg_id(); + inline ::std::string* release_gpg_id(); + + // required string name = 2; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 2; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + + // repeated .rsctrl.base.Location locations = 3; + inline int locations_size() const; + inline void clear_locations(); + static const int kLocationsFieldNumber = 3; + inline const ::rsctrl::base::Location& locations(int index) const; + inline ::rsctrl::base::Location* mutable_locations(int index); + inline ::rsctrl::base::Location* add_locations(); + inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Location >& + locations() const; + inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Location >* + mutable_locations(); + + // @@protoc_insertion_point(class_scope:rsctrl.base.Person) + private: + inline void set_has_gpg_id(); + inline void clear_has_gpg_id(); + inline void set_has_name(); + inline void clear_has_name(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* gpg_id_; + ::std::string* name_; + ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Location > locations_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_base_2eproto(); + friend void protobuf_AssignDesc_base_2eproto(); + friend void protobuf_ShutdownFile_base_2eproto(); + + void InitAsDefaultInstance(); + static Person* default_instance_; +}; +// ------------------------------------------------------------------- + +class File : public ::google::protobuf::Message { + public: + File(); + virtual ~File(); + + File(const File& from); + + inline File& operator=(const File& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const File& default_instance(); + + void Swap(File* other); + + // implements Message ---------------------------------------------- + + File* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const File& from); + void MergeFrom(const File& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string name = 1; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 1; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + + // required string hash = 2; + inline bool has_hash() const; + inline void clear_hash(); + static const int kHashFieldNumber = 2; + inline const ::std::string& hash() const; + inline void set_hash(const ::std::string& value); + inline void set_hash(const char* value); + inline void set_hash(const char* value, size_t size); + inline ::std::string* mutable_hash(); + inline ::std::string* release_hash(); + + // required int64 size = 3; + inline bool has_size() const; + inline void clear_size(); + static const int kSizeFieldNumber = 3; + inline ::google::protobuf::int64 size() const; + inline void set_size(::google::protobuf::int64 value); + + // optional string path = 4; + inline bool has_path() const; + inline void clear_path(); + static const int kPathFieldNumber = 4; + inline const ::std::string& path() const; + inline void set_path(const ::std::string& value); + inline void set_path(const char* value); + inline void set_path(const char* value, size_t size); + inline ::std::string* mutable_path(); + inline ::std::string* release_path(); + + // optional string avail = 5; + inline bool has_avail() const; + inline void clear_avail(); + static const int kAvailFieldNumber = 5; + inline const ::std::string& avail() const; + inline void set_avail(const ::std::string& value); + inline void set_avail(const char* value); + inline void set_avail(const char* value, size_t size); + inline ::std::string* mutable_avail(); + inline ::std::string* release_avail(); + + // @@protoc_insertion_point(class_scope:rsctrl.base.File) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_hash(); + inline void clear_has_hash(); + inline void set_has_size(); + inline void clear_has_size(); + inline void set_has_path(); + inline void clear_has_path(); + inline void set_has_avail(); + inline void clear_has_avail(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* name_; + ::std::string* hash_; + ::google::protobuf::int64 size_; + ::std::string* path_; + ::std::string* avail_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(5 + 31) / 32]; + + friend void protobuf_AddDesc_base_2eproto(); + friend void protobuf_AssignDesc_base_2eproto(); + friend void protobuf_ShutdownFile_base_2eproto(); + + void InitAsDefaultInstance(); + static File* default_instance_; +}; +// ------------------------------------------------------------------- + +class Dir : public ::google::protobuf::Message { + public: + Dir(); + virtual ~Dir(); + + Dir(const Dir& from); + + inline Dir& operator=(const Dir& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Dir& default_instance(); + + void Swap(Dir* other); + + // implements Message ---------------------------------------------- + + Dir* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Dir& from); + void MergeFrom(const Dir& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string name = 1; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 1; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + + // required string path = 2; + inline bool has_path() const; + inline void clear_path(); + static const int kPathFieldNumber = 2; + inline const ::std::string& path() const; + inline void set_path(const ::std::string& value); + inline void set_path(const char* value); + inline void set_path(const char* value, size_t size); + inline ::std::string* mutable_path(); + inline ::std::string* release_path(); + + // repeated .rsctrl.base.Dir subdirs = 3; + inline int subdirs_size() const; + inline void clear_subdirs(); + static const int kSubdirsFieldNumber = 3; + inline const ::rsctrl::base::Dir& subdirs(int index) const; + inline ::rsctrl::base::Dir* mutable_subdirs(int index); + inline ::rsctrl::base::Dir* add_subdirs(); + inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Dir >& + subdirs() const; + inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Dir >* + mutable_subdirs(); + + // repeated .rsctrl.base.File files = 4; + inline int files_size() const; + inline void clear_files(); + static const int kFilesFieldNumber = 4; + inline const ::rsctrl::base::File& files(int index) const; + inline ::rsctrl::base::File* mutable_files(int index); + inline ::rsctrl::base::File* add_files(); + inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::File >& + files() const; + inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::File >* + mutable_files(); + + // @@protoc_insertion_point(class_scope:rsctrl.base.Dir) + private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_path(); + inline void clear_has_path(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* name_; + ::std::string* path_; + ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Dir > subdirs_; + ::google::protobuf::RepeatedPtrField< ::rsctrl::base::File > files_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_base_2eproto(); + friend void protobuf_AssignDesc_base_2eproto(); + friend void protobuf_ShutdownFile_base_2eproto(); + + void InitAsDefaultInstance(); + static Dir* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// Status + +// required .rsctrl.base.Status.StatusCode code = 1; +inline bool Status::has_code() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void Status::set_has_code() { + _has_bits_[0] |= 0x00000001u; +} +inline void Status::clear_has_code() { + _has_bits_[0] &= ~0x00000001u; +} +inline void Status::clear_code() { + code_ = 0; + clear_has_code(); +} +inline ::rsctrl::base::Status_StatusCode Status::code() const { + return static_cast< ::rsctrl::base::Status_StatusCode >(code_); +} +inline void Status::set_code(::rsctrl::base::Status_StatusCode value) { + GOOGLE_DCHECK(::rsctrl::base::Status_StatusCode_IsValid(value)); + set_has_code(); + code_ = value; +} + +// optional string msg = 2; +inline bool Status::has_msg() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void Status::set_has_msg() { + _has_bits_[0] |= 0x00000002u; +} +inline void Status::clear_has_msg() { + _has_bits_[0] &= ~0x00000002u; +} +inline void Status::clear_msg() { + if (msg_ != &::google::protobuf::internal::kEmptyString) { + msg_->clear(); + } + clear_has_msg(); +} +inline const ::std::string& Status::msg() const { + return *msg_; +} +inline void Status::set_msg(const ::std::string& value) { + set_has_msg(); + if (msg_ == &::google::protobuf::internal::kEmptyString) { + msg_ = new ::std::string; + } + msg_->assign(value); +} +inline void Status::set_msg(const char* value) { + set_has_msg(); + if (msg_ == &::google::protobuf::internal::kEmptyString) { + msg_ = new ::std::string; + } + msg_->assign(value); +} +inline void Status::set_msg(const char* value, size_t size) { + set_has_msg(); + if (msg_ == &::google::protobuf::internal::kEmptyString) { + msg_ = new ::std::string; + } + msg_->assign(reinterpret_cast(value), size); +} +inline ::std::string* Status::mutable_msg() { + set_has_msg(); + if (msg_ == &::google::protobuf::internal::kEmptyString) { + msg_ = new ::std::string; + } + return msg_; +} +inline ::std::string* Status::release_msg() { + clear_has_msg(); + if (msg_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = msg_; + msg_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// ------------------------------------------------------------------- + +// Location + +// required string ssl_id = 1; +inline bool Location::has_ssl_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void Location::set_has_ssl_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void Location::clear_has_ssl_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void Location::clear_ssl_id() { + if (ssl_id_ != &::google::protobuf::internal::kEmptyString) { + ssl_id_->clear(); + } + clear_has_ssl_id(); +} +inline const ::std::string& Location::ssl_id() const { + return *ssl_id_; +} +inline void Location::set_ssl_id(const ::std::string& value) { + set_has_ssl_id(); + if (ssl_id_ == &::google::protobuf::internal::kEmptyString) { + ssl_id_ = new ::std::string; + } + ssl_id_->assign(value); +} +inline void Location::set_ssl_id(const char* value) { + set_has_ssl_id(); + if (ssl_id_ == &::google::protobuf::internal::kEmptyString) { + ssl_id_ = new ::std::string; + } + ssl_id_->assign(value); +} +inline void Location::set_ssl_id(const char* value, size_t size) { + set_has_ssl_id(); + if (ssl_id_ == &::google::protobuf::internal::kEmptyString) { + ssl_id_ = new ::std::string; + } + ssl_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* Location::mutable_ssl_id() { + set_has_ssl_id(); + if (ssl_id_ == &::google::protobuf::internal::kEmptyString) { + ssl_id_ = new ::std::string; + } + return ssl_id_; +} +inline ::std::string* Location::release_ssl_id() { + clear_has_ssl_id(); + if (ssl_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = ssl_id_; + ssl_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// required string location = 2; +inline bool Location::has_location() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void Location::set_has_location() { + _has_bits_[0] |= 0x00000002u; +} +inline void Location::clear_has_location() { + _has_bits_[0] &= ~0x00000002u; +} +inline void Location::clear_location() { + if (location_ != &::google::protobuf::internal::kEmptyString) { + location_->clear(); + } + clear_has_location(); +} +inline const ::std::string& Location::location() const { + return *location_; +} +inline void Location::set_location(const ::std::string& value) { + set_has_location(); + if (location_ == &::google::protobuf::internal::kEmptyString) { + location_ = new ::std::string; + } + location_->assign(value); +} +inline void Location::set_location(const char* value) { + set_has_location(); + if (location_ == &::google::protobuf::internal::kEmptyString) { + location_ = new ::std::string; + } + location_->assign(value); +} +inline void Location::set_location(const char* value, size_t size) { + set_has_location(); + if (location_ == &::google::protobuf::internal::kEmptyString) { + location_ = new ::std::string; + } + location_->assign(reinterpret_cast(value), size); +} +inline ::std::string* Location::mutable_location() { + set_has_location(); + if (location_ == &::google::protobuf::internal::kEmptyString) { + location_ = new ::std::string; + } + return location_; +} +inline ::std::string* Location::release_location() { + clear_has_location(); + if (location_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = location_; + location_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// required string localaddr = 3; +inline bool Location::has_localaddr() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void Location::set_has_localaddr() { + _has_bits_[0] |= 0x00000004u; +} +inline void Location::clear_has_localaddr() { + _has_bits_[0] &= ~0x00000004u; +} +inline void Location::clear_localaddr() { + if (localaddr_ != &::google::protobuf::internal::kEmptyString) { + localaddr_->clear(); + } + clear_has_localaddr(); +} +inline const ::std::string& Location::localaddr() const { + return *localaddr_; +} +inline void Location::set_localaddr(const ::std::string& value) { + set_has_localaddr(); + if (localaddr_ == &::google::protobuf::internal::kEmptyString) { + localaddr_ = new ::std::string; + } + localaddr_->assign(value); +} +inline void Location::set_localaddr(const char* value) { + set_has_localaddr(); + if (localaddr_ == &::google::protobuf::internal::kEmptyString) { + localaddr_ = new ::std::string; + } + localaddr_->assign(value); +} +inline void Location::set_localaddr(const char* value, size_t size) { + set_has_localaddr(); + if (localaddr_ == &::google::protobuf::internal::kEmptyString) { + localaddr_ = new ::std::string; + } + localaddr_->assign(reinterpret_cast(value), size); +} +inline ::std::string* Location::mutable_localaddr() { + set_has_localaddr(); + if (localaddr_ == &::google::protobuf::internal::kEmptyString) { + localaddr_ = new ::std::string; + } + return localaddr_; +} +inline ::std::string* Location::release_localaddr() { + clear_has_localaddr(); + if (localaddr_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = localaddr_; + localaddr_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// required string extaddr = 4; +inline bool Location::has_extaddr() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void Location::set_has_extaddr() { + _has_bits_[0] |= 0x00000008u; +} +inline void Location::clear_has_extaddr() { + _has_bits_[0] &= ~0x00000008u; +} +inline void Location::clear_extaddr() { + if (extaddr_ != &::google::protobuf::internal::kEmptyString) { + extaddr_->clear(); + } + clear_has_extaddr(); +} +inline const ::std::string& Location::extaddr() const { + return *extaddr_; +} +inline void Location::set_extaddr(const ::std::string& value) { + set_has_extaddr(); + if (extaddr_ == &::google::protobuf::internal::kEmptyString) { + extaddr_ = new ::std::string; + } + extaddr_->assign(value); +} +inline void Location::set_extaddr(const char* value) { + set_has_extaddr(); + if (extaddr_ == &::google::protobuf::internal::kEmptyString) { + extaddr_ = new ::std::string; + } + extaddr_->assign(value); +} +inline void Location::set_extaddr(const char* value, size_t size) { + set_has_extaddr(); + if (extaddr_ == &::google::protobuf::internal::kEmptyString) { + extaddr_ = new ::std::string; + } + extaddr_->assign(reinterpret_cast(value), size); +} +inline ::std::string* Location::mutable_extaddr() { + set_has_extaddr(); + if (extaddr_ == &::google::protobuf::internal::kEmptyString) { + extaddr_ = new ::std::string; + } + return extaddr_; +} +inline ::std::string* Location::release_extaddr() { + clear_has_extaddr(); + if (extaddr_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = extaddr_; + extaddr_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// ------------------------------------------------------------------- + +// Person + +// required string gpg_id = 1; +inline bool Person::has_gpg_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void Person::set_has_gpg_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void Person::clear_has_gpg_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void Person::clear_gpg_id() { + if (gpg_id_ != &::google::protobuf::internal::kEmptyString) { + gpg_id_->clear(); + } + clear_has_gpg_id(); +} +inline const ::std::string& Person::gpg_id() const { + return *gpg_id_; +} +inline void Person::set_gpg_id(const ::std::string& value) { + set_has_gpg_id(); + if (gpg_id_ == &::google::protobuf::internal::kEmptyString) { + gpg_id_ = new ::std::string; + } + gpg_id_->assign(value); +} +inline void Person::set_gpg_id(const char* value) { + set_has_gpg_id(); + if (gpg_id_ == &::google::protobuf::internal::kEmptyString) { + gpg_id_ = new ::std::string; + } + gpg_id_->assign(value); +} +inline void Person::set_gpg_id(const char* value, size_t size) { + set_has_gpg_id(); + if (gpg_id_ == &::google::protobuf::internal::kEmptyString) { + gpg_id_ = new ::std::string; + } + gpg_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* Person::mutable_gpg_id() { + set_has_gpg_id(); + if (gpg_id_ == &::google::protobuf::internal::kEmptyString) { + gpg_id_ = new ::std::string; + } + return gpg_id_; +} +inline ::std::string* Person::release_gpg_id() { + clear_has_gpg_id(); + if (gpg_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = gpg_id_; + gpg_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// required string name = 2; +inline bool Person::has_name() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void Person::set_has_name() { + _has_bits_[0] |= 0x00000002u; +} +inline void Person::clear_has_name() { + _has_bits_[0] &= ~0x00000002u; +} +inline void Person::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& Person::name() const { + return *name_; +} +inline void Person::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void Person::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void Person::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* Person::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* Person::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// repeated .rsctrl.base.Location locations = 3; +inline int Person::locations_size() const { + return locations_.size(); +} +inline void Person::clear_locations() { + locations_.Clear(); +} +inline const ::rsctrl::base::Location& Person::locations(int index) const { + return locations_.Get(index); +} +inline ::rsctrl::base::Location* Person::mutable_locations(int index) { + return locations_.Mutable(index); +} +inline ::rsctrl::base::Location* Person::add_locations() { + return locations_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Location >& +Person::locations() const { + return locations_; +} +inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Location >* +Person::mutable_locations() { + return &locations_; +} + +// ------------------------------------------------------------------- + +// File + +// required string name = 1; +inline bool File::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void File::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void File::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void File::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& File::name() const { + return *name_; +} +inline void File::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void File::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void File::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* File::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* File::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// required string hash = 2; +inline bool File::has_hash() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void File::set_has_hash() { + _has_bits_[0] |= 0x00000002u; +} +inline void File::clear_has_hash() { + _has_bits_[0] &= ~0x00000002u; +} +inline void File::clear_hash() { + if (hash_ != &::google::protobuf::internal::kEmptyString) { + hash_->clear(); + } + clear_has_hash(); +} +inline const ::std::string& File::hash() const { + return *hash_; +} +inline void File::set_hash(const ::std::string& value) { + set_has_hash(); + if (hash_ == &::google::protobuf::internal::kEmptyString) { + hash_ = new ::std::string; + } + hash_->assign(value); +} +inline void File::set_hash(const char* value) { + set_has_hash(); + if (hash_ == &::google::protobuf::internal::kEmptyString) { + hash_ = new ::std::string; + } + hash_->assign(value); +} +inline void File::set_hash(const char* value, size_t size) { + set_has_hash(); + if (hash_ == &::google::protobuf::internal::kEmptyString) { + hash_ = new ::std::string; + } + hash_->assign(reinterpret_cast(value), size); +} +inline ::std::string* File::mutable_hash() { + set_has_hash(); + if (hash_ == &::google::protobuf::internal::kEmptyString) { + hash_ = new ::std::string; + } + return hash_; +} +inline ::std::string* File::release_hash() { + clear_has_hash(); + if (hash_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = hash_; + hash_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// required int64 size = 3; +inline bool File::has_size() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void File::set_has_size() { + _has_bits_[0] |= 0x00000004u; +} +inline void File::clear_has_size() { + _has_bits_[0] &= ~0x00000004u; +} +inline void File::clear_size() { + size_ = GOOGLE_LONGLONG(0); + clear_has_size(); +} +inline ::google::protobuf::int64 File::size() const { + return size_; +} +inline void File::set_size(::google::protobuf::int64 value) { + set_has_size(); + size_ = value; +} + +// optional string path = 4; +inline bool File::has_path() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void File::set_has_path() { + _has_bits_[0] |= 0x00000008u; +} +inline void File::clear_has_path() { + _has_bits_[0] &= ~0x00000008u; +} +inline void File::clear_path() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + clear_has_path(); +} +inline const ::std::string& File::path() const { + return *path_; +} +inline void File::set_path(const ::std::string& value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void File::set_path(const char* value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void File::set_path(const char* value, size_t size) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* File::mutable_path() { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + return path_; +} +inline ::std::string* File::release_path() { + clear_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = path_; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// optional string avail = 5; +inline bool File::has_avail() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void File::set_has_avail() { + _has_bits_[0] |= 0x00000010u; +} +inline void File::clear_has_avail() { + _has_bits_[0] &= ~0x00000010u; +} +inline void File::clear_avail() { + if (avail_ != &::google::protobuf::internal::kEmptyString) { + avail_->clear(); + } + clear_has_avail(); +} +inline const ::std::string& File::avail() const { + return *avail_; +} +inline void File::set_avail(const ::std::string& value) { + set_has_avail(); + if (avail_ == &::google::protobuf::internal::kEmptyString) { + avail_ = new ::std::string; + } + avail_->assign(value); +} +inline void File::set_avail(const char* value) { + set_has_avail(); + if (avail_ == &::google::protobuf::internal::kEmptyString) { + avail_ = new ::std::string; + } + avail_->assign(value); +} +inline void File::set_avail(const char* value, size_t size) { + set_has_avail(); + if (avail_ == &::google::protobuf::internal::kEmptyString) { + avail_ = new ::std::string; + } + avail_->assign(reinterpret_cast(value), size); +} +inline ::std::string* File::mutable_avail() { + set_has_avail(); + if (avail_ == &::google::protobuf::internal::kEmptyString) { + avail_ = new ::std::string; + } + return avail_; +} +inline ::std::string* File::release_avail() { + clear_has_avail(); + if (avail_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = avail_; + avail_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// ------------------------------------------------------------------- + +// Dir + +// required string name = 1; +inline bool Dir::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void Dir::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void Dir::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void Dir::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& Dir::name() const { + return *name_; +} +inline void Dir::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void Dir::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void Dir::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* Dir::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* Dir::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// required string path = 2; +inline bool Dir::has_path() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void Dir::set_has_path() { + _has_bits_[0] |= 0x00000002u; +} +inline void Dir::clear_has_path() { + _has_bits_[0] &= ~0x00000002u; +} +inline void Dir::clear_path() { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + clear_has_path(); +} +inline const ::std::string& Dir::path() const { + return *path_; +} +inline void Dir::set_path(const ::std::string& value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void Dir::set_path(const char* value) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(value); +} +inline void Dir::set_path(const char* value, size_t size) { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + path_->assign(reinterpret_cast(value), size); +} +inline ::std::string* Dir::mutable_path() { + set_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + path_ = new ::std::string; + } + return path_; +} +inline ::std::string* Dir::release_path() { + clear_has_path(); + if (path_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = path_; + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// repeated .rsctrl.base.Dir subdirs = 3; +inline int Dir::subdirs_size() const { + return subdirs_.size(); +} +inline void Dir::clear_subdirs() { + subdirs_.Clear(); +} +inline const ::rsctrl::base::Dir& Dir::subdirs(int index) const { + return subdirs_.Get(index); +} +inline ::rsctrl::base::Dir* Dir::mutable_subdirs(int index) { + return subdirs_.Mutable(index); +} +inline ::rsctrl::base::Dir* Dir::add_subdirs() { + return subdirs_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Dir >& +Dir::subdirs() const { + return subdirs_; +} +inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Dir >* +Dir::mutable_subdirs() { + return &subdirs_; +} + +// repeated .rsctrl.base.File files = 4; +inline int Dir::files_size() const { + return files_.size(); +} +inline void Dir::clear_files() { + files_.Clear(); +} +inline const ::rsctrl::base::File& Dir::files(int index) const { + return files_.Get(index); +} +inline ::rsctrl::base::File* Dir::mutable_files(int index) { + return files_.Mutable(index); +} +inline ::rsctrl::base::File* Dir::add_files() { + return files_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::File >& +Dir::files() const { + return files_; +} +inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::File >* +Dir::mutable_files() { + return &files_; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace base +} // namespace rsctrl + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::base::Status_StatusCode>() { + return ::rsctrl::base::Status_StatusCode_descriptor(); +} + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_base_2eproto__INCLUDED diff --git a/retroshare-nogui/src/rpc/proto/gencc/peers.pb.cc b/retroshare-nogui/src/rpc/proto/gencc/peers.pb.cc new file mode 100644 index 000000000..880cc50e4 --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/gencc/peers.pb.cc @@ -0,0 +1,2101 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "peers.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace rsctrl { +namespace peers { + +namespace { + +const ::google::protobuf::Descriptor* RequestPeers_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestPeers_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* RequestPeers_SetOption_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* RequestPeers_InfoOption_descriptor_ = NULL; +const ::google::protobuf::Descriptor* ResponsePeerList_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ResponsePeerList_reflection_ = NULL; +const ::google::protobuf::Descriptor* RequestAddPeer_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestAddPeer_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* RequestAddPeer_AddCmd_descriptor_ = NULL; +const ::google::protobuf::Descriptor* ResponseAddPeer_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ResponseAddPeer_reflection_ = NULL; +const ::google::protobuf::Descriptor* RequestModifyPeer_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestModifyPeer_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* RequestModifyPeer_ModCmd_descriptor_ = NULL; +const ::google::protobuf::Descriptor* ResponseModifyPeer_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ResponseModifyPeer_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* ExtensionId_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* PackageId_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_peers_2eproto() { + protobuf_AddDesc_peers_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "peers.proto"); + GOOGLE_CHECK(file != NULL); + RequestPeers_descriptor_ = file->message_type(0); + static const int RequestPeers_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestPeers, set_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestPeers, info_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestPeers, gpg_ids_), + }; + RequestPeers_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestPeers_descriptor_, + RequestPeers::default_instance_, + RequestPeers_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestPeers, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestPeers, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestPeers)); + RequestPeers_SetOption_descriptor_ = RequestPeers_descriptor_->enum_type(0); + RequestPeers_InfoOption_descriptor_ = RequestPeers_descriptor_->enum_type(1); + ResponsePeerList_descriptor_ = file->message_type(1); + static const int ResponsePeerList_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponsePeerList, status_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponsePeerList, peers_), + }; + ResponsePeerList_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ResponsePeerList_descriptor_, + ResponsePeerList::default_instance_, + ResponsePeerList_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponsePeerList, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponsePeerList, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ResponsePeerList)); + RequestAddPeer_descriptor_ = file->message_type(2); + static const int RequestAddPeer_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestAddPeer, gpg_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestAddPeer, cmd_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestAddPeer, cert_), + }; + RequestAddPeer_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestAddPeer_descriptor_, + RequestAddPeer::default_instance_, + RequestAddPeer_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestAddPeer, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestAddPeer, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestAddPeer)); + RequestAddPeer_AddCmd_descriptor_ = RequestAddPeer_descriptor_->enum_type(0); + ResponseAddPeer_descriptor_ = file->message_type(3); + static const int ResponseAddPeer_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseAddPeer, status_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseAddPeer, peers_), + }; + ResponseAddPeer_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ResponseAddPeer_descriptor_, + ResponseAddPeer::default_instance_, + ResponseAddPeer_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseAddPeer, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseAddPeer, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ResponseAddPeer)); + RequestModifyPeer_descriptor_ = file->message_type(4); + static const int RequestModifyPeer_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestModifyPeer, cmd_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestModifyPeer, peers_), + }; + RequestModifyPeer_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestModifyPeer_descriptor_, + RequestModifyPeer::default_instance_, + RequestModifyPeer_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestModifyPeer, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestModifyPeer, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestModifyPeer)); + RequestModifyPeer_ModCmd_descriptor_ = RequestModifyPeer_descriptor_->enum_type(0); + ResponseModifyPeer_descriptor_ = file->message_type(5); + static const int ResponseModifyPeer_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseModifyPeer, status_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseModifyPeer, peers_), + }; + ResponseModifyPeer_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ResponseModifyPeer_descriptor_, + ResponseModifyPeer::default_instance_, + ResponseModifyPeer_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseModifyPeer, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseModifyPeer, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ResponseModifyPeer)); + ExtensionId_descriptor_ = file->enum_type(0); + PackageId_descriptor_ = file->enum_type(1); + RequestMsgIds_descriptor_ = file->enum_type(2); + ResponseMsgIds_descriptor_ = file->enum_type(3); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_peers_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestPeers_descriptor_, &RequestPeers::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ResponsePeerList_descriptor_, &ResponsePeerList::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestAddPeer_descriptor_, &RequestAddPeer::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ResponseAddPeer_descriptor_, &ResponseAddPeer::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestModifyPeer_descriptor_, &RequestModifyPeer::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ResponseModifyPeer_descriptor_, &ResponseModifyPeer::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_peers_2eproto() { + delete RequestPeers::default_instance_; + delete RequestPeers_reflection_; + delete ResponsePeerList::default_instance_; + delete ResponsePeerList_reflection_; + delete RequestAddPeer::default_instance_; + delete RequestAddPeer_reflection_; + delete ResponseAddPeer::default_instance_; + delete ResponseAddPeer_reflection_; + delete RequestModifyPeer::default_instance_; + delete RequestModifyPeer_reflection_; + delete ResponseModifyPeer::default_instance_; + delete ResponseModifyPeer_reflection_; +} + +void protobuf_AddDesc_peers_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::rsctrl::base::protobuf_AddDesc_base_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\013peers.proto\022\014rsctrl.peers\032\nbase.proto\"" + "\217\002\n\014RequestPeers\0221\n\003set\030\001 \002(\0162$.rsctrl.p" + "eers.RequestPeers.SetOption\0223\n\004info\030\002 \002(" + "\0162%.rsctrl.peers.RequestPeers.InfoOption" + "\022\017\n\007gpg_ids\030\003 \003(\t\"D\n\tSetOption\022\n\n\006LISTED" + "\020\001\022\n\n\006ONLINE\020\002\022\013\n\007FRIENDS\020\003\022\t\n\005VALID\020\004\022\007" + "\n\003ALL\020\005\"@\n\nInfoOption\022\014\n\010NAMEONLY\020\001\022\t\n\005B" + "ASIC\020\002\022\014\n\010LOCATION\020\003\022\013\n\007ALLINFO\020\004\"[\n\020Res" + "ponsePeerList\022#\n\006status\030\001 \002(\0132\023.rsctrl.b" + "ase.Status\022\"\n\005peers\030\002 \003(\0132\023.rsctrl.base." + "Person\"\242\001\n\016RequestAddPeer\022\016\n\006gpg_id\030\001 \002(" + "\t\0220\n\003cmd\030\002 \002(\0162#.rsctrl.peers.RequestAdd" + "Peer.AddCmd\022\014\n\004cert\030\003 \001(\t\"@\n\006AddCmd\022\010\n\004N" + "OOP\020\000\022\007\n\003ADD\020\001\022\n\n\006REMOVE\020\002\022\n\n\006IMPORT\020\003\022\013" + "\n\007EXAMINE\020\004\"Z\n\017ResponseAddPeer\022#\n\006status" + "\030\001 \002(\0132\023.rsctrl.base.Status\022\"\n\005peers\030\002 \003" + "(\0132\023.rsctrl.base.Person\"\231\001\n\021RequestModif" + "yPeer\0223\n\003cmd\030\001 \002(\0162&.rsctrl.peers.Reques" + "tModifyPeer.ModCmd\022\"\n\005peers\030\002 \003(\0132\023.rsct" + "rl.base.Person\"+\n\006ModCmd\022\010\n\004NOOP\020\000\022\013\n\007AD" + "DRESS\020\001\022\n\n\006DYNDNS\020\002\"]\n\022ResponseModifyPee" + "r\022#\n\006status\030\001 \002(\0132\023.rsctrl.base.Status\022\"" + "\n\005peers\030\002 \003(\0132\023.rsctrl.base.Person*\027\n\013Ex" + "tensionId\022\010\n\004BASE\020\000*\026\n\tPackageId\022\t\n\005PEER" + "S\020\001*^\n\rRequestMsgIds\022\026\n\022MsgId_RequestPee" + "rs\020\001\022\030\n\024MsgId_RequestAddPeer\020\002\022\033\n\027MsgId_" + "RequestModifyPeer\020\003*e\n\016ResponseMsgIds\022\032\n" + "\026MsgId_ResponsePeerList\020\001\022\031\n\025MsgId_Respo" + "nseAddPeer\020\002\022\034\n\030MsgId_ResponseModifyPeer" + "\020\003", 1162); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "peers.proto", &protobuf_RegisterTypes); + RequestPeers::default_instance_ = new RequestPeers(); + ResponsePeerList::default_instance_ = new ResponsePeerList(); + RequestAddPeer::default_instance_ = new RequestAddPeer(); + ResponseAddPeer::default_instance_ = new ResponseAddPeer(); + RequestModifyPeer::default_instance_ = new RequestModifyPeer(); + ResponseModifyPeer::default_instance_ = new ResponseModifyPeer(); + RequestPeers::default_instance_->InitAsDefaultInstance(); + ResponsePeerList::default_instance_->InitAsDefaultInstance(); + RequestAddPeer::default_instance_->InitAsDefaultInstance(); + ResponseAddPeer::default_instance_->InitAsDefaultInstance(); + RequestModifyPeer::default_instance_->InitAsDefaultInstance(); + ResponseModifyPeer::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_peers_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_peers_2eproto { + StaticDescriptorInitializer_peers_2eproto() { + protobuf_AddDesc_peers_2eproto(); + } +} static_descriptor_initializer_peers_2eproto_; + +const ::google::protobuf::EnumDescriptor* ExtensionId_descriptor() { + protobuf_AssignDescriptorsOnce(); + return ExtensionId_descriptor_; +} +bool ExtensionId_IsValid(int value) { + switch(value) { + case 0: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* PackageId_descriptor() { + protobuf_AssignDescriptorsOnce(); + return PackageId_descriptor_; +} +bool PackageId_IsValid(int value) { + switch(value) { + case 1: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestMsgIds_descriptor_; +} +bool RequestMsgIds_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 3: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor() { + protobuf_AssignDescriptorsOnce(); + return ResponseMsgIds_descriptor_; +} +bool ResponseMsgIds_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 3: + return true; + default: + return false; + } +} + + +// =================================================================== + +const ::google::protobuf::EnumDescriptor* RequestPeers_SetOption_descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestPeers_SetOption_descriptor_; +} +bool RequestPeers_SetOption_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 3: + case 4: + case 5: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const RequestPeers_SetOption RequestPeers::LISTED; +const RequestPeers_SetOption RequestPeers::ONLINE; +const RequestPeers_SetOption RequestPeers::FRIENDS; +const RequestPeers_SetOption RequestPeers::VALID; +const RequestPeers_SetOption RequestPeers::ALL; +const RequestPeers_SetOption RequestPeers::SetOption_MIN; +const RequestPeers_SetOption RequestPeers::SetOption_MAX; +const int RequestPeers::SetOption_ARRAYSIZE; +#endif // _MSC_VER +const ::google::protobuf::EnumDescriptor* RequestPeers_InfoOption_descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestPeers_InfoOption_descriptor_; +} +bool RequestPeers_InfoOption_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 3: + case 4: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const RequestPeers_InfoOption RequestPeers::NAMEONLY; +const RequestPeers_InfoOption RequestPeers::BASIC; +const RequestPeers_InfoOption RequestPeers::LOCATION; +const RequestPeers_InfoOption RequestPeers::ALLINFO; +const RequestPeers_InfoOption RequestPeers::InfoOption_MIN; +const RequestPeers_InfoOption RequestPeers::InfoOption_MAX; +const int RequestPeers::InfoOption_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int RequestPeers::kSetFieldNumber; +const int RequestPeers::kInfoFieldNumber; +const int RequestPeers::kGpgIdsFieldNumber; +#endif // !_MSC_VER + +RequestPeers::RequestPeers() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RequestPeers::InitAsDefaultInstance() { +} + +RequestPeers::RequestPeers(const RequestPeers& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RequestPeers::SharedCtor() { + _cached_size_ = 0; + set_ = 1; + info_ = 1; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RequestPeers::~RequestPeers() { + SharedDtor(); +} + +void RequestPeers::SharedDtor() { + if (this != default_instance_) { + } +} + +void RequestPeers::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestPeers::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestPeers_descriptor_; +} + +const RequestPeers& RequestPeers::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_peers_2eproto(); return *default_instance_; +} + +RequestPeers* RequestPeers::default_instance_ = NULL; + +RequestPeers* RequestPeers::New() const { + return new RequestPeers; +} + +void RequestPeers::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + set_ = 1; + info_ = 1; + } + gpg_ids_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestPeers::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.peers.RequestPeers.SetOption set = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::rsctrl::peers::RequestPeers_SetOption_IsValid(value)) { + set_set(static_cast< ::rsctrl::peers::RequestPeers_SetOption >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_info; + break; + } + + // required .rsctrl.peers.RequestPeers.InfoOption info = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_info: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::rsctrl::peers::RequestPeers_InfoOption_IsValid(value)) { + set_info(static_cast< ::rsctrl::peers::RequestPeers_InfoOption >(value)); + } else { + mutable_unknown_fields()->AddVarint(2, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_gpg_ids; + break; + } + + // repeated string gpg_ids = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_gpg_ids: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_gpg_ids())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->gpg_ids(0).data(), this->gpg_ids(0).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_gpg_ids; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void RequestPeers::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.peers.RequestPeers.SetOption set = 1; + if (has_set()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->set(), output); + } + + // required .rsctrl.peers.RequestPeers.InfoOption info = 2; + if (has_info()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 2, this->info(), output); + } + + // repeated string gpg_ids = 3; + for (int i = 0; i < this->gpg_ids_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->gpg_ids(i).data(), this->gpg_ids(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->gpg_ids(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RequestPeers::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.peers.RequestPeers.SetOption set = 1; + if (has_set()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->set(), target); + } + + // required .rsctrl.peers.RequestPeers.InfoOption info = 2; + if (has_info()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 2, this->info(), target); + } + + // repeated string gpg_ids = 3; + for (int i = 0; i < this->gpg_ids_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->gpg_ids(i).data(), this->gpg_ids(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(3, this->gpg_ids(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RequestPeers::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.peers.RequestPeers.SetOption set = 1; + if (has_set()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->set()); + } + + // required .rsctrl.peers.RequestPeers.InfoOption info = 2; + if (has_info()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->info()); + } + + } + // repeated string gpg_ids = 3; + total_size += 1 * this->gpg_ids_size(); + for (int i = 0; i < this->gpg_ids_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->gpg_ids(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestPeers::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestPeers* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestPeers::MergeFrom(const RequestPeers& from) { + GOOGLE_CHECK_NE(&from, this); + gpg_ids_.MergeFrom(from.gpg_ids_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_set()) { + set_set(from.set()); + } + if (from.has_info()) { + set_info(from.info()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestPeers::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestPeers::CopyFrom(const RequestPeers& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestPeers::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void RequestPeers::Swap(RequestPeers* other) { + if (other != this) { + std::swap(set_, other->set_); + std::swap(info_, other->info_); + gpg_ids_.Swap(&other->gpg_ids_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestPeers::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestPeers_descriptor_; + metadata.reflection = RequestPeers_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ResponsePeerList::kStatusFieldNumber; +const int ResponsePeerList::kPeersFieldNumber; +#endif // !_MSC_VER + +ResponsePeerList::ResponsePeerList() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ResponsePeerList::InitAsDefaultInstance() { + status_ = const_cast< ::rsctrl::base::Status*>(&::rsctrl::base::Status::default_instance()); +} + +ResponsePeerList::ResponsePeerList(const ResponsePeerList& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ResponsePeerList::SharedCtor() { + _cached_size_ = 0; + status_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ResponsePeerList::~ResponsePeerList() { + SharedDtor(); +} + +void ResponsePeerList::SharedDtor() { + if (this != default_instance_) { + delete status_; + } +} + +void ResponsePeerList::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ResponsePeerList::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ResponsePeerList_descriptor_; +} + +const ResponsePeerList& ResponsePeerList::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_peers_2eproto(); return *default_instance_; +} + +ResponsePeerList* ResponsePeerList::default_instance_ = NULL; + +ResponsePeerList* ResponsePeerList::New() const { + return new ResponsePeerList; +} + +void ResponsePeerList::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_status()) { + if (status_ != NULL) status_->::rsctrl::base::Status::Clear(); + } + } + peers_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ResponsePeerList::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.base.Status status = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_status())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_peers; + break; + } + + // repeated .rsctrl.base.Person peers = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_peers: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_peers())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_peers; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ResponsePeerList::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.base.Status status = 1; + if (has_status()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->status(), output); + } + + // repeated .rsctrl.base.Person peers = 2; + for (int i = 0; i < this->peers_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->peers(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ResponsePeerList::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.base.Status status = 1; + if (has_status()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->status(), target); + } + + // repeated .rsctrl.base.Person peers = 2; + for (int i = 0; i < this->peers_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->peers(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ResponsePeerList::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.base.Status status = 1; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->status()); + } + + } + // repeated .rsctrl.base.Person peers = 2; + total_size += 1 * this->peers_size(); + for (int i = 0; i < this->peers_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->peers(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ResponsePeerList::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ResponsePeerList* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ResponsePeerList::MergeFrom(const ResponsePeerList& from) { + GOOGLE_CHECK_NE(&from, this); + peers_.MergeFrom(from.peers_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_status()) { + mutable_status()->::rsctrl::base::Status::MergeFrom(from.status()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ResponsePeerList::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ResponsePeerList::CopyFrom(const ResponsePeerList& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ResponsePeerList::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_status()) { + if (!this->status().IsInitialized()) return false; + } + for (int i = 0; i < peers_size(); i++) { + if (!this->peers(i).IsInitialized()) return false; + } + return true; +} + +void ResponsePeerList::Swap(ResponsePeerList* other) { + if (other != this) { + std::swap(status_, other->status_); + peers_.Swap(&other->peers_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ResponsePeerList::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ResponsePeerList_descriptor_; + metadata.reflection = ResponsePeerList_reflection_; + return metadata; +} + + +// =================================================================== + +const ::google::protobuf::EnumDescriptor* RequestAddPeer_AddCmd_descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestAddPeer_AddCmd_descriptor_; +} +bool RequestAddPeer_AddCmd_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + case 3: + case 4: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const RequestAddPeer_AddCmd RequestAddPeer::NOOP; +const RequestAddPeer_AddCmd RequestAddPeer::ADD; +const RequestAddPeer_AddCmd RequestAddPeer::REMOVE; +const RequestAddPeer_AddCmd RequestAddPeer::IMPORT; +const RequestAddPeer_AddCmd RequestAddPeer::EXAMINE; +const RequestAddPeer_AddCmd RequestAddPeer::AddCmd_MIN; +const RequestAddPeer_AddCmd RequestAddPeer::AddCmd_MAX; +const int RequestAddPeer::AddCmd_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int RequestAddPeer::kGpgIdFieldNumber; +const int RequestAddPeer::kCmdFieldNumber; +const int RequestAddPeer::kCertFieldNumber; +#endif // !_MSC_VER + +RequestAddPeer::RequestAddPeer() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RequestAddPeer::InitAsDefaultInstance() { +} + +RequestAddPeer::RequestAddPeer(const RequestAddPeer& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RequestAddPeer::SharedCtor() { + _cached_size_ = 0; + gpg_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + cmd_ = 0; + cert_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RequestAddPeer::~RequestAddPeer() { + SharedDtor(); +} + +void RequestAddPeer::SharedDtor() { + if (gpg_id_ != &::google::protobuf::internal::kEmptyString) { + delete gpg_id_; + } + if (cert_ != &::google::protobuf::internal::kEmptyString) { + delete cert_; + } + if (this != default_instance_) { + } +} + +void RequestAddPeer::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestAddPeer::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestAddPeer_descriptor_; +} + +const RequestAddPeer& RequestAddPeer::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_peers_2eproto(); return *default_instance_; +} + +RequestAddPeer* RequestAddPeer::default_instance_ = NULL; + +RequestAddPeer* RequestAddPeer::New() const { + return new RequestAddPeer; +} + +void RequestAddPeer::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_gpg_id()) { + if (gpg_id_ != &::google::protobuf::internal::kEmptyString) { + gpg_id_->clear(); + } + } + cmd_ = 0; + if (has_cert()) { + if (cert_ != &::google::protobuf::internal::kEmptyString) { + cert_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestAddPeer::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string gpg_id = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_gpg_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->gpg_id().data(), this->gpg_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_cmd; + break; + } + + // required .rsctrl.peers.RequestAddPeer.AddCmd cmd = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_cmd: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::rsctrl::peers::RequestAddPeer_AddCmd_IsValid(value)) { + set_cmd(static_cast< ::rsctrl::peers::RequestAddPeer_AddCmd >(value)); + } else { + mutable_unknown_fields()->AddVarint(2, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_cert; + break; + } + + // optional string cert = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_cert: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_cert())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->cert().data(), this->cert().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void RequestAddPeer::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string gpg_id = 1; + if (has_gpg_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->gpg_id().data(), this->gpg_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->gpg_id(), output); + } + + // required .rsctrl.peers.RequestAddPeer.AddCmd cmd = 2; + if (has_cmd()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 2, this->cmd(), output); + } + + // optional string cert = 3; + if (has_cert()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->cert().data(), this->cert().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->cert(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RequestAddPeer::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string gpg_id = 1; + if (has_gpg_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->gpg_id().data(), this->gpg_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->gpg_id(), target); + } + + // required .rsctrl.peers.RequestAddPeer.AddCmd cmd = 2; + if (has_cmd()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 2, this->cmd(), target); + } + + // optional string cert = 3; + if (has_cert()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->cert().data(), this->cert().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->cert(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RequestAddPeer::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string gpg_id = 1; + if (has_gpg_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->gpg_id()); + } + + // required .rsctrl.peers.RequestAddPeer.AddCmd cmd = 2; + if (has_cmd()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->cmd()); + } + + // optional string cert = 3; + if (has_cert()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->cert()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestAddPeer::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestAddPeer* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestAddPeer::MergeFrom(const RequestAddPeer& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_gpg_id()) { + set_gpg_id(from.gpg_id()); + } + if (from.has_cmd()) { + set_cmd(from.cmd()); + } + if (from.has_cert()) { + set_cert(from.cert()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestAddPeer::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestAddPeer::CopyFrom(const RequestAddPeer& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestAddPeer::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void RequestAddPeer::Swap(RequestAddPeer* other) { + if (other != this) { + std::swap(gpg_id_, other->gpg_id_); + std::swap(cmd_, other->cmd_); + std::swap(cert_, other->cert_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestAddPeer::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestAddPeer_descriptor_; + metadata.reflection = RequestAddPeer_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ResponseAddPeer::kStatusFieldNumber; +const int ResponseAddPeer::kPeersFieldNumber; +#endif // !_MSC_VER + +ResponseAddPeer::ResponseAddPeer() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ResponseAddPeer::InitAsDefaultInstance() { + status_ = const_cast< ::rsctrl::base::Status*>(&::rsctrl::base::Status::default_instance()); +} + +ResponseAddPeer::ResponseAddPeer(const ResponseAddPeer& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ResponseAddPeer::SharedCtor() { + _cached_size_ = 0; + status_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ResponseAddPeer::~ResponseAddPeer() { + SharedDtor(); +} + +void ResponseAddPeer::SharedDtor() { + if (this != default_instance_) { + delete status_; + } +} + +void ResponseAddPeer::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ResponseAddPeer::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ResponseAddPeer_descriptor_; +} + +const ResponseAddPeer& ResponseAddPeer::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_peers_2eproto(); return *default_instance_; +} + +ResponseAddPeer* ResponseAddPeer::default_instance_ = NULL; + +ResponseAddPeer* ResponseAddPeer::New() const { + return new ResponseAddPeer; +} + +void ResponseAddPeer::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_status()) { + if (status_ != NULL) status_->::rsctrl::base::Status::Clear(); + } + } + peers_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ResponseAddPeer::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.base.Status status = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_status())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_peers; + break; + } + + // repeated .rsctrl.base.Person peers = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_peers: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_peers())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_peers; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ResponseAddPeer::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.base.Status status = 1; + if (has_status()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->status(), output); + } + + // repeated .rsctrl.base.Person peers = 2; + for (int i = 0; i < this->peers_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->peers(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ResponseAddPeer::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.base.Status status = 1; + if (has_status()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->status(), target); + } + + // repeated .rsctrl.base.Person peers = 2; + for (int i = 0; i < this->peers_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->peers(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ResponseAddPeer::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.base.Status status = 1; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->status()); + } + + } + // repeated .rsctrl.base.Person peers = 2; + total_size += 1 * this->peers_size(); + for (int i = 0; i < this->peers_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->peers(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ResponseAddPeer::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ResponseAddPeer* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ResponseAddPeer::MergeFrom(const ResponseAddPeer& from) { + GOOGLE_CHECK_NE(&from, this); + peers_.MergeFrom(from.peers_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_status()) { + mutable_status()->::rsctrl::base::Status::MergeFrom(from.status()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ResponseAddPeer::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ResponseAddPeer::CopyFrom(const ResponseAddPeer& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ResponseAddPeer::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_status()) { + if (!this->status().IsInitialized()) return false; + } + for (int i = 0; i < peers_size(); i++) { + if (!this->peers(i).IsInitialized()) return false; + } + return true; +} + +void ResponseAddPeer::Swap(ResponseAddPeer* other) { + if (other != this) { + std::swap(status_, other->status_); + peers_.Swap(&other->peers_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ResponseAddPeer::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ResponseAddPeer_descriptor_; + metadata.reflection = ResponseAddPeer_reflection_; + return metadata; +} + + +// =================================================================== + +const ::google::protobuf::EnumDescriptor* RequestModifyPeer_ModCmd_descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestModifyPeer_ModCmd_descriptor_; +} +bool RequestModifyPeer_ModCmd_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const RequestModifyPeer_ModCmd RequestModifyPeer::NOOP; +const RequestModifyPeer_ModCmd RequestModifyPeer::ADDRESS; +const RequestModifyPeer_ModCmd RequestModifyPeer::DYNDNS; +const RequestModifyPeer_ModCmd RequestModifyPeer::ModCmd_MIN; +const RequestModifyPeer_ModCmd RequestModifyPeer::ModCmd_MAX; +const int RequestModifyPeer::ModCmd_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int RequestModifyPeer::kCmdFieldNumber; +const int RequestModifyPeer::kPeersFieldNumber; +#endif // !_MSC_VER + +RequestModifyPeer::RequestModifyPeer() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RequestModifyPeer::InitAsDefaultInstance() { +} + +RequestModifyPeer::RequestModifyPeer(const RequestModifyPeer& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RequestModifyPeer::SharedCtor() { + _cached_size_ = 0; + cmd_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RequestModifyPeer::~RequestModifyPeer() { + SharedDtor(); +} + +void RequestModifyPeer::SharedDtor() { + if (this != default_instance_) { + } +} + +void RequestModifyPeer::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestModifyPeer::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestModifyPeer_descriptor_; +} + +const RequestModifyPeer& RequestModifyPeer::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_peers_2eproto(); return *default_instance_; +} + +RequestModifyPeer* RequestModifyPeer::default_instance_ = NULL; + +RequestModifyPeer* RequestModifyPeer::New() const { + return new RequestModifyPeer; +} + +void RequestModifyPeer::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + cmd_ = 0; + } + peers_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestModifyPeer::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.peers.RequestModifyPeer.ModCmd cmd = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::rsctrl::peers::RequestModifyPeer_ModCmd_IsValid(value)) { + set_cmd(static_cast< ::rsctrl::peers::RequestModifyPeer_ModCmd >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_peers; + break; + } + + // repeated .rsctrl.base.Person peers = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_peers: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_peers())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_peers; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void RequestModifyPeer::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.peers.RequestModifyPeer.ModCmd cmd = 1; + if (has_cmd()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->cmd(), output); + } + + // repeated .rsctrl.base.Person peers = 2; + for (int i = 0; i < this->peers_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->peers(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RequestModifyPeer::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.peers.RequestModifyPeer.ModCmd cmd = 1; + if (has_cmd()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->cmd(), target); + } + + // repeated .rsctrl.base.Person peers = 2; + for (int i = 0; i < this->peers_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->peers(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RequestModifyPeer::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.peers.RequestModifyPeer.ModCmd cmd = 1; + if (has_cmd()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->cmd()); + } + + } + // repeated .rsctrl.base.Person peers = 2; + total_size += 1 * this->peers_size(); + for (int i = 0; i < this->peers_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->peers(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestModifyPeer::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestModifyPeer* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestModifyPeer::MergeFrom(const RequestModifyPeer& from) { + GOOGLE_CHECK_NE(&from, this); + peers_.MergeFrom(from.peers_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_cmd()) { + set_cmd(from.cmd()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestModifyPeer::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestModifyPeer::CopyFrom(const RequestModifyPeer& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestModifyPeer::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + for (int i = 0; i < peers_size(); i++) { + if (!this->peers(i).IsInitialized()) return false; + } + return true; +} + +void RequestModifyPeer::Swap(RequestModifyPeer* other) { + if (other != this) { + std::swap(cmd_, other->cmd_); + peers_.Swap(&other->peers_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestModifyPeer::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestModifyPeer_descriptor_; + metadata.reflection = RequestModifyPeer_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ResponseModifyPeer::kStatusFieldNumber; +const int ResponseModifyPeer::kPeersFieldNumber; +#endif // !_MSC_VER + +ResponseModifyPeer::ResponseModifyPeer() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ResponseModifyPeer::InitAsDefaultInstance() { + status_ = const_cast< ::rsctrl::base::Status*>(&::rsctrl::base::Status::default_instance()); +} + +ResponseModifyPeer::ResponseModifyPeer(const ResponseModifyPeer& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ResponseModifyPeer::SharedCtor() { + _cached_size_ = 0; + status_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ResponseModifyPeer::~ResponseModifyPeer() { + SharedDtor(); +} + +void ResponseModifyPeer::SharedDtor() { + if (this != default_instance_) { + delete status_; + } +} + +void ResponseModifyPeer::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ResponseModifyPeer::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ResponseModifyPeer_descriptor_; +} + +const ResponseModifyPeer& ResponseModifyPeer::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_peers_2eproto(); return *default_instance_; +} + +ResponseModifyPeer* ResponseModifyPeer::default_instance_ = NULL; + +ResponseModifyPeer* ResponseModifyPeer::New() const { + return new ResponseModifyPeer; +} + +void ResponseModifyPeer::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_status()) { + if (status_ != NULL) status_->::rsctrl::base::Status::Clear(); + } + } + peers_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ResponseModifyPeer::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.base.Status status = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_status())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_peers; + break; + } + + // repeated .rsctrl.base.Person peers = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_peers: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_peers())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_peers; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ResponseModifyPeer::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.base.Status status = 1; + if (has_status()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->status(), output); + } + + // repeated .rsctrl.base.Person peers = 2; + for (int i = 0; i < this->peers_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->peers(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ResponseModifyPeer::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.base.Status status = 1; + if (has_status()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->status(), target); + } + + // repeated .rsctrl.base.Person peers = 2; + for (int i = 0; i < this->peers_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->peers(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ResponseModifyPeer::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.base.Status status = 1; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->status()); + } + + } + // repeated .rsctrl.base.Person peers = 2; + total_size += 1 * this->peers_size(); + for (int i = 0; i < this->peers_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->peers(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ResponseModifyPeer::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ResponseModifyPeer* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ResponseModifyPeer::MergeFrom(const ResponseModifyPeer& from) { + GOOGLE_CHECK_NE(&from, this); + peers_.MergeFrom(from.peers_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_status()) { + mutable_status()->::rsctrl::base::Status::MergeFrom(from.status()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ResponseModifyPeer::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ResponseModifyPeer::CopyFrom(const ResponseModifyPeer& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ResponseModifyPeer::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_status()) { + if (!this->status().IsInitialized()) return false; + } + for (int i = 0; i < peers_size(); i++) { + if (!this->peers(i).IsInitialized()) return false; + } + return true; +} + +void ResponseModifyPeer::Swap(ResponseModifyPeer* other) { + if (other != this) { + std::swap(status_, other->status_); + peers_.Swap(&other->peers_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ResponseModifyPeer::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ResponseModifyPeer_descriptor_; + metadata.reflection = ResponseModifyPeer_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace peers +} // namespace rsctrl + +// @@protoc_insertion_point(global_scope) diff --git a/retroshare-nogui/src/rpc/proto/gencc/peers.pb.h b/retroshare-nogui/src/rpc/proto/gencc/peers.pb.h new file mode 100644 index 000000000..8696bd617 --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/gencc/peers.pb.h @@ -0,0 +1,1427 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: peers.proto + +#ifndef PROTOBUF_peers_2eproto__INCLUDED +#define PROTOBUF_peers_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2004000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2004001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include "base.pb.h" +// @@protoc_insertion_point(includes) + +namespace rsctrl { +namespace peers { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_peers_2eproto(); +void protobuf_AssignDesc_peers_2eproto(); +void protobuf_ShutdownFile_peers_2eproto(); + +class RequestPeers; +class ResponsePeerList; +class RequestAddPeer; +class ResponseAddPeer; +class RequestModifyPeer; +class ResponseModifyPeer; + +enum RequestPeers_SetOption { + RequestPeers_SetOption_LISTED = 1, + RequestPeers_SetOption_ONLINE = 2, + RequestPeers_SetOption_FRIENDS = 3, + RequestPeers_SetOption_VALID = 4, + RequestPeers_SetOption_ALL = 5 +}; +bool RequestPeers_SetOption_IsValid(int value); +const RequestPeers_SetOption RequestPeers_SetOption_SetOption_MIN = RequestPeers_SetOption_LISTED; +const RequestPeers_SetOption RequestPeers_SetOption_SetOption_MAX = RequestPeers_SetOption_ALL; +const int RequestPeers_SetOption_SetOption_ARRAYSIZE = RequestPeers_SetOption_SetOption_MAX + 1; + +const ::google::protobuf::EnumDescriptor* RequestPeers_SetOption_descriptor(); +inline const ::std::string& RequestPeers_SetOption_Name(RequestPeers_SetOption value) { + return ::google::protobuf::internal::NameOfEnum( + RequestPeers_SetOption_descriptor(), value); +} +inline bool RequestPeers_SetOption_Parse( + const ::std::string& name, RequestPeers_SetOption* value) { + return ::google::protobuf::internal::ParseNamedEnum( + RequestPeers_SetOption_descriptor(), name, value); +} +enum RequestPeers_InfoOption { + RequestPeers_InfoOption_NAMEONLY = 1, + RequestPeers_InfoOption_BASIC = 2, + RequestPeers_InfoOption_LOCATION = 3, + RequestPeers_InfoOption_ALLINFO = 4 +}; +bool RequestPeers_InfoOption_IsValid(int value); +const RequestPeers_InfoOption RequestPeers_InfoOption_InfoOption_MIN = RequestPeers_InfoOption_NAMEONLY; +const RequestPeers_InfoOption RequestPeers_InfoOption_InfoOption_MAX = RequestPeers_InfoOption_ALLINFO; +const int RequestPeers_InfoOption_InfoOption_ARRAYSIZE = RequestPeers_InfoOption_InfoOption_MAX + 1; + +const ::google::protobuf::EnumDescriptor* RequestPeers_InfoOption_descriptor(); +inline const ::std::string& RequestPeers_InfoOption_Name(RequestPeers_InfoOption value) { + return ::google::protobuf::internal::NameOfEnum( + RequestPeers_InfoOption_descriptor(), value); +} +inline bool RequestPeers_InfoOption_Parse( + const ::std::string& name, RequestPeers_InfoOption* value) { + return ::google::protobuf::internal::ParseNamedEnum( + RequestPeers_InfoOption_descriptor(), name, value); +} +enum RequestAddPeer_AddCmd { + RequestAddPeer_AddCmd_NOOP = 0, + RequestAddPeer_AddCmd_ADD = 1, + RequestAddPeer_AddCmd_REMOVE = 2, + RequestAddPeer_AddCmd_IMPORT = 3, + RequestAddPeer_AddCmd_EXAMINE = 4 +}; +bool RequestAddPeer_AddCmd_IsValid(int value); +const RequestAddPeer_AddCmd RequestAddPeer_AddCmd_AddCmd_MIN = RequestAddPeer_AddCmd_NOOP; +const RequestAddPeer_AddCmd RequestAddPeer_AddCmd_AddCmd_MAX = RequestAddPeer_AddCmd_EXAMINE; +const int RequestAddPeer_AddCmd_AddCmd_ARRAYSIZE = RequestAddPeer_AddCmd_AddCmd_MAX + 1; + +const ::google::protobuf::EnumDescriptor* RequestAddPeer_AddCmd_descriptor(); +inline const ::std::string& RequestAddPeer_AddCmd_Name(RequestAddPeer_AddCmd value) { + return ::google::protobuf::internal::NameOfEnum( + RequestAddPeer_AddCmd_descriptor(), value); +} +inline bool RequestAddPeer_AddCmd_Parse( + const ::std::string& name, RequestAddPeer_AddCmd* value) { + return ::google::protobuf::internal::ParseNamedEnum( + RequestAddPeer_AddCmd_descriptor(), name, value); +} +enum RequestModifyPeer_ModCmd { + RequestModifyPeer_ModCmd_NOOP = 0, + RequestModifyPeer_ModCmd_ADDRESS = 1, + RequestModifyPeer_ModCmd_DYNDNS = 2 +}; +bool RequestModifyPeer_ModCmd_IsValid(int value); +const RequestModifyPeer_ModCmd RequestModifyPeer_ModCmd_ModCmd_MIN = RequestModifyPeer_ModCmd_NOOP; +const RequestModifyPeer_ModCmd RequestModifyPeer_ModCmd_ModCmd_MAX = RequestModifyPeer_ModCmd_DYNDNS; +const int RequestModifyPeer_ModCmd_ModCmd_ARRAYSIZE = RequestModifyPeer_ModCmd_ModCmd_MAX + 1; + +const ::google::protobuf::EnumDescriptor* RequestModifyPeer_ModCmd_descriptor(); +inline const ::std::string& RequestModifyPeer_ModCmd_Name(RequestModifyPeer_ModCmd value) { + return ::google::protobuf::internal::NameOfEnum( + RequestModifyPeer_ModCmd_descriptor(), value); +} +inline bool RequestModifyPeer_ModCmd_Parse( + const ::std::string& name, RequestModifyPeer_ModCmd* value) { + return ::google::protobuf::internal::ParseNamedEnum( + RequestModifyPeer_ModCmd_descriptor(), name, value); +} +enum ExtensionId { + BASE = 0 +}; +bool ExtensionId_IsValid(int value); +const ExtensionId ExtensionId_MIN = BASE; +const ExtensionId ExtensionId_MAX = BASE; +const int ExtensionId_ARRAYSIZE = ExtensionId_MAX + 1; + +const ::google::protobuf::EnumDescriptor* ExtensionId_descriptor(); +inline const ::std::string& ExtensionId_Name(ExtensionId value) { + return ::google::protobuf::internal::NameOfEnum( + ExtensionId_descriptor(), value); +} +inline bool ExtensionId_Parse( + const ::std::string& name, ExtensionId* value) { + return ::google::protobuf::internal::ParseNamedEnum( + ExtensionId_descriptor(), name, value); +} +enum PackageId { + PEERS = 1 +}; +bool PackageId_IsValid(int value); +const PackageId PackageId_MIN = PEERS; +const PackageId PackageId_MAX = PEERS; +const int PackageId_ARRAYSIZE = PackageId_MAX + 1; + +const ::google::protobuf::EnumDescriptor* PackageId_descriptor(); +inline const ::std::string& PackageId_Name(PackageId value) { + return ::google::protobuf::internal::NameOfEnum( + PackageId_descriptor(), value); +} +inline bool PackageId_Parse( + const ::std::string& name, PackageId* value) { + return ::google::protobuf::internal::ParseNamedEnum( + PackageId_descriptor(), name, value); +} +enum RequestMsgIds { + MsgId_RequestPeers = 1, + MsgId_RequestAddPeer = 2, + MsgId_RequestModifyPeer = 3 +}; +bool RequestMsgIds_IsValid(int value); +const RequestMsgIds RequestMsgIds_MIN = MsgId_RequestPeers; +const RequestMsgIds RequestMsgIds_MAX = MsgId_RequestModifyPeer; +const int RequestMsgIds_ARRAYSIZE = RequestMsgIds_MAX + 1; + +const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor(); +inline const ::std::string& RequestMsgIds_Name(RequestMsgIds value) { + return ::google::protobuf::internal::NameOfEnum( + RequestMsgIds_descriptor(), value); +} +inline bool RequestMsgIds_Parse( + const ::std::string& name, RequestMsgIds* value) { + return ::google::protobuf::internal::ParseNamedEnum( + RequestMsgIds_descriptor(), name, value); +} +enum ResponseMsgIds { + MsgId_ResponsePeerList = 1, + MsgId_ResponseAddPeer = 2, + MsgId_ResponseModifyPeer = 3 +}; +bool ResponseMsgIds_IsValid(int value); +const ResponseMsgIds ResponseMsgIds_MIN = MsgId_ResponsePeerList; +const ResponseMsgIds ResponseMsgIds_MAX = MsgId_ResponseModifyPeer; +const int ResponseMsgIds_ARRAYSIZE = ResponseMsgIds_MAX + 1; + +const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor(); +inline const ::std::string& ResponseMsgIds_Name(ResponseMsgIds value) { + return ::google::protobuf::internal::NameOfEnum( + ResponseMsgIds_descriptor(), value); +} +inline bool ResponseMsgIds_Parse( + const ::std::string& name, ResponseMsgIds* value) { + return ::google::protobuf::internal::ParseNamedEnum( + ResponseMsgIds_descriptor(), name, value); +} +// =================================================================== + +class RequestPeers : public ::google::protobuf::Message { + public: + RequestPeers(); + virtual ~RequestPeers(); + + RequestPeers(const RequestPeers& from); + + inline RequestPeers& operator=(const RequestPeers& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestPeers& default_instance(); + + void Swap(RequestPeers* other); + + // implements Message ---------------------------------------------- + + RequestPeers* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestPeers& from); + void MergeFrom(const RequestPeers& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef RequestPeers_SetOption SetOption; + static const SetOption LISTED = RequestPeers_SetOption_LISTED; + static const SetOption ONLINE = RequestPeers_SetOption_ONLINE; + static const SetOption FRIENDS = RequestPeers_SetOption_FRIENDS; + static const SetOption VALID = RequestPeers_SetOption_VALID; + static const SetOption ALL = RequestPeers_SetOption_ALL; + static inline bool SetOption_IsValid(int value) { + return RequestPeers_SetOption_IsValid(value); + } + static const SetOption SetOption_MIN = + RequestPeers_SetOption_SetOption_MIN; + static const SetOption SetOption_MAX = + RequestPeers_SetOption_SetOption_MAX; + static const int SetOption_ARRAYSIZE = + RequestPeers_SetOption_SetOption_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + SetOption_descriptor() { + return RequestPeers_SetOption_descriptor(); + } + static inline const ::std::string& SetOption_Name(SetOption value) { + return RequestPeers_SetOption_Name(value); + } + static inline bool SetOption_Parse(const ::std::string& name, + SetOption* value) { + return RequestPeers_SetOption_Parse(name, value); + } + + typedef RequestPeers_InfoOption InfoOption; + static const InfoOption NAMEONLY = RequestPeers_InfoOption_NAMEONLY; + static const InfoOption BASIC = RequestPeers_InfoOption_BASIC; + static const InfoOption LOCATION = RequestPeers_InfoOption_LOCATION; + static const InfoOption ALLINFO = RequestPeers_InfoOption_ALLINFO; + static inline bool InfoOption_IsValid(int value) { + return RequestPeers_InfoOption_IsValid(value); + } + static const InfoOption InfoOption_MIN = + RequestPeers_InfoOption_InfoOption_MIN; + static const InfoOption InfoOption_MAX = + RequestPeers_InfoOption_InfoOption_MAX; + static const int InfoOption_ARRAYSIZE = + RequestPeers_InfoOption_InfoOption_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + InfoOption_descriptor() { + return RequestPeers_InfoOption_descriptor(); + } + static inline const ::std::string& InfoOption_Name(InfoOption value) { + return RequestPeers_InfoOption_Name(value); + } + static inline bool InfoOption_Parse(const ::std::string& name, + InfoOption* value) { + return RequestPeers_InfoOption_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // required .rsctrl.peers.RequestPeers.SetOption set = 1; + inline bool has_set() const; + inline void clear_set(); + static const int kSetFieldNumber = 1; + inline ::rsctrl::peers::RequestPeers_SetOption set() const; + inline void set_set(::rsctrl::peers::RequestPeers_SetOption value); + + // required .rsctrl.peers.RequestPeers.InfoOption info = 2; + inline bool has_info() const; + inline void clear_info(); + static const int kInfoFieldNumber = 2; + inline ::rsctrl::peers::RequestPeers_InfoOption info() const; + inline void set_info(::rsctrl::peers::RequestPeers_InfoOption value); + + // repeated string gpg_ids = 3; + inline int gpg_ids_size() const; + inline void clear_gpg_ids(); + static const int kGpgIdsFieldNumber = 3; + inline const ::std::string& gpg_ids(int index) const; + inline ::std::string* mutable_gpg_ids(int index); + inline void set_gpg_ids(int index, const ::std::string& value); + inline void set_gpg_ids(int index, const char* value); + inline void set_gpg_ids(int index, const char* value, size_t size); + inline ::std::string* add_gpg_ids(); + inline void add_gpg_ids(const ::std::string& value); + inline void add_gpg_ids(const char* value); + inline void add_gpg_ids(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& gpg_ids() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_gpg_ids(); + + // @@protoc_insertion_point(class_scope:rsctrl.peers.RequestPeers) + private: + inline void set_has_set(); + inline void clear_has_set(); + inline void set_has_info(); + inline void clear_has_info(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + int set_; + int info_; + ::google::protobuf::RepeatedPtrField< ::std::string> gpg_ids_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_peers_2eproto(); + friend void protobuf_AssignDesc_peers_2eproto(); + friend void protobuf_ShutdownFile_peers_2eproto(); + + void InitAsDefaultInstance(); + static RequestPeers* default_instance_; +}; +// ------------------------------------------------------------------- + +class ResponsePeerList : public ::google::protobuf::Message { + public: + ResponsePeerList(); + virtual ~ResponsePeerList(); + + ResponsePeerList(const ResponsePeerList& from); + + inline ResponsePeerList& operator=(const ResponsePeerList& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ResponsePeerList& default_instance(); + + void Swap(ResponsePeerList* other); + + // implements Message ---------------------------------------------- + + ResponsePeerList* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ResponsePeerList& from); + void MergeFrom(const ResponsePeerList& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .rsctrl.base.Status status = 1; + inline bool has_status() const; + inline void clear_status(); + static const int kStatusFieldNumber = 1; + inline const ::rsctrl::base::Status& status() const; + inline ::rsctrl::base::Status* mutable_status(); + inline ::rsctrl::base::Status* release_status(); + + // repeated .rsctrl.base.Person peers = 2; + inline int peers_size() const; + inline void clear_peers(); + static const int kPeersFieldNumber = 2; + inline const ::rsctrl::base::Person& peers(int index) const; + inline ::rsctrl::base::Person* mutable_peers(int index); + inline ::rsctrl::base::Person* add_peers(); + inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >& + peers() const; + inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >* + mutable_peers(); + + // @@protoc_insertion_point(class_scope:rsctrl.peers.ResponsePeerList) + private: + inline void set_has_status(); + inline void clear_has_status(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::rsctrl::base::Status* status_; + ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person > peers_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_peers_2eproto(); + friend void protobuf_AssignDesc_peers_2eproto(); + friend void protobuf_ShutdownFile_peers_2eproto(); + + void InitAsDefaultInstance(); + static ResponsePeerList* default_instance_; +}; +// ------------------------------------------------------------------- + +class RequestAddPeer : public ::google::protobuf::Message { + public: + RequestAddPeer(); + virtual ~RequestAddPeer(); + + RequestAddPeer(const RequestAddPeer& from); + + inline RequestAddPeer& operator=(const RequestAddPeer& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestAddPeer& default_instance(); + + void Swap(RequestAddPeer* other); + + // implements Message ---------------------------------------------- + + RequestAddPeer* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestAddPeer& from); + void MergeFrom(const RequestAddPeer& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef RequestAddPeer_AddCmd AddCmd; + static const AddCmd NOOP = RequestAddPeer_AddCmd_NOOP; + static const AddCmd ADD = RequestAddPeer_AddCmd_ADD; + static const AddCmd REMOVE = RequestAddPeer_AddCmd_REMOVE; + static const AddCmd IMPORT = RequestAddPeer_AddCmd_IMPORT; + static const AddCmd EXAMINE = RequestAddPeer_AddCmd_EXAMINE; + static inline bool AddCmd_IsValid(int value) { + return RequestAddPeer_AddCmd_IsValid(value); + } + static const AddCmd AddCmd_MIN = + RequestAddPeer_AddCmd_AddCmd_MIN; + static const AddCmd AddCmd_MAX = + RequestAddPeer_AddCmd_AddCmd_MAX; + static const int AddCmd_ARRAYSIZE = + RequestAddPeer_AddCmd_AddCmd_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + AddCmd_descriptor() { + return RequestAddPeer_AddCmd_descriptor(); + } + static inline const ::std::string& AddCmd_Name(AddCmd value) { + return RequestAddPeer_AddCmd_Name(value); + } + static inline bool AddCmd_Parse(const ::std::string& name, + AddCmd* value) { + return RequestAddPeer_AddCmd_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // required string gpg_id = 1; + inline bool has_gpg_id() const; + inline void clear_gpg_id(); + static const int kGpgIdFieldNumber = 1; + inline const ::std::string& gpg_id() const; + inline void set_gpg_id(const ::std::string& value); + inline void set_gpg_id(const char* value); + inline void set_gpg_id(const char* value, size_t size); + inline ::std::string* mutable_gpg_id(); + inline ::std::string* release_gpg_id(); + + // required .rsctrl.peers.RequestAddPeer.AddCmd cmd = 2; + inline bool has_cmd() const; + inline void clear_cmd(); + static const int kCmdFieldNumber = 2; + inline ::rsctrl::peers::RequestAddPeer_AddCmd cmd() const; + inline void set_cmd(::rsctrl::peers::RequestAddPeer_AddCmd value); + + // optional string cert = 3; + inline bool has_cert() const; + inline void clear_cert(); + static const int kCertFieldNumber = 3; + inline const ::std::string& cert() const; + inline void set_cert(const ::std::string& value); + inline void set_cert(const char* value); + inline void set_cert(const char* value, size_t size); + inline ::std::string* mutable_cert(); + inline ::std::string* release_cert(); + + // @@protoc_insertion_point(class_scope:rsctrl.peers.RequestAddPeer) + private: + inline void set_has_gpg_id(); + inline void clear_has_gpg_id(); + inline void set_has_cmd(); + inline void clear_has_cmd(); + inline void set_has_cert(); + inline void clear_has_cert(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* gpg_id_; + ::std::string* cert_; + int cmd_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_peers_2eproto(); + friend void protobuf_AssignDesc_peers_2eproto(); + friend void protobuf_ShutdownFile_peers_2eproto(); + + void InitAsDefaultInstance(); + static RequestAddPeer* default_instance_; +}; +// ------------------------------------------------------------------- + +class ResponseAddPeer : public ::google::protobuf::Message { + public: + ResponseAddPeer(); + virtual ~ResponseAddPeer(); + + ResponseAddPeer(const ResponseAddPeer& from); + + inline ResponseAddPeer& operator=(const ResponseAddPeer& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ResponseAddPeer& default_instance(); + + void Swap(ResponseAddPeer* other); + + // implements Message ---------------------------------------------- + + ResponseAddPeer* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ResponseAddPeer& from); + void MergeFrom(const ResponseAddPeer& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .rsctrl.base.Status status = 1; + inline bool has_status() const; + inline void clear_status(); + static const int kStatusFieldNumber = 1; + inline const ::rsctrl::base::Status& status() const; + inline ::rsctrl::base::Status* mutable_status(); + inline ::rsctrl::base::Status* release_status(); + + // repeated .rsctrl.base.Person peers = 2; + inline int peers_size() const; + inline void clear_peers(); + static const int kPeersFieldNumber = 2; + inline const ::rsctrl::base::Person& peers(int index) const; + inline ::rsctrl::base::Person* mutable_peers(int index); + inline ::rsctrl::base::Person* add_peers(); + inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >& + peers() const; + inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >* + mutable_peers(); + + // @@protoc_insertion_point(class_scope:rsctrl.peers.ResponseAddPeer) + private: + inline void set_has_status(); + inline void clear_has_status(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::rsctrl::base::Status* status_; + ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person > peers_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_peers_2eproto(); + friend void protobuf_AssignDesc_peers_2eproto(); + friend void protobuf_ShutdownFile_peers_2eproto(); + + void InitAsDefaultInstance(); + static ResponseAddPeer* default_instance_; +}; +// ------------------------------------------------------------------- + +class RequestModifyPeer : public ::google::protobuf::Message { + public: + RequestModifyPeer(); + virtual ~RequestModifyPeer(); + + RequestModifyPeer(const RequestModifyPeer& from); + + inline RequestModifyPeer& operator=(const RequestModifyPeer& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestModifyPeer& default_instance(); + + void Swap(RequestModifyPeer* other); + + // implements Message ---------------------------------------------- + + RequestModifyPeer* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestModifyPeer& from); + void MergeFrom(const RequestModifyPeer& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef RequestModifyPeer_ModCmd ModCmd; + static const ModCmd NOOP = RequestModifyPeer_ModCmd_NOOP; + static const ModCmd ADDRESS = RequestModifyPeer_ModCmd_ADDRESS; + static const ModCmd DYNDNS = RequestModifyPeer_ModCmd_DYNDNS; + static inline bool ModCmd_IsValid(int value) { + return RequestModifyPeer_ModCmd_IsValid(value); + } + static const ModCmd ModCmd_MIN = + RequestModifyPeer_ModCmd_ModCmd_MIN; + static const ModCmd ModCmd_MAX = + RequestModifyPeer_ModCmd_ModCmd_MAX; + static const int ModCmd_ARRAYSIZE = + RequestModifyPeer_ModCmd_ModCmd_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + ModCmd_descriptor() { + return RequestModifyPeer_ModCmd_descriptor(); + } + static inline const ::std::string& ModCmd_Name(ModCmd value) { + return RequestModifyPeer_ModCmd_Name(value); + } + static inline bool ModCmd_Parse(const ::std::string& name, + ModCmd* value) { + return RequestModifyPeer_ModCmd_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // required .rsctrl.peers.RequestModifyPeer.ModCmd cmd = 1; + inline bool has_cmd() const; + inline void clear_cmd(); + static const int kCmdFieldNumber = 1; + inline ::rsctrl::peers::RequestModifyPeer_ModCmd cmd() const; + inline void set_cmd(::rsctrl::peers::RequestModifyPeer_ModCmd value); + + // repeated .rsctrl.base.Person peers = 2; + inline int peers_size() const; + inline void clear_peers(); + static const int kPeersFieldNumber = 2; + inline const ::rsctrl::base::Person& peers(int index) const; + inline ::rsctrl::base::Person* mutable_peers(int index); + inline ::rsctrl::base::Person* add_peers(); + inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >& + peers() const; + inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >* + mutable_peers(); + + // @@protoc_insertion_point(class_scope:rsctrl.peers.RequestModifyPeer) + private: + inline void set_has_cmd(); + inline void clear_has_cmd(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person > peers_; + int cmd_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_peers_2eproto(); + friend void protobuf_AssignDesc_peers_2eproto(); + friend void protobuf_ShutdownFile_peers_2eproto(); + + void InitAsDefaultInstance(); + static RequestModifyPeer* default_instance_; +}; +// ------------------------------------------------------------------- + +class ResponseModifyPeer : public ::google::protobuf::Message { + public: + ResponseModifyPeer(); + virtual ~ResponseModifyPeer(); + + ResponseModifyPeer(const ResponseModifyPeer& from); + + inline ResponseModifyPeer& operator=(const ResponseModifyPeer& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ResponseModifyPeer& default_instance(); + + void Swap(ResponseModifyPeer* other); + + // implements Message ---------------------------------------------- + + ResponseModifyPeer* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ResponseModifyPeer& from); + void MergeFrom(const ResponseModifyPeer& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .rsctrl.base.Status status = 1; + inline bool has_status() const; + inline void clear_status(); + static const int kStatusFieldNumber = 1; + inline const ::rsctrl::base::Status& status() const; + inline ::rsctrl::base::Status* mutable_status(); + inline ::rsctrl::base::Status* release_status(); + + // repeated .rsctrl.base.Person peers = 2; + inline int peers_size() const; + inline void clear_peers(); + static const int kPeersFieldNumber = 2; + inline const ::rsctrl::base::Person& peers(int index) const; + inline ::rsctrl::base::Person* mutable_peers(int index); + inline ::rsctrl::base::Person* add_peers(); + inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >& + peers() const; + inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >* + mutable_peers(); + + // @@protoc_insertion_point(class_scope:rsctrl.peers.ResponseModifyPeer) + private: + inline void set_has_status(); + inline void clear_has_status(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::rsctrl::base::Status* status_; + ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person > peers_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_peers_2eproto(); + friend void protobuf_AssignDesc_peers_2eproto(); + friend void protobuf_ShutdownFile_peers_2eproto(); + + void InitAsDefaultInstance(); + static ResponseModifyPeer* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// RequestPeers + +// required .rsctrl.peers.RequestPeers.SetOption set = 1; +inline bool RequestPeers::has_set() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void RequestPeers::set_has_set() { + _has_bits_[0] |= 0x00000001u; +} +inline void RequestPeers::clear_has_set() { + _has_bits_[0] &= ~0x00000001u; +} +inline void RequestPeers::clear_set() { + set_ = 1; + clear_has_set(); +} +inline ::rsctrl::peers::RequestPeers_SetOption RequestPeers::set() const { + return static_cast< ::rsctrl::peers::RequestPeers_SetOption >(set_); +} +inline void RequestPeers::set_set(::rsctrl::peers::RequestPeers_SetOption value) { + GOOGLE_DCHECK(::rsctrl::peers::RequestPeers_SetOption_IsValid(value)); + set_has_set(); + set_ = value; +} + +// required .rsctrl.peers.RequestPeers.InfoOption info = 2; +inline bool RequestPeers::has_info() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void RequestPeers::set_has_info() { + _has_bits_[0] |= 0x00000002u; +} +inline void RequestPeers::clear_has_info() { + _has_bits_[0] &= ~0x00000002u; +} +inline void RequestPeers::clear_info() { + info_ = 1; + clear_has_info(); +} +inline ::rsctrl::peers::RequestPeers_InfoOption RequestPeers::info() const { + return static_cast< ::rsctrl::peers::RequestPeers_InfoOption >(info_); +} +inline void RequestPeers::set_info(::rsctrl::peers::RequestPeers_InfoOption value) { + GOOGLE_DCHECK(::rsctrl::peers::RequestPeers_InfoOption_IsValid(value)); + set_has_info(); + info_ = value; +} + +// repeated string gpg_ids = 3; +inline int RequestPeers::gpg_ids_size() const { + return gpg_ids_.size(); +} +inline void RequestPeers::clear_gpg_ids() { + gpg_ids_.Clear(); +} +inline const ::std::string& RequestPeers::gpg_ids(int index) const { + return gpg_ids_.Get(index); +} +inline ::std::string* RequestPeers::mutable_gpg_ids(int index) { + return gpg_ids_.Mutable(index); +} +inline void RequestPeers::set_gpg_ids(int index, const ::std::string& value) { + gpg_ids_.Mutable(index)->assign(value); +} +inline void RequestPeers::set_gpg_ids(int index, const char* value) { + gpg_ids_.Mutable(index)->assign(value); +} +inline void RequestPeers::set_gpg_ids(int index, const char* value, size_t size) { + gpg_ids_.Mutable(index)->assign( + reinterpret_cast(value), size); +} +inline ::std::string* RequestPeers::add_gpg_ids() { + return gpg_ids_.Add(); +} +inline void RequestPeers::add_gpg_ids(const ::std::string& value) { + gpg_ids_.Add()->assign(value); +} +inline void RequestPeers::add_gpg_ids(const char* value) { + gpg_ids_.Add()->assign(value); +} +inline void RequestPeers::add_gpg_ids(const char* value, size_t size) { + gpg_ids_.Add()->assign(reinterpret_cast(value), size); +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +RequestPeers::gpg_ids() const { + return gpg_ids_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +RequestPeers::mutable_gpg_ids() { + return &gpg_ids_; +} + +// ------------------------------------------------------------------- + +// ResponsePeerList + +// required .rsctrl.base.Status status = 1; +inline bool ResponsePeerList::has_status() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ResponsePeerList::set_has_status() { + _has_bits_[0] |= 0x00000001u; +} +inline void ResponsePeerList::clear_has_status() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ResponsePeerList::clear_status() { + if (status_ != NULL) status_->::rsctrl::base::Status::Clear(); + clear_has_status(); +} +inline const ::rsctrl::base::Status& ResponsePeerList::status() const { + return status_ != NULL ? *status_ : *default_instance_->status_; +} +inline ::rsctrl::base::Status* ResponsePeerList::mutable_status() { + set_has_status(); + if (status_ == NULL) status_ = new ::rsctrl::base::Status; + return status_; +} +inline ::rsctrl::base::Status* ResponsePeerList::release_status() { + clear_has_status(); + ::rsctrl::base::Status* temp = status_; + status_ = NULL; + return temp; +} + +// repeated .rsctrl.base.Person peers = 2; +inline int ResponsePeerList::peers_size() const { + return peers_.size(); +} +inline void ResponsePeerList::clear_peers() { + peers_.Clear(); +} +inline const ::rsctrl::base::Person& ResponsePeerList::peers(int index) const { + return peers_.Get(index); +} +inline ::rsctrl::base::Person* ResponsePeerList::mutable_peers(int index) { + return peers_.Mutable(index); +} +inline ::rsctrl::base::Person* ResponsePeerList::add_peers() { + return peers_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >& +ResponsePeerList::peers() const { + return peers_; +} +inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >* +ResponsePeerList::mutable_peers() { + return &peers_; +} + +// ------------------------------------------------------------------- + +// RequestAddPeer + +// required string gpg_id = 1; +inline bool RequestAddPeer::has_gpg_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void RequestAddPeer::set_has_gpg_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void RequestAddPeer::clear_has_gpg_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void RequestAddPeer::clear_gpg_id() { + if (gpg_id_ != &::google::protobuf::internal::kEmptyString) { + gpg_id_->clear(); + } + clear_has_gpg_id(); +} +inline const ::std::string& RequestAddPeer::gpg_id() const { + return *gpg_id_; +} +inline void RequestAddPeer::set_gpg_id(const ::std::string& value) { + set_has_gpg_id(); + if (gpg_id_ == &::google::protobuf::internal::kEmptyString) { + gpg_id_ = new ::std::string; + } + gpg_id_->assign(value); +} +inline void RequestAddPeer::set_gpg_id(const char* value) { + set_has_gpg_id(); + if (gpg_id_ == &::google::protobuf::internal::kEmptyString) { + gpg_id_ = new ::std::string; + } + gpg_id_->assign(value); +} +inline void RequestAddPeer::set_gpg_id(const char* value, size_t size) { + set_has_gpg_id(); + if (gpg_id_ == &::google::protobuf::internal::kEmptyString) { + gpg_id_ = new ::std::string; + } + gpg_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* RequestAddPeer::mutable_gpg_id() { + set_has_gpg_id(); + if (gpg_id_ == &::google::protobuf::internal::kEmptyString) { + gpg_id_ = new ::std::string; + } + return gpg_id_; +} +inline ::std::string* RequestAddPeer::release_gpg_id() { + clear_has_gpg_id(); + if (gpg_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = gpg_id_; + gpg_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// required .rsctrl.peers.RequestAddPeer.AddCmd cmd = 2; +inline bool RequestAddPeer::has_cmd() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void RequestAddPeer::set_has_cmd() { + _has_bits_[0] |= 0x00000002u; +} +inline void RequestAddPeer::clear_has_cmd() { + _has_bits_[0] &= ~0x00000002u; +} +inline void RequestAddPeer::clear_cmd() { + cmd_ = 0; + clear_has_cmd(); +} +inline ::rsctrl::peers::RequestAddPeer_AddCmd RequestAddPeer::cmd() const { + return static_cast< ::rsctrl::peers::RequestAddPeer_AddCmd >(cmd_); +} +inline void RequestAddPeer::set_cmd(::rsctrl::peers::RequestAddPeer_AddCmd value) { + GOOGLE_DCHECK(::rsctrl::peers::RequestAddPeer_AddCmd_IsValid(value)); + set_has_cmd(); + cmd_ = value; +} + +// optional string cert = 3; +inline bool RequestAddPeer::has_cert() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void RequestAddPeer::set_has_cert() { + _has_bits_[0] |= 0x00000004u; +} +inline void RequestAddPeer::clear_has_cert() { + _has_bits_[0] &= ~0x00000004u; +} +inline void RequestAddPeer::clear_cert() { + if (cert_ != &::google::protobuf::internal::kEmptyString) { + cert_->clear(); + } + clear_has_cert(); +} +inline const ::std::string& RequestAddPeer::cert() const { + return *cert_; +} +inline void RequestAddPeer::set_cert(const ::std::string& value) { + set_has_cert(); + if (cert_ == &::google::protobuf::internal::kEmptyString) { + cert_ = new ::std::string; + } + cert_->assign(value); +} +inline void RequestAddPeer::set_cert(const char* value) { + set_has_cert(); + if (cert_ == &::google::protobuf::internal::kEmptyString) { + cert_ = new ::std::string; + } + cert_->assign(value); +} +inline void RequestAddPeer::set_cert(const char* value, size_t size) { + set_has_cert(); + if (cert_ == &::google::protobuf::internal::kEmptyString) { + cert_ = new ::std::string; + } + cert_->assign(reinterpret_cast(value), size); +} +inline ::std::string* RequestAddPeer::mutable_cert() { + set_has_cert(); + if (cert_ == &::google::protobuf::internal::kEmptyString) { + cert_ = new ::std::string; + } + return cert_; +} +inline ::std::string* RequestAddPeer::release_cert() { + clear_has_cert(); + if (cert_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = cert_; + cert_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// ------------------------------------------------------------------- + +// ResponseAddPeer + +// required .rsctrl.base.Status status = 1; +inline bool ResponseAddPeer::has_status() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ResponseAddPeer::set_has_status() { + _has_bits_[0] |= 0x00000001u; +} +inline void ResponseAddPeer::clear_has_status() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ResponseAddPeer::clear_status() { + if (status_ != NULL) status_->::rsctrl::base::Status::Clear(); + clear_has_status(); +} +inline const ::rsctrl::base::Status& ResponseAddPeer::status() const { + return status_ != NULL ? *status_ : *default_instance_->status_; +} +inline ::rsctrl::base::Status* ResponseAddPeer::mutable_status() { + set_has_status(); + if (status_ == NULL) status_ = new ::rsctrl::base::Status; + return status_; +} +inline ::rsctrl::base::Status* ResponseAddPeer::release_status() { + clear_has_status(); + ::rsctrl::base::Status* temp = status_; + status_ = NULL; + return temp; +} + +// repeated .rsctrl.base.Person peers = 2; +inline int ResponseAddPeer::peers_size() const { + return peers_.size(); +} +inline void ResponseAddPeer::clear_peers() { + peers_.Clear(); +} +inline const ::rsctrl::base::Person& ResponseAddPeer::peers(int index) const { + return peers_.Get(index); +} +inline ::rsctrl::base::Person* ResponseAddPeer::mutable_peers(int index) { + return peers_.Mutable(index); +} +inline ::rsctrl::base::Person* ResponseAddPeer::add_peers() { + return peers_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >& +ResponseAddPeer::peers() const { + return peers_; +} +inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >* +ResponseAddPeer::mutable_peers() { + return &peers_; +} + +// ------------------------------------------------------------------- + +// RequestModifyPeer + +// required .rsctrl.peers.RequestModifyPeer.ModCmd cmd = 1; +inline bool RequestModifyPeer::has_cmd() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void RequestModifyPeer::set_has_cmd() { + _has_bits_[0] |= 0x00000001u; +} +inline void RequestModifyPeer::clear_has_cmd() { + _has_bits_[0] &= ~0x00000001u; +} +inline void RequestModifyPeer::clear_cmd() { + cmd_ = 0; + clear_has_cmd(); +} +inline ::rsctrl::peers::RequestModifyPeer_ModCmd RequestModifyPeer::cmd() const { + return static_cast< ::rsctrl::peers::RequestModifyPeer_ModCmd >(cmd_); +} +inline void RequestModifyPeer::set_cmd(::rsctrl::peers::RequestModifyPeer_ModCmd value) { + GOOGLE_DCHECK(::rsctrl::peers::RequestModifyPeer_ModCmd_IsValid(value)); + set_has_cmd(); + cmd_ = value; +} + +// repeated .rsctrl.base.Person peers = 2; +inline int RequestModifyPeer::peers_size() const { + return peers_.size(); +} +inline void RequestModifyPeer::clear_peers() { + peers_.Clear(); +} +inline const ::rsctrl::base::Person& RequestModifyPeer::peers(int index) const { + return peers_.Get(index); +} +inline ::rsctrl::base::Person* RequestModifyPeer::mutable_peers(int index) { + return peers_.Mutable(index); +} +inline ::rsctrl::base::Person* RequestModifyPeer::add_peers() { + return peers_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >& +RequestModifyPeer::peers() const { + return peers_; +} +inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >* +RequestModifyPeer::mutable_peers() { + return &peers_; +} + +// ------------------------------------------------------------------- + +// ResponseModifyPeer + +// required .rsctrl.base.Status status = 1; +inline bool ResponseModifyPeer::has_status() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ResponseModifyPeer::set_has_status() { + _has_bits_[0] |= 0x00000001u; +} +inline void ResponseModifyPeer::clear_has_status() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ResponseModifyPeer::clear_status() { + if (status_ != NULL) status_->::rsctrl::base::Status::Clear(); + clear_has_status(); +} +inline const ::rsctrl::base::Status& ResponseModifyPeer::status() const { + return status_ != NULL ? *status_ : *default_instance_->status_; +} +inline ::rsctrl::base::Status* ResponseModifyPeer::mutable_status() { + set_has_status(); + if (status_ == NULL) status_ = new ::rsctrl::base::Status; + return status_; +} +inline ::rsctrl::base::Status* ResponseModifyPeer::release_status() { + clear_has_status(); + ::rsctrl::base::Status* temp = status_; + status_ = NULL; + return temp; +} + +// repeated .rsctrl.base.Person peers = 2; +inline int ResponseModifyPeer::peers_size() const { + return peers_.size(); +} +inline void ResponseModifyPeer::clear_peers() { + peers_.Clear(); +} +inline const ::rsctrl::base::Person& ResponseModifyPeer::peers(int index) const { + return peers_.Get(index); +} +inline ::rsctrl::base::Person* ResponseModifyPeer::mutable_peers(int index) { + return peers_.Mutable(index); +} +inline ::rsctrl::base::Person* ResponseModifyPeer::add_peers() { + return peers_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >& +ResponseModifyPeer::peers() const { + return peers_; +} +inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >* +ResponseModifyPeer::mutable_peers() { + return &peers_; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace peers +} // namespace rsctrl + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::peers::RequestPeers_SetOption>() { + return ::rsctrl::peers::RequestPeers_SetOption_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::peers::RequestPeers_InfoOption>() { + return ::rsctrl::peers::RequestPeers_InfoOption_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::peers::RequestAddPeer_AddCmd>() { + return ::rsctrl::peers::RequestAddPeer_AddCmd_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::peers::RequestModifyPeer_ModCmd>() { + return ::rsctrl::peers::RequestModifyPeer_ModCmd_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< rsctrl::peers::ExtensionId>() { + return rsctrl::peers::ExtensionId_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< rsctrl::peers::PackageId>() { + return rsctrl::peers::PackageId_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< rsctrl::peers::RequestMsgIds>() { + return rsctrl::peers::RequestMsgIds_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< rsctrl::peers::ResponseMsgIds>() { + return rsctrl::peers::ResponseMsgIds_descriptor(); +} + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_peers_2eproto__INCLUDED diff --git a/retroshare-nogui/src/rpc/proto/rpcprotopeers.cc b/retroshare-nogui/src/rpc/proto/rpcprotopeers.cc new file mode 100644 index 000000000..7f4e07838 --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/rpcprotopeers.cc @@ -0,0 +1,255 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "rpc/proto/rpcprotopeers.h" +#include "rpc/proto/gencc/peers.pb.h" + +#include +#include +#include + +RpcProtoPeers::RpcProtoPeers(uint32_t serviceId) + :RpcQueueService(serviceId) +{ + return; +} + +//RpcProtoPeers::msgsAccepted(std::list &msgIds); /* not used at the moment */ + +int RpcProtoPeers::processMsg(uint32_t msg_id, uint32_t req_id, const std::string &msg) +{ + /* check the msgId */ + uint8_t topbyte = 0; + uint8_t service = 0; + uint8_t submsg = 0; + + std::cerr << "RpcProtoPeers::processMsg() topbyte: " << topbyte; + std::cerr << " service: " << service << " submsg: " << submsg; + std::cerr << std::endl; + + if (service != (uint8_t) rsctrl::peers::BASE) + { + std::cerr << "RpcProtoPeers::processMsg() Service Mismatch - not processing"; + std::cerr << std::endl; + return 0; + } + + if (!rsctrl::peers::RequestMsgIds_IsValid(submsg)) + { + std::cerr << "RpcProtoPeers::processMsg() SubMsg Mismatch - not processing"; + std::cerr << std::endl; + return 0; + } + + switch(submsg) + { + case rsctrl::peers::MsgId_RequestPeers: + processRequestPeers(msg_id, req_id, msg); + break; + case rsctrl::peers::MsgId_RequestAddPeer: + processAddPeer(msg_id, req_id, msg); + break; + case rsctrl::peers::MsgId_RequestModifyPeer: + processModifyPeer(msg_id, req_id, msg); + break; + default: + std::cerr << "RpcProtoPeers::processMsg() ERROR should never get here"; + std::cerr << std::endl; + return 0; + } + + /* must have matched id to get here */ + return 1; +} + + +int RpcProtoPeers::processAddPeer(uint32_t msg_id, uint32_t req_id, const std::string &msg) +{ + std::cerr << "RpcProtoPeers::processAddPeer() NOT FINISHED"; + std::cerr << std::endl; + + return 0; +} + + +int RpcProtoPeers::processModifyPeer(uint32_t msg_id, uint32_t req_id, const std::string &msg) +{ + std::cerr << "RpcProtoPeers::processModifyPeer() NOT FINISHED"; + std::cerr << std::endl; + + return 0; +} + + + +int RpcProtoPeers::processRequestPeers(uint32_t msg_id, uint32_t req_id, const std::string &msg) +{ + std::cerr << "RpcProtoPeers::processRequestPeers()"; + std::cerr << std::endl; + + // parse msg. + rsctrl::peers::RequestPeers reqp; + if (!reqp.ParseFromString(msg)) + { + std::cerr << "RpcProtoPeers::processRequestPeers() ERROR ParseFromString()"; + std::cerr << std::endl; + return 0; + } + + // Get the list of gpg_id to generate data for. + std::list ids; + bool onlyOnline = false; + switch(reqp.set()) + { + case rsctrl::peers::RequestPeers::OWNID: + { + std::string own_id = rsPeers->getGPGOwnId(); + ids.push_back(own_id); + break; + } + case rsctrl::peers::RequestPeers::LISTED: + { + /* extract ids from request (TODO) */ + std::string own_id = rsPeers->getGPGOwnId(); + ids.push_back(own_id); + break; + + } + case rsctrl::peers::RequestPeers::ALL: + rsPeers->getGPGAllList(ids); + break; + case rsctrl::peers::RequestPeers::ONLINE: + { + /* this ones a bit hard too */ + onlyOnline = true; + std::list ssl_ids; + std::list::const_iterator sit; + rsPeers->getOnlineList(ssl_ids); + for(sit = ssl_ids.begin(); sit != ssl_ids.end(); sit++) + { + std::string gpg_id = rsPeers->getGPGId(*sit); + if (gpg_id.size() > 0) + { + if (std::find(ids.begin(), ids.end(),gpg_id) == ids.end()) + { + ids.push_back(gpg_id); + } + } + } + break; + } + case rsctrl::peers::RequestPeers::FRIENDS: + rsPeers->getGPGAcceptedList(ids); + break; + case rsctrl::peers::RequestPeers::SIGNED: + rsPeers->getGPGSignedList(ids); + break; + case rsctrl::peers::RequestPeers::VALID: + rsPeers->getGPGSignedList(ids); + break; + } + + + // work out what data we need to request. + bool getLocations = false; + switch(reqp.info()) + { + default: + case rsctrl::peers::RequestPeers::NAMEONLY: + case rsctrl::peers::RequestPeers::BASIC: + break; + case rsctrl::peers::RequestPeers::LOCATION: + case rsctrl::peers::RequestPeers::ALLINFO: + getLocations = true; + break; + } + + // response. + rsctrl::peers::ResponsePeerList respp; + + /* now iterate through the peers and fill in the response. */ + std::list::const_iterator git; + for(git = ids.begin(); git != ids.end(); git++) + { + + RsPeerDetails details; + if (!rsPeers->getGPGDetails(*git, details)) + { + continue; /* uhm.. */ + } + + rsctrl::base::Person *person = respp.add_peers(); + + + /* fill in key gpg details */ + + + + + if (getLocations) + { + std::list ssl_ids; + std::list::const_iterator sit; + + if (!rsPeers->getAssociatedSSLIds(*git, ssl_ids)) + { + continue; /* end of this peer */ + } + + for(sit = ssl_ids.begin(); sit != ssl_ids.end(); sit++) + { + RsPeerDetails ssldetails; + if (!rsPeers->getPeerDetails(*sit, ssldetails)) + { + continue; /* uhm.. */ + } + + rsctrl::base::Location *loc = person->add_locations(); + + /* fill in ssl details */ + } + } + } + + + std::string outmsg; + if (!respp.SerializeToString(&outmsg)) + { + std::cerr << "RpcProtoPeers::processRequestPeers() ERROR SerialiseToString()"; + std::cerr << std::endl; + return 0; + } + + // Correctly Name Message. + uint32_t out_msg_id = create_msg_id( + rsctrl::peers::BASE, + rsctrl::peers::MsgId_ResponsePeerList); + + // queue it. + queueResponse(out_msg_id, req_id, outmsg); +} + + + + + diff --git a/retroshare-nogui/src/rpc/proto/rpcprotopeers.h b/retroshare-nogui/src/rpc/proto/rpcprotopeers.h new file mode 100644 index 000000000..d9dd2ef1d --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/rpcprotopeers.h @@ -0,0 +1,43 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + + +#ifndef RS_RPC_PROTO_PEERS_H +#define RS_RPC_PROTO_PEERS_H + +#include "rpc/rpcserver.h" + +class RpcProtoPeers: RpcQueueService +{ +public: + RpcProtoPeers(uint32_t serviceId); +// virtual msgsAccepted(std::list &msgIds); /* not used at the moment */ + virtual int processMsg(uint32_t msgId, uint32_t req_id, const std::string &msg); + + virtual int processRequestPeers(uint32_t msg_id, uint32_t req_id, const std::string &msg); + virtual int processAddPeer(uint32_t msg_id, uint32_t req_id, const std::string &msg); + virtual int processModifyPeer(uint32_t msg_id, uint32_t req_id, const std::string &msg); +}; + + +#endif /* RS_PROTO_PEERS_H */ From b67f66faa0bfbdf0b6317aa9c25ccae868eacef8 Mon Sep 17 00:00:00 2001 From: drbob Date: Thu, 23 Aug 2012 15:20:43 +0000 Subject: [PATCH 034/222] Put the first rpc service into action. (untested though). * Added functions to split up MsgId into Extension / Service / SubMsg. * Updated the generated code. * Switched on compilation too. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5461 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/retroshare-nogui.pro | 2 +- .../src/rpc/proto/gencc/base.pb.cc | 937 +++++++++++++++++- .../src/rpc/proto/gencc/base.pb.h | 619 ++++++++++++ .../src/rpc/proto/gencc/peers.pb.cc | 89 +- .../src/rpc/proto/gencc/peers.pb.h | 60 +- .../src/rpc/proto/rpcprotopeers.cc | 36 +- .../src/rpc/proto/rpcprotopeers.h | 2 +- retroshare-nogui/src/rpc/rpcserver.cc | 39 + retroshare-nogui/src/rpc/rpcserver.h | 9 + retroshare-nogui/src/rpc/rpcsetup.cc | 7 +- 10 files changed, 1677 insertions(+), 123 deletions(-) diff --git a/retroshare-nogui/src/retroshare-nogui.pro b/retroshare-nogui/src/retroshare-nogui.pro index d56e5c1e5..7ad06d836 100644 --- a/retroshare-nogui/src/retroshare-nogui.pro +++ b/retroshare-nogui/src/retroshare-nogui.pro @@ -179,7 +179,7 @@ sshserver { DEFINES *= RS_SSH_SERVER # Include Protobuf classes. - #CONFIG += protorpc + CONFIG += protorpc } protorpc { diff --git a/retroshare-nogui/src/rpc/proto/gencc/base.pb.cc b/retroshare-nogui/src/rpc/proto/gencc/base.pb.cc index 0a2821fa2..30854a9d3 100644 --- a/retroshare-nogui/src/rpc/proto/gencc/base.pb.cc +++ b/retroshare-nogui/src/rpc/proto/gencc/base.pb.cc @@ -34,6 +34,18 @@ const ::google::protobuf::internal::GeneratedMessageReflection* const ::google::protobuf::Descriptor* Dir_descriptor_ = NULL; const ::google::protobuf::internal::GeneratedMessageReflection* Dir_reflection_ = NULL; +const ::google::protobuf::Descriptor* SystemStatus_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + SystemStatus_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* SystemStatus_NetCode_descriptor_ = NULL; +const ::google::protobuf::Descriptor* Bandwidth_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Bandwidth_reflection_ = NULL; +const ::google::protobuf::Descriptor* BandwidthSet_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + BandwidthSet_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* ExtensionId_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* PackageId_descriptor_ = NULL; } // namespace @@ -133,6 +145,57 @@ void protobuf_AssignDesc_base_2eproto() { ::google::protobuf::DescriptorPool::generated_pool(), ::google::protobuf::MessageFactory::generated_factory(), sizeof(Dir)); + SystemStatus_descriptor_ = file->message_type(5); + static const int SystemStatus_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SystemStatus, net_status_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SystemStatus, msg_), + }; + SystemStatus_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + SystemStatus_descriptor_, + SystemStatus::default_instance_, + SystemStatus_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SystemStatus, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SystemStatus, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(SystemStatus)); + SystemStatus_NetCode_descriptor_ = SystemStatus_descriptor_->enum_type(0); + Bandwidth_descriptor_ = file->message_type(6); + static const int Bandwidth_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Bandwidth, up_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Bandwidth, down_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Bandwidth, name_), + }; + Bandwidth_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + Bandwidth_descriptor_, + Bandwidth::default_instance_, + Bandwidth_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Bandwidth, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Bandwidth, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(Bandwidth)); + BandwidthSet_descriptor_ = file->message_type(7); + static const int BandwidthSet_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BandwidthSet, bandwidths_), + }; + BandwidthSet_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + BandwidthSet_descriptor_, + BandwidthSet::default_instance_, + BandwidthSet_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BandwidthSet, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BandwidthSet, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(BandwidthSet)); + ExtensionId_descriptor_ = file->enum_type(0); + PackageId_descriptor_ = file->enum_type(1); } namespace { @@ -155,6 +218,12 @@ void protobuf_RegisterTypes(const ::std::string&) { File_descriptor_, &File::default_instance()); ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( Dir_descriptor_, &Dir::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + SystemStatus_descriptor_, &SystemStatus::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Bandwidth_descriptor_, &Bandwidth::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + BandwidthSet_descriptor_, &BandwidthSet::default_instance()); } } // namespace @@ -170,6 +239,12 @@ void protobuf_ShutdownFile_base_2eproto() { delete File_reflection_; delete Dir::default_instance_; delete Dir_reflection_; + delete SystemStatus::default_instance_; + delete SystemStatus_reflection_; + delete Bandwidth::default_instance_; + delete Bandwidth_reflection_; + delete BandwidthSet::default_instance_; + delete BandwidthSet_reflection_; } void protobuf_AddDesc_base_2eproto() { @@ -191,7 +266,19 @@ void protobuf_AddDesc_base_2eproto() { "\030\002 \002(\t\022\014\n\004size\030\003 \002(\003\022\014\n\004path\030\004 \001(\t\022\r\n\005av" "ail\030\005 \001(\t\"f\n\003Dir\022\014\n\004name\030\001 \002(\t\022\014\n\004path\030\002" " \002(\t\022!\n\007subdirs\030\003 \003(\0132\020.rsctrl.base.Dir\022" - " \n\005files\030\004 \003(\0132\021.rsctrl.base.File", 513); + " \n\005files\030\004 \003(\0132\021.rsctrl.base.File\"\372\001\n\014Sy" + "stemStatus\0225\n\nnet_status\030\001 \002(\0162!.rsctrl." + "base.SystemStatus.NetCode\022\013\n\003msg\030\002 \001(\t\"\245" + "\001\n\007NetCode\022\017\n\013BAD_UNKNOWN\020\000\022\017\n\013BAD_OFFLI" + "NE\020\001\022\016\n\nBAD_NATSYM\020\002\022\021\n\rBAD_NODHT_NAT\020\003\022" + "\023\n\017WARNING_RESTART\020\004\022\022\n\016WARNING_NATTED\020\005" + "\022\021\n\rWARNING_NODHT\020\006\022\010\n\004GOOD\020\007\022\017\n\013ADV_FOR" + "WARD\020\010\"3\n\tBandwidth\022\n\n\002up\030\001 \002(\002\022\014\n\004down\030" + "\002 \002(\002\022\014\n\004name\030\003 \001(\t\":\n\014BandwidthSet\022*\n\nb" + "andwidths\030\001 \003(\0132\026.rsctrl.base.Bandwidth*" + "\027\n\013ExtensionId\022\010\n\004BASE\020\000*A\n\tPackageId\022\t\n" + "\005PEERS\020\001\022\n\n\006SYSTEM\020\002\022\t\n\005FILES\020\003\022\010\n\004MSGS\020" + "\004\022\010\n\003GXS\020\350\007", 971); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "base.proto", &protobuf_RegisterTypes); Status::default_instance_ = new Status(); @@ -199,11 +286,17 @@ void protobuf_AddDesc_base_2eproto() { Person::default_instance_ = new Person(); File::default_instance_ = new File(); Dir::default_instance_ = new Dir(); + SystemStatus::default_instance_ = new SystemStatus(); + Bandwidth::default_instance_ = new Bandwidth(); + BandwidthSet::default_instance_ = new BandwidthSet(); Status::default_instance_->InitAsDefaultInstance(); Location::default_instance_->InitAsDefaultInstance(); Person::default_instance_->InitAsDefaultInstance(); File::default_instance_->InitAsDefaultInstance(); Dir::default_instance_->InitAsDefaultInstance(); + SystemStatus::default_instance_->InitAsDefaultInstance(); + Bandwidth::default_instance_->InitAsDefaultInstance(); + BandwidthSet::default_instance_->InitAsDefaultInstance(); ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_base_2eproto); } @@ -214,6 +307,36 @@ struct StaticDescriptorInitializer_base_2eproto { } } static_descriptor_initializer_base_2eproto_; +const ::google::protobuf::EnumDescriptor* ExtensionId_descriptor() { + protobuf_AssignDescriptorsOnce(); + return ExtensionId_descriptor_; +} +bool ExtensionId_IsValid(int value) { + switch(value) { + case 0: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* PackageId_descriptor() { + protobuf_AssignDescriptorsOnce(); + return PackageId_descriptor_; +} +bool PackageId_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 3: + case 4: + case 1000: + return true; + default: + return false; + } +} + // =================================================================== @@ -2036,6 +2159,818 @@ void Dir::Swap(Dir* other) { } +// =================================================================== + +const ::google::protobuf::EnumDescriptor* SystemStatus_NetCode_descriptor() { + protobuf_AssignDescriptorsOnce(); + return SystemStatus_NetCode_descriptor_; +} +bool SystemStatus_NetCode_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const SystemStatus_NetCode SystemStatus::BAD_UNKNOWN; +const SystemStatus_NetCode SystemStatus::BAD_OFFLINE; +const SystemStatus_NetCode SystemStatus::BAD_NATSYM; +const SystemStatus_NetCode SystemStatus::BAD_NODHT_NAT; +const SystemStatus_NetCode SystemStatus::WARNING_RESTART; +const SystemStatus_NetCode SystemStatus::WARNING_NATTED; +const SystemStatus_NetCode SystemStatus::WARNING_NODHT; +const SystemStatus_NetCode SystemStatus::GOOD; +const SystemStatus_NetCode SystemStatus::ADV_FORWARD; +const SystemStatus_NetCode SystemStatus::NetCode_MIN; +const SystemStatus_NetCode SystemStatus::NetCode_MAX; +const int SystemStatus::NetCode_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int SystemStatus::kNetStatusFieldNumber; +const int SystemStatus::kMsgFieldNumber; +#endif // !_MSC_VER + +SystemStatus::SystemStatus() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void SystemStatus::InitAsDefaultInstance() { +} + +SystemStatus::SystemStatus(const SystemStatus& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void SystemStatus::SharedCtor() { + _cached_size_ = 0; + net_status_ = 0; + msg_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +SystemStatus::~SystemStatus() { + SharedDtor(); +} + +void SystemStatus::SharedDtor() { + if (msg_ != &::google::protobuf::internal::kEmptyString) { + delete msg_; + } + if (this != default_instance_) { + } +} + +void SystemStatus::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* SystemStatus::descriptor() { + protobuf_AssignDescriptorsOnce(); + return SystemStatus_descriptor_; +} + +const SystemStatus& SystemStatus::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_base_2eproto(); return *default_instance_; +} + +SystemStatus* SystemStatus::default_instance_ = NULL; + +SystemStatus* SystemStatus::New() const { + return new SystemStatus; +} + +void SystemStatus::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + net_status_ = 0; + if (has_msg()) { + if (msg_ != &::google::protobuf::internal::kEmptyString) { + msg_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool SystemStatus::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.base.SystemStatus.NetCode net_status = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::rsctrl::base::SystemStatus_NetCode_IsValid(value)) { + set_net_status(static_cast< ::rsctrl::base::SystemStatus_NetCode >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_msg; + break; + } + + // optional string msg = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_msg: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_msg())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->msg().data(), this->msg().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void SystemStatus::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.base.SystemStatus.NetCode net_status = 1; + if (has_net_status()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->net_status(), output); + } + + // optional string msg = 2; + if (has_msg()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->msg().data(), this->msg().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->msg(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* SystemStatus::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.base.SystemStatus.NetCode net_status = 1; + if (has_net_status()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->net_status(), target); + } + + // optional string msg = 2; + if (has_msg()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->msg().data(), this->msg().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->msg(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int SystemStatus::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.base.SystemStatus.NetCode net_status = 1; + if (has_net_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->net_status()); + } + + // optional string msg = 2; + if (has_msg()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->msg()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void SystemStatus::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const SystemStatus* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void SystemStatus::MergeFrom(const SystemStatus& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_net_status()) { + set_net_status(from.net_status()); + } + if (from.has_msg()) { + set_msg(from.msg()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void SystemStatus::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void SystemStatus::CopyFrom(const SystemStatus& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool SystemStatus::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void SystemStatus::Swap(SystemStatus* other) { + if (other != this) { + std::swap(net_status_, other->net_status_); + std::swap(msg_, other->msg_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata SystemStatus::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = SystemStatus_descriptor_; + metadata.reflection = SystemStatus_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int Bandwidth::kUpFieldNumber; +const int Bandwidth::kDownFieldNumber; +const int Bandwidth::kNameFieldNumber; +#endif // !_MSC_VER + +Bandwidth::Bandwidth() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void Bandwidth::InitAsDefaultInstance() { +} + +Bandwidth::Bandwidth(const Bandwidth& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void Bandwidth::SharedCtor() { + _cached_size_ = 0; + up_ = 0; + down_ = 0; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Bandwidth::~Bandwidth() { + SharedDtor(); +} + +void Bandwidth::SharedDtor() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + delete name_; + } + if (this != default_instance_) { + } +} + +void Bandwidth::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Bandwidth::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Bandwidth_descriptor_; +} + +const Bandwidth& Bandwidth::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_base_2eproto(); return *default_instance_; +} + +Bandwidth* Bandwidth::default_instance_ = NULL; + +Bandwidth* Bandwidth::New() const { + return new Bandwidth; +} + +void Bandwidth::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + up_ = 0; + down_ = 0; + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool Bandwidth::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required float up = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, &up_))); + set_has_up(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(21)) goto parse_down; + break; + } + + // required float down = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_down: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, &down_))); + set_has_down(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_name; + break; + } + + // optional string name = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void Bandwidth::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required float up = 1; + if (has_up()) { + ::google::protobuf::internal::WireFormatLite::WriteFloat(1, this->up(), output); + } + + // required float down = 2; + if (has_down()) { + ::google::protobuf::internal::WireFormatLite::WriteFloat(2, this->down(), output); + } + + // optional string name = 3; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->name(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* Bandwidth::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required float up = 1; + if (has_up()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(1, this->up(), target); + } + + // required float down = 2; + if (has_down()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(2, this->down(), target); + } + + // optional string name = 3; + if (has_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->name(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int Bandwidth::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required float up = 1; + if (has_up()) { + total_size += 1 + 4; + } + + // required float down = 2; + if (has_down()) { + total_size += 1 + 4; + } + + // optional string name = 3; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Bandwidth::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const Bandwidth* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Bandwidth::MergeFrom(const Bandwidth& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_up()) { + set_up(from.up()); + } + if (from.has_down()) { + set_down(from.down()); + } + if (from.has_name()) { + set_name(from.name()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void Bandwidth::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Bandwidth::CopyFrom(const Bandwidth& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Bandwidth::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void Bandwidth::Swap(Bandwidth* other) { + if (other != this) { + std::swap(up_, other->up_); + std::swap(down_, other->down_); + std::swap(name_, other->name_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata Bandwidth::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Bandwidth_descriptor_; + metadata.reflection = Bandwidth_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int BandwidthSet::kBandwidthsFieldNumber; +#endif // !_MSC_VER + +BandwidthSet::BandwidthSet() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void BandwidthSet::InitAsDefaultInstance() { +} + +BandwidthSet::BandwidthSet(const BandwidthSet& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void BandwidthSet::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +BandwidthSet::~BandwidthSet() { + SharedDtor(); +} + +void BandwidthSet::SharedDtor() { + if (this != default_instance_) { + } +} + +void BandwidthSet::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* BandwidthSet::descriptor() { + protobuf_AssignDescriptorsOnce(); + return BandwidthSet_descriptor_; +} + +const BandwidthSet& BandwidthSet::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_base_2eproto(); return *default_instance_; +} + +BandwidthSet* BandwidthSet::default_instance_ = NULL; + +BandwidthSet* BandwidthSet::New() const { + return new BandwidthSet; +} + +void BandwidthSet::Clear() { + bandwidths_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool BandwidthSet::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .rsctrl.base.Bandwidth bandwidths = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_bandwidths: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_bandwidths())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_bandwidths; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void BandwidthSet::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated .rsctrl.base.Bandwidth bandwidths = 1; + for (int i = 0; i < this->bandwidths_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->bandwidths(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* BandwidthSet::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated .rsctrl.base.Bandwidth bandwidths = 1; + for (int i = 0; i < this->bandwidths_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->bandwidths(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int BandwidthSet::ByteSize() const { + int total_size = 0; + + // repeated .rsctrl.base.Bandwidth bandwidths = 1; + total_size += 1 * this->bandwidths_size(); + for (int i = 0; i < this->bandwidths_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->bandwidths(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void BandwidthSet::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const BandwidthSet* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void BandwidthSet::MergeFrom(const BandwidthSet& from) { + GOOGLE_CHECK_NE(&from, this); + bandwidths_.MergeFrom(from.bandwidths_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void BandwidthSet::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void BandwidthSet::CopyFrom(const BandwidthSet& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool BandwidthSet::IsInitialized() const { + + for (int i = 0; i < bandwidths_size(); i++) { + if (!this->bandwidths(i).IsInitialized()) return false; + } + return true; +} + +void BandwidthSet::Swap(BandwidthSet* other) { + if (other != this) { + bandwidths_.Swap(&other->bandwidths_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata BandwidthSet::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = BandwidthSet_descriptor_; + metadata.reflection = BandwidthSet_reflection_; + return metadata; +} + + // @@protoc_insertion_point(namespace_scope) } // namespace base diff --git a/retroshare-nogui/src/rpc/proto/gencc/base.pb.h b/retroshare-nogui/src/rpc/proto/gencc/base.pb.h index d1819b91b..35dfa7841 100644 --- a/retroshare-nogui/src/rpc/proto/gencc/base.pb.h +++ b/retroshare-nogui/src/rpc/proto/gencc/base.pb.h @@ -38,6 +38,9 @@ class Location; class Person; class File; class Dir; +class SystemStatus; +class Bandwidth; +class BandwidthSet; enum Status_StatusCode { Status_StatusCode_FAILED = 0, @@ -60,6 +63,72 @@ inline bool Status_StatusCode_Parse( return ::google::protobuf::internal::ParseNamedEnum( Status_StatusCode_descriptor(), name, value); } +enum SystemStatus_NetCode { + SystemStatus_NetCode_BAD_UNKNOWN = 0, + SystemStatus_NetCode_BAD_OFFLINE = 1, + SystemStatus_NetCode_BAD_NATSYM = 2, + SystemStatus_NetCode_BAD_NODHT_NAT = 3, + SystemStatus_NetCode_WARNING_RESTART = 4, + SystemStatus_NetCode_WARNING_NATTED = 5, + SystemStatus_NetCode_WARNING_NODHT = 6, + SystemStatus_NetCode_GOOD = 7, + SystemStatus_NetCode_ADV_FORWARD = 8 +}; +bool SystemStatus_NetCode_IsValid(int value); +const SystemStatus_NetCode SystemStatus_NetCode_NetCode_MIN = SystemStatus_NetCode_BAD_UNKNOWN; +const SystemStatus_NetCode SystemStatus_NetCode_NetCode_MAX = SystemStatus_NetCode_ADV_FORWARD; +const int SystemStatus_NetCode_NetCode_ARRAYSIZE = SystemStatus_NetCode_NetCode_MAX + 1; + +const ::google::protobuf::EnumDescriptor* SystemStatus_NetCode_descriptor(); +inline const ::std::string& SystemStatus_NetCode_Name(SystemStatus_NetCode value) { + return ::google::protobuf::internal::NameOfEnum( + SystemStatus_NetCode_descriptor(), value); +} +inline bool SystemStatus_NetCode_Parse( + const ::std::string& name, SystemStatus_NetCode* value) { + return ::google::protobuf::internal::ParseNamedEnum( + SystemStatus_NetCode_descriptor(), name, value); +} +enum ExtensionId { + BASE = 0 +}; +bool ExtensionId_IsValid(int value); +const ExtensionId ExtensionId_MIN = BASE; +const ExtensionId ExtensionId_MAX = BASE; +const int ExtensionId_ARRAYSIZE = ExtensionId_MAX + 1; + +const ::google::protobuf::EnumDescriptor* ExtensionId_descriptor(); +inline const ::std::string& ExtensionId_Name(ExtensionId value) { + return ::google::protobuf::internal::NameOfEnum( + ExtensionId_descriptor(), value); +} +inline bool ExtensionId_Parse( + const ::std::string& name, ExtensionId* value) { + return ::google::protobuf::internal::ParseNamedEnum( + ExtensionId_descriptor(), name, value); +} +enum PackageId { + PEERS = 1, + SYSTEM = 2, + FILES = 3, + MSGS = 4, + GXS = 1000 +}; +bool PackageId_IsValid(int value); +const PackageId PackageId_MIN = PEERS; +const PackageId PackageId_MAX = GXS; +const int PackageId_ARRAYSIZE = PackageId_MAX + 1; + +const ::google::protobuf::EnumDescriptor* PackageId_descriptor(); +inline const ::std::string& PackageId_Name(PackageId value) { + return ::google::protobuf::internal::NameOfEnum( + PackageId_descriptor(), value); +} +inline bool PackageId_Parse( + const ::std::string& name, PackageId* value) { + return ::google::protobuf::internal::ParseNamedEnum( + PackageId_descriptor(), name, value); +} // =================================================================== class Status : public ::google::protobuf::Message { @@ -687,6 +756,324 @@ class Dir : public ::google::protobuf::Message { void InitAsDefaultInstance(); static Dir* default_instance_; }; +// ------------------------------------------------------------------- + +class SystemStatus : public ::google::protobuf::Message { + public: + SystemStatus(); + virtual ~SystemStatus(); + + SystemStatus(const SystemStatus& from); + + inline SystemStatus& operator=(const SystemStatus& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const SystemStatus& default_instance(); + + void Swap(SystemStatus* other); + + // implements Message ---------------------------------------------- + + SystemStatus* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const SystemStatus& from); + void MergeFrom(const SystemStatus& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef SystemStatus_NetCode NetCode; + static const NetCode BAD_UNKNOWN = SystemStatus_NetCode_BAD_UNKNOWN; + static const NetCode BAD_OFFLINE = SystemStatus_NetCode_BAD_OFFLINE; + static const NetCode BAD_NATSYM = SystemStatus_NetCode_BAD_NATSYM; + static const NetCode BAD_NODHT_NAT = SystemStatus_NetCode_BAD_NODHT_NAT; + static const NetCode WARNING_RESTART = SystemStatus_NetCode_WARNING_RESTART; + static const NetCode WARNING_NATTED = SystemStatus_NetCode_WARNING_NATTED; + static const NetCode WARNING_NODHT = SystemStatus_NetCode_WARNING_NODHT; + static const NetCode GOOD = SystemStatus_NetCode_GOOD; + static const NetCode ADV_FORWARD = SystemStatus_NetCode_ADV_FORWARD; + static inline bool NetCode_IsValid(int value) { + return SystemStatus_NetCode_IsValid(value); + } + static const NetCode NetCode_MIN = + SystemStatus_NetCode_NetCode_MIN; + static const NetCode NetCode_MAX = + SystemStatus_NetCode_NetCode_MAX; + static const int NetCode_ARRAYSIZE = + SystemStatus_NetCode_NetCode_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + NetCode_descriptor() { + return SystemStatus_NetCode_descriptor(); + } + static inline const ::std::string& NetCode_Name(NetCode value) { + return SystemStatus_NetCode_Name(value); + } + static inline bool NetCode_Parse(const ::std::string& name, + NetCode* value) { + return SystemStatus_NetCode_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // required .rsctrl.base.SystemStatus.NetCode net_status = 1; + inline bool has_net_status() const; + inline void clear_net_status(); + static const int kNetStatusFieldNumber = 1; + inline ::rsctrl::base::SystemStatus_NetCode net_status() const; + inline void set_net_status(::rsctrl::base::SystemStatus_NetCode value); + + // optional string msg = 2; + inline bool has_msg() const; + inline void clear_msg(); + static const int kMsgFieldNumber = 2; + inline const ::std::string& msg() const; + inline void set_msg(const ::std::string& value); + inline void set_msg(const char* value); + inline void set_msg(const char* value, size_t size); + inline ::std::string* mutable_msg(); + inline ::std::string* release_msg(); + + // @@protoc_insertion_point(class_scope:rsctrl.base.SystemStatus) + private: + inline void set_has_net_status(); + inline void clear_has_net_status(); + inline void set_has_msg(); + inline void clear_has_msg(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* msg_; + int net_status_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_base_2eproto(); + friend void protobuf_AssignDesc_base_2eproto(); + friend void protobuf_ShutdownFile_base_2eproto(); + + void InitAsDefaultInstance(); + static SystemStatus* default_instance_; +}; +// ------------------------------------------------------------------- + +class Bandwidth : public ::google::protobuf::Message { + public: + Bandwidth(); + virtual ~Bandwidth(); + + Bandwidth(const Bandwidth& from); + + inline Bandwidth& operator=(const Bandwidth& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Bandwidth& default_instance(); + + void Swap(Bandwidth* other); + + // implements Message ---------------------------------------------- + + Bandwidth* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Bandwidth& from); + void MergeFrom(const Bandwidth& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required float up = 1; + inline bool has_up() const; + inline void clear_up(); + static const int kUpFieldNumber = 1; + inline float up() const; + inline void set_up(float value); + + // required float down = 2; + inline bool has_down() const; + inline void clear_down(); + static const int kDownFieldNumber = 2; + inline float down() const; + inline void set_down(float value); + + // optional string name = 3; + inline bool has_name() const; + inline void clear_name(); + static const int kNameFieldNumber = 3; + inline const ::std::string& name() const; + inline void set_name(const ::std::string& value); + inline void set_name(const char* value); + inline void set_name(const char* value, size_t size); + inline ::std::string* mutable_name(); + inline ::std::string* release_name(); + + // @@protoc_insertion_point(class_scope:rsctrl.base.Bandwidth) + private: + inline void set_has_up(); + inline void clear_has_up(); + inline void set_has_down(); + inline void clear_has_down(); + inline void set_has_name(); + inline void clear_has_name(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + float up_; + float down_; + ::std::string* name_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_base_2eproto(); + friend void protobuf_AssignDesc_base_2eproto(); + friend void protobuf_ShutdownFile_base_2eproto(); + + void InitAsDefaultInstance(); + static Bandwidth* default_instance_; +}; +// ------------------------------------------------------------------- + +class BandwidthSet : public ::google::protobuf::Message { + public: + BandwidthSet(); + virtual ~BandwidthSet(); + + BandwidthSet(const BandwidthSet& from); + + inline BandwidthSet& operator=(const BandwidthSet& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const BandwidthSet& default_instance(); + + void Swap(BandwidthSet* other); + + // implements Message ---------------------------------------------- + + BandwidthSet* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const BandwidthSet& from); + void MergeFrom(const BandwidthSet& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .rsctrl.base.Bandwidth bandwidths = 1; + inline int bandwidths_size() const; + inline void clear_bandwidths(); + static const int kBandwidthsFieldNumber = 1; + inline const ::rsctrl::base::Bandwidth& bandwidths(int index) const; + inline ::rsctrl::base::Bandwidth* mutable_bandwidths(int index); + inline ::rsctrl::base::Bandwidth* add_bandwidths(); + inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Bandwidth >& + bandwidths() const; + inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Bandwidth >* + mutable_bandwidths(); + + // @@protoc_insertion_point(class_scope:rsctrl.base.BandwidthSet) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Bandwidth > bandwidths_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_base_2eproto(); + friend void protobuf_AssignDesc_base_2eproto(); + friend void protobuf_ShutdownFile_base_2eproto(); + + void InitAsDefaultInstance(); + static BandwidthSet* default_instance_; +}; // =================================================================== @@ -1584,6 +1971,226 @@ Dir::mutable_files() { return &files_; } +// ------------------------------------------------------------------- + +// SystemStatus + +// required .rsctrl.base.SystemStatus.NetCode net_status = 1; +inline bool SystemStatus::has_net_status() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void SystemStatus::set_has_net_status() { + _has_bits_[0] |= 0x00000001u; +} +inline void SystemStatus::clear_has_net_status() { + _has_bits_[0] &= ~0x00000001u; +} +inline void SystemStatus::clear_net_status() { + net_status_ = 0; + clear_has_net_status(); +} +inline ::rsctrl::base::SystemStatus_NetCode SystemStatus::net_status() const { + return static_cast< ::rsctrl::base::SystemStatus_NetCode >(net_status_); +} +inline void SystemStatus::set_net_status(::rsctrl::base::SystemStatus_NetCode value) { + GOOGLE_DCHECK(::rsctrl::base::SystemStatus_NetCode_IsValid(value)); + set_has_net_status(); + net_status_ = value; +} + +// optional string msg = 2; +inline bool SystemStatus::has_msg() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void SystemStatus::set_has_msg() { + _has_bits_[0] |= 0x00000002u; +} +inline void SystemStatus::clear_has_msg() { + _has_bits_[0] &= ~0x00000002u; +} +inline void SystemStatus::clear_msg() { + if (msg_ != &::google::protobuf::internal::kEmptyString) { + msg_->clear(); + } + clear_has_msg(); +} +inline const ::std::string& SystemStatus::msg() const { + return *msg_; +} +inline void SystemStatus::set_msg(const ::std::string& value) { + set_has_msg(); + if (msg_ == &::google::protobuf::internal::kEmptyString) { + msg_ = new ::std::string; + } + msg_->assign(value); +} +inline void SystemStatus::set_msg(const char* value) { + set_has_msg(); + if (msg_ == &::google::protobuf::internal::kEmptyString) { + msg_ = new ::std::string; + } + msg_->assign(value); +} +inline void SystemStatus::set_msg(const char* value, size_t size) { + set_has_msg(); + if (msg_ == &::google::protobuf::internal::kEmptyString) { + msg_ = new ::std::string; + } + msg_->assign(reinterpret_cast(value), size); +} +inline ::std::string* SystemStatus::mutable_msg() { + set_has_msg(); + if (msg_ == &::google::protobuf::internal::kEmptyString) { + msg_ = new ::std::string; + } + return msg_; +} +inline ::std::string* SystemStatus::release_msg() { + clear_has_msg(); + if (msg_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = msg_; + msg_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// ------------------------------------------------------------------- + +// Bandwidth + +// required float up = 1; +inline bool Bandwidth::has_up() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void Bandwidth::set_has_up() { + _has_bits_[0] |= 0x00000001u; +} +inline void Bandwidth::clear_has_up() { + _has_bits_[0] &= ~0x00000001u; +} +inline void Bandwidth::clear_up() { + up_ = 0; + clear_has_up(); +} +inline float Bandwidth::up() const { + return up_; +} +inline void Bandwidth::set_up(float value) { + set_has_up(); + up_ = value; +} + +// required float down = 2; +inline bool Bandwidth::has_down() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void Bandwidth::set_has_down() { + _has_bits_[0] |= 0x00000002u; +} +inline void Bandwidth::clear_has_down() { + _has_bits_[0] &= ~0x00000002u; +} +inline void Bandwidth::clear_down() { + down_ = 0; + clear_has_down(); +} +inline float Bandwidth::down() const { + return down_; +} +inline void Bandwidth::set_down(float value) { + set_has_down(); + down_ = value; +} + +// optional string name = 3; +inline bool Bandwidth::has_name() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void Bandwidth::set_has_name() { + _has_bits_[0] |= 0x00000004u; +} +inline void Bandwidth::clear_has_name() { + _has_bits_[0] &= ~0x00000004u; +} +inline void Bandwidth::clear_name() { + if (name_ != &::google::protobuf::internal::kEmptyString) { + name_->clear(); + } + clear_has_name(); +} +inline const ::std::string& Bandwidth::name() const { + return *name_; +} +inline void Bandwidth::set_name(const ::std::string& value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void Bandwidth::set_name(const char* value) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(value); +} +inline void Bandwidth::set_name(const char* value, size_t size) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* Bandwidth::mutable_name() { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + name_ = new ::std::string; + } + return name_; +} +inline ::std::string* Bandwidth::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// ------------------------------------------------------------------- + +// BandwidthSet + +// repeated .rsctrl.base.Bandwidth bandwidths = 1; +inline int BandwidthSet::bandwidths_size() const { + return bandwidths_.size(); +} +inline void BandwidthSet::clear_bandwidths() { + bandwidths_.Clear(); +} +inline const ::rsctrl::base::Bandwidth& BandwidthSet::bandwidths(int index) const { + return bandwidths_.Get(index); +} +inline ::rsctrl::base::Bandwidth* BandwidthSet::mutable_bandwidths(int index) { + return bandwidths_.Mutable(index); +} +inline ::rsctrl::base::Bandwidth* BandwidthSet::add_bandwidths() { + return bandwidths_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Bandwidth >& +BandwidthSet::bandwidths() const { + return bandwidths_; +} +inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Bandwidth >* +BandwidthSet::mutable_bandwidths() { + return &bandwidths_; +} + // @@protoc_insertion_point(namespace_scope) @@ -1598,6 +2205,18 @@ template <> inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::base::Status_StatusCode>() { return ::rsctrl::base::Status_StatusCode_descriptor(); } +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::base::SystemStatus_NetCode>() { + return ::rsctrl::base::SystemStatus_NetCode_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< rsctrl::base::ExtensionId>() { + return rsctrl::base::ExtensionId_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< rsctrl::base::PackageId>() { + return rsctrl::base::PackageId_descriptor(); +} } // namespace google } // namespace protobuf diff --git a/retroshare-nogui/src/rpc/proto/gencc/peers.pb.cc b/retroshare-nogui/src/rpc/proto/gencc/peers.pb.cc index 880cc50e4..9fc028d38 100644 --- a/retroshare-nogui/src/rpc/proto/gencc/peers.pb.cc +++ b/retroshare-nogui/src/rpc/proto/gencc/peers.pb.cc @@ -40,8 +40,6 @@ const ::google::protobuf::EnumDescriptor* RequestModifyPeer_ModCmd_descriptor_ = const ::google::protobuf::Descriptor* ResponseModifyPeer_descriptor_ = NULL; const ::google::protobuf::internal::GeneratedMessageReflection* ResponseModifyPeer_reflection_ = NULL; -const ::google::protobuf::EnumDescriptor* ExtensionId_descriptor_ = NULL; -const ::google::protobuf::EnumDescriptor* PackageId_descriptor_ = NULL; const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor_ = NULL; const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor_ = NULL; @@ -156,10 +154,8 @@ void protobuf_AssignDesc_peers_2eproto() { ::google::protobuf::DescriptorPool::generated_pool(), ::google::protobuf::MessageFactory::generated_factory(), sizeof(ResponseModifyPeer)); - ExtensionId_descriptor_ = file->enum_type(0); - PackageId_descriptor_ = file->enum_type(1); - RequestMsgIds_descriptor_ = file->enum_type(2); - ResponseMsgIds_descriptor_ = file->enum_type(3); + RequestMsgIds_descriptor_ = file->enum_type(0); + ResponseMsgIds_descriptor_ = file->enum_type(1); } namespace { @@ -212,35 +208,34 @@ void protobuf_AddDesc_peers_2eproto() { ::rsctrl::base::protobuf_AddDesc_base_2eproto(); ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( "\n\013peers.proto\022\014rsctrl.peers\032\nbase.proto\"" - "\217\002\n\014RequestPeers\0221\n\003set\030\001 \002(\0162$.rsctrl.p" + "\246\002\n\014RequestPeers\0221\n\003set\030\001 \002(\0162$.rsctrl.p" "eers.RequestPeers.SetOption\0223\n\004info\030\002 \002(" "\0162%.rsctrl.peers.RequestPeers.InfoOption" - "\022\017\n\007gpg_ids\030\003 \003(\t\"D\n\tSetOption\022\n\n\006LISTED" - "\020\001\022\n\n\006ONLINE\020\002\022\013\n\007FRIENDS\020\003\022\t\n\005VALID\020\004\022\007" - "\n\003ALL\020\005\"@\n\nInfoOption\022\014\n\010NAMEONLY\020\001\022\t\n\005B" - "ASIC\020\002\022\014\n\010LOCATION\020\003\022\013\n\007ALLINFO\020\004\"[\n\020Res" - "ponsePeerList\022#\n\006status\030\001 \002(\0132\023.rsctrl.b" + "\022\017\n\007gpg_ids\030\003 \003(\t\"[\n\tSetOption\022\t\n\005OWNID\020" + "\001\022\n\n\006LISTED\020\002\022\n\n\006ONLINE\020\003\022\013\n\007FRIENDS\020\004\022\t" + "\n\005VALID\020\005\022\n\n\006SIGNED\020\006\022\007\n\003ALL\020\007\"@\n\nInfoOp" + "tion\022\014\n\010NAMEONLY\020\001\022\t\n\005BASIC\020\002\022\014\n\010LOCATIO" + "N\020\003\022\013\n\007ALLINFO\020\004\"[\n\020ResponsePeerList\022#\n\006" + "status\030\001 \002(\0132\023.rsctrl.base.Status\022\"\n\005pee" + "rs\030\002 \003(\0132\023.rsctrl.base.Person\"\242\001\n\016Reques" + "tAddPeer\022\016\n\006gpg_id\030\001 \002(\t\0220\n\003cmd\030\002 \002(\0162#." + "rsctrl.peers.RequestAddPeer.AddCmd\022\014\n\004ce" + "rt\030\003 \001(\t\"@\n\006AddCmd\022\010\n\004NOOP\020\000\022\007\n\003ADD\020\001\022\n\n" + "\006REMOVE\020\002\022\n\n\006IMPORT\020\003\022\013\n\007EXAMINE\020\004\"Z\n\017Re" + "sponseAddPeer\022#\n\006status\030\001 \002(\0132\023.rsctrl.b" "ase.Status\022\"\n\005peers\030\002 \003(\0132\023.rsctrl.base." - "Person\"\242\001\n\016RequestAddPeer\022\016\n\006gpg_id\030\001 \002(" - "\t\0220\n\003cmd\030\002 \002(\0162#.rsctrl.peers.RequestAdd" - "Peer.AddCmd\022\014\n\004cert\030\003 \001(\t\"@\n\006AddCmd\022\010\n\004N" - "OOP\020\000\022\007\n\003ADD\020\001\022\n\n\006REMOVE\020\002\022\n\n\006IMPORT\020\003\022\013" - "\n\007EXAMINE\020\004\"Z\n\017ResponseAddPeer\022#\n\006status" - "\030\001 \002(\0132\023.rsctrl.base.Status\022\"\n\005peers\030\002 \003" - "(\0132\023.rsctrl.base.Person\"\231\001\n\021RequestModif" - "yPeer\0223\n\003cmd\030\001 \002(\0162&.rsctrl.peers.Reques" - "tModifyPeer.ModCmd\022\"\n\005peers\030\002 \003(\0132\023.rsct" - "rl.base.Person\"+\n\006ModCmd\022\010\n\004NOOP\020\000\022\013\n\007AD" - "DRESS\020\001\022\n\n\006DYNDNS\020\002\"]\n\022ResponseModifyPee" - "r\022#\n\006status\030\001 \002(\0132\023.rsctrl.base.Status\022\"" - "\n\005peers\030\002 \003(\0132\023.rsctrl.base.Person*\027\n\013Ex" - "tensionId\022\010\n\004BASE\020\000*\026\n\tPackageId\022\t\n\005PEER" - "S\020\001*^\n\rRequestMsgIds\022\026\n\022MsgId_RequestPee" - "rs\020\001\022\030\n\024MsgId_RequestAddPeer\020\002\022\033\n\027MsgId_" - "RequestModifyPeer\020\003*e\n\016ResponseMsgIds\022\032\n" - "\026MsgId_ResponsePeerList\020\001\022\031\n\025MsgId_Respo" - "nseAddPeer\020\002\022\034\n\030MsgId_ResponseModifyPeer" - "\020\003", 1162); + "Person\"\231\001\n\021RequestModifyPeer\0223\n\003cmd\030\001 \002(" + "\0162&.rsctrl.peers.RequestModifyPeer.ModCm" + "d\022\"\n\005peers\030\002 \003(\0132\023.rsctrl.base.Person\"+\n" + "\006ModCmd\022\010\n\004NOOP\020\000\022\013\n\007ADDRESS\020\001\022\n\n\006DYNDNS" + "\020\002\"]\n\022ResponseModifyPeer\022#\n\006status\030\001 \002(\013" + "2\023.rsctrl.base.Status\022\"\n\005peers\030\002 \003(\0132\023.r" + "sctrl.base.Person*^\n\rRequestMsgIds\022\026\n\022Ms" + "gId_RequestPeers\020\001\022\030\n\024MsgId_RequestAddPe" + "er\020\002\022\033\n\027MsgId_RequestModifyPeer\020\003*e\n\016Res" + "ponseMsgIds\022\032\n\026MsgId_ResponsePeerList\020\001\022" + "\031\n\025MsgId_ResponseAddPeer\020\002\022\034\n\030MsgId_Resp" + "onseModifyPeer\020\003", 1136); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "peers.proto", &protobuf_RegisterTypes); RequestPeers::default_instance_ = new RequestPeers(); @@ -265,32 +260,6 @@ struct StaticDescriptorInitializer_peers_2eproto { } } static_descriptor_initializer_peers_2eproto_; -const ::google::protobuf::EnumDescriptor* ExtensionId_descriptor() { - protobuf_AssignDescriptorsOnce(); - return ExtensionId_descriptor_; -} -bool ExtensionId_IsValid(int value) { - switch(value) { - case 0: - return true; - default: - return false; - } -} - -const ::google::protobuf::EnumDescriptor* PackageId_descriptor() { - protobuf_AssignDescriptorsOnce(); - return PackageId_descriptor_; -} -bool PackageId_IsValid(int value) { - switch(value) { - case 1: - return true; - default: - return false; - } -} - const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor() { protobuf_AssignDescriptorsOnce(); return RequestMsgIds_descriptor_; @@ -335,6 +304,8 @@ bool RequestPeers_SetOption_IsValid(int value) { case 3: case 4: case 5: + case 6: + case 7: return true; default: return false; @@ -342,10 +313,12 @@ bool RequestPeers_SetOption_IsValid(int value) { } #ifndef _MSC_VER +const RequestPeers_SetOption RequestPeers::OWNID; const RequestPeers_SetOption RequestPeers::LISTED; const RequestPeers_SetOption RequestPeers::ONLINE; const RequestPeers_SetOption RequestPeers::FRIENDS; const RequestPeers_SetOption RequestPeers::VALID; +const RequestPeers_SetOption RequestPeers::SIGNED; const RequestPeers_SetOption RequestPeers::ALL; const RequestPeers_SetOption RequestPeers::SetOption_MIN; const RequestPeers_SetOption RequestPeers::SetOption_MAX; diff --git a/retroshare-nogui/src/rpc/proto/gencc/peers.pb.h b/retroshare-nogui/src/rpc/proto/gencc/peers.pb.h index 8696bd617..fd5113a23 100644 --- a/retroshare-nogui/src/rpc/proto/gencc/peers.pb.h +++ b/retroshare-nogui/src/rpc/proto/gencc/peers.pb.h @@ -42,14 +42,16 @@ class RequestModifyPeer; class ResponseModifyPeer; enum RequestPeers_SetOption { - RequestPeers_SetOption_LISTED = 1, - RequestPeers_SetOption_ONLINE = 2, - RequestPeers_SetOption_FRIENDS = 3, - RequestPeers_SetOption_VALID = 4, - RequestPeers_SetOption_ALL = 5 + RequestPeers_SetOption_OWNID = 1, + RequestPeers_SetOption_LISTED = 2, + RequestPeers_SetOption_ONLINE = 3, + RequestPeers_SetOption_FRIENDS = 4, + RequestPeers_SetOption_VALID = 5, + RequestPeers_SetOption_SIGNED = 6, + RequestPeers_SetOption_ALL = 7 }; bool RequestPeers_SetOption_IsValid(int value); -const RequestPeers_SetOption RequestPeers_SetOption_SetOption_MIN = RequestPeers_SetOption_LISTED; +const RequestPeers_SetOption RequestPeers_SetOption_SetOption_MIN = RequestPeers_SetOption_OWNID; const RequestPeers_SetOption RequestPeers_SetOption_SetOption_MAX = RequestPeers_SetOption_ALL; const int RequestPeers_SetOption_SetOption_ARRAYSIZE = RequestPeers_SetOption_SetOption_MAX + 1; @@ -126,42 +128,6 @@ inline bool RequestModifyPeer_ModCmd_Parse( return ::google::protobuf::internal::ParseNamedEnum( RequestModifyPeer_ModCmd_descriptor(), name, value); } -enum ExtensionId { - BASE = 0 -}; -bool ExtensionId_IsValid(int value); -const ExtensionId ExtensionId_MIN = BASE; -const ExtensionId ExtensionId_MAX = BASE; -const int ExtensionId_ARRAYSIZE = ExtensionId_MAX + 1; - -const ::google::protobuf::EnumDescriptor* ExtensionId_descriptor(); -inline const ::std::string& ExtensionId_Name(ExtensionId value) { - return ::google::protobuf::internal::NameOfEnum( - ExtensionId_descriptor(), value); -} -inline bool ExtensionId_Parse( - const ::std::string& name, ExtensionId* value) { - return ::google::protobuf::internal::ParseNamedEnum( - ExtensionId_descriptor(), name, value); -} -enum PackageId { - PEERS = 1 -}; -bool PackageId_IsValid(int value); -const PackageId PackageId_MIN = PEERS; -const PackageId PackageId_MAX = PEERS; -const int PackageId_ARRAYSIZE = PackageId_MAX + 1; - -const ::google::protobuf::EnumDescriptor* PackageId_descriptor(); -inline const ::std::string& PackageId_Name(PackageId value) { - return ::google::protobuf::internal::NameOfEnum( - PackageId_descriptor(), value); -} -inline bool PackageId_Parse( - const ::std::string& name, PackageId* value) { - return ::google::protobuf::internal::ParseNamedEnum( - PackageId_descriptor(), name, value); -} enum RequestMsgIds { MsgId_RequestPeers = 1, MsgId_RequestAddPeer = 2, @@ -257,10 +223,12 @@ class RequestPeers : public ::google::protobuf::Message { // nested types ---------------------------------------------------- typedef RequestPeers_SetOption SetOption; + static const SetOption OWNID = RequestPeers_SetOption_OWNID; static const SetOption LISTED = RequestPeers_SetOption_LISTED; static const SetOption ONLINE = RequestPeers_SetOption_ONLINE; static const SetOption FRIENDS = RequestPeers_SetOption_FRIENDS; static const SetOption VALID = RequestPeers_SetOption_VALID; + static const SetOption SIGNED = RequestPeers_SetOption_SIGNED; static const SetOption ALL = RequestPeers_SetOption_ALL; static inline bool SetOption_IsValid(int value) { return RequestPeers_SetOption_IsValid(value); @@ -1402,14 +1370,6 @@ inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::peers::RequestModifyPe return ::rsctrl::peers::RequestModifyPeer_ModCmd_descriptor(); } template <> -inline const EnumDescriptor* GetEnumDescriptor< rsctrl::peers::ExtensionId>() { - return rsctrl::peers::ExtensionId_descriptor(); -} -template <> -inline const EnumDescriptor* GetEnumDescriptor< rsctrl::peers::PackageId>() { - return rsctrl::peers::PackageId_descriptor(); -} -template <> inline const EnumDescriptor* GetEnumDescriptor< rsctrl::peers::RequestMsgIds>() { return rsctrl::peers::RequestMsgIds_descriptor(); } diff --git a/retroshare-nogui/src/rpc/proto/rpcprotopeers.cc b/retroshare-nogui/src/rpc/proto/rpcprotopeers.cc index 7f4e07838..bea75c786 100644 --- a/retroshare-nogui/src/rpc/proto/rpcprotopeers.cc +++ b/retroshare-nogui/src/rpc/proto/rpcprotopeers.cc @@ -39,15 +39,32 @@ RpcProtoPeers::RpcProtoPeers(uint32_t serviceId) int RpcProtoPeers::processMsg(uint32_t msg_id, uint32_t req_id, const std::string &msg) { /* check the msgId */ - uint8_t topbyte = 0; - uint8_t service = 0; - uint8_t submsg = 0; + uint8_t topbyte = getRpcMsgIdExtension(msg_id); + uint16_t service = getRpcMsgIdService(msg_id); + uint8_t submsg = getRpcMsgIdSubMsg(msg_id); + bool isResponse = isRpcMsgIdResponse(msg_id); + std::cerr << "RpcProtoPeers::processMsg() topbyte: " << topbyte; std::cerr << " service: " << service << " submsg: " << submsg; std::cerr << std::endl; - if (service != (uint8_t) rsctrl::peers::BASE) + if (isResponse) + { + std::cerr << "RpcProtoPeers::processMsg() isResponse() - not processing"; + std::cerr << std::endl; + return 0; + } + + + if (topbyte != (uint8_t) rsctrl::base::BASE) + { + std::cerr << "RpcProtoPeers::processMsg() Extension Mismatch - not processing"; + std::cerr << std::endl; + return 0; + } + + if (service != (uint16_t) rsctrl::base::PEERS) { std::cerr << "RpcProtoPeers::processMsg() Service Mismatch - not processing"; std::cerr << std::endl; @@ -231,7 +248,6 @@ int RpcProtoPeers::processRequestPeers(uint32_t msg_id, uint32_t req_id, const s } } - std::string outmsg; if (!respp.SerializeToString(&outmsg)) { @@ -241,15 +257,13 @@ int RpcProtoPeers::processRequestPeers(uint32_t msg_id, uint32_t req_id, const s } // Correctly Name Message. - uint32_t out_msg_id = create_msg_id( - rsctrl::peers::BASE, - rsctrl::peers::MsgId_ResponsePeerList); + uint32_t out_msg_id = constructMsgId(rsctrl::base::BASE, rsctrl::base::PEERS, + rsctrl::peers::MsgId_ResponsePeerList, true); // queue it. queueResponse(out_msg_id, req_id, outmsg); + + return 1; } - - - diff --git a/retroshare-nogui/src/rpc/proto/rpcprotopeers.h b/retroshare-nogui/src/rpc/proto/rpcprotopeers.h index d9dd2ef1d..969aa1a59 100644 --- a/retroshare-nogui/src/rpc/proto/rpcprotopeers.h +++ b/retroshare-nogui/src/rpc/proto/rpcprotopeers.h @@ -27,7 +27,7 @@ #include "rpc/rpcserver.h" -class RpcProtoPeers: RpcQueueService +class RpcProtoPeers: public RpcQueueService { public: RpcProtoPeers(uint32_t serviceId); diff --git a/retroshare-nogui/src/rpc/rpcserver.cc b/retroshare-nogui/src/rpc/rpcserver.cc index 3392eaffa..0f167d1da 100644 --- a/retroshare-nogui/src/rpc/rpcserver.cc +++ b/retroshare-nogui/src/rpc/rpcserver.cc @@ -225,3 +225,42 @@ int RpcQueueService::queueResponse(uint32_t msg_id, uint32_t req_id, const std:: } +// Lower 8 bits. +uint8_t getRpcMsgIdSubMsg(uint32_t msg_id) +{ + return msg_id & 0xFF; +} + +// Middle 16 bits. +uint16_t getRpcMsgIdService(uint32_t msg_id) +{ + return (msg_id >> 8) & 0xFFFF; +} + +// Top 8 bits. +uint8_t getRpcMsgIdExtension(uint32_t msg_id) +{ + return (msg_id >> 24) & 0xFE; // Bottom Bit is for Request / Response +} + +bool isRpcMsgIdResponse(uint32_t msg_id) +{ + return (msg_id >> 24) & 0x01; +} + + +uint32_t constructMsgId(uint8_t ext, uint16_t service, uint8_t submsg, bool is_response) +{ + if (is_response) + ext |= 0x01; // Set Bottom Bit. + else + ext &= 0xFE; // Clear Bottom Bit. + + uint32_t msg_id = (ext << 24) + (service << 8) + (submsg); + return msg_id; +} + + + + + diff --git a/retroshare-nogui/src/rpc/rpcserver.h b/retroshare-nogui/src/rpc/rpcserver.h index 061ad7842..4d506ef36 100644 --- a/retroshare-nogui/src/rpc/rpcserver.h +++ b/retroshare-nogui/src/rpc/rpcserver.h @@ -32,6 +32,15 @@ #include "util/rsthreads.h" +// Dividing up MsgIds into components: + +uint8_t getRpcMsgIdSubMsg(uint32_t msg_id); +uint16_t getRpcMsgIdService(uint32_t msg_id); // Middle 16 bits. +uint8_t getRpcMsgIdExtension(uint32_t msg_id); // Top 7 of 8 bits. Bottom Bit is for Request / Response +bool isRpcMsgIdResponse(uint32_t msg_id); + +uint32_t constructMsgId(uint8_t ext, uint16_t service, uint8_t submsg, bool is_response); + /*** This can be overloaded for plugins * Also allows a natural seperation of the full interface into sections. */ diff --git a/retroshare-nogui/src/rpc/rpcsetup.cc b/retroshare-nogui/src/rpc/rpcsetup.cc index 38b8a9c5b..0adc416bc 100644 --- a/retroshare-nogui/src/rpc/rpcsetup.cc +++ b/retroshare-nogui/src/rpc/rpcsetup.cc @@ -24,8 +24,9 @@ #include "rpc/rpcsetup.h" #include "rpc/rpcserver.h" -#include "rpc/rpcecho.h" +#include "rpc/proto/rpcprotopeers.h" +#include "rpc/rpcecho.h" RpcMediator *CreateRpcSystem(RpcComms *comms) { @@ -33,6 +34,10 @@ RpcMediator *CreateRpcSystem(RpcComms *comms) RpcServer *server = new RpcServer(med); /* add services */ + RpcProtoPeers *peers = new RpcProtoPeers(1); + server->addService(peers); + + /* Finally an Echo Service - which will echo back any unprocesses commands. */ RpcEcho *echo = new RpcEcho(1); server->addService(echo); From 5a1115e6e477428953a76c70cd989d724f1cab55 Mon Sep 17 00:00:00 2001 From: drbob Date: Thu, 23 Aug 2012 15:44:04 +0000 Subject: [PATCH 035/222] * Updated message definitions. - only base & peers are vaguely complete, the others are work in progress. - gxs is a crazy idea: to expose the generic gxs interface, so anyone can write an external GXS service. * Added Makefile to generate python and c++ code. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5462 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- rsctrl/src/Makefile | 30 ++++ rsctrl/src/definition/base.proto | 60 ++++++- rsctrl/src/definition/files.proto | 113 +++++++++++++ rsctrl/src/definition/gxs.proto | 261 +++++++++++++++++++++++++++++ rsctrl/src/definition/msgs.proto | 108 ++++++++++++ rsctrl/src/definition/peers.proto | 34 ++-- rsctrl/src/definition/system.proto | 56 +++++++ 7 files changed, 645 insertions(+), 17 deletions(-) create mode 100644 rsctrl/src/Makefile create mode 100644 rsctrl/src/definition/files.proto create mode 100644 rsctrl/src/definition/gxs.proto create mode 100644 rsctrl/src/definition/msgs.proto create mode 100644 rsctrl/src/definition/system.proto diff --git a/rsctrl/src/Makefile b/rsctrl/src/Makefile new file mode 100644 index 000000000..497622038 --- /dev/null +++ b/rsctrl/src/Makefile @@ -0,0 +1,30 @@ + +EXEC = protoc +#PROTO = base.proto files.proto gxs.proto msgs.proto peers.proto system.proto +PROTO = base.proto peers.proto + +PROTOPATH = ./definition +CDESTPATH = ./gencc +#CDESTPATH = ../../retroshare-nogui/src/rpc/proto/gencc +PYDESTPATH = ./genpy + +CLIST = $(PROTO:%.proto=%.cc) +CCODE = $(patsubst %.proto,$(CDESTPATH)/%.pb.cc, $(PROTO)) +HCODE = $(patsubst %.proto,$(CDESTPATH)/%.pb.h, $(PROTO)) +PYCODE = $(patsubst %.proto,$(PYDESTPATH)/%_pb2.py, $(PROTO)) + + +all: allc + echo $(CCODE) + echo $(PYCODE) + +allc: $(CCODE) $(PYCODE) + +$(CDESTPATH)/%.pb.cc : $(PROTOPATH)/%.proto + $(EXEC) --proto_path=$(PROTOPATH) --cpp_out=$(CDESTPATH) $< + +$(PYDESTPATH)/%_pb2.py : $(PROTOPATH)/%.proto + $(EXEC) --proto_path=$(PROTOPATH) --python_out=$(PYDESTPATH) $< + +clean: + -/bin/rm $(CCODE) $(HCODE) $(PYCODE) diff --git a/rsctrl/src/definition/base.proto b/rsctrl/src/definition/base.proto index 076bfe06a..cdde0d362 100644 --- a/rsctrl/src/definition/base.proto +++ b/rsctrl/src/definition/base.proto @@ -1,4 +1,4 @@ -package rsctrl.base: +package rsctrl.base; /////////////////////////////////////////////////////////////// // These are basic Messages, which are used as building blocks @@ -6,6 +6,22 @@ package rsctrl.base: // They should not be sent RAW, but should be wrapped in another msg. /////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +// Expected PackageIds. + +enum ExtensionId { BASE = 0; } + +enum PackageId { + PEERS = 1; + SYSTEM = 2; + FILES = 3; + MSGS = 4; + + // THEORETICAL ONES. + GXS = 1000; +} + + /////////////////////////////////////////////////////////////// // Basic Status Response, should be in all responses @@ -59,3 +75,45 @@ message Dir { repeated File files = 4; } + +/////////////////////////////////////////////////////////////// +// System Status + +message SystemStatus { + enum NetCode { + BAD_UNKNOWN = 0; + BAD_OFFLINE = 1; + BAD_NATSYM = 2; + BAD_NODHT_NAT = 3; + WARNING_RESTART = 4; + WARNING_NATTED = 5; + WARNING_NODHT = 6; + GOOD = 7; + ADV_FORWARD = 8; + } + + required NetCode net_status = 1; + optional string msg = 2; +} + + +/////////////////////////////////////////////////////////////// +// Bandwidth Measurements. + +message Bandwidth { + required float up = 1; // kB/s + required float down = 2; // kB/s + optional string name = 3; // e.g. DHT, UDP, TCP, Stun, or Total. +} + +message BandwidthSet { + repeated Bandwidth bandwidths = 1; +} + + + +/////////////////////////////////////////////////////////////// + + + + diff --git a/rsctrl/src/definition/files.proto b/rsctrl/src/definition/files.proto new file mode 100644 index 000000000..87fa59237 --- /dev/null +++ b/rsctrl/src/definition/files.proto @@ -0,0 +1,113 @@ +package rsctrl.files; + +import "base.proto"; + +/////////////////////////////////////////////////////////////// +// Mirror most of rsFiles functionality. +// +// Share Directories. +// Searches +// List Transfers. +// Control Transfers. +/////////////////////////////////////////////////////////////// + +enum RequestMsgIds { + MsgId_RequestPeers = 1; + MsgId_RequestAddPeer = 2; + MsgId_RequestModifyPeer = 3; +} + +enum ResponseMsgIds { + MsgId_ResponsePeerList = 1; + MsgId_ResponseAddPeer = 2; + MsgId_ResponseModifyPeer = 3; +} + +/////////////////////////////////////////////////////////////// + +// REQUEST: RequestPeers +message RequestPeers { + + // About Who? + enum SetOption { + OWNID = 1; + LISTED = 2; + ONLINE = 3; + FRIENDS = 4; + VALID = 5; + SIGNED = 6; + ALL = 7; + } + + // What do you want? + enum InfoOption { + NAMEONLY = 1; + BASIC = 2; + LOCATION = 3; + ALLINFO = 4; + } + + required SetOption set = 1; + required InfoOption info = 2; + repeated string gpg_ids = 3; +} + + +// RESPONSE: ResponsePeerList +message ResponsePeerList { + required rsctrl.base.Status status = 1; + repeated rsctrl.base.Person peers = 2; +} + +/////////////////////////////////////////////////////////////// + +// REQUEST: RequestAddPeer +message RequestAddPeer { + + enum AddCmd { + NOOP = 0; // No op. + ADD = 1; // Add existing from gpg_id. + REMOVE = 2; // Remove existing from gpg_id. + IMPORT = 3; // Import from cert, with gpg_id. + EXAMINE = 4; // Examine cert, but no action. + } + + required string gpg_id = 1; + required AddCmd cmd = 2; + optional string cert = 3; +} + +// RESPONSE: ResponseAddPeer +message ResponseAddPeer { + required rsctrl.base.Status status = 1; + repeated rsctrl.base.Person peers = 2; +} + +/////////////////////////////////////////////////////////////// + +// REQUEST: RequestModifyPeer +message RequestModifyPeer { + + enum ModCmd { + NOOP = 0; + ADDRESS = 1; + DYNDNS = 2; + //SOMETHING_ELSE = 0x0000010; + //SOMETHING_ELSE = 0x0000020; + //SOMETHING_ELSE = 0x0000040; + //SOMETHING_ELSE = 0x0000080; + } + + required ModCmd cmd = 1; + //required int64 cmd = 1; // Could we OR the Cmds together? + repeated rsctrl.base.Person peers = 2; +} + +// RESPONSE: ResponseModifyPeer +message ResponseModifyPeer { + required rsctrl.base.Status status = 1; + repeated rsctrl.base.Person peers = 2; +} + +/////////////////////////////////////////////////////////////// + diff --git a/rsctrl/src/definition/gxs.proto b/rsctrl/src/definition/gxs.proto new file mode 100644 index 000000000..98a88c7c4 --- /dev/null +++ b/rsctrl/src/definition/gxs.proto @@ -0,0 +1,261 @@ +package rsctrl.gxs; + +import "base.proto"; + +/////////////////////////////////////////////////////////////// +// Base Messages for GXS Interface. +/////////////////////////////////////////////////////////////// + +enum RequestMsgIds { + MsgId_RequestPeers = 1; + MsgId_RequestAddPeer = 2; + MsgId_RequestModifyPeer = 3; +} + +enum ResponseMsgIds { + MsgId_ResponsePeerList = 1; + MsgId_ResponseAddPeer = 2; + MsgId_ResponseModifyPeer = 3; +} + +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// + +// BASE DATA TYPES + +message Service { + // + required uint32 service_id = 1; + optional string service_name = 2; +} + +message GroupMeta { + + // FLAGS as ENUMs. + enum GroupFlags { + GF_FLAG1 = 1; + GF_FLAG2 = 2; + GF_FLAG3 = 4; + GF_FLAG4 = 8; + } + + enum SignFlags { + SF_FLAG1 = 1; + SF_FLAG2 = 2; + } + + enum SubscribeFlags { + SUBF_FLAG1 = 1; + SUBF_FLAG2 = 2; + } + + enum StatusFlags { + STATF_FLAG1 = 1; + STATF_FLAG2 = 2; + } + + // THIS IS FIXED: From NETWORK. + required string group_id = 1; + required string group_name = 2; + required uint32 group_flags = 3; + required uint32 sign_flags = 4; + + required uint32 publish_ts = 5; + optional string author_id = 6; + + // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. + + required uint32 subscribe_flags = 7; + required uint32 group_status = 8; + + optional string service_string = 9; + + optional uint32 pop = 10; // USED? + optional uint32 msg_count = 11; // ??? + optional int32 last_post = 12; // ??? +} + + +message GroupGenericData { + required GroupMeta meta = 1; + required string encoded_data = 2; +} + + +message MsgMeta { + + // FLAGS as ENUMs. + enum GroupFlags { + GF_FLAG1 = 1; + GF_FLAG2 = 2; + GF_FLAG3 = 4; + GF_FLAG4 = 8; + } + + enum SignFlags { + SF_FLAG1 = 1; + SF_FLAG2 = 2; + } + + enum SubscribeFlags { + SUBF_FLAG1 = 1; + SUBF_FLAG2 = 2; + } + + enum StatusFlags { + STATF_FLAG1 = 1; + STATF_FLAG2 = 2; + } + + // THIS IS FIXED: From NETWORK. + required string group_id = 1; + required string msg_id = 2; + + required string thread_id = 3; + required uint32 parent_id = 4; + required uint32 origmsg_id = 5; + + optional string author_id = 6; + + required uint32 publish_ts = 7; + required uint32 msg_name = 8; + + required uint32 msg_flags = 9; + + // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. + + required uint32 msg_status = 10; + required uint32 child_ts = 11; + optional string service_string = 12; +} + +message MsgGenericData { + required MsgMeta meta = 1; + required string encoded_data = 2; +} + + +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// + +message Filter { + required uint32 options = 1; + + optional uint32 status_filter = 2; + optional uint32 status_mask = 3; + + optional uint32 req_type = 4; + + optional uint32 subscribe_filter = 5; + + optional int32 before = 6; + optional int32 after = 7; +} + +message MsgSet { + required string group_id = 1; + repeated string msg_id = 2; +} + +message GroupMsgSet { + repeated MsgSet groups = 1; +} + + +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// + +// REQUEST: RequestGroupInfo +message RequestGroupInfo { + + required Service service = 1; + + required uint32 ans_type = 2; + required Filter options = 3; + repeated string group_ids = 4; +} + + +// RESPONSE: ResponseGroupList +message ResponseGroupList { + + required rsctrl.base.Status status = 1; + + required Service service = 2; + repeated string group_ids = 3; +} + + +// RESPONSE: ResponseGroupMeta +message ResponseGroupMeta { + + required rsctrl.base.Status status = 1; + + required Service service = 2; + repeated GroupMeta meta = 3; +} + + +// RESPONSE: ResponseGroupData +message ResponseGroupData { + + required rsctrl.base.Status status = 1; + + required Service service = 2; + repeated GroupGenericData data = 3; +} + + +/////////////////////////////////////////////////////////////// + +// REQUEST: RequestMsgInfo +message RequestMsgInfo { + + required Service service = 1; + + required uint32 ans_type = 2; + required Filter options = 3; + repeated GroupMsgSet msgs = 4; +} + +// REQUEST: RequestMsgRelatedInfo +message RequestMsgRelatedInfo { + + required Service service = 1; + + required uint32 ans_type = 2; + required Filter options = 3; + repeated GroupMsgSet msgs = 4; +} + +// RESPONSE: ResponseMsgList +message ResponseMsgList { + + required rsctrl.base.Status status = 1; + + required Service service = 2; + repeated GroupMsgSet msgs = 3; +} + +// RESPONSE: ResponseMsgMeta +message ResponseMsgMeta { + + required rsctrl.base.Status status = 1; + + required Service service = 2; + repeated MsgMeta meta = 3; +} + +// RESPONSE: ResponseMsgData +message ResponseMsgData { + + required rsctrl.base.Status status = 1; + + required Service service = 2; + repeated MsgGenericData data = 3; +} + + +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// + diff --git a/rsctrl/src/definition/msgs.proto b/rsctrl/src/definition/msgs.proto new file mode 100644 index 000000000..a6842c9d3 --- /dev/null +++ b/rsctrl/src/definition/msgs.proto @@ -0,0 +1,108 @@ +package rsctrl.msgs; + +import "base.proto"; + +/////////////////////////////////////////////////////////////// +// Access, and Control your Friends / Peers and related Settings. +/////////////////////////////////////////////////////////////// + +enum RequestMsgIds { + MsgId_RequestPeers = 1; + MsgId_RequestAddPeer = 2; + MsgId_RequestModifyPeer = 3; +} + +enum ResponseMsgIds { + MsgId_ResponsePeerList = 1; + MsgId_ResponseAddPeer = 2; + MsgId_ResponseModifyPeer = 3; +} + +/////////////////////////////////////////////////////////////// + +// REQUEST: RequestPeers +message RequestPeers { + + // About Who? + enum SetOption { + OWNID = 1; + LISTED = 2; + ONLINE = 3; + FRIENDS = 4; + VALID = 5; + SIGNED = 6; + ALL = 7; + } + + // What do you want? + enum InfoOption { + NAMEONLY = 1; + BASIC = 2; + LOCATION = 3; + ALLINFO = 4; + } + + required SetOption set = 1; + required InfoOption info = 2; + repeated string gpg_ids = 3; +} + + +// RESPONSE: ResponsePeerList +message ResponsePeerList { + required rsctrl.base.Status status = 1; + repeated rsctrl.base.Person peers = 2; +} + +/////////////////////////////////////////////////////////////// + +// REQUEST: RequestAddPeer +message RequestAddPeer { + + enum AddCmd { + NOOP = 0; // No op. + ADD = 1; // Add existing from gpg_id. + REMOVE = 2; // Remove existing from gpg_id. + IMPORT = 3; // Import from cert, with gpg_id. + EXAMINE = 4; // Examine cert, but no action. + } + + required string gpg_id = 1; + required AddCmd cmd = 2; + optional string cert = 3; +} + +// RESPONSE: ResponseAddPeer +message ResponseAddPeer { + required rsctrl.base.Status status = 1; + repeated rsctrl.base.Person peers = 2; +} + +/////////////////////////////////////////////////////////////// + +// REQUEST: RequestModifyPeer +message RequestModifyPeer { + + enum ModCmd { + NOOP = 0; + ADDRESS = 1; + DYNDNS = 2; + //SOMETHING_ELSE = 0x0000010; + //SOMETHING_ELSE = 0x0000020; + //SOMETHING_ELSE = 0x0000040; + //SOMETHING_ELSE = 0x0000080; + } + + required ModCmd cmd = 1; + //required int64 cmd = 1; // Could we OR the Cmds together? + repeated rsctrl.base.Person peers = 2; +} + +// RESPONSE: ResponseModifyPeer +message ResponseModifyPeer { + required rsctrl.base.Status status = 1; + repeated rsctrl.base.Person peers = 2; +} + +/////////////////////////////////////////////////////////////// + diff --git a/rsctrl/src/definition/peers.proto b/rsctrl/src/definition/peers.proto index 8f0539f0a..c4886cbfd 100644 --- a/rsctrl/src/definition/peers.proto +++ b/rsctrl/src/definition/peers.proto @@ -1,21 +1,21 @@ -package rsctrl.peers: +package rsctrl.peers; + +import "base.proto"; + /////////////////////////////////////////////////////////////// // Access, and Control your Friends / Peers and related Settings. /////////////////////////////////////////////////////////////// -enum ExtensionId { BASE = 0; } -enum PackageId { PEERS = 1; } - enum RequestMsgIds { - RequestPeers = 1; - RequestAddPeer = 2; - RequestModifyPeer = 2; + MsgId_RequestPeers = 1; + MsgId_RequestAddPeer = 2; + MsgId_RequestModifyPeer = 3; } enum ResponseMsgIds { - ResponsePeerList = 1; - ResponseAddPeer = 2; - ResponseModifyPeer = 2; + MsgId_ResponsePeerList = 1; + MsgId_ResponseAddPeer = 2; + MsgId_ResponseModifyPeer = 3; } /////////////////////////////////////////////////////////////// @@ -25,11 +25,13 @@ message RequestPeers { // About Who? enum SetOption { - LISTED = 1; - ONLINE = 2; - FRIENDS = 3; - VALID = 4; - ALL = 5; + OWNID = 1; + LISTED = 2; + ONLINE = 3; + FRIENDS = 4; + VALID = 5; + SIGNED = 6; + ALL = 7; } // What do you want? @@ -37,7 +39,7 @@ message RequestPeers { NAMEONLY = 1; BASIC = 2; LOCATION = 3; - ALL = 4; + ALLINFO = 4; } required SetOption set = 1; diff --git a/rsctrl/src/definition/system.proto b/rsctrl/src/definition/system.proto new file mode 100644 index 000000000..e8eadd0ea --- /dev/null +++ b/rsctrl/src/definition/system.proto @@ -0,0 +1,56 @@ +package rsctrl.peers; + +import "base.proto"; + +/////////////////////////////////////////////////////////////// +// Configuration and Stats. +/////////////////////////////////////////////////////////////// + +enum RequestMsgIds { + MsgId_RequestSystemStatus = 1; + //MsgId_RequestNetConfig = 2; +} + +enum ResponseMsgIds { + MsgId_ResponseSystemStatus = 1; + //MsgId_ResponseNetConfig = 2; +} + +/////////////////////////////////////////////////////////////// + +// REQUEST: RequestSystemStatus +message RequestSystemStatus { + // Nothing here? +} + +// RESPONSE: ResponseSystemStatus +message ResponseSystemStatus { + + enum NetCode { + BAD_UNKNOWN = 0; + BAD_OFFLINE = 1; + BAD_NATSYM = 2; + BAD_NODHT_NAT = 3; + WARNING_RESTART = 4; + WARNING_NATTED = 5; + WARNING_NODHT = 6; + GOOD = 7; + ADV_FORWARD = 8; + } + + // Status of response. + required rsctrl.base.Status status = 1; + + // Peers. + required uint32 peer_count = 2; + required uint32 online_count = 3; + + // Basic Network Information. + required NetCode net_status = 4; + required rsctrl.base.Bandwidth bw_total = 5; +} + +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// + From e1f54c239f016a6d09600d7d14bd7521c1d99fce Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Thu, 23 Aug 2012 21:59:51 +0000 Subject: [PATCH 036/222] system test code for rsgenexchange initial attempt at msg retrieval test added dummy serialiser and dummy gxs items need to make some more compile fixes but essentials in place git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5463 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/tests/gxs/genexchangetester.cpp | 234 ++++++++++++++++++ .../src/tests/gxs/genexchangetester.h | 75 ++++++ .../src/tests/gxs/genexchangetestservice.cpp | 52 ++++ .../src/tests/gxs/genexchangetestservice.h | 64 +++++ .../src/tests/gxs/rsdummyservices.cc | 226 +++++++++++++++++ libretroshare/src/tests/gxs/rsdummyservices.h | 94 +++++++ .../src/tests/gxs/rsgenexchange_test.cc | 28 +++ .../src/tests/gxs/rsgenexhchange_test.pro | 62 +++++ 8 files changed, 835 insertions(+) create mode 100644 libretroshare/src/tests/gxs/genexchangetester.cpp create mode 100644 libretroshare/src/tests/gxs/genexchangetester.h create mode 100644 libretroshare/src/tests/gxs/genexchangetestservice.cpp create mode 100644 libretroshare/src/tests/gxs/genexchangetestservice.h create mode 100644 libretroshare/src/tests/gxs/rsdummyservices.cc create mode 100644 libretroshare/src/tests/gxs/rsdummyservices.h create mode 100644 libretroshare/src/tests/gxs/rsgenexchange_test.cc create mode 100644 libretroshare/src/tests/gxs/rsgenexhchange_test.pro diff --git a/libretroshare/src/tests/gxs/genexchangetester.cpp b/libretroshare/src/tests/gxs/genexchangetester.cpp new file mode 100644 index 000000000..d2bf93660 --- /dev/null +++ b/libretroshare/src/tests/gxs/genexchangetester.cpp @@ -0,0 +1,234 @@ +#include "genexchangetester.h" +#include "support.h" + + +GenExchangeTester::GenExchangeTester(GenExchangeTestService* testService) + : mTestService(testService) +{ + mTokenService = mTestService->getTokenService(); +} + +bool GenExchangeTester::testMsgSubmissionRetrieval() +{ + RsDummyMsg* msg = new RsDummyMsg(); + init(msg); + uint32_t token; + mTestService->publishDummyMsg(token, msg); + + // poll will block until found + pollForToken(token); + + if(mMsgIdsIn.empty()) + return false; + + RsGxsMessageId& msgId = mMsgIdsIn.begin()->second; + RsGxsGroupId& grpId = mMsgIdsIn.begin()->first; + + GxsMsgReq req; + req.insert(std::make_pair(msgId, grpId)); + + RsTokReqOptionsV2 opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + mTokenService->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, req); + + // poll again + pollForToken(token); + + mTestService->getMsgDataTS(token, mMsgDataIn); + + bool ok = true; + + if(mMsgDataIn.size() != mMsgDataOut.size()) return false; + + GxsMsgDataMap::iterator mit = mMsgDataOut.begin(); + + for(; mit != mMsgDataOut.end(); mit++) + { + const RsGxsGroupId& gId = mit->first; + + std::vector& msgV_1 = mit->second, + msgV_2 = mMsgDataIn[grpId]; + std::vector::iterator vit1, vit2; + + for(vit1 = msgV_1.begin(); vit1 = msgV_1.end(); + vit1++) + { + RsDummyMsg* lMsg = dynamic_cast(*vit1); + for(vit2 = msgV_2.begin(); vit2 = msgV_2.end(); + vit2++) + { + RsDummyMsg* rMsg = dynamic_cast(*vit2); + + if(rMsg->meta.mMsgId == lMsg->meta.mMsgId) + ok &= *rMsg == *lMsg; + + } + } + + } + + return ok; +} + +bool GenExchangeTester::testMsgIdRetrieval() +{ + return false; +} + +bool GenExchangeTester::testSpecificMsgRetrieval() +{ + return false; +} + +bool GenExchangeTester::testGrpIdRetrieval() +{ + return false; +} + +bool GenExchangeTester::testGrpStatusRequest() +{ + return false; +} + + +// helper functions + +void GenExchangeTester::storeMsgData(GxsMsgDataMap &msgData) +{ + +} + +void GenExchangeTester::storeGrpData(GxsMsgDataMap &grpData) +{ + +} + +void GenExchangeTester::storeGrpId(GxsMsgIdResult &grpIds) +{ + +} + +void GenExchangeTester::storeMsgData(GxsMsgDataMap &msgData) +{ + +} + + +void GenExchangeTester::storeMsgMeta(GxsMsgMetaMap &msgMetaData) +{ + +} + +void GenExchangeTester::storeMsgIds(GxsMsgIdResult &msgIds) +{ + +} + + +void GenExchangeTester::init(RsGroupMetaData &grpMeta) +{ + +} + +void GenExchangeTester::init(RsMsgMetaData &msgMeta) +{ + randString(LARGE_STR, msgMeta.mAuthorId); + randString(LARGE_STR, msgMeta.mMsgName); + randString(LARGE_STR, msgMeta.mServiceString); + randString(LARGE_STR, msgMeta.mOrigMsgId); + randString(LARGE_STR, msgMeta.mParentId); + randString(LARGE_STR, msgMeta.mThreadId); + randString(LARGE_STR, msgMeta.mGroupId); + + randNum(msgMeta.mChildTs); + randNum(msgMeta.mMsgStatus); + randNum(msgMeta.mMsgFlags); + randNum(msgMeta.mPublishTs); +} + +void randNum(uint32_t& num) +{ + num = rand()%23562424; +} + + +bool GenExchangeTester::operator ==(const RsMsgMetaData& lMeta, const RsMsgMetaData& rMeta) +{ + + if(lMeta.mAuthorId != rMeta.mAuthorId) return false; + if(lMeta.mChildTs != rMeta.mChildTs) return false; + if(lMeta.mGroupId != rMeta.mGroupId) return false; + if(lMeta.mMsgFlags != rMeta.mMsgFlags) return false; + if(lMeta.mMsgId != rMeta.mMsgId) return false; + if(lMeta.mMsgName != rMeta.mMsgName) return false; + if(lMeta.mMsgStatus != rMeta.mMsgStatus) return false; + if(lMeta.mOrigMsgId != rMeta.mOrigMsgId) return false; + if(lMeta.mParentId != rMeta.mParentId) return false; + if(lMeta.mPublishTs != rMeta.mPublishTs) return false; + if(lMeta.mThreadId != rMeta.mThreadId) return false; + + return true; +} + +bool operator ==(const RsDummyMsg& lMsg, const RsDummyMsg& rMsg) +{ + if(lMsg.msgData != rMsg.msgData) return false; + if(!(lMsg.meta == rMsg.meta)) return false; + + return true; +} + +void GenExchangeTester::init(RsGxsGrpItem *grpItem) +{ + +} + +void GenExchangeTester::init(RsDummyMsg *msgItem) +{ + randString(LARGE_STR, msgItem->msgData); + init(msgItem->meta); +} + +void GenExchangeTester::pollForToken(uint32_t token) +{ + double timeDelta = 0.2; + + while(true) + { +#ifndef WINDOWS_SYS + usleep((int) (timeDelta * 1000000)); +#else + Sleep((int) (timeDelta * 1000)); +#endif + + if(RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE == + mTokenService->requestStatus(token)) + { + break; + } + } +} + +void GenExchangeTester::setUp() +{ + +} + +void GenExchangeTester::setUpGrps() +{ + +} + +void GenExchangeTester::breakDown() +{ + +} + + + + + + + + + diff --git a/libretroshare/src/tests/gxs/genexchangetester.h b/libretroshare/src/tests/gxs/genexchangetester.h new file mode 100644 index 000000000..6378e1ae6 --- /dev/null +++ b/libretroshare/src/tests/gxs/genexchangetester.h @@ -0,0 +1,75 @@ +#ifndef GENEXCHANGETESTER_H +#define GENEXCHANGETESTER_H + +#include "genexchangetestservice.h" + +/*! + * The job of the service tester is to send dummy msg items to the GenExchange service + * and then retrieve them (ignoring ackowledge message) + * Also it modifies local meta items and check if it worked out + */ +class GenExchangeTester +{ +public: + + void pollForToken(uint32_t); + + GenExchangeTester(GenExchangeTestService* testService); + + bool testMsgSubmissionRetrieval(); + bool testMsgIdRetrieval(); + bool testSpecificMsgRetrieval(); + + bool testGrpSubmissionRetrieval(); + bool testSpecificGrpRetrieval(); + bool testGrpIdRetrieval(); + + bool testGrpSubscribeRequest(); + bool testGrpStatusRequest(); + +private: + + // to be called at start + void setUp(); + + // and at end of test routines, resets db and clears out maps + void breakDown(); + + + void setUpGrps(); // to be called at start of msg tests + + void storeMsgData(GxsMsgDataMap& msgData); + void storeMsgMeta(GxsMsgMetaMap& msgMetaData); + void storeMsgIds(GxsMsgIdResult& msgIds); + + void storeGrpData(GxsMsgDataMap& grpData); + void storeGrpMeta(GxsMsgMetaMap& grpMetaData); + void storeGrpId(GxsMsgIdResult& grpIds); + + void init(RsDummyGrp* grpItem); + void init(RsGroupMetaData&); + void init(RsDummyMsg* msgItem); + void init(RsMsgMetaData&); + + bool operator ==(const RsMsgMetaData& lMeta, const RsMsgMetaData& rMeta); + bool operator ==(const RsDummyMsg& lMsg, const RsDummyMsg& rMsg); + +private: + + RsMutex mGenTestMutex; + + GxsMsgDataMap mGrpDataOut, mGrpDataIn; + GxsMsgMetaMap mGrpMetaDataOut, mGrpMetaDataIn; + GxsMsgIdResult mGrpIdsOut, mGrpIdsIn; + + GxsMsgDataMap mMsgDataOut, mMsgDataIn; + GxsMsgMetaMap mMsgMetaDataOut, mMsgMetaDataIn; + GxsMsgIdResult mMsgIdsOut, mMsgIdsIn; + +private: + + GenExchangeTestService* mTestService; + RsTokenServiceV2* mTokenService; +}; + +#endif // GENEXCHANGETESTER_H diff --git a/libretroshare/src/tests/gxs/genexchangetestservice.cpp b/libretroshare/src/tests/gxs/genexchangetestservice.cpp new file mode 100644 index 000000000..6051c19be --- /dev/null +++ b/libretroshare/src/tests/gxs/genexchangetestservice.cpp @@ -0,0 +1,52 @@ +#include "genexchangetestservice.h" + +GenExchangeTestService::GenExchangeTestService(RsGeneralDataService *dataServ, RsNetworkExchangeService * netService) + : RsGenExchange(dataServ, netService) +{ + +} + +void GenExchangeTestService::notifyChanges(std::vector &changes) +{ + return; +} + +void GenExchangeTestService::publishDummyGrp(uint32_t &token, RsDummyGrp *grp) +{ + publishGroup(token, grp); +} + +void GenExchangeTestService::publishDummyMsg(uint32_t &token, RsDummyMsg *msg) +{ + publishMsg(token, msg); +} + +bool GenExchangeTestService::getGroupListTS(const uint32_t &token, std::list &groupIds) +{ + return getGroupList(token, groupIds); +} + +bool GenExchangeTestService::getGroupMetaTS(const uint32_t &token, std::list &groupInfo) +{ + return getGroupMeta(token, groupInfo); +} + +bool GenExchangeTestService::getGroupDataTS(const uint32_t &token, std::vector &grpItem) +{ + return getGroupData(token, grpItem); +} + +bool GenExchangeTestService::getMsgDataTS(const uint32_t &token, GxsMsgDataMap &msgItems) +{ + return getMsgData(token, msgItems); +} + +bool GenExchangeTestService::getMsgMetaTS(const uint32_t &token, GxsMsgMetaMap &msgInfo) +{ + return getMsgMeta(token, msgInfo); +} + +bool GenExchangeTestService::getMsgListTS(const uint32_t &token, GxsMsgIdResult &msgIds) +{ + return getMsgList(token, msgIds); +} diff --git a/libretroshare/src/tests/gxs/genexchangetestservice.h b/libretroshare/src/tests/gxs/genexchangetestservice.h new file mode 100644 index 000000000..c83879739 --- /dev/null +++ b/libretroshare/src/tests/gxs/genexchangetestservice.h @@ -0,0 +1,64 @@ +#ifndef GENEXCHANGETESTSERVICE_H +#define GENEXCHANGETESTSERVICE_H + +#include "gxs/rsgenexchange.h" +#include "rsdummyservices.h" + +class GenExchangeTestService : public RsGenExchange +{ +public: + GenExchangeTestService(RsGeneralDataService* dataServ, RsNetworkExchangeService*); + + void notifyChanges(std::vector& changes); + + void publishDummyGrp(uint32_t& token, RsDummyGrp* grp); + void publishDummyMsg(uint32_t& token, RsDummyMsg* msg); + + + /*! + * Retrieve group list for a given token + * @param token + * @param groupIds + * @return false if token cannot be redeemed, if false you may have tried to redeem when not ready + */ + bool getGroupListTS(const uint32_t &token, std::list &groupIds); + + /*! + * Retrieve msg list for a given token sectioned by group Ids + * @param token token to be redeemed + * @param msgIds a map of grpId -> msgList (vector) + */ + bool getMsgListTS(const uint32_t &token, GxsMsgIdResult &msgIds); + + + /*! + * retrieve group meta data associated to a request token + * @param token + * @param groupInfo + */ + bool getGroupMetaTS(const uint32_t &token, std::list &groupInfo); + + /*! + * retrieves message meta data associated to a request token + * @param token token to be redeemed + * @param msgInfo the meta data to be retrieved for token store here + */ + bool getMsgMetaTS(const uint32_t &token, GxsMsgMetaMap &msgInfo); + + /*! + * retrieves group data associated to a request token + * @param token token to be redeemed for grpitem retrieval + * @param grpItem the items to be retrieved for token are stored here + */ + bool getGroupDataTS(const uint32_t &token, std::vector& grpItem); + + /*! + * retrieves message data associated to a request token + * @param token token to be redeemed for message item retrieval + * @param msgItems + */ + bool getMsgDataTS(const uint32_t &token, GxsMsgDataMap& msgItems); + +}; + +#endif // GENEXCHANGETESTSERVICE_H diff --git a/libretroshare/src/tests/gxs/rsdummyservices.cc b/libretroshare/src/tests/gxs/rsdummyservices.cc new file mode 100644 index 000000000..07eb1a7e5 --- /dev/null +++ b/libretroshare/src/tests/gxs/rsdummyservices.cc @@ -0,0 +1,226 @@ + + +#include "rsdummyservices.h" + + +uint32_t RsDummySerialiser::size(RsItem *item) +{ + RsDummyMsg* msg; + RsDummyGrp* grp; + + if( (msg = dynamic_cast(item)) != NULL ) + { + return sizeDummyMsgItem(msg); + }else if( (grp = dynamic_cast(item)) != NULL ) + { + return sizeDummyGrpItem(grp); + }else + { + std::cerr << "RsDummySerialiser::size(RsItem *item) Error with dummy cast!\n"; + } + + return 0; +} + + +bool RsDummySerialiser::serialise(RsItem *item, void *data, uint32_t *size) +{ + RsDummyMsg* msg; + RsDummyGrp* grp; + + if( (msg = dynamic_cast(item)) != NULL ) + { + return serialiseDummyMsgItem(msg, data, size); + }else if( (grp = dynamic_cast(item)) != NULL ) + { + return serialiseDummyGrpItem(grp, data, size); + }else + { + std::cerr << "RsDummySerialiser::size(RsItem *item) Error with dummy cast!\n"; + } + + return false; +} + +RsItem* RsDummySerialiser::deserialise(void *data, uint32_t *size) +{ + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_TYPE_DUMMY != getRsItemService(rstype))) + { + return NULL; /* wrong type */ + } + + switch(getRsItemSubType(rstype)) + { + case RS_PKT_SUBTYPE_DUMMY_MSG: + return deserialiseDummyMsgItem(data, size); + case RS_PKT_SUBTYPE_DUMMY_GRP: + return deserialiseDummyGrpItem(data, size); + default: + return NULL; + } + + return NULL; +} + + +uint32_t RsDummySerialiser::sizeDummyMsgItem(RsDummyMsg *item) +{ + s += 8; // header + s += GetTlvStringSize(item->msgData); + + return s; +} + +bool RsDummySerialiser::serialiseDummyMsgItem (RsDummyMsg *item, void *data, uint32_t *size) +{ + uint32_t tlvsize = sizeDummyMsgItem(item); + uint32_t offset = 0; + + if (*size < tlvsize) + return false; /* not enough space */ + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* RsDistribMsg first */ + + ok &= SetTlvString(data, *size, &offset, 1, item->msgData); + + if (offset != tlvsize) + { + ok = false; + std::cerr << "RsDummySerialiser::serialiseDummyMsgItem Size Error! " << std::endl; + } + + return ok; +} + +RsDummyMsg * RsDummySerialiser::deserialiseDummyMsgItem(void *data, uint32_t *size) +{ + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_TYPE_DUMMY != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_DUMMY_MSG != getRsItemSubType(rstype))) + { + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + return NULL; /* not enough data */ + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + /* ready to load */ + RsDummyMsg *item = new RsDummyMsg(); + + /* skip the header */ + offset += 8; + + ok &= GetTlvString(data, *size, offset, 1, item->msgData); + + if (!ok) + { + delete item; + return NULL; + } + + return item; +} + +uint32_t RsDummySerialiser::sizeDummyGrpItem(RsDummyGrp *item) +{ + s += 8; + s += GetTlvStringSize(item->grpData); + + return s; +} + +bool RsDummySerialiser::serialiseDummyGrpItem (RsDummyGrp *item, void *data, uint32_t *size) +{ + uint32_t tlvsize = sizeDummyGrpItem(item); + uint32_t offset = 0; + + if (*size < tlvsize) + return false; /* not enough space */ + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + ok &= SetTlvString(data, *size, &offset, 1, item->grpData); + + if (offset != tlvsize) + { + ok = false; + std::cerr << "RsDummySerialiser::serialiseDummyGrpItem Size Error! " << std::endl; + } + + return ok; +} + +RsDummyGrp * RsDummySerialiser::deserialiseDummyGrpItem(void *data, uint32_t *size) +{ + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_TYPE_DUMMY != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_DUMMY_GRP != getRsItemSubType(rstype))) + { + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + return NULL; /* not enough data */ + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + /* ready to load */ + RsDummyGrp *item = new RsDummyGrp(); + + /* skip the header */ + offset += 8; + + ok &= GetTlvString(data, *size, offset, 1, item->grpData); + + if (!ok) + { + delete item; + return NULL; + } + + return item; +} + + diff --git a/libretroshare/src/tests/gxs/rsdummyservices.h b/libretroshare/src/tests/gxs/rsdummyservices.h new file mode 100644 index 000000000..c4ae37d64 --- /dev/null +++ b/libretroshare/src/tests/gxs/rsdummyservices.h @@ -0,0 +1,94 @@ +#ifndef RSDUMMYSERVICES_H +#define RSDUMMYSERVICES_H + + +// dummy services to make + +#include "gxs/rsnxs.h" +#include "serialiser/rsgxsitems.h" + +class RsDummyNetService: public RsNetworkExchangeService +{ +public: + + RsNetworkExchangeService(){ return;} + + void setSyncAge(uint32_t age){} + + void requestGroupsOfPeer(const std::string& peerId){} + + void requestMessagesOfPeer(const std::string& peerId, const std::string& grpId){} + + void pauseSynchronisation(bool enabled) {} + + int requestMsg(const std::string& msgId, uint8_t hops){ return 0;} + + int requestGrp(const std::list& grpId, uint8_t hops) { return 0;} +}; + + + +uint16_t RS_SERVICE_TYPE_DUMMY = 0x01; +uint8_t RS_PKT_SUBTYPE_DUMMY_MSG = 0x02; +uint8_t RS_PKT_SUBTYPE_DUMMY_GRP = 0x03; + + +class RsDummyMsg : public RsGxsMsgItem +{ +public: + RsDummyMsg() : RsGxsMsgItem(RS_SERVICE_TYPE_DUMMY, RS_PKT_SUBTYPE_DUMMY_MSG) { return; } + virtual RsDummyMsg() { return; } + + std::string msgData; + + std::ostream &print(std::ostream &out, uint16_t indent = 0){ return out; } + void clear() { msgData.clear(); } + +}; + +class RsDummyGrp : public RsGxsGrpItem +{ + RsDummyGrp() : RsGxsGrpItem(RS_SERVICE_TYPE_DUMMY, RS_PKT_SUBTYPE_DUMMY_GRP) { return; } + virtual RsDummyGrp() { return; } + + + + std::string grpData; + void clear() { grpData.clear(); } + std::ostream &print(std::ostream &out, uint16_t indent = 0){ return out; } +}; + + + +class RsDummySerialiser : public RsSerialType +{ + +public: + + + RsDummySerialiser() + :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_DUMMY) + { return; } + virtual ~RsGxsPhotoSerialiser() { return; } + + uint32_t size(RsItem *item); + bool serialise (RsItem *item, void *data, uint32_t *size); + RsItem * deserialise(void *data, uint32_t *size); + + private: + + uint32_t sizeDummyMsgItem(RsDummyMsg *item); + bool serialiseDummyMsgItem (RsDummyMsg *item, void *data, uint32_t *size); + RsDummyMsg * deserialiseDummyMsgItem(void *data, uint32_t *size); + + uint32_t sizeDummyGrpItem(RsDummyGrp *item); + bool serialiseDummyGrpItem (RsDummyGrp *item, void *data, uint32_t *size); + RsDummyGrp * deserialiseDummyGrpItem(void *data, uint32_t *size); + + +}; + + + + +#endif // RSDUMMYSERVICES_H diff --git a/libretroshare/src/tests/gxs/rsgenexchange_test.cc b/libretroshare/src/tests/gxs/rsgenexchange_test.cc new file mode 100644 index 000000000..6d3d57a07 --- /dev/null +++ b/libretroshare/src/tests/gxs/rsgenexchange_test.cc @@ -0,0 +1,28 @@ + + +#include "genexchangetester.h" +#include "genexchangetestservice.h" +#include "util/utest.h" +#include "gxs/gxscoreserver.h" +#include "gxs/rsdataservice.h" +#include "rsdummyservices.h" + +INITTEST(); + + +int main() +{ + + + GxsCoreServer gxsCore; + + // create data service and dummy net service + RsDummyNetService dummyNet; + RsDataService dataStore("./", "testServiceDb", 0, NULL); + GenExchangeTestService testService; + gxsCore.addService(&testService); + createThread(gxsCore); + + + +} diff --git a/libretroshare/src/tests/gxs/rsgenexhchange_test.pro b/libretroshare/src/tests/gxs/rsgenexhchange_test.pro new file mode 100644 index 000000000..042fe2565 --- /dev/null +++ b/libretroshare/src/tests/gxs/rsgenexhchange_test.pro @@ -0,0 +1,62 @@ + +TEMPLATE = app +TARGET = rsgenexcahnge_test + + +win32 { + + # Switch on extra warnings + QMAKE_CFLAGS += -Wextra + QMAKE_CXXFLAGS += -Wextra + + # Switch off optimization for release version + QMAKE_CXXFLAGS_RELEASE -= -O2 + QMAKE_CXXFLAGS_RELEASE += -O0 + QMAKE_CFLAGS_RELEASE -= -O2 + QMAKE_CFLAGS_RELEASE += -O0 + + # Switch on optimization for debug version + #QMAKE_CXXFLAGS_DEBUG += -O2 + #QMAKE_CFLAGS_DEBUG += -O2 + +# PRE_TARGETDEPS += ../../libretroshare/src/lib/libretroshare.a + PRE_TARGETDEPS += C:\Development\Rs\v0.5-gxs-b1/libretroshare/libretroshare-build-desktop/lib/libretroshare.a + + LIBS += C:\Development\Rs\v0.5-gxs-b1/libretroshare/libretroshare-build-desktop/lib/libretroshare.a + LIBS += C:\Development\Rs\v0.5-gxs-b1\openpgpsdk\openpgpsdk-build-desktop\lib\libops.a + LIBS += C:\Development\Libraries\sqlite\sqlite-autoconf-3070900\lib\libsqlite3.a + LIBS += -L"../../../lib" + LIBS += -lssl -lcrypto -lgpgme -lpthreadGC2d -lminiupnpc -lz -lbz2 +# added after bitdht +# LIBS += -lws2_32 + LIBS += -luuid -lole32 -liphlpapi -lcrypt32-cygwin -lgdi32 + LIBS += -lole32 -lwinmm + RC_FILE = gui/images/retroshare_win.rc + + # export symbols for the plugins + #LIBS += -Wl,--export-all-symbols,--out-implib,lib/libretroshare-gui.a + + GPG_ERROR_DIR = ../../../../libgpg-error-1.7 + GPGME_DIR = ../../../../gpgme-1.1.8 + GPG_ERROR_DIR = ../../../../lib/libgpg-error-1.7 + GPGME_DIR = ../../../../lib/gpgme-1.1.8 + INCLUDEPATH += . $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src + + + +} + +INCLUDEPATH += C:\Development\Rs\v0.5-gxs-b1\libretroshare\src + +HEADERS += \ + genexchangetestservice.h \ + genexchangetester.h \ + rsdummyservices.h \ + support.h + +SOURCES += \ + genexchangetestservice.cpp \ + genexchangetester.cpp \ + rsgenexchange_test.cc \ + support.cc \ + rsdummyservices.cc From 7694bc8bf3c307ec26f989558bde93b9181b6424 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Fri, 24 Aug 2012 11:49:31 +0000 Subject: [PATCH 037/222] fixed bug introduced into retrodb. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5465 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/util/retrodb.cc | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/libretroshare/src/util/retrodb.cc b/libretroshare/src/util/retrodb.cc index d5b2964ca..2075cec45 100644 --- a/libretroshare/src/util/retrodb.cc +++ b/libretroshare/src/util/retrodb.cc @@ -30,7 +30,7 @@ #include "retrodb.h" -//#define RETRODB_DEBUG +#define RETRODB_DEBUG @@ -237,7 +237,6 @@ bool RetroDb::sqlInsert(const std::string &table, const std::string& nullColumnH cv.getAsBool(key, value); oStrStream << value; qValues += oStrStream.str(); - break; } else if( ContentValue::DOUBLE_TYPE == type) { @@ -245,7 +244,6 @@ bool RetroDb::sqlInsert(const std::string &table, const std::string& nullColumnH cv.getAsDouble(key, value); oStrStream << value; qValues += oStrStream.str(); - break; } else if( ContentValue::DATA_TYPE == type) { @@ -258,14 +256,12 @@ bool RetroDb::sqlInsert(const std::string &table, const std::string& nullColumnH b.index = ++index; blobL.push_back(b); qValues += "?"; // parameter - break; } else if ( ContentValue::STRING_TYPE == type) { std::string value; cv.getAsString(key, value); qValues += "'" + value +"'"; - break; } else if ( ContentValue::INT32_TYPE == type) { @@ -273,7 +269,6 @@ bool RetroDb::sqlInsert(const std::string &table, const std::string& nullColumnH cv.getAsInt32(key, value); oStrStream << value; qValues += oStrStream.str(); - break; } else if( ContentValue::INT64_TYPE == type) { @@ -281,7 +276,6 @@ bool RetroDb::sqlInsert(const std::string &table, const std::string& nullColumnH cv.getAsInt64(key, value); oStrStream << value; qValues += oStrStream.str(); - break; } @@ -420,7 +414,6 @@ bool RetroDb::sqlUpdate(const std::string &tableName, std::string whereClause, c cv.getAsBool(key, value); oStrStream << value; qValues += key + "='" + oStrStream.str(); - break; } else if( ContentValue::DOUBLE_TYPE == type) { @@ -428,7 +421,6 @@ bool RetroDb::sqlUpdate(const std::string &tableName, std::string whereClause, c cv.getAsDouble(key, value); oStrStream << value; qValues += key + "='" + oStrStream.str(); - break; } else if( ContentValue::DATA_TYPE == type) { @@ -437,14 +429,12 @@ bool RetroDb::sqlUpdate(const std::string &tableName, std::string whereClause, c cv.getAsData(key, len, value); oStrStream.write(value, len); qValues += key + "='" + oStrStream.str() + "' "; - break; } else if( ContentValue::STRING_TYPE == type) { std::string value; cv.getAsString(key, value); qValues += key + "='" + value + "' "; - break; } else if( ContentValue::INT32_TYPE == type) { @@ -452,7 +442,6 @@ bool RetroDb::sqlUpdate(const std::string &tableName, std::string whereClause, c cv.getAsInt32(key, value); oStrStream << value; qValues += key + "='" + oStrStream.str() + "' "; - break; } else if( ContentValue::INT64_TYPE == type) { @@ -460,10 +449,8 @@ bool RetroDb::sqlUpdate(const std::string &tableName, std::string whereClause, c cv.getAsInt64(key, value); oStrStream << value; qValues += key + "='" + oStrStream.str() + "' "; - break; } - mit++; if(mit != keyTypeMap.end()){ // add comma if more columns left qValues += ","; From 1d35dc291576613622e02f62463a501edc19728b Mon Sep 17 00:00:00 2001 From: drbob Date: Fri, 24 Aug 2012 22:33:24 +0000 Subject: [PATCH 038/222] Changed base.proto & namespace to "core", as base is a reserved keyword in C# * Started specifying the search protocol in files.proto * Added Create Msgs in gxs.proto. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5466 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- rsctrl/src/Makefile | 4 +- .../src/definition/{base.proto => core.proto} | 4 +- rsctrl/src/definition/files.proto | 152 ++++++++++++++---- rsctrl/src/definition/gxs.proto | 40 ++++- rsctrl/src/definition/msgs.proto | 16 +- rsctrl/src/definition/peers.proto | 16 +- rsctrl/src/definition/system.proto | 7 +- 7 files changed, 177 insertions(+), 62 deletions(-) rename rsctrl/src/definition/{base.proto => core.proto} (97%) diff --git a/rsctrl/src/Makefile b/rsctrl/src/Makefile index 497622038..8f95ce873 100644 --- a/rsctrl/src/Makefile +++ b/rsctrl/src/Makefile @@ -1,7 +1,7 @@ EXEC = protoc -#PROTO = base.proto files.proto gxs.proto msgs.proto peers.proto system.proto -PROTO = base.proto peers.proto +#PROTO = core.proto files.proto gxs.proto msgs.proto peers.proto system.proto +PROTO = core.proto peers.proto PROTOPATH = ./definition CDESTPATH = ./gencc diff --git a/rsctrl/src/definition/base.proto b/rsctrl/src/definition/core.proto similarity index 97% rename from rsctrl/src/definition/base.proto rename to rsctrl/src/definition/core.proto index cdde0d362..6d817a4e6 100644 --- a/rsctrl/src/definition/base.proto +++ b/rsctrl/src/definition/core.proto @@ -1,4 +1,4 @@ -package rsctrl.base; +package rsctrl.core; /////////////////////////////////////////////////////////////// // These are basic Messages, which are used as building blocks @@ -9,7 +9,7 @@ package rsctrl.base; /////////////////////////////////////////////////////////////// // Expected PackageIds. -enum ExtensionId { BASE = 0; } +enum ExtensionId { CORE = 0; } enum PackageId { PEERS = 1; diff --git a/rsctrl/src/definition/files.proto b/rsctrl/src/definition/files.proto index 87fa59237..25df217bc 100644 --- a/rsctrl/src/definition/files.proto +++ b/rsctrl/src/definition/files.proto @@ -1,6 +1,6 @@ package rsctrl.files; -import "base.proto"; +import "core.proto"; /////////////////////////////////////////////////////////////// // Mirror most of rsFiles functionality. @@ -24,42 +24,130 @@ enum ResponseMsgIds { } /////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +// SEARCH (start). -// REQUEST: RequestPeers -message RequestPeers { +// REQUEST: RequestBasicSearch +message RequestBasicSearch { - // About Who? - enum SetOption { - OWNID = 1; - LISTED = 2; - ONLINE = 3; - FRIENDS = 4; - VALID = 5; - SIGNED = 6; - ALL = 7; - } + repeated string terms = 1; +} - // What do you want? - enum InfoOption { - NAMEONLY = 1; - BASIC = 2; - LOCATION = 3; - ALLINFO = 4; - } +// REQUEST: RequestAdvSearch +message RequestAdvSearch { - required SetOption set = 1; - required InfoOption info = 2; - repeated string gpg_ids = 3; + repeated string terms = 1; } -// RESPONSE: ResponsePeerList -message ResponsePeerList { - required rsctrl.base.Status status = 1; - repeated rsctrl.base.Person peers = 2; +// RESPONSE: ResponseSearchId +message ResponseSearchId { + + required rsctrl.core.Status status = 1; + required string search_id = 2; } /////////////////////////////////////////////////////////////// +// SEARCH (list) + + +// REQUEST: RequestSearchResults +message RequestSearchResults { + + enum SetCmd { + ALLIDS = 1; // All + LISTED = 2; // Only Search Ids in the Vector. + } + + required SetCmd set = 1; + repeated string search_ids = 2; +} + +// Building Block +message SearchHit { + + enum LocFlag { + LOCAL = 1; // We Have it. + FRIEND = 2; // Browsable + NETWORK = 4; // Network. + } + + required rsctrl.core.File file = 1; + required int no_hits = 2 + required LocFlag loc = 3; + +} + +message SearchSet { + + required string search_id = 1; + + enum SearchType { + BASIC = 1; // Stuff. + ADVANCED = 2; // Stuff. + } + + // One of these will be filled in depending on flag. + + required SearchType search_type = 2; + optional RequestBasicSearch basic_req = 3; + optional RequestAdvSearch adv_req = 4; + + repeated SearchHit = 5; + +} + +// RESPONSE: ResponseSearchResults +message ResponseSearchResults { + + required rsctrl.core.Status status = 1; + repeated SearchSet searches = 2; +} + + +/////////////////////////////////////////////////////////////// +// SEARCH (cancel) + +// REQUEST: RequestCloseSearch +message RequestCloseSearch { + + required string search_id = 2; +} + + +// RESPONSE: ResponseSearchId +// As before. + + +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +// SHARED FILES + + + +// REQUEST: RequestListShares +message RequestListShares { + + required int depth = 1; // HOW Many Directories to drill down. + repeated string ShareLocation = 2; +} + +message ShareLocation { + required string ssl_id = 1; + required string path = 2; +} + +message + + + +// REQUEST: RequestChangeShares + +// REQUEST: RequestLiCloseSearch +// REQUEST: RequestCloseSearch + + + // REQUEST: RequestAddPeer message RequestAddPeer { @@ -79,8 +167,8 @@ message RequestAddPeer { // RESPONSE: ResponseAddPeer message ResponseAddPeer { - required rsctrl.base.Status status = 1; - repeated rsctrl.base.Person peers = 2; + required rsctrl.core.Status status = 1; + repeated rsctrl.core.Person peers = 2; } /////////////////////////////////////////////////////////////// @@ -100,13 +188,13 @@ message RequestModifyPeer { required ModCmd cmd = 1; //required int64 cmd = 1; // Could we OR the Cmds together? - repeated rsctrl.base.Person peers = 2; + repeated rsctrl.core.Person peers = 2; } // RESPONSE: ResponseModifyPeer message ResponseModifyPeer { - required rsctrl.base.Status status = 1; - repeated rsctrl.base.Person peers = 2; + required rsctrl.core.Status status = 1; + repeated rsctrl.core.Person peers = 2; } /////////////////////////////////////////////////////////////// diff --git a/rsctrl/src/definition/gxs.proto b/rsctrl/src/definition/gxs.proto index 98a88c7c4..57bcd5a0f 100644 --- a/rsctrl/src/definition/gxs.proto +++ b/rsctrl/src/definition/gxs.proto @@ -1,6 +1,6 @@ package rsctrl.gxs; -import "base.proto"; +import "core.proto"; /////////////////////////////////////////////////////////////// // Base Messages for GXS Interface. @@ -179,7 +179,7 @@ message RequestGroupInfo { // RESPONSE: ResponseGroupList message ResponseGroupList { - required rsctrl.base.Status status = 1; + required rsctrl.core.Status status = 1; required Service service = 2; repeated string group_ids = 3; @@ -189,7 +189,7 @@ message ResponseGroupList { // RESPONSE: ResponseGroupMeta message ResponseGroupMeta { - required rsctrl.base.Status status = 1; + required rsctrl.core.Status status = 1; required Service service = 2; repeated GroupMeta meta = 3; @@ -199,7 +199,7 @@ message ResponseGroupMeta { // RESPONSE: ResponseGroupData message ResponseGroupData { - required rsctrl.base.Status status = 1; + required rsctrl.core.Status status = 1; required Service service = 2; repeated GroupGenericData data = 3; @@ -231,7 +231,7 @@ message RequestMsgRelatedInfo { // RESPONSE: ResponseMsgList message ResponseMsgList { - required rsctrl.base.Status status = 1; + required rsctrl.core.Status status = 1; required Service service = 2; repeated GroupMsgSet msgs = 3; @@ -240,7 +240,7 @@ message ResponseMsgList { // RESPONSE: ResponseMsgMeta message ResponseMsgMeta { - required rsctrl.base.Status status = 1; + required rsctrl.core.Status status = 1; required Service service = 2; repeated MsgMeta meta = 3; @@ -249,7 +249,7 @@ message ResponseMsgMeta { // RESPONSE: ResponseMsgData message ResponseMsgData { - required rsctrl.base.Status status = 1; + required rsctrl.core.Status status = 1; required Service service = 2; repeated MsgGenericData data = 3; @@ -259,3 +259,29 @@ message ResponseMsgData { /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// + +// REQUEST: RequestCreateGroup +message RequestCreateGroup { + + required Service service = 1; + repeated GroupGenericData data = 2; +} + + +// RESPONSE: ResponseMsgMeta +// As defined above. + + +// REQUEST: RequestCreateMsg +message RequestCreateMsg { + + required Service service = 1; + repeated MsgGenericData data = 2; +} + +// RESPONSE: ResponseMsgMeta +// As defined above. + + + + diff --git a/rsctrl/src/definition/msgs.proto b/rsctrl/src/definition/msgs.proto index a6842c9d3..e011dfb33 100644 --- a/rsctrl/src/definition/msgs.proto +++ b/rsctrl/src/definition/msgs.proto @@ -1,6 +1,6 @@ package rsctrl.msgs; -import "base.proto"; +import "core.proto"; /////////////////////////////////////////////////////////////// // Access, and Control your Friends / Peers and related Settings. @@ -50,8 +50,8 @@ message RequestPeers { // RESPONSE: ResponsePeerList message ResponsePeerList { - required rsctrl.base.Status status = 1; - repeated rsctrl.base.Person peers = 2; + required rsctrl.core.Status status = 1; + repeated rsctrl.core.Person peers = 2; } /////////////////////////////////////////////////////////////// @@ -74,8 +74,8 @@ message RequestAddPeer { // RESPONSE: ResponseAddPeer message ResponseAddPeer { - required rsctrl.base.Status status = 1; - repeated rsctrl.base.Person peers = 2; + required rsctrl.core.Status status = 1; + repeated rsctrl.core.Person peers = 2; } /////////////////////////////////////////////////////////////// @@ -95,13 +95,13 @@ message RequestModifyPeer { required ModCmd cmd = 1; //required int64 cmd = 1; // Could we OR the Cmds together? - repeated rsctrl.base.Person peers = 2; + repeated rsctrl.core.Person peers = 2; } // RESPONSE: ResponseModifyPeer message ResponseModifyPeer { - required rsctrl.base.Status status = 1; - repeated rsctrl.base.Person peers = 2; + required rsctrl.core.Status status = 1; + repeated rsctrl.core.Person peers = 2; } /////////////////////////////////////////////////////////////// diff --git a/rsctrl/src/definition/peers.proto b/rsctrl/src/definition/peers.proto index c4886cbfd..6c85029f3 100644 --- a/rsctrl/src/definition/peers.proto +++ b/rsctrl/src/definition/peers.proto @@ -1,6 +1,6 @@ package rsctrl.peers; -import "base.proto"; +import "core.proto"; /////////////////////////////////////////////////////////////// // Access, and Control your Friends / Peers and related Settings. @@ -50,8 +50,8 @@ message RequestPeers { // RESPONSE: ResponsePeerList message ResponsePeerList { - required rsctrl.base.Status status = 1; - repeated rsctrl.base.Person peers = 2; + required rsctrl.core.Status status = 1; + repeated rsctrl.core.Person peers = 2; } /////////////////////////////////////////////////////////////// @@ -74,8 +74,8 @@ message RequestAddPeer { // RESPONSE: ResponseAddPeer message ResponseAddPeer { - required rsctrl.base.Status status = 1; - repeated rsctrl.base.Person peers = 2; + required rsctrl.core.Status status = 1; + repeated rsctrl.core.Person peers = 2; } /////////////////////////////////////////////////////////////// @@ -95,13 +95,13 @@ message RequestModifyPeer { required ModCmd cmd = 1; //required int64 cmd = 1; // Could we OR the Cmds together? - repeated rsctrl.base.Person peers = 2; + repeated rsctrl.core.Person peers = 2; } // RESPONSE: ResponseModifyPeer message ResponseModifyPeer { - required rsctrl.base.Status status = 1; - repeated rsctrl.base.Person peers = 2; + required rsctrl.core.Status status = 1; + repeated rsctrl.core.Person peers = 2; } /////////////////////////////////////////////////////////////// diff --git a/rsctrl/src/definition/system.proto b/rsctrl/src/definition/system.proto index e8eadd0ea..12ff57685 100644 --- a/rsctrl/src/definition/system.proto +++ b/rsctrl/src/definition/system.proto @@ -1,6 +1,6 @@ package rsctrl.peers; -import "base.proto"; +import "core.proto"; /////////////////////////////////////////////////////////////// // Configuration and Stats. @@ -39,7 +39,7 @@ message ResponseSystemStatus { } // Status of response. - required rsctrl.base.Status status = 1; + required rsctrl.core.Status status = 1; // Peers. required uint32 peer_count = 2; @@ -47,7 +47,8 @@ message ResponseSystemStatus { // Basic Network Information. required NetCode net_status = 4; - required rsctrl.base.Bandwidth bw_total = 5; + + required rsctrl.core.Bandwidth bw_total = 5; } /////////////////////////////////////////////////////////////// From 51fc0c59feeb4b8f4627f81b2e9946242ce1d89b Mon Sep 17 00:00:00 2001 From: drbob Date: Sat, 25 Aug 2012 11:41:39 +0000 Subject: [PATCH 039/222] Updates to some of the protobuf files. Added System.proto for basic info. - added relationship field to core.person. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5468 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- rsctrl/src/Makefile | 9 ++++--- rsctrl/src/definition/core.proto | 43 +++++++++++++++++++++++------- rsctrl/src/definition/files.proto | 8 +++--- rsctrl/src/definition/peers.proto | 2 +- rsctrl/src/definition/system.proto | 6 ++--- 5 files changed, 46 insertions(+), 22 deletions(-) diff --git a/rsctrl/src/Makefile b/rsctrl/src/Makefile index 8f95ce873..b879f4c0b 100644 --- a/rsctrl/src/Makefile +++ b/rsctrl/src/Makefile @@ -1,12 +1,13 @@ EXEC = protoc #PROTO = core.proto files.proto gxs.proto msgs.proto peers.proto system.proto -PROTO = core.proto peers.proto +PROTO = core.proto peers.proto system.proto PROTOPATH = ./definition -CDESTPATH = ./gencc -#CDESTPATH = ../../retroshare-nogui/src/rpc/proto/gencc -PYDESTPATH = ./genpy +#CDESTPATH = ./gencc +CDESTPATH = ../../retroshare-nogui/src/rpc/proto/gencc +#PYDESTPATH = ./genpy +PYDESTPATH = ../../../../github/pyrs/pyrs/proto CLIST = $(PROTO:%.proto=%.cc) CCODE = $(patsubst %.proto,$(CDESTPATH)/%.pb.cc, $(PROTO)) diff --git a/rsctrl/src/definition/core.proto b/rsctrl/src/definition/core.proto index 6d817a4e6..58da5bef8 100644 --- a/rsctrl/src/definition/core.proto +++ b/rsctrl/src/definition/core.proto @@ -27,31 +27,58 @@ enum PackageId { message Status { enum StatusCode { - FAILED = 0; - INVALID_QUERY = 1; - SUCCESS = 2; - READMSG = 3; + FAILED = 0; + NO_IMPL_YET = 1; + INVALID_QUERY = 2; + SUCCESS = 3; + READMSG = 4; } required StatusCode code = 1; optional string msg = 2; } +/////////////////////////////////////////////////////////////// + +message IpAddr { + required string addr = 1 [default = ""]; + required uint32 port = 2 [default = 0]; // must be 16 bit, 0 for unknown. +} + +/////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// // Peer structures, mainly rsctrl.peers related. message Location { + + enum StateFlags { // ORd together... + ONLINE = 1; + CONNECTED = 2; + UNREACHABLE = 4; + } + required string ssl_id = 1; required string location = 2; - required string localaddr = 3; - required string extaddr = 4; + required IpAddr localaddr = 3; + required IpAddr extaddr = 4; + + required uint32 state = 5; // Not an ENUM as ORd together. } message Person { + + enum Relationship { + FRIEND = 1; + FRIEND_OF_MANY_FRIENDS = 2; // 3+ at the moment. + FRIEND_OF_FRIENDS = 3; // 1 or 2. + UNKNOWN = 4; + } + required string gpg_id = 1; required string name = 2; + required Relationship relation = 3; - repeated Location locations = 3; + repeated Location locations = 4; } /////////////////////////////////////////////////////////////// @@ -115,5 +142,3 @@ message BandwidthSet { /////////////////////////////////////////////////////////////// - - diff --git a/rsctrl/src/definition/files.proto b/rsctrl/src/definition/files.proto index 25df217bc..1c813b032 100644 --- a/rsctrl/src/definition/files.proto +++ b/rsctrl/src/definition/files.proto @@ -73,7 +73,7 @@ message SearchHit { } required rsctrl.core.File file = 1; - required int no_hits = 2 + required uint32 no_hits = 2; required LocFlag loc = 3; } @@ -93,7 +93,7 @@ message SearchSet { optional RequestBasicSearch basic_req = 3; optional RequestAdvSearch adv_req = 4; - repeated SearchHit = 5; + repeated SearchHit hits = 5; } @@ -128,7 +128,7 @@ message RequestCloseSearch { // REQUEST: RequestListShares message RequestListShares { - required int depth = 1; // HOW Many Directories to drill down. + required uint32 depth = 1; // HOW Many Directories to drill down. repeated string ShareLocation = 2; } @@ -137,8 +137,6 @@ message ShareLocation { required string path = 2; } -message - // REQUEST: RequestChangeShares diff --git a/rsctrl/src/definition/peers.proto b/rsctrl/src/definition/peers.proto index 6c85029f3..8e27ae8f8 100644 --- a/rsctrl/src/definition/peers.proto +++ b/rsctrl/src/definition/peers.proto @@ -27,7 +27,7 @@ message RequestPeers { enum SetOption { OWNID = 1; LISTED = 2; - ONLINE = 3; + CONNECTED = 3; FRIENDS = 4; VALID = 5; SIGNED = 6; diff --git a/rsctrl/src/definition/system.proto b/rsctrl/src/definition/system.proto index 12ff57685..73ed8da8a 100644 --- a/rsctrl/src/definition/system.proto +++ b/rsctrl/src/definition/system.proto @@ -1,4 +1,4 @@ -package rsctrl.peers; +package rsctrl.system; import "core.proto"; @@ -42,8 +42,8 @@ message ResponseSystemStatus { required rsctrl.core.Status status = 1; // Peers. - required uint32 peer_count = 2; - required uint32 online_count = 3; + required uint32 no_peers = 2; + required uint32 no_connected = 3; // Basic Network Information. required NetCode net_status = 4; From c8350ad0114acc04d098cb7a237b415525817e96 Mon Sep 17 00:00:00 2001 From: drbob Date: Sat, 25 Aug 2012 11:47:20 +0000 Subject: [PATCH 040/222] Got the first RPC commands working now and tested with python library. * Switched from BASE => CORE in proto files. * finished first RPC call to list peers. * return "NO_IMPL_YET" for other peer fns (Not Implemented Yet) * Added SystemStatus RPC call too. * Disable Verbose SSH logging - so we can see debug better. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5469 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/retroshare-nogui.pro | 8 +- .../proto/gencc/{base.pb.cc => core.pb.cc} | 712 +++++++++++++---- .../rpc/proto/gencc/{base.pb.h => core.pb.h} | 724 ++++++++++++----- .../src/rpc/proto/gencc/peers.pb.cc | 132 +-- .../src/rpc/proto/gencc/peers.pb.h | 182 ++--- .../src/rpc/proto/gencc/system.pb.cc | 753 ++++++++++++++++++ .../src/rpc/proto/gencc/system.pb.h | 494 ++++++++++++ .../src/rpc/proto/rpcprotopeers.cc | 188 ++++- .../src/rpc/proto/rpcprotosystem.cc | 213 +++++ .../src/rpc/proto/rpcprotosystem.h | 41 + retroshare-nogui/src/rpc/rpcsetup.cc | 4 + retroshare-nogui/src/ssh/rssshd.cc | 2 +- 12 files changed, 2914 insertions(+), 539 deletions(-) rename retroshare-nogui/src/rpc/proto/gencc/{base.pb.cc => core.pb.cc} (80%) rename retroshare-nogui/src/rpc/proto/gencc/{base.pb.h => core.pb.h} (74%) create mode 100644 retroshare-nogui/src/rpc/proto/gencc/system.pb.cc create mode 100644 retroshare-nogui/src/rpc/proto/gencc/system.pb.h create mode 100644 retroshare-nogui/src/rpc/proto/rpcprotosystem.cc create mode 100644 retroshare-nogui/src/rpc/proto/rpcprotosystem.h diff --git a/retroshare-nogui/src/retroshare-nogui.pro b/retroshare-nogui/src/retroshare-nogui.pro index 7ad06d836..ec7571f3f 100644 --- a/retroshare-nogui/src/retroshare-nogui.pro +++ b/retroshare-nogui/src/retroshare-nogui.pro @@ -185,15 +185,19 @@ sshserver { protorpc { # Proto Services HEADERS += rpc/proto/rpcprotopeers.h \ + rpc/proto/rpcprotosystem.h \ SOURCES += rpc/proto/rpcprotopeers.cc \ + rpc/proto/rpcprotosystem.cc \ # Generated ProtoBuf Code the RPC System - HEADERS += rpc/proto/gencc/base.pb.h \ + HEADERS += rpc/proto/gencc/core.pb.h \ rpc/proto/gencc/peers.pb.h \ + rpc/proto/gencc/system.pb.h \ - SOURCES += rpc/proto/gencc/base.pb.cc \ + SOURCES += rpc/proto/gencc/core.pb.cc \ rpc/proto/gencc/peers.pb.cc \ + rpc/proto/gencc/system.pb.cc \ QMAKE_CFLAGS += -pthread QMAKE_CXXFLAGS += -pthread diff --git a/retroshare-nogui/src/rpc/proto/gencc/base.pb.cc b/retroshare-nogui/src/rpc/proto/gencc/core.pb.cc similarity index 80% rename from retroshare-nogui/src/rpc/proto/gencc/base.pb.cc rename to retroshare-nogui/src/rpc/proto/gencc/core.pb.cc index 30854a9d3..f669e5f61 100644 --- a/retroshare-nogui/src/rpc/proto/gencc/base.pb.cc +++ b/retroshare-nogui/src/rpc/proto/gencc/core.pb.cc @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! #define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION -#include "base.pb.h" +#include "core.pb.h" #include @@ -14,7 +14,7 @@ // @@protoc_insertion_point(includes) namespace rsctrl { -namespace base { +namespace core { namespace { @@ -22,12 +22,17 @@ const ::google::protobuf::Descriptor* Status_descriptor_ = NULL; const ::google::protobuf::internal::GeneratedMessageReflection* Status_reflection_ = NULL; const ::google::protobuf::EnumDescriptor* Status_StatusCode_descriptor_ = NULL; +const ::google::protobuf::Descriptor* IpAddr_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + IpAddr_reflection_ = NULL; const ::google::protobuf::Descriptor* Location_descriptor_ = NULL; const ::google::protobuf::internal::GeneratedMessageReflection* Location_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* Location_StateFlags_descriptor_ = NULL; const ::google::protobuf::Descriptor* Person_descriptor_ = NULL; const ::google::protobuf::internal::GeneratedMessageReflection* Person_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* Person_Relationship_descriptor_ = NULL; const ::google::protobuf::Descriptor* File_descriptor_ = NULL; const ::google::protobuf::internal::GeneratedMessageReflection* File_reflection_ = NULL; @@ -50,11 +55,11 @@ const ::google::protobuf::EnumDescriptor* PackageId_descriptor_ = NULL; } // namespace -void protobuf_AssignDesc_base_2eproto() { - protobuf_AddDesc_base_2eproto(); +void protobuf_AssignDesc_core_2eproto() { + protobuf_AddDesc_core_2eproto(); const ::google::protobuf::FileDescriptor* file = ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( - "base.proto"); + "core.proto"); GOOGLE_CHECK(file != NULL); Status_descriptor_ = file->message_type(0); static const int Status_offsets_[2] = { @@ -73,12 +78,29 @@ void protobuf_AssignDesc_base_2eproto() { ::google::protobuf::MessageFactory::generated_factory(), sizeof(Status)); Status_StatusCode_descriptor_ = Status_descriptor_->enum_type(0); - Location_descriptor_ = file->message_type(1); - static const int Location_offsets_[4] = { + IpAddr_descriptor_ = file->message_type(1); + static const int IpAddr_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(IpAddr, addr_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(IpAddr, port_), + }; + IpAddr_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + IpAddr_descriptor_, + IpAddr::default_instance_, + IpAddr_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(IpAddr, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(IpAddr, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(IpAddr)); + Location_descriptor_ = file->message_type(2); + static const int Location_offsets_[5] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Location, ssl_id_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Location, location_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Location, localaddr_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Location, extaddr_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Location, state_), }; Location_reflection_ = new ::google::protobuf::internal::GeneratedMessageReflection( @@ -91,10 +113,12 @@ void protobuf_AssignDesc_base_2eproto() { ::google::protobuf::DescriptorPool::generated_pool(), ::google::protobuf::MessageFactory::generated_factory(), sizeof(Location)); - Person_descriptor_ = file->message_type(2); - static const int Person_offsets_[3] = { + Location_StateFlags_descriptor_ = Location_descriptor_->enum_type(0); + Person_descriptor_ = file->message_type(3); + static const int Person_offsets_[4] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Person, gpg_id_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Person, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Person, relation_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Person, locations_), }; Person_reflection_ = @@ -108,7 +132,8 @@ void protobuf_AssignDesc_base_2eproto() { ::google::protobuf::DescriptorPool::generated_pool(), ::google::protobuf::MessageFactory::generated_factory(), sizeof(Person)); - File_descriptor_ = file->message_type(3); + Person_Relationship_descriptor_ = Person_descriptor_->enum_type(0); + File_descriptor_ = file->message_type(4); static const int File_offsets_[5] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, hash_), @@ -127,7 +152,7 @@ void protobuf_AssignDesc_base_2eproto() { ::google::protobuf::DescriptorPool::generated_pool(), ::google::protobuf::MessageFactory::generated_factory(), sizeof(File)); - Dir_descriptor_ = file->message_type(4); + Dir_descriptor_ = file->message_type(5); static const int Dir_offsets_[4] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Dir, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Dir, path_), @@ -145,7 +170,7 @@ void protobuf_AssignDesc_base_2eproto() { ::google::protobuf::DescriptorPool::generated_pool(), ::google::protobuf::MessageFactory::generated_factory(), sizeof(Dir)); - SystemStatus_descriptor_ = file->message_type(5); + SystemStatus_descriptor_ = file->message_type(6); static const int SystemStatus_offsets_[2] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SystemStatus, net_status_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SystemStatus, msg_), @@ -162,7 +187,7 @@ void protobuf_AssignDesc_base_2eproto() { ::google::protobuf::MessageFactory::generated_factory(), sizeof(SystemStatus)); SystemStatus_NetCode_descriptor_ = SystemStatus_descriptor_->enum_type(0); - Bandwidth_descriptor_ = file->message_type(6); + Bandwidth_descriptor_ = file->message_type(7); static const int Bandwidth_offsets_[3] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Bandwidth, up_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Bandwidth, down_), @@ -179,7 +204,7 @@ void protobuf_AssignDesc_base_2eproto() { ::google::protobuf::DescriptorPool::generated_pool(), ::google::protobuf::MessageFactory::generated_factory(), sizeof(Bandwidth)); - BandwidthSet_descriptor_ = file->message_type(7); + BandwidthSet_descriptor_ = file->message_type(8); static const int BandwidthSet_offsets_[1] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BandwidthSet, bandwidths_), }; @@ -203,13 +228,15 @@ namespace { GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); inline void protobuf_AssignDescriptorsOnce() { ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, - &protobuf_AssignDesc_base_2eproto); + &protobuf_AssignDesc_core_2eproto); } void protobuf_RegisterTypes(const ::std::string&) { protobuf_AssignDescriptorsOnce(); ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( Status_descriptor_, &Status::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + IpAddr_descriptor_, &IpAddr::default_instance()); ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( Location_descriptor_, &Location::default_instance()); ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( @@ -228,9 +255,11 @@ void protobuf_RegisterTypes(const ::std::string&) { } // namespace -void protobuf_ShutdownFile_base_2eproto() { +void protobuf_ShutdownFile_core_2eproto() { delete Status::default_instance_; delete Status_reflection_; + delete IpAddr::default_instance_; + delete IpAddr_reflection_; delete Location::default_instance_; delete Location_reflection_; delete Person::default_instance_; @@ -247,41 +276,50 @@ void protobuf_ShutdownFile_base_2eproto() { delete BandwidthSet_reflection_; } -void protobuf_AddDesc_base_2eproto() { +void protobuf_AddDesc_core_2eproto() { static bool already_here = false; if (already_here) return; already_here = true; GOOGLE_PROTOBUF_VERIFY_VERSION; ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( - "\n\nbase.proto\022\013rsctrl.base\"\212\001\n\006Status\022,\n\004" - "code\030\001 \002(\0162\036.rsctrl.base.Status.StatusCo" - "de\022\013\n\003msg\030\002 \001(\t\"E\n\nStatusCode\022\n\n\006FAILED\020" - "\000\022\021\n\rINVALID_QUERY\020\001\022\013\n\007SUCCESS\020\002\022\013\n\007REA" - "DMSG\020\003\"P\n\010Location\022\016\n\006ssl_id\030\001 \002(\t\022\020\n\010lo" - "cation\030\002 \002(\t\022\021\n\tlocaladdr\030\003 \002(\t\022\017\n\007extad" - "dr\030\004 \002(\t\"P\n\006Person\022\016\n\006gpg_id\030\001 \002(\t\022\014\n\004na" - "me\030\002 \002(\t\022(\n\tlocations\030\003 \003(\0132\025.rsctrl.bas" - "e.Location\"M\n\004File\022\014\n\004name\030\001 \002(\t\022\014\n\004hash" - "\030\002 \002(\t\022\014\n\004size\030\003 \002(\003\022\014\n\004path\030\004 \001(\t\022\r\n\005av" - "ail\030\005 \001(\t\"f\n\003Dir\022\014\n\004name\030\001 \002(\t\022\014\n\004path\030\002" - " \002(\t\022!\n\007subdirs\030\003 \003(\0132\020.rsctrl.base.Dir\022" - " \n\005files\030\004 \003(\0132\021.rsctrl.base.File\"\372\001\n\014Sy" - "stemStatus\0225\n\nnet_status\030\001 \002(\0162!.rsctrl." - "base.SystemStatus.NetCode\022\013\n\003msg\030\002 \001(\t\"\245" - "\001\n\007NetCode\022\017\n\013BAD_UNKNOWN\020\000\022\017\n\013BAD_OFFLI" - "NE\020\001\022\016\n\nBAD_NATSYM\020\002\022\021\n\rBAD_NODHT_NAT\020\003\022" - "\023\n\017WARNING_RESTART\020\004\022\022\n\016WARNING_NATTED\020\005" - "\022\021\n\rWARNING_NODHT\020\006\022\010\n\004GOOD\020\007\022\017\n\013ADV_FOR" - "WARD\020\010\"3\n\tBandwidth\022\n\n\002up\030\001 \002(\002\022\014\n\004down\030" - "\002 \002(\002\022\014\n\004name\030\003 \001(\t\":\n\014BandwidthSet\022*\n\nb" - "andwidths\030\001 \003(\0132\026.rsctrl.base.Bandwidth*" - "\027\n\013ExtensionId\022\010\n\004BASE\020\000*A\n\tPackageId\022\t\n" - "\005PEERS\020\001\022\n\n\006SYSTEM\020\002\022\t\n\005FILES\020\003\022\010\n\004MSGS\020" - "\004\022\010\n\003GXS\020\350\007", 971); + "\n\ncore.proto\022\013rsctrl.core\"\233\001\n\006Status\022,\n\004" + "code\030\001 \002(\0162\036.rsctrl.core.Status.StatusCo" + "de\022\013\n\003msg\030\002 \001(\t\"V\n\nStatusCode\022\n\n\006FAILED\020" + "\000\022\017\n\013NO_IMPL_YET\020\001\022\021\n\rINVALID_QUERY\020\002\022\013\n" + "\007SUCCESS\020\003\022\013\n\007READMSG\020\004\")\n\006IpAddr\022\016\n\004add" + "r\030\001 \002(\t:\000\022\017\n\004port\030\002 \002(\r:\0010\"\303\001\n\010Location\022" + "\016\n\006ssl_id\030\001 \002(\t\022\020\n\010location\030\002 \002(\t\022&\n\tloc" + "aladdr\030\003 \002(\0132\023.rsctrl.core.IpAddr\022$\n\007ext" + "addr\030\004 \002(\0132\023.rsctrl.core.IpAddr\022\r\n\005state" + "\030\005 \002(\r\"8\n\nStateFlags\022\n\n\006ONLINE\020\001\022\r\n\tCONN" + "ECTED\020\002\022\017\n\013UNREACHABLE\020\004\"\340\001\n\006Person\022\016\n\006g" + "pg_id\030\001 \002(\t\022\014\n\004name\030\002 \002(\t\0222\n\010relation\030\003 " + "\002(\0162 .rsctrl.core.Person.Relationship\022(\n" + "\tlocations\030\004 \003(\0132\025.rsctrl.core.Location\"" + "Z\n\014Relationship\022\n\n\006FRIEND\020\001\022\032\n\026FRIEND_OF" + "_MANY_FRIENDS\020\002\022\025\n\021FRIEND_OF_FRIENDS\020\003\022\013" + "\n\007UNKNOWN\020\004\"M\n\004File\022\014\n\004name\030\001 \002(\t\022\014\n\004has" + "h\030\002 \002(\t\022\014\n\004size\030\003 \002(\003\022\014\n\004path\030\004 \001(\t\022\r\n\005a" + "vail\030\005 \001(\t\"f\n\003Dir\022\014\n\004name\030\001 \002(\t\022\014\n\004path\030" + "\002 \002(\t\022!\n\007subdirs\030\003 \003(\0132\020.rsctrl.core.Dir" + "\022 \n\005files\030\004 \003(\0132\021.rsctrl.core.File\"\372\001\n\014S" + "ystemStatus\0225\n\nnet_status\030\001 \002(\0162!.rsctrl" + ".core.SystemStatus.NetCode\022\013\n\003msg\030\002 \001(\t\"" + "\245\001\n\007NetCode\022\017\n\013BAD_UNKNOWN\020\000\022\017\n\013BAD_OFFL" + "INE\020\001\022\016\n\nBAD_NATSYM\020\002\022\021\n\rBAD_NODHT_NAT\020\003" + "\022\023\n\017WARNING_RESTART\020\004\022\022\n\016WARNING_NATTED\020" + "\005\022\021\n\rWARNING_NODHT\020\006\022\010\n\004GOOD\020\007\022\017\n\013ADV_FO" + "RWARD\020\010\"3\n\tBandwidth\022\n\n\002up\030\001 \002(\002\022\014\n\004down" + "\030\002 \002(\002\022\014\n\004name\030\003 \001(\t\":\n\014BandwidthSet\022*\n\n" + "bandwidths\030\001 \003(\0132\026.rsctrl.core.Bandwidth" + "*\027\n\013ExtensionId\022\010\n\004CORE\020\000*A\n\tPackageId\022\t" + "\n\005PEERS\020\001\022\n\n\006SYSTEM\020\002\022\t\n\005FILES\020\003\022\010\n\004MSGS" + "\020\004\022\010\n\003GXS\020\350\007", 1292); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( - "base.proto", &protobuf_RegisterTypes); + "core.proto", &protobuf_RegisterTypes); Status::default_instance_ = new Status(); + IpAddr::default_instance_ = new IpAddr(); Location::default_instance_ = new Location(); Person::default_instance_ = new Person(); File::default_instance_ = new File(); @@ -290,6 +328,7 @@ void protobuf_AddDesc_base_2eproto() { Bandwidth::default_instance_ = new Bandwidth(); BandwidthSet::default_instance_ = new BandwidthSet(); Status::default_instance_->InitAsDefaultInstance(); + IpAddr::default_instance_->InitAsDefaultInstance(); Location::default_instance_->InitAsDefaultInstance(); Person::default_instance_->InitAsDefaultInstance(); File::default_instance_->InitAsDefaultInstance(); @@ -297,15 +336,15 @@ void protobuf_AddDesc_base_2eproto() { SystemStatus::default_instance_->InitAsDefaultInstance(); Bandwidth::default_instance_->InitAsDefaultInstance(); BandwidthSet::default_instance_->InitAsDefaultInstance(); - ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_base_2eproto); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_core_2eproto); } // Force AddDescriptors() to be called at static initialization time. -struct StaticDescriptorInitializer_base_2eproto { - StaticDescriptorInitializer_base_2eproto() { - protobuf_AddDesc_base_2eproto(); +struct StaticDescriptorInitializer_core_2eproto { + StaticDescriptorInitializer_core_2eproto() { + protobuf_AddDesc_core_2eproto(); } -} static_descriptor_initializer_base_2eproto_; +} static_descriptor_initializer_core_2eproto_; const ::google::protobuf::EnumDescriptor* ExtensionId_descriptor() { protobuf_AssignDescriptorsOnce(); @@ -350,6 +389,7 @@ bool Status_StatusCode_IsValid(int value) { case 1: case 2: case 3: + case 4: return true; default: return false; @@ -358,6 +398,7 @@ bool Status_StatusCode_IsValid(int value) { #ifndef _MSC_VER const Status_StatusCode Status::FAILED; +const Status_StatusCode Status::NO_IMPL_YET; const Status_StatusCode Status::INVALID_QUERY; const Status_StatusCode Status::SUCCESS; const Status_StatusCode Status::READMSG; @@ -414,7 +455,7 @@ const ::google::protobuf::Descriptor* Status::descriptor() { } const Status& Status::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_base_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_core_2eproto(); return *default_instance_; } Status* Status::default_instance_ = NULL; @@ -442,7 +483,7 @@ bool Status::MergePartialFromCodedStream( ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // required .rsctrl.base.Status.StatusCode code = 1; + // required .rsctrl.core.Status.StatusCode code = 1; case 1: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { @@ -450,8 +491,8 @@ bool Status::MergePartialFromCodedStream( DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( input, &value))); - if (::rsctrl::base::Status_StatusCode_IsValid(value)) { - set_code(static_cast< ::rsctrl::base::Status_StatusCode >(value)); + if (::rsctrl::core::Status_StatusCode_IsValid(value)) { + set_code(static_cast< ::rsctrl::core::Status_StatusCode >(value)); } else { mutable_unknown_fields()->AddVarint(1, value); } @@ -497,7 +538,7 @@ bool Status::MergePartialFromCodedStream( void Status::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - // required .rsctrl.base.Status.StatusCode code = 1; + // required .rsctrl.core.Status.StatusCode code = 1; if (has_code()) { ::google::protobuf::internal::WireFormatLite::WriteEnum( 1, this->code(), output); @@ -520,7 +561,7 @@ void Status::SerializeWithCachedSizes( ::google::protobuf::uint8* Status::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { - // required .rsctrl.base.Status.StatusCode code = 1; + // required .rsctrl.core.Status.StatusCode code = 1; if (has_code()) { target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( 1, this->code(), target); @@ -547,7 +588,7 @@ int Status::ByteSize() const { int total_size = 0; if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // required .rsctrl.base.Status.StatusCode code = 1; + // required .rsctrl.core.Status.StatusCode code = 1; if (has_code()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::EnumSize(this->code()); @@ -636,11 +677,300 @@ void Status::Swap(Status* other) { // =================================================================== +#ifndef _MSC_VER +const int IpAddr::kAddrFieldNumber; +const int IpAddr::kPortFieldNumber; +#endif // !_MSC_VER + +IpAddr::IpAddr() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void IpAddr::InitAsDefaultInstance() { +} + +IpAddr::IpAddr(const IpAddr& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void IpAddr::SharedCtor() { + _cached_size_ = 0; + addr_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + port_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +IpAddr::~IpAddr() { + SharedDtor(); +} + +void IpAddr::SharedDtor() { + if (addr_ != &::google::protobuf::internal::kEmptyString) { + delete addr_; + } + if (this != default_instance_) { + } +} + +void IpAddr::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* IpAddr::descriptor() { + protobuf_AssignDescriptorsOnce(); + return IpAddr_descriptor_; +} + +const IpAddr& IpAddr::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_core_2eproto(); return *default_instance_; +} + +IpAddr* IpAddr::default_instance_ = NULL; + +IpAddr* IpAddr::New() const { + return new IpAddr; +} + +void IpAddr::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_addr()) { + if (addr_ != &::google::protobuf::internal::kEmptyString) { + addr_->clear(); + } + } + port_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool IpAddr::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string addr = 1 [default = ""]; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_addr())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->addr().data(), this->addr().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_port; + break; + } + + // required uint32 port = 2 [default = 0]; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_port: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &port_))); + set_has_port(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void IpAddr::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string addr = 1 [default = ""]; + if (has_addr()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->addr().data(), this->addr().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->addr(), output); + } + + // required uint32 port = 2 [default = 0]; + if (has_port()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->port(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* IpAddr::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string addr = 1 [default = ""]; + if (has_addr()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->addr().data(), this->addr().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->addr(), target); + } + + // required uint32 port = 2 [default = 0]; + if (has_port()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->port(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int IpAddr::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string addr = 1 [default = ""]; + if (has_addr()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->addr()); + } + + // required uint32 port = 2 [default = 0]; + if (has_port()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->port()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void IpAddr::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const IpAddr* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void IpAddr::MergeFrom(const IpAddr& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_addr()) { + set_addr(from.addr()); + } + if (from.has_port()) { + set_port(from.port()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void IpAddr::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void IpAddr::CopyFrom(const IpAddr& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool IpAddr::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void IpAddr::Swap(IpAddr* other) { + if (other != this) { + std::swap(addr_, other->addr_); + std::swap(port_, other->port_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata IpAddr::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = IpAddr_descriptor_; + metadata.reflection = IpAddr_reflection_; + return metadata; +} + + +// =================================================================== + +const ::google::protobuf::EnumDescriptor* Location_StateFlags_descriptor() { + protobuf_AssignDescriptorsOnce(); + return Location_StateFlags_descriptor_; +} +bool Location_StateFlags_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 4: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const Location_StateFlags Location::ONLINE; +const Location_StateFlags Location::CONNECTED; +const Location_StateFlags Location::UNREACHABLE; +const Location_StateFlags Location::StateFlags_MIN; +const Location_StateFlags Location::StateFlags_MAX; +const int Location::StateFlags_ARRAYSIZE; +#endif // _MSC_VER #ifndef _MSC_VER const int Location::kSslIdFieldNumber; const int Location::kLocationFieldNumber; const int Location::kLocaladdrFieldNumber; const int Location::kExtaddrFieldNumber; +const int Location::kStateFieldNumber; #endif // !_MSC_VER Location::Location() @@ -649,6 +979,8 @@ Location::Location() } void Location::InitAsDefaultInstance() { + localaddr_ = const_cast< ::rsctrl::core::IpAddr*>(&::rsctrl::core::IpAddr::default_instance()); + extaddr_ = const_cast< ::rsctrl::core::IpAddr*>(&::rsctrl::core::IpAddr::default_instance()); } Location::Location(const Location& from) @@ -661,8 +993,9 @@ void Location::SharedCtor() { _cached_size_ = 0; ssl_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); location_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); - localaddr_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); - extaddr_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + localaddr_ = NULL; + extaddr_ = NULL; + state_ = 0u; ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -677,13 +1010,9 @@ void Location::SharedDtor() { if (location_ != &::google::protobuf::internal::kEmptyString) { delete location_; } - if (localaddr_ != &::google::protobuf::internal::kEmptyString) { - delete localaddr_; - } - if (extaddr_ != &::google::protobuf::internal::kEmptyString) { - delete extaddr_; - } if (this != default_instance_) { + delete localaddr_; + delete extaddr_; } } @@ -698,7 +1027,7 @@ const ::google::protobuf::Descriptor* Location::descriptor() { } const Location& Location::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_base_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_core_2eproto(); return *default_instance_; } Location* Location::default_instance_ = NULL; @@ -720,15 +1049,12 @@ void Location::Clear() { } } if (has_localaddr()) { - if (localaddr_ != &::google::protobuf::internal::kEmptyString) { - localaddr_->clear(); - } + if (localaddr_ != NULL) localaddr_->::rsctrl::core::IpAddr::Clear(); } if (has_extaddr()) { - if (extaddr_ != &::google::protobuf::internal::kEmptyString) { - extaddr_->clear(); - } + if (extaddr_ != NULL) extaddr_->::rsctrl::core::IpAddr::Clear(); } + state_ = 0u; } ::memset(_has_bits_, 0, sizeof(_has_bits_)); mutable_unknown_fields()->Clear(); @@ -773,16 +1099,13 @@ bool Location::MergePartialFromCodedStream( break; } - // required string localaddr = 3; + // required .rsctrl.core.IpAddr localaddr = 3; case 3: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { parse_localaddr: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_localaddr())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->localaddr().data(), this->localaddr().length(), - ::google::protobuf::internal::WireFormat::PARSE); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_localaddr())); } else { goto handle_uninterpreted; } @@ -790,16 +1113,29 @@ bool Location::MergePartialFromCodedStream( break; } - // required string extaddr = 4; + // required .rsctrl.core.IpAddr extaddr = 4; case 4: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { parse_extaddr: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_extaddr())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->extaddr().data(), this->extaddr().length(), - ::google::protobuf::internal::WireFormat::PARSE); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_extaddr())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(40)) goto parse_state; + break; + } + + // required uint32 state = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_state: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &state_))); + set_has_state(); } else { goto handle_uninterpreted; } @@ -843,24 +1179,23 @@ void Location::SerializeWithCachedSizes( 2, this->location(), output); } - // required string localaddr = 3; + // required .rsctrl.core.IpAddr localaddr = 3; if (has_localaddr()) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->localaddr().data(), this->localaddr().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 3, this->localaddr(), output); } - // required string extaddr = 4; + // required .rsctrl.core.IpAddr extaddr = 4; if (has_extaddr()) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->extaddr().data(), this->extaddr().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 4, this->extaddr(), output); } + // required uint32 state = 5; + if (has_state()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(5, this->state(), output); + } + if (!unknown_fields().empty()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( unknown_fields(), output); @@ -889,26 +1224,25 @@ void Location::SerializeWithCachedSizes( 2, this->location(), target); } - // required string localaddr = 3; + // required .rsctrl.core.IpAddr localaddr = 3; if (has_localaddr()) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->localaddr().data(), this->localaddr().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( 3, this->localaddr(), target); } - // required string extaddr = 4; + // required .rsctrl.core.IpAddr extaddr = 4; if (has_extaddr()) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->extaddr().data(), this->extaddr().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( 4, this->extaddr(), target); } + // required uint32 state = 5; + if (has_state()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(5, this->state(), target); + } + if (!unknown_fields().empty()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( unknown_fields(), target); @@ -934,20 +1268,27 @@ int Location::ByteSize() const { this->location()); } - // required string localaddr = 3; + // required .rsctrl.core.IpAddr localaddr = 3; if (has_localaddr()) { total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->localaddr()); } - // required string extaddr = 4; + // required .rsctrl.core.IpAddr extaddr = 4; if (has_extaddr()) { total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->extaddr()); } + // required uint32 state = 5; + if (has_state()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->state()); + } + } if (!unknown_fields().empty()) { total_size += @@ -982,10 +1323,13 @@ void Location::MergeFrom(const Location& from) { set_location(from.location()); } if (from.has_localaddr()) { - set_localaddr(from.localaddr()); + mutable_localaddr()->::rsctrl::core::IpAddr::MergeFrom(from.localaddr()); } if (from.has_extaddr()) { - set_extaddr(from.extaddr()); + mutable_extaddr()->::rsctrl::core::IpAddr::MergeFrom(from.extaddr()); + } + if (from.has_state()) { + set_state(from.state()); } } mutable_unknown_fields()->MergeFrom(from.unknown_fields()); @@ -1004,8 +1348,14 @@ void Location::CopyFrom(const Location& from) { } bool Location::IsInitialized() const { - if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false; + if ((_has_bits_[0] & 0x0000001f) != 0x0000001f) return false; + if (has_localaddr()) { + if (!this->localaddr().IsInitialized()) return false; + } + if (has_extaddr()) { + if (!this->extaddr().IsInitialized()) return false; + } return true; } @@ -1015,6 +1365,7 @@ void Location::Swap(Location* other) { std::swap(location_, other->location_); std::swap(localaddr_, other->localaddr_); std::swap(extaddr_, other->extaddr_); + std::swap(state_, other->state_); std::swap(_has_bits_[0], other->_has_bits_[0]); _unknown_fields_.Swap(&other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); @@ -1032,9 +1383,35 @@ void Location::Swap(Location* other) { // =================================================================== +const ::google::protobuf::EnumDescriptor* Person_Relationship_descriptor() { + protobuf_AssignDescriptorsOnce(); + return Person_Relationship_descriptor_; +} +bool Person_Relationship_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 3: + case 4: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const Person_Relationship Person::FRIEND; +const Person_Relationship Person::FRIEND_OF_MANY_FRIENDS; +const Person_Relationship Person::FRIEND_OF_FRIENDS; +const Person_Relationship Person::UNKNOWN; +const Person_Relationship Person::Relationship_MIN; +const Person_Relationship Person::Relationship_MAX; +const int Person::Relationship_ARRAYSIZE; +#endif // _MSC_VER #ifndef _MSC_VER const int Person::kGpgIdFieldNumber; const int Person::kNameFieldNumber; +const int Person::kRelationFieldNumber; const int Person::kLocationsFieldNumber; #endif // !_MSC_VER @@ -1056,6 +1433,7 @@ void Person::SharedCtor() { _cached_size_ = 0; gpg_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + relation_ = 1; ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -1085,7 +1463,7 @@ const ::google::protobuf::Descriptor* Person::descriptor() { } const Person& Person::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_base_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_core_2eproto(); return *default_instance_; } Person* Person::default_instance_ = NULL; @@ -1106,6 +1484,7 @@ void Person::Clear() { name_->clear(); } } + relation_ = 1; } locations_.Clear(); ::memset(_has_bits_, 0, sizeof(_has_bits_)); @@ -1147,12 +1526,33 @@ bool Person::MergePartialFromCodedStream( } else { goto handle_uninterpreted; } - if (input->ExpectTag(26)) goto parse_locations; + if (input->ExpectTag(24)) goto parse_relation; break; } - // repeated .rsctrl.base.Location locations = 3; + // required .rsctrl.core.Person.Relationship relation = 3; case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_relation: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::rsctrl::core::Person_Relationship_IsValid(value)) { + set_relation(static_cast< ::rsctrl::core::Person_Relationship >(value)); + } else { + mutable_unknown_fields()->AddVarint(3, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_locations; + break; + } + + // repeated .rsctrl.core.Location locations = 4; + case 4: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { parse_locations: @@ -1161,7 +1561,7 @@ bool Person::MergePartialFromCodedStream( } else { goto handle_uninterpreted; } - if (input->ExpectTag(26)) goto parse_locations; + if (input->ExpectTag(34)) goto parse_locations; if (input->ExpectAtEnd()) return true; break; } @@ -1202,10 +1602,16 @@ void Person::SerializeWithCachedSizes( 2, this->name(), output); } - // repeated .rsctrl.base.Location locations = 3; + // required .rsctrl.core.Person.Relationship relation = 3; + if (has_relation()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 3, this->relation(), output); + } + + // repeated .rsctrl.core.Location locations = 4; for (int i = 0; i < this->locations_size(); i++) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 3, this->locations(i), output); + 4, this->locations(i), output); } if (!unknown_fields().empty()) { @@ -1236,11 +1642,17 @@ void Person::SerializeWithCachedSizes( 2, this->name(), target); } - // repeated .rsctrl.base.Location locations = 3; + // required .rsctrl.core.Person.Relationship relation = 3; + if (has_relation()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 3, this->relation(), target); + } + + // repeated .rsctrl.core.Location locations = 4; for (int i = 0; i < this->locations_size(); i++) { target = ::google::protobuf::internal::WireFormatLite:: WriteMessageNoVirtualToArray( - 3, this->locations(i), target); + 4, this->locations(i), target); } if (!unknown_fields().empty()) { @@ -1268,8 +1680,14 @@ int Person::ByteSize() const { this->name()); } + // required .rsctrl.core.Person.Relationship relation = 3; + if (has_relation()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->relation()); + } + } - // repeated .rsctrl.base.Location locations = 3; + // repeated .rsctrl.core.Location locations = 4; total_size += 1 * this->locations_size(); for (int i = 0; i < this->locations_size(); i++) { total_size += @@ -1310,6 +1728,9 @@ void Person::MergeFrom(const Person& from) { if (from.has_name()) { set_name(from.name()); } + if (from.has_relation()) { + set_relation(from.relation()); + } } mutable_unknown_fields()->MergeFrom(from.unknown_fields()); } @@ -1327,7 +1748,7 @@ void Person::CopyFrom(const Person& from) { } bool Person::IsInitialized() const { - if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; for (int i = 0; i < locations_size(); i++) { if (!this->locations(i).IsInitialized()) return false; @@ -1339,6 +1760,7 @@ void Person::Swap(Person* other) { if (other != this) { std::swap(gpg_id_, other->gpg_id_); std::swap(name_, other->name_); + std::swap(relation_, other->relation_); locations_.Swap(&other->locations_); std::swap(_has_bits_[0], other->_has_bits_[0]); _unknown_fields_.Swap(&other->_unknown_fields_); @@ -1421,7 +1843,7 @@ const ::google::protobuf::Descriptor* File::descriptor() { } const File& File::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_base_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_core_2eproto(); return *default_instance_; } File* File::default_instance_ = NULL; @@ -1847,7 +2269,7 @@ const ::google::protobuf::Descriptor* Dir::descriptor() { } const Dir& Dir::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_base_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_core_2eproto(); return *default_instance_; } Dir* Dir::default_instance_ = NULL; @@ -1914,7 +2336,7 @@ bool Dir::MergePartialFromCodedStream( break; } - // repeated .rsctrl.base.Dir subdirs = 3; + // repeated .rsctrl.core.Dir subdirs = 3; case 3: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { @@ -1929,7 +2351,7 @@ bool Dir::MergePartialFromCodedStream( break; } - // repeated .rsctrl.base.File files = 4; + // repeated .rsctrl.core.File files = 4; case 4: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { @@ -1980,13 +2402,13 @@ void Dir::SerializeWithCachedSizes( 2, this->path(), output); } - // repeated .rsctrl.base.Dir subdirs = 3; + // repeated .rsctrl.core.Dir subdirs = 3; for (int i = 0; i < this->subdirs_size(); i++) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 3, this->subdirs(i), output); } - // repeated .rsctrl.base.File files = 4; + // repeated .rsctrl.core.File files = 4; for (int i = 0; i < this->files_size(); i++) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 4, this->files(i), output); @@ -2020,14 +2442,14 @@ void Dir::SerializeWithCachedSizes( 2, this->path(), target); } - // repeated .rsctrl.base.Dir subdirs = 3; + // repeated .rsctrl.core.Dir subdirs = 3; for (int i = 0; i < this->subdirs_size(); i++) { target = ::google::protobuf::internal::WireFormatLite:: WriteMessageNoVirtualToArray( 3, this->subdirs(i), target); } - // repeated .rsctrl.base.File files = 4; + // repeated .rsctrl.core.File files = 4; for (int i = 0; i < this->files_size(); i++) { target = ::google::protobuf::internal::WireFormatLite:: WriteMessageNoVirtualToArray( @@ -2060,7 +2482,7 @@ int Dir::ByteSize() const { } } - // repeated .rsctrl.base.Dir subdirs = 3; + // repeated .rsctrl.core.Dir subdirs = 3; total_size += 1 * this->subdirs_size(); for (int i = 0; i < this->subdirs_size(); i++) { total_size += @@ -2068,7 +2490,7 @@ int Dir::ByteSize() const { this->subdirs(i)); } - // repeated .rsctrl.base.File files = 4; + // repeated .rsctrl.core.File files = 4; total_size += 1 * this->files_size(); for (int i = 0; i < this->files_size(); i++) { total_size += @@ -2245,7 +2667,7 @@ const ::google::protobuf::Descriptor* SystemStatus::descriptor() { } const SystemStatus& SystemStatus::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_base_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_core_2eproto(); return *default_instance_; } SystemStatus* SystemStatus::default_instance_ = NULL; @@ -2273,7 +2695,7 @@ bool SystemStatus::MergePartialFromCodedStream( ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // required .rsctrl.base.SystemStatus.NetCode net_status = 1; + // required .rsctrl.core.SystemStatus.NetCode net_status = 1; case 1: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { @@ -2281,8 +2703,8 @@ bool SystemStatus::MergePartialFromCodedStream( DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( input, &value))); - if (::rsctrl::base::SystemStatus_NetCode_IsValid(value)) { - set_net_status(static_cast< ::rsctrl::base::SystemStatus_NetCode >(value)); + if (::rsctrl::core::SystemStatus_NetCode_IsValid(value)) { + set_net_status(static_cast< ::rsctrl::core::SystemStatus_NetCode >(value)); } else { mutable_unknown_fields()->AddVarint(1, value); } @@ -2328,7 +2750,7 @@ bool SystemStatus::MergePartialFromCodedStream( void SystemStatus::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - // required .rsctrl.base.SystemStatus.NetCode net_status = 1; + // required .rsctrl.core.SystemStatus.NetCode net_status = 1; if (has_net_status()) { ::google::protobuf::internal::WireFormatLite::WriteEnum( 1, this->net_status(), output); @@ -2351,7 +2773,7 @@ void SystemStatus::SerializeWithCachedSizes( ::google::protobuf::uint8* SystemStatus::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { - // required .rsctrl.base.SystemStatus.NetCode net_status = 1; + // required .rsctrl.core.SystemStatus.NetCode net_status = 1; if (has_net_status()) { target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( 1, this->net_status(), target); @@ -2378,7 +2800,7 @@ int SystemStatus::ByteSize() const { int total_size = 0; if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // required .rsctrl.base.SystemStatus.NetCode net_status = 1; + // required .rsctrl.core.SystemStatus.NetCode net_status = 1; if (has_net_status()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::EnumSize(this->net_status()); @@ -2518,7 +2940,7 @@ const ::google::protobuf::Descriptor* Bandwidth::descriptor() { } const Bandwidth& Bandwidth::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_base_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_core_2eproto(); return *default_instance_; } Bandwidth* Bandwidth::default_instance_ = NULL; @@ -2811,7 +3233,7 @@ const ::google::protobuf::Descriptor* BandwidthSet::descriptor() { } const BandwidthSet& BandwidthSet::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_base_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_core_2eproto(); return *default_instance_; } BandwidthSet* BandwidthSet::default_instance_ = NULL; @@ -2832,7 +3254,7 @@ bool BandwidthSet::MergePartialFromCodedStream( ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // repeated .rsctrl.base.Bandwidth bandwidths = 1; + // repeated .rsctrl.core.Bandwidth bandwidths = 1; case 1: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { @@ -2865,7 +3287,7 @@ bool BandwidthSet::MergePartialFromCodedStream( void BandwidthSet::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - // repeated .rsctrl.base.Bandwidth bandwidths = 1; + // repeated .rsctrl.core.Bandwidth bandwidths = 1; for (int i = 0; i < this->bandwidths_size(); i++) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 1, this->bandwidths(i), output); @@ -2879,7 +3301,7 @@ void BandwidthSet::SerializeWithCachedSizes( ::google::protobuf::uint8* BandwidthSet::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { - // repeated .rsctrl.base.Bandwidth bandwidths = 1; + // repeated .rsctrl.core.Bandwidth bandwidths = 1; for (int i = 0; i < this->bandwidths_size(); i++) { target = ::google::protobuf::internal::WireFormatLite:: WriteMessageNoVirtualToArray( @@ -2896,7 +3318,7 @@ void BandwidthSet::SerializeWithCachedSizes( int BandwidthSet::ByteSize() const { int total_size = 0; - // repeated .rsctrl.base.Bandwidth bandwidths = 1; + // repeated .rsctrl.core.Bandwidth bandwidths = 1; total_size += 1 * this->bandwidths_size(); for (int i = 0; i < this->bandwidths_size(); i++) { total_size += @@ -2973,7 +3395,7 @@ void BandwidthSet::Swap(BandwidthSet* other) { // @@protoc_insertion_point(namespace_scope) -} // namespace base +} // namespace core } // namespace rsctrl // @@protoc_insertion_point(global_scope) diff --git a/retroshare-nogui/src/rpc/proto/gencc/base.pb.h b/retroshare-nogui/src/rpc/proto/gencc/core.pb.h similarity index 74% rename from retroshare-nogui/src/rpc/proto/gencc/base.pb.h rename to retroshare-nogui/src/rpc/proto/gencc/core.pb.h index 35dfa7841..ef2ab4074 100644 --- a/retroshare-nogui/src/rpc/proto/gencc/base.pb.h +++ b/retroshare-nogui/src/rpc/proto/gencc/core.pb.h @@ -1,8 +1,8 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: base.proto +// source: core.proto -#ifndef PROTOBUF_base_2eproto__INCLUDED -#define PROTOBUF_base_2eproto__INCLUDED +#ifndef PROTOBUF_core_2eproto__INCLUDED +#define PROTOBUF_core_2eproto__INCLUDED #include @@ -26,14 +26,15 @@ // @@protoc_insertion_point(includes) namespace rsctrl { -namespace base { +namespace core { // Internal implementation detail -- do not call these. -void protobuf_AddDesc_base_2eproto(); -void protobuf_AssignDesc_base_2eproto(); -void protobuf_ShutdownFile_base_2eproto(); +void protobuf_AddDesc_core_2eproto(); +void protobuf_AssignDesc_core_2eproto(); +void protobuf_ShutdownFile_core_2eproto(); class Status; +class IpAddr; class Location; class Person; class File; @@ -44,9 +45,10 @@ class BandwidthSet; enum Status_StatusCode { Status_StatusCode_FAILED = 0, - Status_StatusCode_INVALID_QUERY = 1, - Status_StatusCode_SUCCESS = 2, - Status_StatusCode_READMSG = 3 + Status_StatusCode_NO_IMPL_YET = 1, + Status_StatusCode_INVALID_QUERY = 2, + Status_StatusCode_SUCCESS = 3, + Status_StatusCode_READMSG = 4 }; bool Status_StatusCode_IsValid(int value); const Status_StatusCode Status_StatusCode_StatusCode_MIN = Status_StatusCode_FAILED; @@ -63,6 +65,47 @@ inline bool Status_StatusCode_Parse( return ::google::protobuf::internal::ParseNamedEnum( Status_StatusCode_descriptor(), name, value); } +enum Location_StateFlags { + Location_StateFlags_ONLINE = 1, + Location_StateFlags_CONNECTED = 2, + Location_StateFlags_UNREACHABLE = 4 +}; +bool Location_StateFlags_IsValid(int value); +const Location_StateFlags Location_StateFlags_StateFlags_MIN = Location_StateFlags_ONLINE; +const Location_StateFlags Location_StateFlags_StateFlags_MAX = Location_StateFlags_UNREACHABLE; +const int Location_StateFlags_StateFlags_ARRAYSIZE = Location_StateFlags_StateFlags_MAX + 1; + +const ::google::protobuf::EnumDescriptor* Location_StateFlags_descriptor(); +inline const ::std::string& Location_StateFlags_Name(Location_StateFlags value) { + return ::google::protobuf::internal::NameOfEnum( + Location_StateFlags_descriptor(), value); +} +inline bool Location_StateFlags_Parse( + const ::std::string& name, Location_StateFlags* value) { + return ::google::protobuf::internal::ParseNamedEnum( + Location_StateFlags_descriptor(), name, value); +} +enum Person_Relationship { + Person_Relationship_FRIEND = 1, + Person_Relationship_FRIEND_OF_MANY_FRIENDS = 2, + Person_Relationship_FRIEND_OF_FRIENDS = 3, + Person_Relationship_UNKNOWN = 4 +}; +bool Person_Relationship_IsValid(int value); +const Person_Relationship Person_Relationship_Relationship_MIN = Person_Relationship_FRIEND; +const Person_Relationship Person_Relationship_Relationship_MAX = Person_Relationship_UNKNOWN; +const int Person_Relationship_Relationship_ARRAYSIZE = Person_Relationship_Relationship_MAX + 1; + +const ::google::protobuf::EnumDescriptor* Person_Relationship_descriptor(); +inline const ::std::string& Person_Relationship_Name(Person_Relationship value) { + return ::google::protobuf::internal::NameOfEnum( + Person_Relationship_descriptor(), value); +} +inline bool Person_Relationship_Parse( + const ::std::string& name, Person_Relationship* value) { + return ::google::protobuf::internal::ParseNamedEnum( + Person_Relationship_descriptor(), name, value); +} enum SystemStatus_NetCode { SystemStatus_NetCode_BAD_UNKNOWN = 0, SystemStatus_NetCode_BAD_OFFLINE = 1, @@ -90,11 +133,11 @@ inline bool SystemStatus_NetCode_Parse( SystemStatus_NetCode_descriptor(), name, value); } enum ExtensionId { - BASE = 0 + CORE = 0 }; bool ExtensionId_IsValid(int value); -const ExtensionId ExtensionId_MIN = BASE; -const ExtensionId ExtensionId_MAX = BASE; +const ExtensionId ExtensionId_MIN = CORE; +const ExtensionId ExtensionId_MAX = CORE; const int ExtensionId_ARRAYSIZE = ExtensionId_MAX + 1; const ::google::protobuf::EnumDescriptor* ExtensionId_descriptor(); @@ -185,6 +228,7 @@ class Status : public ::google::protobuf::Message { typedef Status_StatusCode StatusCode; static const StatusCode FAILED = Status_StatusCode_FAILED; + static const StatusCode NO_IMPL_YET = Status_StatusCode_NO_IMPL_YET; static const StatusCode INVALID_QUERY = Status_StatusCode_INVALID_QUERY; static const StatusCode SUCCESS = Status_StatusCode_SUCCESS; static const StatusCode READMSG = Status_StatusCode_READMSG; @@ -211,12 +255,12 @@ class Status : public ::google::protobuf::Message { // accessors ------------------------------------------------------- - // required .rsctrl.base.Status.StatusCode code = 1; + // required .rsctrl.core.Status.StatusCode code = 1; inline bool has_code() const; inline void clear_code(); static const int kCodeFieldNumber = 1; - inline ::rsctrl::base::Status_StatusCode code() const; - inline void set_code(::rsctrl::base::Status_StatusCode value); + inline ::rsctrl::core::Status_StatusCode code() const; + inline void set_code(::rsctrl::core::Status_StatusCode value); // optional string msg = 2; inline bool has_msg() const; @@ -229,7 +273,7 @@ class Status : public ::google::protobuf::Message { inline ::std::string* mutable_msg(); inline ::std::string* release_msg(); - // @@protoc_insertion_point(class_scope:rsctrl.base.Status) + // @@protoc_insertion_point(class_scope:rsctrl.core.Status) private: inline void set_has_code(); inline void clear_has_code(); @@ -244,15 +288,111 @@ class Status : public ::google::protobuf::Message { mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; - friend void protobuf_AddDesc_base_2eproto(); - friend void protobuf_AssignDesc_base_2eproto(); - friend void protobuf_ShutdownFile_base_2eproto(); + friend void protobuf_AddDesc_core_2eproto(); + friend void protobuf_AssignDesc_core_2eproto(); + friend void protobuf_ShutdownFile_core_2eproto(); void InitAsDefaultInstance(); static Status* default_instance_; }; // ------------------------------------------------------------------- +class IpAddr : public ::google::protobuf::Message { + public: + IpAddr(); + virtual ~IpAddr(); + + IpAddr(const IpAddr& from); + + inline IpAddr& operator=(const IpAddr& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const IpAddr& default_instance(); + + void Swap(IpAddr* other); + + // implements Message ---------------------------------------------- + + IpAddr* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const IpAddr& from); + void MergeFrom(const IpAddr& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string addr = 1 [default = ""]; + inline bool has_addr() const; + inline void clear_addr(); + static const int kAddrFieldNumber = 1; + inline const ::std::string& addr() const; + inline void set_addr(const ::std::string& value); + inline void set_addr(const char* value); + inline void set_addr(const char* value, size_t size); + inline ::std::string* mutable_addr(); + inline ::std::string* release_addr(); + + // required uint32 port = 2 [default = 0]; + inline bool has_port() const; + inline void clear_port(); + static const int kPortFieldNumber = 2; + inline ::google::protobuf::uint32 port() const; + inline void set_port(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:rsctrl.core.IpAddr) + private: + inline void set_has_addr(); + inline void clear_has_addr(); + inline void set_has_port(); + inline void clear_has_port(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* addr_; + ::google::protobuf::uint32 port_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_core_2eproto(); + friend void protobuf_AssignDesc_core_2eproto(); + friend void protobuf_ShutdownFile_core_2eproto(); + + void InitAsDefaultInstance(); + static IpAddr* default_instance_; +}; +// ------------------------------------------------------------------- + class Location : public ::google::protobuf::Message { public: Location(); @@ -305,6 +445,31 @@ class Location : public ::google::protobuf::Message { // nested types ---------------------------------------------------- + typedef Location_StateFlags StateFlags; + static const StateFlags ONLINE = Location_StateFlags_ONLINE; + static const StateFlags CONNECTED = Location_StateFlags_CONNECTED; + static const StateFlags UNREACHABLE = Location_StateFlags_UNREACHABLE; + static inline bool StateFlags_IsValid(int value) { + return Location_StateFlags_IsValid(value); + } + static const StateFlags StateFlags_MIN = + Location_StateFlags_StateFlags_MIN; + static const StateFlags StateFlags_MAX = + Location_StateFlags_StateFlags_MAX; + static const int StateFlags_ARRAYSIZE = + Location_StateFlags_StateFlags_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + StateFlags_descriptor() { + return Location_StateFlags_descriptor(); + } + static inline const ::std::string& StateFlags_Name(StateFlags value) { + return Location_StateFlags_Name(value); + } + static inline bool StateFlags_Parse(const ::std::string& name, + StateFlags* value) { + return Location_StateFlags_Parse(name, value); + } + // accessors ------------------------------------------------------- // required string ssl_id = 1; @@ -329,29 +494,30 @@ class Location : public ::google::protobuf::Message { inline ::std::string* mutable_location(); inline ::std::string* release_location(); - // required string localaddr = 3; + // required .rsctrl.core.IpAddr localaddr = 3; inline bool has_localaddr() const; inline void clear_localaddr(); static const int kLocaladdrFieldNumber = 3; - inline const ::std::string& localaddr() const; - inline void set_localaddr(const ::std::string& value); - inline void set_localaddr(const char* value); - inline void set_localaddr(const char* value, size_t size); - inline ::std::string* mutable_localaddr(); - inline ::std::string* release_localaddr(); + inline const ::rsctrl::core::IpAddr& localaddr() const; + inline ::rsctrl::core::IpAddr* mutable_localaddr(); + inline ::rsctrl::core::IpAddr* release_localaddr(); - // required string extaddr = 4; + // required .rsctrl.core.IpAddr extaddr = 4; inline bool has_extaddr() const; inline void clear_extaddr(); static const int kExtaddrFieldNumber = 4; - inline const ::std::string& extaddr() const; - inline void set_extaddr(const ::std::string& value); - inline void set_extaddr(const char* value); - inline void set_extaddr(const char* value, size_t size); - inline ::std::string* mutable_extaddr(); - inline ::std::string* release_extaddr(); + inline const ::rsctrl::core::IpAddr& extaddr() const; + inline ::rsctrl::core::IpAddr* mutable_extaddr(); + inline ::rsctrl::core::IpAddr* release_extaddr(); - // @@protoc_insertion_point(class_scope:rsctrl.base.Location) + // required uint32 state = 5; + inline bool has_state() const; + inline void clear_state(); + static const int kStateFieldNumber = 5; + inline ::google::protobuf::uint32 state() const; + inline void set_state(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:rsctrl.core.Location) private: inline void set_has_ssl_id(); inline void clear_has_ssl_id(); @@ -361,20 +527,23 @@ class Location : public ::google::protobuf::Message { inline void clear_has_localaddr(); inline void set_has_extaddr(); inline void clear_has_extaddr(); + inline void set_has_state(); + inline void clear_has_state(); ::google::protobuf::UnknownFieldSet _unknown_fields_; ::std::string* ssl_id_; ::std::string* location_; - ::std::string* localaddr_; - ::std::string* extaddr_; + ::rsctrl::core::IpAddr* localaddr_; + ::rsctrl::core::IpAddr* extaddr_; + ::google::protobuf::uint32 state_; mutable int _cached_size_; - ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + ::google::protobuf::uint32 _has_bits_[(5 + 31) / 32]; - friend void protobuf_AddDesc_base_2eproto(); - friend void protobuf_AssignDesc_base_2eproto(); - friend void protobuf_ShutdownFile_base_2eproto(); + friend void protobuf_AddDesc_core_2eproto(); + friend void protobuf_AssignDesc_core_2eproto(); + friend void protobuf_ShutdownFile_core_2eproto(); void InitAsDefaultInstance(); static Location* default_instance_; @@ -433,6 +602,32 @@ class Person : public ::google::protobuf::Message { // nested types ---------------------------------------------------- + typedef Person_Relationship Relationship; + static const Relationship FRIEND = Person_Relationship_FRIEND; + static const Relationship FRIEND_OF_MANY_FRIENDS = Person_Relationship_FRIEND_OF_MANY_FRIENDS; + static const Relationship FRIEND_OF_FRIENDS = Person_Relationship_FRIEND_OF_FRIENDS; + static const Relationship UNKNOWN = Person_Relationship_UNKNOWN; + static inline bool Relationship_IsValid(int value) { + return Person_Relationship_IsValid(value); + } + static const Relationship Relationship_MIN = + Person_Relationship_Relationship_MIN; + static const Relationship Relationship_MAX = + Person_Relationship_Relationship_MAX; + static const int Relationship_ARRAYSIZE = + Person_Relationship_Relationship_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + Relationship_descriptor() { + return Person_Relationship_descriptor(); + } + static inline const ::std::string& Relationship_Name(Relationship value) { + return Person_Relationship_Name(value); + } + static inline bool Relationship_Parse(const ::std::string& name, + Relationship* value) { + return Person_Relationship_Parse(name, value); + } + // accessors ------------------------------------------------------- // required string gpg_id = 1; @@ -457,37 +652,47 @@ class Person : public ::google::protobuf::Message { inline ::std::string* mutable_name(); inline ::std::string* release_name(); - // repeated .rsctrl.base.Location locations = 3; + // required .rsctrl.core.Person.Relationship relation = 3; + inline bool has_relation() const; + inline void clear_relation(); + static const int kRelationFieldNumber = 3; + inline ::rsctrl::core::Person_Relationship relation() const; + inline void set_relation(::rsctrl::core::Person_Relationship value); + + // repeated .rsctrl.core.Location locations = 4; inline int locations_size() const; inline void clear_locations(); - static const int kLocationsFieldNumber = 3; - inline const ::rsctrl::base::Location& locations(int index) const; - inline ::rsctrl::base::Location* mutable_locations(int index); - inline ::rsctrl::base::Location* add_locations(); - inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Location >& + static const int kLocationsFieldNumber = 4; + inline const ::rsctrl::core::Location& locations(int index) const; + inline ::rsctrl::core::Location* mutable_locations(int index); + inline ::rsctrl::core::Location* add_locations(); + inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Location >& locations() const; - inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Location >* + inline ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Location >* mutable_locations(); - // @@protoc_insertion_point(class_scope:rsctrl.base.Person) + // @@protoc_insertion_point(class_scope:rsctrl.core.Person) private: inline void set_has_gpg_id(); inline void clear_has_gpg_id(); inline void set_has_name(); inline void clear_has_name(); + inline void set_has_relation(); + inline void clear_has_relation(); ::google::protobuf::UnknownFieldSet _unknown_fields_; ::std::string* gpg_id_; ::std::string* name_; - ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Location > locations_; + ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Location > locations_; + int relation_; mutable int _cached_size_; - ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; - friend void protobuf_AddDesc_base_2eproto(); - friend void protobuf_AssignDesc_base_2eproto(); - friend void protobuf_ShutdownFile_base_2eproto(); + friend void protobuf_AddDesc_core_2eproto(); + friend void protobuf_AssignDesc_core_2eproto(); + friend void protobuf_ShutdownFile_core_2eproto(); void InitAsDefaultInstance(); static Person* default_instance_; @@ -599,7 +804,7 @@ class File : public ::google::protobuf::Message { inline ::std::string* mutable_avail(); inline ::std::string* release_avail(); - // @@protoc_insertion_point(class_scope:rsctrl.base.File) + // @@protoc_insertion_point(class_scope:rsctrl.core.File) private: inline void set_has_name(); inline void clear_has_name(); @@ -623,9 +828,9 @@ class File : public ::google::protobuf::Message { mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(5 + 31) / 32]; - friend void protobuf_AddDesc_base_2eproto(); - friend void protobuf_AssignDesc_base_2eproto(); - friend void protobuf_ShutdownFile_base_2eproto(); + friend void protobuf_AddDesc_core_2eproto(); + friend void protobuf_AssignDesc_core_2eproto(); + friend void protobuf_ShutdownFile_core_2eproto(); void InitAsDefaultInstance(); static File* default_instance_; @@ -708,31 +913,31 @@ class Dir : public ::google::protobuf::Message { inline ::std::string* mutable_path(); inline ::std::string* release_path(); - // repeated .rsctrl.base.Dir subdirs = 3; + // repeated .rsctrl.core.Dir subdirs = 3; inline int subdirs_size() const; inline void clear_subdirs(); static const int kSubdirsFieldNumber = 3; - inline const ::rsctrl::base::Dir& subdirs(int index) const; - inline ::rsctrl::base::Dir* mutable_subdirs(int index); - inline ::rsctrl::base::Dir* add_subdirs(); - inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Dir >& + inline const ::rsctrl::core::Dir& subdirs(int index) const; + inline ::rsctrl::core::Dir* mutable_subdirs(int index); + inline ::rsctrl::core::Dir* add_subdirs(); + inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Dir >& subdirs() const; - inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Dir >* + inline ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Dir >* mutable_subdirs(); - // repeated .rsctrl.base.File files = 4; + // repeated .rsctrl.core.File files = 4; inline int files_size() const; inline void clear_files(); static const int kFilesFieldNumber = 4; - inline const ::rsctrl::base::File& files(int index) const; - inline ::rsctrl::base::File* mutable_files(int index); - inline ::rsctrl::base::File* add_files(); - inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::File >& + inline const ::rsctrl::core::File& files(int index) const; + inline ::rsctrl::core::File* mutable_files(int index); + inline ::rsctrl::core::File* add_files(); + inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::core::File >& files() const; - inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::File >* + inline ::google::protobuf::RepeatedPtrField< ::rsctrl::core::File >* mutable_files(); - // @@protoc_insertion_point(class_scope:rsctrl.base.Dir) + // @@protoc_insertion_point(class_scope:rsctrl.core.Dir) private: inline void set_has_name(); inline void clear_has_name(); @@ -743,15 +948,15 @@ class Dir : public ::google::protobuf::Message { ::std::string* name_; ::std::string* path_; - ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Dir > subdirs_; - ::google::protobuf::RepeatedPtrField< ::rsctrl::base::File > files_; + ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Dir > subdirs_; + ::google::protobuf::RepeatedPtrField< ::rsctrl::core::File > files_; mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; - friend void protobuf_AddDesc_base_2eproto(); - friend void protobuf_AssignDesc_base_2eproto(); - friend void protobuf_ShutdownFile_base_2eproto(); + friend void protobuf_AddDesc_core_2eproto(); + friend void protobuf_AssignDesc_core_2eproto(); + friend void protobuf_ShutdownFile_core_2eproto(); void InitAsDefaultInstance(); static Dir* default_instance_; @@ -843,12 +1048,12 @@ class SystemStatus : public ::google::protobuf::Message { // accessors ------------------------------------------------------- - // required .rsctrl.base.SystemStatus.NetCode net_status = 1; + // required .rsctrl.core.SystemStatus.NetCode net_status = 1; inline bool has_net_status() const; inline void clear_net_status(); static const int kNetStatusFieldNumber = 1; - inline ::rsctrl::base::SystemStatus_NetCode net_status() const; - inline void set_net_status(::rsctrl::base::SystemStatus_NetCode value); + inline ::rsctrl::core::SystemStatus_NetCode net_status() const; + inline void set_net_status(::rsctrl::core::SystemStatus_NetCode value); // optional string msg = 2; inline bool has_msg() const; @@ -861,7 +1066,7 @@ class SystemStatus : public ::google::protobuf::Message { inline ::std::string* mutable_msg(); inline ::std::string* release_msg(); - // @@protoc_insertion_point(class_scope:rsctrl.base.SystemStatus) + // @@protoc_insertion_point(class_scope:rsctrl.core.SystemStatus) private: inline void set_has_net_status(); inline void clear_has_net_status(); @@ -876,9 +1081,9 @@ class SystemStatus : public ::google::protobuf::Message { mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; - friend void protobuf_AddDesc_base_2eproto(); - friend void protobuf_AssignDesc_base_2eproto(); - friend void protobuf_ShutdownFile_base_2eproto(); + friend void protobuf_AddDesc_core_2eproto(); + friend void protobuf_AssignDesc_core_2eproto(); + friend void protobuf_ShutdownFile_core_2eproto(); void InitAsDefaultInstance(); static SystemStatus* default_instance_; @@ -964,7 +1169,7 @@ class Bandwidth : public ::google::protobuf::Message { inline ::std::string* mutable_name(); inline ::std::string* release_name(); - // @@protoc_insertion_point(class_scope:rsctrl.base.Bandwidth) + // @@protoc_insertion_point(class_scope:rsctrl.core.Bandwidth) private: inline void set_has_up(); inline void clear_has_up(); @@ -982,9 +1187,9 @@ class Bandwidth : public ::google::protobuf::Message { mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; - friend void protobuf_AddDesc_base_2eproto(); - friend void protobuf_AssignDesc_base_2eproto(); - friend void protobuf_ShutdownFile_base_2eproto(); + friend void protobuf_AddDesc_core_2eproto(); + friend void protobuf_AssignDesc_core_2eproto(); + friend void protobuf_ShutdownFile_core_2eproto(); void InitAsDefaultInstance(); static Bandwidth* default_instance_; @@ -1045,31 +1250,31 @@ class BandwidthSet : public ::google::protobuf::Message { // accessors ------------------------------------------------------- - // repeated .rsctrl.base.Bandwidth bandwidths = 1; + // repeated .rsctrl.core.Bandwidth bandwidths = 1; inline int bandwidths_size() const; inline void clear_bandwidths(); static const int kBandwidthsFieldNumber = 1; - inline const ::rsctrl::base::Bandwidth& bandwidths(int index) const; - inline ::rsctrl::base::Bandwidth* mutable_bandwidths(int index); - inline ::rsctrl::base::Bandwidth* add_bandwidths(); - inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Bandwidth >& + inline const ::rsctrl::core::Bandwidth& bandwidths(int index) const; + inline ::rsctrl::core::Bandwidth* mutable_bandwidths(int index); + inline ::rsctrl::core::Bandwidth* add_bandwidths(); + inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Bandwidth >& bandwidths() const; - inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Bandwidth >* + inline ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Bandwidth >* mutable_bandwidths(); - // @@protoc_insertion_point(class_scope:rsctrl.base.BandwidthSet) + // @@protoc_insertion_point(class_scope:rsctrl.core.BandwidthSet) private: ::google::protobuf::UnknownFieldSet _unknown_fields_; - ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Bandwidth > bandwidths_; + ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Bandwidth > bandwidths_; mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; - friend void protobuf_AddDesc_base_2eproto(); - friend void protobuf_AssignDesc_base_2eproto(); - friend void protobuf_ShutdownFile_base_2eproto(); + friend void protobuf_AddDesc_core_2eproto(); + friend void protobuf_AssignDesc_core_2eproto(); + friend void protobuf_ShutdownFile_core_2eproto(); void InitAsDefaultInstance(); static BandwidthSet* default_instance_; @@ -1081,7 +1286,7 @@ class BandwidthSet : public ::google::protobuf::Message { // Status -// required .rsctrl.base.Status.StatusCode code = 1; +// required .rsctrl.core.Status.StatusCode code = 1; inline bool Status::has_code() const { return (_has_bits_[0] & 0x00000001u) != 0; } @@ -1095,11 +1300,11 @@ inline void Status::clear_code() { code_ = 0; clear_has_code(); } -inline ::rsctrl::base::Status_StatusCode Status::code() const { - return static_cast< ::rsctrl::base::Status_StatusCode >(code_); +inline ::rsctrl::core::Status_StatusCode Status::code() const { + return static_cast< ::rsctrl::core::Status_StatusCode >(code_); } -inline void Status::set_code(::rsctrl::base::Status_StatusCode value) { - GOOGLE_DCHECK(::rsctrl::base::Status_StatusCode_IsValid(value)); +inline void Status::set_code(::rsctrl::core::Status_StatusCode value) { + GOOGLE_DCHECK(::rsctrl::core::Status_StatusCode_IsValid(value)); set_has_code(); code_ = value; } @@ -1164,6 +1369,90 @@ inline ::std::string* Status::release_msg() { // ------------------------------------------------------------------- +// IpAddr + +// required string addr = 1 [default = ""]; +inline bool IpAddr::has_addr() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void IpAddr::set_has_addr() { + _has_bits_[0] |= 0x00000001u; +} +inline void IpAddr::clear_has_addr() { + _has_bits_[0] &= ~0x00000001u; +} +inline void IpAddr::clear_addr() { + if (addr_ != &::google::protobuf::internal::kEmptyString) { + addr_->clear(); + } + clear_has_addr(); +} +inline const ::std::string& IpAddr::addr() const { + return *addr_; +} +inline void IpAddr::set_addr(const ::std::string& value) { + set_has_addr(); + if (addr_ == &::google::protobuf::internal::kEmptyString) { + addr_ = new ::std::string; + } + addr_->assign(value); +} +inline void IpAddr::set_addr(const char* value) { + set_has_addr(); + if (addr_ == &::google::protobuf::internal::kEmptyString) { + addr_ = new ::std::string; + } + addr_->assign(value); +} +inline void IpAddr::set_addr(const char* value, size_t size) { + set_has_addr(); + if (addr_ == &::google::protobuf::internal::kEmptyString) { + addr_ = new ::std::string; + } + addr_->assign(reinterpret_cast(value), size); +} +inline ::std::string* IpAddr::mutable_addr() { + set_has_addr(); + if (addr_ == &::google::protobuf::internal::kEmptyString) { + addr_ = new ::std::string; + } + return addr_; +} +inline ::std::string* IpAddr::release_addr() { + clear_has_addr(); + if (addr_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = addr_; + addr_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// required uint32 port = 2 [default = 0]; +inline bool IpAddr::has_port() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void IpAddr::set_has_port() { + _has_bits_[0] |= 0x00000002u; +} +inline void IpAddr::clear_has_port() { + _has_bits_[0] &= ~0x00000002u; +} +inline void IpAddr::clear_port() { + port_ = 0u; + clear_has_port(); +} +inline ::google::protobuf::uint32 IpAddr::port() const { + return port_; +} +inline void IpAddr::set_port(::google::protobuf::uint32 value) { + set_has_port(); + port_ = value; +} + +// ------------------------------------------------------------------- + // Location // required string ssl_id = 1; @@ -1282,7 +1571,7 @@ inline ::std::string* Location::release_location() { } } -// required string localaddr = 3; +// required .rsctrl.core.IpAddr localaddr = 3; inline bool Location::has_localaddr() const { return (_has_bits_[0] & 0x00000004u) != 0; } @@ -1293,54 +1582,25 @@ inline void Location::clear_has_localaddr() { _has_bits_[0] &= ~0x00000004u; } inline void Location::clear_localaddr() { - if (localaddr_ != &::google::protobuf::internal::kEmptyString) { - localaddr_->clear(); - } + if (localaddr_ != NULL) localaddr_->::rsctrl::core::IpAddr::Clear(); clear_has_localaddr(); } -inline const ::std::string& Location::localaddr() const { - return *localaddr_; +inline const ::rsctrl::core::IpAddr& Location::localaddr() const { + return localaddr_ != NULL ? *localaddr_ : *default_instance_->localaddr_; } -inline void Location::set_localaddr(const ::std::string& value) { +inline ::rsctrl::core::IpAddr* Location::mutable_localaddr() { set_has_localaddr(); - if (localaddr_ == &::google::protobuf::internal::kEmptyString) { - localaddr_ = new ::std::string; - } - localaddr_->assign(value); -} -inline void Location::set_localaddr(const char* value) { - set_has_localaddr(); - if (localaddr_ == &::google::protobuf::internal::kEmptyString) { - localaddr_ = new ::std::string; - } - localaddr_->assign(value); -} -inline void Location::set_localaddr(const char* value, size_t size) { - set_has_localaddr(); - if (localaddr_ == &::google::protobuf::internal::kEmptyString) { - localaddr_ = new ::std::string; - } - localaddr_->assign(reinterpret_cast(value), size); -} -inline ::std::string* Location::mutable_localaddr() { - set_has_localaddr(); - if (localaddr_ == &::google::protobuf::internal::kEmptyString) { - localaddr_ = new ::std::string; - } + if (localaddr_ == NULL) localaddr_ = new ::rsctrl::core::IpAddr; return localaddr_; } -inline ::std::string* Location::release_localaddr() { +inline ::rsctrl::core::IpAddr* Location::release_localaddr() { clear_has_localaddr(); - if (localaddr_ == &::google::protobuf::internal::kEmptyString) { - return NULL; - } else { - ::std::string* temp = localaddr_; - localaddr_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); - return temp; - } + ::rsctrl::core::IpAddr* temp = localaddr_; + localaddr_ = NULL; + return temp; } -// required string extaddr = 4; +// required .rsctrl.core.IpAddr extaddr = 4; inline bool Location::has_extaddr() const { return (_has_bits_[0] & 0x00000008u) != 0; } @@ -1351,51 +1611,44 @@ inline void Location::clear_has_extaddr() { _has_bits_[0] &= ~0x00000008u; } inline void Location::clear_extaddr() { - if (extaddr_ != &::google::protobuf::internal::kEmptyString) { - extaddr_->clear(); - } + if (extaddr_ != NULL) extaddr_->::rsctrl::core::IpAddr::Clear(); clear_has_extaddr(); } -inline const ::std::string& Location::extaddr() const { - return *extaddr_; +inline const ::rsctrl::core::IpAddr& Location::extaddr() const { + return extaddr_ != NULL ? *extaddr_ : *default_instance_->extaddr_; } -inline void Location::set_extaddr(const ::std::string& value) { +inline ::rsctrl::core::IpAddr* Location::mutable_extaddr() { set_has_extaddr(); - if (extaddr_ == &::google::protobuf::internal::kEmptyString) { - extaddr_ = new ::std::string; - } - extaddr_->assign(value); -} -inline void Location::set_extaddr(const char* value) { - set_has_extaddr(); - if (extaddr_ == &::google::protobuf::internal::kEmptyString) { - extaddr_ = new ::std::string; - } - extaddr_->assign(value); -} -inline void Location::set_extaddr(const char* value, size_t size) { - set_has_extaddr(); - if (extaddr_ == &::google::protobuf::internal::kEmptyString) { - extaddr_ = new ::std::string; - } - extaddr_->assign(reinterpret_cast(value), size); -} -inline ::std::string* Location::mutable_extaddr() { - set_has_extaddr(); - if (extaddr_ == &::google::protobuf::internal::kEmptyString) { - extaddr_ = new ::std::string; - } + if (extaddr_ == NULL) extaddr_ = new ::rsctrl::core::IpAddr; return extaddr_; } -inline ::std::string* Location::release_extaddr() { +inline ::rsctrl::core::IpAddr* Location::release_extaddr() { clear_has_extaddr(); - if (extaddr_ == &::google::protobuf::internal::kEmptyString) { - return NULL; - } else { - ::std::string* temp = extaddr_; - extaddr_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); - return temp; - } + ::rsctrl::core::IpAddr* temp = extaddr_; + extaddr_ = NULL; + return temp; +} + +// required uint32 state = 5; +inline bool Location::has_state() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void Location::set_has_state() { + _has_bits_[0] |= 0x00000010u; +} +inline void Location::clear_has_state() { + _has_bits_[0] &= ~0x00000010u; +} +inline void Location::clear_state() { + state_ = 0u; + clear_has_state(); +} +inline ::google::protobuf::uint32 Location::state() const { + return state_; +} +inline void Location::set_state(::google::protobuf::uint32 value) { + set_has_state(); + state_ = value; } // ------------------------------------------------------------------- @@ -1518,27 +1771,50 @@ inline ::std::string* Person::release_name() { } } -// repeated .rsctrl.base.Location locations = 3; +// required .rsctrl.core.Person.Relationship relation = 3; +inline bool Person::has_relation() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void Person::set_has_relation() { + _has_bits_[0] |= 0x00000004u; +} +inline void Person::clear_has_relation() { + _has_bits_[0] &= ~0x00000004u; +} +inline void Person::clear_relation() { + relation_ = 1; + clear_has_relation(); +} +inline ::rsctrl::core::Person_Relationship Person::relation() const { + return static_cast< ::rsctrl::core::Person_Relationship >(relation_); +} +inline void Person::set_relation(::rsctrl::core::Person_Relationship value) { + GOOGLE_DCHECK(::rsctrl::core::Person_Relationship_IsValid(value)); + set_has_relation(); + relation_ = value; +} + +// repeated .rsctrl.core.Location locations = 4; inline int Person::locations_size() const { return locations_.size(); } inline void Person::clear_locations() { locations_.Clear(); } -inline const ::rsctrl::base::Location& Person::locations(int index) const { +inline const ::rsctrl::core::Location& Person::locations(int index) const { return locations_.Get(index); } -inline ::rsctrl::base::Location* Person::mutable_locations(int index) { +inline ::rsctrl::core::Location* Person::mutable_locations(int index) { return locations_.Mutable(index); } -inline ::rsctrl::base::Location* Person::add_locations() { +inline ::rsctrl::core::Location* Person::add_locations() { return locations_.Add(); } -inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Location >& +inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Location >& Person::locations() const { return locations_; } -inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Location >* +inline ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Location >* Person::mutable_locations() { return &locations_; } @@ -1921,52 +2197,52 @@ inline ::std::string* Dir::release_path() { } } -// repeated .rsctrl.base.Dir subdirs = 3; +// repeated .rsctrl.core.Dir subdirs = 3; inline int Dir::subdirs_size() const { return subdirs_.size(); } inline void Dir::clear_subdirs() { subdirs_.Clear(); } -inline const ::rsctrl::base::Dir& Dir::subdirs(int index) const { +inline const ::rsctrl::core::Dir& Dir::subdirs(int index) const { return subdirs_.Get(index); } -inline ::rsctrl::base::Dir* Dir::mutable_subdirs(int index) { +inline ::rsctrl::core::Dir* Dir::mutable_subdirs(int index) { return subdirs_.Mutable(index); } -inline ::rsctrl::base::Dir* Dir::add_subdirs() { +inline ::rsctrl::core::Dir* Dir::add_subdirs() { return subdirs_.Add(); } -inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Dir >& +inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Dir >& Dir::subdirs() const { return subdirs_; } -inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Dir >* +inline ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Dir >* Dir::mutable_subdirs() { return &subdirs_; } -// repeated .rsctrl.base.File files = 4; +// repeated .rsctrl.core.File files = 4; inline int Dir::files_size() const { return files_.size(); } inline void Dir::clear_files() { files_.Clear(); } -inline const ::rsctrl::base::File& Dir::files(int index) const { +inline const ::rsctrl::core::File& Dir::files(int index) const { return files_.Get(index); } -inline ::rsctrl::base::File* Dir::mutable_files(int index) { +inline ::rsctrl::core::File* Dir::mutable_files(int index) { return files_.Mutable(index); } -inline ::rsctrl::base::File* Dir::add_files() { +inline ::rsctrl::core::File* Dir::add_files() { return files_.Add(); } -inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::File >& +inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::core::File >& Dir::files() const { return files_; } -inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::File >* +inline ::google::protobuf::RepeatedPtrField< ::rsctrl::core::File >* Dir::mutable_files() { return &files_; } @@ -1975,7 +2251,7 @@ Dir::mutable_files() { // SystemStatus -// required .rsctrl.base.SystemStatus.NetCode net_status = 1; +// required .rsctrl.core.SystemStatus.NetCode net_status = 1; inline bool SystemStatus::has_net_status() const { return (_has_bits_[0] & 0x00000001u) != 0; } @@ -1989,11 +2265,11 @@ inline void SystemStatus::clear_net_status() { net_status_ = 0; clear_has_net_status(); } -inline ::rsctrl::base::SystemStatus_NetCode SystemStatus::net_status() const { - return static_cast< ::rsctrl::base::SystemStatus_NetCode >(net_status_); +inline ::rsctrl::core::SystemStatus_NetCode SystemStatus::net_status() const { + return static_cast< ::rsctrl::core::SystemStatus_NetCode >(net_status_); } -inline void SystemStatus::set_net_status(::rsctrl::base::SystemStatus_NetCode value) { - GOOGLE_DCHECK(::rsctrl::base::SystemStatus_NetCode_IsValid(value)); +inline void SystemStatus::set_net_status(::rsctrl::core::SystemStatus_NetCode value) { + GOOGLE_DCHECK(::rsctrl::core::SystemStatus_NetCode_IsValid(value)); set_has_net_status(); net_status_ = value; } @@ -2166,27 +2442,27 @@ inline ::std::string* Bandwidth::release_name() { // BandwidthSet -// repeated .rsctrl.base.Bandwidth bandwidths = 1; +// repeated .rsctrl.core.Bandwidth bandwidths = 1; inline int BandwidthSet::bandwidths_size() const { return bandwidths_.size(); } inline void BandwidthSet::clear_bandwidths() { bandwidths_.Clear(); } -inline const ::rsctrl::base::Bandwidth& BandwidthSet::bandwidths(int index) const { +inline const ::rsctrl::core::Bandwidth& BandwidthSet::bandwidths(int index) const { return bandwidths_.Get(index); } -inline ::rsctrl::base::Bandwidth* BandwidthSet::mutable_bandwidths(int index) { +inline ::rsctrl::core::Bandwidth* BandwidthSet::mutable_bandwidths(int index) { return bandwidths_.Mutable(index); } -inline ::rsctrl::base::Bandwidth* BandwidthSet::add_bandwidths() { +inline ::rsctrl::core::Bandwidth* BandwidthSet::add_bandwidths() { return bandwidths_.Add(); } -inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Bandwidth >& +inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Bandwidth >& BandwidthSet::bandwidths() const { return bandwidths_; } -inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Bandwidth >* +inline ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Bandwidth >* BandwidthSet::mutable_bandwidths() { return &bandwidths_; } @@ -2194,7 +2470,7 @@ BandwidthSet::mutable_bandwidths() { // @@protoc_insertion_point(namespace_scope) -} // namespace base +} // namespace core } // namespace rsctrl #ifndef SWIG @@ -2202,20 +2478,28 @@ namespace google { namespace protobuf { template <> -inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::base::Status_StatusCode>() { - return ::rsctrl::base::Status_StatusCode_descriptor(); +inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::core::Status_StatusCode>() { + return ::rsctrl::core::Status_StatusCode_descriptor(); } template <> -inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::base::SystemStatus_NetCode>() { - return ::rsctrl::base::SystemStatus_NetCode_descriptor(); +inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::core::Location_StateFlags>() { + return ::rsctrl::core::Location_StateFlags_descriptor(); } template <> -inline const EnumDescriptor* GetEnumDescriptor< rsctrl::base::ExtensionId>() { - return rsctrl::base::ExtensionId_descriptor(); +inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::core::Person_Relationship>() { + return ::rsctrl::core::Person_Relationship_descriptor(); } template <> -inline const EnumDescriptor* GetEnumDescriptor< rsctrl::base::PackageId>() { - return rsctrl::base::PackageId_descriptor(); +inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::core::SystemStatus_NetCode>() { + return ::rsctrl::core::SystemStatus_NetCode_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< rsctrl::core::ExtensionId>() { + return rsctrl::core::ExtensionId_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< rsctrl::core::PackageId>() { + return rsctrl::core::PackageId_descriptor(); } } // namespace google @@ -2224,4 +2508,4 @@ inline const EnumDescriptor* GetEnumDescriptor< rsctrl::base::PackageId>() { // @@protoc_insertion_point(global_scope) -#endif // PROTOBUF_base_2eproto__INCLUDED +#endif // PROTOBUF_core_2eproto__INCLUDED diff --git a/retroshare-nogui/src/rpc/proto/gencc/peers.pb.cc b/retroshare-nogui/src/rpc/proto/gencc/peers.pb.cc index 9fc028d38..948feed64 100644 --- a/retroshare-nogui/src/rpc/proto/gencc/peers.pb.cc +++ b/retroshare-nogui/src/rpc/proto/gencc/peers.pb.cc @@ -205,37 +205,37 @@ void protobuf_AddDesc_peers_2eproto() { already_here = true; GOOGLE_PROTOBUF_VERIFY_VERSION; - ::rsctrl::base::protobuf_AddDesc_base_2eproto(); + ::rsctrl::core::protobuf_AddDesc_core_2eproto(); ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( - "\n\013peers.proto\022\014rsctrl.peers\032\nbase.proto\"" - "\246\002\n\014RequestPeers\0221\n\003set\030\001 \002(\0162$.rsctrl.p" + "\n\013peers.proto\022\014rsctrl.peers\032\ncore.proto\"" + "\251\002\n\014RequestPeers\0221\n\003set\030\001 \002(\0162$.rsctrl.p" "eers.RequestPeers.SetOption\0223\n\004info\030\002 \002(" "\0162%.rsctrl.peers.RequestPeers.InfoOption" - "\022\017\n\007gpg_ids\030\003 \003(\t\"[\n\tSetOption\022\t\n\005OWNID\020" - "\001\022\n\n\006LISTED\020\002\022\n\n\006ONLINE\020\003\022\013\n\007FRIENDS\020\004\022\t" - "\n\005VALID\020\005\022\n\n\006SIGNED\020\006\022\007\n\003ALL\020\007\"@\n\nInfoOp" - "tion\022\014\n\010NAMEONLY\020\001\022\t\n\005BASIC\020\002\022\014\n\010LOCATIO" - "N\020\003\022\013\n\007ALLINFO\020\004\"[\n\020ResponsePeerList\022#\n\006" - "status\030\001 \002(\0132\023.rsctrl.base.Status\022\"\n\005pee" - "rs\030\002 \003(\0132\023.rsctrl.base.Person\"\242\001\n\016Reques" - "tAddPeer\022\016\n\006gpg_id\030\001 \002(\t\0220\n\003cmd\030\002 \002(\0162#." - "rsctrl.peers.RequestAddPeer.AddCmd\022\014\n\004ce" - "rt\030\003 \001(\t\"@\n\006AddCmd\022\010\n\004NOOP\020\000\022\007\n\003ADD\020\001\022\n\n" - "\006REMOVE\020\002\022\n\n\006IMPORT\020\003\022\013\n\007EXAMINE\020\004\"Z\n\017Re" - "sponseAddPeer\022#\n\006status\030\001 \002(\0132\023.rsctrl.b" - "ase.Status\022\"\n\005peers\030\002 \003(\0132\023.rsctrl.base." - "Person\"\231\001\n\021RequestModifyPeer\0223\n\003cmd\030\001 \002(" - "\0162&.rsctrl.peers.RequestModifyPeer.ModCm" - "d\022\"\n\005peers\030\002 \003(\0132\023.rsctrl.base.Person\"+\n" - "\006ModCmd\022\010\n\004NOOP\020\000\022\013\n\007ADDRESS\020\001\022\n\n\006DYNDNS" - "\020\002\"]\n\022ResponseModifyPeer\022#\n\006status\030\001 \002(\013" - "2\023.rsctrl.base.Status\022\"\n\005peers\030\002 \003(\0132\023.r" - "sctrl.base.Person*^\n\rRequestMsgIds\022\026\n\022Ms" - "gId_RequestPeers\020\001\022\030\n\024MsgId_RequestAddPe" - "er\020\002\022\033\n\027MsgId_RequestModifyPeer\020\003*e\n\016Res" - "ponseMsgIds\022\032\n\026MsgId_ResponsePeerList\020\001\022" - "\031\n\025MsgId_ResponseAddPeer\020\002\022\034\n\030MsgId_Resp" - "onseModifyPeer\020\003", 1136); + "\022\017\n\007gpg_ids\030\003 \003(\t\"^\n\tSetOption\022\t\n\005OWNID\020" + "\001\022\n\n\006LISTED\020\002\022\r\n\tCONNECTED\020\003\022\013\n\007FRIENDS\020" + "\004\022\t\n\005VALID\020\005\022\n\n\006SIGNED\020\006\022\007\n\003ALL\020\007\"@\n\nInf" + "oOption\022\014\n\010NAMEONLY\020\001\022\t\n\005BASIC\020\002\022\014\n\010LOCA" + "TION\020\003\022\013\n\007ALLINFO\020\004\"[\n\020ResponsePeerList\022" + "#\n\006status\030\001 \002(\0132\023.rsctrl.core.Status\022\"\n\005" + "peers\030\002 \003(\0132\023.rsctrl.core.Person\"\242\001\n\016Req" + "uestAddPeer\022\016\n\006gpg_id\030\001 \002(\t\0220\n\003cmd\030\002 \002(\016" + "2#.rsctrl.peers.RequestAddPeer.AddCmd\022\014\n" + "\004cert\030\003 \001(\t\"@\n\006AddCmd\022\010\n\004NOOP\020\000\022\007\n\003ADD\020\001" + "\022\n\n\006REMOVE\020\002\022\n\n\006IMPORT\020\003\022\013\n\007EXAMINE\020\004\"Z\n" + "\017ResponseAddPeer\022#\n\006status\030\001 \002(\0132\023.rsctr" + "l.core.Status\022\"\n\005peers\030\002 \003(\0132\023.rsctrl.co" + "re.Person\"\231\001\n\021RequestModifyPeer\0223\n\003cmd\030\001" + " \002(\0162&.rsctrl.peers.RequestModifyPeer.Mo" + "dCmd\022\"\n\005peers\030\002 \003(\0132\023.rsctrl.core.Person" + "\"+\n\006ModCmd\022\010\n\004NOOP\020\000\022\013\n\007ADDRESS\020\001\022\n\n\006DYN" + "DNS\020\002\"]\n\022ResponseModifyPeer\022#\n\006status\030\001 " + "\002(\0132\023.rsctrl.core.Status\022\"\n\005peers\030\002 \003(\0132" + "\023.rsctrl.core.Person*^\n\rRequestMsgIds\022\026\n" + "\022MsgId_RequestPeers\020\001\022\030\n\024MsgId_RequestAd" + "dPeer\020\002\022\033\n\027MsgId_RequestModifyPeer\020\003*e\n\016" + "ResponseMsgIds\022\032\n\026MsgId_ResponsePeerList" + "\020\001\022\031\n\025MsgId_ResponseAddPeer\020\002\022\034\n\030MsgId_R" + "esponseModifyPeer\020\003", 1139); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "peers.proto", &protobuf_RegisterTypes); RequestPeers::default_instance_ = new RequestPeers(); @@ -315,7 +315,7 @@ bool RequestPeers_SetOption_IsValid(int value) { #ifndef _MSC_VER const RequestPeers_SetOption RequestPeers::OWNID; const RequestPeers_SetOption RequestPeers::LISTED; -const RequestPeers_SetOption RequestPeers::ONLINE; +const RequestPeers_SetOption RequestPeers::CONNECTED; const RequestPeers_SetOption RequestPeers::FRIENDS; const RequestPeers_SetOption RequestPeers::VALID; const RequestPeers_SetOption RequestPeers::SIGNED; @@ -667,7 +667,7 @@ ResponsePeerList::ResponsePeerList() } void ResponsePeerList::InitAsDefaultInstance() { - status_ = const_cast< ::rsctrl::base::Status*>(&::rsctrl::base::Status::default_instance()); + status_ = const_cast< ::rsctrl::core::Status*>(&::rsctrl::core::Status::default_instance()); } ResponsePeerList::ResponsePeerList(const ResponsePeerList& from) @@ -715,7 +715,7 @@ ResponsePeerList* ResponsePeerList::New() const { void ResponsePeerList::Clear() { if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { if (has_status()) { - if (status_ != NULL) status_->::rsctrl::base::Status::Clear(); + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); } } peers_.Clear(); @@ -729,7 +729,7 @@ bool ResponsePeerList::MergePartialFromCodedStream( ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // required .rsctrl.base.Status status = 1; + // required .rsctrl.core.Status status = 1; case 1: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { @@ -742,7 +742,7 @@ bool ResponsePeerList::MergePartialFromCodedStream( break; } - // repeated .rsctrl.base.Person peers = 2; + // repeated .rsctrl.core.Person peers = 2; case 2: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { @@ -775,13 +775,13 @@ bool ResponsePeerList::MergePartialFromCodedStream( void ResponsePeerList::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - // required .rsctrl.base.Status status = 1; + // required .rsctrl.core.Status status = 1; if (has_status()) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 1, this->status(), output); } - // repeated .rsctrl.base.Person peers = 2; + // repeated .rsctrl.core.Person peers = 2; for (int i = 0; i < this->peers_size(); i++) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 2, this->peers(i), output); @@ -795,14 +795,14 @@ void ResponsePeerList::SerializeWithCachedSizes( ::google::protobuf::uint8* ResponsePeerList::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { - // required .rsctrl.base.Status status = 1; + // required .rsctrl.core.Status status = 1; if (has_status()) { target = ::google::protobuf::internal::WireFormatLite:: WriteMessageNoVirtualToArray( 1, this->status(), target); } - // repeated .rsctrl.base.Person peers = 2; + // repeated .rsctrl.core.Person peers = 2; for (int i = 0; i < this->peers_size(); i++) { target = ::google::protobuf::internal::WireFormatLite:: WriteMessageNoVirtualToArray( @@ -820,7 +820,7 @@ int ResponsePeerList::ByteSize() const { int total_size = 0; if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // required .rsctrl.base.Status status = 1; + // required .rsctrl.core.Status status = 1; if (has_status()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( @@ -828,7 +828,7 @@ int ResponsePeerList::ByteSize() const { } } - // repeated .rsctrl.base.Person peers = 2; + // repeated .rsctrl.core.Person peers = 2; total_size += 1 * this->peers_size(); for (int i = 0; i < this->peers_size(); i++) { total_size += @@ -864,7 +864,7 @@ void ResponsePeerList::MergeFrom(const ResponsePeerList& from) { peers_.MergeFrom(from.peers_); if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { if (from.has_status()) { - mutable_status()->::rsctrl::base::Status::MergeFrom(from.status()); + mutable_status()->::rsctrl::core::Status::MergeFrom(from.status()); } } mutable_unknown_fields()->MergeFrom(from.unknown_fields()); @@ -1281,7 +1281,7 @@ ResponseAddPeer::ResponseAddPeer() } void ResponseAddPeer::InitAsDefaultInstance() { - status_ = const_cast< ::rsctrl::base::Status*>(&::rsctrl::base::Status::default_instance()); + status_ = const_cast< ::rsctrl::core::Status*>(&::rsctrl::core::Status::default_instance()); } ResponseAddPeer::ResponseAddPeer(const ResponseAddPeer& from) @@ -1329,7 +1329,7 @@ ResponseAddPeer* ResponseAddPeer::New() const { void ResponseAddPeer::Clear() { if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { if (has_status()) { - if (status_ != NULL) status_->::rsctrl::base::Status::Clear(); + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); } } peers_.Clear(); @@ -1343,7 +1343,7 @@ bool ResponseAddPeer::MergePartialFromCodedStream( ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // required .rsctrl.base.Status status = 1; + // required .rsctrl.core.Status status = 1; case 1: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { @@ -1356,7 +1356,7 @@ bool ResponseAddPeer::MergePartialFromCodedStream( break; } - // repeated .rsctrl.base.Person peers = 2; + // repeated .rsctrl.core.Person peers = 2; case 2: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { @@ -1389,13 +1389,13 @@ bool ResponseAddPeer::MergePartialFromCodedStream( void ResponseAddPeer::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - // required .rsctrl.base.Status status = 1; + // required .rsctrl.core.Status status = 1; if (has_status()) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 1, this->status(), output); } - // repeated .rsctrl.base.Person peers = 2; + // repeated .rsctrl.core.Person peers = 2; for (int i = 0; i < this->peers_size(); i++) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 2, this->peers(i), output); @@ -1409,14 +1409,14 @@ void ResponseAddPeer::SerializeWithCachedSizes( ::google::protobuf::uint8* ResponseAddPeer::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { - // required .rsctrl.base.Status status = 1; + // required .rsctrl.core.Status status = 1; if (has_status()) { target = ::google::protobuf::internal::WireFormatLite:: WriteMessageNoVirtualToArray( 1, this->status(), target); } - // repeated .rsctrl.base.Person peers = 2; + // repeated .rsctrl.core.Person peers = 2; for (int i = 0; i < this->peers_size(); i++) { target = ::google::protobuf::internal::WireFormatLite:: WriteMessageNoVirtualToArray( @@ -1434,7 +1434,7 @@ int ResponseAddPeer::ByteSize() const { int total_size = 0; if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // required .rsctrl.base.Status status = 1; + // required .rsctrl.core.Status status = 1; if (has_status()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( @@ -1442,7 +1442,7 @@ int ResponseAddPeer::ByteSize() const { } } - // repeated .rsctrl.base.Person peers = 2; + // repeated .rsctrl.core.Person peers = 2; total_size += 1 * this->peers_size(); for (int i = 0; i < this->peers_size(); i++) { total_size += @@ -1478,7 +1478,7 @@ void ResponseAddPeer::MergeFrom(const ResponseAddPeer& from) { peers_.MergeFrom(from.peers_); if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { if (from.has_status()) { - mutable_status()->::rsctrl::base::Status::MergeFrom(from.status()); + mutable_status()->::rsctrl::core::Status::MergeFrom(from.status()); } } mutable_unknown_fields()->MergeFrom(from.unknown_fields()); @@ -1641,7 +1641,7 @@ bool RequestModifyPeer::MergePartialFromCodedStream( break; } - // repeated .rsctrl.base.Person peers = 2; + // repeated .rsctrl.core.Person peers = 2; case 2: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { @@ -1680,7 +1680,7 @@ void RequestModifyPeer::SerializeWithCachedSizes( 1, this->cmd(), output); } - // repeated .rsctrl.base.Person peers = 2; + // repeated .rsctrl.core.Person peers = 2; for (int i = 0; i < this->peers_size(); i++) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 2, this->peers(i), output); @@ -1700,7 +1700,7 @@ void RequestModifyPeer::SerializeWithCachedSizes( 1, this->cmd(), target); } - // repeated .rsctrl.base.Person peers = 2; + // repeated .rsctrl.core.Person peers = 2; for (int i = 0; i < this->peers_size(); i++) { target = ::google::protobuf::internal::WireFormatLite:: WriteMessageNoVirtualToArray( @@ -1725,7 +1725,7 @@ int RequestModifyPeer::ByteSize() const { } } - // repeated .rsctrl.base.Person peers = 2; + // repeated .rsctrl.core.Person peers = 2; total_size += 1 * this->peers_size(); for (int i = 0; i < this->peers_size(); i++) { total_size += @@ -1820,7 +1820,7 @@ ResponseModifyPeer::ResponseModifyPeer() } void ResponseModifyPeer::InitAsDefaultInstance() { - status_ = const_cast< ::rsctrl::base::Status*>(&::rsctrl::base::Status::default_instance()); + status_ = const_cast< ::rsctrl::core::Status*>(&::rsctrl::core::Status::default_instance()); } ResponseModifyPeer::ResponseModifyPeer(const ResponseModifyPeer& from) @@ -1868,7 +1868,7 @@ ResponseModifyPeer* ResponseModifyPeer::New() const { void ResponseModifyPeer::Clear() { if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { if (has_status()) { - if (status_ != NULL) status_->::rsctrl::base::Status::Clear(); + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); } } peers_.Clear(); @@ -1882,7 +1882,7 @@ bool ResponseModifyPeer::MergePartialFromCodedStream( ::google::protobuf::uint32 tag; while ((tag = input->ReadTag()) != 0) { switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // required .rsctrl.base.Status status = 1; + // required .rsctrl.core.Status status = 1; case 1: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { @@ -1895,7 +1895,7 @@ bool ResponseModifyPeer::MergePartialFromCodedStream( break; } - // repeated .rsctrl.base.Person peers = 2; + // repeated .rsctrl.core.Person peers = 2; case 2: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { @@ -1928,13 +1928,13 @@ bool ResponseModifyPeer::MergePartialFromCodedStream( void ResponseModifyPeer::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { - // required .rsctrl.base.Status status = 1; + // required .rsctrl.core.Status status = 1; if (has_status()) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 1, this->status(), output); } - // repeated .rsctrl.base.Person peers = 2; + // repeated .rsctrl.core.Person peers = 2; for (int i = 0; i < this->peers_size(); i++) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 2, this->peers(i), output); @@ -1948,14 +1948,14 @@ void ResponseModifyPeer::SerializeWithCachedSizes( ::google::protobuf::uint8* ResponseModifyPeer::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { - // required .rsctrl.base.Status status = 1; + // required .rsctrl.core.Status status = 1; if (has_status()) { target = ::google::protobuf::internal::WireFormatLite:: WriteMessageNoVirtualToArray( 1, this->status(), target); } - // repeated .rsctrl.base.Person peers = 2; + // repeated .rsctrl.core.Person peers = 2; for (int i = 0; i < this->peers_size(); i++) { target = ::google::protobuf::internal::WireFormatLite:: WriteMessageNoVirtualToArray( @@ -1973,7 +1973,7 @@ int ResponseModifyPeer::ByteSize() const { int total_size = 0; if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // required .rsctrl.base.Status status = 1; + // required .rsctrl.core.Status status = 1; if (has_status()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( @@ -1981,7 +1981,7 @@ int ResponseModifyPeer::ByteSize() const { } } - // repeated .rsctrl.base.Person peers = 2; + // repeated .rsctrl.core.Person peers = 2; total_size += 1 * this->peers_size(); for (int i = 0; i < this->peers_size(); i++) { total_size += @@ -2017,7 +2017,7 @@ void ResponseModifyPeer::MergeFrom(const ResponseModifyPeer& from) { peers_.MergeFrom(from.peers_); if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { if (from.has_status()) { - mutable_status()->::rsctrl::base::Status::MergeFrom(from.status()); + mutable_status()->::rsctrl::core::Status::MergeFrom(from.status()); } } mutable_unknown_fields()->MergeFrom(from.unknown_fields()); diff --git a/retroshare-nogui/src/rpc/proto/gencc/peers.pb.h b/retroshare-nogui/src/rpc/proto/gencc/peers.pb.h index fd5113a23..75a90eb12 100644 --- a/retroshare-nogui/src/rpc/proto/gencc/peers.pb.h +++ b/retroshare-nogui/src/rpc/proto/gencc/peers.pb.h @@ -23,7 +23,7 @@ #include #include #include -#include "base.pb.h" +#include "core.pb.h" // @@protoc_insertion_point(includes) namespace rsctrl { @@ -44,7 +44,7 @@ class ResponseModifyPeer; enum RequestPeers_SetOption { RequestPeers_SetOption_OWNID = 1, RequestPeers_SetOption_LISTED = 2, - RequestPeers_SetOption_ONLINE = 3, + RequestPeers_SetOption_CONNECTED = 3, RequestPeers_SetOption_FRIENDS = 4, RequestPeers_SetOption_VALID = 5, RequestPeers_SetOption_SIGNED = 6, @@ -225,7 +225,7 @@ class RequestPeers : public ::google::protobuf::Message { typedef RequestPeers_SetOption SetOption; static const SetOption OWNID = RequestPeers_SetOption_OWNID; static const SetOption LISTED = RequestPeers_SetOption_LISTED; - static const SetOption ONLINE = RequestPeers_SetOption_ONLINE; + static const SetOption CONNECTED = RequestPeers_SetOption_CONNECTED; static const SetOption FRIENDS = RequestPeers_SetOption_FRIENDS; static const SetOption VALID = RequestPeers_SetOption_VALID; static const SetOption SIGNED = RequestPeers_SetOption_SIGNED; @@ -388,24 +388,24 @@ class ResponsePeerList : public ::google::protobuf::Message { // accessors ------------------------------------------------------- - // required .rsctrl.base.Status status = 1; + // required .rsctrl.core.Status status = 1; inline bool has_status() const; inline void clear_status(); static const int kStatusFieldNumber = 1; - inline const ::rsctrl::base::Status& status() const; - inline ::rsctrl::base::Status* mutable_status(); - inline ::rsctrl::base::Status* release_status(); + inline const ::rsctrl::core::Status& status() const; + inline ::rsctrl::core::Status* mutable_status(); + inline ::rsctrl::core::Status* release_status(); - // repeated .rsctrl.base.Person peers = 2; + // repeated .rsctrl.core.Person peers = 2; inline int peers_size() const; inline void clear_peers(); static const int kPeersFieldNumber = 2; - inline const ::rsctrl::base::Person& peers(int index) const; - inline ::rsctrl::base::Person* mutable_peers(int index); - inline ::rsctrl::base::Person* add_peers(); - inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >& + inline const ::rsctrl::core::Person& peers(int index) const; + inline ::rsctrl::core::Person* mutable_peers(int index); + inline ::rsctrl::core::Person* add_peers(); + inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Person >& peers() const; - inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >* + inline ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Person >* mutable_peers(); // @@protoc_insertion_point(class_scope:rsctrl.peers.ResponsePeerList) @@ -415,8 +415,8 @@ class ResponsePeerList : public ::google::protobuf::Message { ::google::protobuf::UnknownFieldSet _unknown_fields_; - ::rsctrl::base::Status* status_; - ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person > peers_; + ::rsctrl::core::Status* status_; + ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Person > peers_; mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; @@ -621,24 +621,24 @@ class ResponseAddPeer : public ::google::protobuf::Message { // accessors ------------------------------------------------------- - // required .rsctrl.base.Status status = 1; + // required .rsctrl.core.Status status = 1; inline bool has_status() const; inline void clear_status(); static const int kStatusFieldNumber = 1; - inline const ::rsctrl::base::Status& status() const; - inline ::rsctrl::base::Status* mutable_status(); - inline ::rsctrl::base::Status* release_status(); + inline const ::rsctrl::core::Status& status() const; + inline ::rsctrl::core::Status* mutable_status(); + inline ::rsctrl::core::Status* release_status(); - // repeated .rsctrl.base.Person peers = 2; + // repeated .rsctrl.core.Person peers = 2; inline int peers_size() const; inline void clear_peers(); static const int kPeersFieldNumber = 2; - inline const ::rsctrl::base::Person& peers(int index) const; - inline ::rsctrl::base::Person* mutable_peers(int index); - inline ::rsctrl::base::Person* add_peers(); - inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >& + inline const ::rsctrl::core::Person& peers(int index) const; + inline ::rsctrl::core::Person* mutable_peers(int index); + inline ::rsctrl::core::Person* add_peers(); + inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Person >& peers() const; - inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >* + inline ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Person >* mutable_peers(); // @@protoc_insertion_point(class_scope:rsctrl.peers.ResponseAddPeer) @@ -648,8 +648,8 @@ class ResponseAddPeer : public ::google::protobuf::Message { ::google::protobuf::UnknownFieldSet _unknown_fields_; - ::rsctrl::base::Status* status_; - ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person > peers_; + ::rsctrl::core::Status* status_; + ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Person > peers_; mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; @@ -749,16 +749,16 @@ class RequestModifyPeer : public ::google::protobuf::Message { inline ::rsctrl::peers::RequestModifyPeer_ModCmd cmd() const; inline void set_cmd(::rsctrl::peers::RequestModifyPeer_ModCmd value); - // repeated .rsctrl.base.Person peers = 2; + // repeated .rsctrl.core.Person peers = 2; inline int peers_size() const; inline void clear_peers(); static const int kPeersFieldNumber = 2; - inline const ::rsctrl::base::Person& peers(int index) const; - inline ::rsctrl::base::Person* mutable_peers(int index); - inline ::rsctrl::base::Person* add_peers(); - inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >& + inline const ::rsctrl::core::Person& peers(int index) const; + inline ::rsctrl::core::Person* mutable_peers(int index); + inline ::rsctrl::core::Person* add_peers(); + inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Person >& peers() const; - inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >* + inline ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Person >* mutable_peers(); // @@protoc_insertion_point(class_scope:rsctrl.peers.RequestModifyPeer) @@ -768,7 +768,7 @@ class RequestModifyPeer : public ::google::protobuf::Message { ::google::protobuf::UnknownFieldSet _unknown_fields_; - ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person > peers_; + ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Person > peers_; int cmd_; mutable int _cached_size_; @@ -837,24 +837,24 @@ class ResponseModifyPeer : public ::google::protobuf::Message { // accessors ------------------------------------------------------- - // required .rsctrl.base.Status status = 1; + // required .rsctrl.core.Status status = 1; inline bool has_status() const; inline void clear_status(); static const int kStatusFieldNumber = 1; - inline const ::rsctrl::base::Status& status() const; - inline ::rsctrl::base::Status* mutable_status(); - inline ::rsctrl::base::Status* release_status(); + inline const ::rsctrl::core::Status& status() const; + inline ::rsctrl::core::Status* mutable_status(); + inline ::rsctrl::core::Status* release_status(); - // repeated .rsctrl.base.Person peers = 2; + // repeated .rsctrl.core.Person peers = 2; inline int peers_size() const; inline void clear_peers(); static const int kPeersFieldNumber = 2; - inline const ::rsctrl::base::Person& peers(int index) const; - inline ::rsctrl::base::Person* mutable_peers(int index); - inline ::rsctrl::base::Person* add_peers(); - inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >& + inline const ::rsctrl::core::Person& peers(int index) const; + inline ::rsctrl::core::Person* mutable_peers(int index); + inline ::rsctrl::core::Person* add_peers(); + inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Person >& peers() const; - inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >* + inline ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Person >* mutable_peers(); // @@protoc_insertion_point(class_scope:rsctrl.peers.ResponseModifyPeer) @@ -864,8 +864,8 @@ class ResponseModifyPeer : public ::google::protobuf::Message { ::google::protobuf::UnknownFieldSet _unknown_fields_; - ::rsctrl::base::Status* status_; - ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person > peers_; + ::rsctrl::core::Status* status_; + ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Person > peers_; mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; @@ -978,7 +978,7 @@ RequestPeers::mutable_gpg_ids() { // ResponsePeerList -// required .rsctrl.base.Status status = 1; +// required .rsctrl.core.Status status = 1; inline bool ResponsePeerList::has_status() const { return (_has_bits_[0] & 0x00000001u) != 0; } @@ -989,45 +989,45 @@ inline void ResponsePeerList::clear_has_status() { _has_bits_[0] &= ~0x00000001u; } inline void ResponsePeerList::clear_status() { - if (status_ != NULL) status_->::rsctrl::base::Status::Clear(); + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); clear_has_status(); } -inline const ::rsctrl::base::Status& ResponsePeerList::status() const { +inline const ::rsctrl::core::Status& ResponsePeerList::status() const { return status_ != NULL ? *status_ : *default_instance_->status_; } -inline ::rsctrl::base::Status* ResponsePeerList::mutable_status() { +inline ::rsctrl::core::Status* ResponsePeerList::mutable_status() { set_has_status(); - if (status_ == NULL) status_ = new ::rsctrl::base::Status; + if (status_ == NULL) status_ = new ::rsctrl::core::Status; return status_; } -inline ::rsctrl::base::Status* ResponsePeerList::release_status() { +inline ::rsctrl::core::Status* ResponsePeerList::release_status() { clear_has_status(); - ::rsctrl::base::Status* temp = status_; + ::rsctrl::core::Status* temp = status_; status_ = NULL; return temp; } -// repeated .rsctrl.base.Person peers = 2; +// repeated .rsctrl.core.Person peers = 2; inline int ResponsePeerList::peers_size() const { return peers_.size(); } inline void ResponsePeerList::clear_peers() { peers_.Clear(); } -inline const ::rsctrl::base::Person& ResponsePeerList::peers(int index) const { +inline const ::rsctrl::core::Person& ResponsePeerList::peers(int index) const { return peers_.Get(index); } -inline ::rsctrl::base::Person* ResponsePeerList::mutable_peers(int index) { +inline ::rsctrl::core::Person* ResponsePeerList::mutable_peers(int index) { return peers_.Mutable(index); } -inline ::rsctrl::base::Person* ResponsePeerList::add_peers() { +inline ::rsctrl::core::Person* ResponsePeerList::add_peers() { return peers_.Add(); } -inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >& +inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Person >& ResponsePeerList::peers() const { return peers_; } -inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >* +inline ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Person >* ResponsePeerList::mutable_peers() { return &peers_; } @@ -1179,7 +1179,7 @@ inline ::std::string* RequestAddPeer::release_cert() { // ResponseAddPeer -// required .rsctrl.base.Status status = 1; +// required .rsctrl.core.Status status = 1; inline bool ResponseAddPeer::has_status() const { return (_has_bits_[0] & 0x00000001u) != 0; } @@ -1190,45 +1190,45 @@ inline void ResponseAddPeer::clear_has_status() { _has_bits_[0] &= ~0x00000001u; } inline void ResponseAddPeer::clear_status() { - if (status_ != NULL) status_->::rsctrl::base::Status::Clear(); + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); clear_has_status(); } -inline const ::rsctrl::base::Status& ResponseAddPeer::status() const { +inline const ::rsctrl::core::Status& ResponseAddPeer::status() const { return status_ != NULL ? *status_ : *default_instance_->status_; } -inline ::rsctrl::base::Status* ResponseAddPeer::mutable_status() { +inline ::rsctrl::core::Status* ResponseAddPeer::mutable_status() { set_has_status(); - if (status_ == NULL) status_ = new ::rsctrl::base::Status; + if (status_ == NULL) status_ = new ::rsctrl::core::Status; return status_; } -inline ::rsctrl::base::Status* ResponseAddPeer::release_status() { +inline ::rsctrl::core::Status* ResponseAddPeer::release_status() { clear_has_status(); - ::rsctrl::base::Status* temp = status_; + ::rsctrl::core::Status* temp = status_; status_ = NULL; return temp; } -// repeated .rsctrl.base.Person peers = 2; +// repeated .rsctrl.core.Person peers = 2; inline int ResponseAddPeer::peers_size() const { return peers_.size(); } inline void ResponseAddPeer::clear_peers() { peers_.Clear(); } -inline const ::rsctrl::base::Person& ResponseAddPeer::peers(int index) const { +inline const ::rsctrl::core::Person& ResponseAddPeer::peers(int index) const { return peers_.Get(index); } -inline ::rsctrl::base::Person* ResponseAddPeer::mutable_peers(int index) { +inline ::rsctrl::core::Person* ResponseAddPeer::mutable_peers(int index) { return peers_.Mutable(index); } -inline ::rsctrl::base::Person* ResponseAddPeer::add_peers() { +inline ::rsctrl::core::Person* ResponseAddPeer::add_peers() { return peers_.Add(); } -inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >& +inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Person >& ResponseAddPeer::peers() const { return peers_; } -inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >* +inline ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Person >* ResponseAddPeer::mutable_peers() { return &peers_; } @@ -1260,27 +1260,27 @@ inline void RequestModifyPeer::set_cmd(::rsctrl::peers::RequestModifyPeer_ModCmd cmd_ = value; } -// repeated .rsctrl.base.Person peers = 2; +// repeated .rsctrl.core.Person peers = 2; inline int RequestModifyPeer::peers_size() const { return peers_.size(); } inline void RequestModifyPeer::clear_peers() { peers_.Clear(); } -inline const ::rsctrl::base::Person& RequestModifyPeer::peers(int index) const { +inline const ::rsctrl::core::Person& RequestModifyPeer::peers(int index) const { return peers_.Get(index); } -inline ::rsctrl::base::Person* RequestModifyPeer::mutable_peers(int index) { +inline ::rsctrl::core::Person* RequestModifyPeer::mutable_peers(int index) { return peers_.Mutable(index); } -inline ::rsctrl::base::Person* RequestModifyPeer::add_peers() { +inline ::rsctrl::core::Person* RequestModifyPeer::add_peers() { return peers_.Add(); } -inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >& +inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Person >& RequestModifyPeer::peers() const { return peers_; } -inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >* +inline ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Person >* RequestModifyPeer::mutable_peers() { return &peers_; } @@ -1289,7 +1289,7 @@ RequestModifyPeer::mutable_peers() { // ResponseModifyPeer -// required .rsctrl.base.Status status = 1; +// required .rsctrl.core.Status status = 1; inline bool ResponseModifyPeer::has_status() const { return (_has_bits_[0] & 0x00000001u) != 0; } @@ -1300,45 +1300,45 @@ inline void ResponseModifyPeer::clear_has_status() { _has_bits_[0] &= ~0x00000001u; } inline void ResponseModifyPeer::clear_status() { - if (status_ != NULL) status_->::rsctrl::base::Status::Clear(); + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); clear_has_status(); } -inline const ::rsctrl::base::Status& ResponseModifyPeer::status() const { +inline const ::rsctrl::core::Status& ResponseModifyPeer::status() const { return status_ != NULL ? *status_ : *default_instance_->status_; } -inline ::rsctrl::base::Status* ResponseModifyPeer::mutable_status() { +inline ::rsctrl::core::Status* ResponseModifyPeer::mutable_status() { set_has_status(); - if (status_ == NULL) status_ = new ::rsctrl::base::Status; + if (status_ == NULL) status_ = new ::rsctrl::core::Status; return status_; } -inline ::rsctrl::base::Status* ResponseModifyPeer::release_status() { +inline ::rsctrl::core::Status* ResponseModifyPeer::release_status() { clear_has_status(); - ::rsctrl::base::Status* temp = status_; + ::rsctrl::core::Status* temp = status_; status_ = NULL; return temp; } -// repeated .rsctrl.base.Person peers = 2; +// repeated .rsctrl.core.Person peers = 2; inline int ResponseModifyPeer::peers_size() const { return peers_.size(); } inline void ResponseModifyPeer::clear_peers() { peers_.Clear(); } -inline const ::rsctrl::base::Person& ResponseModifyPeer::peers(int index) const { +inline const ::rsctrl::core::Person& ResponseModifyPeer::peers(int index) const { return peers_.Get(index); } -inline ::rsctrl::base::Person* ResponseModifyPeer::mutable_peers(int index) { +inline ::rsctrl::core::Person* ResponseModifyPeer::mutable_peers(int index) { return peers_.Mutable(index); } -inline ::rsctrl::base::Person* ResponseModifyPeer::add_peers() { +inline ::rsctrl::core::Person* ResponseModifyPeer::add_peers() { return peers_.Add(); } -inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >& +inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Person >& ResponseModifyPeer::peers() const { return peers_; } -inline ::google::protobuf::RepeatedPtrField< ::rsctrl::base::Person >* +inline ::google::protobuf::RepeatedPtrField< ::rsctrl::core::Person >* ResponseModifyPeer::mutable_peers() { return &peers_; } diff --git a/retroshare-nogui/src/rpc/proto/gencc/system.pb.cc b/retroshare-nogui/src/rpc/proto/gencc/system.pb.cc new file mode 100644 index 000000000..ca729ce8f --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/gencc/system.pb.cc @@ -0,0 +1,753 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "system.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace rsctrl { +namespace system { + +namespace { + +const ::google::protobuf::Descriptor* RequestSystemStatus_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestSystemStatus_reflection_ = NULL; +const ::google::protobuf::Descriptor* ResponseSystemStatus_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ResponseSystemStatus_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* ResponseSystemStatus_NetCode_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_system_2eproto() { + protobuf_AddDesc_system_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "system.proto"); + GOOGLE_CHECK(file != NULL); + RequestSystemStatus_descriptor_ = file->message_type(0); + static const int RequestSystemStatus_offsets_[1] = { + }; + RequestSystemStatus_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestSystemStatus_descriptor_, + RequestSystemStatus::default_instance_, + RequestSystemStatus_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestSystemStatus, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestSystemStatus, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestSystemStatus)); + ResponseSystemStatus_descriptor_ = file->message_type(1); + static const int ResponseSystemStatus_offsets_[5] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSystemStatus, status_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSystemStatus, no_peers_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSystemStatus, no_connected_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSystemStatus, net_status_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSystemStatus, bw_total_), + }; + ResponseSystemStatus_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ResponseSystemStatus_descriptor_, + ResponseSystemStatus::default_instance_, + ResponseSystemStatus_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSystemStatus, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSystemStatus, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ResponseSystemStatus)); + ResponseSystemStatus_NetCode_descriptor_ = ResponseSystemStatus_descriptor_->enum_type(0); + RequestMsgIds_descriptor_ = file->enum_type(0); + ResponseMsgIds_descriptor_ = file->enum_type(1); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_system_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestSystemStatus_descriptor_, &RequestSystemStatus::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ResponseSystemStatus_descriptor_, &ResponseSystemStatus::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_system_2eproto() { + delete RequestSystemStatus::default_instance_; + delete RequestSystemStatus_reflection_; + delete ResponseSystemStatus::default_instance_; + delete ResponseSystemStatus_reflection_; +} + +void protobuf_AddDesc_system_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::rsctrl::core::protobuf_AddDesc_core_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\014system.proto\022\rrsctrl.system\032\ncore.prot" + "o\"\025\n\023RequestSystemStatus\"\366\002\n\024ResponseSys" + "temStatus\022#\n\006status\030\001 \002(\0132\023.rsctrl.core." + "Status\022\020\n\010no_peers\030\002 \002(\r\022\024\n\014no_connected" + "\030\003 \002(\r\022\?\n\nnet_status\030\004 \002(\0162+.rsctrl.syst" + "em.ResponseSystemStatus.NetCode\022(\n\010bw_to" + "tal\030\005 \002(\0132\026.rsctrl.core.Bandwidth\"\245\001\n\007Ne" + "tCode\022\017\n\013BAD_UNKNOWN\020\000\022\017\n\013BAD_OFFLINE\020\001\022" + "\016\n\nBAD_NATSYM\020\002\022\021\n\rBAD_NODHT_NAT\020\003\022\023\n\017WA" + "RNING_RESTART\020\004\022\022\n\016WARNING_NATTED\020\005\022\021\n\rW" + "ARNING_NODHT\020\006\022\010\n\004GOOD\020\007\022\017\n\013ADV_FORWARD\020" + "\010*.\n\rRequestMsgIds\022\035\n\031MsgId_RequestSyste" + "mStatus\020\001*0\n\016ResponseMsgIds\022\036\n\032MsgId_Res" + "ponseSystemStatus\020\001", 539); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "system.proto", &protobuf_RegisterTypes); + RequestSystemStatus::default_instance_ = new RequestSystemStatus(); + ResponseSystemStatus::default_instance_ = new ResponseSystemStatus(); + RequestSystemStatus::default_instance_->InitAsDefaultInstance(); + ResponseSystemStatus::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_system_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_system_2eproto { + StaticDescriptorInitializer_system_2eproto() { + protobuf_AddDesc_system_2eproto(); + } +} static_descriptor_initializer_system_2eproto_; + +const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestMsgIds_descriptor_; +} +bool RequestMsgIds_IsValid(int value) { + switch(value) { + case 1: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor() { + protobuf_AssignDescriptorsOnce(); + return ResponseMsgIds_descriptor_; +} +bool ResponseMsgIds_IsValid(int value) { + switch(value) { + case 1: + return true; + default: + return false; + } +} + + +// =================================================================== + +#ifndef _MSC_VER +#endif // !_MSC_VER + +RequestSystemStatus::RequestSystemStatus() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RequestSystemStatus::InitAsDefaultInstance() { +} + +RequestSystemStatus::RequestSystemStatus(const RequestSystemStatus& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RequestSystemStatus::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RequestSystemStatus::~RequestSystemStatus() { + SharedDtor(); +} + +void RequestSystemStatus::SharedDtor() { + if (this != default_instance_) { + } +} + +void RequestSystemStatus::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestSystemStatus::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestSystemStatus_descriptor_; +} + +const RequestSystemStatus& RequestSystemStatus::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_system_2eproto(); return *default_instance_; +} + +RequestSystemStatus* RequestSystemStatus::default_instance_ = NULL; + +RequestSystemStatus* RequestSystemStatus::New() const { + return new RequestSystemStatus; +} + +void RequestSystemStatus::Clear() { + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestSystemStatus::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + } + return true; +#undef DO_ +} + +void RequestSystemStatus::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RequestSystemStatus::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RequestSystemStatus::ByteSize() const { + int total_size = 0; + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestSystemStatus::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestSystemStatus* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestSystemStatus::MergeFrom(const RequestSystemStatus& from) { + GOOGLE_CHECK_NE(&from, this); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestSystemStatus::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestSystemStatus::CopyFrom(const RequestSystemStatus& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestSystemStatus::IsInitialized() const { + + return true; +} + +void RequestSystemStatus::Swap(RequestSystemStatus* other) { + if (other != this) { + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestSystemStatus::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestSystemStatus_descriptor_; + metadata.reflection = RequestSystemStatus_reflection_; + return metadata; +} + + +// =================================================================== + +const ::google::protobuf::EnumDescriptor* ResponseSystemStatus_NetCode_descriptor() { + protobuf_AssignDescriptorsOnce(); + return ResponseSystemStatus_NetCode_descriptor_; +} +bool ResponseSystemStatus_NetCode_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const ResponseSystemStatus_NetCode ResponseSystemStatus::BAD_UNKNOWN; +const ResponseSystemStatus_NetCode ResponseSystemStatus::BAD_OFFLINE; +const ResponseSystemStatus_NetCode ResponseSystemStatus::BAD_NATSYM; +const ResponseSystemStatus_NetCode ResponseSystemStatus::BAD_NODHT_NAT; +const ResponseSystemStatus_NetCode ResponseSystemStatus::WARNING_RESTART; +const ResponseSystemStatus_NetCode ResponseSystemStatus::WARNING_NATTED; +const ResponseSystemStatus_NetCode ResponseSystemStatus::WARNING_NODHT; +const ResponseSystemStatus_NetCode ResponseSystemStatus::GOOD; +const ResponseSystemStatus_NetCode ResponseSystemStatus::ADV_FORWARD; +const ResponseSystemStatus_NetCode ResponseSystemStatus::NetCode_MIN; +const ResponseSystemStatus_NetCode ResponseSystemStatus::NetCode_MAX; +const int ResponseSystemStatus::NetCode_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int ResponseSystemStatus::kStatusFieldNumber; +const int ResponseSystemStatus::kNoPeersFieldNumber; +const int ResponseSystemStatus::kNoConnectedFieldNumber; +const int ResponseSystemStatus::kNetStatusFieldNumber; +const int ResponseSystemStatus::kBwTotalFieldNumber; +#endif // !_MSC_VER + +ResponseSystemStatus::ResponseSystemStatus() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ResponseSystemStatus::InitAsDefaultInstance() { + status_ = const_cast< ::rsctrl::core::Status*>(&::rsctrl::core::Status::default_instance()); + bw_total_ = const_cast< ::rsctrl::core::Bandwidth*>(&::rsctrl::core::Bandwidth::default_instance()); +} + +ResponseSystemStatus::ResponseSystemStatus(const ResponseSystemStatus& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ResponseSystemStatus::SharedCtor() { + _cached_size_ = 0; + status_ = NULL; + no_peers_ = 0u; + no_connected_ = 0u; + net_status_ = 0; + bw_total_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ResponseSystemStatus::~ResponseSystemStatus() { + SharedDtor(); +} + +void ResponseSystemStatus::SharedDtor() { + if (this != default_instance_) { + delete status_; + delete bw_total_; + } +} + +void ResponseSystemStatus::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ResponseSystemStatus::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ResponseSystemStatus_descriptor_; +} + +const ResponseSystemStatus& ResponseSystemStatus::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_system_2eproto(); return *default_instance_; +} + +ResponseSystemStatus* ResponseSystemStatus::default_instance_ = NULL; + +ResponseSystemStatus* ResponseSystemStatus::New() const { + return new ResponseSystemStatus; +} + +void ResponseSystemStatus::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_status()) { + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); + } + no_peers_ = 0u; + no_connected_ = 0u; + net_status_ = 0; + if (has_bw_total()) { + if (bw_total_ != NULL) bw_total_->::rsctrl::core::Bandwidth::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ResponseSystemStatus::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.core.Status status = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_status())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_no_peers; + break; + } + + // required uint32 no_peers = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_no_peers: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &no_peers_))); + set_has_no_peers(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(24)) goto parse_no_connected; + break; + } + + // required uint32 no_connected = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_no_connected: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &no_connected_))); + set_has_no_connected(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(32)) goto parse_net_status; + break; + } + + // required .rsctrl.system.ResponseSystemStatus.NetCode net_status = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_net_status: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::rsctrl::system::ResponseSystemStatus_NetCode_IsValid(value)) { + set_net_status(static_cast< ::rsctrl::system::ResponseSystemStatus_NetCode >(value)); + } else { + mutable_unknown_fields()->AddVarint(4, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(42)) goto parse_bw_total; + break; + } + + // required .rsctrl.core.Bandwidth bw_total = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_bw_total: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_bw_total())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ResponseSystemStatus::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->status(), output); + } + + // required uint32 no_peers = 2; + if (has_no_peers()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->no_peers(), output); + } + + // required uint32 no_connected = 3; + if (has_no_connected()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->no_connected(), output); + } + + // required .rsctrl.system.ResponseSystemStatus.NetCode net_status = 4; + if (has_net_status()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 4, this->net_status(), output); + } + + // required .rsctrl.core.Bandwidth bw_total = 5; + if (has_bw_total()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 5, this->bw_total(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ResponseSystemStatus::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->status(), target); + } + + // required uint32 no_peers = 2; + if (has_no_peers()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->no_peers(), target); + } + + // required uint32 no_connected = 3; + if (has_no_connected()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->no_connected(), target); + } + + // required .rsctrl.system.ResponseSystemStatus.NetCode net_status = 4; + if (has_net_status()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 4, this->net_status(), target); + } + + // required .rsctrl.core.Bandwidth bw_total = 5; + if (has_bw_total()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 5, this->bw_total(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ResponseSystemStatus::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->status()); + } + + // required uint32 no_peers = 2; + if (has_no_peers()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->no_peers()); + } + + // required uint32 no_connected = 3; + if (has_no_connected()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->no_connected()); + } + + // required .rsctrl.system.ResponseSystemStatus.NetCode net_status = 4; + if (has_net_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->net_status()); + } + + // required .rsctrl.core.Bandwidth bw_total = 5; + if (has_bw_total()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->bw_total()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ResponseSystemStatus::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ResponseSystemStatus* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ResponseSystemStatus::MergeFrom(const ResponseSystemStatus& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_status()) { + mutable_status()->::rsctrl::core::Status::MergeFrom(from.status()); + } + if (from.has_no_peers()) { + set_no_peers(from.no_peers()); + } + if (from.has_no_connected()) { + set_no_connected(from.no_connected()); + } + if (from.has_net_status()) { + set_net_status(from.net_status()); + } + if (from.has_bw_total()) { + mutable_bw_total()->::rsctrl::core::Bandwidth::MergeFrom(from.bw_total()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ResponseSystemStatus::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ResponseSystemStatus::CopyFrom(const ResponseSystemStatus& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ResponseSystemStatus::IsInitialized() const { + if ((_has_bits_[0] & 0x0000001f) != 0x0000001f) return false; + + if (has_status()) { + if (!this->status().IsInitialized()) return false; + } + if (has_bw_total()) { + if (!this->bw_total().IsInitialized()) return false; + } + return true; +} + +void ResponseSystemStatus::Swap(ResponseSystemStatus* other) { + if (other != this) { + std::swap(status_, other->status_); + std::swap(no_peers_, other->no_peers_); + std::swap(no_connected_, other->no_connected_); + std::swap(net_status_, other->net_status_); + std::swap(bw_total_, other->bw_total_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ResponseSystemStatus::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ResponseSystemStatus_descriptor_; + metadata.reflection = ResponseSystemStatus_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace system +} // namespace rsctrl + +// @@protoc_insertion_point(global_scope) diff --git a/retroshare-nogui/src/rpc/proto/gencc/system.pb.h b/retroshare-nogui/src/rpc/proto/gencc/system.pb.h new file mode 100644 index 000000000..8a294713d --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/gencc/system.pb.h @@ -0,0 +1,494 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: system.proto + +#ifndef PROTOBUF_system_2eproto__INCLUDED +#define PROTOBUF_system_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2004000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2004001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include "core.pb.h" +// @@protoc_insertion_point(includes) + +namespace rsctrl { +namespace system { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_system_2eproto(); +void protobuf_AssignDesc_system_2eproto(); +void protobuf_ShutdownFile_system_2eproto(); + +class RequestSystemStatus; +class ResponseSystemStatus; + +enum ResponseSystemStatus_NetCode { + ResponseSystemStatus_NetCode_BAD_UNKNOWN = 0, + ResponseSystemStatus_NetCode_BAD_OFFLINE = 1, + ResponseSystemStatus_NetCode_BAD_NATSYM = 2, + ResponseSystemStatus_NetCode_BAD_NODHT_NAT = 3, + ResponseSystemStatus_NetCode_WARNING_RESTART = 4, + ResponseSystemStatus_NetCode_WARNING_NATTED = 5, + ResponseSystemStatus_NetCode_WARNING_NODHT = 6, + ResponseSystemStatus_NetCode_GOOD = 7, + ResponseSystemStatus_NetCode_ADV_FORWARD = 8 +}; +bool ResponseSystemStatus_NetCode_IsValid(int value); +const ResponseSystemStatus_NetCode ResponseSystemStatus_NetCode_NetCode_MIN = ResponseSystemStatus_NetCode_BAD_UNKNOWN; +const ResponseSystemStatus_NetCode ResponseSystemStatus_NetCode_NetCode_MAX = ResponseSystemStatus_NetCode_ADV_FORWARD; +const int ResponseSystemStatus_NetCode_NetCode_ARRAYSIZE = ResponseSystemStatus_NetCode_NetCode_MAX + 1; + +const ::google::protobuf::EnumDescriptor* ResponseSystemStatus_NetCode_descriptor(); +inline const ::std::string& ResponseSystemStatus_NetCode_Name(ResponseSystemStatus_NetCode value) { + return ::google::protobuf::internal::NameOfEnum( + ResponseSystemStatus_NetCode_descriptor(), value); +} +inline bool ResponseSystemStatus_NetCode_Parse( + const ::std::string& name, ResponseSystemStatus_NetCode* value) { + return ::google::protobuf::internal::ParseNamedEnum( + ResponseSystemStatus_NetCode_descriptor(), name, value); +} +enum RequestMsgIds { + MsgId_RequestSystemStatus = 1 +}; +bool RequestMsgIds_IsValid(int value); +const RequestMsgIds RequestMsgIds_MIN = MsgId_RequestSystemStatus; +const RequestMsgIds RequestMsgIds_MAX = MsgId_RequestSystemStatus; +const int RequestMsgIds_ARRAYSIZE = RequestMsgIds_MAX + 1; + +const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor(); +inline const ::std::string& RequestMsgIds_Name(RequestMsgIds value) { + return ::google::protobuf::internal::NameOfEnum( + RequestMsgIds_descriptor(), value); +} +inline bool RequestMsgIds_Parse( + const ::std::string& name, RequestMsgIds* value) { + return ::google::protobuf::internal::ParseNamedEnum( + RequestMsgIds_descriptor(), name, value); +} +enum ResponseMsgIds { + MsgId_ResponseSystemStatus = 1 +}; +bool ResponseMsgIds_IsValid(int value); +const ResponseMsgIds ResponseMsgIds_MIN = MsgId_ResponseSystemStatus; +const ResponseMsgIds ResponseMsgIds_MAX = MsgId_ResponseSystemStatus; +const int ResponseMsgIds_ARRAYSIZE = ResponseMsgIds_MAX + 1; + +const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor(); +inline const ::std::string& ResponseMsgIds_Name(ResponseMsgIds value) { + return ::google::protobuf::internal::NameOfEnum( + ResponseMsgIds_descriptor(), value); +} +inline bool ResponseMsgIds_Parse( + const ::std::string& name, ResponseMsgIds* value) { + return ::google::protobuf::internal::ParseNamedEnum( + ResponseMsgIds_descriptor(), name, value); +} +// =================================================================== + +class RequestSystemStatus : public ::google::protobuf::Message { + public: + RequestSystemStatus(); + virtual ~RequestSystemStatus(); + + RequestSystemStatus(const RequestSystemStatus& from); + + inline RequestSystemStatus& operator=(const RequestSystemStatus& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestSystemStatus& default_instance(); + + void Swap(RequestSystemStatus* other); + + // implements Message ---------------------------------------------- + + RequestSystemStatus* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestSystemStatus& from); + void MergeFrom(const RequestSystemStatus& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // @@protoc_insertion_point(class_scope:rsctrl.system.RequestSystemStatus) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[1]; + + friend void protobuf_AddDesc_system_2eproto(); + friend void protobuf_AssignDesc_system_2eproto(); + friend void protobuf_ShutdownFile_system_2eproto(); + + void InitAsDefaultInstance(); + static RequestSystemStatus* default_instance_; +}; +// ------------------------------------------------------------------- + +class ResponseSystemStatus : public ::google::protobuf::Message { + public: + ResponseSystemStatus(); + virtual ~ResponseSystemStatus(); + + ResponseSystemStatus(const ResponseSystemStatus& from); + + inline ResponseSystemStatus& operator=(const ResponseSystemStatus& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ResponseSystemStatus& default_instance(); + + void Swap(ResponseSystemStatus* other); + + // implements Message ---------------------------------------------- + + ResponseSystemStatus* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ResponseSystemStatus& from); + void MergeFrom(const ResponseSystemStatus& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef ResponseSystemStatus_NetCode NetCode; + static const NetCode BAD_UNKNOWN = ResponseSystemStatus_NetCode_BAD_UNKNOWN; + static const NetCode BAD_OFFLINE = ResponseSystemStatus_NetCode_BAD_OFFLINE; + static const NetCode BAD_NATSYM = ResponseSystemStatus_NetCode_BAD_NATSYM; + static const NetCode BAD_NODHT_NAT = ResponseSystemStatus_NetCode_BAD_NODHT_NAT; + static const NetCode WARNING_RESTART = ResponseSystemStatus_NetCode_WARNING_RESTART; + static const NetCode WARNING_NATTED = ResponseSystemStatus_NetCode_WARNING_NATTED; + static const NetCode WARNING_NODHT = ResponseSystemStatus_NetCode_WARNING_NODHT; + static const NetCode GOOD = ResponseSystemStatus_NetCode_GOOD; + static const NetCode ADV_FORWARD = ResponseSystemStatus_NetCode_ADV_FORWARD; + static inline bool NetCode_IsValid(int value) { + return ResponseSystemStatus_NetCode_IsValid(value); + } + static const NetCode NetCode_MIN = + ResponseSystemStatus_NetCode_NetCode_MIN; + static const NetCode NetCode_MAX = + ResponseSystemStatus_NetCode_NetCode_MAX; + static const int NetCode_ARRAYSIZE = + ResponseSystemStatus_NetCode_NetCode_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + NetCode_descriptor() { + return ResponseSystemStatus_NetCode_descriptor(); + } + static inline const ::std::string& NetCode_Name(NetCode value) { + return ResponseSystemStatus_NetCode_Name(value); + } + static inline bool NetCode_Parse(const ::std::string& name, + NetCode* value) { + return ResponseSystemStatus_NetCode_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // required .rsctrl.core.Status status = 1; + inline bool has_status() const; + inline void clear_status(); + static const int kStatusFieldNumber = 1; + inline const ::rsctrl::core::Status& status() const; + inline ::rsctrl::core::Status* mutable_status(); + inline ::rsctrl::core::Status* release_status(); + + // required uint32 no_peers = 2; + inline bool has_no_peers() const; + inline void clear_no_peers(); + static const int kNoPeersFieldNumber = 2; + inline ::google::protobuf::uint32 no_peers() const; + inline void set_no_peers(::google::protobuf::uint32 value); + + // required uint32 no_connected = 3; + inline bool has_no_connected() const; + inline void clear_no_connected(); + static const int kNoConnectedFieldNumber = 3; + inline ::google::protobuf::uint32 no_connected() const; + inline void set_no_connected(::google::protobuf::uint32 value); + + // required .rsctrl.system.ResponseSystemStatus.NetCode net_status = 4; + inline bool has_net_status() const; + inline void clear_net_status(); + static const int kNetStatusFieldNumber = 4; + inline ::rsctrl::system::ResponseSystemStatus_NetCode net_status() const; + inline void set_net_status(::rsctrl::system::ResponseSystemStatus_NetCode value); + + // required .rsctrl.core.Bandwidth bw_total = 5; + inline bool has_bw_total() const; + inline void clear_bw_total(); + static const int kBwTotalFieldNumber = 5; + inline const ::rsctrl::core::Bandwidth& bw_total() const; + inline ::rsctrl::core::Bandwidth* mutable_bw_total(); + inline ::rsctrl::core::Bandwidth* release_bw_total(); + + // @@protoc_insertion_point(class_scope:rsctrl.system.ResponseSystemStatus) + private: + inline void set_has_status(); + inline void clear_has_status(); + inline void set_has_no_peers(); + inline void clear_has_no_peers(); + inline void set_has_no_connected(); + inline void clear_has_no_connected(); + inline void set_has_net_status(); + inline void clear_has_net_status(); + inline void set_has_bw_total(); + inline void clear_has_bw_total(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::rsctrl::core::Status* status_; + ::google::protobuf::uint32 no_peers_; + ::google::protobuf::uint32 no_connected_; + ::rsctrl::core::Bandwidth* bw_total_; + int net_status_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(5 + 31) / 32]; + + friend void protobuf_AddDesc_system_2eproto(); + friend void protobuf_AssignDesc_system_2eproto(); + friend void protobuf_ShutdownFile_system_2eproto(); + + void InitAsDefaultInstance(); + static ResponseSystemStatus* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// RequestSystemStatus + +// ------------------------------------------------------------------- + +// ResponseSystemStatus + +// required .rsctrl.core.Status status = 1; +inline bool ResponseSystemStatus::has_status() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ResponseSystemStatus::set_has_status() { + _has_bits_[0] |= 0x00000001u; +} +inline void ResponseSystemStatus::clear_has_status() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ResponseSystemStatus::clear_status() { + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); + clear_has_status(); +} +inline const ::rsctrl::core::Status& ResponseSystemStatus::status() const { + return status_ != NULL ? *status_ : *default_instance_->status_; +} +inline ::rsctrl::core::Status* ResponseSystemStatus::mutable_status() { + set_has_status(); + if (status_ == NULL) status_ = new ::rsctrl::core::Status; + return status_; +} +inline ::rsctrl::core::Status* ResponseSystemStatus::release_status() { + clear_has_status(); + ::rsctrl::core::Status* temp = status_; + status_ = NULL; + return temp; +} + +// required uint32 no_peers = 2; +inline bool ResponseSystemStatus::has_no_peers() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void ResponseSystemStatus::set_has_no_peers() { + _has_bits_[0] |= 0x00000002u; +} +inline void ResponseSystemStatus::clear_has_no_peers() { + _has_bits_[0] &= ~0x00000002u; +} +inline void ResponseSystemStatus::clear_no_peers() { + no_peers_ = 0u; + clear_has_no_peers(); +} +inline ::google::protobuf::uint32 ResponseSystemStatus::no_peers() const { + return no_peers_; +} +inline void ResponseSystemStatus::set_no_peers(::google::protobuf::uint32 value) { + set_has_no_peers(); + no_peers_ = value; +} + +// required uint32 no_connected = 3; +inline bool ResponseSystemStatus::has_no_connected() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void ResponseSystemStatus::set_has_no_connected() { + _has_bits_[0] |= 0x00000004u; +} +inline void ResponseSystemStatus::clear_has_no_connected() { + _has_bits_[0] &= ~0x00000004u; +} +inline void ResponseSystemStatus::clear_no_connected() { + no_connected_ = 0u; + clear_has_no_connected(); +} +inline ::google::protobuf::uint32 ResponseSystemStatus::no_connected() const { + return no_connected_; +} +inline void ResponseSystemStatus::set_no_connected(::google::protobuf::uint32 value) { + set_has_no_connected(); + no_connected_ = value; +} + +// required .rsctrl.system.ResponseSystemStatus.NetCode net_status = 4; +inline bool ResponseSystemStatus::has_net_status() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void ResponseSystemStatus::set_has_net_status() { + _has_bits_[0] |= 0x00000008u; +} +inline void ResponseSystemStatus::clear_has_net_status() { + _has_bits_[0] &= ~0x00000008u; +} +inline void ResponseSystemStatus::clear_net_status() { + net_status_ = 0; + clear_has_net_status(); +} +inline ::rsctrl::system::ResponseSystemStatus_NetCode ResponseSystemStatus::net_status() const { + return static_cast< ::rsctrl::system::ResponseSystemStatus_NetCode >(net_status_); +} +inline void ResponseSystemStatus::set_net_status(::rsctrl::system::ResponseSystemStatus_NetCode value) { + GOOGLE_DCHECK(::rsctrl::system::ResponseSystemStatus_NetCode_IsValid(value)); + set_has_net_status(); + net_status_ = value; +} + +// required .rsctrl.core.Bandwidth bw_total = 5; +inline bool ResponseSystemStatus::has_bw_total() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void ResponseSystemStatus::set_has_bw_total() { + _has_bits_[0] |= 0x00000010u; +} +inline void ResponseSystemStatus::clear_has_bw_total() { + _has_bits_[0] &= ~0x00000010u; +} +inline void ResponseSystemStatus::clear_bw_total() { + if (bw_total_ != NULL) bw_total_->::rsctrl::core::Bandwidth::Clear(); + clear_has_bw_total(); +} +inline const ::rsctrl::core::Bandwidth& ResponseSystemStatus::bw_total() const { + return bw_total_ != NULL ? *bw_total_ : *default_instance_->bw_total_; +} +inline ::rsctrl::core::Bandwidth* ResponseSystemStatus::mutable_bw_total() { + set_has_bw_total(); + if (bw_total_ == NULL) bw_total_ = new ::rsctrl::core::Bandwidth; + return bw_total_; +} +inline ::rsctrl::core::Bandwidth* ResponseSystemStatus::release_bw_total() { + clear_has_bw_total(); + ::rsctrl::core::Bandwidth* temp = bw_total_; + bw_total_ = NULL; + return temp; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace system +} // namespace rsctrl + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::system::ResponseSystemStatus_NetCode>() { + return ::rsctrl::system::ResponseSystemStatus_NetCode_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< rsctrl::system::RequestMsgIds>() { + return rsctrl::system::RequestMsgIds_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< rsctrl::system::ResponseMsgIds>() { + return rsctrl::system::ResponseMsgIds_descriptor(); +} + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_system_2eproto__INCLUDED diff --git a/retroshare-nogui/src/rpc/proto/rpcprotopeers.cc b/retroshare-nogui/src/rpc/proto/rpcprotopeers.cc index bea75c786..7943f3248 100644 --- a/retroshare-nogui/src/rpc/proto/rpcprotopeers.cc +++ b/retroshare-nogui/src/rpc/proto/rpcprotopeers.cc @@ -25,6 +25,8 @@ #include "rpc/proto/gencc/peers.pb.h" #include +#include + #include #include @@ -45,8 +47,8 @@ int RpcProtoPeers::processMsg(uint32_t msg_id, uint32_t req_id, const std::strin bool isResponse = isRpcMsgIdResponse(msg_id); - std::cerr << "RpcProtoPeers::processMsg() topbyte: " << topbyte; - std::cerr << " service: " << service << " submsg: " << submsg; + std::cerr << "RpcProtoPeers::processMsg() topbyte: " << (int32_t) topbyte; + std::cerr << " service: " << (int32_t) service << " submsg: " << (int32_t) submsg; std::cerr << std::endl; if (isResponse) @@ -57,14 +59,14 @@ int RpcProtoPeers::processMsg(uint32_t msg_id, uint32_t req_id, const std::strin } - if (topbyte != (uint8_t) rsctrl::base::BASE) + if (topbyte != (uint8_t) rsctrl::core::CORE) { std::cerr << "RpcProtoPeers::processMsg() Extension Mismatch - not processing"; std::cerr << std::endl; return 0; } - if (service != (uint16_t) rsctrl::base::PEERS) + if (service != (uint16_t) rsctrl::core::PEERS) { std::cerr << "RpcProtoPeers::processMsg() Service Mismatch - not processing"; std::cerr << std::endl; @@ -105,7 +107,38 @@ int RpcProtoPeers::processAddPeer(uint32_t msg_id, uint32_t req_id, const std::s std::cerr << "RpcProtoPeers::processAddPeer() NOT FINISHED"; std::cerr << std::endl; - return 0; + // response. + rsctrl::peers::ResponseAddPeer resp; + bool success = false; + + if (success) + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::SUCCESS); + } + else + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::NO_IMPL_YET); + } + + + std::string outmsg; + if (!resp.SerializeToString(&outmsg)) + { + std::cerr << "RpcProtoPeers::processAddPeer() ERROR SerialiseToString()"; + std::cerr << std::endl; + return 0; + } + + // Correctly Name Message. + uint32_t out_msg_id = constructMsgId(rsctrl::core::CORE, rsctrl::core::PEERS, + rsctrl::peers::MsgId_ResponseAddPeer, true); + + // queue it. + queueResponse(out_msg_id, req_id, outmsg); + + return 1; } @@ -114,7 +147,39 @@ int RpcProtoPeers::processModifyPeer(uint32_t msg_id, uint32_t req_id, const std std::cerr << "RpcProtoPeers::processModifyPeer() NOT FINISHED"; std::cerr << std::endl; - return 0; + + // response. + rsctrl::peers::ResponseModifyPeer resp; + bool success = false; + + if (success) + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::SUCCESS); + } + else + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::NO_IMPL_YET); + } + + + std::string outmsg; + if (!resp.SerializeToString(&outmsg)) + { + std::cerr << "RpcProtoPeers::processModifyPeer() ERROR SerialiseToString()"; + std::cerr << std::endl; + return 0; + } + + // Correctly Name Message. + uint32_t out_msg_id = constructMsgId(rsctrl::core::CORE, rsctrl::core::PEERS, + rsctrl::peers::MsgId_ResponseModifyPeer, true); + + // queue it. + queueResponse(out_msg_id, req_id, outmsg); + + return 1; } @@ -135,17 +200,22 @@ int RpcProtoPeers::processRequestPeers(uint32_t msg_id, uint32_t req_id, const s // Get the list of gpg_id to generate data for. std::list ids; - bool onlyOnline = false; + bool onlyConnected = false; + bool success = true; switch(reqp.set()) { case rsctrl::peers::RequestPeers::OWNID: { + std::cerr << "RpcProtoPeers::processRequestPeers() OWNID"; + std::cerr << std::endl; std::string own_id = rsPeers->getGPGOwnId(); ids.push_back(own_id); break; } case rsctrl::peers::RequestPeers::LISTED: { + std::cerr << "RpcProtoPeers::processRequestPeers() LISTED"; + std::cerr << std::endl; /* extract ids from request (TODO) */ std::string own_id = rsPeers->getGPGOwnId(); ids.push_back(own_id); @@ -153,12 +223,16 @@ int RpcProtoPeers::processRequestPeers(uint32_t msg_id, uint32_t req_id, const s } case rsctrl::peers::RequestPeers::ALL: + std::cerr << "RpcProtoPeers::processRequestPeers() ALL"; + std::cerr << std::endl; rsPeers->getGPGAllList(ids); break; - case rsctrl::peers::RequestPeers::ONLINE: + case rsctrl::peers::RequestPeers::CONNECTED: { + std::cerr << "RpcProtoPeers::processRequestPeers() CONNECTED"; + std::cerr << std::endl; /* this ones a bit hard too */ - onlyOnline = true; + onlyConnected = true; std::list ssl_ids; std::list::const_iterator sit; rsPeers->getOnlineList(ssl_ids); @@ -176,12 +250,18 @@ int RpcProtoPeers::processRequestPeers(uint32_t msg_id, uint32_t req_id, const s break; } case rsctrl::peers::RequestPeers::FRIENDS: + std::cerr << "RpcProtoPeers::processRequestPeers() FRIENDS"; + std::cerr << std::endl; rsPeers->getGPGAcceptedList(ids); break; case rsctrl::peers::RequestPeers::SIGNED: + std::cerr << "RpcProtoPeers::processRequestPeers() SIGNED"; + std::cerr << std::endl; rsPeers->getGPGSignedList(ids); break; case rsctrl::peers::RequestPeers::VALID: + std::cerr << "RpcProtoPeers::processRequestPeers() VALID"; + std::cerr << std::endl; rsPeers->getGPGSignedList(ids); break; } @@ -215,13 +295,41 @@ int RpcProtoPeers::processRequestPeers(uint32_t msg_id, uint32_t req_id, const s continue; /* uhm.. */ } - rsctrl::base::Person *person = respp.add_peers(); - + rsctrl::core::Person *person = respp.add_peers(); /* fill in key gpg details */ + person->set_gpg_id(*git); + person->set_name(details.name); + std::cerr << "RpcProtoPeers::processRequestPeers() Adding GPGID: "; + std::cerr << *git << " name: " << details.name; + std::cerr << std::endl; - + if (details.state & RS_PEER_STATE_FRIEND) + { + person->set_relation(rsctrl::core::Person::FRIEND); + } + else + { + std::list common_friends; + rsDisc->getDiscGPGFriends(*git, common_friends); + int size = common_friends.size(); + if (size) + { + if (size > 2) + { + person->set_relation(rsctrl::core::Person::FRIEND_OF_MANY_FRIENDS); + } + else + { + person->set_relation(rsctrl::core::Person::FRIEND_OF_FRIENDS); + } + } + else + { + person->set_relation(rsctrl::core::Person::UNKNOWN); + } + } if (getLocations) { @@ -240,14 +348,66 @@ int RpcProtoPeers::processRequestPeers(uint32_t msg_id, uint32_t req_id, const s { continue; /* uhm.. */ } + if ((onlyConnected) && + (!(ssldetails.state & RS_PEER_STATE_CONNECTED))) + { + continue; + } - rsctrl::base::Location *loc = person->add_locations(); + rsctrl::core::Location *loc = person->add_locations(); + + std::cerr << "RpcProtoPeers::processRequestPeers() \t Adding Location: "; + std::cerr << *sit << " loc: " << ssldetails.location; + std::cerr << std::endl; /* fill in ssl details */ + loc->set_ssl_id(*sit); + loc->set_location(ssldetails.location); + + /* set addresses */ + rsctrl::core::IpAddr *laddr = loc->mutable_localaddr(); + laddr->set_addr(ssldetails.localAddr); + laddr->set_port(ssldetails.localPort); + + rsctrl::core::IpAddr *eaddr = loc->mutable_extaddr(); + eaddr->set_addr(ssldetails.extAddr); + eaddr->set_port(ssldetails.extPort); + + /* translate status */ + uint32_t loc_state = 0; + //dont think this state should be here. + //if (ssldetails.state & RS_PEER_STATE_FRIEND) + if (ssldetails.state & RS_PEER_STATE_ONLINE) + { + loc_state |= (uint32_t) rsctrl::core::Location::ONLINE; + } + if (ssldetails.state & RS_PEER_STATE_CONNECTED) + { + loc_state |= (uint32_t) rsctrl::core::Location::CONNECTED; + } + if (ssldetails.state & RS_PEER_STATE_UNREACHABLE) + { + loc_state |= (uint32_t) rsctrl::core::Location::UNREACHABLE; + } + + loc->set_state(loc_state); } } } + if (success) + { + rsctrl::core::Status *status = respp.mutable_status(); + status->set_code(rsctrl::core::Status::SUCCESS); + } + else + { + rsctrl::core::Status *status = respp.mutable_status(); + status->set_code(rsctrl::core::Status::FAILED); + status->set_msg("Unknown ERROR"); + } + + std::string outmsg; if (!respp.SerializeToString(&outmsg)) { @@ -257,7 +417,7 @@ int RpcProtoPeers::processRequestPeers(uint32_t msg_id, uint32_t req_id, const s } // Correctly Name Message. - uint32_t out_msg_id = constructMsgId(rsctrl::base::BASE, rsctrl::base::PEERS, + uint32_t out_msg_id = constructMsgId(rsctrl::core::CORE, rsctrl::core::PEERS, rsctrl::peers::MsgId_ResponsePeerList, true); // queue it. diff --git a/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc b/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc new file mode 100644 index 000000000..abdc7d626 --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc @@ -0,0 +1,213 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "rpc/proto/rpcprotosystem.h" +#include "rpc/proto/gencc/system.pb.h" + +#include +#include +#include + +#include +#include + +RpcProtoSystem::RpcProtoSystem(uint32_t serviceId) + :RpcQueueService(serviceId) +{ + return; +} + +//RpcProtoSystem::msgsAccepted(std::list &msgIds); /* not used at the moment */ + +int RpcProtoSystem::processMsg(uint32_t msg_id, uint32_t req_id, const std::string &msg) +{ + /* check the msgId */ + uint8_t topbyte = getRpcMsgIdExtension(msg_id); + uint16_t service = getRpcMsgIdService(msg_id); + uint8_t submsg = getRpcMsgIdSubMsg(msg_id); + bool isResponse = isRpcMsgIdResponse(msg_id); + + + std::cerr << "RpcProtoSystem::processMsg() topbyte: " << (int32_t) topbyte; + std::cerr << " service: " << (int32_t) service << " submsg: " << (int32_t) submsg; + std::cerr << std::endl; + + if (isResponse) + { + std::cerr << "RpcProtoSystem::processMsg() isResponse() - not processing"; + std::cerr << std::endl; + return 0; + } + + + if (topbyte != (uint8_t) rsctrl::core::CORE) + { + std::cerr << "RpcProtoSystem::processMsg() Extension Mismatch - not processing"; + std::cerr << std::endl; + return 0; + } + + if (service != (uint16_t) rsctrl::core::SYSTEM) + { + std::cerr << "RpcProtoSystem::processMsg() Service Mismatch - not processing"; + std::cerr << std::endl; + return 0; + } + + if (!rsctrl::system::RequestMsgIds_IsValid(submsg)) + { + std::cerr << "RpcProtoSystem::processMsg() SubMsg Mismatch - not processing"; + std::cerr << std::endl; + return 0; + } + + switch(submsg) + { + case rsctrl::system::MsgId_RequestSystemStatus: + processSystemStatus(msg_id, req_id, msg); + break; + default: + std::cerr << "RpcProtoSystem::processMsg() ERROR should never get here"; + std::cerr << std::endl; + return 0; + } + + /* must have matched id to get here */ + return 1; +} + + +int RpcProtoSystem::processSystemStatus(uint32_t msg_id, uint32_t req_id, const std::string &msg) +{ + std::cerr << "RpcProtoSystem::processSystemStatus()"; + std::cerr << std::endl; + + // parse msg. + rsctrl::system::RequestSystemStatus req; + if (!req.ParseFromString(msg)) + { + std::cerr << "RpcProtoSystem::processSystemStatus() ERROR ParseFromString()"; + std::cerr << std::endl; + return 0; + } + + // NO Options... so go straight to answer. + // response. + rsctrl::system::ResponseSystemStatus resp; + bool success = true; + + unsigned int nTotal = 0; + unsigned int nConnected = 0; + rsPeers->getPeerCount(&nTotal, &nConnected, false); + + float downKb = 0; + float upKb = 0; + rsicontrol -> ConfigGetDataRates(downKb, upKb); + + // set the data. + resp.set_no_peers(nTotal); + resp.set_no_connected(nConnected); + + rsctrl::core::Bandwidth *bw = resp.mutable_bw_total(); + bw->set_up(upKb); + bw->set_down(downKb); + bw->set_name("Total Connection Bandwidth"); + + uint32_t netState = rsConfig->getNetState(); + std::string natState("Unknown"); + rsctrl::system::ResponseSystemStatus_NetCode protoCode; + + switch(netState) + { + default: + case RSNET_NETSTATE_BAD_UNKNOWN: + protoCode = rsctrl::system::ResponseSystemStatus::BAD_UNKNOWN; + break; + + case RSNET_NETSTATE_BAD_OFFLINE: + protoCode = rsctrl::system::ResponseSystemStatus::BAD_OFFLINE; + break; + + case RSNET_NETSTATE_BAD_NATSYM: + protoCode = rsctrl::system::ResponseSystemStatus::BAD_NATSYM; + break; + + case RSNET_NETSTATE_BAD_NODHT_NAT: + protoCode = rsctrl::system::ResponseSystemStatus::BAD_NODHT_NAT; + break; + + case RSNET_NETSTATE_WARNING_RESTART: + protoCode = rsctrl::system::ResponseSystemStatus::WARNING_RESTART; + break; + + case RSNET_NETSTATE_WARNING_NATTED: + protoCode = rsctrl::system::ResponseSystemStatus::WARNING_NATTED; + break; + + case RSNET_NETSTATE_WARNING_NODHT: + protoCode = rsctrl::system::ResponseSystemStatus::WARNING_NODHT; + break; + + case RSNET_NETSTATE_GOOD: + protoCode = rsctrl::system::ResponseSystemStatus::GOOD; + break; + + case RSNET_NETSTATE_ADV_FORWARD: + protoCode = rsctrl::system::ResponseSystemStatus::ADV_FORWARD; + break; + } + + resp.set_net_status(protoCode); + + + if (success) + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::SUCCESS); + } + else + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::FAILED); + status->set_msg("Unknown ERROR"); + } + + std::string outmsg; + if (!resp.SerializeToString(&outmsg)) + { + std::cerr << "RpcProtoSystem::processSystemStatus() ERROR SerialiseToString()"; + std::cerr << std::endl; + return 0; + } + + // Correctly Name Message. + uint32_t out_msg_id = constructMsgId(rsctrl::core::CORE, rsctrl::core::SYSTEM, + rsctrl::system::MsgId_ResponseSystemStatus, true); + + // queue it. + queueResponse(out_msg_id, req_id, outmsg); + + return 1; +} + + diff --git a/retroshare-nogui/src/rpc/proto/rpcprotosystem.h b/retroshare-nogui/src/rpc/proto/rpcprotosystem.h new file mode 100644 index 000000000..57dfcb1de --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/rpcprotosystem.h @@ -0,0 +1,41 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + + +#ifndef RS_RPC_PROTO_SYSTEM_H +#define RS_RPC_PROTO_SYSTEM_H + +#include "rpc/rpcserver.h" + +class RpcProtoSystem: public RpcQueueService +{ +public: + RpcProtoSystem(uint32_t serviceId); +// virtual msgsAccepted(std::list &msgIds); /* not used at the moment */ + virtual int processMsg(uint32_t msgId, uint32_t req_id, const std::string &msg); + + virtual int processSystemStatus(uint32_t msg_id, uint32_t req_id, const std::string &msg); +}; + + +#endif /* RS_PROTO_SYSTEM_H */ diff --git a/retroshare-nogui/src/rpc/rpcsetup.cc b/retroshare-nogui/src/rpc/rpcsetup.cc index 0adc416bc..5451d7196 100644 --- a/retroshare-nogui/src/rpc/rpcsetup.cc +++ b/retroshare-nogui/src/rpc/rpcsetup.cc @@ -25,6 +25,7 @@ #include "rpc/rpcserver.h" #include "rpc/proto/rpcprotopeers.h" +#include "rpc/proto/rpcprotosystem.h" #include "rpc/rpcecho.h" @@ -37,6 +38,9 @@ RpcMediator *CreateRpcSystem(RpcComms *comms) RpcProtoPeers *peers = new RpcProtoPeers(1); server->addService(peers); + RpcProtoSystem *system = new RpcProtoSystem(1); + server->addService(system); + /* Finally an Echo Service - which will echo back any unprocesses commands. */ RpcEcho *echo = new RpcEcho(1); server->addService(echo); diff --git a/retroshare-nogui/src/ssh/rssshd.cc b/retroshare-nogui/src/ssh/rssshd.cc index 195d85af0..94b1baf59 100644 --- a/retroshare-nogui/src/ssh/rssshd.cc +++ b/retroshare-nogui/src/ssh/rssshd.cc @@ -77,7 +77,7 @@ int RsSshd::init(std::string pathrsakey) //ssh_bind_options_set(mBind, SSH_BIND_OPTIONS_DSAKEY, arg); //ssh_bind_options_set(mBind, SSH_BIND_OPTIONS_HOSTKEY, arg); ssh_bind_options_set(mBind, SSH_BIND_OPTIONS_RSAKEY, pathrsakey.c_str()); - ssh_bind_options_set(mBind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3"); + //ssh_bind_options_set(mBind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3"); mState = RSSSHD_STATE_INIT_OK; mBindState = 0; From 9d42715cad4343bba1ff75ee41267839cdec135c Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sat, 25 Aug 2012 15:48:55 +0000 Subject: [PATCH 041/222] Fixes for Gxs msg retrieval: msgId retrieval fixed, including incorrect stack mtx lock msgRelatedId retrieval fixed, mem leak removed (did not clean meta) msg data retrieval fixed added related tests RsThread::start now initialises mIsRunning to true, needed to unit tear down on gxs test system. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5471 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/gxscoreserver.cc | 7 +- libretroshare/src/gxs/rsdataservice.cc | 1 + libretroshare/src/gxs/rsgenexchange.cc | 20 ++++- libretroshare/src/gxs/rsgenexchange.h | 23 +++--- libretroshare/src/gxs/rsgxsdataaccess.cc | 93 ++++++++--------------- libretroshare/src/gxs/rsgxsdataaccess.h | 10 +-- libretroshare/src/serialiser/rsgxsitems.h | 1 + libretroshare/src/util/retrodb.cc | 2 +- libretroshare/src/util/rsthreads.h | 2 +- 9 files changed, 72 insertions(+), 87 deletions(-) diff --git a/libretroshare/src/gxs/gxscoreserver.cc b/libretroshare/src/gxs/gxscoreserver.cc index 749f96063..024e7d9df 100644 --- a/libretroshare/src/gxs/gxscoreserver.cc +++ b/libretroshare/src/gxs/gxscoreserver.cc @@ -48,10 +48,12 @@ void GxsCoreServer::run() { std::set::iterator sit; - double timeDelta = 0.2; + double timeDelta = 0.02; while(isRunning()) { + for(sit = mGxsServices.begin(); sit != mGxsServices.end(); sit++) + (*sit)->tick(); #ifndef WINDOWS_SYS usleep((int) (timeDelta * 1000000)); @@ -59,9 +61,6 @@ void GxsCoreServer::run() Sleep((int) (timeDelta * 1000)); #endif - for(sit = mGxsServices.begin(); sit != mGxsServices.end(); sit++) - (*sit)->tick(); - } } diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index a362f3bda..ce983d6b7 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -778,6 +778,7 @@ int RsDataService::retrieveNxsMsgs(const GxsMsgReq &reqIds, GxsMsgResult &msg, b { RsGxsMsgMetaData* meta = *meta_lit; delete meta; + meta_lit = msgMetaV.erase(meta_lit); } } } diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index e93c16c0a..8edfa26ff 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -551,7 +551,7 @@ void RsGenExchange::publishMsgs() { msg->metaData = new RsGxsMsgMetaData(); msg->msg.setBinData(mData, size); - *(msg->metaData) = msgItem->meta; + *(msg->metaData) = msgItem->meta; size = msg->metaData->serial_size(); char metaDataBuff[size]; @@ -560,8 +560,24 @@ void RsGenExchange::publishMsgs() ok = createMessage(msg); - if(ok) + if(ok) + { + msg->metaData->mPublishTs = time(NULL); + + // empty orig msg id means this is the original + // msg + // TODO: a non empty msgid means one should at least + // have the msg on disk, after which this msg is signed + // based on the security settings + // public grp (sign by grp public pub key, private/id: signed by + // id + if(msg->metaData->mOrigMsgId.empty()) + { + msg->metaData->mOrigMsgId = msg->metaData->mMsgId; + } + ok = mDataAccess->addMsgData(msg); + } // add to published to allow acknowledgement mMsgNotify.insert(std::make_pair(mit->first, std::make_pair(msg->grpId, msg->msgId))); diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index cf433dbaa..0ca1be9c1 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -27,6 +27,7 @@ */ #include +#include #include "rsgxs.h" #include "rsgds.h" @@ -40,6 +41,7 @@ typedef std::map > GxsMsgDataMap; typedef std::map GxsGroupDataMap; typedef std::map > GxsMsgMetaMap; + /*! * This should form the parent class to \n * all gxs services. This provides access to service's msg/grp data \n @@ -75,7 +77,6 @@ public: virtual ~RsGenExchange(); - /** S: Observer implementation **/ /*! @@ -155,7 +156,7 @@ protected: public: /*! - * This allows the client service to acknowledge that their msgs has + * This allows the client service to acknowledge that their msgs has \n * been created/modified and retrieve the create/modified msg ids * @param token the token related to modification/create request * @param msgIds map of grpid->msgIds of message created/modified @@ -164,7 +165,7 @@ public: bool acknowledgeTokenMsg(const uint32_t& token, RsGxsGrpMsgIdPair& msgId); /*! - * This allows the client service to acknowledge that their grps has + * This allows the client service to acknowledge that their grps has \n * been created/modified and retrieve the create/modified grp ids * @param token the token related to modification/create request * @param msgIds vector of ids of groups created/modified @@ -177,19 +178,21 @@ protected: /** Modifications **/ /*! - * Enables publication of a group item - * If the item exists already this is simply versioned - * This will induce a related change message - * Ownership of item passes to this rsgenexchange + * Enables publication of a group item \n + * If the item exists already this is simply versioned \n + * This will induce a related change message \n + * Ownership of item passes to this rsgenexchange \n * @param token * @param grpItem */ void publishGroup(uint32_t& token, RsGxsGrpItem* grpItem); /*! - * Enables publication of a message item - * If the item exists already this is simply versioned - * This will induce a related a change message + * Enables publication of a message item \n + * Setting mOrigMsgId meta member to blank \n + * leads to this msg being an original msg \n + * if mOrigMsgId is not blank the msgId then this msg is \n + * considered a versioned msg \n * Ownership of item passes to this rsgenexchange * @param token * @param msgItem diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index e72035217..b00454fd1 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -134,6 +134,7 @@ bool RsGxsDataAccess::requestMsgInfo(uint32_t &token, uint32_t ansType, }else if(reqType & GXS_REQUEST_TYPE_MSG_IDS) { MsgIdReq* mir = new MsgIdReq(); + mir->mMsgIds = msgIds; req = mir; } @@ -338,12 +339,12 @@ bool RsGxsDataAccess::getMsgSummary(const uint32_t& token, GxsMsgMetaResult& msg return false; }else if(req->status == GXS_REQUEST_STATUS_COMPLETE){ - MsgMetaReq* mmreq = dynamic_cast(req); + MsgMetaReq* mmreq = dynamic_cast(req); if(mmreq) { - msgInfo = mmreq->mMsgMetaData; - locked_updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + msgInfo = mmreq->mMsgMetaData; + locked_updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); }else{ std::cerr << "RsGxsDataAccess::getMsgSummary() Req found, failed caste" << std::endl; @@ -370,13 +371,19 @@ bool RsGxsDataAccess::getMsgList(const uint32_t& token, GxsMsgIdResult& msgIds) }else if(req->status == GXS_REQUEST_STATUS_COMPLETE){ MsgIdReq* mireq = dynamic_cast(req); + MsgRelatedInfoReq* mrireq = dynamic_cast(req); if(mireq) - { - msgIds = mireq->mMsgIdResult; - locked_updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - }else{ + { + msgIds = mireq->mMsgIdResult; + locked_updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + } + else if(mrireq) + { + msgIds = mrireq->mMsgIdResult; + locked_updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + } + else{ std::cerr << "RsGxsDataAccess::getMsgList() Req found, failed caste" << std::endl; return false; } @@ -388,37 +395,6 @@ bool RsGxsDataAccess::getMsgList(const uint32_t& token, GxsMsgIdResult& msgIds) return true; } -bool RsGxsDataAccess::getMsgRelatedInfo(const uint32_t &token, GxsMsgIdResult &msgIds) -{ - RsStackMutex stack(mDataMutex); - - GxsRequest* req = locked_retrieveRequest(token); - - if(req == NULL){ - - std::cerr << "RsGxsDataAccess::getMsgRelatedInfo() Unable to retrieve group data" << std::endl; - return false; - }else if(req->status == GXS_REQUEST_STATUS_COMPLETE){ - - MsgRelatedInfoReq* mrireq = dynamic_cast(req); - - if(mrireq) - { - msgIds = mrireq->mMsgIdResult; - locked_updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - }else{ - std::cerr << "RsGxsDataAccess::::getMsgRelatedInfo() Req found, failed caste" << std::endl; - return false; - } - }else{ - std::cerr << "RsGxsDataAccess::::getMsgRelatedInfo() Req not ready" << std::endl; - return false; - } - - return true; -} - bool RsGxsDataAccess::getGroupList(const uint32_t& token, std::list& groupIds) { RsStackMutex stack(mDataMutex); @@ -656,10 +632,8 @@ bool RsGxsDataAccess::getMsgRelatedInfo(MsgRelatedInfoReq* req) const RsTokReqOptionsV2& opts = req->Options; - { - RsStackMutex stack(mDataMutex); - mDataStore->retrieveGxsMsgMetaData(req->mMsgIds, result); - } + mDataStore->retrieveGxsMsgMetaData(req->mMsgIds, result); + /* CASEs this handles. @@ -764,7 +738,6 @@ bool RsGxsDataAccess::getMsgRelatedInfo(MsgRelatedInfoReq* req) for(oit = origMsgTs.begin(); oit != origMsgTs.end(); oit++) { req->mMsgIdResult[grpId].push_back(oit->second.first); - } } @@ -802,6 +775,7 @@ bool RsGxsDataAccess::getMsgRelatedInfo(MsgRelatedInfoReq* req) if (add) { req->mMsgIdResult[grpId].push_back(msgMeta->mMsgId); + metaFilter[grpId].insert(std::make_pair(msgMeta->mMsgId, msgMeta)); } } @@ -810,8 +784,10 @@ bool RsGxsDataAccess::getMsgRelatedInfo(MsgRelatedInfoReq* req) filterMsgList(req->mMsgIdResult, opts, metaFilter); - // delete the data - cleanseMetaFilter(metaFilter); + metaFilter.clear(); + + // delete meta data + cleanseMsgMetaMap(result); return true; } @@ -821,10 +797,9 @@ bool RsGxsDataAccess::getMsgList(MsgIdReq* req) GxsMsgMetaResult result; - { - RsStackMutex stack(mDataMutex); - mDataStore->retrieveGxsMsgMetaData(req->mMsgIds, result); - } + + mDataStore->retrieveGxsMsgMetaData(req->mMsgIds, result); + GxsMsgMetaResult::iterator mit = result.begin(), mit_end = result.end(); @@ -845,24 +820,22 @@ bool RsGxsDataAccess::getMsgList(MsgIdReq* req) return true; } -void RsGxsDataAccess::cleanseMetaFilter(MsgMetaFilter& filter) +void RsGxsDataAccess::cleanseMsgMetaMap(GxsMsgMetaResult& result) { - MsgMetaFilter::iterator mit = filter.begin(); + GxsMsgMetaResult::iterator mit = result.begin(); - for(; mit !=filter.end(); mit++) + for(; mit !=result.end(); mit++) { - std::map& metaM = - mit->second; - std::map::iterator mit2 - = metaM.begin(); - for(; mit2 != metaM.end(); mit2++) + std::vector& msgMetaV = mit->second; + std::vector::iterator vit = msgMetaV.begin(); + for(; vit != msgMetaV.end(); vit++) { - delete mit2->second; + delete *vit; } } - filter.clear(); + result.clear(); return; } diff --git a/libretroshare/src/gxs/rsgxsdataaccess.h b/libretroshare/src/gxs/rsgxsdataaccess.h index f67a25ec1..176d011d8 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.h +++ b/libretroshare/src/gxs/rsgxsdataaccess.h @@ -153,14 +153,6 @@ public: */ bool getMsgData(const uint32_t &token, NxsMsgDataResult& msgData); - /*! - * - * @param token request token to be redeemed - * @param msgIds - * @return false if data cannot be found for token - */ - bool getMsgRelatedInfo(const uint32_t &token, GxsMsgIdResult &msgIds); - private: /** helper functions to implement token service **/ @@ -231,7 +223,7 @@ private: * Convenience function to delete the ids * @param filter the meta filter to clean */ - void cleanseMetaFilter(MsgMetaFilter& filter); + void cleanseMsgMetaMap(GxsMsgMetaResult& result); public: diff --git a/libretroshare/src/serialiser/rsgxsitems.h b/libretroshare/src/serialiser/rsgxsitems.h index 6bf98c703..082468fc2 100644 --- a/libretroshare/src/serialiser/rsgxsitems.h +++ b/libretroshare/src/serialiser/rsgxsitems.h @@ -124,6 +124,7 @@ public: : RsItem(RS_PKT_VERSION_SERVICE, service, subtype) { return; } virtual ~RsGxsGrpItem(){} + RsGroupMetaData meta; }; diff --git a/libretroshare/src/util/retrodb.cc b/libretroshare/src/util/retrodb.cc index 2075cec45..7346cc380 100644 --- a/libretroshare/src/util/retrodb.cc +++ b/libretroshare/src/util/retrodb.cc @@ -30,7 +30,7 @@ #include "retrodb.h" -#define RETRODB_DEBUG +//#define RETRODB_DEBUG diff --git a/libretroshare/src/util/rsthreads.h b/libretroshare/src/util/rsthreads.h index 34dc098f4..7cd81a294 100644 --- a/libretroshare/src/util/rsthreads.h +++ b/libretroshare/src/util/rsthreads.h @@ -119,7 +119,7 @@ class RsThread RsThread(); virtual ~RsThread() {} -virtual void start() { createThread(*this); } +virtual void start() { mIsRunning = true; createThread(*this); } virtual void run() = 0; /* called once the thread is started */ virtual void join(); /* waits for the the mTid thread to stop */ virtual void stop(); /* calls pthread_exit() */ From a6cb2b6a3533873aedf3697532a1d13e07272920 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sat, 25 Aug 2012 17:01:13 +0000 Subject: [PATCH 042/222] fix for msg/grp meta retrieval, added service string to == operator overloads for grps and msgs added gxs updated tests, was not included mistakenly in my last update (5471) git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5472 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/serialiser/rsgxsitems.cc | 2 + .../src/tests/gxs/genexchangetester.cpp | 909 ++++++++++++++++-- .../src/tests/gxs/genexchangetester.h | 55 +- .../src/tests/gxs/genexchangetestservice.cpp | 2 +- .../src/tests/gxs/rsdummyservices.cc | 8 +- libretroshare/src/tests/gxs/rsdummyservices.h | 16 +- .../src/tests/gxs/rsgenexchange_test.cc | 19 +- .../src/tests/gxs/rsgenexhchange_test.pro | 15 +- 8 files changed, 900 insertions(+), 126 deletions(-) diff --git a/libretroshare/src/serialiser/rsgxsitems.cc b/libretroshare/src/serialiser/rsgxsitems.cc index 6b05d22fb..9f38e2496 100644 --- a/libretroshare/src/serialiser/rsgxsitems.cc +++ b/libretroshare/src/serialiser/rsgxsitems.cc @@ -22,6 +22,7 @@ this->mParentId = rGxsMeta.mParentId; this->mPublishTs = rGxsMeta.mPublishTs; this->mThreadId = rGxsMeta.mThreadId; + this->mServiceString = rGxsMeta.mServiceString; } @@ -37,4 +38,5 @@ this->mPublishTs = rGxsMeta.mPublishTs; this->mSubscribeFlags = rGxsMeta.mSubscribeFlags; this->mGroupName = rGxsMeta.mGroupName; + this->mServiceString = rGxsMeta.mServiceString; } diff --git a/libretroshare/src/tests/gxs/genexchangetester.cpp b/libretroshare/src/tests/gxs/genexchangetester.cpp index d2bf93660..203eaca0d 100644 --- a/libretroshare/src/tests/gxs/genexchangetester.cpp +++ b/libretroshare/src/tests/gxs/genexchangetester.cpp @@ -1,60 +1,203 @@ #include "genexchangetester.h" #include "support.h" +#include "gxs/rsdataservice.h" -GenExchangeTester::GenExchangeTester(GenExchangeTestService* testService) - : mTestService(testService) +GenExchangeTester::GenExchangeTester() + : mGenTestMutex("genTest") { - mTokenService = mTestService->getTokenService(); + remove("testServiceDb"); } + +void GenExchangeTester::setUp() +{ + mDataStore = new RsDataService("./", "testServiceDb", RS_SERVICE_TYPE_DUMMY, NULL); + mNxs = new RsDummyNetService(); + mTestService = new GenExchangeTestService(mDataStore, mNxs); + mGxsCore.addService(mTestService); + mTokenService = mTestService->getTokenService(); + mGxsCore.start(); +} + +void GenExchangeTester::setUpGrps() +{ + // create some random grps to allow msg testing + + RsDummyGrp* dgrp1 = new RsDummyGrp(); + RsDummyGrp* dgrp2 = new RsDummyGrp(); + RsDummyGrp* dgrp3 = new RsDummyGrp(); + init(dgrp1); + uint32_t token; + mTestService->publishDummyGrp(token, dgrp1); + + RsTokReqOptionsV2 opts; + opts.mReqType = 45000; + pollForToken(token, opts); + + RsGxsGroupId grpId; + mTestService->acknowledgeTokenGrp(token, grpId); + mRandGrpIds.push_back(grpId); + + mTestService->publishDummyGrp(token, dgrp2); + pollForToken(token, opts); + mTestService->acknowledgeTokenGrp(token, grpId); + mRandGrpIds.push_back(grpId); + + mTestService->publishDummyGrp(token, dgrp3); + pollForToken(token, opts); + mTestService->acknowledgeTokenGrp(token, grpId); + mRandGrpIds.push_back(grpId); +} + + +void GenExchangeTester::breakDown() +{ + + mGxsCore.join(); // indicate server to stop + + mGxsCore.removeService(mTestService); + delete mTestService; + + // a bit protracted, but start a new db and use to clear up junk + mDataStore = new RsDataService("./", "testServiceDb", RS_SERVICE_TYPE_DUMMY, NULL); + mDataStore->resetDataStore(); + delete mDataStore; + mTokenService = NULL; + // remove data base file + remove("testServiceDb"); + + // clear up all latent data + GxsMsgDataMap::iterator gmd_mit = mMsgDataIn.begin(); + + for(; gmd_mit != mMsgDataIn.end(); gmd_mit++) + { + std::vector& msgV = gmd_mit->second; + std::vector::iterator vit = msgV.begin(); + + for(; vit != msgV.end(); vit++) + { + delete *vit; + } + } + mMsgDataIn.clear(); + + gmd_mit = mMsgDataOut.begin(); + + for(; gmd_mit != mMsgDataOut.end(); gmd_mit++) + { + std::vector& msgV = gmd_mit->second; + std::vector::iterator vit = msgV.begin(); + + for(; vit != msgV.end(); vit++) + { + delete *vit; + } + } + + mMsgDataOut.clear(); + + std::vector::iterator g_mit = mGrpDataIn.begin(); + + for(; g_mit != mGrpDataIn.end(); g_mit++) + { + delete *g_mit; + } + + mGrpDataIn.clear(); + g_mit = mGrpDataOut.begin(); + + for(; g_mit != mGrpDataOut.end(); g_mit++) + { + delete *g_mit; + } + mGrpDataOut.clear(); + + + // these don't hold any dynamic memory + mGrpIdsIn.clear(); + mGrpIdsOut.clear(); + mMsgIdsIn.clear(); + mMsgIdsOut.clear(); + mRandGrpIds.clear(); + mMsgMetaDataIn.clear(); + mMsgMetaDataOut.clear(); + mGrpMetaDataIn.clear(); + mGrpMetaDataOut.clear(); +} + + bool GenExchangeTester::testMsgSubmissionRetrieval() { + + // start up + setUp(); + setUpGrps(); + + /********************/ + RsDummyMsg* msg = new RsDummyMsg(); init(msg); + + msg->meta.mGroupId = mRandGrpIds[(rand()%3)]; uint32_t token; + RsDummyMsg* msgOut = new RsDummyMsg(); + *msgOut = *msg; mTestService->publishDummyMsg(token, msg); // poll will block until found - pollForToken(token); + RsTokReqOptionsV2 opts; + opts.mReqType = 4200; + pollForToken(token, opts); + RsGxsGrpMsgIdPair msgId; - if(mMsgIdsIn.empty()) + mTestService->acknowledgeTokenMsg(token, msgId); + + // add msg sent to msg out + msgOut->meta.mMsgId = msgId.second; + std::vector msgDataV; + msgDataV.push_back(msgOut); + mMsgDataOut[msgId.first] = msgDataV; + + if(msgId.first.empty() || msgId.second.empty()){ + breakDown(); return false; - - RsGxsMessageId& msgId = mMsgIdsIn.begin()->second; - RsGxsGroupId& grpId = mMsgIdsIn.begin()->first; + } GxsMsgReq req; - req.insert(std::make_pair(msgId, grpId)); + std::vector msgV; + msgV.push_back(msgId.second); + req.insert(std::make_pair(msgId.first, msgV)); - RsTokReqOptionsV2 opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - mTokenService->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, req); + mTokenService->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, req); // poll again - pollForToken(token); - - mTestService->getMsgDataTS(token, mMsgDataIn); + pollForToken(token, opts); bool ok = true; - if(mMsgDataIn.size() != mMsgDataOut.size()) return false; + if(mMsgDataIn.size() != mMsgDataOut.size()) + { + breakDown(); + return false; + } GxsMsgDataMap::iterator mit = mMsgDataOut.begin(); for(; mit != mMsgDataOut.end(); mit++) { - const RsGxsGroupId& gId = mit->first; + const RsGxsGroupId& grpId = mit->first; std::vector& msgV_1 = mit->second, msgV_2 = mMsgDataIn[grpId]; std::vector::iterator vit1, vit2; - for(vit1 = msgV_1.begin(); vit1 = msgV_1.end(); + for(vit1 = msgV_1.begin(); vit1 != msgV_1.end(); vit1++) { RsDummyMsg* lMsg = dynamic_cast(*vit1); - for(vit2 = msgV_2.begin(); vit2 = msgV_2.end(); + for(vit2 = msgV_2.begin(); vit2 != msgV_2.end(); vit2++) { RsDummyMsg* rMsg = dynamic_cast(*vit2); @@ -64,28 +207,627 @@ bool GenExchangeTester::testMsgSubmissionRetrieval() } } - } + /********************/ + + // complete + breakDown(); + return ok; } bool GenExchangeTester::testMsgIdRetrieval() { - return false; + + // start up + setUp(); + setUpGrps(); + + /********************/ + + // first create several msgs for 3 different groups (the "this" rand groups) + // and store them + + // then make all requests immediately then poll afterwards for each and run outbound test + // we want only latest for now + int nMsgs = (rand()%121)+2; // test a large number of msgs + std::vector msgs; + createMsgs(msgs, nMsgs); + RsTokReqOptionsV2 opts; + opts.mReqType = 4000; + uint32_t token; + + std::vector tokenV; + for(int i=0; i < nMsgs; i++) + { + mTestService->publishDummyMsg(token, msgs[i]); + tokenV.push_back(token); + } + + for(int i=0; i < nMsgs; i++) + { + pollForToken(tokenV[i], opts); + RsGxsGrpMsgIdPair msgId; + mTestService->acknowledgeTokenMsg(tokenV[i], msgId); + mMsgIdsOut[msgId.first].push_back(msgId.second); + } + + // now do ask of all msg ids + + GxsMsgReq req; + opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; + + // use empty grp ids request types, non specific msgs ids + for(int i=0; i < mRandGrpIds.size(); i++) + { + req[mRandGrpIds[i]] = std::vector(); + } + + mTokenService->requestMsgInfo(token, 0, opts, req); + + pollForToken(token, opts); + + GxsMsgIdResult::iterator mit = mMsgIdsOut.begin(); + for(; mit != mMsgIdsOut.end(); mit++) + { + std::vector msgIdsOut, msgIdsIn; + msgIdsOut = mit->second; + + std::vector::iterator vit_out = msgIdsOut.begin(), vit_in; + + for(; vit_out != msgIdsOut.end(); vit_out++) + { + bool found = false; + msgIdsIn = mMsgIdsIn[mit->first]; + vit_in = msgIdsIn.begin(); + + for(; vit_in != msgIdsIn.end(); vit_in++) + { + if(*vit_in == *vit_out) + found = true; + } + + if(!found){ + breakDown(); + return false; + } + + } + } + + /********************/ + + // complete + breakDown(); + + return true; } -bool GenExchangeTester::testSpecificMsgRetrieval() +bool GenExchangeTester::testSpecificMsgMetaRetrieval() { - return false; + + + // start up + setUp(); + setUpGrps(); + + /********************/ + + RsDummyMsg* msg = new RsDummyMsg(); + init(msg); + + msg->meta.mGroupId = mRandGrpIds[(rand()%3)]; + uint32_t token; + RsMsgMetaData msgMetaOut; + msgMetaOut = msg->meta; + mTestService->publishDummyMsg(token, msg); + + // poll will block until found + RsTokReqOptionsV2 opts; + opts.mReqType = 4200; + pollForToken(token, opts); + RsGxsGrpMsgIdPair msgId; + + mTestService->acknowledgeTokenMsg(token, msgId); + + // add msg sent to msg out + msgMetaOut.mMsgId = msgId.second; + + std::vector msgMetaDataV; + msgMetaDataV.push_back(msgMetaOut); + mMsgMetaDataOut[msgId.first] = msgMetaDataV; + + if(msgId.first.empty() || msgId.second.empty()){ + breakDown(); + return false; + } + + GxsMsgReq req; + std::vector msgV; + msgV.push_back(msgId.second); + req.insert(std::make_pair(msgId.first, msgV)); + + opts.mReqType = GXS_REQUEST_TYPE_MSG_META; + mTokenService->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, req); + + // poll again + pollForToken(token, opts); + + bool ok = true; + + if(mMsgMetaDataIn.size() != mMsgMetaDataOut.size()) + { + breakDown(); + return false; + } + + GxsMsgMetaMap::iterator mit = mMsgMetaDataOut.begin(); + + for(; mit != mMsgMetaDataOut.end(); mit++) + { + const RsGxsGroupId& grpId = mit->first; + + std::vector& msgV_1 = mit->second, + msgV_2 = mMsgMetaDataIn[grpId]; + std::vector::iterator vit1, vit2; + + for(vit1 = msgV_1.begin(); vit1 != msgV_1.end(); + vit1++) + { + bool found = false; + const RsMsgMetaData& lMsgMeta = *vit1; + for(vit2 = msgV_2.begin(); vit2 != msgV_2.end(); + vit2++) + { + const RsMsgMetaData& rMsgMeta = *vit2; + + if(rMsgMeta.mMsgId == lMsgMeta.mMsgId){ + found = true; + ok &= rMsgMeta == lMsgMeta; + } + + } + + if(!found) + { + breakDown(); + return false; + } + + } + } + + /********************/ + + // complete + breakDown(); + + return ok; } +bool GenExchangeTester::testRelatedMsgIdRetrieval_Parents() +{ + // start up + setUp(); + setUpGrps(); + + /********************/ + + + // create msgs + // then make all requests immediately then poll afterwards for each and run outbound test + // we want only latest for now + int nMsgs = (rand()%50)+2; // test a large number of msgs + std::vector msgs; + createMsgs(msgs, nMsgs); + RsTokReqOptionsV2 opts; + opts.mReqType = 4000; + uint32_t token; + + + for(int i=0; i < nMsgs; i++) + { + RsDummyMsg* msg = msgs[i]; + + int j = rand()%5; + + + if(j<3) + msg->meta.mParentId = ""; + + mTestService->publishDummyMsg(token, msg); + pollForToken(token, opts); + RsGxsGrpMsgIdPair msgId; + mTestService->acknowledgeTokenMsg(token, msgId); + + if(msgId.first.empty() || msgId.second.empty()) + { + breakDown(); + std::cerr << "serious error: Acknowledgement failed! " << std::endl; + return false; + } + + if(j<3) + mMsgIdsOut[msgId.first].push_back(msgId.second); + + } + + GxsMsgReq req; + + // use empty grp ids request types, non specific msgs ids + for(int i=0; i < mRandGrpIds.size(); i++) + { + req[mRandGrpIds[i]] = std::vector(); + } + + opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; + opts.mOptions = RS_TOKREQOPT_MSG_THREAD; + mTokenService->requestMsgRelatedInfo(token, 0, opts, req); + + pollForToken(token, opts); + + GxsMsgIdResult::iterator mit = mMsgIdsOut.begin(); + for(; mit != mMsgIdsOut.end(); mit++) + { + std::vector msgIdsOut, msgIdsIn; + msgIdsOut = mit->second; + + std::vector::iterator vit_out = msgIdsOut.begin(), vit_in; + + for(; vit_out != msgIdsOut.end(); vit_out++) + { + bool found = false; + msgIdsIn = mMsgIdsIn[mit->first]; + vit_in = msgIdsIn.begin(); + + for(; vit_in != msgIdsIn.end(); vit_in++) + { + if(*vit_in == *vit_out) + found = true; + } + + if(!found){ + breakDown(); + return false; + } + + } + } + + /********************/ + + // complete + breakDown(); + + return true; + +} + +bool GenExchangeTester::testRelatedMsgIdRetrieval_OrigMsgId() +{ + // start up + setUp(); + setUpGrps(); + + /********************/ + + + // create msgs + // then make all requests immediately then poll afterwards for each and run outbound test + // we want only latest for now + int nMsgs = (rand()%50)+2; // test a large number of msgs + std::vector msgs; + createMsgs(msgs, nMsgs); + RsTokReqOptionsV2 opts; + opts.mReqType = 4000; + uint32_t token; + + + for(int i=0; i < nMsgs; i++) + { + RsDummyMsg* msg = msgs[i]; + + int j = rand()%5; + + if(j<3) + msg->meta.mOrigMsgId = ""; + + mTestService->publishDummyMsg(token, msg); + pollForToken(token, opts); + RsGxsGrpMsgIdPair msgId; + mTestService->acknowledgeTokenMsg(token, msgId); + + if(msgId.first.empty() || msgId.second.empty()) + { + breakDown(); + std::cerr << "serious error: Acknowledgement failed! " << std::endl; + return false; + } + + if(j<3) + mMsgIdsOut[msgId.first].push_back(msgId.second); + + } + + GxsMsgReq req; + + // use empty grp ids request types, non specific msgs ids + for(int i=0; i < mRandGrpIds.size(); i++) + { + req[mRandGrpIds[i]] = std::vector(); + } + + opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; + opts.mOptions = RS_TOKREQOPT_MSG_ORIGMSG; + mTokenService->requestMsgRelatedInfo(token, 0, opts, req); + + pollForToken(token, opts); + + GxsMsgIdResult::iterator mit = mMsgIdsOut.begin(); + for(; mit != mMsgIdsOut.end(); mit++) + { + std::vector msgIdsOut, msgIdsIn; + msgIdsOut = mit->second; + + std::vector::iterator vit_out = msgIdsOut.begin(), vit_in; + + for(; vit_out != msgIdsOut.end(); vit_out++) + { + bool found = false; + msgIdsIn = mMsgIdsIn[mit->first]; + vit_in = msgIdsIn.begin(); + + for(; vit_in != msgIdsIn.end(); vit_in++) + { + if(*vit_in == *vit_out) + found = true; + } + + if(!found){ + breakDown(); + return false; + } + + } + } + + /********************/ + + // complete + breakDown(); + + return true; +} + + +bool GenExchangeTester::testRelatedMsgIdRetrieval_Latest() +{ + + // testing for latest, create msg which are origMsgIds then + // create another batch and select random msgs again to have + // id of the other, so selecting latest msg should only come up + // with this batch of msgs for the grp plus the others not selected + // start up + setUp(); + setUpGrps(); + + /********************/ + + + // create msgs which will be used later to set orig msg ids of latest msgs + int nMsgs = (rand()%50)+2; // test a large number of msgs + std::vector msgs; + createMsgs(msgs, nMsgs); + RsTokReqOptionsV2 opts; + opts.mReqType = 4000; + uint32_t token; + + + for(int i=0; i < nMsgs; i++) + { + RsDummyMsg* msg = msgs[i]; + + int j = rand()%5; + + if(j<3) + msg->meta.mOrigMsgId = ""; + + mTestService->publishDummyMsg(token, msg); + pollForToken(token, opts); + RsGxsGrpMsgIdPair msgId; + mTestService->acknowledgeTokenMsg(token, msgId); + + if(msgId.first.empty() || msgId.second.empty()) + { + breakDown(); + std::cerr << "serious error: Acknowledgement failed! " << std::endl; + return false; + } + + if(j<3) + mMsgIdsOut[msgId.first].push_back(msgId.second); + + } + + + /** just in case put it to sleep so publish time is sufficiently different **/ + + double timeDelta = 2.; + +#ifndef WINDOWS_SYS + usleep((int) (timeDelta * 1000000)); +#else + Sleep((int) (timeDelta * 1000)); +#endif + + + /* now to create the later msgs */ + + nMsgs = (rand()%50)+2; // test a large number of msgs + msgs.clear(); + createMsgs(msgs, nMsgs); + opts.mReqType = 4000; + + // fist transfer to grpID->msgId(Set) pair in + // order to remove used msgs, that is + // msgs who ids have been used for orig id so not expected in result set + GxsMsgIdResult::iterator mit = mMsgIdsOut.begin(); + std::map > msgIdOutTemp; + + for(; mit != mMsgIdsOut.end(); mit++) + { + std::vector msgIdsOut; + msgIdsOut = mit->second; + std::vector::iterator vit = msgIdsOut.begin(); + + for(; vit != msgIdsOut.end(); vit++) + msgIdOutTemp[mit->first].insert(*vit); + } + + mMsgIdsOut.clear(); // to be repopulated later with expected result set + + std::vector::iterator vit = msgs.begin(); + + // loop over newly create msgs and assign a msg ids + // to origmsg id field from previously published msgs + for(; vit != msgs.end();) + { + RsDummyMsg* msg = *vit; + + // first find grp + const RsGxsGroupId& grpId = msg->meta.mGroupId; + + // if grp does not exist then don't pub msg + if(msgIdOutTemp.find(grpId) == msgIdOutTemp.end()){ + delete msg; + vit = msgs.erase(vit); + continue; + }else{ + + // now assign msg a rand msgId + std::set& msgIdS = msgIdOutTemp[grpId]; + + std::set::iterator sit = msgIdS.begin(); + std::vector tempMsgV; + + // store in vect for convenience + for(; sit != msgIdS.end(); sit++) + tempMsgV.push_back(*sit); + + if(tempMsgV.size() == 0) + { + delete msg; + vit = msgs.erase(vit); + continue; + } + int j = rand()%tempMsgV.size(); + + msg->meta.mOrigMsgId = tempMsgV[j]; + msgIdS.erase(tempMsgV[j]); // remove msg as it has been used + } + + // go on and publish msg + mTestService->publishDummyMsg(token, msg); + pollForToken(token, opts); + RsGxsGrpMsgIdPair msgId; + mTestService->acknowledgeTokenMsg(token, msgId); + + if(msgId.first.empty() || msgId.second.empty()) + { + breakDown(); + std::cerr << "serious error: Acknowledgement failed! " << std::endl; + return false; + } + + mMsgIdsOut[msgId.first].push_back(msgId.second); + vit++; + } + + // now add back unused msgs + std::map >::iterator mit_id_temp = msgIdOutTemp.begin(); + + for(; mit_id_temp != msgIdOutTemp.end(); mit_id_temp++){ + + std::set& idSet = mit_id_temp->second; + std::set::iterator sit = idSet.begin(); + + for(; sit != idSet.end(); sit++) + { + mMsgIdsOut[mit_id_temp->first].push_back(*sit); + } + } + + + // use empty grp ids request types, non specific msgs ids + GxsMsgReq req; + for(int i=0; i < mRandGrpIds.size(); i++) + { + req[mRandGrpIds[i]] = std::vector(); + } + + opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST; + mTokenService->requestMsgRelatedInfo(token, 0, opts, req); + + pollForToken(token, opts); + + mit = mMsgIdsOut.begin(); + for(; mit != mMsgIdsOut.end(); mit++) + { + std::vector msgIdsOut, msgIdsIn; + msgIdsOut = mit->second; + + std::vector::iterator vit_out = msgIdsOut.begin(), vit_in; + + for(; vit_out != msgIdsOut.end(); vit_out++) + { + bool found = false; + msgIdsIn = mMsgIdsIn[mit->first]; + vit_in = msgIdsIn.begin(); + + for(; vit_in != msgIdsIn.end(); vit_in++) + { + if(*vit_in == *vit_out) + found = true; + } + + if(!found){ + breakDown(); + return false; + } + + } + } + + /********************/ + + // complete + breakDown(); + + return true; +} + +void GenExchangeTester::createMsgs(std::vector &msgs, int nMsgs) const +{ + for(int i = 0; i < nMsgs; i++) + { + RsDummyMsg* msg = new RsDummyMsg(); + init(msg); + msgs.push_back(msg); + int j = (rand()%3); + msg->meta.mGroupId = mRandGrpIds[j]; + } +} + + + bool GenExchangeTester::testGrpIdRetrieval() { return false; } -bool GenExchangeTester::testGrpStatusRequest() +bool GenExchangeTester::testGrpMetaModRequest() { return false; } @@ -93,66 +835,66 @@ bool GenExchangeTester::testGrpStatusRequest() // helper functions -void GenExchangeTester::storeMsgData(GxsMsgDataMap &msgData) -{ - -} - -void GenExchangeTester::storeGrpData(GxsMsgDataMap &grpData) -{ - -} - -void GenExchangeTester::storeGrpId(GxsMsgIdResult &grpIds) -{ - +void GenExchangeTester::storeGrpMeta(std::list &grpMetaData){ + mGrpMetaDataIn = grpMetaData; } void GenExchangeTester::storeMsgData(GxsMsgDataMap &msgData) { + mMsgDataIn = msgData; + +} + +void GenExchangeTester::storeGrpData(std::vector &grpData) +{ + mGrpDataIn = grpData; +} + +void GenExchangeTester::storeGrpId(std::list &grpIds) +{ + mGrpIdsIn = grpIds; } void GenExchangeTester::storeMsgMeta(GxsMsgMetaMap &msgMetaData) { - + mMsgMetaDataIn = msgMetaData; } void GenExchangeTester::storeMsgIds(GxsMsgIdResult &msgIds) { - + mMsgIdsIn = msgIds; } -void GenExchangeTester::init(RsGroupMetaData &grpMeta) +void GenExchangeTester::init(RsGroupMetaData &grpMeta) const { - } -void GenExchangeTester::init(RsMsgMetaData &msgMeta) +void GenExchangeTester::init(RsMsgMetaData &msgMeta) const { - randString(LARGE_STR, msgMeta.mAuthorId); - randString(LARGE_STR, msgMeta.mMsgName); - randString(LARGE_STR, msgMeta.mServiceString); - randString(LARGE_STR, msgMeta.mOrigMsgId); - randString(LARGE_STR, msgMeta.mParentId); - randString(LARGE_STR, msgMeta.mThreadId); - randString(LARGE_STR, msgMeta.mGroupId); + randString(SHORT_STR, msgMeta.mAuthorId); + randString(SHORT_STR, msgMeta.mMsgName); + randString(SHORT_STR, msgMeta.mServiceString); + randString(SHORT_STR, msgMeta.mOrigMsgId); + randString(SHORT_STR, msgMeta.mParentId); + randString(SHORT_STR, msgMeta.mThreadId); + randString(SHORT_STR, msgMeta.mGroupId); - randNum(msgMeta.mChildTs); - randNum(msgMeta.mMsgStatus); - randNum(msgMeta.mMsgFlags); - randNum(msgMeta.mPublishTs); + msgMeta.mChildTs = randNum(); + msgMeta.mMsgStatus = randNum(); + msgMeta.mMsgFlags = randNum(); + msgMeta.mPublishTs = randNum(); } -void randNum(uint32_t& num) +uint32_t GenExchangeTester::randNum() const { - num = rand()%23562424; + return rand()%23562424; } -bool GenExchangeTester::operator ==(const RsMsgMetaData& lMeta, const RsMsgMetaData& rMeta) +bool operator ==(const RsMsgMetaData& lMeta, const RsMsgMetaData& rMeta) { if(lMeta.mAuthorId != rMeta.mAuthorId) return false; @@ -164,8 +906,9 @@ bool GenExchangeTester::operator ==(const RsMsgMetaData& lMeta, const RsMsgMetaD if(lMeta.mMsgStatus != rMeta.mMsgStatus) return false; if(lMeta.mOrigMsgId != rMeta.mOrigMsgId) return false; if(lMeta.mParentId != rMeta.mParentId) return false; - if(lMeta.mPublishTs != rMeta.mPublishTs) return false; + //if(lMeta.mPublishTs != rMeta.mPublishTs) return false; // don't compare this as internally set in gxs if(lMeta.mThreadId != rMeta.mThreadId) return false; + if(lMeta.mServiceString != rMeta.mServiceString) return false; return true; } @@ -178,18 +921,18 @@ bool operator ==(const RsDummyMsg& lMsg, const RsDummyMsg& rMsg) return true; } -void GenExchangeTester::init(RsGxsGrpItem *grpItem) +void GenExchangeTester::init(RsDummyGrp *grpItem) const { } -void GenExchangeTester::init(RsDummyMsg *msgItem) +void GenExchangeTester::init(RsDummyMsg *msgItem) const { - randString(LARGE_STR, msgItem->msgData); + randString(SHORT_STR, msgItem->msgData); init(msgItem->meta); } -void GenExchangeTester::pollForToken(uint32_t token) +void GenExchangeTester::pollForToken(uint32_t token, const RsTokReqOptionsV2 &opts) { double timeDelta = 0.2; @@ -204,31 +947,29 @@ void GenExchangeTester::pollForToken(uint32_t token) if(RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE == mTokenService->requestStatus(token)) { + switch(opts.mReqType) + { + case GXS_REQUEST_TYPE_GROUP_DATA: + mTestService->getGroupDataTS(token, mGrpDataIn); + break; + case GXS_REQUEST_TYPE_GROUP_META: + mTestService->getGroupMetaTS(token, mGrpMetaDataIn); + break; + case GXS_REQUEST_TYPE_GROUP_IDS: + mTestService->getGroupListTS(token, mGrpIdsIn); + break; + case GXS_REQUEST_TYPE_MSG_DATA: + mTestService->getMsgDataTS(token, mMsgDataIn); + break; + case GXS_REQUEST_TYPE_MSG_META: + mTestService->getMsgMetaTS(token, mMsgMetaDataIn); + break; + case GXS_REQUEST_TYPE_MSG_IDS: + mTestService->getMsgListTS(token, mMsgIdsIn); + break; + } break; } + } } - -void GenExchangeTester::setUp() -{ - -} - -void GenExchangeTester::setUpGrps() -{ - -} - -void GenExchangeTester::breakDown() -{ - -} - - - - - - - - - diff --git a/libretroshare/src/tests/gxs/genexchangetester.h b/libretroshare/src/tests/gxs/genexchangetester.h index 6378e1ae6..392fc4338 100644 --- a/libretroshare/src/tests/gxs/genexchangetester.h +++ b/libretroshare/src/tests/gxs/genexchangetester.h @@ -2,6 +2,12 @@ #define GENEXCHANGETESTER_H #include "genexchangetestservice.h" +#include "gxs/rsgds.h" +#include "gxs/rsnxs.h" +#include "gxs/gxscoreserver.h" + +bool operator ==(const RsMsgMetaData& lMeta, const RsMsgMetaData& rMeta); +bool operator ==(const RsDummyMsg& lMsg, const RsDummyMsg& rMsg); /*! * The job of the service tester is to send dummy msg items to the GenExchange service @@ -12,20 +18,24 @@ class GenExchangeTester { public: - void pollForToken(uint32_t); + void pollForToken(uint32_t, const RsTokReqOptionsV2& opts); - GenExchangeTester(GenExchangeTestService* testService); + GenExchangeTester(); bool testMsgSubmissionRetrieval(); bool testMsgIdRetrieval(); - bool testSpecificMsgRetrieval(); + bool testRelatedMsgIdRetrieval_Parents(); + bool testRelatedMsgIdRetrieval_OrigMsgId(); + bool testRelatedMsgIdRetrieval_Latest(); + bool testSpecificMsgMetaRetrieval(); bool testGrpSubmissionRetrieval(); bool testSpecificGrpRetrieval(); bool testGrpIdRetrieval(); + bool testGrpMetaRetrieval(); - bool testGrpSubscribeRequest(); - bool testGrpStatusRequest(); + bool testGrpMetaModRequest(); + bool testMsgMetaModRequest(); private: @@ -42,34 +52,45 @@ private: void storeMsgMeta(GxsMsgMetaMap& msgMetaData); void storeMsgIds(GxsMsgIdResult& msgIds); - void storeGrpData(GxsMsgDataMap& grpData); - void storeGrpMeta(GxsMsgMetaMap& grpMetaData); - void storeGrpId(GxsMsgIdResult& grpIds); + void storeGrpData(std::vector& grpData); + void storeGrpMeta(std::list& grpMetaData); + void storeGrpId(std::list& grpIds); - void init(RsDummyGrp* grpItem); - void init(RsGroupMetaData&); - void init(RsDummyMsg* msgItem); - void init(RsMsgMetaData&); + void init(RsDummyGrp* grpItem) const; + void init(RsGroupMetaData&) const; + void init(RsDummyMsg* msgItem) const; + void init(RsMsgMetaData&) const; - bool operator ==(const RsMsgMetaData& lMeta, const RsMsgMetaData& rMeta); - bool operator ==(const RsDummyMsg& lMsg, const RsDummyMsg& rMsg); + uint32_t randNum() const; +private: + + void createMsgs(std::vector& msgs, int nMsgs) const; private: + RsMutex mGenTestMutex; - GxsMsgDataMap mGrpDataOut, mGrpDataIn; - GxsMsgMetaMap mGrpMetaDataOut, mGrpMetaDataIn; - GxsMsgIdResult mGrpIdsOut, mGrpIdsIn; + std::vector mGrpDataOut, mGrpDataIn; + std::list mGrpMetaDataOut, mGrpMetaDataIn; + std::list mGrpIdsOut, mGrpIdsIn; GxsMsgDataMap mMsgDataOut, mMsgDataIn; GxsMsgMetaMap mMsgMetaDataOut, mMsgMetaDataIn; GxsMsgIdResult mMsgIdsOut, mMsgIdsIn; + std::vector mRandGrpIds; // ids that exist to help group testing + private: GenExchangeTestService* mTestService; RsTokenServiceV2* mTokenService; + + RsNetworkExchangeService* mNxs; + RsGeneralDataService* mDataStore; + + GxsCoreServer mGxsCore; + }; #endif // GENEXCHANGETESTER_H diff --git a/libretroshare/src/tests/gxs/genexchangetestservice.cpp b/libretroshare/src/tests/gxs/genexchangetestservice.cpp index 6051c19be..461c872ef 100644 --- a/libretroshare/src/tests/gxs/genexchangetestservice.cpp +++ b/libretroshare/src/tests/gxs/genexchangetestservice.cpp @@ -1,7 +1,7 @@ #include "genexchangetestservice.h" GenExchangeTestService::GenExchangeTestService(RsGeneralDataService *dataServ, RsNetworkExchangeService * netService) - : RsGenExchange(dataServ, netService) + : RsGenExchange(dataServ, netService, new RsDummySerialiser(), RS_SERVICE_TYPE_DUMMY) { } diff --git a/libretroshare/src/tests/gxs/rsdummyservices.cc b/libretroshare/src/tests/gxs/rsdummyservices.cc index 07eb1a7e5..4d8dd4984 100644 --- a/libretroshare/src/tests/gxs/rsdummyservices.cc +++ b/libretroshare/src/tests/gxs/rsdummyservices.cc @@ -69,7 +69,7 @@ RsItem* RsDummySerialiser::deserialise(void *data, uint32_t *size) uint32_t RsDummySerialiser::sizeDummyMsgItem(RsDummyMsg *item) { - s += 8; // header + uint32_t s = 8; // header s += GetTlvStringSize(item->msgData); return s; @@ -135,7 +135,7 @@ RsDummyMsg * RsDummySerialiser::deserialiseDummyMsgItem(void *data, uint32_t /* skip the header */ offset += 8; - ok &= GetTlvString(data, *size, offset, 1, item->msgData); + ok &= GetTlvString(data, *size, &offset, 1, item->msgData); if (!ok) { @@ -148,7 +148,7 @@ RsDummyMsg * RsDummySerialiser::deserialiseDummyMsgItem(void *data, uint32_t uint32_t RsDummySerialiser::sizeDummyGrpItem(RsDummyGrp *item) { - s += 8; + uint32_t s = 8; s += GetTlvStringSize(item->grpData); return s; @@ -212,7 +212,7 @@ RsDummyGrp * RsDummySerialiser::deserialiseDummyGrpItem(void *data, uint32_t /* skip the header */ offset += 8; - ok &= GetTlvString(data, *size, offset, 1, item->grpData); + ok &= GetTlvString(data, *size, &offset, 1, item->grpData); if (!ok) { diff --git a/libretroshare/src/tests/gxs/rsdummyservices.h b/libretroshare/src/tests/gxs/rsdummyservices.h index c4ae37d64..854c6b4c8 100644 --- a/libretroshare/src/tests/gxs/rsdummyservices.h +++ b/libretroshare/src/tests/gxs/rsdummyservices.h @@ -11,7 +11,7 @@ class RsDummyNetService: public RsNetworkExchangeService { public: - RsNetworkExchangeService(){ return;} + RsDummyNetService(){ return;} void setSyncAge(uint32_t age){} @@ -28,16 +28,16 @@ public: -uint16_t RS_SERVICE_TYPE_DUMMY = 0x01; -uint8_t RS_PKT_SUBTYPE_DUMMY_MSG = 0x02; -uint8_t RS_PKT_SUBTYPE_DUMMY_GRP = 0x03; +const uint16_t RS_SERVICE_TYPE_DUMMY = 0x01; +const uint8_t RS_PKT_SUBTYPE_DUMMY_MSG = 0x02; +const uint8_t RS_PKT_SUBTYPE_DUMMY_GRP = 0x03; class RsDummyMsg : public RsGxsMsgItem { public: RsDummyMsg() : RsGxsMsgItem(RS_SERVICE_TYPE_DUMMY, RS_PKT_SUBTYPE_DUMMY_MSG) { return; } - virtual RsDummyMsg() { return; } + virtual ~RsDummyMsg() { return; } std::string msgData; @@ -48,8 +48,10 @@ public: class RsDummyGrp : public RsGxsGrpItem { +public: + RsDummyGrp() : RsGxsGrpItem(RS_SERVICE_TYPE_DUMMY, RS_PKT_SUBTYPE_DUMMY_GRP) { return; } - virtual RsDummyGrp() { return; } + virtual ~RsDummyGrp() { return; } @@ -69,7 +71,7 @@ public: RsDummySerialiser() :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_DUMMY) { return; } - virtual ~RsGxsPhotoSerialiser() { return; } + virtual ~RsDummySerialiser() { return; } uint32_t size(RsItem *item); bool serialise (RsItem *item, void *data, uint32_t *size); diff --git a/libretroshare/src/tests/gxs/rsgenexchange_test.cc b/libretroshare/src/tests/gxs/rsgenexchange_test.cc index 6d3d57a07..3cd82b40b 100644 --- a/libretroshare/src/tests/gxs/rsgenexchange_test.cc +++ b/libretroshare/src/tests/gxs/rsgenexchange_test.cc @@ -12,17 +12,16 @@ INITTEST(); int main() { + GenExchangeTester tester; + CHECK(tester.testMsgSubmissionRetrieval()); REPORT("testMsgSubmissionRetrieval()"); + CHECK(tester.testSpecificMsgMetaRetrieval()); REPORT("testSpecificMsgMetaRetrieval()"); + CHECK(tester.testMsgIdRetrieval()); REPORT("tester.testMsgIdRetrieval()"); + CHECK(tester.testRelatedMsgIdRetrieval_Parents()); REPORT("tester.testRelatedMsgIdRetrieval_Parents()"); + CHECK(tester.testRelatedMsgIdRetrieval_OrigMsgId()); REPORT("tester.testRelatedMsgIdRetrieval_OrigMsgId()"); + CHECK(tester.testRelatedMsgIdRetrieval_Latest()); REPORT("tester.testRelatedMsgIdRetrieval_Latest()"); - GxsCoreServer gxsCore; - - // create data service and dummy net service - RsDummyNetService dummyNet; - RsDataService dataStore("./", "testServiceDb", 0, NULL); - GenExchangeTestService testService; - gxsCore.addService(&testService); - createThread(gxsCore); - - + FINALREPORT("RsGenExchangeTest"); + return 0; } diff --git a/libretroshare/src/tests/gxs/rsgenexhchange_test.pro b/libretroshare/src/tests/gxs/rsgenexhchange_test.pro index 042fe2565..0346c5f34 100644 --- a/libretroshare/src/tests/gxs/rsgenexhchange_test.pro +++ b/libretroshare/src/tests/gxs/rsgenexhchange_test.pro @@ -1,10 +1,15 @@ TEMPLATE = app TARGET = rsgenexcahnge_test - +CONFIG += debug win32 { + DEFINES *= WINDOWS_SYS \ + WIN32 \ + STATICLIB \ + MINGW + # Switch on extra warnings QMAKE_CFLAGS += -Wextra QMAKE_CXXFLAGS += -Wextra @@ -25,13 +30,12 @@ win32 { LIBS += C:\Development\Rs\v0.5-gxs-b1/libretroshare/libretroshare-build-desktop/lib/libretroshare.a LIBS += C:\Development\Rs\v0.5-gxs-b1\openpgpsdk\openpgpsdk-build-desktop\lib\libops.a LIBS += C:\Development\Libraries\sqlite\sqlite-autoconf-3070900\lib\libsqlite3.a - LIBS += -L"../../../lib" + LIBS += -L"../lib" LIBS += -lssl -lcrypto -lgpgme -lpthreadGC2d -lminiupnpc -lz -lbz2 # added after bitdht # LIBS += -lws2_32 LIBS += -luuid -lole32 -liphlpapi -lcrypt32-cygwin -lgdi32 LIBS += -lole32 -lwinmm - RC_FILE = gui/images/retroshare_win.rc # export symbols for the plugins #LIBS += -Wl,--export-all-symbols,--out-implib,lib/libretroshare-gui.a @@ -41,6 +45,11 @@ win32 { GPG_ERROR_DIR = ../../../../lib/libgpg-error-1.7 GPGME_DIR = ../../../../lib/gpgme-1.1.8 INCLUDEPATH += . $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src + SQLITE_DIR = ../../Libraries/sqlite/sqlite-autoconf-3070900 + INCLUDEPATH += . \ + $${SQLITE_DIR} + + LIBS += -lws2_32 From 932a1a44f51fe1220e193e6848a760deab48e941 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sun, 26 Aug 2012 14:02:47 +0000 Subject: [PATCH 043/222] added gxs group tests (submission, all retrieval types) also tested group meta mod request for service strings all group and msg submission and retrieval requests now tested msg meta mod request to test still Added fixes: genexchange (mGrpSign was not included in overloaded assignment operator) added grp sign flag as Db field git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5473 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsdataservice.cc | 64 ++- libretroshare/src/gxs/rsgenexchange.cc | 25 +- libretroshare/src/gxs/rsgxsdata.cc | 1 + libretroshare/src/gxs/rsgxsdata.h | 1 + libretroshare/src/gxs/rsgxsdataaccess.h | 6 +- libretroshare/src/serialiser/rsgxsitems.cc | 2 + .../src/tests/gxs/genexchangetester.cpp | 374 +++++++++++++++++- .../src/tests/gxs/genexchangetester.h | 10 + .../src/tests/gxs/genexchangetestservice.cpp | 26 ++ .../src/tests/gxs/genexchangetestservice.h | 11 + .../src/tests/gxs/rsgenexchange_test.cc | 5 + libretroshare/src/util/retrodb.cc | 1 - 12 files changed, 486 insertions(+), 40 deletions(-) diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index ce983d6b7..cc0ae6ff5 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -51,6 +51,7 @@ #define KEY_ADMIN_SIGN std::string("adminSign") #define KEY_KEY_SET std::string("keySet") #define KEY_GRP_NAME std::string("grpName") +#define KEY_GRP_SIGN_FLAGS std::string("signFlags") // grp local #define KEY_GRP_SUBCR_FLAG std::string("subscribeFlag") @@ -99,6 +100,7 @@ #define COL_GRP_LAST_POST 12 #define COL_ORIG_GRP_ID 13 #define COL_GRP_SERV_STRING 14 +#define COL_GRP_SIGN_FLAGS 15 // msg col numbers #define COL_PUBLISH_SIGN 5 @@ -151,6 +153,7 @@ RsDataService::RsDataService(const std::string &serviceDir, const std::string &d grpMetaColumns.push_back(KEY_KEY_SET); grpMetaColumns.push_back(KEY_GRP_SUBCR_FLAG); grpMetaColumns.push_back(KEY_GRP_POP); grpMetaColumns.push_back(KEY_MSG_COUNT); grpMetaColumns.push_back(KEY_GRP_STATUS); grpMetaColumns.push_back(KEY_GRP_NAME); grpMetaColumns.push_back(KEY_GRP_LAST_POST); grpMetaColumns.push_back(KEY_ORIG_GRP_ID); grpMetaColumns.push_back(KEY_NXS_SERV_STRING); + grpMetaColumns.push_back(KEY_GRP_SIGN_FLAGS); // for retrieving actual grp data grpColumns.push_back(KEY_GRP_ID); grpColumns.push_back(KEY_NXS_FILE); grpColumns.push_back(KEY_NXS_FILE_OFFSET); @@ -208,6 +211,7 @@ void RsDataService::initialise(){ KEY_ORIG_GRP_ID + " TEXT," + KEY_NXS_SERV_STRING + " TEXT," + KEY_NXS_FLAGS + " INT," + + KEY_GRP_SIGN_FLAGS + " INT," + KEY_IDENTITY_SIGN + " BLOB);"); } @@ -234,6 +238,7 @@ RsGxsGrpMetaData* RsDataService::getGrpMeta(RetroCursor &c) c.getString(COL_GRP_NAME, grpMeta->mGroupName); c.getString(COL_ORIG_GRP_ID, grpMeta->mOrigGrpId); c.getString(COL_GRP_SERV_STRING, grpMeta->mServiceString); + grpMeta->mSignFlags = c.getInt32(COL_GRP_SIGN_FLAGS); grpMeta->mPublishTs = c.getInt32(COL_TIME_STAMP); grpMeta->mGroupFlags = c.getInt32(COL_NXS_FLAGS); @@ -540,6 +545,7 @@ int RsDataService::storeGroup(std::map &grp) cv.put(KEY_NXS_SERV_STRING, grpMetaPtr->mServiceString); cv.put(KEY_NXS_FLAGS, (int32_t)grpMetaPtr->mGroupFlags); cv.put(KEY_TIME_STAMP, (int32_t)grpMetaPtr->mPublishTs); + cv.put(KEY_GRP_SIGN_FLAGS, (int32_t)grpMetaPtr->mSignFlags); if(! (grpMetaPtr->mAuthorId.empty()) ){ cv.put(KEY_NXS_IDENTITY, grpMetaPtr->mAuthorId); @@ -857,26 +863,62 @@ void RsDataService::retrieveMsgMeta(RetroCursor *c, std::vector& grp) +int RsDataService::retrieveGxsGrpMetaData(std::map& grp) { - RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, grpMetaColumns, "", ""); - if(c) - { - bool valid = c->moveToFirst(); - while(valid) + if(grp.empty()){ + + RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, grpMetaColumns, "", ""); + + if(c) { - RsGxsGrpMetaData* g = getGrpMeta(*c); + bool valid = c->moveToFirst(); - if(g) + while(valid) { - grp[g->mGroupId] = g; + RsGxsGrpMetaData* g = getGrpMeta(*c); + + if(g) + { + grp[g->mGroupId] = g; + } + valid = c->moveToNext(); } - valid = c->moveToNext(); + delete c; } + + }else + { + + std::map::iterator mit = grp.begin(); + + for(; mit != grp.end(); mit++) + { + const RsGxsGroupId& grpId = mit->first; + RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, grpMetaColumns, "grpId='" + grpId + "'", ""); + + if(c) + { + bool valid = c->moveToFirst(); + + while(valid) + { + RsGxsGrpMetaData* g = getGrpMeta(*c); + + if(g) + { + grp[g->mGroupId] = g; + } + valid = c->moveToNext(); + } + delete c; + } + + } + } - delete c; + return 1; } diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 8edfa26ff..afe021242 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -624,20 +624,21 @@ void RsGenExchange::publishGrps() if(ok) { - grp->metaData = new RsGxsGrpMetaData(); - *(grp->metaData) = grpItem->meta; - createGroup(grp); - size = grp->metaData->serial_size(); - char mData[size]; - grp->metaData->mGroupId = grp->grpId; - ok = grp->metaData->serialise(mData, size); - grp->meta.setBinData(mData, size); + grp->metaData = new RsGxsGrpMetaData(); + grpItem->meta.mPublishTs = time(NULL); + *(grp->metaData) = grpItem->meta; + createGroup(grp); + size = grp->metaData->serial_size(); + char mData[size]; + grp->metaData->mGroupId = grp->grpId; + ok = grp->metaData->serialise(mData, size); + grp->meta.setBinData(mData, size); - ok = mDataAccess->addGroupData(grp); + ok = mDataAccess->addGroupData(grp); - // add to published to allow acknowledgement - mGrpNotify.insert(std::make_pair(mit->first, grp->grpId)); - mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE); + // add to published to allow acknowledgement + mGrpNotify.insert(std::make_pair(mit->first, grp->grpId)); + mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE); } if(!ok) diff --git a/libretroshare/src/gxs/rsgxsdata.cc b/libretroshare/src/gxs/rsgxsdata.cc index dc5178605..7b3bc59e3 100644 --- a/libretroshare/src/gxs/rsgxsdata.cc +++ b/libretroshare/src/gxs/rsgxsdata.cc @@ -268,6 +268,7 @@ void RsGxsGrpMetaData::operator =(const RsGroupMetaData& rMeta) this->mSubscribeFlags = rMeta.mSubscribeFlags; this->mGroupName = rMeta.mGroupName; this->mServiceString = rMeta.mServiceString; + this->mSignFlags = rMeta.mSignFlags; } void RsGxsMsgMetaData::operator =(const RsMsgMetaData& rMeta) diff --git a/libretroshare/src/gxs/rsgxsdata.h b/libretroshare/src/gxs/rsgxsdata.h index a9d51be26..47fa29516 100644 --- a/libretroshare/src/gxs/rsgxsdata.h +++ b/libretroshare/src/gxs/rsgxsdata.h @@ -56,6 +56,7 @@ public: std::string mGroupName; uint32_t mGroupFlags; uint32_t mPublishTs; + uint32_t mSignFlags; std::string mAuthorId; diff --git a/libretroshare/src/gxs/rsgxsdataaccess.h b/libretroshare/src/gxs/rsgxsdataaccess.h index 176d011d8..94c5d4403 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.h +++ b/libretroshare/src/gxs/rsgxsdataaccess.h @@ -327,9 +327,9 @@ private: private: RsGeneralDataService* mDataStore; - uint32_t mNextToken; - std::map mPublicToken; - std::map mRequests; + uint32_t mNextToken; + std::map mPublicToken; + std::map mRequests; RsMutex mDataMutex; diff --git a/libretroshare/src/serialiser/rsgxsitems.cc b/libretroshare/src/serialiser/rsgxsitems.cc index 9f38e2496..2d8374fd0 100644 --- a/libretroshare/src/serialiser/rsgxsitems.cc +++ b/libretroshare/src/serialiser/rsgxsitems.cc @@ -23,6 +23,7 @@ this->mPublishTs = rGxsMeta.mPublishTs; this->mThreadId = rGxsMeta.mThreadId; this->mServiceString = rGxsMeta.mServiceString; + } @@ -39,4 +40,5 @@ this->mSubscribeFlags = rGxsMeta.mSubscribeFlags; this->mGroupName = rGxsMeta.mGroupName; this->mServiceString = rGxsMeta.mServiceString; + this->mSignFlags = rGxsMeta.mSignFlags; } diff --git a/libretroshare/src/tests/gxs/genexchangetester.cpp b/libretroshare/src/tests/gxs/genexchangetester.cpp index 203eaca0d..dfc057de4 100644 --- a/libretroshare/src/tests/gxs/genexchangetester.cpp +++ b/libretroshare/src/tests/gxs/genexchangetester.cpp @@ -126,6 +126,321 @@ void GenExchangeTester::breakDown() mGrpMetaDataOut.clear(); } +bool GenExchangeTester::testGrpSubmissionRetrieval() +{ + + + setUp(); + + // create some random grps to allow msg testing + + RsDummyGrp* dgrp1 = new RsDummyGrp(); + RsDummyGrp* dgrp2 = new RsDummyGrp(); + RsDummyGrp* dgrp3 = new RsDummyGrp(); + + RsDummyGrp* dgrp1_copy = new RsDummyGrp(); + RsDummyGrp* dgrp2_copy = new RsDummyGrp(); + RsDummyGrp* dgrp3_copy = new RsDummyGrp(); + + init(dgrp1); + init(dgrp2); + init(dgrp3); + + RsTokReqOptionsV2 opts; + opts.mReqType = 45000; + uint32_t token; + RsGxsGroupId grpId; + + *dgrp1_copy = *dgrp1; + mTestService->publishDummyGrp(token, dgrp1); + pollForToken(token, opts); + mTestService->acknowledgeTokenGrp(token, grpId); + dgrp1_copy->meta.mGroupId = grpId; + mGrpDataOut.push_back(dgrp1_copy); + + *dgrp2_copy = *dgrp2; + mTestService->publishDummyGrp(token, dgrp2); + pollForToken(token, opts); + mTestService->acknowledgeTokenGrp(token, grpId); + dgrp2_copy->meta.mGroupId = grpId; + mGrpDataOut.push_back(dgrp2_copy); + + *dgrp3_copy = *dgrp3; + mTestService->publishDummyGrp(token, dgrp3); + pollForToken(token, opts); + mTestService->acknowledgeTokenGrp(token, grpId); + dgrp3_copy->meta.mGroupId = grpId; + mGrpDataOut.push_back(dgrp3_copy); + + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + + std::list grpIds; + mTokenService->requestGroupInfo(token, 0, opts, grpIds); + + pollForToken(token, opts); + + std::vector::iterator lit_out = mGrpDataOut.begin(); + + bool ok = true; + + for(; lit_out != mGrpDataOut.end(); lit_out++) + { + RsDummyGrp* grpOut = dynamic_cast(*lit_out); + if(!grpOut) + { + ok = false; + break; + } + + + + std::vector::iterator lit_in = mGrpDataIn.begin(); + + bool found = true; + for(; lit_in != mGrpDataIn.end(); lit_in++) + { + RsDummyGrp* grpIn = dynamic_cast(*lit_in); + + if(!grpIn) + { + ok = false; + break; + } + + if(grpIn->meta.mGroupId == grpOut->meta.mGroupId) + { + found = true; + ok &= *grpIn == *grpOut; + } + } + + if(!found) + { + ok = false; + break; + } + } + + breakDown(); + return ok; +} + +bool GenExchangeTester::testGrpMetaRetrieval() +{ + setUp(); + + // create some random grps to allow msg testing + + RsDummyGrp* dgrp1 = new RsDummyGrp(); + RsDummyGrp* dgrp2 = new RsDummyGrp(); + RsDummyGrp* dgrp3 = new RsDummyGrp(); + + init(dgrp1); + init(dgrp2); + init(dgrp3); + + RsTokReqOptionsV2 opts; + opts.mReqType = 45000; + uint32_t token; + RsGxsGroupId grpId; + + RsGroupMetaData tempMeta; + + tempMeta = dgrp1->meta; + mTestService->publishDummyGrp(token, dgrp1); + pollForToken(token, opts); + mTestService->acknowledgeTokenGrp(token, grpId); + tempMeta.mGroupId = grpId; + mGrpMetaDataOut.push_back(tempMeta); + + + tempMeta = dgrp2->meta; + mTestService->publishDummyGrp(token, dgrp2); + pollForToken(token, opts); + mTestService->acknowledgeTokenGrp(token, grpId); + tempMeta.mGroupId = grpId; + mGrpMetaDataOut.push_back(tempMeta); + + tempMeta = dgrp3->meta; + mTestService->publishDummyGrp(token, dgrp3); + pollForToken(token, opts); + mTestService->acknowledgeTokenGrp(token, grpId); + tempMeta.mGroupId = grpId; + mGrpMetaDataOut.push_back(tempMeta); + + + opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; + + std::list grpIds; + mTokenService->requestGroupInfo(token, 0, opts, grpIds); + + pollForToken(token, opts); + + std::list::iterator lit_out = mGrpMetaDataOut.begin(); + + bool ok = true; + + for(; lit_out != mGrpMetaDataOut.end(); lit_out++) + { + const RsGroupMetaData& grpMetaOut = *lit_out; + + std::list::iterator lit_in = mGrpMetaDataIn.begin(); + + bool found = true; + for(; lit_in != mGrpMetaDataIn.end(); lit_in++) + { + const RsGroupMetaData& grpMetaIn = *lit_in; + + if(grpMetaOut.mGroupId == grpMetaIn.mGroupId) + { + found = true; + ok &= grpMetaIn == grpMetaOut; + } + } + + if(!found) + { + ok = false; + break; + } + } + + breakDown(); + return ok; +} + +bool GenExchangeTester::testGrpIdRetrieval() +{ + setUp(); + setUpLargeGrps(30); // create a large amount of grps + + + RsTokReqOptionsV2 opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; + uint32_t token; + std::list grpIds; + mTokenService->requestGroupInfo(token, 0, opts, grpIds); + + pollForToken(token, opts); + + std::list::iterator lit_out = mGrpIdsOut.begin(); + + bool ok = true; + + for(; lit_out != mGrpIdsOut.end(); lit_out++) + { + std::list::iterator lit_in = mGrpIdsIn.begin(); + + bool found = true; + for(; lit_in != mGrpIdsIn.end(); lit_in++) + { + + if(*lit_out == *lit_in) + { + found = true; + } + } + + if(!found) + { + ok = false; + break; + } + } + + breakDown(); + return ok; +} + + +bool GenExchangeTester::testGrpMetaModRequest() +{ + + setUp(); + + // create some random grps to allow msg testing + + RsDummyGrp* dgrp1 = new RsDummyGrp(); + RsDummyGrp* dgrp2 = new RsDummyGrp(); + RsDummyGrp* dgrp3 = new RsDummyGrp(); + init(dgrp1); + init(dgrp2); + init(dgrp3); + + uint32_t token; + RsTokReqOptionsV2 opts; + opts.mReqType = 45000; + std::vector grpIds; + RsGxsGroupId grpId; + + mTestService->publishDummyGrp(token, dgrp1); + pollForToken(token, opts); + mTestService->acknowledgeTokenGrp(token, grpId); + grpIds.push_back(grpId); + + mTestService->publishDummyGrp(token, dgrp2); + pollForToken(token, opts); + mTestService->acknowledgeTokenGrp(token, grpId); + grpIds.push_back(grpId); + + mTestService->publishDummyGrp(token, dgrp3); + pollForToken(token, opts); + mTestService->acknowledgeTokenGrp(token, grpId); + grpIds.push_back(grpId); + + bool ok = true; + + std::string newServiceString; + randString(SHORT_STR, newServiceString); + + // mod service flag for first grp + mTestService->setGroupServiceStringTS(token, grpIds[0], newServiceString); + pollForToken(token, opts); + ok = mTestService->acknowledgeTokenGrp(token, grpId); + + std::list reqGrpIds; + reqGrpIds.push_back(grpIds[0]); + opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; + mTokenService->requestGroupInfo(token, 0, opts, reqGrpIds); + pollForToken(token, opts); + + + + if(mGrpMetaDataIn.empty()) + ok = false; + + if(ok) + { + RsGroupMetaData meta = *(mGrpMetaDataIn.begin()); + + if(meta.mServiceString != newServiceString) + ok = false; + + } + + breakDown(); + return ok; +} + + +void GenExchangeTester::setUpLargeGrps(uint32_t nGrps) +{ + + + for(int i=0; i < nGrps; i++) + { + RsDummyGrp* dgrp = new RsDummyGrp(); + RsGxsGroupId grpId; + uint32_t token; + init(dgrp); + RsTokReqOptionsV2 opts; + opts.mReqType = 4000; + mTestService->publishDummyGrp(token, dgrp); + pollForToken(token, opts); + mTestService->acknowledgeTokenGrp(token, grpId); + mGrpIdsOut.push_back(grpId); + } +} bool GenExchangeTester::testMsgSubmissionRetrieval() { @@ -821,18 +1136,6 @@ void GenExchangeTester::createMsgs(std::vector &msgs, int nMsgs) c } - -bool GenExchangeTester::testGrpIdRetrieval() -{ - return false; -} - -bool GenExchangeTester::testGrpMetaModRequest() -{ - return false; -} - - // helper functions void GenExchangeTester::storeGrpMeta(std::list &grpMetaData){ @@ -870,6 +1173,21 @@ void GenExchangeTester::storeMsgIds(GxsMsgIdResult &msgIds) void GenExchangeTester::init(RsGroupMetaData &grpMeta) const { + randString(SHORT_STR, grpMeta.mGroupId); + randString(SHORT_STR, grpMeta.mAuthorId); + randString(SHORT_STR, grpMeta.mGroupName); + randString(SHORT_STR, grpMeta.mServiceString); + + + grpMeta.mGroupFlags = randNum(); + grpMeta.mLastPost = randNum(); + grpMeta.mGroupStatus = randNum(); + grpMeta.mMsgCount = randNum(); + grpMeta.mPop = randNum(); + grpMeta.mSignFlags = randNum(); + grpMeta.mPublishTs = randNum(); + grpMeta.mSubscribeFlags = randNum(); + } void GenExchangeTester::init(RsMsgMetaData &msgMeta) const @@ -913,6 +1231,35 @@ bool operator ==(const RsMsgMetaData& lMeta, const RsMsgMetaData& rMeta) return true; } +bool operator ==(const RsGroupMetaData& lMeta, const RsGroupMetaData& rMeta) +{ + if(lMeta.mAuthorId != rMeta.mAuthorId) return false; + if(lMeta.mGroupFlags != rMeta.mGroupFlags) return false; + if(lMeta.mGroupId != rMeta.mGroupId) return false; + if(lMeta.mGroupName != rMeta.mGroupName) return false; + if(lMeta.mGroupStatus != rMeta.mGroupStatus) return false; + if(lMeta.mLastPost != rMeta.mLastPost) return false; + if(lMeta.mMsgCount != rMeta.mMsgCount) return false; + if(lMeta.mPop != rMeta.mPop) return false; + // if(lMeta.mPublishTs != rMeta.mPublishTs) return false; set in gxs + if(lMeta.mServiceString != rMeta.mServiceString) return false; + if(lMeta.mSignFlags != rMeta.mSignFlags) return false; + if(lMeta.mSubscribeFlags != rMeta.mSubscribeFlags) return false; + + return true; +} + +bool operator ==(const RsDummyGrp& lGrp, const RsDummyGrp& rGrp) +{ + + if(lGrp.grpData != rGrp.grpData) return false; + if(! (lGrp.meta == rGrp.meta)) return false; + + return true; + + +} + bool operator ==(const RsDummyMsg& lMsg, const RsDummyMsg& rMsg) { if(lMsg.msgData != rMsg.msgData) return false; @@ -923,7 +1270,8 @@ bool operator ==(const RsDummyMsg& lMsg, const RsDummyMsg& rMsg) void GenExchangeTester::init(RsDummyGrp *grpItem) const { - + randString(SHORT_STR, grpItem->grpData); + init(grpItem->meta); } void GenExchangeTester::init(RsDummyMsg *msgItem) const diff --git a/libretroshare/src/tests/gxs/genexchangetester.h b/libretroshare/src/tests/gxs/genexchangetester.h index 392fc4338..63619bc12 100644 --- a/libretroshare/src/tests/gxs/genexchangetester.h +++ b/libretroshare/src/tests/gxs/genexchangetester.h @@ -9,6 +9,9 @@ bool operator ==(const RsMsgMetaData& lMeta, const RsMsgMetaData& rMeta); bool operator ==(const RsDummyMsg& lMsg, const RsDummyMsg& rMsg); +bool operator ==(const RsGroupMetaData& lMeta, const RsGroupMetaData& rMeta); +bool operator ==(const RsDummyGrp& lMsg, const RsDummyGrp& rMsg); + /*! * The job of the service tester is to send dummy msg items to the GenExchange service * and then retrieve them (ignoring ackowledge message) @@ -48,6 +51,13 @@ private: void setUpGrps(); // to be called at start of msg tests + /*! + * Can be called at start grpId or grpMeta test + * to help out + * ids are store is mGrpIdsOut + */ + void setUpLargeGrps(uint32_t nGrps); + void storeMsgData(GxsMsgDataMap& msgData); void storeMsgMeta(GxsMsgMetaMap& msgMetaData); void storeMsgIds(GxsMsgIdResult& msgIds); diff --git a/libretroshare/src/tests/gxs/genexchangetestservice.cpp b/libretroshare/src/tests/gxs/genexchangetestservice.cpp index 461c872ef..7fe38add8 100644 --- a/libretroshare/src/tests/gxs/genexchangetestservice.cpp +++ b/libretroshare/src/tests/gxs/genexchangetestservice.cpp @@ -50,3 +50,29 @@ bool GenExchangeTestService::getMsgListTS(const uint32_t &token, GxsMsgIdResult { return getMsgList(token, msgIds); } + +void GenExchangeTestService::setGroupServiceStringTS(uint32_t &token, const RsGxsGroupId &grpId, const std::string &servString) +{ + RsGenExchange::setGroupServiceString(token, grpId, servString); +} + +void GenExchangeTestService::setGroupStatusFlagTS(uint32_t &token, const RsGxsGroupId &grpId, const uint32_t &status) +{ + RsGenExchange::setGroupStatusFlag(token, grpId, status); +} + +void GenExchangeTestService::setGroupSubscribeFlagTS(uint32_t &token, const RsGxsGroupId &grpId, const uint32_t &status) +{ + RsGenExchange::setGroupSubscribeFlag(token, grpId, status); +} + +void GenExchangeTestService::setMsgServiceStringTS(uint32_t &token, const RsGxsGrpMsgIdPair &msgId, const std::string &servString) +{ + RsGenExchange::setMsgServiceString(token, msgId, servString); +} + +void GenExchangeTestService::setMsgStatusFlagTS(uint32_t &token, const RsGxsGrpMsgIdPair &msgId, const uint32_t &status) +{ + RsGenExchange::setMsgStatusFlag(token, msgId, status); +} + diff --git a/libretroshare/src/tests/gxs/genexchangetestservice.h b/libretroshare/src/tests/gxs/genexchangetestservice.h index c83879739..0a1249619 100644 --- a/libretroshare/src/tests/gxs/genexchangetestservice.h +++ b/libretroshare/src/tests/gxs/genexchangetestservice.h @@ -59,6 +59,17 @@ public: */ bool getMsgDataTS(const uint32_t &token, GxsMsgDataMap& msgItems); + + void setGroupSubscribeFlagTS(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status); + + void setGroupStatusFlagTS(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status); + + void setGroupServiceStringTS(uint32_t& token, const RsGxsGroupId& grpId, const std::string& servString); + + void setMsgStatusFlagTS(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const uint32_t& status); + + void setMsgServiceStringTS(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const std::string& servString ); + }; #endif // GENEXCHANGETESTSERVICE_H diff --git a/libretroshare/src/tests/gxs/rsgenexchange_test.cc b/libretroshare/src/tests/gxs/rsgenexchange_test.cc index 3cd82b40b..68b2baff5 100644 --- a/libretroshare/src/tests/gxs/rsgenexchange_test.cc +++ b/libretroshare/src/tests/gxs/rsgenexchange_test.cc @@ -21,6 +21,11 @@ int main() CHECK(tester.testRelatedMsgIdRetrieval_OrigMsgId()); REPORT("tester.testRelatedMsgIdRetrieval_OrigMsgId()"); CHECK(tester.testRelatedMsgIdRetrieval_Latest()); REPORT("tester.testRelatedMsgIdRetrieval_Latest()"); + CHECK(tester.testGrpSubmissionRetrieval()); REPORT("tester.testGrpSubmissionRetrieval()"); + CHECK(tester.testGrpMetaRetrieval()); REPORT("tester.testGrpMetaRetrieval()"); + CHECK(tester.testGrpIdRetrieval()); REPORT("tester.testGrpIdRetrieval()"); + CHECK(tester.testGrpMetaModRequest()); REPORT("tester.testGrpMetaModRequest()"); + FINALREPORT("RsGenExchangeTest"); return 0; diff --git a/libretroshare/src/util/retrodb.cc b/libretroshare/src/util/retrodb.cc index 7346cc380..c7402a8a3 100644 --- a/libretroshare/src/util/retrodb.cc +++ b/libretroshare/src/util/retrodb.cc @@ -476,7 +476,6 @@ bool RetroDb::sqlUpdate(const std::string &tableName, std::string whereClause, c // execute query return execSQL(sqlQuery); - } From e99d84403d7bb3f9a262005235c42700ea167af0 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sun, 26 Aug 2012 21:07:51 +0000 Subject: [PATCH 044/222] All Msg and Grp meta modification tests done, no fixes needed! git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5475 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/tests/gxs/genexchangetester.cpp | 110 +++++++++++++++++- .../src/tests/gxs/rsgenexchange_test.cc | 1 + 2 files changed, 109 insertions(+), 2 deletions(-) diff --git a/libretroshare/src/tests/gxs/genexchangetester.cpp b/libretroshare/src/tests/gxs/genexchangetester.cpp index dfc057de4..4434a4ab8 100644 --- a/libretroshare/src/tests/gxs/genexchangetester.cpp +++ b/libretroshare/src/tests/gxs/genexchangetester.cpp @@ -391,6 +391,8 @@ bool GenExchangeTester::testGrpMetaModRequest() bool ok = true; std::string newServiceString; + uint32_t newGrpStatus = randNum(); + uint32_t newSubscribeGrpFlag = randNum(); randString(SHORT_STR, newServiceString); // mod service flag for first grp @@ -398,6 +400,14 @@ bool GenExchangeTester::testGrpMetaModRequest() pollForToken(token, opts); ok = mTestService->acknowledgeTokenGrp(token, grpId); + mTestService->setGroupStatusFlagTS(token, grpIds[0], newGrpStatus); + pollForToken(token, opts); + ok = mTestService->acknowledgeTokenGrp(token, grpId); + + mTestService->setGroupSubscribeFlagTS(token, grpIds[0], newSubscribeGrpFlag); + pollForToken(token, opts); + ok = mTestService->acknowledgeTokenGrp(token, grpId); + std::list reqGrpIds; reqGrpIds.push_back(grpIds[0]); opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; @@ -416,6 +426,13 @@ bool GenExchangeTester::testGrpMetaModRequest() if(meta.mServiceString != newServiceString) ok = false; + if(meta.mSubscribeFlags != newSubscribeGrpFlag) + ok = false; + + if(meta.mGroupStatus != newGrpStatus) + ok = false; + + } breakDown(); @@ -425,8 +442,6 @@ bool GenExchangeTester::testGrpMetaModRequest() void GenExchangeTester::setUpLargeGrps(uint32_t nGrps) { - - for(int i=0; i < nGrps; i++) { RsDummyGrp* dgrp = new RsDummyGrp(); @@ -442,6 +457,97 @@ void GenExchangeTester::setUpLargeGrps(uint32_t nGrps) } } +bool GenExchangeTester::testMsgMetaModRequest() +{ + setUp(); + setUpGrps(); + + RsDummyMsg* msg = new RsDummyMsg(); + init(msg); + + msg->meta.mGroupId = mRandGrpIds[(rand()%3)]; + uint32_t token; + RsDummyMsg* msgOut = new RsDummyMsg(); + *msgOut = *msg; + mTestService->publishDummyMsg(token, msg); + + // poll will block until found + RsTokReqOptionsV2 opts; + opts.mReqType = 4200; + pollForToken(token, opts); + RsGxsGrpMsgIdPair msgId; + + mTestService->acknowledgeTokenMsg(token, msgId); + + if(msgId.first.empty() || msgId.second.empty()){ + breakDown(); + return false; + } + + std::string newServiceString; + randString(SHORT_STR, newServiceString); + + // first modify service string + mTestService->setMsgServiceStringTS(token, msgId, newServiceString); + pollForToken(token, opts); + + mTestService->acknowledgeTokenMsg(token, msgId); + + uint32_t newStatus = 2; + // first modify service string + mTestService->setMsgStatusFlagTS(token, msgId, newStatus); + pollForToken(token, opts); + + mTestService->acknowledgeTokenMsg(token, msgId); + + // now request msg + GxsMsgReq req; + std::vector msgV; + msgV.push_back(msgId.second); + req.insert(std::make_pair(msgId.first, msgV)); + + opts.mReqType = GXS_REQUEST_TYPE_MSG_META; + mTokenService->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, req); + + // poll again + pollForToken(token, opts); + + bool ok = true; + + if(mMsgMetaDataIn.empty()) + ok = false; + + if(ok){ + + GxsMsgMetaMap::iterator mit = mMsgMetaDataIn.begin(); + std::vector& metaV = mit->second; + + RsMsgMetaData meta; + if(metaV.empty()){ + ok = false; + }else{ + meta = *(metaV.begin()); + } + + + if(meta.mServiceString != newServiceString) + ok &= false; + + if(meta.mMsgStatus != newStatus) + ok &= false; + + + } + + /********************/ + + // complete + breakDown(); + + return ok; + +} + bool GenExchangeTester::testMsgSubmissionRetrieval() { diff --git a/libretroshare/src/tests/gxs/rsgenexchange_test.cc b/libretroshare/src/tests/gxs/rsgenexchange_test.cc index 68b2baff5..4ae8adb3c 100644 --- a/libretroshare/src/tests/gxs/rsgenexchange_test.cc +++ b/libretroshare/src/tests/gxs/rsgenexchange_test.cc @@ -20,6 +20,7 @@ int main() CHECK(tester.testRelatedMsgIdRetrieval_Parents()); REPORT("tester.testRelatedMsgIdRetrieval_Parents()"); CHECK(tester.testRelatedMsgIdRetrieval_OrigMsgId()); REPORT("tester.testRelatedMsgIdRetrieval_OrigMsgId()"); CHECK(tester.testRelatedMsgIdRetrieval_Latest()); REPORT("tester.testRelatedMsgIdRetrieval_Latest()"); + CHECK(tester.testMsgMetaModRequest()); REPORT("tester.testMsgMetaModRequest()"); CHECK(tester.testGrpSubmissionRetrieval()); REPORT("tester.testGrpSubmissionRetrieval()"); CHECK(tester.testGrpMetaRetrieval()); REPORT("tester.testGrpMetaRetrieval()"); From 60e1d5e68e7cc9d1631b5749935f1643b7ae36c8 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Tue, 28 Aug 2012 21:11:54 +0000 Subject: [PATCH 045/222] Fix for NXS group sync: need to set destination peer when constructing payload. Generalised nxstest to simulate sync among arbitrary number of peers added pass conditions to test scenerio with seperate notify observers per peer cleaned up test code and enabled auto cleaning of run dir (remove db junk) git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5480 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgds.h | 4 +- libretroshare/src/gxs/rsgxsnetservice.cc | 85 ++++++----- libretroshare/src/tests/gxs/nxstesthub.cc | 140 ++++++++++++------ libretroshare/src/tests/gxs/nxstesthub.h | 38 ++--- .../src/tests/gxs/nxstestscenario.cc | 118 +++++++++------ libretroshare/src/tests/gxs/nxstestscenario.h | 67 ++++++--- .../src/tests/gxs/rsgxsnetservice_test.cc | 14 +- 7 files changed, 279 insertions(+), 187 deletions(-) diff --git a/libretroshare/src/gxs/rsgds.h b/libretroshare/src/gxs/rsgds.h index 428a0be69..1ea61233b 100644 --- a/libretroshare/src/gxs/rsgds.h +++ b/libretroshare/src/gxs/rsgds.h @@ -182,14 +182,14 @@ public: * @param msg map of message and decoded meta data information * @return error code */ - virtual int storeMessage(std::map& msg) = 0; + virtual int storeMessage(std::map& msgs) = 0; /*! * Stores a list of groups in data store * @param grp map of group and decoded meta data * @return error code */ - virtual int storeGroup(std::map& grp) = 0; + virtual int storeGroup(std::map& grsp) = 0; /*! diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 7c2a43a36..e619e1ebd 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -28,7 +28,7 @@ #define NXS_NET_DEBUG -#define SYNC_PERIOD 12 // in microseconds every 10 seconds (1 second for testing) +#define SYNC_PERIOD 10 // in microseconds every 10 seconds (1 second for testing) #define TRANSAC_TIMEOUT 5 // 5 seconds @@ -36,7 +36,7 @@ RsGxsNetService::RsGxsNetService(uint16_t servType, RsGeneralDataService *gds, RsNxsNetMgr *netMgr, RsNxsObserver *nxsObs) : p3Config(servType), p3ThreadedService(servType), mTransactionTimeOut(TRANSAC_TIMEOUT), mServType(servType), mDataStore(gds), mTransactionN(0), - mObserver(nxsObs), mNxsMutex("RsGxsNetService"), mNetMgr(netMgr), mSYNC_PERIOD(SYNC_PERIOD) + mObserver(nxsObs), mNxsMutex("RsGxsNetService"), mNetMgr(netMgr), mSYNC_PERIOD(SYNC_PERIOD), mSyncTs(0) { addSerialType(new RsNxsSerialiser(mServType)); @@ -57,8 +57,9 @@ int RsGxsNetService::tick(){ recvNxsItemQueue(); uint32_t now = time(NULL); + uint32_t elapsed = mSYNC_PERIOD + mSyncTs; - if((mSYNC_PERIOD + mSyncTs) < now) + if((elapsed) < now) { syncWithPeers(); mSyncTs = now; @@ -75,16 +76,23 @@ void RsGxsNetService::syncWithPeers() std::set::iterator sit = peers.begin(); - // for now just grps - for(; sit != peers.end(); sit++) - { - RsNxsSyncGrp *grp = new RsNxsSyncGrp(mServType); - grp->clear(); - grp->PeerId(*sit); - sendItem(grp); - } + // for now just grps + for(; sit != peers.end(); sit++) + { + RsNxsSyncGrp *grp = new RsNxsSyncGrp(mServType); + grp->clear(); + grp->PeerId(*sit); + sendItem(grp); + } - // TODO msgs +// // TODO msgs +// for(; sit != peers.end(); sit++) +// { +// RsNxsSyncMsg* msg = new RsNxsSyncMsg(mServType); +// msg->clear(); +// msg->PeerId(*sit); +// sendItem(msg); +// } } @@ -326,7 +334,8 @@ void RsGxsNetService::run(){ bool RsGxsNetService::locked_checkTransacTimedOut(NxsTransaction* tr) { - return tr->mTimeOut < ((uint32_t) time(NULL)); + //return tr->mTimeOut < ((uint32_t) time(NULL)); + return false; } void RsGxsNetService::processTransactions(){ @@ -599,7 +608,6 @@ void RsGxsNetService::locked_processCompletedIncomingTrans(NxsTransaction* tr) }else if(flag & RsNxsTransac::FLAG_TYPE_MSGS) { - std::list::iterator lit = tr->mItems.begin(); std::vector msgs; while(tr->mItems.size() > 0) @@ -762,31 +770,34 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr) } } + if(reqList.empty()) + { - RsNxsTransac* transac = new RsNxsTransac(mServType); - transac->transactFlag = RsNxsTransac::FLAG_TYPE_MSG_LIST_REQ - | RsNxsTransac::FLAG_BEGIN_P1; - transac->timestamp = 0; - transac->nItems = reqList.size(); - transac->PeerId(tr->mTransaction->PeerId()); - transac->transactionNumber = transN; + RsNxsTransac* transac = new RsNxsTransac(mServType); + transac->transactFlag = RsNxsTransac::FLAG_TYPE_MSG_LIST_REQ + | RsNxsTransac::FLAG_BEGIN_P1; + transac->timestamp = 0; + transac->nItems = reqList.size(); + transac->PeerId(tr->mTransaction->PeerId()); + transac->transactionNumber = transN; - NxsTransaction* newTrans = new NxsTransaction(); - newTrans->mItems = reqList; - newTrans->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM; - newTrans->mTimeOut = time(NULL) + mTransactionTimeOut; + NxsTransaction* newTrans = new NxsTransaction(); + newTrans->mItems = reqList; + newTrans->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM; + newTrans->mTimeOut = time(NULL) + mTransactionTimeOut; - // create transaction copy with your id to indicate - // its an outgoing transaction - newTrans->mTransaction = new RsNxsTransac(*transac); - newTrans->mTransaction->PeerId(mOwnId); + // create transaction copy with your id to indicate + // its an outgoing transaction + newTrans->mTransaction = new RsNxsTransac(*transac); + newTrans->mTransaction->PeerId(mOwnId); - sendItem(transac); + sendItem(transac); - { - if(!locked_addTransaction(newTrans)) - delete newTrans; - } + { + if(!locked_addTransaction(newTrans)) + delete newTrans; + } + } } void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr) @@ -832,7 +843,7 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr) if(grpMetaMap.find(grpId) == grpMetaMap.end()){ RsNxsSyncGrpItem* grpItem = new RsNxsSyncGrpItem(mServType); - + grpItem->PeerId(tr->mTransaction->PeerId()); grpItem->grpId = grpId; grpItem->flag = RsNxsSyncMsgItem::FLAG_REQUEST; grpItem->transactionNumber = transN; @@ -897,7 +908,7 @@ void RsGxsNetService::locked_genSendGrpsTransaction(NxsTransaction* tr) std::string peerId = tr->mTransaction->PeerId(); for(;mit != grps.end(); mit++) { - mit->second->PeerId(peerId); // set so it gets send to right peer + mit->second->PeerId(peerId); // set so it gets sent to right peer mit->second->transactionNumber = transN; newTr->mItems.push_back(mit->second); } @@ -913,6 +924,7 @@ void RsGxsNetService::locked_genSendGrpsTransaction(NxsTransaction* tr) ntr->transactFlag = RsNxsTransac::FLAG_BEGIN_P1 | RsNxsTransac::FLAG_TYPE_GRPS; ntr->nItems = grps.size(); + ntr->PeerId(tr->mTransaction->PeerId()); newTr->mTransaction = new RsNxsTransac(*ntr); newTr->mTransaction->PeerId(mOwnId); @@ -982,7 +994,6 @@ void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrp* item) if(grp.empty()) return; - std::vector grpSyncItems; std::map::iterator mit = grp.begin(); diff --git a/libretroshare/src/tests/gxs/nxstesthub.cc b/libretroshare/src/tests/gxs/nxstesthub.cc index d6ca55f01..e0c505464 100644 --- a/libretroshare/src/tests/gxs/nxstesthub.cc +++ b/libretroshare/src/tests/gxs/nxstesthub.cc @@ -1,78 +1,126 @@ #include "nxstesthub.h" -NxsTestHub::NxsTestHub(NxsTestScenario* nts) : mTestScenario(nts) +NxsTestHub::NxsTestHub(NxsTestScenario * nts, std::set &peers) : mTestScenario(nts) { - netServicePairs.first = new RsGxsNetService(mTestScenario->getServiceType(), - mTestScenario->dummyDataService1(), &netMgr1, mTestScenario); - netServicePairs.second = new RsGxsNetService(mTestScenario->getServiceType(), - mTestScenario->dummyDataService2(), &netMgr2, mTestScenario); + std::set::iterator sit = peers.begin(); - mServicePairs.first = netServicePairs.first; - mServicePairs.second = netServicePairs.second; + for(; sit != peers.end(); sit++) + { + std::set msgPeers = peers; - createThread(*(netServicePairs.first)); - createThread(*(netServicePairs.second)); + // add peers all peers except one iterator currently points to + msgPeers.erase(*sit); + NxsNetDummyMgr* dummyMgr = new NxsNetDummyMgr(*sit, msgPeers); + RsGeneralDataService* ds = mTestScenario->getDataService(*sit); + NxsMessageTestObserver* obs = new NxsMessageTestObserver(ds); + + RsGxsNetService* netService = + new RsGxsNetService(mTestScenario->getServiceType(), + ds, dummyMgr, obs); + + + mNetServices.insert(std::make_pair(*sit, netService)); + mObservers.insert(std::make_pair(*sit, obs)); + } + + sit = peers.begin(); + + // launch net services + for(; sit != peers.end(); sit++) + { + RsGxsNetService* n = mNetServices[*sit]; + createThread(*n); + mServices.insert(std::make_pair(*sit, n)); + } } NxsTestHub::~NxsTestHub() { - delete netServicePairs.first; - delete netServicePairs.second; + std::map::iterator mit = mNetServices.begin(); + + for(; mit != mNetServices.end(); mit++) + delete mit->second; } void NxsTestHub::run() { - - std::list send_queue_s1, send_queue_s2; + double timeDelta = .2; while(isRunning()){ - // make thread sleep for a couple secs - usleep(3000); + // make thread sleep for a bit + #ifndef WINDOWS_SYS + usleep((int) (timeDelta * 1000000)); + #else + Sleep((int) (timeDelta * 1000)); + #endif - p3Service* s1 = mServicePairs.first; - p3Service* s2 = mServicePairs.second; - RsItem* item = NULL; - while((item = s1->send()) != NULL) - { - item->PeerId("PeerB"); - send_queue_s1.push_back(item); - } + std::map::iterator mit = mServices.begin(); - while((item = s2->send()) != NULL) - { - item->PeerId("PeerA"); - send_queue_s2.push_back(item); - } + for(; mit != mServices.end(); mit++) + { + p3Service* s = mit->second; + s->tick(); + } - while(!send_queue_s1.empty()){ - item = send_queue_s1.front(); - s2->receive(dynamic_cast(item)); - send_queue_s1.pop_front(); - } + mit = mServices.begin(); - while(!send_queue_s2.empty()){ - item = send_queue_s2.front(); - s1->receive(dynamic_cast(item)); - send_queue_s2.pop_front(); - } + // collect msgs to send to peers from peers + for(; mit != mServices.end(); mit++) + { + const std::string& peer = mit->first; + p3Service* s = mit->second; - // tick services so nxs net services process items - s1->tick(); - s2->tick(); + // first store all the sends from all services + RsItem* item = NULL; + + while((item = s->send()) != NULL){ + + const std::string peerToReceive = item->PeerId(); + + // set the peer this item comes from + item->PeerId(peer); + mPeerQueues[peerToReceive].push_back(item); + } + + + } + + // now route items to peers + std::map >::iterator mit_queue = mPeerQueues.begin(); + + for(; mit_queue != mPeerQueues.end(); mit_queue++) + { + std::vector& queueV = mit_queue->second; + std::vector::iterator vit = queueV.begin(); + const std::string peerToReceive = mit_queue->first; + for(; vit != queueV.end(); vit++) + { + + RsItem* item = *vit; + p3Service* service = mServices[peerToReceive]; + + service->receive(dynamic_cast(item)); + } + queueV.clear(); + } } - - // also shut down this net service peers if this goes down - netServicePairs.first->join(); - netServicePairs.second->join(); } void NxsTestHub::cleanUp() { - mTestScenario->cleanUp(); + std::map::iterator mit = mNetServices.begin(); + for(; mit != mNetServices.end(); mit++) + { + RsGxsNetService* n = mit->second; + n->join(); + } + + // also shut down this net service peers if this goes down + mTestScenario->cleanUp(); } bool NxsTestHub::testsPassed() diff --git a/libretroshare/src/tests/gxs/nxstesthub.h b/libretroshare/src/tests/gxs/nxstesthub.h index 46849aad9..15f10e0b4 100644 --- a/libretroshare/src/tests/gxs/nxstesthub.h +++ b/libretroshare/src/tests/gxs/nxstesthub.h @@ -11,14 +11,13 @@ // of peers -class NxsNetDummyMgr1 : public RsNxsNetMgr +class NxsNetDummyMgr : public RsNxsNetMgr { public: - NxsNetDummyMgr1() : mOwnId("peerA") { + NxsNetDummyMgr(std::string ownId, std::set peers) : mOwnId(ownId), mPeers(peers) { - mPeers.insert("peerB"); } std::string getOwnId() { return mOwnId; } @@ -31,26 +30,6 @@ private: }; -class NxsNetDummyMgr2 : public RsNxsNetMgr -{ - -public: - - NxsNetDummyMgr2() : mOwnId("peerB") { - - mPeers.insert("peerA"); - - } - - std::string getOwnId() { return mOwnId; } - void getOnlineList(std::set& ssl_peers) { ssl_peers = mPeers; } - -private: - - std::string mOwnId; - std::set mPeers; -}; - /*! * Testing of nxs services occurs through use of two services @@ -73,7 +52,7 @@ public: * This construct the test hub * for a give scenario in mind */ - NxsTestHub(NxsTestScenario*); + NxsTestHub(NxsTestScenario*, std::set& peers); /*! @@ -97,12 +76,13 @@ public: void cleanUp(); private: - std::pair mServicePairs; - std::pair netServicePairs; - NxsTestScenario *mTestScenario; + std::map mServices; + std::map mNetServices; + std::map mObservers; - NxsNetDummyMgr1 netMgr1; - NxsNetDummyMgr2 netMgr2; + std::map > mPeerQueues; + + NxsTestScenario *mTestScenario; }; diff --git a/libretroshare/src/tests/gxs/nxstestscenario.cc b/libretroshare/src/tests/gxs/nxstestscenario.cc index 901ed555a..61c0cac72 100644 --- a/libretroshare/src/tests/gxs/nxstestscenario.cc +++ b/libretroshare/src/tests/gxs/nxstestscenario.cc @@ -10,12 +10,9 @@ #include "data_support.h" NxsMessageTest::NxsMessageTest(uint16_t servtype) -: mServType(servtype) +: mServType(servtype), mMsgTestMtx("mMsgTestMtx") { - mStorePair.first = new RsDataService(".", "dStore1", mServType); - mStorePair.second = new RsDataService(".", "dStore2", mServType); - setUpDataBases(); } std::string NxsMessageTest::getTestName() @@ -24,21 +21,33 @@ std::string NxsMessageTest::getTestName() } NxsMessageTest::~NxsMessageTest(){ - delete mStorePair.first; - delete mStorePair.second; + + std::map::iterator mit = mPeerStoreMap.begin(); + + for(; mit != mPeerStoreMap.end(); mit++) + { + delete mit->second; + } + + std::set::iterator sit = mStoreNames.begin(); + + // remove db file + for(; sit != mStoreNames.end(); sit++) + { + const std::string& name = *sit; + remove(name.c_str()); + } } -void NxsMessageTest::setUpDataBases() +RsGeneralDataService* NxsMessageTest::getDataService(const std::string& peer) { - // create several groups and then messages of that - // group for both second and first of pair - RsDataService* dStore = dynamic_cast(mStorePair.first); - populateStore(dStore); + if(mPeerStoreMap.find(peer) != mPeerStoreMap.end()) return NULL; - dStore = dynamic_cast(mStorePair.second); - populateStore(dStore); + RsDataService* dStore = new RsDataService("./", peer.c_str(), mServType); + mStoreNames.insert(peer); + mPeerStoreMap.insert(std::make_pair(peer, dStore)); + populateStore(dStore); - dStore = NULL; - return; + return dStore; } uint16_t NxsMessageTest::getServiceType() @@ -49,7 +58,7 @@ uint16_t NxsMessageTest::getServiceType() void NxsMessageTest::populateStore(RsGeneralDataService* dStore) { - int nGrp = rand()%7; + int nGrp = (rand()%2)+1; std::vector grpIdList; std::map grps; RsNxsGrp* grp = NULL; @@ -122,40 +131,51 @@ void NxsMessageTest::populateStore(RsGeneralDataService* dStore) return; } -void NxsMessageTest::notifyNewMessages(std::vector& messages) -{ - std::vector::iterator vit = messages.begin(); - - for(; vit != messages.end(); vit++) - { - mPeerMsgs[(*vit)->PeerId()].push_back(*vit); - } -} - -void NxsMessageTest::notifyNewGroups(std::vector& groups) -{ - std::vector::iterator vit = groups.begin(); - - for(; vit != groups.end(); vit++) - { - mPeerGrps[(*vit)->PeerId()].push_back(*vit); - } -} - -RsGeneralDataService* NxsMessageTest::dummyDataService1() -{ - return mStorePair.first; -} - -RsGeneralDataService* NxsMessageTest::dummyDataService2() -{ - return mStorePair.second; -} - void NxsMessageTest::cleanUp() { - mStorePair.first->resetDataStore(); - mStorePair.second->resetDataStore(); - return; + + std::map::iterator mit = mPeerStoreMap.begin(); + + for(; mit != mPeerStoreMap.end(); mit++) + { + RsGeneralDataService* d = mit->second; + d->resetDataStore(); + } + + return; } + +bool NxsMessageTest::testPassed(){ + return false; +} + +/*******************************/ + +NxsMessageTestObserver::NxsMessageTestObserver(RsGeneralDataService *dStore) + :mStore(dStore) +{ + +} + +void NxsMessageTestObserver::notifyNewGroups(std::vector &groups) +{ + std::vector::iterator vit = groups.begin(); + std::map grps; + + for(; vit != groups.end(); vit++) + { + RsNxsGrp* grp = *vit; + RsGxsGrpMetaData* meta = new RsGxsGrpMetaData(); + meta->mGroupId = grp->grpId; + grps.insert(std::make_pair(grp, meta)); + } + + mStore->storeGroup(grps); +} + +void NxsMessageTestObserver::notifyNewMessages(std::vector &messages) +{ + +} + diff --git a/libretroshare/src/tests/gxs/nxstestscenario.h b/libretroshare/src/tests/gxs/nxstestscenario.h index 66efe0084..72500e4d3 100644 --- a/libretroshare/src/tests/gxs/nxstestscenario.h +++ b/libretroshare/src/tests/gxs/nxstestscenario.h @@ -15,14 +15,26 @@ /*! * This scenario module provides data resources */ -class NxsTestScenario : public RsNxsObserver +class NxsTestScenario { public: virtual std::string getTestName() = 0; - virtual RsGeneralDataService* dummyDataService1() = 0; - virtual RsGeneralDataService* dummyDataService2() = 0; + + /*! + * @param peer + * @param namePath + * @return data service with populated with random grp/msg data, null if peer or pathname exists + */ + virtual RsGeneralDataService* getDataService(const std::string& peer) = 0; + + + virtual bool testPassed() = 0; + /*! + * Service type for this test + * should correspond to serialiser service type + */ virtual uint16_t getServiceType() = 0; /*! @@ -34,25 +46,11 @@ public: }; -class NxsMessageTest : public NxsTestScenario +class NxsMessageTestObserver : public RsNxsObserver { - public: - NxsMessageTest(uint16_t servtype); - virtual ~NxsMessageTest(); - std::string getTestName(); - uint16_t getServiceType(); - RsGeneralDataService* dummyDataService1(); - RsGeneralDataService* dummyDataService2(); - - /*! - * Call to remove files created - * in the test directory - */ - void cleanUp(); - -public: + NxsMessageTestObserver(RsGeneralDataService* dStore); /*! * @param messages messages are deleted after function returns @@ -64,6 +62,30 @@ public: */ void notifyNewGroups(std::vector& groups); +private: + + RsGeneralDataService* mStore; + +}; + +class NxsMessageTest : public NxsTestScenario +{ + +public: + + NxsMessageTest(uint16_t servtype); + virtual ~NxsMessageTest(); + std::string getTestName(); + uint16_t getServiceType(); + RsGeneralDataService* getDataService(const std::string& peer); + + /*! + * Call to remove files created + * in the test directory + */ + void cleanUp(); + + bool testPassed(); private: void setUpDataBases(); @@ -72,11 +94,12 @@ private: private: std::string mTestName; - std::pair mStorePair; - std::map > mPeerMsgs; - std::map > mPeerGrps; + std::map mPeerStoreMap; + std::set mStoreNames; uint16_t mServType; + RsMutex mMsgTestMtx; + }; diff --git a/libretroshare/src/tests/gxs/rsgxsnetservice_test.cc b/libretroshare/src/tests/gxs/rsgxsnetservice_test.cc index 68ccbe10a..d187ad144 100644 --- a/libretroshare/src/tests/gxs/rsgxsnetservice_test.cc +++ b/libretroshare/src/tests/gxs/rsgxsnetservice_test.cc @@ -17,13 +17,23 @@ int main() // first setup NxsMessageTest msgTest(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); - NxsTestHub hub(&msgTest); + std::set peers; + peers.insert("PeerA"); + peers.insert("PeerB"); + NxsTestHub hub(&msgTest, peers); // now get things started createThread(hub); + double timeDelta = 30; + // put this thread to sleep for 10 secs - sleep(10); + // make thread sleep for a bit +#ifndef WINDOWS_SYS + usleep((int) (timeDelta * 1000000)); +#else + Sleep((int) (timeDelta * 1000)); +#endif hub.join(); CHECK(hub.testsPassed()); From bd1435c72b81d0faab99e916dcb4ec7038fd8947 Mon Sep 17 00:00:00 2001 From: drbob Date: Wed, 29 Aug 2012 23:42:00 +0000 Subject: [PATCH 046/222] Added First Pass at a chat RPC protocol. This still needs to be generalised further - and made future proof. It is based roughly on libretroshare/src/retroshare/rsmsgs.h git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5485 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- rsctrl/src/definition/chat.proto | 212 +++++++++++++++++++++++++++++++ rsctrl/src/definition/core.proto | 6 +- 2 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 rsctrl/src/definition/chat.proto diff --git a/rsctrl/src/definition/chat.proto b/rsctrl/src/definition/chat.proto new file mode 100644 index 000000000..b80c41ae3 --- /dev/null +++ b/rsctrl/src/definition/chat.proto @@ -0,0 +1,212 @@ +package rsctrl.chat; + +import "core.proto"; + +/////////////////////////////////////////////////////////////// +// Private, Group and Chat Lobby RPC. +/////////////////////////////////////////////////////////////// + +enum RequestMsgIds { + MsgId_RequestChatLobbies = 1; + MsgId_RequestCreateLobby = 2; + MsgId_RequestJoinOrLeaveLobby = 3; + MsgId_RequestSetLobbyNickname = 4; + MsgId_RequestRegisterEvents = 5; + MsgId_RequestSendMessage = 6; +} + +enum ResponseMsgIds { + // STANDARD RESPONSES. + MsgId_ResponseChatLobbies = 1; + MsgId_ResponseRegisterEvents = 2; + MsgId_ResponseSendMessage = 6; + + // EVENTS + MsgId_EventLobbyInvite = 101; + MsgId_EventChatMessage = 102; +} + +/////////////////////////////////////////////////////////////// +// BUILDING BLOCKS. + +// This is a combination of ChatLobbyInfo & PublicChatLobbyRecord. +// Which seem very similar?? + +enum LobbyPrivacyLevel { + PRIVATE = 1; + PUBLIC = 2; +} + +enum ChatType { + TYPE_PRIVATE = 1; + TYPE_LOBBY = 2; + TYPE_GROUP = 3; +} + +message ChatLobbyInfo { + required string lobby_id = 1; + required string lobby_topic = 2; + required string lobby_name = 3; + + required string lobby_nickname = 4; // empty for none set. + + enum LobbyState { + JOINED = 1; + INVITED = 2; + PUBLIC = 3; + } + + required LobbyPrivacyLevel privacy_level = 5; + required LobbyState lobby_state = 6; + + required uint32 no_peers = 7; + required uint32 last_report_time = 8; + required uint32 last_activity = 9; + + repeated string participating_friends = 10; // SSL_IDS? + repeated string nick_names = 11; +} + + +message ChatMessage { + + required ChatType chat_type = 1; + required string chat_id = 2; + + required string peer_nickname = 3; + required uint32 chatflags = 4; + + required uint32 sendTime = 5; + required uint32 recvTime = 6; + + required string msg = 7; + } + + +// RESPONSE: ResponseChatLobbies +// This is a generic Response - used often. +// lobbies, will contain a list of affected / requested Lobbies. +message ResponseChatLobbies { + + required rsctrl.core.Status status = 1; + repeated ChatLobbyInfo lobbies = 2; +} + + + +/////////////////////////////////////////////////////////////// + +// REQUEST: RequestChatLobbies +message RequestChatLobbies { + + enum LobbyType { + ALL = 1; + NEW = 2; + INVITED = 3; + PRIVATE = 4; + PUBLIC = 5; + } + + required LobbyType lobby_type = 1; + +} + +// RESPONSE: ResponseChatLobbies + +/////////////////////////////////////////////////////////////// + + +// REQUEST: RequestCreateLobby +message RequestCreateLobby { + + required string lobby_name = 1; + required string lobby_topic = 2; + + required LobbyPrivacyLevel privacy_level = 4; + + repeated string invited_friends = 3; // SSL_IDS? +} + +// RESPONSE: ResponseChatLobbies + +/////////////////////////////////////////////////////////////// + +// Accept / Deny Invite, Join / Leave Lobby (these can be combined?) + +// REQUEST: RequestJoinOrLeaveLobby +message RequestJoinOrLeaveLobby { + + enum LobbyAction { + JOIN_OR_ACCEPT = 1; + LEAVE_OR_DENY = 2; + } + + required string lobby_id = 1; + required LobbyAction action = 2; +} + +// RESPONSE: ResponseChatLobbies + +/////////////////////////////////////////////////////////////// + +// Set Nickname. +// Get is done via requesting ChatLobby Info. +// Empty lobby_ids => default id. + +// REQUEST: RequestSetLobbyNickname +message RequestSetLobbyNickname { + required string nickname = 1; + repeated string lobby_ids = 2; +} + +// RESPONSE: ResponseChatLobbies + +/////////////////////////////////////////////////////////////// + +// Request Chat Events. +// This is done by registering for events. + +// REQUEST: ReqestRegisterEvents +message RequestRegisterEvents { + + enum RegisterAction { + REGISTER = 1; + DEREGISTER = 1; + } + + required RegisterAction action = 1; +} + +// RESPONSE: ResponseRegisterEvents +message ResponseRegisterEvents { + required rsctrl.core.Status status = 1; +} + +// RESPONSE: EventLobbyInvite +message EventLobbyInvite { + required ChatLobbyInfo lobby = 1; +} + +// RESPONSE: EventChatMessage +message EventChatMessage { + required ChatMessage msg = 1; +} + +/////////////////////////////////////////////////////////////// +// Send Message. + +// Request Chat Events. +// This is done by registering for events. + +// REQUEST: RequestSendMessage +message RequestSendMessage { + required ChatMessage msg = 2; +} + +// RESPONSE: ResponseSendMessage +message ResponseSendMessage { + required rsctrl.core.Status status = 1; +} + +/////////////////////////////////////////////////////////////// + diff --git a/rsctrl/src/definition/core.proto b/rsctrl/src/definition/core.proto index 58da5bef8..ddf3f2466 100644 --- a/rsctrl/src/definition/core.proto +++ b/rsctrl/src/definition/core.proto @@ -14,8 +14,10 @@ enum ExtensionId { CORE = 0; } enum PackageId { PEERS = 1; SYSTEM = 2; - FILES = 3; - MSGS = 4; + // BELOW HERE IS STILL BEING DESIGNED. + //CHAT = 3; + //FILES = 4; + //MSGS = 5; // THEORETICAL ONES. GXS = 1000; From 46c945de9674147578e4ecf797eaffef5a4945fc Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sat, 1 Sep 2012 14:47:22 +0000 Subject: [PATCH 047/222] nxs msg transaction now working and test commited some clean up still needed (msgs to sync should be determined by grp flag in db) git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5497 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgxsnetservice.cc | 229 +++++++++++++++--- libretroshare/src/gxs/rsgxsnetservice.h | 3 + .../src/tests/gxs/nxstestscenario.cc | 17 +- .../src/tests/gxs/rsgxsnetservice_test.cc | 2 +- libretroshare/src/util/contentvalue.cc | 1 + 5 files changed, 215 insertions(+), 37 deletions(-) diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index e619e1ebd..5becd34ec 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -28,7 +28,7 @@ #define NXS_NET_DEBUG -#define SYNC_PERIOD 10 // in microseconds every 10 seconds (1 second for testing) +#define SYNC_PERIOD 12 // in microseconds every 10 seconds (1 second for testing) #define TRANSAC_TIMEOUT 5 // 5 seconds @@ -85,14 +85,23 @@ void RsGxsNetService::syncWithPeers() sendItem(grp); } -// // TODO msgs -// for(; sit != peers.end(); sit++) -// { -// RsNxsSyncMsg* msg = new RsNxsSyncMsg(mServType); -// msg->clear(); -// msg->PeerId(*sit); -// sendItem(msg); -// } + sit = peers.begin(); + // TODO msgs + for(; sit != peers.end(); sit++) + { + RsStackMutex stack(mNxsMutex); + + std::set::iterator sit_grp = mGroupSubscribedTo.begin(); + + for(; sit_grp != mGroupSubscribedTo.end(); sit_grp++) + { + RsNxsSyncMsg* msg = new RsNxsSyncMsg(mServType); + msg->clear(); + msg->PeerId(*sit); + msg->grpId = *sit_grp; + sendItem(msg); + } + } } @@ -334,8 +343,8 @@ void RsGxsNetService::run(){ bool RsGxsNetService::locked_checkTransacTimedOut(NxsTransaction* tr) { - //return tr->mTimeOut < ((uint32_t) time(NULL)); - return false; + return tr->mTimeOut < ((uint32_t) time(NULL)); + // return false; } void RsGxsNetService::processTransactions(){ @@ -591,6 +600,10 @@ void RsGxsNetService::locked_processCompletedIncomingTrans(NxsTransaction* tr) { tr->mItems.pop_front(); grps.push_back(grp); + + //TODO: remove subscription should be handled + // outside netservice + mGroupSubscribedTo.insert(grp->grpId); } else { @@ -605,6 +618,8 @@ void RsGxsNetService::locked_processCompletedIncomingTrans(NxsTransaction* tr) // notify listener of grps mObserver->notifyNewGroups(grps); + + }else if(flag & RsNxsTransac::FLAG_TYPE_MSGS) { @@ -627,6 +642,8 @@ void RsGxsNetService::locked_processCompletedIncomingTrans(NxsTransaction* tr) } } + int nitems = msgs.size(); + // notify listener of msgs mObserver->notifyNewMessages(msgs); @@ -735,10 +752,10 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr) // get grp id for this transaction RsNxsSyncMsgItem* item = msgItemL.front(); const std::string& grpId = item->grpId; - GxsMsgReq reqIds; - reqIds[grpId] = std::vector(); + GxsMsgReq reqIds; + reqIds[grpId] = std::vector(); GxsMsgMetaResult result; - mDataStore->retrieveGxsMsgMetaData(reqIds, result); + mDataStore->retrieveGxsMsgMetaData(reqIds, result); std::vector &msgMetaV = result[grpId]; std::vector::const_iterator vit = msgMetaV.begin(); @@ -756,6 +773,8 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr) std::list::iterator llit = msgItemL.begin(); std::list reqList; + const std::string peerFrom = tr->mTransaction->PeerId(); + for(; llit != msgItemL.end(); llit++) { const std::string& msgId = (*llit)->msgId; @@ -766,11 +785,12 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr) msgItem->msgId = msgId; msgItem->flag = RsNxsSyncMsgItem::FLAG_REQUEST; msgItem->transactionNumber = transN; + msgItem->PeerId(peerFrom); reqList.push_back(msgItem); } } - if(reqList.empty()) + if(!reqList.empty()) { RsNxsTransac* transac = new RsNxsTransac(mServType); @@ -852,26 +872,36 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr) } - RsNxsTransac* transac = new RsNxsTransac(mServType); - transac->transactFlag = RsNxsTransac::FLAG_TYPE_GRP_LIST_REQ - | RsNxsTransac::FLAG_BEGIN_P1; - transac->timestamp = 0; - transac->nItems = reqList.size(); - transac->PeerId(tr->mTransaction->PeerId()); - transac->transactionNumber = transN; + if(!reqList.empty()) + { - NxsTransaction* newTrans = new NxsTransaction(); - newTrans->mItems = reqList; - newTrans->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM; - newTrans->mTimeOut = time(NULL) + mTransactionTimeOut; - newTrans->mTransaction = new RsNxsTransac(*transac); - newTrans->mTransaction->PeerId(mOwnId); + RsNxsTransac* transac = new RsNxsTransac(mServType); + transac->transactFlag = RsNxsTransac::FLAG_TYPE_GRP_LIST_REQ + | RsNxsTransac::FLAG_BEGIN_P1; + transac->timestamp = 0; + transac->nItems = reqList.size(); + transac->PeerId(tr->mTransaction->PeerId()); + transac->transactionNumber = transN; - sendItem(transac); + NxsTransaction* newTrans = new NxsTransaction(); + newTrans->mItems = reqList; + newTrans->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM; + newTrans->mTimeOut = time(NULL) + mTransactionTimeOut; + newTrans->mTransaction = new RsNxsTransac(*transac); + newTrans->mTransaction->PeerId(mOwnId); - if(!locked_addTransaction(newTrans)) - delete newTrans; + sendItem(transac); + if(!locked_addTransaction(newTrans)) + delete newTrans; + + } + + // clean up meta data + std::map::iterator mit = grpMetaMap.begin(); + + for(; mit != grpMetaMap.end(); mit++) + delete mit->second; } void RsGxsNetService::locked_genSendGrpsTransaction(NxsTransaction* tr) @@ -895,8 +925,13 @@ void RsGxsNetService::locked_genSendGrpsTransaction(NxsTransaction* tr) grps[item->grpId] = NULL; } - mDataStore->retrieveNxsGrps(grps, false, false); - + if(!grps.empty()) + { + mDataStore->retrieveNxsGrps(grps, false, false); + } + else{ + return; + } NxsTransaction* newTr = new NxsTransaction(); newTr->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM; @@ -908,7 +943,7 @@ void RsGxsNetService::locked_genSendGrpsTransaction(NxsTransaction* tr) std::string peerId = tr->mTransaction->PeerId(); for(;mit != grps.end(); mit++) { - mit->second->PeerId(peerId); // set so it gets sent to right peer + mit->second->PeerId(peerId); // set so it gets sent to right peer mit->second->transactionNumber = transN; newTr->mItems.push_back(mit->second); } @@ -941,6 +976,77 @@ void RsGxsNetService::locked_genSendGrpsTransaction(NxsTransaction* tr) void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr) { +#ifdef NXS_NET_DEBUG + std::cerr << "locked_genSendMsgsTransaction()" << std::endl; + std::cerr << "Generating Msg data send fron TransN: " << tr->mTransaction->transactionNumber + << std::endl; +#endif + + // go groups requested in transaction tr + + std::list::iterator lit = tr->mItems.begin(); + + GxsMsgReq msgIds; + GxsMsgResult msgs; + + if(tr->mItems.empty()){ + return; + } + + for(;lit != tr->mItems.end(); lit++) + { + RsNxsSyncMsgItem* item = dynamic_cast(*lit); + msgIds[item->grpId].push_back(item->msgId); + } + + mDataStore->retrieveNxsMsgs(msgIds, msgs, false, false); + + NxsTransaction* newTr = new NxsTransaction(); + newTr->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM; + + uint32_t transN = locked_getTransactionId(); + + // store grp items to send in transaction + GxsMsgResult::iterator mit = msgs.begin(); + std::string peerId = tr->mTransaction->PeerId(); + uint32_t msgSize = 0; + + for(;mit != msgs.end(); mit++) + { + std::vector& msgV = mit->second; + std::vector::iterator vit = msgV.begin(); + + for(; vit != msgV.end(); vit++) + { + RsNxsMsg* msg = *vit; + msg->PeerId(peerId); + msg->transactionNumber = transN; + newTr->mItems.push_back(msg); + msgSize++; + } + } + + if(newTr->mItems.empty()){ + delete newTr; + return; + } + + RsNxsTransac* ntr = new RsNxsTransac(mServType); + ntr->transactionNumber = transN; + ntr->transactFlag = RsNxsTransac::FLAG_BEGIN_P1 | + RsNxsTransac::FLAG_TYPE_MSGS; + ntr->nItems = msgSize; + ntr->PeerId(peerId); + + newTr->mTransaction = new RsNxsTransac(*ntr); + newTr->mTransaction->PeerId(mOwnId); + newTr->mTimeOut = time(NULL) + mTransactionTimeOut; + + ntr->PeerId(tr->mTransaction->PeerId()); + sendItem(ntr); + + locked_addTransaction(newTr); + return; } uint32_t RsGxsNetService::locked_getTransactionId() @@ -1040,6 +1146,61 @@ void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrp* item) void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsg* item) { RsStackMutex stack(mNxsMutex); + + const std::string& peer = item->PeerId(); + + GxsMsgMetaResult metaResult; + GxsMsgReq req; + req[item->grpId] = std::vector(); + mDataStore->retrieveGxsMsgMetaData(req, metaResult); + + std::vector& msgMeta = metaResult[item->grpId]; + + if(req.empty()){ + return; + } + + std::vector::iterator vit = msgMeta.begin(); + + NxsTransaction* tr = new NxsTransaction(); + std::list& itemL = tr->mItems; + + uint32_t transN = locked_getTransactionId(); + + for(; vit != msgMeta.end(); vit++) + { + RsGxsMsgMetaData* m = *vit; + RsNxsSyncMsgItem* mItem = new + RsNxsSyncMsgItem(mServType); + mItem->flag = RsNxsSyncGrpItem::FLAG_RESPONSE; + mItem->grpId = m->mGroupId; + mItem->msgId = m->mMsgId; + mItem->PeerId(peer); + mItem->transactionNumber = transN; + itemL.push_back(mItem); + } + + tr->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM; + RsNxsTransac* trItem = new RsNxsTransac(mServType); + trItem->transactFlag = RsNxsTransac::FLAG_BEGIN_P1 + | RsNxsTransac::FLAG_TYPE_MSG_LIST_RESP; + + trItem->nItems = itemL.size(); + + trItem->timestamp = 0; + trItem->PeerId(peer); + trItem->transactionNumber = transN; + + // also make a copy for the resident transaction + tr->mTransaction = new RsNxsTransac(*trItem); + tr->mTransaction->PeerId(mOwnId); + tr->mTimeOut = time(NULL) + mTransactionTimeOut; + + // signal peer to prepare for transaction + sendItem(trItem); + + locked_addTransaction(tr); + return; } diff --git a/libretroshare/src/gxs/rsgxsnetservice.h b/libretroshare/src/gxs/rsgxsnetservice.h index c4c0b9b40..096e5c8c7 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.h +++ b/libretroshare/src/gxs/rsgxsnetservice.h @@ -395,6 +395,9 @@ private: RsMutex mNxsMutex; uint32_t mSyncTs; + // TODO: remove, temp, for testing. + // subscription handled outside netservice + std::set mGroupSubscribedTo; const uint32_t mSYNC_PERIOD; }; diff --git a/libretroshare/src/tests/gxs/nxstestscenario.cc b/libretroshare/src/tests/gxs/nxstestscenario.cc index 61c0cac72..e5806a8a9 100644 --- a/libretroshare/src/tests/gxs/nxstestscenario.cc +++ b/libretroshare/src/tests/gxs/nxstestscenario.cc @@ -8,6 +8,7 @@ #include "nxstestscenario.h" #include "gxs/rsdataservice.h" #include "data_support.h" +#include NxsMessageTest::NxsMessageTest(uint16_t servtype) : mServType(servtype), mMsgTestMtx("mMsgTestMtx") @@ -42,7 +43,7 @@ RsGeneralDataService* NxsMessageTest::getDataService(const std::string& peer) { if(mPeerStoreMap.find(peer) != mPeerStoreMap.end()) return NULL; - RsDataService* dStore = new RsDataService("./", peer.c_str(), mServType); + RsDataService* dStore = new RsDataService("./", peer, mServType); mStoreNames.insert(peer); mPeerStoreMap.insert(std::make_pair(peer, dStore)); populateStore(dStore); @@ -134,7 +135,6 @@ void NxsMessageTest::populateStore(RsGeneralDataService* dStore) void NxsMessageTest::cleanUp() { - std::map::iterator mit = mPeerStoreMap.begin(); for(; mit != mPeerStoreMap.end(); mit++) @@ -177,5 +177,18 @@ void NxsMessageTestObserver::notifyNewGroups(std::vector &groups) void NxsMessageTestObserver::notifyNewMessages(std::vector &messages) { + std::vector::iterator vit = messages.begin(); + std::map msgs; + + for(; vit != messages.end(); vit++) + { + RsNxsMsg* msg = *vit; + RsGxsMsgMetaData* meta = new RsGxsMsgMetaData(); + meta->mGroupId = msg->grpId; + meta->mMsgId = msg->msgId; + msgs.insert(std::make_pair(msg, meta)); + } + + mStore->storeMessage(msgs); } diff --git a/libretroshare/src/tests/gxs/rsgxsnetservice_test.cc b/libretroshare/src/tests/gxs/rsgxsnetservice_test.cc index d187ad144..ddcc2f6c0 100644 --- a/libretroshare/src/tests/gxs/rsgxsnetservice_test.cc +++ b/libretroshare/src/tests/gxs/rsgxsnetservice_test.cc @@ -25,7 +25,7 @@ int main() // now get things started createThread(hub); - double timeDelta = 30; + double timeDelta = 50; // put this thread to sleep for 10 secs // make thread sleep for a bit diff --git a/libretroshare/src/util/contentvalue.cc b/libretroshare/src/util/contentvalue.cc index 58f237cf7..cce492df3 100644 --- a/libretroshare/src/util/contentvalue.cc +++ b/libretroshare/src/util/contentvalue.cc @@ -112,6 +112,7 @@ ContentValue::ContentValue(ContentValue &from){ default: std::cerr << "ContentValue::ContentValue(ContentValue &from):" << "Error! Unrecognised data type!" << std::endl; + break; } } } From 9c2f7f39e76da70d7002528508710739b2076dd8 Mon Sep 17 00:00:00 2001 From: drbob Date: Sat, 1 Sep 2012 19:35:23 +0000 Subject: [PATCH 048/222] Added Multiple Channels and Event support to RPC system. * added chan_id parameter to many RPC calls, this allows RPC to support multiple SSH clients. - the combination of (chan_id, req_id) rather than req_id, should be unique now -> TODO inside rpcserver queued requests. * Modified SSH server to match the new API. Multiple client support has not been added here yet. * Modified Menu System to match these changes too. * Added an Registration Framework to RpcQueueService, to enable easy event support. This code has not been throughly tested yet. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5500 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/menu/menu.cc | 10 +- retroshare-nogui/src/menu/menu.h | 2 +- retroshare-nogui/src/menu/stdiocomms.cc | 27 +- retroshare-nogui/src/menu/stdiocomms.h | 18 +- .../src/rpc/proto/rpcprotopeers.cc | 20 +- .../src/rpc/proto/rpcprotopeers.h | 8 +- .../src/rpc/proto/rpcprotosystem.cc | 8 +- .../src/rpc/proto/rpcprotosystem.h | 4 +- retroshare-nogui/src/rpc/rpc.cc | 51 ++-- retroshare-nogui/src/rpc/rpc.h | 6 +- retroshare-nogui/src/rpc/rpcecho.cc | 4 +- retroshare-nogui/src/rpc/rpcecho.h | 2 +- retroshare-nogui/src/rpc/rpcserver.cc | 284 +++++++++++++++++- retroshare-nogui/src/rpc/rpcserver.h | 41 ++- retroshare-nogui/src/rpcsystem.h | 21 +- retroshare-nogui/src/ssh/rssshd.cc | 29 +- retroshare-nogui/src/ssh/rssshd.h | 17 +- 17 files changed, 435 insertions(+), 117 deletions(-) diff --git a/retroshare-nogui/src/menu/menu.cc b/retroshare-nogui/src/menu/menu.cc index bfe55e048..46852a4f3 100644 --- a/retroshare-nogui/src/menu/menu.cc +++ b/retroshare-nogui/src/menu/menu.cc @@ -37,7 +37,7 @@ */ // RsTermServer Interface. -void MenuInterface::reset() +void MenuInterface::reset(uint32_t /* chan_id */) { mBase->reset(); mCurrentMenu = mBase; @@ -59,7 +59,9 @@ int MenuInterface::tick() uint8_t keypress; std::string output; - int read = mComms->recv(&keypress, 1); + uint32_t chan_id = 1; // dummy - for menu system. + + int read = mComms->recv(chan_id, &keypress, 1); #ifdef MENU_DEBUG std::cerr << "MenuInterface::tick() read " << read << " bytes"; std::cerr << std::endl; @@ -78,7 +80,7 @@ int MenuInterface::tick() else { /* error, NON BLOCKING is handled by recv returning 0 */ - mComms->error("Bad Input"); + mComms->error(chan_id, "Bad Input"); return -1; } @@ -121,7 +123,7 @@ int MenuInterface::tick() if (output.size() > 0) { - mComms->send(output); + mComms->send(chan_id, output); } return (haveInput); diff --git a/retroshare-nogui/src/menu/menu.h b/retroshare-nogui/src/menu/menu.h index 0feaec1b5..c667e64dd 100644 --- a/retroshare-nogui/src/menu/menu.h +++ b/retroshare-nogui/src/menu/menu.h @@ -232,7 +232,7 @@ public: uint32_t drawHeader(uint32_t drawFlags, std::string &buffer); // RsSystem Interface. - virtual void reset(); + virtual void reset(uint32_t chan_id); virtual int tick(); diff --git a/retroshare-nogui/src/menu/stdiocomms.cc b/retroshare-nogui/src/menu/stdiocomms.cc index 08d1abb76..99d982616 100644 --- a/retroshare-nogui/src/menu/stdiocomms.cc +++ b/retroshare-nogui/src/menu/stdiocomms.cc @@ -66,7 +66,16 @@ int StdioComms::isOkay() } -int StdioComms::error(std::string msg) +int StdioComms::active_channels(std::list &chan_ids) +{ + if (isOkay()) + { + chan_ids.push_back(1); // only one possible here (stdin/stdout) + } + return 1; +} + +int StdioComms::error(uint32_t chan_id, std::string msg) { std::cerr << "StdioComms::error(" << msg << ")"; std::cerr << std::endl; @@ -75,14 +84,14 @@ int StdioComms::error(std::string msg) -int StdioComms::recv_ready() +int StdioComms::recv_ready(uint32_t chan_id) { /* should be proper poll / select! - but we don't use this at the moment */ return 1; } -int StdioComms::recv(uint8_t *buffer, int bytes) +int StdioComms::recv(uint32_t chan_id, uint8_t *buffer, int bytes) { int size = read(mIn, buffer, bytes); std::cerr << "StdioComms::recv() returned: " << size; @@ -102,7 +111,7 @@ int StdioComms::recv(uint8_t *buffer, int bytes) } -int StdioComms::recv(std::string &buffer, int bytes) +int StdioComms::recv(uint32_t chan_id, std::string &buffer, int bytes) { uint8_t tmpbuffer[bytes]; int size = read(mIn, tmpbuffer, bytes); @@ -114,7 +123,7 @@ int StdioComms::recv(std::string &buffer, int bytes) } // these make it easier... -int StdioComms::recv_blocking(uint8_t *buffer, int bytes) +int StdioComms::recv_blocking(uint32_t chan_id, uint8_t *buffer, int bytes) { int totalread = 0; while(totalread < bytes) @@ -137,10 +146,10 @@ int StdioComms::recv_blocking(uint8_t *buffer, int bytes) } -int StdioComms::recv_blocking(std::string &buffer, int bytes) +int StdioComms::recv_blocking(uint32_t chan_id, std::string &buffer, int bytes) { uint8_t tmpbuffer[bytes]; - int size = recv_blocking(tmpbuffer, bytes); + int size = recv_blocking(chan_id, tmpbuffer, bytes); if (size < 0) return size; // error. @@ -152,14 +161,14 @@ int StdioComms::recv_blocking(std::string &buffer, int bytes) } -int StdioComms::send(uint8_t *buffer, int bytes) +int StdioComms::send(uint32_t chan_id, uint8_t *buffer, int bytes) { write(mOut, buffer, bytes); return bytes; } -int StdioComms::send(const std::string &output) +int StdioComms::send(uint32_t chan_id, const std::string &output) { if (output.size() > 0) { diff --git a/retroshare-nogui/src/menu/stdiocomms.h b/retroshare-nogui/src/menu/stdiocomms.h index bad510d6c..bc559af4c 100644 --- a/retroshare-nogui/src/menu/stdiocomms.h +++ b/retroshare-nogui/src/menu/stdiocomms.h @@ -36,18 +36,20 @@ public: StdioComms(int infd, int outfd); virtual int isOkay(); - virtual int error(std::string msg); + virtual int error(uint32_t chan_id, std::string msg); - virtual int recv_ready(); - virtual int recv(uint8_t *buffer, int bytes); - virtual int recv(std::string &buffer, int bytes); + virtual int active_channels(std::list &chan_ids); + + virtual int recv_ready(uint32_t chan_id); + virtual int recv(uint32_t chan_id, uint8_t *buffer, int bytes); + virtual int recv(uint32_t chan_id, std::string &buffer, int bytes); // these make it easier... - virtual int recv_blocking(uint8_t *buffer, int bytes); - virtual int recv_blocking(std::string &buffer, int bytes); + virtual int recv_blocking(uint32_t chan_id, uint8_t *buffer, int bytes); + virtual int recv_blocking(uint32_t chan_id, std::string &buffer, int bytes); - virtual int send(uint8_t *buffer, int bytes); - virtual int send(const std::string &buffer); + virtual int send(uint32_t chan_id, uint8_t *buffer, int bytes); + virtual int send(uint32_t chan_id, const std::string &buffer); private: int mIn, mOut; diff --git a/retroshare-nogui/src/rpc/proto/rpcprotopeers.cc b/retroshare-nogui/src/rpc/proto/rpcprotopeers.cc index 7943f3248..aefe0312d 100644 --- a/retroshare-nogui/src/rpc/proto/rpcprotopeers.cc +++ b/retroshare-nogui/src/rpc/proto/rpcprotopeers.cc @@ -38,7 +38,7 @@ RpcProtoPeers::RpcProtoPeers(uint32_t serviceId) //RpcProtoPeers::msgsAccepted(std::list &msgIds); /* not used at the moment */ -int RpcProtoPeers::processMsg(uint32_t msg_id, uint32_t req_id, const std::string &msg) +int RpcProtoPeers::processMsg(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg) { /* check the msgId */ uint8_t topbyte = getRpcMsgIdExtension(msg_id); @@ -83,13 +83,13 @@ int RpcProtoPeers::processMsg(uint32_t msg_id, uint32_t req_id, const std::strin switch(submsg) { case rsctrl::peers::MsgId_RequestPeers: - processRequestPeers(msg_id, req_id, msg); + processRequestPeers(chan_id, msg_id, req_id, msg); break; case rsctrl::peers::MsgId_RequestAddPeer: - processAddPeer(msg_id, req_id, msg); + processAddPeer(chan_id, msg_id, req_id, msg); break; case rsctrl::peers::MsgId_RequestModifyPeer: - processModifyPeer(msg_id, req_id, msg); + processModifyPeer(chan_id, msg_id, req_id, msg); break; default: std::cerr << "RpcProtoPeers::processMsg() ERROR should never get here"; @@ -102,7 +102,7 @@ int RpcProtoPeers::processMsg(uint32_t msg_id, uint32_t req_id, const std::strin } -int RpcProtoPeers::processAddPeer(uint32_t msg_id, uint32_t req_id, const std::string &msg) +int RpcProtoPeers::processAddPeer(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg) { std::cerr << "RpcProtoPeers::processAddPeer() NOT FINISHED"; std::cerr << std::endl; @@ -136,13 +136,13 @@ int RpcProtoPeers::processAddPeer(uint32_t msg_id, uint32_t req_id, const std::s rsctrl::peers::MsgId_ResponseAddPeer, true); // queue it. - queueResponse(out_msg_id, req_id, outmsg); + queueResponse(chan_id, out_msg_id, req_id, outmsg); return 1; } -int RpcProtoPeers::processModifyPeer(uint32_t msg_id, uint32_t req_id, const std::string &msg) +int RpcProtoPeers::processModifyPeer(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg) { std::cerr << "RpcProtoPeers::processModifyPeer() NOT FINISHED"; std::cerr << std::endl; @@ -177,14 +177,14 @@ int RpcProtoPeers::processModifyPeer(uint32_t msg_id, uint32_t req_id, const std rsctrl::peers::MsgId_ResponseModifyPeer, true); // queue it. - queueResponse(out_msg_id, req_id, outmsg); + queueResponse(chan_id, out_msg_id, req_id, outmsg); return 1; } -int RpcProtoPeers::processRequestPeers(uint32_t msg_id, uint32_t req_id, const std::string &msg) +int RpcProtoPeers::processRequestPeers(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg) { std::cerr << "RpcProtoPeers::processRequestPeers()"; std::cerr << std::endl; @@ -421,7 +421,7 @@ int RpcProtoPeers::processRequestPeers(uint32_t msg_id, uint32_t req_id, const s rsctrl::peers::MsgId_ResponsePeerList, true); // queue it. - queueResponse(out_msg_id, req_id, outmsg); + queueResponse(chan_id, out_msg_id, req_id, outmsg); return 1; } diff --git a/retroshare-nogui/src/rpc/proto/rpcprotopeers.h b/retroshare-nogui/src/rpc/proto/rpcprotopeers.h index 969aa1a59..92e91d88a 100644 --- a/retroshare-nogui/src/rpc/proto/rpcprotopeers.h +++ b/retroshare-nogui/src/rpc/proto/rpcprotopeers.h @@ -32,11 +32,11 @@ class RpcProtoPeers: public RpcQueueService public: RpcProtoPeers(uint32_t serviceId); // virtual msgsAccepted(std::list &msgIds); /* not used at the moment */ - virtual int processMsg(uint32_t msgId, uint32_t req_id, const std::string &msg); + virtual int processMsg(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); - virtual int processRequestPeers(uint32_t msg_id, uint32_t req_id, const std::string &msg); - virtual int processAddPeer(uint32_t msg_id, uint32_t req_id, const std::string &msg); - virtual int processModifyPeer(uint32_t msg_id, uint32_t req_id, const std::string &msg); + virtual int processRequestPeers(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); + virtual int processAddPeer(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); + virtual int processModifyPeer(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); }; diff --git a/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc b/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc index abdc7d626..29c7c5cbc 100644 --- a/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc +++ b/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc @@ -39,7 +39,7 @@ RpcProtoSystem::RpcProtoSystem(uint32_t serviceId) //RpcProtoSystem::msgsAccepted(std::list &msgIds); /* not used at the moment */ -int RpcProtoSystem::processMsg(uint32_t msg_id, uint32_t req_id, const std::string &msg) +int RpcProtoSystem::processMsg(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg) { /* check the msgId */ uint8_t topbyte = getRpcMsgIdExtension(msg_id); @@ -84,7 +84,7 @@ int RpcProtoSystem::processMsg(uint32_t msg_id, uint32_t req_id, const std::stri switch(submsg) { case rsctrl::system::MsgId_RequestSystemStatus: - processSystemStatus(msg_id, req_id, msg); + processSystemStatus(chan_id, msg_id, req_id, msg); break; default: std::cerr << "RpcProtoSystem::processMsg() ERROR should never get here"; @@ -97,7 +97,7 @@ int RpcProtoSystem::processMsg(uint32_t msg_id, uint32_t req_id, const std::stri } -int RpcProtoSystem::processSystemStatus(uint32_t msg_id, uint32_t req_id, const std::string &msg) +int RpcProtoSystem::processSystemStatus(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg) { std::cerr << "RpcProtoSystem::processSystemStatus()"; std::cerr << std::endl; @@ -205,7 +205,7 @@ int RpcProtoSystem::processSystemStatus(uint32_t msg_id, uint32_t req_id, const rsctrl::system::MsgId_ResponseSystemStatus, true); // queue it. - queueResponse(out_msg_id, req_id, outmsg); + queueResponse(chan_id, out_msg_id, req_id, outmsg); return 1; } diff --git a/retroshare-nogui/src/rpc/proto/rpcprotosystem.h b/retroshare-nogui/src/rpc/proto/rpcprotosystem.h index 57dfcb1de..db29cf207 100644 --- a/retroshare-nogui/src/rpc/proto/rpcprotosystem.h +++ b/retroshare-nogui/src/rpc/proto/rpcprotosystem.h @@ -32,9 +32,9 @@ class RpcProtoSystem: public RpcQueueService public: RpcProtoSystem(uint32_t serviceId); // virtual msgsAccepted(std::list &msgIds); /* not used at the moment */ - virtual int processMsg(uint32_t msgId, uint32_t req_id, const std::string &msg); + virtual int processMsg(uint32_t chan_id, uint32_t msgId, uint32_t req_id, const std::string &msg); - virtual int processSystemStatus(uint32_t msg_id, uint32_t req_id, const std::string &msg); + virtual int processSystemStatus(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); }; diff --git a/retroshare-nogui/src/rpc/rpc.cc b/retroshare-nogui/src/rpc/rpc.cc index 368baf22e..6fd5a0b74 100644 --- a/retroshare-nogui/src/rpc/rpc.cc +++ b/retroshare-nogui/src/rpc/rpc.cc @@ -38,9 +38,9 @@ RpcMediator::RpcMediator(RpcComms *c) return; } -void RpcMediator::reset() +void RpcMediator::reset(uint32_t chan_id) { - mServer->reset(); + mServer->reset(chan_id); } @@ -57,6 +57,11 @@ int RpcMediator::tick() worked = true; } + if (mServer->checkEvents()) + { + worked = true; + } + if (worked) return 1; else @@ -68,19 +73,26 @@ int RpcMediator::tick() int RpcMediator::recv() { int recvd = 0; - while(recv_msg()) + + std::list chan_ids; + std::list::iterator it; + mComms->active_channels(chan_ids); + for(it = chan_ids.begin(); it != chan_ids.end(); it++) { - recvd = 1; + while(recv_msg(*it)) + { + recvd = 1; + } } return recvd; } -int RpcMediator::recv_msg() +int RpcMediator::recv_msg(uint32_t chan_id) { /* nothing in here needs a Mutex... */ - if (!mComms->recv_ready()) + if (!mComms->recv_ready(chan_id)) { return 0; } @@ -99,14 +111,14 @@ int RpcMediator::recv_msg() std::cerr << "RpcMediator::recv_msg() get Header: " << bufsize; std::cerr << " bytes" << std::endl; - int read = mComms->recv_blocking(buffer, bufsize); + int read = mComms->recv_blocking(chan_id, buffer, bufsize); if (read != bufsize) { /* error */ std::cerr << "RpcMediator::recv_msg() Error Reading Header: " << bufsize; std::cerr << " bytes" << std::endl; - mComms->error("Failed to Recv Header"); + mComms->error(chan_id, "Failed to Recv Header"); return 0; } @@ -116,11 +128,12 @@ int RpcMediator::recv_msg() std::cerr << "RpcMediator::recv_msg() Error Deserialising Header"; std::cerr << std::endl; - mComms->error("Failed to Deserialise Header"); + mComms->error(chan_id, "Failed to Deserialise Header"); return 0; } - std::cerr << "RpcMediator::recv_msg() MsgId: " << msg_id; + std::cerr << "RpcMediator::recv_msg() ChanId: " << chan_id; + std::cerr << " MsgId: " << msg_id; std::cerr << " ReqId: " << req_id; std::cerr << std::endl; @@ -128,27 +141,27 @@ int RpcMediator::recv_msg() std::cerr << " bytes" << std::endl; /* grab real size */ - read = mComms->recv_blocking(msg_body, msg_size); + read = mComms->recv_blocking(chan_id, msg_body, msg_size); if (read != msg_size) { /* error */ std::cerr << "RpcMediator::recv_msg() Error Reading Body: " << bufsize; std::cerr << " bytes" << std::endl; - mComms->error("Failed to Recv MsgBody"); + mComms->error(chan_id, "Failed to Recv MsgBody"); return 0; } - mServer->processMsg(msg_id, req_id, msg_body); + mServer->processMsg(chan_id, msg_id, req_id, msg_body); return 1; } -int RpcMediator::send(uint32_t msg_id, uint32_t req_id, const std::string &msg) +int RpcMediator::send(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg) { std::cerr << "RpcMediator::send(" << msg_id << "," << req_id << ", len("; - std::cerr << msg.size() << "))"; + std::cerr << msg.size() << ")) on chan_id: " << chan_id; std::cerr << std::endl; uint8_t buffer[kMsgHeaderSize]; @@ -164,22 +177,22 @@ int RpcMediator::send(uint32_t msg_id, uint32_t req_id, const std::string &msg) return 0; } - if (!mComms->send(buffer, bufsize)) + if (!mComms->send(chan_id, buffer, bufsize)) { std::cerr << "RpcMediator::send() Send Header Failed"; std::cerr << std::endl; /* error */ - mComms->error("Failed to Send Header"); + mComms->error(chan_id, "Failed to Send Header"); return 0; } /* now send the body */ - if (!mComms->send(msg)) + if (!mComms->send(chan_id, msg)) { std::cerr << "RpcMediator::send() Send Body Failed"; std::cerr << std::endl; /* error */ - mComms->error("Failed to Send Msg"); + mComms->error(chan_id, "Failed to Send Msg"); return 0; } return 1; diff --git a/retroshare-nogui/src/rpc/rpc.h b/retroshare-nogui/src/rpc/rpc.h index ff1817cd1..33e9dec9e 100644 --- a/retroshare-nogui/src/rpc/rpc.h +++ b/retroshare-nogui/src/rpc/rpc.h @@ -43,12 +43,12 @@ public: void setRpcServer(RpcServer *s) { mServer = s; } /* Must only be called during setup */ // Overloaded from RpcSystem. -virtual void reset(); +virtual void reset(uint32_t chan_id); virtual int tick(); int recv(); - int recv_msg(); - int send(uint32_t msg_id, uint32_t req_id, const std::string &msg); + int recv_msg(uint32_t chan_id); + int send(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); private: RpcComms *mComms; diff --git a/retroshare-nogui/src/rpc/rpcecho.cc b/retroshare-nogui/src/rpc/rpcecho.cc index ff01ccaf8..b11220bb8 100644 --- a/retroshare-nogui/src/rpc/rpcecho.cc +++ b/retroshare-nogui/src/rpc/rpcecho.cc @@ -29,10 +29,10 @@ RpcEcho::RpcEcho(uint32_t serviceId) return; } -int RpcEcho::processMsg(uint32_t msg_id, uint32_t req_id, const std::string &msg) +int RpcEcho::processMsg(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg) { /* */ - queueResponse(msg_id, req_id, msg); + queueResponse(chan_id, msg_id, req_id, msg); return 1; } diff --git a/retroshare-nogui/src/rpc/rpcecho.h b/retroshare-nogui/src/rpc/rpcecho.h index a72871382..b34446310 100644 --- a/retroshare-nogui/src/rpc/rpcecho.h +++ b/retroshare-nogui/src/rpc/rpcecho.h @@ -31,7 +31,7 @@ class RpcEcho: public RpcQueueService { public: RpcEcho(uint32_t serviceId); - virtual int processMsg(uint32_t msgId, uint32_t req_id, const std::string &msg); + virtual int processMsg(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); }; diff --git a/retroshare-nogui/src/rpc/rpcserver.cc b/retroshare-nogui/src/rpc/rpcserver.cc index 0f167d1da..4b796097b 100644 --- a/retroshare-nogui/src/rpc/rpcserver.cc +++ b/retroshare-nogui/src/rpc/rpcserver.cc @@ -33,9 +33,9 @@ RpcServer::RpcServer(RpcMediator *med) } -void RpcServer::reset() +void RpcServer::reset(uint32_t chan_id) { - std::cerr << "RpcServer::reset()" << std::endl; + std::cerr << "RpcServer::reset(" << chan_id << ")" << std::endl; { RsStackMutex stack(mRpcMtx); /********** LOCKED MUTEX ***************/ @@ -43,7 +43,7 @@ void RpcServer::reset() for(it = mAllServices.begin(); it != mAllServices.end(); it++) { /* in mutex, but should be okay */ - (*it)->reset(); + (*it)->reset(chan_id); } // clear existing queue. @@ -64,22 +64,24 @@ int RpcServer::addService(RpcService *service) } -int RpcServer::processMsg(uint32_t msg_id, uint32_t req_id, const std::string &msg) +int RpcServer::processMsg(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg) { std::cerr << "RpcServer::processMsg(" << msg_id << "," << req_id; - std::cerr << ", len(" << msg.size() << "))" << std::endl; + std::cerr << ", len(" << msg.size() << ")) from channel: " << chan_id; + std::cerr << std::endl; + { RsStackMutex stack(mRpcMtx); /********** LOCKED MUTEX ***************/ std::list::iterator it; for(it = mAllServices.begin(); it != mAllServices.end(); it++) { - int rt = (*it)->processMsg(msg_id, req_id, msg); + int rt = (*it)->processMsg(chan_id, msg_id, req_id, msg); if (!rt) continue; /* remember request */ - queueRequest_locked(msg_id, req_id, (*it)); + queueRequest_locked(chan_id, msg_id, req_id, (*it)); return 1; } } @@ -89,7 +91,7 @@ int RpcServer::processMsg(uint32_t msg_id, uint32_t req_id, const std::string &m return 0; } -int RpcServer::queueRequest_locked(uint32_t /* msgId */, uint32_t req_id, RpcService *service) +int RpcServer::queueRequest_locked(uint32_t /* chan_id */, uint32_t /* msgId */, uint32_t req_id, RpcService *service) { std::cerr << "RpcServer::queueRequest_locked() req_id: " << req_id; std::cerr << std::endl; @@ -116,18 +118,21 @@ bool RpcServer::checkPending() std::list::iterator it; for(it = mRpcQueue.begin(); it != mRpcQueue.end();) { + uint32_t out_chan_id = 0; uint32_t out_msg_id = 0; uint32_t out_req_id = it->mReqId; std::string out_msg; - if (it->mService->getResponse(out_msg_id, out_req_id, out_msg)) + if (it->mService->getResponse(out_chan_id, out_msg_id, out_req_id, out_msg)) { std::cerr << "RpcServer::checkPending() Response: ("; std::cerr << out_msg_id << "," << out_req_id; std::cerr << ", len(" << out_msg.size() << "))"; + std::cerr << " for chan_id: " << out_chan_id; std::cerr << std::endl; /* store and send after queue is processed */ RpcQueuedMsg msg; + msg.mChanId = out_chan_id; msg.mMsgId = out_msg_id; msg.mReqId = out_req_id; msg.mMsg = out_msg; @@ -153,6 +158,30 @@ bool RpcServer::checkPending() return someRemaining; } + +bool RpcServer::checkEvents() +{ + std::list msgsToSend; + bool someToSend = false; + + { + RsStackMutex stack(mRpcMtx); /********** LOCKED MUTEX ***************/ + + std::list::iterator it; + for(it = mAllServices.begin(); it != mAllServices.end(); it++) + { + if ((*it)->getEvents(msgsToSend)) + someToSend = true; + } + } + + if (someToSend) + { + sendQueuedMsgs(msgsToSend); + } + return someToSend; +} + bool RpcServer::sendQueuedMsgs(std::list &msgs) { /* No need for lock, as mOut is the only accessed item - and that has own protection */ @@ -163,7 +192,7 @@ bool RpcServer::sendQueuedMsgs(std::list &msgs) std::list::iterator it; for (it = msgs.begin(); it != msgs.end(); it++) { - mMediator->send(it->mMsgId, it->mReqId, it->mMsg); + mMediator->send(it->mChanId, it->mMsgId, it->mReqId, it->mMsg); } return true; } @@ -181,16 +210,35 @@ RpcQueueService::RpcQueueService(uint32_t serviceId) } -void RpcQueueService::reset() +void RpcQueueService::reset(uint32_t chan_id) { + clearEventsForChannel(chan_id); + RsStackMutex stack(mQueueMtx); /********** LOCKED MUTEX ***************/ - // clear existing queue. - mResponses.clear(); + std::list toRemove; + + // iterate through and remove only chan_id items. + std::map::iterator mit; + for(mit = mResponses.begin(); mit != mResponses.end(); mit++) + { + if (mit->second.mChanId == chan_id) + toRemove.push_back(mit->first); + } + + /* remove items */ + std::list::iterator rit; + for(rit = toRemove.begin(); rit != toRemove.end(); rit++) + { + mit = mResponses.find(*rit); + mResponses.erase(mit); + } + + return; } -int RpcQueueService::getResponse(uint32_t &msg_id, uint32_t &req_id, std::string &msg) +int RpcQueueService::getResponse(uint32_t &chan_id, uint32_t &msg_id, uint32_t &req_id, std::string &msg) { RsStackMutex stack(mQueueMtx); /********** LOCKED MUTEX ***************/ @@ -202,6 +250,7 @@ int RpcQueueService::getResponse(uint32_t &msg_id, uint32_t &req_id, std::string return 0; } + chan_id = it->second.mChanId; msg_id = it->second.mMsgId; msg = it->second.mMsg; @@ -210,11 +259,12 @@ int RpcQueueService::getResponse(uint32_t &msg_id, uint32_t &req_id, std::string return 1; } -int RpcQueueService::queueResponse(uint32_t msg_id, uint32_t req_id, const std::string &msg) +int RpcQueueService::queueResponse(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg) { RsStackMutex stack(mQueueMtx); /********** LOCKED MUTEX ***************/ RpcQueuedMsg qmsg; + qmsg.mChanId = chan_id; qmsg.mMsgId = msg_id; qmsg.mReqId = req_id; qmsg.mMsg = msg; @@ -225,6 +275,210 @@ int RpcQueueService::queueResponse(uint32_t msg_id, uint32_t req_id, const std:: } + + +/********* Events & Registration ******/ + + +int RpcQueueService::getEvents(std::list &events) +{ + RsStackMutex stack(mQueueMtx); /********** LOCKED MUTEX ***************/ + + std::map >::iterator it; + for(it = mEventRegister.begin(); it != mEventRegister.end(); it++) + { + locked_checkForEvents(it->first, it->second, events); + } + + if (events.empty()) + { + return 0; + } + return 1; +} + +int RpcQueueService::locked_checkForEvents(uint32_t event, const std::list ®istered, std::list &events) +{ + std::cerr << "RpcQueueService::locked_checkForEvents() NOT IMPLEMENTED"; + std::cerr << std::endl; + std::cerr << "\tRegistered for Event Type: " << event; + std::cerr << std::endl; + + std::list::const_iterator it; + for(it = registered.begin(); it != registered.end(); it++) + { + std::cerr << "\t\t Channel ID: " << it->mChanId; + std::cerr << " Request ID: " << it->mReqId; + std::cerr << std::endl; + } + + return 1; +} + +int RpcQueueService::registerForEvents(uint32_t chan_id, uint32_t req_id, uint32_t event_id) +{ + std::cerr << "RpcQueueService::registerForEvents(ChanId: " << chan_id; + std::cerr << ", ReqId: " << req_id; + std::cerr << ", EventId: " << event_id; + std::cerr << ")"; + std::cerr << std::endl; + + RsStackMutex stack(mQueueMtx); /********** LOCKED MUTEX ***************/ + + std::map >::iterator mit; + mit = mEventRegister.find(event_id); + if (mit == mEventRegister.end()) + { + std::list emptyList; + mEventRegister[event_id] = emptyList; + + mit = mEventRegister.find(event_id); + } + + RpcEventRegister reg; + reg.mChanId = chan_id; + reg.mReqId = req_id; + reg.mEventId = event_id; + + mit->second.push_back(reg); + + return 1; +} + +int RpcQueueService::deregisterForEvents(uint32_t chan_id, uint32_t req_id, uint32_t event_id) +{ + std::cerr << "RpcQueueService::deregisterForEvents(ChanId: " << chan_id; + std::cerr << ", ReqId: " << req_id; + std::cerr << ", EventId: " << event_id; + std::cerr << ")"; + std::cerr << std::endl; + + RsStackMutex stack(mQueueMtx); /********** LOCKED MUTEX ***************/ + + std::map >::iterator mit; + mit = mEventRegister.find(event_id); + if (mit == mEventRegister.end()) + { + std::cerr << "RpcQueueService::deregisterForEvents() "; + std::cerr << "ERROR no EventId: " << event_id; + std::cerr << std::endl; + + return 0; + } + + bool removed = false; + std::list::iterator lit; + for(lit = mit->second.begin(); lit != mit->second.end();) + { + /* remove all matches */ + if ((lit->mReqId == req_id) && (lit->mChanId == chan_id)) + { + lit = mit->second.erase(lit); + if (removed == true) + { + std::cerr << "RpcQueueService::deregisterForEvents() "; + std::cerr << "WARNING REMOVING MULTIPLE MATCHES"; + std::cerr << std::endl; + } + removed = true; + } + else + { + lit++; + } + } + + if (mit->second.empty()) + { + std::cerr << "RpcQueueService::deregisterForEvents() "; + std::cerr << " Last Registrant for Event, removing List from Map"; + std::cerr << std::endl; + + mEventRegister.erase(mit); + } + + return 1; +} + + +int RpcQueueService::clearEventsForChannel(uint32_t chan_id) +{ + std::cerr << "RpcQueueService::clearEventsForChannel(" << chan_id; + std::cerr << ")"; + std::cerr << std::endl; + + RsStackMutex stack(mQueueMtx); /********** LOCKED MUTEX ***************/ + + std::list toMapRemove; + + std::map >::iterator mit; + for(mit = mEventRegister.begin(); mit != mEventRegister.end(); mit++) + { + std::list::iterator lit; + for(lit = mit->second.begin(); lit != mit->second.end();) + { + /* remove all matches */ + if (lit->mChanId == chan_id) + { + std::cerr << "RpcQueueService::clearEventsForChannel() "; + std::cerr << " Removing ReqId: " << lit->mReqId; + std::cerr << " for EventId: " << lit->mEventId; + std::cerr << std::endl; + + lit = mit->second.erase(lit); + } + else + { + lit++; + } + } + if (mit->second.empty()) + { + toMapRemove.push_back(mit->first); + } + } + + /* remove any empty lists now */ + std::list::iterator rit; + for(rit = toMapRemove.begin(); rit != toMapRemove.end(); rit++) + { + mit = mEventRegister.find(*rit); + mEventRegister.erase(mit); + } + + return 1; +} + + +int RpcQueueService::printEventRegister(std::ostream &out) +{ + out << "RpcQueueService::printEventRegister()"; + out << std::endl; + + RsStackMutex stack(mQueueMtx); /********** LOCKED MUTEX ***************/ + + std::list toMapRemove; + + std::map >::iterator mit; + for(mit = mEventRegister.begin(); mit != mEventRegister.end(); mit++) + { + out << "Event: " << mit->first; + out << std::endl; + + std::list::iterator lit; + for(lit = mit->second.begin(); lit != mit->second.end(); lit++) + { + out << "\tRegistrant: ReqId: " << lit->mReqId; + out << "\t ChanId: " << lit->mChanId; + out << std::endl; + } + } + return 1; +} + + + + // Lower 8 bits. uint8_t getRpcMsgIdSubMsg(uint32_t msg_id) { diff --git a/retroshare-nogui/src/rpc/rpcserver.h b/retroshare-nogui/src/rpc/rpcserver.h index 4d506ef36..f92b4b5aa 100644 --- a/retroshare-nogui/src/rpc/rpcserver.h +++ b/retroshare-nogui/src/rpc/rpcserver.h @@ -48,6 +48,7 @@ uint32_t constructMsgId(uint8_t ext, uint16_t service, uint8_t submsg, bool is_r class RpcQueuedMsg { public: + uint32_t mChanId; uint32_t mMsgId; uint32_t mReqId; std::string mMsg; @@ -58,26 +59,47 @@ class RpcService { public: RpcService(uint32_t /* serviceId */ ) { return; } - virtual void reset() { return; } + virtual void reset(uint32_t /* chan_id */) { return; } virtual int msgsAccepted(std::list & /* msgIds */) { return 0; } /* not used at the moment */ - virtual int processMsg(uint32_t msgId, uint32_t req_id, const std::string &msg) = 0; /* returns 0 - not handled, > 0, accepted */ - virtual int getResponse(uint32_t &msgId, uint32_t &req_id, std::string &msg) = 0; /* 0 - not ready, > 0 heres the response */ + virtual int processMsg(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg) = 0; /* returns 0 - not handled, > 0, accepted */ + virtual int getResponse(uint32_t &chan_id, uint32_t &msgId, uint32_t &req_id, std::string &msg) = 0; /* 0 - not ready, > 0 heres the response */ + + virtual int getEvents(std::list & /* events */) { return 0; } /* 0 = none, optional feature */ }; +class RpcEventRegister +{ + public: + uint32_t mChanId; + uint32_t mReqId; + uint32_t mEventId; // THIS IS A LOCAL PARAMETER, Service Specific +}; /* Implements a Queue for quick implementation of Instant Response Services */ class RpcQueueService: public RpcService { public: RpcQueueService(uint32_t serviceId); -virtual void reset(); -virtual int getResponse(uint32_t &msgId, uint32_t &req_id, std::string &msg); +virtual void reset(uint32_t chan_id); +virtual int getResponse(uint32_t &chan_id, uint32_t &msg_id, uint32_t &req_id, std::string &msg); +virtual int getEvents(std::list &events); protected: - int queueResponse(uint32_t msgId, uint32_t req_id, const std::string &msg); + int queueResponse(uint32_t chan_id, uint32_t msgId, uint32_t req_id, const std::string &msg); + +virtual int locked_checkForEvents(uint32_t event, const std::list ®istered, std::list &events); // Overload for functionality. + + int registerForEvents(uint32_t chan_id, uint32_t req_id, uint32_t event_id); + int deregisterForEvents(uint32_t chan_id, uint32_t req_id, uint32_t event_id); + + int clearEventsForChannel(uint32_t chan_id); + int printEventRegister(std::ostream &out); + private: RsMutex mQueueMtx; + std::map mResponses; + std::map > mEventRegister; }; @@ -98,14 +120,15 @@ class RpcServer public: RpcServer(RpcMediator *med); int addService(RpcService *service); - int processMsg(uint32_t msgId, uint32_t req_id, const std::string &msg); + int processMsg(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); bool checkPending(); + bool checkEvents(); - void reset(); + void reset(uint32_t chan_id); private: bool sendQueuedMsgs(std::list &msgs); - int queueRequest_locked(uint32_t msgId, uint32_t req_id, RpcService *service); + int queueRequest_locked(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, RpcService *service); RpcMediator *mMediator; diff --git a/retroshare-nogui/src/rpcsystem.h b/retroshare-nogui/src/rpcsystem.h index db81d5702..dd1ccfc43 100644 --- a/retroshare-nogui/src/rpcsystem.h +++ b/retroshare-nogui/src/rpcsystem.h @@ -25,6 +25,7 @@ #ifndef RS_RPC_SYSTEM_H #define RS_RPC_SYSTEM_H +#include #include #include @@ -32,18 +33,20 @@ class RpcComms { public: virtual int isOkay() = 0; - virtual int error(std::string msg) = 0; + virtual int error(uint32_t chan_id, std::string msg) = 0; - virtual int recv_ready() = 0; - virtual int recv(uint8_t *buffer, int bytes) = 0; - virtual int recv(std::string &buffer, int bytes) = 0; + virtual int active_channels(std::list &chan_ids) = 0; + + virtual int recv_ready(uint32_t chan_id) = 0; + virtual int recv(uint32_t chan_id, uint8_t *buffer, int bytes) = 0; + virtual int recv(uint32_t chan_id, std::string &buffer, int bytes) = 0; // these make it easier... - virtual int recv_blocking(uint8_t *buffer, int bytes) = 0; - virtual int recv_blocking(std::string &buffer, int bytes) = 0; + virtual int recv_blocking(uint32_t chan_id, uint8_t *buffer, int bytes) = 0; + virtual int recv_blocking(uint32_t chan_id, std::string &buffer, int bytes) = 0; - virtual int send(uint8_t *buffer, int bytes) = 0; - virtual int send(const std::string &buffer) = 0; + virtual int send(uint32_t chan_id, uint8_t *buffer, int bytes) = 0; + virtual int send(uint32_t chan_id, const std::string &buffer) = 0; virtual int setSleepPeriods(float /* busy */, float /* idle */) { return 0; } }; @@ -53,7 +56,7 @@ class RpcSystem { public: /* this must be regularly ticked to update the display */ - virtual void reset() = 0; + virtual void reset(uint32_t chan_id) = 0; virtual int tick() = 0; }; diff --git a/retroshare-nogui/src/ssh/rssshd.cc b/retroshare-nogui/src/ssh/rssshd.cc index 94b1baf59..94360baed 100644 --- a/retroshare-nogui/src/ssh/rssshd.cc +++ b/retroshare-nogui/src/ssh/rssshd.cc @@ -471,7 +471,8 @@ int RsSshd::doRpcSystem() return 0; } - mRpcSystem->reset(); // clear everything for new user. + uint32_t dummy_chan_id = 1; + mRpcSystem->reset(dummy_chan_id); // clear everything for new user. bool okay = true; while(okay) @@ -511,8 +512,18 @@ int RsSshd::isOkay() return (mState == RSSSHD_STATE_CONNECTED); } + std::list::iterator it; +int RsSshd::active_channels(std::list &chan_ids) +{ + if (isOkay()) + { + chan_ids.push_back(1); // dummy for now. + } -int RsSshd::error(std::string msg) + return 1; +} + +int RsSshd::error(uint32_t chan_id, std::string msg) { std::cerr << "RsSshd::error(" << msg << ")"; std::cerr << std::endl; @@ -522,14 +533,14 @@ int RsSshd::error(std::string msg) } -int RsSshd::recv_ready() +int RsSshd::recv_ready(uint32_t chan_id) { int bytes = ssh_channel_poll(mChannel, 0); return bytes; } -int RsSshd::recv(uint8_t *buffer, int bytes) +int RsSshd::recv(uint32_t chan_id, uint8_t *buffer, int bytes) { #if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0) int size = ssh_channel_read_nonblocking(mChannel, buffer, bytes, 0); @@ -540,7 +551,7 @@ int RsSshd::recv(uint8_t *buffer, int bytes) } -int RsSshd::recv(std::string &buffer, int bytes) +int RsSshd::recv(uint32_t chan_id, std::string &buffer, int bytes) { char input[bytes]; #if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0) @@ -556,7 +567,7 @@ int RsSshd::recv(std::string &buffer, int bytes) } -int RsSshd::recv_blocking(uint8_t *buffer, int bytes) +int RsSshd::recv_blocking(uint32_t chan_id, uint8_t *buffer, int bytes) { #if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0) int size = ssh_channel_read(mChannel, buffer, bytes, 0); @@ -567,7 +578,7 @@ int RsSshd::recv_blocking(uint8_t *buffer, int bytes) } -int RsSshd::recv_blocking(std::string &buffer, int bytes) +int RsSshd::recv_blocking(uint32_t chan_id, std::string &buffer, int bytes) { char input[bytes]; #if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0) @@ -582,7 +593,7 @@ int RsSshd::recv_blocking(std::string &buffer, int bytes) return size; } -int RsSshd::send(uint8_t *buffer, int bytes) +int RsSshd::send(uint32_t chan_id, uint8_t *buffer, int bytes) { #if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0) ssh_channel_write(mChannel, buffer, bytes); @@ -592,7 +603,7 @@ int RsSshd::send(uint8_t *buffer, int bytes) return 1; } -int RsSshd::send(const std::string &buffer) +int RsSshd::send(uint32_t chan_id, const std::string &buffer) { #if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0) ssh_channel_write(mChannel, buffer.c_str(), buffer.size()); diff --git a/retroshare-nogui/src/ssh/rssshd.h b/retroshare-nogui/src/ssh/rssshd.h index 2f0a87d36..07f289d2a 100644 --- a/retroshare-nogui/src/ssh/rssshd.h +++ b/retroshare-nogui/src/ssh/rssshd.h @@ -83,17 +83,18 @@ int adduserpwdhash(std::string username, std::string hash); // RsComms Interface. virtual int isOkay(); - virtual int error(std::string msg); + virtual int error(uint32_t chan_id, std::string msg); - virtual int recv_ready(); + virtual int active_channels(std::list &chan_ids); + virtual int recv_ready(uint32_t chan_id); - virtual int recv(uint8_t *buffer, int bytes); - virtual int recv(std::string &buffer, int bytes); - virtual int recv_blocking(uint8_t *buffer, int bytes); - virtual int recv_blocking(std::string &buffer, int bytes); + virtual int recv(uint32_t chan_id, uint8_t *buffer, int bytes); + virtual int recv(uint32_t chan_id, std::string &buffer, int bytes); + virtual int recv_blocking(uint32_t chan_id, uint8_t *buffer, int bytes); + virtual int recv_blocking(uint32_t chan_id, std::string &buffer, int bytes); - virtual int send(uint8_t *buffer, int bytes); - virtual int send(const std::string &buffer); + virtual int send(uint32_t chan_id, uint8_t *buffer, int bytes); + virtual int send(uint32_t chan_id, const std::string &buffer); virtual int setSleepPeriods(float busy, float idle); From 9ad322d37993f9d64c86f1db59e918b7928ad1c1 Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 3 Sep 2012 19:11:17 +0000 Subject: [PATCH 049/222] Some changes to chat.proto - Changed ENUMs to include type in the name. - made non-essential member of ChatMessage optional. - Fixed some incorrect numbering. Enabled chat in core.proto & Makefile. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5507 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- rsctrl/src/Makefile | 4 +- rsctrl/src/definition/chat.proto | 93 +++++++++++++++++++++----------- rsctrl/src/definition/core.proto | 2 +- 3 files changed, 65 insertions(+), 34 deletions(-) diff --git a/rsctrl/src/Makefile b/rsctrl/src/Makefile index b879f4c0b..103370652 100644 --- a/rsctrl/src/Makefile +++ b/rsctrl/src/Makefile @@ -1,7 +1,7 @@ EXEC = protoc -#PROTO = core.proto files.proto gxs.proto msgs.proto peers.proto system.proto -PROTO = core.proto peers.proto system.proto +#PROTO = core.proto peers.proto system.proto chat.proto files.proto gxs.proto msgs.proto +PROTO = core.proto peers.proto system.proto chat.proto PROTOPATH = ./definition #CDESTPATH = ./gencc diff --git a/rsctrl/src/definition/chat.proto b/rsctrl/src/definition/chat.proto index b80c41ae3..12706e3ed 100644 --- a/rsctrl/src/definition/chat.proto +++ b/rsctrl/src/definition/chat.proto @@ -4,6 +4,12 @@ import "core.proto"; /////////////////////////////////////////////////////////////// // Private, Group and Chat Lobby RPC. +// +// OTHER COMMANDS TO ADD? +// Status Strings. +// Invite Friends to Private Lobbies. +// Chat History. +// ??? /////////////////////////////////////////////////////////////// enum RequestMsgIds { @@ -18,7 +24,8 @@ enum RequestMsgIds { enum ResponseMsgIds { // STANDARD RESPONSES. MsgId_ResponseChatLobbies = 1; - MsgId_ResponseRegisterEvents = 2; + MsgId_ResponseSetLobbyNickname = 4; + MsgId_ResponseRegisterEvents = 5; MsgId_ResponseSendMessage = 6; // EVENTS @@ -33,8 +40,8 @@ enum ResponseMsgIds { // Which seem very similar?? enum LobbyPrivacyLevel { - PRIVATE = 1; - PUBLIC = 2; + PRIVACY_PRIVATE = 1; + PRIVACY_PUBLIC = 2; } enum ChatType { @@ -51,9 +58,9 @@ message ChatLobbyInfo { required string lobby_nickname = 4; // empty for none set. enum LobbyState { - JOINED = 1; - INVITED = 2; - PUBLIC = 3; + LOBBYSTATE_JOINED = 1; + LOBBYSTATE_INVITED = 2; + LOBBYSTATE_PUBLIC = 3; } required LobbyPrivacyLevel privacy_level = 5; @@ -64,23 +71,29 @@ message ChatLobbyInfo { required uint32 last_activity = 9; repeated string participating_friends = 10; // SSL_IDS? - repeated string nick_names = 11; + repeated string nicknames = 11; } -message ChatMessage { +message ChatId { required ChatType chat_type = 1; - required string chat_id = 2; + required string chat_id = 2; - required string peer_nickname = 3; - required uint32 chatflags = 4; +} - required uint32 sendTime = 5; - required uint32 recvTime = 6; +message ChatMessage { - required string msg = 7; - } + required ChatId id = 1; + required string msg = 2; + + optional string peer_nickname = 3; + optional uint32 chat_flags = 4; + + optional uint32 send_time = 5; + optional uint32 recv_time = 6; + +} // RESPONSE: ResponseChatLobbies @@ -99,15 +112,14 @@ message ResponseChatLobbies { // REQUEST: RequestChatLobbies message RequestChatLobbies { - enum LobbyType { - ALL = 1; - NEW = 2; - INVITED = 3; - PRIVATE = 4; - PUBLIC = 5; + enum LobbySet { + LOBBYSET_ALL = 1; + LOBBYSET_JOINED = 2; + LOBBYSET_INVITED = 3; + LOBBYSET_PUBLIC = 4; } - required LobbyType lobby_type = 1; + required LobbySet lobby_set = 1; } @@ -124,7 +136,7 @@ message RequestCreateLobby { required LobbyPrivacyLevel privacy_level = 4; - repeated string invited_friends = 3; // SSL_IDS? + repeated string invited_friends = 3; // SSL_IDS } // RESPONSE: ResponseChatLobbies @@ -151,7 +163,7 @@ message RequestJoinOrLeaveLobby { // Set Nickname. // Get is done via requesting ChatLobby Info. -// Empty lobby_ids => default id. +// Empty lobby_ids => default Nickname. // REQUEST: RequestSetLobbyNickname message RequestSetLobbyNickname { @@ -159,19 +171,24 @@ message RequestSetLobbyNickname { repeated string lobby_ids = 2; } -// RESPONSE: ResponseChatLobbies +// RESPONSE: ResponseSetLobbyNickname +// Didnt think the whole Lobby status was necessary. +message ResponseSetLobbyNickname { + required rsctrl.core.Status status = 1; +} + /////////////////////////////////////////////////////////////// // Request Chat Events. // This is done by registering for events. -// REQUEST: ReqestRegisterEvents +// REQUEST: RequestRegisterEvents message RequestRegisterEvents { enum RegisterAction { REGISTER = 1; - DEREGISTER = 1; + DEREGISTER = 2; } required RegisterAction action = 1; @@ -195,12 +212,9 @@ message EventChatMessage { /////////////////////////////////////////////////////////////// // Send Message. -// Request Chat Events. -// This is done by registering for events. - // REQUEST: RequestSendMessage message RequestSendMessage { - required ChatMessage msg = 2; + required ChatMessage msg = 1; } // RESPONSE: ResponseSendMessage @@ -209,4 +223,21 @@ message ResponseSendMessage { } /////////////////////////////////////////////////////////////// +//// Chat History. +//// THIS IS NOT IMPLEMENTED YET, DONT USE. +// +//// REQUEST: RequestChatHistory +//message RequestChatHistory { +// required ChatId id = 1; /* lobby or chat, group id */ +// required bool incoming = 2; +//} +// +//// RESPONSE: ResponseChatHistory +//message ResponseChatHistory { +// required rsctrl.core.Status status = 1; +// repeated ChatMessage msg = 2; +//} +// +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// diff --git a/rsctrl/src/definition/core.proto b/rsctrl/src/definition/core.proto index ddf3f2466..58d550077 100644 --- a/rsctrl/src/definition/core.proto +++ b/rsctrl/src/definition/core.proto @@ -14,8 +14,8 @@ enum ExtensionId { CORE = 0; } enum PackageId { PEERS = 1; SYSTEM = 2; + CHAT = 3; // BELOW HERE IS STILL BEING DESIGNED. - //CHAT = 3; //FILES = 4; //MSGS = 5; From 84074fdca15fa8a2bef2e69983a7272a09a48962 Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 3 Sep 2012 19:18:59 +0000 Subject: [PATCH 050/222] * Adding Chat RPC support into retroshare-nogui. ( About 90% there, and 40% tested. ) - RPC commands are outlined in the proto file. - You can: get listing, send msg, register for recv events, change nickname and join/create lobbiey - updated chat & core generated files. * Added RpcUniqueId(chan_id, req_id) for identifying requests. - Modified Responses Queues to use new datatype. * Fixed reset to occur after the connection has died. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5508 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/retroshare-nogui.pro | 4 + .../src/rpc/proto/gencc/chat.pb.cc | 5019 +++++++++++++++++ .../src/rpc/proto/gencc/chat.pb.h | 3325 +++++++++++ .../src/rpc/proto/gencc/core.pb.cc | 7 +- .../src/rpc/proto/gencc/core.pb.h | 3 +- .../src/rpc/proto/rpcprotochat.cc | 1286 +++++ retroshare-nogui/src/rpc/proto/rpcprotochat.h | 53 + retroshare-nogui/src/rpc/rpcserver.cc | 33 +- retroshare-nogui/src/rpc/rpcserver.h | 17 +- retroshare-nogui/src/rpc/rpcsetup.cc | 4 + retroshare-nogui/src/ssh/rssshd.cc | 2 + 11 files changed, 9736 insertions(+), 17 deletions(-) create mode 100644 retroshare-nogui/src/rpc/proto/gencc/chat.pb.cc create mode 100644 retroshare-nogui/src/rpc/proto/gencc/chat.pb.h create mode 100644 retroshare-nogui/src/rpc/proto/rpcprotochat.cc create mode 100644 retroshare-nogui/src/rpc/proto/rpcprotochat.h diff --git a/retroshare-nogui/src/retroshare-nogui.pro b/retroshare-nogui/src/retroshare-nogui.pro index ec7571f3f..619531b37 100644 --- a/retroshare-nogui/src/retroshare-nogui.pro +++ b/retroshare-nogui/src/retroshare-nogui.pro @@ -186,18 +186,22 @@ protorpc { # Proto Services HEADERS += rpc/proto/rpcprotopeers.h \ rpc/proto/rpcprotosystem.h \ + rpc/proto/rpcprotochat.h \ SOURCES += rpc/proto/rpcprotopeers.cc \ rpc/proto/rpcprotosystem.cc \ + rpc/proto/rpcprotochat.cc \ # Generated ProtoBuf Code the RPC System HEADERS += rpc/proto/gencc/core.pb.h \ rpc/proto/gencc/peers.pb.h \ rpc/proto/gencc/system.pb.h \ + rpc/proto/gencc/chat.pb.h \ SOURCES += rpc/proto/gencc/core.pb.cc \ rpc/proto/gencc/peers.pb.cc \ rpc/proto/gencc/system.pb.cc \ + rpc/proto/gencc/chat.pb.cc \ QMAKE_CFLAGS += -pthread QMAKE_CXXFLAGS += -pthread diff --git a/retroshare-nogui/src/rpc/proto/gencc/chat.pb.cc b/retroshare-nogui/src/rpc/proto/gencc/chat.pb.cc new file mode 100644 index 000000000..cff430bdb --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/gencc/chat.pb.cc @@ -0,0 +1,5019 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "chat.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace rsctrl { +namespace chat { + +namespace { + +const ::google::protobuf::Descriptor* ChatLobbyInfo_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ChatLobbyInfo_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* ChatLobbyInfo_LobbyState_descriptor_ = NULL; +const ::google::protobuf::Descriptor* ChatId_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ChatId_reflection_ = NULL; +const ::google::protobuf::Descriptor* ChatMessage_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ChatMessage_reflection_ = NULL; +const ::google::protobuf::Descriptor* ResponseChatLobbies_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ResponseChatLobbies_reflection_ = NULL; +const ::google::protobuf::Descriptor* RequestChatLobbies_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestChatLobbies_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* RequestChatLobbies_LobbySet_descriptor_ = NULL; +const ::google::protobuf::Descriptor* RequestCreateLobby_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestCreateLobby_reflection_ = NULL; +const ::google::protobuf::Descriptor* RequestJoinOrLeaveLobby_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestJoinOrLeaveLobby_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* RequestJoinOrLeaveLobby_LobbyAction_descriptor_ = NULL; +const ::google::protobuf::Descriptor* RequestSetLobbyNickname_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestSetLobbyNickname_reflection_ = NULL; +const ::google::protobuf::Descriptor* ResponseSetLobbyNickname_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ResponseSetLobbyNickname_reflection_ = NULL; +const ::google::protobuf::Descriptor* RequestRegisterEvents_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestRegisterEvents_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* RequestRegisterEvents_RegisterAction_descriptor_ = NULL; +const ::google::protobuf::Descriptor* ResponseRegisterEvents_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ResponseRegisterEvents_reflection_ = NULL; +const ::google::protobuf::Descriptor* EventLobbyInvite_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + EventLobbyInvite_reflection_ = NULL; +const ::google::protobuf::Descriptor* EventChatMessage_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + EventChatMessage_reflection_ = NULL; +const ::google::protobuf::Descriptor* RequestSendMessage_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestSendMessage_reflection_ = NULL; +const ::google::protobuf::Descriptor* ResponseSendMessage_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ResponseSendMessage_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* LobbyPrivacyLevel_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* ChatType_descriptor_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_chat_2eproto() { + protobuf_AddDesc_chat_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "chat.proto"); + GOOGLE_CHECK(file != NULL); + ChatLobbyInfo_descriptor_ = file->message_type(0); + static const int ChatLobbyInfo_offsets_[11] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatLobbyInfo, lobby_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatLobbyInfo, lobby_topic_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatLobbyInfo, lobby_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatLobbyInfo, lobby_nickname_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatLobbyInfo, privacy_level_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatLobbyInfo, lobby_state_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatLobbyInfo, no_peers_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatLobbyInfo, last_report_time_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatLobbyInfo, last_activity_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatLobbyInfo, participating_friends_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatLobbyInfo, nicknames_), + }; + ChatLobbyInfo_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ChatLobbyInfo_descriptor_, + ChatLobbyInfo::default_instance_, + ChatLobbyInfo_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatLobbyInfo, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatLobbyInfo, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ChatLobbyInfo)); + ChatLobbyInfo_LobbyState_descriptor_ = ChatLobbyInfo_descriptor_->enum_type(0); + ChatId_descriptor_ = file->message_type(1); + static const int ChatId_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatId, chat_type_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatId, chat_id_), + }; + ChatId_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ChatId_descriptor_, + ChatId::default_instance_, + ChatId_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatId, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatId, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ChatId)); + ChatMessage_descriptor_ = file->message_type(2); + static const int ChatMessage_offsets_[6] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatMessage, id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatMessage, msg_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatMessage, peer_nickname_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatMessage, chat_flags_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatMessage, send_time_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatMessage, recv_time_), + }; + ChatMessage_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ChatMessage_descriptor_, + ChatMessage::default_instance_, + ChatMessage_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatMessage, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ChatMessage, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ChatMessage)); + ResponseChatLobbies_descriptor_ = file->message_type(3); + static const int ResponseChatLobbies_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseChatLobbies, status_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseChatLobbies, lobbies_), + }; + ResponseChatLobbies_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ResponseChatLobbies_descriptor_, + ResponseChatLobbies::default_instance_, + ResponseChatLobbies_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseChatLobbies, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseChatLobbies, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ResponseChatLobbies)); + RequestChatLobbies_descriptor_ = file->message_type(4); + static const int RequestChatLobbies_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestChatLobbies, lobby_set_), + }; + RequestChatLobbies_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestChatLobbies_descriptor_, + RequestChatLobbies::default_instance_, + RequestChatLobbies_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestChatLobbies, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestChatLobbies, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestChatLobbies)); + RequestChatLobbies_LobbySet_descriptor_ = RequestChatLobbies_descriptor_->enum_type(0); + RequestCreateLobby_descriptor_ = file->message_type(5); + static const int RequestCreateLobby_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestCreateLobby, lobby_name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestCreateLobby, lobby_topic_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestCreateLobby, privacy_level_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestCreateLobby, invited_friends_), + }; + RequestCreateLobby_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestCreateLobby_descriptor_, + RequestCreateLobby::default_instance_, + RequestCreateLobby_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestCreateLobby, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestCreateLobby, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestCreateLobby)); + RequestJoinOrLeaveLobby_descriptor_ = file->message_type(6); + static const int RequestJoinOrLeaveLobby_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestJoinOrLeaveLobby, lobby_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestJoinOrLeaveLobby, action_), + }; + RequestJoinOrLeaveLobby_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestJoinOrLeaveLobby_descriptor_, + RequestJoinOrLeaveLobby::default_instance_, + RequestJoinOrLeaveLobby_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestJoinOrLeaveLobby, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestJoinOrLeaveLobby, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestJoinOrLeaveLobby)); + RequestJoinOrLeaveLobby_LobbyAction_descriptor_ = RequestJoinOrLeaveLobby_descriptor_->enum_type(0); + RequestSetLobbyNickname_descriptor_ = file->message_type(7); + static const int RequestSetLobbyNickname_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestSetLobbyNickname, nickname_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestSetLobbyNickname, lobby_ids_), + }; + RequestSetLobbyNickname_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestSetLobbyNickname_descriptor_, + RequestSetLobbyNickname::default_instance_, + RequestSetLobbyNickname_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestSetLobbyNickname, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestSetLobbyNickname, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestSetLobbyNickname)); + ResponseSetLobbyNickname_descriptor_ = file->message_type(8); + static const int ResponseSetLobbyNickname_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSetLobbyNickname, status_), + }; + ResponseSetLobbyNickname_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ResponseSetLobbyNickname_descriptor_, + ResponseSetLobbyNickname::default_instance_, + ResponseSetLobbyNickname_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSetLobbyNickname, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSetLobbyNickname, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ResponseSetLobbyNickname)); + RequestRegisterEvents_descriptor_ = file->message_type(9); + static const int RequestRegisterEvents_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestRegisterEvents, action_), + }; + RequestRegisterEvents_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestRegisterEvents_descriptor_, + RequestRegisterEvents::default_instance_, + RequestRegisterEvents_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestRegisterEvents, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestRegisterEvents, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestRegisterEvents)); + RequestRegisterEvents_RegisterAction_descriptor_ = RequestRegisterEvents_descriptor_->enum_type(0); + ResponseRegisterEvents_descriptor_ = file->message_type(10); + static const int ResponseRegisterEvents_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseRegisterEvents, status_), + }; + ResponseRegisterEvents_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ResponseRegisterEvents_descriptor_, + ResponseRegisterEvents::default_instance_, + ResponseRegisterEvents_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseRegisterEvents, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseRegisterEvents, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ResponseRegisterEvents)); + EventLobbyInvite_descriptor_ = file->message_type(11); + static const int EventLobbyInvite_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EventLobbyInvite, lobby_), + }; + EventLobbyInvite_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + EventLobbyInvite_descriptor_, + EventLobbyInvite::default_instance_, + EventLobbyInvite_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EventLobbyInvite, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EventLobbyInvite, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(EventLobbyInvite)); + EventChatMessage_descriptor_ = file->message_type(12); + static const int EventChatMessage_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EventChatMessage, msg_), + }; + EventChatMessage_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + EventChatMessage_descriptor_, + EventChatMessage::default_instance_, + EventChatMessage_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EventChatMessage, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EventChatMessage, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(EventChatMessage)); + RequestSendMessage_descriptor_ = file->message_type(13); + static const int RequestSendMessage_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestSendMessage, msg_), + }; + RequestSendMessage_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestSendMessage_descriptor_, + RequestSendMessage::default_instance_, + RequestSendMessage_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestSendMessage, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestSendMessage, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestSendMessage)); + ResponseSendMessage_descriptor_ = file->message_type(14); + static const int ResponseSendMessage_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSendMessage, status_), + }; + ResponseSendMessage_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ResponseSendMessage_descriptor_, + ResponseSendMessage::default_instance_, + ResponseSendMessage_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSendMessage, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSendMessage, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ResponseSendMessage)); + RequestMsgIds_descriptor_ = file->enum_type(0); + ResponseMsgIds_descriptor_ = file->enum_type(1); + LobbyPrivacyLevel_descriptor_ = file->enum_type(2); + ChatType_descriptor_ = file->enum_type(3); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_chat_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ChatLobbyInfo_descriptor_, &ChatLobbyInfo::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ChatId_descriptor_, &ChatId::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ChatMessage_descriptor_, &ChatMessage::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ResponseChatLobbies_descriptor_, &ResponseChatLobbies::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestChatLobbies_descriptor_, &RequestChatLobbies::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestCreateLobby_descriptor_, &RequestCreateLobby::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestJoinOrLeaveLobby_descriptor_, &RequestJoinOrLeaveLobby::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestSetLobbyNickname_descriptor_, &RequestSetLobbyNickname::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ResponseSetLobbyNickname_descriptor_, &ResponseSetLobbyNickname::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestRegisterEvents_descriptor_, &RequestRegisterEvents::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ResponseRegisterEvents_descriptor_, &ResponseRegisterEvents::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + EventLobbyInvite_descriptor_, &EventLobbyInvite::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + EventChatMessage_descriptor_, &EventChatMessage::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestSendMessage_descriptor_, &RequestSendMessage::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ResponseSendMessage_descriptor_, &ResponseSendMessage::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_chat_2eproto() { + delete ChatLobbyInfo::default_instance_; + delete ChatLobbyInfo_reflection_; + delete ChatId::default_instance_; + delete ChatId_reflection_; + delete ChatMessage::default_instance_; + delete ChatMessage_reflection_; + delete ResponseChatLobbies::default_instance_; + delete ResponseChatLobbies_reflection_; + delete RequestChatLobbies::default_instance_; + delete RequestChatLobbies_reflection_; + delete RequestCreateLobby::default_instance_; + delete RequestCreateLobby_reflection_; + delete RequestJoinOrLeaveLobby::default_instance_; + delete RequestJoinOrLeaveLobby_reflection_; + delete RequestSetLobbyNickname::default_instance_; + delete RequestSetLobbyNickname_reflection_; + delete ResponseSetLobbyNickname::default_instance_; + delete ResponseSetLobbyNickname_reflection_; + delete RequestRegisterEvents::default_instance_; + delete RequestRegisterEvents_reflection_; + delete ResponseRegisterEvents::default_instance_; + delete ResponseRegisterEvents_reflection_; + delete EventLobbyInvite::default_instance_; + delete EventLobbyInvite_reflection_; + delete EventChatMessage::default_instance_; + delete EventChatMessage_reflection_; + delete RequestSendMessage::default_instance_; + delete RequestSendMessage_reflection_; + delete ResponseSendMessage::default_instance_; + delete ResponseSendMessage_reflection_; +} + +void protobuf_AddDesc_chat_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::rsctrl::core::protobuf_AddDesc_core_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\nchat.proto\022\013rsctrl.chat\032\ncore.proto\"\236\003" + "\n\rChatLobbyInfo\022\020\n\010lobby_id\030\001 \002(\t\022\023\n\013lob" + "by_topic\030\002 \002(\t\022\022\n\nlobby_name\030\003 \002(\t\022\026\n\016lo" + "bby_nickname\030\004 \002(\t\0225\n\rprivacy_level\030\005 \002(" + "\0162\036.rsctrl.chat.LobbyPrivacyLevel\022:\n\013lob" + "by_state\030\006 \002(\0162%.rsctrl.chat.ChatLobbyIn" + "fo.LobbyState\022\020\n\010no_peers\030\007 \002(\r\022\030\n\020last_" + "report_time\030\010 \002(\r\022\025\n\rlast_activity\030\t \002(\r" + "\022\035\n\025participating_friends\030\n \003(\t\022\021\n\tnickn" + "ames\030\013 \003(\t\"R\n\nLobbyState\022\025\n\021LOBBYSTATE_J" + "OINED\020\001\022\026\n\022LOBBYSTATE_INVITED\020\002\022\025\n\021LOBBY" + "STATE_PUBLIC\020\003\"C\n\006ChatId\022(\n\tchat_type\030\001 " + "\002(\0162\025.rsctrl.chat.ChatType\022\017\n\007chat_id\030\002 " + "\002(\t\"\214\001\n\013ChatMessage\022\037\n\002id\030\001 \002(\0132\023.rsctrl" + ".chat.ChatId\022\013\n\003msg\030\002 \002(\t\022\025\n\rpeer_nickna" + "me\030\003 \001(\t\022\022\n\nchat_flags\030\004 \001(\r\022\021\n\tsend_tim" + "e\030\005 \001(\r\022\021\n\trecv_time\030\006 \001(\r\"g\n\023ResponseCh" + "atLobbies\022#\n\006status\030\001 \002(\0132\023.rsctrl.core." + "Status\022+\n\007lobbies\030\002 \003(\0132\032.rsctrl.chat.Ch" + "atLobbyInfo\"\257\001\n\022RequestChatLobbies\022;\n\tlo" + "bby_set\030\001 \002(\0162(.rsctrl.chat.RequestChatL" + "obbies.LobbySet\"\\\n\010LobbySet\022\020\n\014LOBBYSET_" + "ALL\020\001\022\023\n\017LOBBYSET_JOINED\020\002\022\024\n\020LOBBYSET_I" + "NVITED\020\003\022\023\n\017LOBBYSET_PUBLIC\020\004\"\215\001\n\022Reques" + "tCreateLobby\022\022\n\nlobby_name\030\001 \002(\t\022\023\n\013lobb" + "y_topic\030\002 \002(\t\0225\n\rprivacy_level\030\004 \002(\0162\036.r" + "sctrl.chat.LobbyPrivacyLevel\022\027\n\017invited_" + "friends\030\003 \003(\t\"\243\001\n\027RequestJoinOrLeaveLobb" + "y\022\020\n\010lobby_id\030\001 \002(\t\022@\n\006action\030\002 \002(\01620.rs" + "ctrl.chat.RequestJoinOrLeaveLobby.LobbyA" + "ction\"4\n\013LobbyAction\022\022\n\016JOIN_OR_ACCEPT\020\001" + "\022\021\n\rLEAVE_OR_DENY\020\002\">\n\027RequestSetLobbyNi" + "ckname\022\020\n\010nickname\030\001 \002(\t\022\021\n\tlobby_ids\030\002 " + "\003(\t\"\?\n\030ResponseSetLobbyNickname\022#\n\006statu" + "s\030\001 \002(\0132\023.rsctrl.core.Status\"\212\001\n\025Request" + "RegisterEvents\022A\n\006action\030\001 \002(\01621.rsctrl." + "chat.RequestRegisterEvents.RegisterActio" + "n\".\n\016RegisterAction\022\014\n\010REGISTER\020\001\022\016\n\nDER" + "EGISTER\020\002\"=\n\026ResponseRegisterEvents\022#\n\006s" + "tatus\030\001 \002(\0132\023.rsctrl.core.Status\"=\n\020Even" + "tLobbyInvite\022)\n\005lobby\030\001 \002(\0132\032.rsctrl.cha" + "t.ChatLobbyInfo\"9\n\020EventChatMessage\022%\n\003m" + "sg\030\001 \002(\0132\030.rsctrl.chat.ChatMessage\";\n\022Re" + "questSendMessage\022%\n\003msg\030\001 \002(\0132\030.rsctrl.c" + "hat.ChatMessage\":\n\023ResponseSendMessage\022#" + "\n\006status\030\001 \002(\0132\023.rsctrl.core.Status*\320\001\n\r" + "RequestMsgIds\022\034\n\030MsgId_RequestChatLobbie" + "s\020\001\022\034\n\030MsgId_RequestCreateLobby\020\002\022!\n\035Msg" + "Id_RequestJoinOrLeaveLobby\020\003\022!\n\035MsgId_Re" + "questSetLobbyNickname\020\004\022\037\n\033MsgId_Request" + "RegisterEvents\020\005\022\034\n\030MsgId_RequestSendMes" + "sage\020\006*\314\001\n\016ResponseMsgIds\022\035\n\031MsgId_Respo" + "nseChatLobbies\020\001\022\"\n\036MsgId_ResponseSetLob" + "byNickname\020\004\022 \n\034MsgId_ResponseRegisterEv" + "ents\020\005\022\035\n\031MsgId_ResponseSendMessage\020\006\022\032\n" + "\026MsgId_EventLobbyInvite\020e\022\032\n\026MsgId_Event" + "ChatMessage\020f*<\n\021LobbyPrivacyLevel\022\023\n\017PR" + "IVACY_PRIVATE\020\001\022\022\n\016PRIVACY_PUBLIC\020\002*<\n\010C" + "hatType\022\020\n\014TYPE_PRIVATE\020\001\022\016\n\nTYPE_LOBBY\020" + "\002\022\016\n\nTYPE_GROUP\020\003", 2377); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "chat.proto", &protobuf_RegisterTypes); + ChatLobbyInfo::default_instance_ = new ChatLobbyInfo(); + ChatId::default_instance_ = new ChatId(); + ChatMessage::default_instance_ = new ChatMessage(); + ResponseChatLobbies::default_instance_ = new ResponseChatLobbies(); + RequestChatLobbies::default_instance_ = new RequestChatLobbies(); + RequestCreateLobby::default_instance_ = new RequestCreateLobby(); + RequestJoinOrLeaveLobby::default_instance_ = new RequestJoinOrLeaveLobby(); + RequestSetLobbyNickname::default_instance_ = new RequestSetLobbyNickname(); + ResponseSetLobbyNickname::default_instance_ = new ResponseSetLobbyNickname(); + RequestRegisterEvents::default_instance_ = new RequestRegisterEvents(); + ResponseRegisterEvents::default_instance_ = new ResponseRegisterEvents(); + EventLobbyInvite::default_instance_ = new EventLobbyInvite(); + EventChatMessage::default_instance_ = new EventChatMessage(); + RequestSendMessage::default_instance_ = new RequestSendMessage(); + ResponseSendMessage::default_instance_ = new ResponseSendMessage(); + ChatLobbyInfo::default_instance_->InitAsDefaultInstance(); + ChatId::default_instance_->InitAsDefaultInstance(); + ChatMessage::default_instance_->InitAsDefaultInstance(); + ResponseChatLobbies::default_instance_->InitAsDefaultInstance(); + RequestChatLobbies::default_instance_->InitAsDefaultInstance(); + RequestCreateLobby::default_instance_->InitAsDefaultInstance(); + RequestJoinOrLeaveLobby::default_instance_->InitAsDefaultInstance(); + RequestSetLobbyNickname::default_instance_->InitAsDefaultInstance(); + ResponseSetLobbyNickname::default_instance_->InitAsDefaultInstance(); + RequestRegisterEvents::default_instance_->InitAsDefaultInstance(); + ResponseRegisterEvents::default_instance_->InitAsDefaultInstance(); + EventLobbyInvite::default_instance_->InitAsDefaultInstance(); + EventChatMessage::default_instance_->InitAsDefaultInstance(); + RequestSendMessage::default_instance_->InitAsDefaultInstance(); + ResponseSendMessage::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_chat_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_chat_2eproto { + StaticDescriptorInitializer_chat_2eproto() { + protobuf_AddDesc_chat_2eproto(); + } +} static_descriptor_initializer_chat_2eproto_; + +const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestMsgIds_descriptor_; +} +bool RequestMsgIds_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor() { + protobuf_AssignDescriptorsOnce(); + return ResponseMsgIds_descriptor_; +} +bool ResponseMsgIds_IsValid(int value) { + switch(value) { + case 1: + case 4: + case 5: + case 6: + case 101: + case 102: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* LobbyPrivacyLevel_descriptor() { + protobuf_AssignDescriptorsOnce(); + return LobbyPrivacyLevel_descriptor_; +} +bool LobbyPrivacyLevel_IsValid(int value) { + switch(value) { + case 1: + case 2: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* ChatType_descriptor() { + protobuf_AssignDescriptorsOnce(); + return ChatType_descriptor_; +} +bool ChatType_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 3: + return true; + default: + return false; + } +} + + +// =================================================================== + +const ::google::protobuf::EnumDescriptor* ChatLobbyInfo_LobbyState_descriptor() { + protobuf_AssignDescriptorsOnce(); + return ChatLobbyInfo_LobbyState_descriptor_; +} +bool ChatLobbyInfo_LobbyState_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 3: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const ChatLobbyInfo_LobbyState ChatLobbyInfo::LOBBYSTATE_JOINED; +const ChatLobbyInfo_LobbyState ChatLobbyInfo::LOBBYSTATE_INVITED; +const ChatLobbyInfo_LobbyState ChatLobbyInfo::LOBBYSTATE_PUBLIC; +const ChatLobbyInfo_LobbyState ChatLobbyInfo::LobbyState_MIN; +const ChatLobbyInfo_LobbyState ChatLobbyInfo::LobbyState_MAX; +const int ChatLobbyInfo::LobbyState_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int ChatLobbyInfo::kLobbyIdFieldNumber; +const int ChatLobbyInfo::kLobbyTopicFieldNumber; +const int ChatLobbyInfo::kLobbyNameFieldNumber; +const int ChatLobbyInfo::kLobbyNicknameFieldNumber; +const int ChatLobbyInfo::kPrivacyLevelFieldNumber; +const int ChatLobbyInfo::kLobbyStateFieldNumber; +const int ChatLobbyInfo::kNoPeersFieldNumber; +const int ChatLobbyInfo::kLastReportTimeFieldNumber; +const int ChatLobbyInfo::kLastActivityFieldNumber; +const int ChatLobbyInfo::kParticipatingFriendsFieldNumber; +const int ChatLobbyInfo::kNicknamesFieldNumber; +#endif // !_MSC_VER + +ChatLobbyInfo::ChatLobbyInfo() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ChatLobbyInfo::InitAsDefaultInstance() { +} + +ChatLobbyInfo::ChatLobbyInfo(const ChatLobbyInfo& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ChatLobbyInfo::SharedCtor() { + _cached_size_ = 0; + lobby_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + lobby_topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + lobby_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + lobby_nickname_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + privacy_level_ = 1; + lobby_state_ = 1; + no_peers_ = 0u; + last_report_time_ = 0u; + last_activity_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ChatLobbyInfo::~ChatLobbyInfo() { + SharedDtor(); +} + +void ChatLobbyInfo::SharedDtor() { + if (lobby_id_ != &::google::protobuf::internal::kEmptyString) { + delete lobby_id_; + } + if (lobby_topic_ != &::google::protobuf::internal::kEmptyString) { + delete lobby_topic_; + } + if (lobby_name_ != &::google::protobuf::internal::kEmptyString) { + delete lobby_name_; + } + if (lobby_nickname_ != &::google::protobuf::internal::kEmptyString) { + delete lobby_nickname_; + } + if (this != default_instance_) { + } +} + +void ChatLobbyInfo::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ChatLobbyInfo::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ChatLobbyInfo_descriptor_; +} + +const ChatLobbyInfo& ChatLobbyInfo::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_chat_2eproto(); return *default_instance_; +} + +ChatLobbyInfo* ChatLobbyInfo::default_instance_ = NULL; + +ChatLobbyInfo* ChatLobbyInfo::New() const { + return new ChatLobbyInfo; +} + +void ChatLobbyInfo::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_lobby_id()) { + if (lobby_id_ != &::google::protobuf::internal::kEmptyString) { + lobby_id_->clear(); + } + } + if (has_lobby_topic()) { + if (lobby_topic_ != &::google::protobuf::internal::kEmptyString) { + lobby_topic_->clear(); + } + } + if (has_lobby_name()) { + if (lobby_name_ != &::google::protobuf::internal::kEmptyString) { + lobby_name_->clear(); + } + } + if (has_lobby_nickname()) { + if (lobby_nickname_ != &::google::protobuf::internal::kEmptyString) { + lobby_nickname_->clear(); + } + } + privacy_level_ = 1; + lobby_state_ = 1; + no_peers_ = 0u; + last_report_time_ = 0u; + } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + last_activity_ = 0u; + } + participating_friends_.Clear(); + nicknames_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ChatLobbyInfo::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string lobby_id = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_lobby_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_id().data(), this->lobby_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_lobby_topic; + break; + } + + // required string lobby_topic = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_lobby_topic: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_lobby_topic())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_topic().data(), this->lobby_topic().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_lobby_name; + break; + } + + // required string lobby_name = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_lobby_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_lobby_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_name().data(), this->lobby_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(34)) goto parse_lobby_nickname; + break; + } + + // required string lobby_nickname = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_lobby_nickname: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_lobby_nickname())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_nickname().data(), this->lobby_nickname().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(40)) goto parse_privacy_level; + break; + } + + // required .rsctrl.chat.LobbyPrivacyLevel privacy_level = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_privacy_level: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (rsctrl::chat::LobbyPrivacyLevel_IsValid(value)) { + set_privacy_level(static_cast< rsctrl::chat::LobbyPrivacyLevel >(value)); + } else { + mutable_unknown_fields()->AddVarint(5, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(48)) goto parse_lobby_state; + break; + } + + // required .rsctrl.chat.ChatLobbyInfo.LobbyState lobby_state = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_lobby_state: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::rsctrl::chat::ChatLobbyInfo_LobbyState_IsValid(value)) { + set_lobby_state(static_cast< ::rsctrl::chat::ChatLobbyInfo_LobbyState >(value)); + } else { + mutable_unknown_fields()->AddVarint(6, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(56)) goto parse_no_peers; + break; + } + + // required uint32 no_peers = 7; + case 7: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_no_peers: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &no_peers_))); + set_has_no_peers(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(64)) goto parse_last_report_time; + break; + } + + // required uint32 last_report_time = 8; + case 8: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_last_report_time: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &last_report_time_))); + set_has_last_report_time(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(72)) goto parse_last_activity; + break; + } + + // required uint32 last_activity = 9; + case 9: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_last_activity: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &last_activity_))); + set_has_last_activity(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(82)) goto parse_participating_friends; + break; + } + + // repeated string participating_friends = 10; + case 10: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_participating_friends: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_participating_friends())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->participating_friends(0).data(), this->participating_friends(0).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(82)) goto parse_participating_friends; + if (input->ExpectTag(90)) goto parse_nicknames; + break; + } + + // repeated string nicknames = 11; + case 11: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_nicknames: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_nicknames())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->nicknames(0).data(), this->nicknames(0).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(90)) goto parse_nicknames; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ChatLobbyInfo::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string lobby_id = 1; + if (has_lobby_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_id().data(), this->lobby_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->lobby_id(), output); + } + + // required string lobby_topic = 2; + if (has_lobby_topic()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_topic().data(), this->lobby_topic().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->lobby_topic(), output); + } + + // required string lobby_name = 3; + if (has_lobby_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_name().data(), this->lobby_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->lobby_name(), output); + } + + // required string lobby_nickname = 4; + if (has_lobby_nickname()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_nickname().data(), this->lobby_nickname().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 4, this->lobby_nickname(), output); + } + + // required .rsctrl.chat.LobbyPrivacyLevel privacy_level = 5; + if (has_privacy_level()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 5, this->privacy_level(), output); + } + + // required .rsctrl.chat.ChatLobbyInfo.LobbyState lobby_state = 6; + if (has_lobby_state()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 6, this->lobby_state(), output); + } + + // required uint32 no_peers = 7; + if (has_no_peers()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(7, this->no_peers(), output); + } + + // required uint32 last_report_time = 8; + if (has_last_report_time()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(8, this->last_report_time(), output); + } + + // required uint32 last_activity = 9; + if (has_last_activity()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(9, this->last_activity(), output); + } + + // repeated string participating_friends = 10; + for (int i = 0; i < this->participating_friends_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->participating_friends(i).data(), this->participating_friends(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 10, this->participating_friends(i), output); + } + + // repeated string nicknames = 11; + for (int i = 0; i < this->nicknames_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->nicknames(i).data(), this->nicknames(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 11, this->nicknames(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ChatLobbyInfo::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string lobby_id = 1; + if (has_lobby_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_id().data(), this->lobby_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->lobby_id(), target); + } + + // required string lobby_topic = 2; + if (has_lobby_topic()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_topic().data(), this->lobby_topic().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->lobby_topic(), target); + } + + // required string lobby_name = 3; + if (has_lobby_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_name().data(), this->lobby_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->lobby_name(), target); + } + + // required string lobby_nickname = 4; + if (has_lobby_nickname()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_nickname().data(), this->lobby_nickname().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 4, this->lobby_nickname(), target); + } + + // required .rsctrl.chat.LobbyPrivacyLevel privacy_level = 5; + if (has_privacy_level()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 5, this->privacy_level(), target); + } + + // required .rsctrl.chat.ChatLobbyInfo.LobbyState lobby_state = 6; + if (has_lobby_state()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 6, this->lobby_state(), target); + } + + // required uint32 no_peers = 7; + if (has_no_peers()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(7, this->no_peers(), target); + } + + // required uint32 last_report_time = 8; + if (has_last_report_time()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(8, this->last_report_time(), target); + } + + // required uint32 last_activity = 9; + if (has_last_activity()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(9, this->last_activity(), target); + } + + // repeated string participating_friends = 10; + for (int i = 0; i < this->participating_friends_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->participating_friends(i).data(), this->participating_friends(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(10, this->participating_friends(i), target); + } + + // repeated string nicknames = 11; + for (int i = 0; i < this->nicknames_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->nicknames(i).data(), this->nicknames(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(11, this->nicknames(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ChatLobbyInfo::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string lobby_id = 1; + if (has_lobby_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->lobby_id()); + } + + // required string lobby_topic = 2; + if (has_lobby_topic()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->lobby_topic()); + } + + // required string lobby_name = 3; + if (has_lobby_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->lobby_name()); + } + + // required string lobby_nickname = 4; + if (has_lobby_nickname()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->lobby_nickname()); + } + + // required .rsctrl.chat.LobbyPrivacyLevel privacy_level = 5; + if (has_privacy_level()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->privacy_level()); + } + + // required .rsctrl.chat.ChatLobbyInfo.LobbyState lobby_state = 6; + if (has_lobby_state()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->lobby_state()); + } + + // required uint32 no_peers = 7; + if (has_no_peers()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->no_peers()); + } + + // required uint32 last_report_time = 8; + if (has_last_report_time()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->last_report_time()); + } + + } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + // required uint32 last_activity = 9; + if (has_last_activity()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->last_activity()); + } + + } + // repeated string participating_friends = 10; + total_size += 1 * this->participating_friends_size(); + for (int i = 0; i < this->participating_friends_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->participating_friends(i)); + } + + // repeated string nicknames = 11; + total_size += 1 * this->nicknames_size(); + for (int i = 0; i < this->nicknames_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->nicknames(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ChatLobbyInfo::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ChatLobbyInfo* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ChatLobbyInfo::MergeFrom(const ChatLobbyInfo& from) { + GOOGLE_CHECK_NE(&from, this); + participating_friends_.MergeFrom(from.participating_friends_); + nicknames_.MergeFrom(from.nicknames_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_lobby_id()) { + set_lobby_id(from.lobby_id()); + } + if (from.has_lobby_topic()) { + set_lobby_topic(from.lobby_topic()); + } + if (from.has_lobby_name()) { + set_lobby_name(from.lobby_name()); + } + if (from.has_lobby_nickname()) { + set_lobby_nickname(from.lobby_nickname()); + } + if (from.has_privacy_level()) { + set_privacy_level(from.privacy_level()); + } + if (from.has_lobby_state()) { + set_lobby_state(from.lobby_state()); + } + if (from.has_no_peers()) { + set_no_peers(from.no_peers()); + } + if (from.has_last_report_time()) { + set_last_report_time(from.last_report_time()); + } + } + if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) { + if (from.has_last_activity()) { + set_last_activity(from.last_activity()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ChatLobbyInfo::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ChatLobbyInfo::CopyFrom(const ChatLobbyInfo& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ChatLobbyInfo::IsInitialized() const { + if ((_has_bits_[0] & 0x000001ff) != 0x000001ff) return false; + + return true; +} + +void ChatLobbyInfo::Swap(ChatLobbyInfo* other) { + if (other != this) { + std::swap(lobby_id_, other->lobby_id_); + std::swap(lobby_topic_, other->lobby_topic_); + std::swap(lobby_name_, other->lobby_name_); + std::swap(lobby_nickname_, other->lobby_nickname_); + std::swap(privacy_level_, other->privacy_level_); + std::swap(lobby_state_, other->lobby_state_); + std::swap(no_peers_, other->no_peers_); + std::swap(last_report_time_, other->last_report_time_); + std::swap(last_activity_, other->last_activity_); + participating_friends_.Swap(&other->participating_friends_); + nicknames_.Swap(&other->nicknames_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ChatLobbyInfo::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ChatLobbyInfo_descriptor_; + metadata.reflection = ChatLobbyInfo_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ChatId::kChatTypeFieldNumber; +const int ChatId::kChatIdFieldNumber; +#endif // !_MSC_VER + +ChatId::ChatId() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ChatId::InitAsDefaultInstance() { +} + +ChatId::ChatId(const ChatId& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ChatId::SharedCtor() { + _cached_size_ = 0; + chat_type_ = 1; + chat_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ChatId::~ChatId() { + SharedDtor(); +} + +void ChatId::SharedDtor() { + if (chat_id_ != &::google::protobuf::internal::kEmptyString) { + delete chat_id_; + } + if (this != default_instance_) { + } +} + +void ChatId::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ChatId::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ChatId_descriptor_; +} + +const ChatId& ChatId::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_chat_2eproto(); return *default_instance_; +} + +ChatId* ChatId::default_instance_ = NULL; + +ChatId* ChatId::New() const { + return new ChatId; +} + +void ChatId::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + chat_type_ = 1; + if (has_chat_id()) { + if (chat_id_ != &::google::protobuf::internal::kEmptyString) { + chat_id_->clear(); + } + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ChatId::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.chat.ChatType chat_type = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (rsctrl::chat::ChatType_IsValid(value)) { + set_chat_type(static_cast< rsctrl::chat::ChatType >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_chat_id; + break; + } + + // required string chat_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_chat_id: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_chat_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->chat_id().data(), this->chat_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ChatId::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.chat.ChatType chat_type = 1; + if (has_chat_type()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->chat_type(), output); + } + + // required string chat_id = 2; + if (has_chat_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->chat_id().data(), this->chat_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->chat_id(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ChatId::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.chat.ChatType chat_type = 1; + if (has_chat_type()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->chat_type(), target); + } + + // required string chat_id = 2; + if (has_chat_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->chat_id().data(), this->chat_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->chat_id(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ChatId::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.chat.ChatType chat_type = 1; + if (has_chat_type()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->chat_type()); + } + + // required string chat_id = 2; + if (has_chat_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->chat_id()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ChatId::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ChatId* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ChatId::MergeFrom(const ChatId& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_chat_type()) { + set_chat_type(from.chat_type()); + } + if (from.has_chat_id()) { + set_chat_id(from.chat_id()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ChatId::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ChatId::CopyFrom(const ChatId& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ChatId::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void ChatId::Swap(ChatId* other) { + if (other != this) { + std::swap(chat_type_, other->chat_type_); + std::swap(chat_id_, other->chat_id_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ChatId::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ChatId_descriptor_; + metadata.reflection = ChatId_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ChatMessage::kIdFieldNumber; +const int ChatMessage::kMsgFieldNumber; +const int ChatMessage::kPeerNicknameFieldNumber; +const int ChatMessage::kChatFlagsFieldNumber; +const int ChatMessage::kSendTimeFieldNumber; +const int ChatMessage::kRecvTimeFieldNumber; +#endif // !_MSC_VER + +ChatMessage::ChatMessage() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ChatMessage::InitAsDefaultInstance() { + id_ = const_cast< ::rsctrl::chat::ChatId*>(&::rsctrl::chat::ChatId::default_instance()); +} + +ChatMessage::ChatMessage(const ChatMessage& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ChatMessage::SharedCtor() { + _cached_size_ = 0; + id_ = NULL; + msg_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + peer_nickname_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + chat_flags_ = 0u; + send_time_ = 0u; + recv_time_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ChatMessage::~ChatMessage() { + SharedDtor(); +} + +void ChatMessage::SharedDtor() { + if (msg_ != &::google::protobuf::internal::kEmptyString) { + delete msg_; + } + if (peer_nickname_ != &::google::protobuf::internal::kEmptyString) { + delete peer_nickname_; + } + if (this != default_instance_) { + delete id_; + } +} + +void ChatMessage::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ChatMessage::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ChatMessage_descriptor_; +} + +const ChatMessage& ChatMessage::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_chat_2eproto(); return *default_instance_; +} + +ChatMessage* ChatMessage::default_instance_ = NULL; + +ChatMessage* ChatMessage::New() const { + return new ChatMessage; +} + +void ChatMessage::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_id()) { + if (id_ != NULL) id_->::rsctrl::chat::ChatId::Clear(); + } + if (has_msg()) { + if (msg_ != &::google::protobuf::internal::kEmptyString) { + msg_->clear(); + } + } + if (has_peer_nickname()) { + if (peer_nickname_ != &::google::protobuf::internal::kEmptyString) { + peer_nickname_->clear(); + } + } + chat_flags_ = 0u; + send_time_ = 0u; + recv_time_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ChatMessage::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.chat.ChatId id = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_id())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_msg; + break; + } + + // required string msg = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_msg: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_msg())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->msg().data(), this->msg().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_peer_nickname; + break; + } + + // optional string peer_nickname = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_peer_nickname: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_peer_nickname())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->peer_nickname().data(), this->peer_nickname().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(32)) goto parse_chat_flags; + break; + } + + // optional uint32 chat_flags = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_chat_flags: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &chat_flags_))); + set_has_chat_flags(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(40)) goto parse_send_time; + break; + } + + // optional uint32 send_time = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_send_time: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &send_time_))); + set_has_send_time(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(48)) goto parse_recv_time; + break; + } + + // optional uint32 recv_time = 6; + case 6: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_recv_time: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &recv_time_))); + set_has_recv_time(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ChatMessage::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.chat.ChatId id = 1; + if (has_id()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->id(), output); + } + + // required string msg = 2; + if (has_msg()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->msg().data(), this->msg().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->msg(), output); + } + + // optional string peer_nickname = 3; + if (has_peer_nickname()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->peer_nickname().data(), this->peer_nickname().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->peer_nickname(), output); + } + + // optional uint32 chat_flags = 4; + if (has_chat_flags()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(4, this->chat_flags(), output); + } + + // optional uint32 send_time = 5; + if (has_send_time()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(5, this->send_time(), output); + } + + // optional uint32 recv_time = 6; + if (has_recv_time()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(6, this->recv_time(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ChatMessage::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.chat.ChatId id = 1; + if (has_id()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->id(), target); + } + + // required string msg = 2; + if (has_msg()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->msg().data(), this->msg().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->msg(), target); + } + + // optional string peer_nickname = 3; + if (has_peer_nickname()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->peer_nickname().data(), this->peer_nickname().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->peer_nickname(), target); + } + + // optional uint32 chat_flags = 4; + if (has_chat_flags()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(4, this->chat_flags(), target); + } + + // optional uint32 send_time = 5; + if (has_send_time()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(5, this->send_time(), target); + } + + // optional uint32 recv_time = 6; + if (has_recv_time()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(6, this->recv_time(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ChatMessage::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.chat.ChatId id = 1; + if (has_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->id()); + } + + // required string msg = 2; + if (has_msg()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->msg()); + } + + // optional string peer_nickname = 3; + if (has_peer_nickname()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->peer_nickname()); + } + + // optional uint32 chat_flags = 4; + if (has_chat_flags()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->chat_flags()); + } + + // optional uint32 send_time = 5; + if (has_send_time()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->send_time()); + } + + // optional uint32 recv_time = 6; + if (has_recv_time()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->recv_time()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ChatMessage::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ChatMessage* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ChatMessage::MergeFrom(const ChatMessage& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_id()) { + mutable_id()->::rsctrl::chat::ChatId::MergeFrom(from.id()); + } + if (from.has_msg()) { + set_msg(from.msg()); + } + if (from.has_peer_nickname()) { + set_peer_nickname(from.peer_nickname()); + } + if (from.has_chat_flags()) { + set_chat_flags(from.chat_flags()); + } + if (from.has_send_time()) { + set_send_time(from.send_time()); + } + if (from.has_recv_time()) { + set_recv_time(from.recv_time()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ChatMessage::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ChatMessage::CopyFrom(const ChatMessage& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ChatMessage::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + if (has_id()) { + if (!this->id().IsInitialized()) return false; + } + return true; +} + +void ChatMessage::Swap(ChatMessage* other) { + if (other != this) { + std::swap(id_, other->id_); + std::swap(msg_, other->msg_); + std::swap(peer_nickname_, other->peer_nickname_); + std::swap(chat_flags_, other->chat_flags_); + std::swap(send_time_, other->send_time_); + std::swap(recv_time_, other->recv_time_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ChatMessage::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ChatMessage_descriptor_; + metadata.reflection = ChatMessage_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ResponseChatLobbies::kStatusFieldNumber; +const int ResponseChatLobbies::kLobbiesFieldNumber; +#endif // !_MSC_VER + +ResponseChatLobbies::ResponseChatLobbies() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ResponseChatLobbies::InitAsDefaultInstance() { + status_ = const_cast< ::rsctrl::core::Status*>(&::rsctrl::core::Status::default_instance()); +} + +ResponseChatLobbies::ResponseChatLobbies(const ResponseChatLobbies& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ResponseChatLobbies::SharedCtor() { + _cached_size_ = 0; + status_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ResponseChatLobbies::~ResponseChatLobbies() { + SharedDtor(); +} + +void ResponseChatLobbies::SharedDtor() { + if (this != default_instance_) { + delete status_; + } +} + +void ResponseChatLobbies::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ResponseChatLobbies::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ResponseChatLobbies_descriptor_; +} + +const ResponseChatLobbies& ResponseChatLobbies::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_chat_2eproto(); return *default_instance_; +} + +ResponseChatLobbies* ResponseChatLobbies::default_instance_ = NULL; + +ResponseChatLobbies* ResponseChatLobbies::New() const { + return new ResponseChatLobbies; +} + +void ResponseChatLobbies::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_status()) { + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); + } + } + lobbies_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ResponseChatLobbies::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.core.Status status = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_status())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_lobbies; + break; + } + + // repeated .rsctrl.chat.ChatLobbyInfo lobbies = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_lobbies: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_lobbies())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_lobbies; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ResponseChatLobbies::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->status(), output); + } + + // repeated .rsctrl.chat.ChatLobbyInfo lobbies = 2; + for (int i = 0; i < this->lobbies_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->lobbies(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ResponseChatLobbies::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->status(), target); + } + + // repeated .rsctrl.chat.ChatLobbyInfo lobbies = 2; + for (int i = 0; i < this->lobbies_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->lobbies(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ResponseChatLobbies::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->status()); + } + + } + // repeated .rsctrl.chat.ChatLobbyInfo lobbies = 2; + total_size += 1 * this->lobbies_size(); + for (int i = 0; i < this->lobbies_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->lobbies(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ResponseChatLobbies::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ResponseChatLobbies* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ResponseChatLobbies::MergeFrom(const ResponseChatLobbies& from) { + GOOGLE_CHECK_NE(&from, this); + lobbies_.MergeFrom(from.lobbies_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_status()) { + mutable_status()->::rsctrl::core::Status::MergeFrom(from.status()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ResponseChatLobbies::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ResponseChatLobbies::CopyFrom(const ResponseChatLobbies& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ResponseChatLobbies::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_status()) { + if (!this->status().IsInitialized()) return false; + } + for (int i = 0; i < lobbies_size(); i++) { + if (!this->lobbies(i).IsInitialized()) return false; + } + return true; +} + +void ResponseChatLobbies::Swap(ResponseChatLobbies* other) { + if (other != this) { + std::swap(status_, other->status_); + lobbies_.Swap(&other->lobbies_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ResponseChatLobbies::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ResponseChatLobbies_descriptor_; + metadata.reflection = ResponseChatLobbies_reflection_; + return metadata; +} + + +// =================================================================== + +const ::google::protobuf::EnumDescriptor* RequestChatLobbies_LobbySet_descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestChatLobbies_LobbySet_descriptor_; +} +bool RequestChatLobbies_LobbySet_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 3: + case 4: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const RequestChatLobbies_LobbySet RequestChatLobbies::LOBBYSET_ALL; +const RequestChatLobbies_LobbySet RequestChatLobbies::LOBBYSET_JOINED; +const RequestChatLobbies_LobbySet RequestChatLobbies::LOBBYSET_INVITED; +const RequestChatLobbies_LobbySet RequestChatLobbies::LOBBYSET_PUBLIC; +const RequestChatLobbies_LobbySet RequestChatLobbies::LobbySet_MIN; +const RequestChatLobbies_LobbySet RequestChatLobbies::LobbySet_MAX; +const int RequestChatLobbies::LobbySet_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int RequestChatLobbies::kLobbySetFieldNumber; +#endif // !_MSC_VER + +RequestChatLobbies::RequestChatLobbies() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RequestChatLobbies::InitAsDefaultInstance() { +} + +RequestChatLobbies::RequestChatLobbies(const RequestChatLobbies& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RequestChatLobbies::SharedCtor() { + _cached_size_ = 0; + lobby_set_ = 1; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RequestChatLobbies::~RequestChatLobbies() { + SharedDtor(); +} + +void RequestChatLobbies::SharedDtor() { + if (this != default_instance_) { + } +} + +void RequestChatLobbies::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestChatLobbies::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestChatLobbies_descriptor_; +} + +const RequestChatLobbies& RequestChatLobbies::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_chat_2eproto(); return *default_instance_; +} + +RequestChatLobbies* RequestChatLobbies::default_instance_ = NULL; + +RequestChatLobbies* RequestChatLobbies::New() const { + return new RequestChatLobbies; +} + +void RequestChatLobbies::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + lobby_set_ = 1; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestChatLobbies::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.chat.RequestChatLobbies.LobbySet lobby_set = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::rsctrl::chat::RequestChatLobbies_LobbySet_IsValid(value)) { + set_lobby_set(static_cast< ::rsctrl::chat::RequestChatLobbies_LobbySet >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void RequestChatLobbies::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.chat.RequestChatLobbies.LobbySet lobby_set = 1; + if (has_lobby_set()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->lobby_set(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RequestChatLobbies::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.chat.RequestChatLobbies.LobbySet lobby_set = 1; + if (has_lobby_set()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->lobby_set(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RequestChatLobbies::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.chat.RequestChatLobbies.LobbySet lobby_set = 1; + if (has_lobby_set()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->lobby_set()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestChatLobbies::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestChatLobbies* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestChatLobbies::MergeFrom(const RequestChatLobbies& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_lobby_set()) { + set_lobby_set(from.lobby_set()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestChatLobbies::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestChatLobbies::CopyFrom(const RequestChatLobbies& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestChatLobbies::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void RequestChatLobbies::Swap(RequestChatLobbies* other) { + if (other != this) { + std::swap(lobby_set_, other->lobby_set_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestChatLobbies::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestChatLobbies_descriptor_; + metadata.reflection = RequestChatLobbies_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int RequestCreateLobby::kLobbyNameFieldNumber; +const int RequestCreateLobby::kLobbyTopicFieldNumber; +const int RequestCreateLobby::kPrivacyLevelFieldNumber; +const int RequestCreateLobby::kInvitedFriendsFieldNumber; +#endif // !_MSC_VER + +RequestCreateLobby::RequestCreateLobby() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RequestCreateLobby::InitAsDefaultInstance() { +} + +RequestCreateLobby::RequestCreateLobby(const RequestCreateLobby& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RequestCreateLobby::SharedCtor() { + _cached_size_ = 0; + lobby_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + lobby_topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + privacy_level_ = 1; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RequestCreateLobby::~RequestCreateLobby() { + SharedDtor(); +} + +void RequestCreateLobby::SharedDtor() { + if (lobby_name_ != &::google::protobuf::internal::kEmptyString) { + delete lobby_name_; + } + if (lobby_topic_ != &::google::protobuf::internal::kEmptyString) { + delete lobby_topic_; + } + if (this != default_instance_) { + } +} + +void RequestCreateLobby::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestCreateLobby::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestCreateLobby_descriptor_; +} + +const RequestCreateLobby& RequestCreateLobby::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_chat_2eproto(); return *default_instance_; +} + +RequestCreateLobby* RequestCreateLobby::default_instance_ = NULL; + +RequestCreateLobby* RequestCreateLobby::New() const { + return new RequestCreateLobby; +} + +void RequestCreateLobby::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_lobby_name()) { + if (lobby_name_ != &::google::protobuf::internal::kEmptyString) { + lobby_name_->clear(); + } + } + if (has_lobby_topic()) { + if (lobby_topic_ != &::google::protobuf::internal::kEmptyString) { + lobby_topic_->clear(); + } + } + privacy_level_ = 1; + } + invited_friends_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestCreateLobby::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string lobby_name = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_lobby_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_name().data(), this->lobby_name().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_lobby_topic; + break; + } + + // required string lobby_topic = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_lobby_topic: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_lobby_topic())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_topic().data(), this->lobby_topic().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_invited_friends; + break; + } + + // repeated string invited_friends = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_invited_friends: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_invited_friends())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->invited_friends(0).data(), this->invited_friends(0).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(26)) goto parse_invited_friends; + if (input->ExpectTag(32)) goto parse_privacy_level; + break; + } + + // required .rsctrl.chat.LobbyPrivacyLevel privacy_level = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_privacy_level: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (rsctrl::chat::LobbyPrivacyLevel_IsValid(value)) { + set_privacy_level(static_cast< rsctrl::chat::LobbyPrivacyLevel >(value)); + } else { + mutable_unknown_fields()->AddVarint(4, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void RequestCreateLobby::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string lobby_name = 1; + if (has_lobby_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_name().data(), this->lobby_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->lobby_name(), output); + } + + // required string lobby_topic = 2; + if (has_lobby_topic()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_topic().data(), this->lobby_topic().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->lobby_topic(), output); + } + + // repeated string invited_friends = 3; + for (int i = 0; i < this->invited_friends_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->invited_friends(i).data(), this->invited_friends(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->invited_friends(i), output); + } + + // required .rsctrl.chat.LobbyPrivacyLevel privacy_level = 4; + if (has_privacy_level()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 4, this->privacy_level(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RequestCreateLobby::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string lobby_name = 1; + if (has_lobby_name()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_name().data(), this->lobby_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->lobby_name(), target); + } + + // required string lobby_topic = 2; + if (has_lobby_topic()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_topic().data(), this->lobby_topic().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->lobby_topic(), target); + } + + // repeated string invited_friends = 3; + for (int i = 0; i < this->invited_friends_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->invited_friends(i).data(), this->invited_friends(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(3, this->invited_friends(i), target); + } + + // required .rsctrl.chat.LobbyPrivacyLevel privacy_level = 4; + if (has_privacy_level()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 4, this->privacy_level(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RequestCreateLobby::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string lobby_name = 1; + if (has_lobby_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->lobby_name()); + } + + // required string lobby_topic = 2; + if (has_lobby_topic()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->lobby_topic()); + } + + // required .rsctrl.chat.LobbyPrivacyLevel privacy_level = 4; + if (has_privacy_level()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->privacy_level()); + } + + } + // repeated string invited_friends = 3; + total_size += 1 * this->invited_friends_size(); + for (int i = 0; i < this->invited_friends_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->invited_friends(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestCreateLobby::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestCreateLobby* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestCreateLobby::MergeFrom(const RequestCreateLobby& from) { + GOOGLE_CHECK_NE(&from, this); + invited_friends_.MergeFrom(from.invited_friends_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_lobby_name()) { + set_lobby_name(from.lobby_name()); + } + if (from.has_lobby_topic()) { + set_lobby_topic(from.lobby_topic()); + } + if (from.has_privacy_level()) { + set_privacy_level(from.privacy_level()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestCreateLobby::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestCreateLobby::CopyFrom(const RequestCreateLobby& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestCreateLobby::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void RequestCreateLobby::Swap(RequestCreateLobby* other) { + if (other != this) { + std::swap(lobby_name_, other->lobby_name_); + std::swap(lobby_topic_, other->lobby_topic_); + std::swap(privacy_level_, other->privacy_level_); + invited_friends_.Swap(&other->invited_friends_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestCreateLobby::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestCreateLobby_descriptor_; + metadata.reflection = RequestCreateLobby_reflection_; + return metadata; +} + + +// =================================================================== + +const ::google::protobuf::EnumDescriptor* RequestJoinOrLeaveLobby_LobbyAction_descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestJoinOrLeaveLobby_LobbyAction_descriptor_; +} +bool RequestJoinOrLeaveLobby_LobbyAction_IsValid(int value) { + switch(value) { + case 1: + case 2: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const RequestJoinOrLeaveLobby_LobbyAction RequestJoinOrLeaveLobby::JOIN_OR_ACCEPT; +const RequestJoinOrLeaveLobby_LobbyAction RequestJoinOrLeaveLobby::LEAVE_OR_DENY; +const RequestJoinOrLeaveLobby_LobbyAction RequestJoinOrLeaveLobby::LobbyAction_MIN; +const RequestJoinOrLeaveLobby_LobbyAction RequestJoinOrLeaveLobby::LobbyAction_MAX; +const int RequestJoinOrLeaveLobby::LobbyAction_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int RequestJoinOrLeaveLobby::kLobbyIdFieldNumber; +const int RequestJoinOrLeaveLobby::kActionFieldNumber; +#endif // !_MSC_VER + +RequestJoinOrLeaveLobby::RequestJoinOrLeaveLobby() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RequestJoinOrLeaveLobby::InitAsDefaultInstance() { +} + +RequestJoinOrLeaveLobby::RequestJoinOrLeaveLobby(const RequestJoinOrLeaveLobby& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RequestJoinOrLeaveLobby::SharedCtor() { + _cached_size_ = 0; + lobby_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + action_ = 1; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RequestJoinOrLeaveLobby::~RequestJoinOrLeaveLobby() { + SharedDtor(); +} + +void RequestJoinOrLeaveLobby::SharedDtor() { + if (lobby_id_ != &::google::protobuf::internal::kEmptyString) { + delete lobby_id_; + } + if (this != default_instance_) { + } +} + +void RequestJoinOrLeaveLobby::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestJoinOrLeaveLobby::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestJoinOrLeaveLobby_descriptor_; +} + +const RequestJoinOrLeaveLobby& RequestJoinOrLeaveLobby::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_chat_2eproto(); return *default_instance_; +} + +RequestJoinOrLeaveLobby* RequestJoinOrLeaveLobby::default_instance_ = NULL; + +RequestJoinOrLeaveLobby* RequestJoinOrLeaveLobby::New() const { + return new RequestJoinOrLeaveLobby; +} + +void RequestJoinOrLeaveLobby::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_lobby_id()) { + if (lobby_id_ != &::google::protobuf::internal::kEmptyString) { + lobby_id_->clear(); + } + } + action_ = 1; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestJoinOrLeaveLobby::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string lobby_id = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_lobby_id())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_id().data(), this->lobby_id().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_action; + break; + } + + // required .rsctrl.chat.RequestJoinOrLeaveLobby.LobbyAction action = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_action: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::rsctrl::chat::RequestJoinOrLeaveLobby_LobbyAction_IsValid(value)) { + set_action(static_cast< ::rsctrl::chat::RequestJoinOrLeaveLobby_LobbyAction >(value)); + } else { + mutable_unknown_fields()->AddVarint(2, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void RequestJoinOrLeaveLobby::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string lobby_id = 1; + if (has_lobby_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_id().data(), this->lobby_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->lobby_id(), output); + } + + // required .rsctrl.chat.RequestJoinOrLeaveLobby.LobbyAction action = 2; + if (has_action()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 2, this->action(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RequestJoinOrLeaveLobby::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string lobby_id = 1; + if (has_lobby_id()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_id().data(), this->lobby_id().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->lobby_id(), target); + } + + // required .rsctrl.chat.RequestJoinOrLeaveLobby.LobbyAction action = 2; + if (has_action()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 2, this->action(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RequestJoinOrLeaveLobby::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string lobby_id = 1; + if (has_lobby_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->lobby_id()); + } + + // required .rsctrl.chat.RequestJoinOrLeaveLobby.LobbyAction action = 2; + if (has_action()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->action()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestJoinOrLeaveLobby::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestJoinOrLeaveLobby* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestJoinOrLeaveLobby::MergeFrom(const RequestJoinOrLeaveLobby& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_lobby_id()) { + set_lobby_id(from.lobby_id()); + } + if (from.has_action()) { + set_action(from.action()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestJoinOrLeaveLobby::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestJoinOrLeaveLobby::CopyFrom(const RequestJoinOrLeaveLobby& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestJoinOrLeaveLobby::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void RequestJoinOrLeaveLobby::Swap(RequestJoinOrLeaveLobby* other) { + if (other != this) { + std::swap(lobby_id_, other->lobby_id_); + std::swap(action_, other->action_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestJoinOrLeaveLobby::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestJoinOrLeaveLobby_descriptor_; + metadata.reflection = RequestJoinOrLeaveLobby_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int RequestSetLobbyNickname::kNicknameFieldNumber; +const int RequestSetLobbyNickname::kLobbyIdsFieldNumber; +#endif // !_MSC_VER + +RequestSetLobbyNickname::RequestSetLobbyNickname() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RequestSetLobbyNickname::InitAsDefaultInstance() { +} + +RequestSetLobbyNickname::RequestSetLobbyNickname(const RequestSetLobbyNickname& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RequestSetLobbyNickname::SharedCtor() { + _cached_size_ = 0; + nickname_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RequestSetLobbyNickname::~RequestSetLobbyNickname() { + SharedDtor(); +} + +void RequestSetLobbyNickname::SharedDtor() { + if (nickname_ != &::google::protobuf::internal::kEmptyString) { + delete nickname_; + } + if (this != default_instance_) { + } +} + +void RequestSetLobbyNickname::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestSetLobbyNickname::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestSetLobbyNickname_descriptor_; +} + +const RequestSetLobbyNickname& RequestSetLobbyNickname::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_chat_2eproto(); return *default_instance_; +} + +RequestSetLobbyNickname* RequestSetLobbyNickname::default_instance_ = NULL; + +RequestSetLobbyNickname* RequestSetLobbyNickname::New() const { + return new RequestSetLobbyNickname; +} + +void RequestSetLobbyNickname::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_nickname()) { + if (nickname_ != &::google::protobuf::internal::kEmptyString) { + nickname_->clear(); + } + } + } + lobby_ids_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestSetLobbyNickname::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required string nickname = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_nickname())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->nickname().data(), this->nickname().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_lobby_ids; + break; + } + + // repeated string lobby_ids = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_lobby_ids: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_lobby_ids())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_ids(0).data(), this->lobby_ids(0).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_lobby_ids; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void RequestSetLobbyNickname::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required string nickname = 1; + if (has_nickname()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->nickname().data(), this->nickname().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->nickname(), output); + } + + // repeated string lobby_ids = 2; + for (int i = 0; i < this->lobby_ids_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_ids(i).data(), this->lobby_ids(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 2, this->lobby_ids(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RequestSetLobbyNickname::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required string nickname = 1; + if (has_nickname()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->nickname().data(), this->nickname().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->nickname(), target); + } + + // repeated string lobby_ids = 2; + for (int i = 0; i < this->lobby_ids_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->lobby_ids(i).data(), this->lobby_ids(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(2, this->lobby_ids(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RequestSetLobbyNickname::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required string nickname = 1; + if (has_nickname()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->nickname()); + } + + } + // repeated string lobby_ids = 2; + total_size += 1 * this->lobby_ids_size(); + for (int i = 0; i < this->lobby_ids_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->lobby_ids(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestSetLobbyNickname::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestSetLobbyNickname* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestSetLobbyNickname::MergeFrom(const RequestSetLobbyNickname& from) { + GOOGLE_CHECK_NE(&from, this); + lobby_ids_.MergeFrom(from.lobby_ids_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_nickname()) { + set_nickname(from.nickname()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestSetLobbyNickname::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestSetLobbyNickname::CopyFrom(const RequestSetLobbyNickname& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestSetLobbyNickname::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void RequestSetLobbyNickname::Swap(RequestSetLobbyNickname* other) { + if (other != this) { + std::swap(nickname_, other->nickname_); + lobby_ids_.Swap(&other->lobby_ids_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestSetLobbyNickname::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestSetLobbyNickname_descriptor_; + metadata.reflection = RequestSetLobbyNickname_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ResponseSetLobbyNickname::kStatusFieldNumber; +#endif // !_MSC_VER + +ResponseSetLobbyNickname::ResponseSetLobbyNickname() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ResponseSetLobbyNickname::InitAsDefaultInstance() { + status_ = const_cast< ::rsctrl::core::Status*>(&::rsctrl::core::Status::default_instance()); +} + +ResponseSetLobbyNickname::ResponseSetLobbyNickname(const ResponseSetLobbyNickname& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ResponseSetLobbyNickname::SharedCtor() { + _cached_size_ = 0; + status_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ResponseSetLobbyNickname::~ResponseSetLobbyNickname() { + SharedDtor(); +} + +void ResponseSetLobbyNickname::SharedDtor() { + if (this != default_instance_) { + delete status_; + } +} + +void ResponseSetLobbyNickname::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ResponseSetLobbyNickname::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ResponseSetLobbyNickname_descriptor_; +} + +const ResponseSetLobbyNickname& ResponseSetLobbyNickname::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_chat_2eproto(); return *default_instance_; +} + +ResponseSetLobbyNickname* ResponseSetLobbyNickname::default_instance_ = NULL; + +ResponseSetLobbyNickname* ResponseSetLobbyNickname::New() const { + return new ResponseSetLobbyNickname; +} + +void ResponseSetLobbyNickname::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_status()) { + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ResponseSetLobbyNickname::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.core.Status status = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_status())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ResponseSetLobbyNickname::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->status(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ResponseSetLobbyNickname::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->status(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ResponseSetLobbyNickname::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->status()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ResponseSetLobbyNickname::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ResponseSetLobbyNickname* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ResponseSetLobbyNickname::MergeFrom(const ResponseSetLobbyNickname& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_status()) { + mutable_status()->::rsctrl::core::Status::MergeFrom(from.status()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ResponseSetLobbyNickname::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ResponseSetLobbyNickname::CopyFrom(const ResponseSetLobbyNickname& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ResponseSetLobbyNickname::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_status()) { + if (!this->status().IsInitialized()) return false; + } + return true; +} + +void ResponseSetLobbyNickname::Swap(ResponseSetLobbyNickname* other) { + if (other != this) { + std::swap(status_, other->status_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ResponseSetLobbyNickname::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ResponseSetLobbyNickname_descriptor_; + metadata.reflection = ResponseSetLobbyNickname_reflection_; + return metadata; +} + + +// =================================================================== + +const ::google::protobuf::EnumDescriptor* RequestRegisterEvents_RegisterAction_descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestRegisterEvents_RegisterAction_descriptor_; +} +bool RequestRegisterEvents_RegisterAction_IsValid(int value) { + switch(value) { + case 1: + case 2: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const RequestRegisterEvents_RegisterAction RequestRegisterEvents::REGISTER; +const RequestRegisterEvents_RegisterAction RequestRegisterEvents::DEREGISTER; +const RequestRegisterEvents_RegisterAction RequestRegisterEvents::RegisterAction_MIN; +const RequestRegisterEvents_RegisterAction RequestRegisterEvents::RegisterAction_MAX; +const int RequestRegisterEvents::RegisterAction_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int RequestRegisterEvents::kActionFieldNumber; +#endif // !_MSC_VER + +RequestRegisterEvents::RequestRegisterEvents() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RequestRegisterEvents::InitAsDefaultInstance() { +} + +RequestRegisterEvents::RequestRegisterEvents(const RequestRegisterEvents& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RequestRegisterEvents::SharedCtor() { + _cached_size_ = 0; + action_ = 1; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RequestRegisterEvents::~RequestRegisterEvents() { + SharedDtor(); +} + +void RequestRegisterEvents::SharedDtor() { + if (this != default_instance_) { + } +} + +void RequestRegisterEvents::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestRegisterEvents::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestRegisterEvents_descriptor_; +} + +const RequestRegisterEvents& RequestRegisterEvents::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_chat_2eproto(); return *default_instance_; +} + +RequestRegisterEvents* RequestRegisterEvents::default_instance_ = NULL; + +RequestRegisterEvents* RequestRegisterEvents::New() const { + return new RequestRegisterEvents; +} + +void RequestRegisterEvents::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + action_ = 1; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestRegisterEvents::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.chat.RequestRegisterEvents.RegisterAction action = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::rsctrl::chat::RequestRegisterEvents_RegisterAction_IsValid(value)) { + set_action(static_cast< ::rsctrl::chat::RequestRegisterEvents_RegisterAction >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void RequestRegisterEvents::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.chat.RequestRegisterEvents.RegisterAction action = 1; + if (has_action()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->action(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RequestRegisterEvents::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.chat.RequestRegisterEvents.RegisterAction action = 1; + if (has_action()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->action(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RequestRegisterEvents::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.chat.RequestRegisterEvents.RegisterAction action = 1; + if (has_action()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->action()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestRegisterEvents::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestRegisterEvents* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestRegisterEvents::MergeFrom(const RequestRegisterEvents& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_action()) { + set_action(from.action()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestRegisterEvents::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestRegisterEvents::CopyFrom(const RequestRegisterEvents& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestRegisterEvents::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void RequestRegisterEvents::Swap(RequestRegisterEvents* other) { + if (other != this) { + std::swap(action_, other->action_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestRegisterEvents::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestRegisterEvents_descriptor_; + metadata.reflection = RequestRegisterEvents_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ResponseRegisterEvents::kStatusFieldNumber; +#endif // !_MSC_VER + +ResponseRegisterEvents::ResponseRegisterEvents() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ResponseRegisterEvents::InitAsDefaultInstance() { + status_ = const_cast< ::rsctrl::core::Status*>(&::rsctrl::core::Status::default_instance()); +} + +ResponseRegisterEvents::ResponseRegisterEvents(const ResponseRegisterEvents& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ResponseRegisterEvents::SharedCtor() { + _cached_size_ = 0; + status_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ResponseRegisterEvents::~ResponseRegisterEvents() { + SharedDtor(); +} + +void ResponseRegisterEvents::SharedDtor() { + if (this != default_instance_) { + delete status_; + } +} + +void ResponseRegisterEvents::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ResponseRegisterEvents::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ResponseRegisterEvents_descriptor_; +} + +const ResponseRegisterEvents& ResponseRegisterEvents::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_chat_2eproto(); return *default_instance_; +} + +ResponseRegisterEvents* ResponseRegisterEvents::default_instance_ = NULL; + +ResponseRegisterEvents* ResponseRegisterEvents::New() const { + return new ResponseRegisterEvents; +} + +void ResponseRegisterEvents::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_status()) { + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ResponseRegisterEvents::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.core.Status status = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_status())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ResponseRegisterEvents::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->status(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ResponseRegisterEvents::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->status(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ResponseRegisterEvents::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->status()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ResponseRegisterEvents::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ResponseRegisterEvents* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ResponseRegisterEvents::MergeFrom(const ResponseRegisterEvents& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_status()) { + mutable_status()->::rsctrl::core::Status::MergeFrom(from.status()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ResponseRegisterEvents::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ResponseRegisterEvents::CopyFrom(const ResponseRegisterEvents& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ResponseRegisterEvents::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_status()) { + if (!this->status().IsInitialized()) return false; + } + return true; +} + +void ResponseRegisterEvents::Swap(ResponseRegisterEvents* other) { + if (other != this) { + std::swap(status_, other->status_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ResponseRegisterEvents::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ResponseRegisterEvents_descriptor_; + metadata.reflection = ResponseRegisterEvents_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int EventLobbyInvite::kLobbyFieldNumber; +#endif // !_MSC_VER + +EventLobbyInvite::EventLobbyInvite() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void EventLobbyInvite::InitAsDefaultInstance() { + lobby_ = const_cast< ::rsctrl::chat::ChatLobbyInfo*>(&::rsctrl::chat::ChatLobbyInfo::default_instance()); +} + +EventLobbyInvite::EventLobbyInvite(const EventLobbyInvite& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void EventLobbyInvite::SharedCtor() { + _cached_size_ = 0; + lobby_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +EventLobbyInvite::~EventLobbyInvite() { + SharedDtor(); +} + +void EventLobbyInvite::SharedDtor() { + if (this != default_instance_) { + delete lobby_; + } +} + +void EventLobbyInvite::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* EventLobbyInvite::descriptor() { + protobuf_AssignDescriptorsOnce(); + return EventLobbyInvite_descriptor_; +} + +const EventLobbyInvite& EventLobbyInvite::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_chat_2eproto(); return *default_instance_; +} + +EventLobbyInvite* EventLobbyInvite::default_instance_ = NULL; + +EventLobbyInvite* EventLobbyInvite::New() const { + return new EventLobbyInvite; +} + +void EventLobbyInvite::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_lobby()) { + if (lobby_ != NULL) lobby_->::rsctrl::chat::ChatLobbyInfo::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool EventLobbyInvite::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.chat.ChatLobbyInfo lobby = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_lobby())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void EventLobbyInvite::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.chat.ChatLobbyInfo lobby = 1; + if (has_lobby()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->lobby(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* EventLobbyInvite::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.chat.ChatLobbyInfo lobby = 1; + if (has_lobby()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->lobby(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int EventLobbyInvite::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.chat.ChatLobbyInfo lobby = 1; + if (has_lobby()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->lobby()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void EventLobbyInvite::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const EventLobbyInvite* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void EventLobbyInvite::MergeFrom(const EventLobbyInvite& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_lobby()) { + mutable_lobby()->::rsctrl::chat::ChatLobbyInfo::MergeFrom(from.lobby()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void EventLobbyInvite::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void EventLobbyInvite::CopyFrom(const EventLobbyInvite& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool EventLobbyInvite::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_lobby()) { + if (!this->lobby().IsInitialized()) return false; + } + return true; +} + +void EventLobbyInvite::Swap(EventLobbyInvite* other) { + if (other != this) { + std::swap(lobby_, other->lobby_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata EventLobbyInvite::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = EventLobbyInvite_descriptor_; + metadata.reflection = EventLobbyInvite_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int EventChatMessage::kMsgFieldNumber; +#endif // !_MSC_VER + +EventChatMessage::EventChatMessage() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void EventChatMessage::InitAsDefaultInstance() { + msg_ = const_cast< ::rsctrl::chat::ChatMessage*>(&::rsctrl::chat::ChatMessage::default_instance()); +} + +EventChatMessage::EventChatMessage(const EventChatMessage& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void EventChatMessage::SharedCtor() { + _cached_size_ = 0; + msg_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +EventChatMessage::~EventChatMessage() { + SharedDtor(); +} + +void EventChatMessage::SharedDtor() { + if (this != default_instance_) { + delete msg_; + } +} + +void EventChatMessage::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* EventChatMessage::descriptor() { + protobuf_AssignDescriptorsOnce(); + return EventChatMessage_descriptor_; +} + +const EventChatMessage& EventChatMessage::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_chat_2eproto(); return *default_instance_; +} + +EventChatMessage* EventChatMessage::default_instance_ = NULL; + +EventChatMessage* EventChatMessage::New() const { + return new EventChatMessage; +} + +void EventChatMessage::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_msg()) { + if (msg_ != NULL) msg_->::rsctrl::chat::ChatMessage::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool EventChatMessage::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.chat.ChatMessage msg = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_msg())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void EventChatMessage::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.chat.ChatMessage msg = 1; + if (has_msg()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->msg(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* EventChatMessage::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.chat.ChatMessage msg = 1; + if (has_msg()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->msg(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int EventChatMessage::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.chat.ChatMessage msg = 1; + if (has_msg()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->msg()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void EventChatMessage::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const EventChatMessage* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void EventChatMessage::MergeFrom(const EventChatMessage& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_msg()) { + mutable_msg()->::rsctrl::chat::ChatMessage::MergeFrom(from.msg()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void EventChatMessage::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void EventChatMessage::CopyFrom(const EventChatMessage& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool EventChatMessage::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_msg()) { + if (!this->msg().IsInitialized()) return false; + } + return true; +} + +void EventChatMessage::Swap(EventChatMessage* other) { + if (other != this) { + std::swap(msg_, other->msg_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata EventChatMessage::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = EventChatMessage_descriptor_; + metadata.reflection = EventChatMessage_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int RequestSendMessage::kMsgFieldNumber; +#endif // !_MSC_VER + +RequestSendMessage::RequestSendMessage() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RequestSendMessage::InitAsDefaultInstance() { + msg_ = const_cast< ::rsctrl::chat::ChatMessage*>(&::rsctrl::chat::ChatMessage::default_instance()); +} + +RequestSendMessage::RequestSendMessage(const RequestSendMessage& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RequestSendMessage::SharedCtor() { + _cached_size_ = 0; + msg_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RequestSendMessage::~RequestSendMessage() { + SharedDtor(); +} + +void RequestSendMessage::SharedDtor() { + if (this != default_instance_) { + delete msg_; + } +} + +void RequestSendMessage::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestSendMessage::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestSendMessage_descriptor_; +} + +const RequestSendMessage& RequestSendMessage::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_chat_2eproto(); return *default_instance_; +} + +RequestSendMessage* RequestSendMessage::default_instance_ = NULL; + +RequestSendMessage* RequestSendMessage::New() const { + return new RequestSendMessage; +} + +void RequestSendMessage::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_msg()) { + if (msg_ != NULL) msg_->::rsctrl::chat::ChatMessage::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestSendMessage::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.chat.ChatMessage msg = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_msg())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void RequestSendMessage::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.chat.ChatMessage msg = 1; + if (has_msg()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->msg(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RequestSendMessage::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.chat.ChatMessage msg = 1; + if (has_msg()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->msg(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RequestSendMessage::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.chat.ChatMessage msg = 1; + if (has_msg()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->msg()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestSendMessage::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestSendMessage* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestSendMessage::MergeFrom(const RequestSendMessage& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_msg()) { + mutable_msg()->::rsctrl::chat::ChatMessage::MergeFrom(from.msg()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestSendMessage::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestSendMessage::CopyFrom(const RequestSendMessage& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestSendMessage::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_msg()) { + if (!this->msg().IsInitialized()) return false; + } + return true; +} + +void RequestSendMessage::Swap(RequestSendMessage* other) { + if (other != this) { + std::swap(msg_, other->msg_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestSendMessage::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestSendMessage_descriptor_; + metadata.reflection = RequestSendMessage_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ResponseSendMessage::kStatusFieldNumber; +#endif // !_MSC_VER + +ResponseSendMessage::ResponseSendMessage() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ResponseSendMessage::InitAsDefaultInstance() { + status_ = const_cast< ::rsctrl::core::Status*>(&::rsctrl::core::Status::default_instance()); +} + +ResponseSendMessage::ResponseSendMessage(const ResponseSendMessage& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ResponseSendMessage::SharedCtor() { + _cached_size_ = 0; + status_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ResponseSendMessage::~ResponseSendMessage() { + SharedDtor(); +} + +void ResponseSendMessage::SharedDtor() { + if (this != default_instance_) { + delete status_; + } +} + +void ResponseSendMessage::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ResponseSendMessage::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ResponseSendMessage_descriptor_; +} + +const ResponseSendMessage& ResponseSendMessage::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_chat_2eproto(); return *default_instance_; +} + +ResponseSendMessage* ResponseSendMessage::default_instance_ = NULL; + +ResponseSendMessage* ResponseSendMessage::New() const { + return new ResponseSendMessage; +} + +void ResponseSendMessage::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_status()) { + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ResponseSendMessage::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.core.Status status = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_status())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ResponseSendMessage::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->status(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ResponseSendMessage::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->status(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ResponseSendMessage::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->status()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ResponseSendMessage::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ResponseSendMessage* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ResponseSendMessage::MergeFrom(const ResponseSendMessage& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_status()) { + mutable_status()->::rsctrl::core::Status::MergeFrom(from.status()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ResponseSendMessage::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ResponseSendMessage::CopyFrom(const ResponseSendMessage& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ResponseSendMessage::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_status()) { + if (!this->status().IsInitialized()) return false; + } + return true; +} + +void ResponseSendMessage::Swap(ResponseSendMessage* other) { + if (other != this) { + std::swap(status_, other->status_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ResponseSendMessage::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ResponseSendMessage_descriptor_; + metadata.reflection = ResponseSendMessage_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace chat +} // namespace rsctrl + +// @@protoc_insertion_point(global_scope) diff --git a/retroshare-nogui/src/rpc/proto/gencc/chat.pb.h b/retroshare-nogui/src/rpc/proto/gencc/chat.pb.h new file mode 100644 index 000000000..d6ebc3adf --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/gencc/chat.pb.h @@ -0,0 +1,3325 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: chat.proto + +#ifndef PROTOBUF_chat_2eproto__INCLUDED +#define PROTOBUF_chat_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2004000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2004001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include "core.pb.h" +// @@protoc_insertion_point(includes) + +namespace rsctrl { +namespace chat { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_chat_2eproto(); +void protobuf_AssignDesc_chat_2eproto(); +void protobuf_ShutdownFile_chat_2eproto(); + +class ChatLobbyInfo; +class ChatId; +class ChatMessage; +class ResponseChatLobbies; +class RequestChatLobbies; +class RequestCreateLobby; +class RequestJoinOrLeaveLobby; +class RequestSetLobbyNickname; +class ResponseSetLobbyNickname; +class RequestRegisterEvents; +class ResponseRegisterEvents; +class EventLobbyInvite; +class EventChatMessage; +class RequestSendMessage; +class ResponseSendMessage; + +enum ChatLobbyInfo_LobbyState { + ChatLobbyInfo_LobbyState_LOBBYSTATE_JOINED = 1, + ChatLobbyInfo_LobbyState_LOBBYSTATE_INVITED = 2, + ChatLobbyInfo_LobbyState_LOBBYSTATE_PUBLIC = 3 +}; +bool ChatLobbyInfo_LobbyState_IsValid(int value); +const ChatLobbyInfo_LobbyState ChatLobbyInfo_LobbyState_LobbyState_MIN = ChatLobbyInfo_LobbyState_LOBBYSTATE_JOINED; +const ChatLobbyInfo_LobbyState ChatLobbyInfo_LobbyState_LobbyState_MAX = ChatLobbyInfo_LobbyState_LOBBYSTATE_PUBLIC; +const int ChatLobbyInfo_LobbyState_LobbyState_ARRAYSIZE = ChatLobbyInfo_LobbyState_LobbyState_MAX + 1; + +const ::google::protobuf::EnumDescriptor* ChatLobbyInfo_LobbyState_descriptor(); +inline const ::std::string& ChatLobbyInfo_LobbyState_Name(ChatLobbyInfo_LobbyState value) { + return ::google::protobuf::internal::NameOfEnum( + ChatLobbyInfo_LobbyState_descriptor(), value); +} +inline bool ChatLobbyInfo_LobbyState_Parse( + const ::std::string& name, ChatLobbyInfo_LobbyState* value) { + return ::google::protobuf::internal::ParseNamedEnum( + ChatLobbyInfo_LobbyState_descriptor(), name, value); +} +enum RequestChatLobbies_LobbySet { + RequestChatLobbies_LobbySet_LOBBYSET_ALL = 1, + RequestChatLobbies_LobbySet_LOBBYSET_JOINED = 2, + RequestChatLobbies_LobbySet_LOBBYSET_INVITED = 3, + RequestChatLobbies_LobbySet_LOBBYSET_PUBLIC = 4 +}; +bool RequestChatLobbies_LobbySet_IsValid(int value); +const RequestChatLobbies_LobbySet RequestChatLobbies_LobbySet_LobbySet_MIN = RequestChatLobbies_LobbySet_LOBBYSET_ALL; +const RequestChatLobbies_LobbySet RequestChatLobbies_LobbySet_LobbySet_MAX = RequestChatLobbies_LobbySet_LOBBYSET_PUBLIC; +const int RequestChatLobbies_LobbySet_LobbySet_ARRAYSIZE = RequestChatLobbies_LobbySet_LobbySet_MAX + 1; + +const ::google::protobuf::EnumDescriptor* RequestChatLobbies_LobbySet_descriptor(); +inline const ::std::string& RequestChatLobbies_LobbySet_Name(RequestChatLobbies_LobbySet value) { + return ::google::protobuf::internal::NameOfEnum( + RequestChatLobbies_LobbySet_descriptor(), value); +} +inline bool RequestChatLobbies_LobbySet_Parse( + const ::std::string& name, RequestChatLobbies_LobbySet* value) { + return ::google::protobuf::internal::ParseNamedEnum( + RequestChatLobbies_LobbySet_descriptor(), name, value); +} +enum RequestJoinOrLeaveLobby_LobbyAction { + RequestJoinOrLeaveLobby_LobbyAction_JOIN_OR_ACCEPT = 1, + RequestJoinOrLeaveLobby_LobbyAction_LEAVE_OR_DENY = 2 +}; +bool RequestJoinOrLeaveLobby_LobbyAction_IsValid(int value); +const RequestJoinOrLeaveLobby_LobbyAction RequestJoinOrLeaveLobby_LobbyAction_LobbyAction_MIN = RequestJoinOrLeaveLobby_LobbyAction_JOIN_OR_ACCEPT; +const RequestJoinOrLeaveLobby_LobbyAction RequestJoinOrLeaveLobby_LobbyAction_LobbyAction_MAX = RequestJoinOrLeaveLobby_LobbyAction_LEAVE_OR_DENY; +const int RequestJoinOrLeaveLobby_LobbyAction_LobbyAction_ARRAYSIZE = RequestJoinOrLeaveLobby_LobbyAction_LobbyAction_MAX + 1; + +const ::google::protobuf::EnumDescriptor* RequestJoinOrLeaveLobby_LobbyAction_descriptor(); +inline const ::std::string& RequestJoinOrLeaveLobby_LobbyAction_Name(RequestJoinOrLeaveLobby_LobbyAction value) { + return ::google::protobuf::internal::NameOfEnum( + RequestJoinOrLeaveLobby_LobbyAction_descriptor(), value); +} +inline bool RequestJoinOrLeaveLobby_LobbyAction_Parse( + const ::std::string& name, RequestJoinOrLeaveLobby_LobbyAction* value) { + return ::google::protobuf::internal::ParseNamedEnum( + RequestJoinOrLeaveLobby_LobbyAction_descriptor(), name, value); +} +enum RequestRegisterEvents_RegisterAction { + RequestRegisterEvents_RegisterAction_REGISTER = 1, + RequestRegisterEvents_RegisterAction_DEREGISTER = 2 +}; +bool RequestRegisterEvents_RegisterAction_IsValid(int value); +const RequestRegisterEvents_RegisterAction RequestRegisterEvents_RegisterAction_RegisterAction_MIN = RequestRegisterEvents_RegisterAction_REGISTER; +const RequestRegisterEvents_RegisterAction RequestRegisterEvents_RegisterAction_RegisterAction_MAX = RequestRegisterEvents_RegisterAction_DEREGISTER; +const int RequestRegisterEvents_RegisterAction_RegisterAction_ARRAYSIZE = RequestRegisterEvents_RegisterAction_RegisterAction_MAX + 1; + +const ::google::protobuf::EnumDescriptor* RequestRegisterEvents_RegisterAction_descriptor(); +inline const ::std::string& RequestRegisterEvents_RegisterAction_Name(RequestRegisterEvents_RegisterAction value) { + return ::google::protobuf::internal::NameOfEnum( + RequestRegisterEvents_RegisterAction_descriptor(), value); +} +inline bool RequestRegisterEvents_RegisterAction_Parse( + const ::std::string& name, RequestRegisterEvents_RegisterAction* value) { + return ::google::protobuf::internal::ParseNamedEnum( + RequestRegisterEvents_RegisterAction_descriptor(), name, value); +} +enum RequestMsgIds { + MsgId_RequestChatLobbies = 1, + MsgId_RequestCreateLobby = 2, + MsgId_RequestJoinOrLeaveLobby = 3, + MsgId_RequestSetLobbyNickname = 4, + MsgId_RequestRegisterEvents = 5, + MsgId_RequestSendMessage = 6 +}; +bool RequestMsgIds_IsValid(int value); +const RequestMsgIds RequestMsgIds_MIN = MsgId_RequestChatLobbies; +const RequestMsgIds RequestMsgIds_MAX = MsgId_RequestSendMessage; +const int RequestMsgIds_ARRAYSIZE = RequestMsgIds_MAX + 1; + +const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor(); +inline const ::std::string& RequestMsgIds_Name(RequestMsgIds value) { + return ::google::protobuf::internal::NameOfEnum( + RequestMsgIds_descriptor(), value); +} +inline bool RequestMsgIds_Parse( + const ::std::string& name, RequestMsgIds* value) { + return ::google::protobuf::internal::ParseNamedEnum( + RequestMsgIds_descriptor(), name, value); +} +enum ResponseMsgIds { + MsgId_ResponseChatLobbies = 1, + MsgId_ResponseSetLobbyNickname = 4, + MsgId_ResponseRegisterEvents = 5, + MsgId_ResponseSendMessage = 6, + MsgId_EventLobbyInvite = 101, + MsgId_EventChatMessage = 102 +}; +bool ResponseMsgIds_IsValid(int value); +const ResponseMsgIds ResponseMsgIds_MIN = MsgId_ResponseChatLobbies; +const ResponseMsgIds ResponseMsgIds_MAX = MsgId_EventChatMessage; +const int ResponseMsgIds_ARRAYSIZE = ResponseMsgIds_MAX + 1; + +const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor(); +inline const ::std::string& ResponseMsgIds_Name(ResponseMsgIds value) { + return ::google::protobuf::internal::NameOfEnum( + ResponseMsgIds_descriptor(), value); +} +inline bool ResponseMsgIds_Parse( + const ::std::string& name, ResponseMsgIds* value) { + return ::google::protobuf::internal::ParseNamedEnum( + ResponseMsgIds_descriptor(), name, value); +} +enum LobbyPrivacyLevel { + PRIVACY_PRIVATE = 1, + PRIVACY_PUBLIC = 2 +}; +bool LobbyPrivacyLevel_IsValid(int value); +const LobbyPrivacyLevel LobbyPrivacyLevel_MIN = PRIVACY_PRIVATE; +const LobbyPrivacyLevel LobbyPrivacyLevel_MAX = PRIVACY_PUBLIC; +const int LobbyPrivacyLevel_ARRAYSIZE = LobbyPrivacyLevel_MAX + 1; + +const ::google::protobuf::EnumDescriptor* LobbyPrivacyLevel_descriptor(); +inline const ::std::string& LobbyPrivacyLevel_Name(LobbyPrivacyLevel value) { + return ::google::protobuf::internal::NameOfEnum( + LobbyPrivacyLevel_descriptor(), value); +} +inline bool LobbyPrivacyLevel_Parse( + const ::std::string& name, LobbyPrivacyLevel* value) { + return ::google::protobuf::internal::ParseNamedEnum( + LobbyPrivacyLevel_descriptor(), name, value); +} +enum ChatType { + TYPE_PRIVATE = 1, + TYPE_LOBBY = 2, + TYPE_GROUP = 3 +}; +bool ChatType_IsValid(int value); +const ChatType ChatType_MIN = TYPE_PRIVATE; +const ChatType ChatType_MAX = TYPE_GROUP; +const int ChatType_ARRAYSIZE = ChatType_MAX + 1; + +const ::google::protobuf::EnumDescriptor* ChatType_descriptor(); +inline const ::std::string& ChatType_Name(ChatType value) { + return ::google::protobuf::internal::NameOfEnum( + ChatType_descriptor(), value); +} +inline bool ChatType_Parse( + const ::std::string& name, ChatType* value) { + return ::google::protobuf::internal::ParseNamedEnum( + ChatType_descriptor(), name, value); +} +// =================================================================== + +class ChatLobbyInfo : public ::google::protobuf::Message { + public: + ChatLobbyInfo(); + virtual ~ChatLobbyInfo(); + + ChatLobbyInfo(const ChatLobbyInfo& from); + + inline ChatLobbyInfo& operator=(const ChatLobbyInfo& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ChatLobbyInfo& default_instance(); + + void Swap(ChatLobbyInfo* other); + + // implements Message ---------------------------------------------- + + ChatLobbyInfo* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ChatLobbyInfo& from); + void MergeFrom(const ChatLobbyInfo& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef ChatLobbyInfo_LobbyState LobbyState; + static const LobbyState LOBBYSTATE_JOINED = ChatLobbyInfo_LobbyState_LOBBYSTATE_JOINED; + static const LobbyState LOBBYSTATE_INVITED = ChatLobbyInfo_LobbyState_LOBBYSTATE_INVITED; + static const LobbyState LOBBYSTATE_PUBLIC = ChatLobbyInfo_LobbyState_LOBBYSTATE_PUBLIC; + static inline bool LobbyState_IsValid(int value) { + return ChatLobbyInfo_LobbyState_IsValid(value); + } + static const LobbyState LobbyState_MIN = + ChatLobbyInfo_LobbyState_LobbyState_MIN; + static const LobbyState LobbyState_MAX = + ChatLobbyInfo_LobbyState_LobbyState_MAX; + static const int LobbyState_ARRAYSIZE = + ChatLobbyInfo_LobbyState_LobbyState_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + LobbyState_descriptor() { + return ChatLobbyInfo_LobbyState_descriptor(); + } + static inline const ::std::string& LobbyState_Name(LobbyState value) { + return ChatLobbyInfo_LobbyState_Name(value); + } + static inline bool LobbyState_Parse(const ::std::string& name, + LobbyState* value) { + return ChatLobbyInfo_LobbyState_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // required string lobby_id = 1; + inline bool has_lobby_id() const; + inline void clear_lobby_id(); + static const int kLobbyIdFieldNumber = 1; + inline const ::std::string& lobby_id() const; + inline void set_lobby_id(const ::std::string& value); + inline void set_lobby_id(const char* value); + inline void set_lobby_id(const char* value, size_t size); + inline ::std::string* mutable_lobby_id(); + inline ::std::string* release_lobby_id(); + + // required string lobby_topic = 2; + inline bool has_lobby_topic() const; + inline void clear_lobby_topic(); + static const int kLobbyTopicFieldNumber = 2; + inline const ::std::string& lobby_topic() const; + inline void set_lobby_topic(const ::std::string& value); + inline void set_lobby_topic(const char* value); + inline void set_lobby_topic(const char* value, size_t size); + inline ::std::string* mutable_lobby_topic(); + inline ::std::string* release_lobby_topic(); + + // required string lobby_name = 3; + inline bool has_lobby_name() const; + inline void clear_lobby_name(); + static const int kLobbyNameFieldNumber = 3; + inline const ::std::string& lobby_name() const; + inline void set_lobby_name(const ::std::string& value); + inline void set_lobby_name(const char* value); + inline void set_lobby_name(const char* value, size_t size); + inline ::std::string* mutable_lobby_name(); + inline ::std::string* release_lobby_name(); + + // required string lobby_nickname = 4; + inline bool has_lobby_nickname() const; + inline void clear_lobby_nickname(); + static const int kLobbyNicknameFieldNumber = 4; + inline const ::std::string& lobby_nickname() const; + inline void set_lobby_nickname(const ::std::string& value); + inline void set_lobby_nickname(const char* value); + inline void set_lobby_nickname(const char* value, size_t size); + inline ::std::string* mutable_lobby_nickname(); + inline ::std::string* release_lobby_nickname(); + + // required .rsctrl.chat.LobbyPrivacyLevel privacy_level = 5; + inline bool has_privacy_level() const; + inline void clear_privacy_level(); + static const int kPrivacyLevelFieldNumber = 5; + inline rsctrl::chat::LobbyPrivacyLevel privacy_level() const; + inline void set_privacy_level(rsctrl::chat::LobbyPrivacyLevel value); + + // required .rsctrl.chat.ChatLobbyInfo.LobbyState lobby_state = 6; + inline bool has_lobby_state() const; + inline void clear_lobby_state(); + static const int kLobbyStateFieldNumber = 6; + inline ::rsctrl::chat::ChatLobbyInfo_LobbyState lobby_state() const; + inline void set_lobby_state(::rsctrl::chat::ChatLobbyInfo_LobbyState value); + + // required uint32 no_peers = 7; + inline bool has_no_peers() const; + inline void clear_no_peers(); + static const int kNoPeersFieldNumber = 7; + inline ::google::protobuf::uint32 no_peers() const; + inline void set_no_peers(::google::protobuf::uint32 value); + + // required uint32 last_report_time = 8; + inline bool has_last_report_time() const; + inline void clear_last_report_time(); + static const int kLastReportTimeFieldNumber = 8; + inline ::google::protobuf::uint32 last_report_time() const; + inline void set_last_report_time(::google::protobuf::uint32 value); + + // required uint32 last_activity = 9; + inline bool has_last_activity() const; + inline void clear_last_activity(); + static const int kLastActivityFieldNumber = 9; + inline ::google::protobuf::uint32 last_activity() const; + inline void set_last_activity(::google::protobuf::uint32 value); + + // repeated string participating_friends = 10; + inline int participating_friends_size() const; + inline void clear_participating_friends(); + static const int kParticipatingFriendsFieldNumber = 10; + inline const ::std::string& participating_friends(int index) const; + inline ::std::string* mutable_participating_friends(int index); + inline void set_participating_friends(int index, const ::std::string& value); + inline void set_participating_friends(int index, const char* value); + inline void set_participating_friends(int index, const char* value, size_t size); + inline ::std::string* add_participating_friends(); + inline void add_participating_friends(const ::std::string& value); + inline void add_participating_friends(const char* value); + inline void add_participating_friends(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& participating_friends() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_participating_friends(); + + // repeated string nicknames = 11; + inline int nicknames_size() const; + inline void clear_nicknames(); + static const int kNicknamesFieldNumber = 11; + inline const ::std::string& nicknames(int index) const; + inline ::std::string* mutable_nicknames(int index); + inline void set_nicknames(int index, const ::std::string& value); + inline void set_nicknames(int index, const char* value); + inline void set_nicknames(int index, const char* value, size_t size); + inline ::std::string* add_nicknames(); + inline void add_nicknames(const ::std::string& value); + inline void add_nicknames(const char* value); + inline void add_nicknames(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& nicknames() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_nicknames(); + + // @@protoc_insertion_point(class_scope:rsctrl.chat.ChatLobbyInfo) + private: + inline void set_has_lobby_id(); + inline void clear_has_lobby_id(); + inline void set_has_lobby_topic(); + inline void clear_has_lobby_topic(); + inline void set_has_lobby_name(); + inline void clear_has_lobby_name(); + inline void set_has_lobby_nickname(); + inline void clear_has_lobby_nickname(); + inline void set_has_privacy_level(); + inline void clear_has_privacy_level(); + inline void set_has_lobby_state(); + inline void clear_has_lobby_state(); + inline void set_has_no_peers(); + inline void clear_has_no_peers(); + inline void set_has_last_report_time(); + inline void clear_has_last_report_time(); + inline void set_has_last_activity(); + inline void clear_has_last_activity(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* lobby_id_; + ::std::string* lobby_topic_; + ::std::string* lobby_name_; + ::std::string* lobby_nickname_; + int privacy_level_; + int lobby_state_; + ::google::protobuf::uint32 no_peers_; + ::google::protobuf::uint32 last_report_time_; + ::google::protobuf::RepeatedPtrField< ::std::string> participating_friends_; + ::google::protobuf::RepeatedPtrField< ::std::string> nicknames_; + ::google::protobuf::uint32 last_activity_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(11 + 31) / 32]; + + friend void protobuf_AddDesc_chat_2eproto(); + friend void protobuf_AssignDesc_chat_2eproto(); + friend void protobuf_ShutdownFile_chat_2eproto(); + + void InitAsDefaultInstance(); + static ChatLobbyInfo* default_instance_; +}; +// ------------------------------------------------------------------- + +class ChatId : public ::google::protobuf::Message { + public: + ChatId(); + virtual ~ChatId(); + + ChatId(const ChatId& from); + + inline ChatId& operator=(const ChatId& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ChatId& default_instance(); + + void Swap(ChatId* other); + + // implements Message ---------------------------------------------- + + ChatId* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ChatId& from); + void MergeFrom(const ChatId& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .rsctrl.chat.ChatType chat_type = 1; + inline bool has_chat_type() const; + inline void clear_chat_type(); + static const int kChatTypeFieldNumber = 1; + inline rsctrl::chat::ChatType chat_type() const; + inline void set_chat_type(rsctrl::chat::ChatType value); + + // required string chat_id = 2; + inline bool has_chat_id() const; + inline void clear_chat_id(); + static const int kChatIdFieldNumber = 2; + inline const ::std::string& chat_id() const; + inline void set_chat_id(const ::std::string& value); + inline void set_chat_id(const char* value); + inline void set_chat_id(const char* value, size_t size); + inline ::std::string* mutable_chat_id(); + inline ::std::string* release_chat_id(); + + // @@protoc_insertion_point(class_scope:rsctrl.chat.ChatId) + private: + inline void set_has_chat_type(); + inline void clear_has_chat_type(); + inline void set_has_chat_id(); + inline void clear_has_chat_id(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* chat_id_; + int chat_type_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_chat_2eproto(); + friend void protobuf_AssignDesc_chat_2eproto(); + friend void protobuf_ShutdownFile_chat_2eproto(); + + void InitAsDefaultInstance(); + static ChatId* default_instance_; +}; +// ------------------------------------------------------------------- + +class ChatMessage : public ::google::protobuf::Message { + public: + ChatMessage(); + virtual ~ChatMessage(); + + ChatMessage(const ChatMessage& from); + + inline ChatMessage& operator=(const ChatMessage& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ChatMessage& default_instance(); + + void Swap(ChatMessage* other); + + // implements Message ---------------------------------------------- + + ChatMessage* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ChatMessage& from); + void MergeFrom(const ChatMessage& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .rsctrl.chat.ChatId id = 1; + inline bool has_id() const; + inline void clear_id(); + static const int kIdFieldNumber = 1; + inline const ::rsctrl::chat::ChatId& id() const; + inline ::rsctrl::chat::ChatId* mutable_id(); + inline ::rsctrl::chat::ChatId* release_id(); + + // required string msg = 2; + inline bool has_msg() const; + inline void clear_msg(); + static const int kMsgFieldNumber = 2; + inline const ::std::string& msg() const; + inline void set_msg(const ::std::string& value); + inline void set_msg(const char* value); + inline void set_msg(const char* value, size_t size); + inline ::std::string* mutable_msg(); + inline ::std::string* release_msg(); + + // optional string peer_nickname = 3; + inline bool has_peer_nickname() const; + inline void clear_peer_nickname(); + static const int kPeerNicknameFieldNumber = 3; + inline const ::std::string& peer_nickname() const; + inline void set_peer_nickname(const ::std::string& value); + inline void set_peer_nickname(const char* value); + inline void set_peer_nickname(const char* value, size_t size); + inline ::std::string* mutable_peer_nickname(); + inline ::std::string* release_peer_nickname(); + + // optional uint32 chat_flags = 4; + inline bool has_chat_flags() const; + inline void clear_chat_flags(); + static const int kChatFlagsFieldNumber = 4; + inline ::google::protobuf::uint32 chat_flags() const; + inline void set_chat_flags(::google::protobuf::uint32 value); + + // optional uint32 send_time = 5; + inline bool has_send_time() const; + inline void clear_send_time(); + static const int kSendTimeFieldNumber = 5; + inline ::google::protobuf::uint32 send_time() const; + inline void set_send_time(::google::protobuf::uint32 value); + + // optional uint32 recv_time = 6; + inline bool has_recv_time() const; + inline void clear_recv_time(); + static const int kRecvTimeFieldNumber = 6; + inline ::google::protobuf::uint32 recv_time() const; + inline void set_recv_time(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:rsctrl.chat.ChatMessage) + private: + inline void set_has_id(); + inline void clear_has_id(); + inline void set_has_msg(); + inline void clear_has_msg(); + inline void set_has_peer_nickname(); + inline void clear_has_peer_nickname(); + inline void set_has_chat_flags(); + inline void clear_has_chat_flags(); + inline void set_has_send_time(); + inline void clear_has_send_time(); + inline void set_has_recv_time(); + inline void clear_has_recv_time(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::rsctrl::chat::ChatId* id_; + ::std::string* msg_; + ::std::string* peer_nickname_; + ::google::protobuf::uint32 chat_flags_; + ::google::protobuf::uint32 send_time_; + ::google::protobuf::uint32 recv_time_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(6 + 31) / 32]; + + friend void protobuf_AddDesc_chat_2eproto(); + friend void protobuf_AssignDesc_chat_2eproto(); + friend void protobuf_ShutdownFile_chat_2eproto(); + + void InitAsDefaultInstance(); + static ChatMessage* default_instance_; +}; +// ------------------------------------------------------------------- + +class ResponseChatLobbies : public ::google::protobuf::Message { + public: + ResponseChatLobbies(); + virtual ~ResponseChatLobbies(); + + ResponseChatLobbies(const ResponseChatLobbies& from); + + inline ResponseChatLobbies& operator=(const ResponseChatLobbies& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ResponseChatLobbies& default_instance(); + + void Swap(ResponseChatLobbies* other); + + // implements Message ---------------------------------------------- + + ResponseChatLobbies* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ResponseChatLobbies& from); + void MergeFrom(const ResponseChatLobbies& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .rsctrl.core.Status status = 1; + inline bool has_status() const; + inline void clear_status(); + static const int kStatusFieldNumber = 1; + inline const ::rsctrl::core::Status& status() const; + inline ::rsctrl::core::Status* mutable_status(); + inline ::rsctrl::core::Status* release_status(); + + // repeated .rsctrl.chat.ChatLobbyInfo lobbies = 2; + inline int lobbies_size() const; + inline void clear_lobbies(); + static const int kLobbiesFieldNumber = 2; + inline const ::rsctrl::chat::ChatLobbyInfo& lobbies(int index) const; + inline ::rsctrl::chat::ChatLobbyInfo* mutable_lobbies(int index); + inline ::rsctrl::chat::ChatLobbyInfo* add_lobbies(); + inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::chat::ChatLobbyInfo >& + lobbies() const; + inline ::google::protobuf::RepeatedPtrField< ::rsctrl::chat::ChatLobbyInfo >* + mutable_lobbies(); + + // @@protoc_insertion_point(class_scope:rsctrl.chat.ResponseChatLobbies) + private: + inline void set_has_status(); + inline void clear_has_status(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::rsctrl::core::Status* status_; + ::google::protobuf::RepeatedPtrField< ::rsctrl::chat::ChatLobbyInfo > lobbies_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_chat_2eproto(); + friend void protobuf_AssignDesc_chat_2eproto(); + friend void protobuf_ShutdownFile_chat_2eproto(); + + void InitAsDefaultInstance(); + static ResponseChatLobbies* default_instance_; +}; +// ------------------------------------------------------------------- + +class RequestChatLobbies : public ::google::protobuf::Message { + public: + RequestChatLobbies(); + virtual ~RequestChatLobbies(); + + RequestChatLobbies(const RequestChatLobbies& from); + + inline RequestChatLobbies& operator=(const RequestChatLobbies& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestChatLobbies& default_instance(); + + void Swap(RequestChatLobbies* other); + + // implements Message ---------------------------------------------- + + RequestChatLobbies* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestChatLobbies& from); + void MergeFrom(const RequestChatLobbies& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef RequestChatLobbies_LobbySet LobbySet; + static const LobbySet LOBBYSET_ALL = RequestChatLobbies_LobbySet_LOBBYSET_ALL; + static const LobbySet LOBBYSET_JOINED = RequestChatLobbies_LobbySet_LOBBYSET_JOINED; + static const LobbySet LOBBYSET_INVITED = RequestChatLobbies_LobbySet_LOBBYSET_INVITED; + static const LobbySet LOBBYSET_PUBLIC = RequestChatLobbies_LobbySet_LOBBYSET_PUBLIC; + static inline bool LobbySet_IsValid(int value) { + return RequestChatLobbies_LobbySet_IsValid(value); + } + static const LobbySet LobbySet_MIN = + RequestChatLobbies_LobbySet_LobbySet_MIN; + static const LobbySet LobbySet_MAX = + RequestChatLobbies_LobbySet_LobbySet_MAX; + static const int LobbySet_ARRAYSIZE = + RequestChatLobbies_LobbySet_LobbySet_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + LobbySet_descriptor() { + return RequestChatLobbies_LobbySet_descriptor(); + } + static inline const ::std::string& LobbySet_Name(LobbySet value) { + return RequestChatLobbies_LobbySet_Name(value); + } + static inline bool LobbySet_Parse(const ::std::string& name, + LobbySet* value) { + return RequestChatLobbies_LobbySet_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // required .rsctrl.chat.RequestChatLobbies.LobbySet lobby_set = 1; + inline bool has_lobby_set() const; + inline void clear_lobby_set(); + static const int kLobbySetFieldNumber = 1; + inline ::rsctrl::chat::RequestChatLobbies_LobbySet lobby_set() const; + inline void set_lobby_set(::rsctrl::chat::RequestChatLobbies_LobbySet value); + + // @@protoc_insertion_point(class_scope:rsctrl.chat.RequestChatLobbies) + private: + inline void set_has_lobby_set(); + inline void clear_has_lobby_set(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + int lobby_set_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_chat_2eproto(); + friend void protobuf_AssignDesc_chat_2eproto(); + friend void protobuf_ShutdownFile_chat_2eproto(); + + void InitAsDefaultInstance(); + static RequestChatLobbies* default_instance_; +}; +// ------------------------------------------------------------------- + +class RequestCreateLobby : public ::google::protobuf::Message { + public: + RequestCreateLobby(); + virtual ~RequestCreateLobby(); + + RequestCreateLobby(const RequestCreateLobby& from); + + inline RequestCreateLobby& operator=(const RequestCreateLobby& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestCreateLobby& default_instance(); + + void Swap(RequestCreateLobby* other); + + // implements Message ---------------------------------------------- + + RequestCreateLobby* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestCreateLobby& from); + void MergeFrom(const RequestCreateLobby& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string lobby_name = 1; + inline bool has_lobby_name() const; + inline void clear_lobby_name(); + static const int kLobbyNameFieldNumber = 1; + inline const ::std::string& lobby_name() const; + inline void set_lobby_name(const ::std::string& value); + inline void set_lobby_name(const char* value); + inline void set_lobby_name(const char* value, size_t size); + inline ::std::string* mutable_lobby_name(); + inline ::std::string* release_lobby_name(); + + // required string lobby_topic = 2; + inline bool has_lobby_topic() const; + inline void clear_lobby_topic(); + static const int kLobbyTopicFieldNumber = 2; + inline const ::std::string& lobby_topic() const; + inline void set_lobby_topic(const ::std::string& value); + inline void set_lobby_topic(const char* value); + inline void set_lobby_topic(const char* value, size_t size); + inline ::std::string* mutable_lobby_topic(); + inline ::std::string* release_lobby_topic(); + + // required .rsctrl.chat.LobbyPrivacyLevel privacy_level = 4; + inline bool has_privacy_level() const; + inline void clear_privacy_level(); + static const int kPrivacyLevelFieldNumber = 4; + inline rsctrl::chat::LobbyPrivacyLevel privacy_level() const; + inline void set_privacy_level(rsctrl::chat::LobbyPrivacyLevel value); + + // repeated string invited_friends = 3; + inline int invited_friends_size() const; + inline void clear_invited_friends(); + static const int kInvitedFriendsFieldNumber = 3; + inline const ::std::string& invited_friends(int index) const; + inline ::std::string* mutable_invited_friends(int index); + inline void set_invited_friends(int index, const ::std::string& value); + inline void set_invited_friends(int index, const char* value); + inline void set_invited_friends(int index, const char* value, size_t size); + inline ::std::string* add_invited_friends(); + inline void add_invited_friends(const ::std::string& value); + inline void add_invited_friends(const char* value); + inline void add_invited_friends(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& invited_friends() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_invited_friends(); + + // @@protoc_insertion_point(class_scope:rsctrl.chat.RequestCreateLobby) + private: + inline void set_has_lobby_name(); + inline void clear_has_lobby_name(); + inline void set_has_lobby_topic(); + inline void clear_has_lobby_topic(); + inline void set_has_privacy_level(); + inline void clear_has_privacy_level(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* lobby_name_; + ::std::string* lobby_topic_; + ::google::protobuf::RepeatedPtrField< ::std::string> invited_friends_; + int privacy_level_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_chat_2eproto(); + friend void protobuf_AssignDesc_chat_2eproto(); + friend void protobuf_ShutdownFile_chat_2eproto(); + + void InitAsDefaultInstance(); + static RequestCreateLobby* default_instance_; +}; +// ------------------------------------------------------------------- + +class RequestJoinOrLeaveLobby : public ::google::protobuf::Message { + public: + RequestJoinOrLeaveLobby(); + virtual ~RequestJoinOrLeaveLobby(); + + RequestJoinOrLeaveLobby(const RequestJoinOrLeaveLobby& from); + + inline RequestJoinOrLeaveLobby& operator=(const RequestJoinOrLeaveLobby& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestJoinOrLeaveLobby& default_instance(); + + void Swap(RequestJoinOrLeaveLobby* other); + + // implements Message ---------------------------------------------- + + RequestJoinOrLeaveLobby* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestJoinOrLeaveLobby& from); + void MergeFrom(const RequestJoinOrLeaveLobby& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef RequestJoinOrLeaveLobby_LobbyAction LobbyAction; + static const LobbyAction JOIN_OR_ACCEPT = RequestJoinOrLeaveLobby_LobbyAction_JOIN_OR_ACCEPT; + static const LobbyAction LEAVE_OR_DENY = RequestJoinOrLeaveLobby_LobbyAction_LEAVE_OR_DENY; + static inline bool LobbyAction_IsValid(int value) { + return RequestJoinOrLeaveLobby_LobbyAction_IsValid(value); + } + static const LobbyAction LobbyAction_MIN = + RequestJoinOrLeaveLobby_LobbyAction_LobbyAction_MIN; + static const LobbyAction LobbyAction_MAX = + RequestJoinOrLeaveLobby_LobbyAction_LobbyAction_MAX; + static const int LobbyAction_ARRAYSIZE = + RequestJoinOrLeaveLobby_LobbyAction_LobbyAction_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + LobbyAction_descriptor() { + return RequestJoinOrLeaveLobby_LobbyAction_descriptor(); + } + static inline const ::std::string& LobbyAction_Name(LobbyAction value) { + return RequestJoinOrLeaveLobby_LobbyAction_Name(value); + } + static inline bool LobbyAction_Parse(const ::std::string& name, + LobbyAction* value) { + return RequestJoinOrLeaveLobby_LobbyAction_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // required string lobby_id = 1; + inline bool has_lobby_id() const; + inline void clear_lobby_id(); + static const int kLobbyIdFieldNumber = 1; + inline const ::std::string& lobby_id() const; + inline void set_lobby_id(const ::std::string& value); + inline void set_lobby_id(const char* value); + inline void set_lobby_id(const char* value, size_t size); + inline ::std::string* mutable_lobby_id(); + inline ::std::string* release_lobby_id(); + + // required .rsctrl.chat.RequestJoinOrLeaveLobby.LobbyAction action = 2; + inline bool has_action() const; + inline void clear_action(); + static const int kActionFieldNumber = 2; + inline ::rsctrl::chat::RequestJoinOrLeaveLobby_LobbyAction action() const; + inline void set_action(::rsctrl::chat::RequestJoinOrLeaveLobby_LobbyAction value); + + // @@protoc_insertion_point(class_scope:rsctrl.chat.RequestJoinOrLeaveLobby) + private: + inline void set_has_lobby_id(); + inline void clear_has_lobby_id(); + inline void set_has_action(); + inline void clear_has_action(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* lobby_id_; + int action_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_chat_2eproto(); + friend void protobuf_AssignDesc_chat_2eproto(); + friend void protobuf_ShutdownFile_chat_2eproto(); + + void InitAsDefaultInstance(); + static RequestJoinOrLeaveLobby* default_instance_; +}; +// ------------------------------------------------------------------- + +class RequestSetLobbyNickname : public ::google::protobuf::Message { + public: + RequestSetLobbyNickname(); + virtual ~RequestSetLobbyNickname(); + + RequestSetLobbyNickname(const RequestSetLobbyNickname& from); + + inline RequestSetLobbyNickname& operator=(const RequestSetLobbyNickname& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestSetLobbyNickname& default_instance(); + + void Swap(RequestSetLobbyNickname* other); + + // implements Message ---------------------------------------------- + + RequestSetLobbyNickname* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestSetLobbyNickname& from); + void MergeFrom(const RequestSetLobbyNickname& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required string nickname = 1; + inline bool has_nickname() const; + inline void clear_nickname(); + static const int kNicknameFieldNumber = 1; + inline const ::std::string& nickname() const; + inline void set_nickname(const ::std::string& value); + inline void set_nickname(const char* value); + inline void set_nickname(const char* value, size_t size); + inline ::std::string* mutable_nickname(); + inline ::std::string* release_nickname(); + + // repeated string lobby_ids = 2; + inline int lobby_ids_size() const; + inline void clear_lobby_ids(); + static const int kLobbyIdsFieldNumber = 2; + inline const ::std::string& lobby_ids(int index) const; + inline ::std::string* mutable_lobby_ids(int index); + inline void set_lobby_ids(int index, const ::std::string& value); + inline void set_lobby_ids(int index, const char* value); + inline void set_lobby_ids(int index, const char* value, size_t size); + inline ::std::string* add_lobby_ids(); + inline void add_lobby_ids(const ::std::string& value); + inline void add_lobby_ids(const char* value); + inline void add_lobby_ids(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& lobby_ids() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_lobby_ids(); + + // @@protoc_insertion_point(class_scope:rsctrl.chat.RequestSetLobbyNickname) + private: + inline void set_has_nickname(); + inline void clear_has_nickname(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::std::string* nickname_; + ::google::protobuf::RepeatedPtrField< ::std::string> lobby_ids_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_chat_2eproto(); + friend void protobuf_AssignDesc_chat_2eproto(); + friend void protobuf_ShutdownFile_chat_2eproto(); + + void InitAsDefaultInstance(); + static RequestSetLobbyNickname* default_instance_; +}; +// ------------------------------------------------------------------- + +class ResponseSetLobbyNickname : public ::google::protobuf::Message { + public: + ResponseSetLobbyNickname(); + virtual ~ResponseSetLobbyNickname(); + + ResponseSetLobbyNickname(const ResponseSetLobbyNickname& from); + + inline ResponseSetLobbyNickname& operator=(const ResponseSetLobbyNickname& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ResponseSetLobbyNickname& default_instance(); + + void Swap(ResponseSetLobbyNickname* other); + + // implements Message ---------------------------------------------- + + ResponseSetLobbyNickname* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ResponseSetLobbyNickname& from); + void MergeFrom(const ResponseSetLobbyNickname& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .rsctrl.core.Status status = 1; + inline bool has_status() const; + inline void clear_status(); + static const int kStatusFieldNumber = 1; + inline const ::rsctrl::core::Status& status() const; + inline ::rsctrl::core::Status* mutable_status(); + inline ::rsctrl::core::Status* release_status(); + + // @@protoc_insertion_point(class_scope:rsctrl.chat.ResponseSetLobbyNickname) + private: + inline void set_has_status(); + inline void clear_has_status(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::rsctrl::core::Status* status_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_chat_2eproto(); + friend void protobuf_AssignDesc_chat_2eproto(); + friend void protobuf_ShutdownFile_chat_2eproto(); + + void InitAsDefaultInstance(); + static ResponseSetLobbyNickname* default_instance_; +}; +// ------------------------------------------------------------------- + +class RequestRegisterEvents : public ::google::protobuf::Message { + public: + RequestRegisterEvents(); + virtual ~RequestRegisterEvents(); + + RequestRegisterEvents(const RequestRegisterEvents& from); + + inline RequestRegisterEvents& operator=(const RequestRegisterEvents& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestRegisterEvents& default_instance(); + + void Swap(RequestRegisterEvents* other); + + // implements Message ---------------------------------------------- + + RequestRegisterEvents* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestRegisterEvents& from); + void MergeFrom(const RequestRegisterEvents& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef RequestRegisterEvents_RegisterAction RegisterAction; + static const RegisterAction REGISTER = RequestRegisterEvents_RegisterAction_REGISTER; + static const RegisterAction DEREGISTER = RequestRegisterEvents_RegisterAction_DEREGISTER; + static inline bool RegisterAction_IsValid(int value) { + return RequestRegisterEvents_RegisterAction_IsValid(value); + } + static const RegisterAction RegisterAction_MIN = + RequestRegisterEvents_RegisterAction_RegisterAction_MIN; + static const RegisterAction RegisterAction_MAX = + RequestRegisterEvents_RegisterAction_RegisterAction_MAX; + static const int RegisterAction_ARRAYSIZE = + RequestRegisterEvents_RegisterAction_RegisterAction_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + RegisterAction_descriptor() { + return RequestRegisterEvents_RegisterAction_descriptor(); + } + static inline const ::std::string& RegisterAction_Name(RegisterAction value) { + return RequestRegisterEvents_RegisterAction_Name(value); + } + static inline bool RegisterAction_Parse(const ::std::string& name, + RegisterAction* value) { + return RequestRegisterEvents_RegisterAction_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // required .rsctrl.chat.RequestRegisterEvents.RegisterAction action = 1; + inline bool has_action() const; + inline void clear_action(); + static const int kActionFieldNumber = 1; + inline ::rsctrl::chat::RequestRegisterEvents_RegisterAction action() const; + inline void set_action(::rsctrl::chat::RequestRegisterEvents_RegisterAction value); + + // @@protoc_insertion_point(class_scope:rsctrl.chat.RequestRegisterEvents) + private: + inline void set_has_action(); + inline void clear_has_action(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + int action_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_chat_2eproto(); + friend void protobuf_AssignDesc_chat_2eproto(); + friend void protobuf_ShutdownFile_chat_2eproto(); + + void InitAsDefaultInstance(); + static RequestRegisterEvents* default_instance_; +}; +// ------------------------------------------------------------------- + +class ResponseRegisterEvents : public ::google::protobuf::Message { + public: + ResponseRegisterEvents(); + virtual ~ResponseRegisterEvents(); + + ResponseRegisterEvents(const ResponseRegisterEvents& from); + + inline ResponseRegisterEvents& operator=(const ResponseRegisterEvents& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ResponseRegisterEvents& default_instance(); + + void Swap(ResponseRegisterEvents* other); + + // implements Message ---------------------------------------------- + + ResponseRegisterEvents* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ResponseRegisterEvents& from); + void MergeFrom(const ResponseRegisterEvents& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .rsctrl.core.Status status = 1; + inline bool has_status() const; + inline void clear_status(); + static const int kStatusFieldNumber = 1; + inline const ::rsctrl::core::Status& status() const; + inline ::rsctrl::core::Status* mutable_status(); + inline ::rsctrl::core::Status* release_status(); + + // @@protoc_insertion_point(class_scope:rsctrl.chat.ResponseRegisterEvents) + private: + inline void set_has_status(); + inline void clear_has_status(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::rsctrl::core::Status* status_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_chat_2eproto(); + friend void protobuf_AssignDesc_chat_2eproto(); + friend void protobuf_ShutdownFile_chat_2eproto(); + + void InitAsDefaultInstance(); + static ResponseRegisterEvents* default_instance_; +}; +// ------------------------------------------------------------------- + +class EventLobbyInvite : public ::google::protobuf::Message { + public: + EventLobbyInvite(); + virtual ~EventLobbyInvite(); + + EventLobbyInvite(const EventLobbyInvite& from); + + inline EventLobbyInvite& operator=(const EventLobbyInvite& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const EventLobbyInvite& default_instance(); + + void Swap(EventLobbyInvite* other); + + // implements Message ---------------------------------------------- + + EventLobbyInvite* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const EventLobbyInvite& from); + void MergeFrom(const EventLobbyInvite& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .rsctrl.chat.ChatLobbyInfo lobby = 1; + inline bool has_lobby() const; + inline void clear_lobby(); + static const int kLobbyFieldNumber = 1; + inline const ::rsctrl::chat::ChatLobbyInfo& lobby() const; + inline ::rsctrl::chat::ChatLobbyInfo* mutable_lobby(); + inline ::rsctrl::chat::ChatLobbyInfo* release_lobby(); + + // @@protoc_insertion_point(class_scope:rsctrl.chat.EventLobbyInvite) + private: + inline void set_has_lobby(); + inline void clear_has_lobby(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::rsctrl::chat::ChatLobbyInfo* lobby_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_chat_2eproto(); + friend void protobuf_AssignDesc_chat_2eproto(); + friend void protobuf_ShutdownFile_chat_2eproto(); + + void InitAsDefaultInstance(); + static EventLobbyInvite* default_instance_; +}; +// ------------------------------------------------------------------- + +class EventChatMessage : public ::google::protobuf::Message { + public: + EventChatMessage(); + virtual ~EventChatMessage(); + + EventChatMessage(const EventChatMessage& from); + + inline EventChatMessage& operator=(const EventChatMessage& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const EventChatMessage& default_instance(); + + void Swap(EventChatMessage* other); + + // implements Message ---------------------------------------------- + + EventChatMessage* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const EventChatMessage& from); + void MergeFrom(const EventChatMessage& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .rsctrl.chat.ChatMessage msg = 1; + inline bool has_msg() const; + inline void clear_msg(); + static const int kMsgFieldNumber = 1; + inline const ::rsctrl::chat::ChatMessage& msg() const; + inline ::rsctrl::chat::ChatMessage* mutable_msg(); + inline ::rsctrl::chat::ChatMessage* release_msg(); + + // @@protoc_insertion_point(class_scope:rsctrl.chat.EventChatMessage) + private: + inline void set_has_msg(); + inline void clear_has_msg(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::rsctrl::chat::ChatMessage* msg_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_chat_2eproto(); + friend void protobuf_AssignDesc_chat_2eproto(); + friend void protobuf_ShutdownFile_chat_2eproto(); + + void InitAsDefaultInstance(); + static EventChatMessage* default_instance_; +}; +// ------------------------------------------------------------------- + +class RequestSendMessage : public ::google::protobuf::Message { + public: + RequestSendMessage(); + virtual ~RequestSendMessage(); + + RequestSendMessage(const RequestSendMessage& from); + + inline RequestSendMessage& operator=(const RequestSendMessage& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestSendMessage& default_instance(); + + void Swap(RequestSendMessage* other); + + // implements Message ---------------------------------------------- + + RequestSendMessage* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestSendMessage& from); + void MergeFrom(const RequestSendMessage& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .rsctrl.chat.ChatMessage msg = 1; + inline bool has_msg() const; + inline void clear_msg(); + static const int kMsgFieldNumber = 1; + inline const ::rsctrl::chat::ChatMessage& msg() const; + inline ::rsctrl::chat::ChatMessage* mutable_msg(); + inline ::rsctrl::chat::ChatMessage* release_msg(); + + // @@protoc_insertion_point(class_scope:rsctrl.chat.RequestSendMessage) + private: + inline void set_has_msg(); + inline void clear_has_msg(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::rsctrl::chat::ChatMessage* msg_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_chat_2eproto(); + friend void protobuf_AssignDesc_chat_2eproto(); + friend void protobuf_ShutdownFile_chat_2eproto(); + + void InitAsDefaultInstance(); + static RequestSendMessage* default_instance_; +}; +// ------------------------------------------------------------------- + +class ResponseSendMessage : public ::google::protobuf::Message { + public: + ResponseSendMessage(); + virtual ~ResponseSendMessage(); + + ResponseSendMessage(const ResponseSendMessage& from); + + inline ResponseSendMessage& operator=(const ResponseSendMessage& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ResponseSendMessage& default_instance(); + + void Swap(ResponseSendMessage* other); + + // implements Message ---------------------------------------------- + + ResponseSendMessage* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ResponseSendMessage& from); + void MergeFrom(const ResponseSendMessage& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .rsctrl.core.Status status = 1; + inline bool has_status() const; + inline void clear_status(); + static const int kStatusFieldNumber = 1; + inline const ::rsctrl::core::Status& status() const; + inline ::rsctrl::core::Status* mutable_status(); + inline ::rsctrl::core::Status* release_status(); + + // @@protoc_insertion_point(class_scope:rsctrl.chat.ResponseSendMessage) + private: + inline void set_has_status(); + inline void clear_has_status(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::rsctrl::core::Status* status_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_chat_2eproto(); + friend void protobuf_AssignDesc_chat_2eproto(); + friend void protobuf_ShutdownFile_chat_2eproto(); + + void InitAsDefaultInstance(); + static ResponseSendMessage* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// ChatLobbyInfo + +// required string lobby_id = 1; +inline bool ChatLobbyInfo::has_lobby_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ChatLobbyInfo::set_has_lobby_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void ChatLobbyInfo::clear_has_lobby_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ChatLobbyInfo::clear_lobby_id() { + if (lobby_id_ != &::google::protobuf::internal::kEmptyString) { + lobby_id_->clear(); + } + clear_has_lobby_id(); +} +inline const ::std::string& ChatLobbyInfo::lobby_id() const { + return *lobby_id_; +} +inline void ChatLobbyInfo::set_lobby_id(const ::std::string& value) { + set_has_lobby_id(); + if (lobby_id_ == &::google::protobuf::internal::kEmptyString) { + lobby_id_ = new ::std::string; + } + lobby_id_->assign(value); +} +inline void ChatLobbyInfo::set_lobby_id(const char* value) { + set_has_lobby_id(); + if (lobby_id_ == &::google::protobuf::internal::kEmptyString) { + lobby_id_ = new ::std::string; + } + lobby_id_->assign(value); +} +inline void ChatLobbyInfo::set_lobby_id(const char* value, size_t size) { + set_has_lobby_id(); + if (lobby_id_ == &::google::protobuf::internal::kEmptyString) { + lobby_id_ = new ::std::string; + } + lobby_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* ChatLobbyInfo::mutable_lobby_id() { + set_has_lobby_id(); + if (lobby_id_ == &::google::protobuf::internal::kEmptyString) { + lobby_id_ = new ::std::string; + } + return lobby_id_; +} +inline ::std::string* ChatLobbyInfo::release_lobby_id() { + clear_has_lobby_id(); + if (lobby_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = lobby_id_; + lobby_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// required string lobby_topic = 2; +inline bool ChatLobbyInfo::has_lobby_topic() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void ChatLobbyInfo::set_has_lobby_topic() { + _has_bits_[0] |= 0x00000002u; +} +inline void ChatLobbyInfo::clear_has_lobby_topic() { + _has_bits_[0] &= ~0x00000002u; +} +inline void ChatLobbyInfo::clear_lobby_topic() { + if (lobby_topic_ != &::google::protobuf::internal::kEmptyString) { + lobby_topic_->clear(); + } + clear_has_lobby_topic(); +} +inline const ::std::string& ChatLobbyInfo::lobby_topic() const { + return *lobby_topic_; +} +inline void ChatLobbyInfo::set_lobby_topic(const ::std::string& value) { + set_has_lobby_topic(); + if (lobby_topic_ == &::google::protobuf::internal::kEmptyString) { + lobby_topic_ = new ::std::string; + } + lobby_topic_->assign(value); +} +inline void ChatLobbyInfo::set_lobby_topic(const char* value) { + set_has_lobby_topic(); + if (lobby_topic_ == &::google::protobuf::internal::kEmptyString) { + lobby_topic_ = new ::std::string; + } + lobby_topic_->assign(value); +} +inline void ChatLobbyInfo::set_lobby_topic(const char* value, size_t size) { + set_has_lobby_topic(); + if (lobby_topic_ == &::google::protobuf::internal::kEmptyString) { + lobby_topic_ = new ::std::string; + } + lobby_topic_->assign(reinterpret_cast(value), size); +} +inline ::std::string* ChatLobbyInfo::mutable_lobby_topic() { + set_has_lobby_topic(); + if (lobby_topic_ == &::google::protobuf::internal::kEmptyString) { + lobby_topic_ = new ::std::string; + } + return lobby_topic_; +} +inline ::std::string* ChatLobbyInfo::release_lobby_topic() { + clear_has_lobby_topic(); + if (lobby_topic_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = lobby_topic_; + lobby_topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// required string lobby_name = 3; +inline bool ChatLobbyInfo::has_lobby_name() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void ChatLobbyInfo::set_has_lobby_name() { + _has_bits_[0] |= 0x00000004u; +} +inline void ChatLobbyInfo::clear_has_lobby_name() { + _has_bits_[0] &= ~0x00000004u; +} +inline void ChatLobbyInfo::clear_lobby_name() { + if (lobby_name_ != &::google::protobuf::internal::kEmptyString) { + lobby_name_->clear(); + } + clear_has_lobby_name(); +} +inline const ::std::string& ChatLobbyInfo::lobby_name() const { + return *lobby_name_; +} +inline void ChatLobbyInfo::set_lobby_name(const ::std::string& value) { + set_has_lobby_name(); + if (lobby_name_ == &::google::protobuf::internal::kEmptyString) { + lobby_name_ = new ::std::string; + } + lobby_name_->assign(value); +} +inline void ChatLobbyInfo::set_lobby_name(const char* value) { + set_has_lobby_name(); + if (lobby_name_ == &::google::protobuf::internal::kEmptyString) { + lobby_name_ = new ::std::string; + } + lobby_name_->assign(value); +} +inline void ChatLobbyInfo::set_lobby_name(const char* value, size_t size) { + set_has_lobby_name(); + if (lobby_name_ == &::google::protobuf::internal::kEmptyString) { + lobby_name_ = new ::std::string; + } + lobby_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* ChatLobbyInfo::mutable_lobby_name() { + set_has_lobby_name(); + if (lobby_name_ == &::google::protobuf::internal::kEmptyString) { + lobby_name_ = new ::std::string; + } + return lobby_name_; +} +inline ::std::string* ChatLobbyInfo::release_lobby_name() { + clear_has_lobby_name(); + if (lobby_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = lobby_name_; + lobby_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// required string lobby_nickname = 4; +inline bool ChatLobbyInfo::has_lobby_nickname() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void ChatLobbyInfo::set_has_lobby_nickname() { + _has_bits_[0] |= 0x00000008u; +} +inline void ChatLobbyInfo::clear_has_lobby_nickname() { + _has_bits_[0] &= ~0x00000008u; +} +inline void ChatLobbyInfo::clear_lobby_nickname() { + if (lobby_nickname_ != &::google::protobuf::internal::kEmptyString) { + lobby_nickname_->clear(); + } + clear_has_lobby_nickname(); +} +inline const ::std::string& ChatLobbyInfo::lobby_nickname() const { + return *lobby_nickname_; +} +inline void ChatLobbyInfo::set_lobby_nickname(const ::std::string& value) { + set_has_lobby_nickname(); + if (lobby_nickname_ == &::google::protobuf::internal::kEmptyString) { + lobby_nickname_ = new ::std::string; + } + lobby_nickname_->assign(value); +} +inline void ChatLobbyInfo::set_lobby_nickname(const char* value) { + set_has_lobby_nickname(); + if (lobby_nickname_ == &::google::protobuf::internal::kEmptyString) { + lobby_nickname_ = new ::std::string; + } + lobby_nickname_->assign(value); +} +inline void ChatLobbyInfo::set_lobby_nickname(const char* value, size_t size) { + set_has_lobby_nickname(); + if (lobby_nickname_ == &::google::protobuf::internal::kEmptyString) { + lobby_nickname_ = new ::std::string; + } + lobby_nickname_->assign(reinterpret_cast(value), size); +} +inline ::std::string* ChatLobbyInfo::mutable_lobby_nickname() { + set_has_lobby_nickname(); + if (lobby_nickname_ == &::google::protobuf::internal::kEmptyString) { + lobby_nickname_ = new ::std::string; + } + return lobby_nickname_; +} +inline ::std::string* ChatLobbyInfo::release_lobby_nickname() { + clear_has_lobby_nickname(); + if (lobby_nickname_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = lobby_nickname_; + lobby_nickname_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// required .rsctrl.chat.LobbyPrivacyLevel privacy_level = 5; +inline bool ChatLobbyInfo::has_privacy_level() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void ChatLobbyInfo::set_has_privacy_level() { + _has_bits_[0] |= 0x00000010u; +} +inline void ChatLobbyInfo::clear_has_privacy_level() { + _has_bits_[0] &= ~0x00000010u; +} +inline void ChatLobbyInfo::clear_privacy_level() { + privacy_level_ = 1; + clear_has_privacy_level(); +} +inline rsctrl::chat::LobbyPrivacyLevel ChatLobbyInfo::privacy_level() const { + return static_cast< rsctrl::chat::LobbyPrivacyLevel >(privacy_level_); +} +inline void ChatLobbyInfo::set_privacy_level(rsctrl::chat::LobbyPrivacyLevel value) { + GOOGLE_DCHECK(rsctrl::chat::LobbyPrivacyLevel_IsValid(value)); + set_has_privacy_level(); + privacy_level_ = value; +} + +// required .rsctrl.chat.ChatLobbyInfo.LobbyState lobby_state = 6; +inline bool ChatLobbyInfo::has_lobby_state() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void ChatLobbyInfo::set_has_lobby_state() { + _has_bits_[0] |= 0x00000020u; +} +inline void ChatLobbyInfo::clear_has_lobby_state() { + _has_bits_[0] &= ~0x00000020u; +} +inline void ChatLobbyInfo::clear_lobby_state() { + lobby_state_ = 1; + clear_has_lobby_state(); +} +inline ::rsctrl::chat::ChatLobbyInfo_LobbyState ChatLobbyInfo::lobby_state() const { + return static_cast< ::rsctrl::chat::ChatLobbyInfo_LobbyState >(lobby_state_); +} +inline void ChatLobbyInfo::set_lobby_state(::rsctrl::chat::ChatLobbyInfo_LobbyState value) { + GOOGLE_DCHECK(::rsctrl::chat::ChatLobbyInfo_LobbyState_IsValid(value)); + set_has_lobby_state(); + lobby_state_ = value; +} + +// required uint32 no_peers = 7; +inline bool ChatLobbyInfo::has_no_peers() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void ChatLobbyInfo::set_has_no_peers() { + _has_bits_[0] |= 0x00000040u; +} +inline void ChatLobbyInfo::clear_has_no_peers() { + _has_bits_[0] &= ~0x00000040u; +} +inline void ChatLobbyInfo::clear_no_peers() { + no_peers_ = 0u; + clear_has_no_peers(); +} +inline ::google::protobuf::uint32 ChatLobbyInfo::no_peers() const { + return no_peers_; +} +inline void ChatLobbyInfo::set_no_peers(::google::protobuf::uint32 value) { + set_has_no_peers(); + no_peers_ = value; +} + +// required uint32 last_report_time = 8; +inline bool ChatLobbyInfo::has_last_report_time() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void ChatLobbyInfo::set_has_last_report_time() { + _has_bits_[0] |= 0x00000080u; +} +inline void ChatLobbyInfo::clear_has_last_report_time() { + _has_bits_[0] &= ~0x00000080u; +} +inline void ChatLobbyInfo::clear_last_report_time() { + last_report_time_ = 0u; + clear_has_last_report_time(); +} +inline ::google::protobuf::uint32 ChatLobbyInfo::last_report_time() const { + return last_report_time_; +} +inline void ChatLobbyInfo::set_last_report_time(::google::protobuf::uint32 value) { + set_has_last_report_time(); + last_report_time_ = value; +} + +// required uint32 last_activity = 9; +inline bool ChatLobbyInfo::has_last_activity() const { + return (_has_bits_[0] & 0x00000100u) != 0; +} +inline void ChatLobbyInfo::set_has_last_activity() { + _has_bits_[0] |= 0x00000100u; +} +inline void ChatLobbyInfo::clear_has_last_activity() { + _has_bits_[0] &= ~0x00000100u; +} +inline void ChatLobbyInfo::clear_last_activity() { + last_activity_ = 0u; + clear_has_last_activity(); +} +inline ::google::protobuf::uint32 ChatLobbyInfo::last_activity() const { + return last_activity_; +} +inline void ChatLobbyInfo::set_last_activity(::google::protobuf::uint32 value) { + set_has_last_activity(); + last_activity_ = value; +} + +// repeated string participating_friends = 10; +inline int ChatLobbyInfo::participating_friends_size() const { + return participating_friends_.size(); +} +inline void ChatLobbyInfo::clear_participating_friends() { + participating_friends_.Clear(); +} +inline const ::std::string& ChatLobbyInfo::participating_friends(int index) const { + return participating_friends_.Get(index); +} +inline ::std::string* ChatLobbyInfo::mutable_participating_friends(int index) { + return participating_friends_.Mutable(index); +} +inline void ChatLobbyInfo::set_participating_friends(int index, const ::std::string& value) { + participating_friends_.Mutable(index)->assign(value); +} +inline void ChatLobbyInfo::set_participating_friends(int index, const char* value) { + participating_friends_.Mutable(index)->assign(value); +} +inline void ChatLobbyInfo::set_participating_friends(int index, const char* value, size_t size) { + participating_friends_.Mutable(index)->assign( + reinterpret_cast(value), size); +} +inline ::std::string* ChatLobbyInfo::add_participating_friends() { + return participating_friends_.Add(); +} +inline void ChatLobbyInfo::add_participating_friends(const ::std::string& value) { + participating_friends_.Add()->assign(value); +} +inline void ChatLobbyInfo::add_participating_friends(const char* value) { + participating_friends_.Add()->assign(value); +} +inline void ChatLobbyInfo::add_participating_friends(const char* value, size_t size) { + participating_friends_.Add()->assign(reinterpret_cast(value), size); +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +ChatLobbyInfo::participating_friends() const { + return participating_friends_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +ChatLobbyInfo::mutable_participating_friends() { + return &participating_friends_; +} + +// repeated string nicknames = 11; +inline int ChatLobbyInfo::nicknames_size() const { + return nicknames_.size(); +} +inline void ChatLobbyInfo::clear_nicknames() { + nicknames_.Clear(); +} +inline const ::std::string& ChatLobbyInfo::nicknames(int index) const { + return nicknames_.Get(index); +} +inline ::std::string* ChatLobbyInfo::mutable_nicknames(int index) { + return nicknames_.Mutable(index); +} +inline void ChatLobbyInfo::set_nicknames(int index, const ::std::string& value) { + nicknames_.Mutable(index)->assign(value); +} +inline void ChatLobbyInfo::set_nicknames(int index, const char* value) { + nicknames_.Mutable(index)->assign(value); +} +inline void ChatLobbyInfo::set_nicknames(int index, const char* value, size_t size) { + nicknames_.Mutable(index)->assign( + reinterpret_cast(value), size); +} +inline ::std::string* ChatLobbyInfo::add_nicknames() { + return nicknames_.Add(); +} +inline void ChatLobbyInfo::add_nicknames(const ::std::string& value) { + nicknames_.Add()->assign(value); +} +inline void ChatLobbyInfo::add_nicknames(const char* value) { + nicknames_.Add()->assign(value); +} +inline void ChatLobbyInfo::add_nicknames(const char* value, size_t size) { + nicknames_.Add()->assign(reinterpret_cast(value), size); +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +ChatLobbyInfo::nicknames() const { + return nicknames_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +ChatLobbyInfo::mutable_nicknames() { + return &nicknames_; +} + +// ------------------------------------------------------------------- + +// ChatId + +// required .rsctrl.chat.ChatType chat_type = 1; +inline bool ChatId::has_chat_type() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ChatId::set_has_chat_type() { + _has_bits_[0] |= 0x00000001u; +} +inline void ChatId::clear_has_chat_type() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ChatId::clear_chat_type() { + chat_type_ = 1; + clear_has_chat_type(); +} +inline rsctrl::chat::ChatType ChatId::chat_type() const { + return static_cast< rsctrl::chat::ChatType >(chat_type_); +} +inline void ChatId::set_chat_type(rsctrl::chat::ChatType value) { + GOOGLE_DCHECK(rsctrl::chat::ChatType_IsValid(value)); + set_has_chat_type(); + chat_type_ = value; +} + +// required string chat_id = 2; +inline bool ChatId::has_chat_id() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void ChatId::set_has_chat_id() { + _has_bits_[0] |= 0x00000002u; +} +inline void ChatId::clear_has_chat_id() { + _has_bits_[0] &= ~0x00000002u; +} +inline void ChatId::clear_chat_id() { + if (chat_id_ != &::google::protobuf::internal::kEmptyString) { + chat_id_->clear(); + } + clear_has_chat_id(); +} +inline const ::std::string& ChatId::chat_id() const { + return *chat_id_; +} +inline void ChatId::set_chat_id(const ::std::string& value) { + set_has_chat_id(); + if (chat_id_ == &::google::protobuf::internal::kEmptyString) { + chat_id_ = new ::std::string; + } + chat_id_->assign(value); +} +inline void ChatId::set_chat_id(const char* value) { + set_has_chat_id(); + if (chat_id_ == &::google::protobuf::internal::kEmptyString) { + chat_id_ = new ::std::string; + } + chat_id_->assign(value); +} +inline void ChatId::set_chat_id(const char* value, size_t size) { + set_has_chat_id(); + if (chat_id_ == &::google::protobuf::internal::kEmptyString) { + chat_id_ = new ::std::string; + } + chat_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* ChatId::mutable_chat_id() { + set_has_chat_id(); + if (chat_id_ == &::google::protobuf::internal::kEmptyString) { + chat_id_ = new ::std::string; + } + return chat_id_; +} +inline ::std::string* ChatId::release_chat_id() { + clear_has_chat_id(); + if (chat_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = chat_id_; + chat_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// ------------------------------------------------------------------- + +// ChatMessage + +// required .rsctrl.chat.ChatId id = 1; +inline bool ChatMessage::has_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ChatMessage::set_has_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void ChatMessage::clear_has_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ChatMessage::clear_id() { + if (id_ != NULL) id_->::rsctrl::chat::ChatId::Clear(); + clear_has_id(); +} +inline const ::rsctrl::chat::ChatId& ChatMessage::id() const { + return id_ != NULL ? *id_ : *default_instance_->id_; +} +inline ::rsctrl::chat::ChatId* ChatMessage::mutable_id() { + set_has_id(); + if (id_ == NULL) id_ = new ::rsctrl::chat::ChatId; + return id_; +} +inline ::rsctrl::chat::ChatId* ChatMessage::release_id() { + clear_has_id(); + ::rsctrl::chat::ChatId* temp = id_; + id_ = NULL; + return temp; +} + +// required string msg = 2; +inline bool ChatMessage::has_msg() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void ChatMessage::set_has_msg() { + _has_bits_[0] |= 0x00000002u; +} +inline void ChatMessage::clear_has_msg() { + _has_bits_[0] &= ~0x00000002u; +} +inline void ChatMessage::clear_msg() { + if (msg_ != &::google::protobuf::internal::kEmptyString) { + msg_->clear(); + } + clear_has_msg(); +} +inline const ::std::string& ChatMessage::msg() const { + return *msg_; +} +inline void ChatMessage::set_msg(const ::std::string& value) { + set_has_msg(); + if (msg_ == &::google::protobuf::internal::kEmptyString) { + msg_ = new ::std::string; + } + msg_->assign(value); +} +inline void ChatMessage::set_msg(const char* value) { + set_has_msg(); + if (msg_ == &::google::protobuf::internal::kEmptyString) { + msg_ = new ::std::string; + } + msg_->assign(value); +} +inline void ChatMessage::set_msg(const char* value, size_t size) { + set_has_msg(); + if (msg_ == &::google::protobuf::internal::kEmptyString) { + msg_ = new ::std::string; + } + msg_->assign(reinterpret_cast(value), size); +} +inline ::std::string* ChatMessage::mutable_msg() { + set_has_msg(); + if (msg_ == &::google::protobuf::internal::kEmptyString) { + msg_ = new ::std::string; + } + return msg_; +} +inline ::std::string* ChatMessage::release_msg() { + clear_has_msg(); + if (msg_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = msg_; + msg_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// optional string peer_nickname = 3; +inline bool ChatMessage::has_peer_nickname() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void ChatMessage::set_has_peer_nickname() { + _has_bits_[0] |= 0x00000004u; +} +inline void ChatMessage::clear_has_peer_nickname() { + _has_bits_[0] &= ~0x00000004u; +} +inline void ChatMessage::clear_peer_nickname() { + if (peer_nickname_ != &::google::protobuf::internal::kEmptyString) { + peer_nickname_->clear(); + } + clear_has_peer_nickname(); +} +inline const ::std::string& ChatMessage::peer_nickname() const { + return *peer_nickname_; +} +inline void ChatMessage::set_peer_nickname(const ::std::string& value) { + set_has_peer_nickname(); + if (peer_nickname_ == &::google::protobuf::internal::kEmptyString) { + peer_nickname_ = new ::std::string; + } + peer_nickname_->assign(value); +} +inline void ChatMessage::set_peer_nickname(const char* value) { + set_has_peer_nickname(); + if (peer_nickname_ == &::google::protobuf::internal::kEmptyString) { + peer_nickname_ = new ::std::string; + } + peer_nickname_->assign(value); +} +inline void ChatMessage::set_peer_nickname(const char* value, size_t size) { + set_has_peer_nickname(); + if (peer_nickname_ == &::google::protobuf::internal::kEmptyString) { + peer_nickname_ = new ::std::string; + } + peer_nickname_->assign(reinterpret_cast(value), size); +} +inline ::std::string* ChatMessage::mutable_peer_nickname() { + set_has_peer_nickname(); + if (peer_nickname_ == &::google::protobuf::internal::kEmptyString) { + peer_nickname_ = new ::std::string; + } + return peer_nickname_; +} +inline ::std::string* ChatMessage::release_peer_nickname() { + clear_has_peer_nickname(); + if (peer_nickname_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = peer_nickname_; + peer_nickname_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// optional uint32 chat_flags = 4; +inline bool ChatMessage::has_chat_flags() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void ChatMessage::set_has_chat_flags() { + _has_bits_[0] |= 0x00000008u; +} +inline void ChatMessage::clear_has_chat_flags() { + _has_bits_[0] &= ~0x00000008u; +} +inline void ChatMessage::clear_chat_flags() { + chat_flags_ = 0u; + clear_has_chat_flags(); +} +inline ::google::protobuf::uint32 ChatMessage::chat_flags() const { + return chat_flags_; +} +inline void ChatMessage::set_chat_flags(::google::protobuf::uint32 value) { + set_has_chat_flags(); + chat_flags_ = value; +} + +// optional uint32 send_time = 5; +inline bool ChatMessage::has_send_time() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void ChatMessage::set_has_send_time() { + _has_bits_[0] |= 0x00000010u; +} +inline void ChatMessage::clear_has_send_time() { + _has_bits_[0] &= ~0x00000010u; +} +inline void ChatMessage::clear_send_time() { + send_time_ = 0u; + clear_has_send_time(); +} +inline ::google::protobuf::uint32 ChatMessage::send_time() const { + return send_time_; +} +inline void ChatMessage::set_send_time(::google::protobuf::uint32 value) { + set_has_send_time(); + send_time_ = value; +} + +// optional uint32 recv_time = 6; +inline bool ChatMessage::has_recv_time() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void ChatMessage::set_has_recv_time() { + _has_bits_[0] |= 0x00000020u; +} +inline void ChatMessage::clear_has_recv_time() { + _has_bits_[0] &= ~0x00000020u; +} +inline void ChatMessage::clear_recv_time() { + recv_time_ = 0u; + clear_has_recv_time(); +} +inline ::google::protobuf::uint32 ChatMessage::recv_time() const { + return recv_time_; +} +inline void ChatMessage::set_recv_time(::google::protobuf::uint32 value) { + set_has_recv_time(); + recv_time_ = value; +} + +// ------------------------------------------------------------------- + +// ResponseChatLobbies + +// required .rsctrl.core.Status status = 1; +inline bool ResponseChatLobbies::has_status() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ResponseChatLobbies::set_has_status() { + _has_bits_[0] |= 0x00000001u; +} +inline void ResponseChatLobbies::clear_has_status() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ResponseChatLobbies::clear_status() { + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); + clear_has_status(); +} +inline const ::rsctrl::core::Status& ResponseChatLobbies::status() const { + return status_ != NULL ? *status_ : *default_instance_->status_; +} +inline ::rsctrl::core::Status* ResponseChatLobbies::mutable_status() { + set_has_status(); + if (status_ == NULL) status_ = new ::rsctrl::core::Status; + return status_; +} +inline ::rsctrl::core::Status* ResponseChatLobbies::release_status() { + clear_has_status(); + ::rsctrl::core::Status* temp = status_; + status_ = NULL; + return temp; +} + +// repeated .rsctrl.chat.ChatLobbyInfo lobbies = 2; +inline int ResponseChatLobbies::lobbies_size() const { + return lobbies_.size(); +} +inline void ResponseChatLobbies::clear_lobbies() { + lobbies_.Clear(); +} +inline const ::rsctrl::chat::ChatLobbyInfo& ResponseChatLobbies::lobbies(int index) const { + return lobbies_.Get(index); +} +inline ::rsctrl::chat::ChatLobbyInfo* ResponseChatLobbies::mutable_lobbies(int index) { + return lobbies_.Mutable(index); +} +inline ::rsctrl::chat::ChatLobbyInfo* ResponseChatLobbies::add_lobbies() { + return lobbies_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::chat::ChatLobbyInfo >& +ResponseChatLobbies::lobbies() const { + return lobbies_; +} +inline ::google::protobuf::RepeatedPtrField< ::rsctrl::chat::ChatLobbyInfo >* +ResponseChatLobbies::mutable_lobbies() { + return &lobbies_; +} + +// ------------------------------------------------------------------- + +// RequestChatLobbies + +// required .rsctrl.chat.RequestChatLobbies.LobbySet lobby_set = 1; +inline bool RequestChatLobbies::has_lobby_set() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void RequestChatLobbies::set_has_lobby_set() { + _has_bits_[0] |= 0x00000001u; +} +inline void RequestChatLobbies::clear_has_lobby_set() { + _has_bits_[0] &= ~0x00000001u; +} +inline void RequestChatLobbies::clear_lobby_set() { + lobby_set_ = 1; + clear_has_lobby_set(); +} +inline ::rsctrl::chat::RequestChatLobbies_LobbySet RequestChatLobbies::lobby_set() const { + return static_cast< ::rsctrl::chat::RequestChatLobbies_LobbySet >(lobby_set_); +} +inline void RequestChatLobbies::set_lobby_set(::rsctrl::chat::RequestChatLobbies_LobbySet value) { + GOOGLE_DCHECK(::rsctrl::chat::RequestChatLobbies_LobbySet_IsValid(value)); + set_has_lobby_set(); + lobby_set_ = value; +} + +// ------------------------------------------------------------------- + +// RequestCreateLobby + +// required string lobby_name = 1; +inline bool RequestCreateLobby::has_lobby_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void RequestCreateLobby::set_has_lobby_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void RequestCreateLobby::clear_has_lobby_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void RequestCreateLobby::clear_lobby_name() { + if (lobby_name_ != &::google::protobuf::internal::kEmptyString) { + lobby_name_->clear(); + } + clear_has_lobby_name(); +} +inline const ::std::string& RequestCreateLobby::lobby_name() const { + return *lobby_name_; +} +inline void RequestCreateLobby::set_lobby_name(const ::std::string& value) { + set_has_lobby_name(); + if (lobby_name_ == &::google::protobuf::internal::kEmptyString) { + lobby_name_ = new ::std::string; + } + lobby_name_->assign(value); +} +inline void RequestCreateLobby::set_lobby_name(const char* value) { + set_has_lobby_name(); + if (lobby_name_ == &::google::protobuf::internal::kEmptyString) { + lobby_name_ = new ::std::string; + } + lobby_name_->assign(value); +} +inline void RequestCreateLobby::set_lobby_name(const char* value, size_t size) { + set_has_lobby_name(); + if (lobby_name_ == &::google::protobuf::internal::kEmptyString) { + lobby_name_ = new ::std::string; + } + lobby_name_->assign(reinterpret_cast(value), size); +} +inline ::std::string* RequestCreateLobby::mutable_lobby_name() { + set_has_lobby_name(); + if (lobby_name_ == &::google::protobuf::internal::kEmptyString) { + lobby_name_ = new ::std::string; + } + return lobby_name_; +} +inline ::std::string* RequestCreateLobby::release_lobby_name() { + clear_has_lobby_name(); + if (lobby_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = lobby_name_; + lobby_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// required string lobby_topic = 2; +inline bool RequestCreateLobby::has_lobby_topic() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void RequestCreateLobby::set_has_lobby_topic() { + _has_bits_[0] |= 0x00000002u; +} +inline void RequestCreateLobby::clear_has_lobby_topic() { + _has_bits_[0] &= ~0x00000002u; +} +inline void RequestCreateLobby::clear_lobby_topic() { + if (lobby_topic_ != &::google::protobuf::internal::kEmptyString) { + lobby_topic_->clear(); + } + clear_has_lobby_topic(); +} +inline const ::std::string& RequestCreateLobby::lobby_topic() const { + return *lobby_topic_; +} +inline void RequestCreateLobby::set_lobby_topic(const ::std::string& value) { + set_has_lobby_topic(); + if (lobby_topic_ == &::google::protobuf::internal::kEmptyString) { + lobby_topic_ = new ::std::string; + } + lobby_topic_->assign(value); +} +inline void RequestCreateLobby::set_lobby_topic(const char* value) { + set_has_lobby_topic(); + if (lobby_topic_ == &::google::protobuf::internal::kEmptyString) { + lobby_topic_ = new ::std::string; + } + lobby_topic_->assign(value); +} +inline void RequestCreateLobby::set_lobby_topic(const char* value, size_t size) { + set_has_lobby_topic(); + if (lobby_topic_ == &::google::protobuf::internal::kEmptyString) { + lobby_topic_ = new ::std::string; + } + lobby_topic_->assign(reinterpret_cast(value), size); +} +inline ::std::string* RequestCreateLobby::mutable_lobby_topic() { + set_has_lobby_topic(); + if (lobby_topic_ == &::google::protobuf::internal::kEmptyString) { + lobby_topic_ = new ::std::string; + } + return lobby_topic_; +} +inline ::std::string* RequestCreateLobby::release_lobby_topic() { + clear_has_lobby_topic(); + if (lobby_topic_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = lobby_topic_; + lobby_topic_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// required .rsctrl.chat.LobbyPrivacyLevel privacy_level = 4; +inline bool RequestCreateLobby::has_privacy_level() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void RequestCreateLobby::set_has_privacy_level() { + _has_bits_[0] |= 0x00000004u; +} +inline void RequestCreateLobby::clear_has_privacy_level() { + _has_bits_[0] &= ~0x00000004u; +} +inline void RequestCreateLobby::clear_privacy_level() { + privacy_level_ = 1; + clear_has_privacy_level(); +} +inline rsctrl::chat::LobbyPrivacyLevel RequestCreateLobby::privacy_level() const { + return static_cast< rsctrl::chat::LobbyPrivacyLevel >(privacy_level_); +} +inline void RequestCreateLobby::set_privacy_level(rsctrl::chat::LobbyPrivacyLevel value) { + GOOGLE_DCHECK(rsctrl::chat::LobbyPrivacyLevel_IsValid(value)); + set_has_privacy_level(); + privacy_level_ = value; +} + +// repeated string invited_friends = 3; +inline int RequestCreateLobby::invited_friends_size() const { + return invited_friends_.size(); +} +inline void RequestCreateLobby::clear_invited_friends() { + invited_friends_.Clear(); +} +inline const ::std::string& RequestCreateLobby::invited_friends(int index) const { + return invited_friends_.Get(index); +} +inline ::std::string* RequestCreateLobby::mutable_invited_friends(int index) { + return invited_friends_.Mutable(index); +} +inline void RequestCreateLobby::set_invited_friends(int index, const ::std::string& value) { + invited_friends_.Mutable(index)->assign(value); +} +inline void RequestCreateLobby::set_invited_friends(int index, const char* value) { + invited_friends_.Mutable(index)->assign(value); +} +inline void RequestCreateLobby::set_invited_friends(int index, const char* value, size_t size) { + invited_friends_.Mutable(index)->assign( + reinterpret_cast(value), size); +} +inline ::std::string* RequestCreateLobby::add_invited_friends() { + return invited_friends_.Add(); +} +inline void RequestCreateLobby::add_invited_friends(const ::std::string& value) { + invited_friends_.Add()->assign(value); +} +inline void RequestCreateLobby::add_invited_friends(const char* value) { + invited_friends_.Add()->assign(value); +} +inline void RequestCreateLobby::add_invited_friends(const char* value, size_t size) { + invited_friends_.Add()->assign(reinterpret_cast(value), size); +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +RequestCreateLobby::invited_friends() const { + return invited_friends_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +RequestCreateLobby::mutable_invited_friends() { + return &invited_friends_; +} + +// ------------------------------------------------------------------- + +// RequestJoinOrLeaveLobby + +// required string lobby_id = 1; +inline bool RequestJoinOrLeaveLobby::has_lobby_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void RequestJoinOrLeaveLobby::set_has_lobby_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void RequestJoinOrLeaveLobby::clear_has_lobby_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void RequestJoinOrLeaveLobby::clear_lobby_id() { + if (lobby_id_ != &::google::protobuf::internal::kEmptyString) { + lobby_id_->clear(); + } + clear_has_lobby_id(); +} +inline const ::std::string& RequestJoinOrLeaveLobby::lobby_id() const { + return *lobby_id_; +} +inline void RequestJoinOrLeaveLobby::set_lobby_id(const ::std::string& value) { + set_has_lobby_id(); + if (lobby_id_ == &::google::protobuf::internal::kEmptyString) { + lobby_id_ = new ::std::string; + } + lobby_id_->assign(value); +} +inline void RequestJoinOrLeaveLobby::set_lobby_id(const char* value) { + set_has_lobby_id(); + if (lobby_id_ == &::google::protobuf::internal::kEmptyString) { + lobby_id_ = new ::std::string; + } + lobby_id_->assign(value); +} +inline void RequestJoinOrLeaveLobby::set_lobby_id(const char* value, size_t size) { + set_has_lobby_id(); + if (lobby_id_ == &::google::protobuf::internal::kEmptyString) { + lobby_id_ = new ::std::string; + } + lobby_id_->assign(reinterpret_cast(value), size); +} +inline ::std::string* RequestJoinOrLeaveLobby::mutable_lobby_id() { + set_has_lobby_id(); + if (lobby_id_ == &::google::protobuf::internal::kEmptyString) { + lobby_id_ = new ::std::string; + } + return lobby_id_; +} +inline ::std::string* RequestJoinOrLeaveLobby::release_lobby_id() { + clear_has_lobby_id(); + if (lobby_id_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = lobby_id_; + lobby_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// required .rsctrl.chat.RequestJoinOrLeaveLobby.LobbyAction action = 2; +inline bool RequestJoinOrLeaveLobby::has_action() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void RequestJoinOrLeaveLobby::set_has_action() { + _has_bits_[0] |= 0x00000002u; +} +inline void RequestJoinOrLeaveLobby::clear_has_action() { + _has_bits_[0] &= ~0x00000002u; +} +inline void RequestJoinOrLeaveLobby::clear_action() { + action_ = 1; + clear_has_action(); +} +inline ::rsctrl::chat::RequestJoinOrLeaveLobby_LobbyAction RequestJoinOrLeaveLobby::action() const { + return static_cast< ::rsctrl::chat::RequestJoinOrLeaveLobby_LobbyAction >(action_); +} +inline void RequestJoinOrLeaveLobby::set_action(::rsctrl::chat::RequestJoinOrLeaveLobby_LobbyAction value) { + GOOGLE_DCHECK(::rsctrl::chat::RequestJoinOrLeaveLobby_LobbyAction_IsValid(value)); + set_has_action(); + action_ = value; +} + +// ------------------------------------------------------------------- + +// RequestSetLobbyNickname + +// required string nickname = 1; +inline bool RequestSetLobbyNickname::has_nickname() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void RequestSetLobbyNickname::set_has_nickname() { + _has_bits_[0] |= 0x00000001u; +} +inline void RequestSetLobbyNickname::clear_has_nickname() { + _has_bits_[0] &= ~0x00000001u; +} +inline void RequestSetLobbyNickname::clear_nickname() { + if (nickname_ != &::google::protobuf::internal::kEmptyString) { + nickname_->clear(); + } + clear_has_nickname(); +} +inline const ::std::string& RequestSetLobbyNickname::nickname() const { + return *nickname_; +} +inline void RequestSetLobbyNickname::set_nickname(const ::std::string& value) { + set_has_nickname(); + if (nickname_ == &::google::protobuf::internal::kEmptyString) { + nickname_ = new ::std::string; + } + nickname_->assign(value); +} +inline void RequestSetLobbyNickname::set_nickname(const char* value) { + set_has_nickname(); + if (nickname_ == &::google::protobuf::internal::kEmptyString) { + nickname_ = new ::std::string; + } + nickname_->assign(value); +} +inline void RequestSetLobbyNickname::set_nickname(const char* value, size_t size) { + set_has_nickname(); + if (nickname_ == &::google::protobuf::internal::kEmptyString) { + nickname_ = new ::std::string; + } + nickname_->assign(reinterpret_cast(value), size); +} +inline ::std::string* RequestSetLobbyNickname::mutable_nickname() { + set_has_nickname(); + if (nickname_ == &::google::protobuf::internal::kEmptyString) { + nickname_ = new ::std::string; + } + return nickname_; +} +inline ::std::string* RequestSetLobbyNickname::release_nickname() { + clear_has_nickname(); + if (nickname_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = nickname_; + nickname_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// repeated string lobby_ids = 2; +inline int RequestSetLobbyNickname::lobby_ids_size() const { + return lobby_ids_.size(); +} +inline void RequestSetLobbyNickname::clear_lobby_ids() { + lobby_ids_.Clear(); +} +inline const ::std::string& RequestSetLobbyNickname::lobby_ids(int index) const { + return lobby_ids_.Get(index); +} +inline ::std::string* RequestSetLobbyNickname::mutable_lobby_ids(int index) { + return lobby_ids_.Mutable(index); +} +inline void RequestSetLobbyNickname::set_lobby_ids(int index, const ::std::string& value) { + lobby_ids_.Mutable(index)->assign(value); +} +inline void RequestSetLobbyNickname::set_lobby_ids(int index, const char* value) { + lobby_ids_.Mutable(index)->assign(value); +} +inline void RequestSetLobbyNickname::set_lobby_ids(int index, const char* value, size_t size) { + lobby_ids_.Mutable(index)->assign( + reinterpret_cast(value), size); +} +inline ::std::string* RequestSetLobbyNickname::add_lobby_ids() { + return lobby_ids_.Add(); +} +inline void RequestSetLobbyNickname::add_lobby_ids(const ::std::string& value) { + lobby_ids_.Add()->assign(value); +} +inline void RequestSetLobbyNickname::add_lobby_ids(const char* value) { + lobby_ids_.Add()->assign(value); +} +inline void RequestSetLobbyNickname::add_lobby_ids(const char* value, size_t size) { + lobby_ids_.Add()->assign(reinterpret_cast(value), size); +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +RequestSetLobbyNickname::lobby_ids() const { + return lobby_ids_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +RequestSetLobbyNickname::mutable_lobby_ids() { + return &lobby_ids_; +} + +// ------------------------------------------------------------------- + +// ResponseSetLobbyNickname + +// required .rsctrl.core.Status status = 1; +inline bool ResponseSetLobbyNickname::has_status() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ResponseSetLobbyNickname::set_has_status() { + _has_bits_[0] |= 0x00000001u; +} +inline void ResponseSetLobbyNickname::clear_has_status() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ResponseSetLobbyNickname::clear_status() { + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); + clear_has_status(); +} +inline const ::rsctrl::core::Status& ResponseSetLobbyNickname::status() const { + return status_ != NULL ? *status_ : *default_instance_->status_; +} +inline ::rsctrl::core::Status* ResponseSetLobbyNickname::mutable_status() { + set_has_status(); + if (status_ == NULL) status_ = new ::rsctrl::core::Status; + return status_; +} +inline ::rsctrl::core::Status* ResponseSetLobbyNickname::release_status() { + clear_has_status(); + ::rsctrl::core::Status* temp = status_; + status_ = NULL; + return temp; +} + +// ------------------------------------------------------------------- + +// RequestRegisterEvents + +// required .rsctrl.chat.RequestRegisterEvents.RegisterAction action = 1; +inline bool RequestRegisterEvents::has_action() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void RequestRegisterEvents::set_has_action() { + _has_bits_[0] |= 0x00000001u; +} +inline void RequestRegisterEvents::clear_has_action() { + _has_bits_[0] &= ~0x00000001u; +} +inline void RequestRegisterEvents::clear_action() { + action_ = 1; + clear_has_action(); +} +inline ::rsctrl::chat::RequestRegisterEvents_RegisterAction RequestRegisterEvents::action() const { + return static_cast< ::rsctrl::chat::RequestRegisterEvents_RegisterAction >(action_); +} +inline void RequestRegisterEvents::set_action(::rsctrl::chat::RequestRegisterEvents_RegisterAction value) { + GOOGLE_DCHECK(::rsctrl::chat::RequestRegisterEvents_RegisterAction_IsValid(value)); + set_has_action(); + action_ = value; +} + +// ------------------------------------------------------------------- + +// ResponseRegisterEvents + +// required .rsctrl.core.Status status = 1; +inline bool ResponseRegisterEvents::has_status() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ResponseRegisterEvents::set_has_status() { + _has_bits_[0] |= 0x00000001u; +} +inline void ResponseRegisterEvents::clear_has_status() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ResponseRegisterEvents::clear_status() { + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); + clear_has_status(); +} +inline const ::rsctrl::core::Status& ResponseRegisterEvents::status() const { + return status_ != NULL ? *status_ : *default_instance_->status_; +} +inline ::rsctrl::core::Status* ResponseRegisterEvents::mutable_status() { + set_has_status(); + if (status_ == NULL) status_ = new ::rsctrl::core::Status; + return status_; +} +inline ::rsctrl::core::Status* ResponseRegisterEvents::release_status() { + clear_has_status(); + ::rsctrl::core::Status* temp = status_; + status_ = NULL; + return temp; +} + +// ------------------------------------------------------------------- + +// EventLobbyInvite + +// required .rsctrl.chat.ChatLobbyInfo lobby = 1; +inline bool EventLobbyInvite::has_lobby() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void EventLobbyInvite::set_has_lobby() { + _has_bits_[0] |= 0x00000001u; +} +inline void EventLobbyInvite::clear_has_lobby() { + _has_bits_[0] &= ~0x00000001u; +} +inline void EventLobbyInvite::clear_lobby() { + if (lobby_ != NULL) lobby_->::rsctrl::chat::ChatLobbyInfo::Clear(); + clear_has_lobby(); +} +inline const ::rsctrl::chat::ChatLobbyInfo& EventLobbyInvite::lobby() const { + return lobby_ != NULL ? *lobby_ : *default_instance_->lobby_; +} +inline ::rsctrl::chat::ChatLobbyInfo* EventLobbyInvite::mutable_lobby() { + set_has_lobby(); + if (lobby_ == NULL) lobby_ = new ::rsctrl::chat::ChatLobbyInfo; + return lobby_; +} +inline ::rsctrl::chat::ChatLobbyInfo* EventLobbyInvite::release_lobby() { + clear_has_lobby(); + ::rsctrl::chat::ChatLobbyInfo* temp = lobby_; + lobby_ = NULL; + return temp; +} + +// ------------------------------------------------------------------- + +// EventChatMessage + +// required .rsctrl.chat.ChatMessage msg = 1; +inline bool EventChatMessage::has_msg() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void EventChatMessage::set_has_msg() { + _has_bits_[0] |= 0x00000001u; +} +inline void EventChatMessage::clear_has_msg() { + _has_bits_[0] &= ~0x00000001u; +} +inline void EventChatMessage::clear_msg() { + if (msg_ != NULL) msg_->::rsctrl::chat::ChatMessage::Clear(); + clear_has_msg(); +} +inline const ::rsctrl::chat::ChatMessage& EventChatMessage::msg() const { + return msg_ != NULL ? *msg_ : *default_instance_->msg_; +} +inline ::rsctrl::chat::ChatMessage* EventChatMessage::mutable_msg() { + set_has_msg(); + if (msg_ == NULL) msg_ = new ::rsctrl::chat::ChatMessage; + return msg_; +} +inline ::rsctrl::chat::ChatMessage* EventChatMessage::release_msg() { + clear_has_msg(); + ::rsctrl::chat::ChatMessage* temp = msg_; + msg_ = NULL; + return temp; +} + +// ------------------------------------------------------------------- + +// RequestSendMessage + +// required .rsctrl.chat.ChatMessage msg = 1; +inline bool RequestSendMessage::has_msg() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void RequestSendMessage::set_has_msg() { + _has_bits_[0] |= 0x00000001u; +} +inline void RequestSendMessage::clear_has_msg() { + _has_bits_[0] &= ~0x00000001u; +} +inline void RequestSendMessage::clear_msg() { + if (msg_ != NULL) msg_->::rsctrl::chat::ChatMessage::Clear(); + clear_has_msg(); +} +inline const ::rsctrl::chat::ChatMessage& RequestSendMessage::msg() const { + return msg_ != NULL ? *msg_ : *default_instance_->msg_; +} +inline ::rsctrl::chat::ChatMessage* RequestSendMessage::mutable_msg() { + set_has_msg(); + if (msg_ == NULL) msg_ = new ::rsctrl::chat::ChatMessage; + return msg_; +} +inline ::rsctrl::chat::ChatMessage* RequestSendMessage::release_msg() { + clear_has_msg(); + ::rsctrl::chat::ChatMessage* temp = msg_; + msg_ = NULL; + return temp; +} + +// ------------------------------------------------------------------- + +// ResponseSendMessage + +// required .rsctrl.core.Status status = 1; +inline bool ResponseSendMessage::has_status() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ResponseSendMessage::set_has_status() { + _has_bits_[0] |= 0x00000001u; +} +inline void ResponseSendMessage::clear_has_status() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ResponseSendMessage::clear_status() { + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); + clear_has_status(); +} +inline const ::rsctrl::core::Status& ResponseSendMessage::status() const { + return status_ != NULL ? *status_ : *default_instance_->status_; +} +inline ::rsctrl::core::Status* ResponseSendMessage::mutable_status() { + set_has_status(); + if (status_ == NULL) status_ = new ::rsctrl::core::Status; + return status_; +} +inline ::rsctrl::core::Status* ResponseSendMessage::release_status() { + clear_has_status(); + ::rsctrl::core::Status* temp = status_; + status_ = NULL; + return temp; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace chat +} // namespace rsctrl + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::chat::ChatLobbyInfo_LobbyState>() { + return ::rsctrl::chat::ChatLobbyInfo_LobbyState_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::chat::RequestChatLobbies_LobbySet>() { + return ::rsctrl::chat::RequestChatLobbies_LobbySet_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::chat::RequestJoinOrLeaveLobby_LobbyAction>() { + return ::rsctrl::chat::RequestJoinOrLeaveLobby_LobbyAction_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::chat::RequestRegisterEvents_RegisterAction>() { + return ::rsctrl::chat::RequestRegisterEvents_RegisterAction_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< rsctrl::chat::RequestMsgIds>() { + return rsctrl::chat::RequestMsgIds_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< rsctrl::chat::ResponseMsgIds>() { + return rsctrl::chat::ResponseMsgIds_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< rsctrl::chat::LobbyPrivacyLevel>() { + return rsctrl::chat::LobbyPrivacyLevel_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< rsctrl::chat::ChatType>() { + return rsctrl::chat::ChatType_descriptor(); +} + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_chat_2eproto__INCLUDED diff --git a/retroshare-nogui/src/rpc/proto/gencc/core.pb.cc b/retroshare-nogui/src/rpc/proto/gencc/core.pb.cc index f669e5f61..e95575c67 100644 --- a/retroshare-nogui/src/rpc/proto/gencc/core.pb.cc +++ b/retroshare-nogui/src/rpc/proto/gencc/core.pb.cc @@ -313,9 +313,9 @@ void protobuf_AddDesc_core_2eproto() { "RWARD\020\010\"3\n\tBandwidth\022\n\n\002up\030\001 \002(\002\022\014\n\004down" "\030\002 \002(\002\022\014\n\004name\030\003 \001(\t\":\n\014BandwidthSet\022*\n\n" "bandwidths\030\001 \003(\0132\026.rsctrl.core.Bandwidth" - "*\027\n\013ExtensionId\022\010\n\004CORE\020\000*A\n\tPackageId\022\t" - "\n\005PEERS\020\001\022\n\n\006SYSTEM\020\002\022\t\n\005FILES\020\003\022\010\n\004MSGS" - "\020\004\022\010\n\003GXS\020\350\007", 1292); + "*\027\n\013ExtensionId\022\010\n\004CORE\020\000*6\n\tPackageId\022\t" + "\n\005PEERS\020\001\022\n\n\006SYSTEM\020\002\022\010\n\004CHAT\020\003\022\010\n\003GXS\020\350" + "\007", 1281); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "core.proto", &protobuf_RegisterTypes); Status::default_instance_ = new Status(); @@ -368,7 +368,6 @@ bool PackageId_IsValid(int value) { case 1: case 2: case 3: - case 4: case 1000: return true; default: diff --git a/retroshare-nogui/src/rpc/proto/gencc/core.pb.h b/retroshare-nogui/src/rpc/proto/gencc/core.pb.h index ef2ab4074..8ed3d8e2d 100644 --- a/retroshare-nogui/src/rpc/proto/gencc/core.pb.h +++ b/retroshare-nogui/src/rpc/proto/gencc/core.pb.h @@ -153,8 +153,7 @@ inline bool ExtensionId_Parse( enum PackageId { PEERS = 1, SYSTEM = 2, - FILES = 3, - MSGS = 4, + CHAT = 3, GXS = 1000 }; bool PackageId_IsValid(int value); diff --git a/retroshare-nogui/src/rpc/proto/rpcprotochat.cc b/retroshare-nogui/src/rpc/proto/rpcprotochat.cc new file mode 100644 index 000000000..7fba114ba --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/rpcprotochat.cc @@ -0,0 +1,1286 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "rpc/proto/rpcprotochat.h" +#include "rpc/proto/gencc/chat.pb.h" + +#include +#include + +#include "util/rsstring.h" + +#include + +#include +#include + +#include + + +// Helper Functions -> maybe move to libretroshare/utils ?? +bool convertUTF8toWString(const std::string &msg_utf8, std::wstring &msg_wstr); +bool convertWStringToUTF8(const std::wstring &msg_wstr, std::string &msg_utf8); + +bool convertStringToLobbyId(const std::string &chat_id, ChatLobbyId &lobby_id); +bool convertLobbyIdToString(const ChatLobbyId &lobby_id, std::string &chat_id); + +bool fillLobbyInfoFromChatLobbyInfo(const ChatLobbyInfo &cfi, rsctrl::chat::ChatLobbyInfo *lobby); +bool fillLobbyInfoFromPublicChatLobbyRecord(const PublicChatLobbyRecord &pclr, rsctrl::chat::ChatLobbyInfo *lobby); +bool fillLobbyInfoFromChatLobbyInvite(const ChatLobbyInvite &cli, rsctrl::chat::ChatLobbyInfo *lobby); + +bool createQueuedEventSendMsg(const ChatInfo &chatinfo, rsctrl::chat::ChatType ctype, + std::string chat_id, const RpcEventRegister &ereg, RpcQueuedMsg &qmsg); + + +RpcProtoChat::RpcProtoChat(uint32_t serviceId) + :RpcQueueService(serviceId) +{ + return; +} + +//RpcProtoChat::msgsAccepted(std::list &msgIds); /* not used at the moment */ + +int RpcProtoChat::processMsg(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg) +{ + /* check the msgId */ + uint8_t topbyte = getRpcMsgIdExtension(msg_id); + uint16_t service = getRpcMsgIdService(msg_id); + uint8_t submsg = getRpcMsgIdSubMsg(msg_id); + bool isResponse = isRpcMsgIdResponse(msg_id); + + + std::cerr << "RpcProtoChat::processMsg() topbyte: " << (int32_t) topbyte; + std::cerr << " service: " << (int32_t) service << " submsg: " << (int32_t) submsg; + std::cerr << std::endl; + + if (isResponse) + { + std::cerr << "RpcProtoChat::processMsg() isResponse() - not processing"; + std::cerr << std::endl; + return 0; + } + + if (topbyte != (uint8_t) rsctrl::core::CORE) + { + std::cerr << "RpcProtoChat::processMsg() Extension Mismatch - not processing"; + std::cerr << std::endl; + return 0; + } + + if (service != (uint16_t) rsctrl::core::CHAT) + { + std::cerr << "RpcProtoChat::processMsg() Service Mismatch - not processing"; + std::cerr << std::endl; + return 0; + } + + if (!rsctrl::chat::RequestMsgIds_IsValid(submsg)) + { + std::cerr << "RpcProtoChat::processMsg() SubMsg Mismatch - not processing"; + std::cerr << std::endl; + return 0; + } + + switch(submsg) + { + case rsctrl::chat::MsgId_RequestChatLobbies: + processReqChatLobbies(chan_id, msg_id, req_id, msg); + break; + case rsctrl::chat::MsgId_RequestCreateLobby: + processReqCreateLobby(chan_id, msg_id, req_id, msg); + break; + + case rsctrl::chat::MsgId_RequestJoinOrLeaveLobby: + processReqJoinOrLeaveLobby(chan_id, msg_id, req_id, msg); + break; + + case rsctrl::chat::MsgId_RequestSetLobbyNickname: + processReqSetLobbyNickname(chan_id, msg_id, req_id, msg); + break; + + case rsctrl::chat::MsgId_RequestRegisterEvents: + processReqRegisterEvents(chan_id, msg_id, req_id, msg); + break; + + case rsctrl::chat::MsgId_RequestSendMessage: + processReqSendMessage(chan_id, msg_id, req_id, msg); + break; + + + default: + std::cerr << "RpcProtoChat::processMsg() ERROR should never get here"; + std::cerr << std::endl; + return 0; + } + + /* must have matched id to get here */ + return 1; +} + + +// Registrations. +//#define REGISTRATION_EVENT_CHAT 1 + +int RpcProtoChat::processReqChatLobbies(uint32_t chan_id, uint32_t /*msg_id*/, uint32_t req_id, const std::string &msg) +{ + std::cerr << "RpcProtoChat::processReqChatLobbies()"; + std::cerr << std::endl; + + // parse msg. + rsctrl::chat::RequestChatLobbies req; + if (!req.ParseFromString(msg)) + { + std::cerr << "RpcProtoChat::processReqChatLobbies() ERROR ParseFromString()"; + std::cerr << std::endl; + return 0; + } + + // response. + rsctrl::chat::ResponseChatLobbies resp; + bool success = true; + std::string errorMsg; + + // set these flags from request. + bool fetch_chatlobbylist = true; + bool fetch_invites = true; + bool fetch_publiclobbies = true; + + switch(req.lobby_set()) + { + case rsctrl::chat::RequestChatLobbies::LOBBYSET_ALL: + std::cerr << "RpcProtoChat::processReqChatLobbies() LOBBYSET_ALL"; + std::cerr << std::endl; + fetch_chatlobbylist = true; + fetch_invites = true; + fetch_publiclobbies = true; + break; + case rsctrl::chat::RequestChatLobbies::LOBBYSET_JOINED: + std::cerr << "RpcProtoChat::processReqChatLobbies() LOBBYSET_JOINED"; + std::cerr << std::endl; + fetch_chatlobbylist = true; + fetch_invites = false; + fetch_publiclobbies = false; + break; + case rsctrl::chat::RequestChatLobbies::LOBBYSET_INVITED: + std::cerr << "RpcProtoChat::processReqChatLobbies() LOBBYSET_INVITED"; + std::cerr << std::endl; + fetch_chatlobbylist = false; + fetch_invites = true; + fetch_publiclobbies = false; + break; + case rsctrl::chat::RequestChatLobbies::LOBBYSET_PUBLIC: + std::cerr << "RpcProtoChat::processReqChatLobbies() LOBBYSET_PUBLIC"; + std::cerr << std::endl; + fetch_chatlobbylist = false; + fetch_invites = false; + fetch_publiclobbies = true; + break; + default: + std::cerr << "RpcProtoChat::processReqChatLobbies() LOBBYSET ERROR"; + std::cerr << std::endl; + success = false; + errorMsg = "Invalid Lobby Set"; + } + + + std::set done_lobbies; // list of ones we've added already (to avoid duplicates). + + if (fetch_chatlobbylist) + { + std::cerr << "RpcProtoChat::processReqChatLobbies() Fetching chatlobbylist"; + std::cerr << std::endl; + + std::list cl_info; + std::list::iterator it; + + rsMsgs->getChatLobbyList(cl_info); + + for(it = cl_info.begin(); it != cl_info.end(); it++) + { + rsctrl::chat::ChatLobbyInfo *lobby = resp.add_lobbies(); + fillLobbyInfoFromChatLobbyInfo(*it, lobby); + + done_lobbies.insert(it->lobby_id); + + std::cerr << "\t Added Lobby: " << it->lobby_id; + std::cerr << std::endl; + } + } + + /* This is before Public Lobbies - as knowing you have been invited is + * more important, than the full info that might be gleaned from lobby. + * In the future, we might try to merge the info. + */ + if (fetch_invites) + { + std::cerr << "RpcProtoChat::processReqChatLobbies() Fetching invites"; + std::cerr << std::endl; + + std::list invites; + std::list::iterator it; + rsMsgs->getPendingChatLobbyInvites(invites); + + for(it = invites.begin(); it != invites.end(); it++) + { + if (done_lobbies.find(it->lobby_id) == done_lobbies.end()) + { + rsctrl::chat::ChatLobbyInfo *lobby = resp.add_lobbies(); + fillLobbyInfoFromChatLobbyInvite(*it, lobby); + + done_lobbies.insert(it->lobby_id); + + std::cerr << "\t Added Lobby: " << it->lobby_id; + std::cerr << std::endl; + } + else + { + std::cerr << "\t Skipping Already Added Lobby: " << it->lobby_id; + std::cerr << std::endl; + } + } + } + + if (fetch_publiclobbies) + { + std::cerr << "RpcProtoChat::processReqChatLobbies() Fetching public lobbies"; + std::cerr << std::endl; + + std::vector public_lobbies; + std::vector::iterator it; + + rsMsgs->getListOfNearbyChatLobbies(public_lobbies); + + for(it = public_lobbies.begin(); it != public_lobbies.end(); it++) + { + if (done_lobbies.find(it->lobby_id) == done_lobbies.end()) + { + rsctrl::chat::ChatLobbyInfo *lobby = resp.add_lobbies(); + fillLobbyInfoFromPublicChatLobbyRecord(*it, lobby); + + done_lobbies.insert(it->lobby_id); + + std::cerr << "\t Added Lobby: " << it->lobby_id; + std::cerr << std::endl; + } + else + { + std::cerr << "\t Skipping Already Added Lobby: " << it->lobby_id; + std::cerr << std::endl; + } + } + } + + + /* DONE - Generate Reply */ + if (success) + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::SUCCESS); + } + else + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::FAILED); + status->set_msg(errorMsg); + } + + std::string outmsg; + if (!resp.SerializeToString(&outmsg)) + { + std::cerr << "RpcProtoChat::processReqChatLobbies() ERROR SerialiseToString()"; + std::cerr << std::endl; + return 0; + } + + // Correctly Name Message. + uint32_t out_msg_id = constructMsgId(rsctrl::core::CORE, rsctrl::core::CHAT, + rsctrl::chat::MsgId_ResponseChatLobbies, true); + + // queue it. + queueResponse(chan_id, out_msg_id, req_id, outmsg); + + return 1; +} + + + +int RpcProtoChat::processReqCreateLobby(uint32_t chan_id, uint32_t /*msg_id*/, uint32_t req_id, const std::string &msg) +{ + std::cerr << "RpcProtoChat::processReqCreateLobby()"; + std::cerr << std::endl; + + // parse msg. + rsctrl::chat::RequestCreateLobby req; + if (!req.ParseFromString(msg)) + { + std::cerr << "RpcProtoChat::processReqCreateLobby() ERROR ParseFromString()"; + std::cerr << std::endl; + return 0; + } + + // response. + rsctrl::chat::ResponseChatLobbies resp; + bool success = true; + std::string errorMsg; + + /* convert msg parameters into local ones */ + + std::string lobby_name = req.lobby_name(); + std::string lobby_topic = req.lobby_topic(); + std::list invited_friends; + uint32_t lobby_privacy_type; + + switch(req.privacy_level()) + { + case rsctrl::chat::PRIVACY_PRIVATE: + std::cerr << "\tCreating Private Lobby"; + std::cerr << std::endl; + lobby_privacy_type = RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE; + break; + case rsctrl::chat::PRIVACY_PUBLIC: + std::cerr << "\tCreating Public Lobby"; + std::cerr << std::endl; + lobby_privacy_type = RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC; + break; + default: + std::cerr << "ERROR invalid Privacy Level"; + std::cerr << std::endl; + + success = false; + errorMsg = "Invalid Privacy Level"; + } + + int no_invites = req.invited_friends_size(); + for(int i = 0; i < no_invites; i++) + { + std::string peer = req.invited_friends(i); + /* check that they are a valid friend */ + if (!rsPeers->isFriend(peer)) // checks SSL ID. + { + std::cerr << "ERROR invalid SSL Friend ID: " << peer; + std::cerr << std::endl; + + success = false; + errorMsg = "Invalid SSL Friend ID"; + break; + } + + std::cerr << "Adding Valid Friend to Invites: " << peer; + std::cerr << std::endl; + + invited_friends.push_back(peer); + } + + ChatLobbyId created_lobby_id = 0; + if (success) + { + created_lobby_id = rsMsgs->createChatLobby(lobby_name,lobby_topic, + invited_friends,lobby_privacy_type); + + std::cerr << "Created Lobby Id: " << created_lobby_id; + std::cerr << std::endl; + + std::list cl_info; + std::list::iterator it; + + rsMsgs->getChatLobbyList(cl_info); + + bool found_entry = false; + for(it = cl_info.begin(); it != cl_info.end(); it++) + { + if (it->lobby_id == created_lobby_id) + { + std::cerr << "Found Created Lobby Id: " << created_lobby_id; + std::cerr << std::endl; + + rsctrl::chat::ChatLobbyInfo *lobby = resp.add_lobbies(); + fillLobbyInfoFromChatLobbyInfo(*it, lobby); + found_entry = true; + break; + } + } + + if (!found_entry) + { + std::cerr << "FAILED TO FIND Created Lobby Id: " << created_lobby_id; + std::cerr << std::endl; + + success = false; + errorMsg = "Chat Lobby Creation appears to have failed"; + } + } + + /* DONE - Generate Reply */ + if (success) + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::SUCCESS); + } + else + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::FAILED); + status->set_msg(errorMsg); + } + + std::string outmsg; + if (!resp.SerializeToString(&outmsg)) + { + std::cerr << "RpcProtoChat::processReqCreateLobbies() ERROR SerialiseToString()"; + std::cerr << std::endl; + return 0; + } + + // Correctly Name Message. + uint32_t out_msg_id = constructMsgId(rsctrl::core::CORE, rsctrl::core::CHAT, + rsctrl::chat::MsgId_ResponseChatLobbies, true); + + // queue it. + queueResponse(chan_id, out_msg_id, req_id, outmsg); + + return 1; +} + + + +int RpcProtoChat::processReqJoinOrLeaveLobby(uint32_t chan_id, uint32_t /*msg_id*/, uint32_t req_id, const std::string &msg) +{ + std::cerr << "RpcProtoChat::processReqJoinOrLeaveLobby()"; + std::cerr << std::endl; + + // parse msg. + rsctrl::chat::RequestJoinOrLeaveLobby req; + if (!req.ParseFromString(msg)) + { + std::cerr << "RpcProtoChat::processReqJoinOrLeaveLobby() ERROR ParseFromString()"; + std::cerr << std::endl; + return 0; + } + + // response. + rsctrl::chat::ResponseChatLobbies resp; + bool success = false; + std::string errorMsg; + + /* convert msg parameters into local ones */ + ChatLobbyId lobby_id = 0; + convertStringToLobbyId(req.lobby_id(), lobby_id); + + std::cerr << "Requested Lobby is: " << lobby_id; + std::cerr << std::endl; + + /* now must work out if its an invite or an existing lobby */ + /* look for a pending invitation */ + bool isPendingInvite = false; + { + std::list invites; + std::list::iterator it; + rsMsgs->getPendingChatLobbyInvites(invites); + + for(it = invites.begin(); it != invites.end(); it++) + { + if (it->lobby_id == lobby_id) + { + std::cerr << "It is a Pending Invite" << lobby_id; + std::cerr << std::endl; + + isPendingInvite = true; + break; + } + } + } + + switch(req.action()) + { + case rsctrl::chat::RequestJoinOrLeaveLobby::JOIN_OR_ACCEPT: + { + std::cerr << "Request to JOIN_OR_ACCEPT"; + std::cerr << std::endl; + + if (isPendingInvite) + { + if (!rsMsgs->acceptLobbyInvite(lobby_id)) + { + std::cerr << "ERROR acceptLobbyInvite FAILED"; + std::cerr << std::endl; + + success = false; + errorMsg = "AcceptLobbyInvite returned False"; + } + } + else + { + if (!rsMsgs->joinPublicChatLobby(lobby_id)) + { + std::cerr << "ERROR joinPublicChatLobby FAILED"; + std::cerr << std::endl; + + success = false; + errorMsg = "joinPublicChatLobby returned False"; + } + } + + break; + } + case rsctrl::chat::RequestJoinOrLeaveLobby::LEAVE_OR_DENY: + { + std::cerr << "Request to LEAVE_OR_DENY (No fail codes!)"; + std::cerr << std::endl; + + if (isPendingInvite) + { + // return void - so can't check. + rsMsgs->denyLobbyInvite(lobby_id); + } + else + { + // return void - so can't check. + rsMsgs->unsubscribeChatLobby(lobby_id); + } + + break; + } + default: + success = false; + errorMsg = "Unknown Action"; + } + + + if (success && (req.action() == rsctrl::chat::RequestJoinOrLeaveLobby::JOIN_OR_ACCEPT)) + { + std::list cl_info; + std::list::iterator it; + + rsMsgs->getChatLobbyList(cl_info); + + bool found_entry = false; + for(it = cl_info.begin(); it != cl_info.end(); it++) + { + if (it->lobby_id == lobby_id) + { + rsctrl::chat::ChatLobbyInfo *lobby = resp.add_lobbies(); + fillLobbyInfoFromChatLobbyInfo(*it, lobby); + found_entry = true; + break; + } + } + + if (!found_entry) + { + success = false; + errorMsg = "Chat Lobby JOIN/ACCEPT appears to have failed"; + } + } + + /* DONE - Generate Reply */ + if (success) + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::SUCCESS); + } + else + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::FAILED); + status->set_msg(errorMsg); + } + + std::string outmsg; + if (!resp.SerializeToString(&outmsg)) + { + std::cerr << "RpcProtoChat::processReqCreateLobbies() ERROR SerialiseToString()"; + std::cerr << std::endl; + return 0; + } + + // Correctly Name Message. + uint32_t out_msg_id = constructMsgId(rsctrl::core::CORE, rsctrl::core::CHAT, + rsctrl::chat::MsgId_ResponseChatLobbies, true); + + // queue it. + queueResponse(chan_id, out_msg_id, req_id, outmsg); + + return 1; +} + + + +int RpcProtoChat::processReqSetLobbyNickname(uint32_t chan_id, uint32_t /*msg_id*/, uint32_t req_id, const std::string &msg) +{ + std::cerr << "RpcProtoChat::processReqSetLobbyNickname()"; + std::cerr << std::endl; + + // parse msg. + rsctrl::chat::RequestSetLobbyNickname req; + if (!req.ParseFromString(msg)) + { + std::cerr << "RpcProtoChat::processReqSetLobbyNickname() ERROR ParseFromString()"; + std::cerr << std::endl; + return 0; + } + + // response. + rsctrl::chat::ResponseSetLobbyNickname resp; + bool success = true; + std::string errorMsg; + + /* convert msg parameters into local ones */ + std::string nickname = req.nickname(); + + std::cerr << "choosen nickname is: " << nickname; + std::cerr << std::endl; + + int no_lobbyids = req.lobby_ids_size(); + for(int i = 0; i < no_lobbyids; i++) + { + std::string idstr = req.lobby_ids(i); + ChatLobbyId id = 0; + convertStringToLobbyId(idstr, id); + + std::cerr << "setting nickname for lobby: " << id; + std::cerr << std::endl; + + if (!rsMsgs->setNickNameForChatLobby(id, nickname)) + { + std::cerr << "ERROR setting nickname for lobby: " << id; + std::cerr << std::endl; + + success = false; + errorMsg = "Failed to Set one of the nicknames"; + break; + } + + } + + if (no_lobbyids == 0) + { + std::cerr << "setting default nickname"; + std::cerr << std::endl; + + /* just do default instead */ + rsMsgs->setDefaultNickNameForChatLobby(nickname); + } + + /* DONE - Generate Reply */ + if (success) + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::SUCCESS); + } + else + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::FAILED); + status->set_msg(errorMsg); + } + + std::string outmsg; + if (!resp.SerializeToString(&outmsg)) + { + std::cerr << "RpcProtoChat::processReqCreateLobbies() ERROR SerialiseToString()"; + std::cerr << std::endl; + return 0; + } + + // Correctly Name Message. + uint32_t out_msg_id = constructMsgId(rsctrl::core::CORE, rsctrl::core::CHAT, + rsctrl::chat::MsgId_ResponseSetLobbyNickname, true); + + // queue it. + queueResponse(chan_id, out_msg_id, req_id, outmsg); + + return 1; + +} + + + +int RpcProtoChat::processReqRegisterEvents(uint32_t chan_id, uint32_t /*msg_id*/, uint32_t req_id, const std::string &msg) +{ + std::cerr << "RpcProtoChat::processReqRegisterEvents()"; + std::cerr << std::endl; + + // parse msg. + rsctrl::chat::RequestRegisterEvents req; + if (!req.ParseFromString(msg)) + { + std::cerr << "RpcProtoChat::processReqRegisterEvents() ERROR ParseFromString()"; + std::cerr << std::endl; + return 0; + } + + // response. + rsctrl::chat::ResponseRegisterEvents resp; + bool success = true; + bool doregister = false; + std::string errorMsg; + + switch(req.action()) + { + case rsctrl::chat::RequestRegisterEvents::REGISTER: + doregister = true; + break; + case rsctrl::chat::RequestRegisterEvents::DEREGISTER: + doregister = false; + break; + default: + std::cerr << "ERROR action is invalid"; + std::cerr << std::endl; + + success = false; + errorMsg = "RegisterEvent.Action is invalid"; + break; + } + + if (success) + { + if (doregister) + { + std::cerr << "Registering for Chat Events"; + std::cerr << std::endl; + + registerForEvents(chan_id, req_id, REGISTRATION_EVENT_CHAT); + } + else + { + std::cerr << "Deregistering for Chat Events"; + std::cerr << std::endl; + + deregisterForEvents(chan_id, req_id, REGISTRATION_EVENT_CHAT); + } + printEventRegister(std::cerr); + } + + + /* DONE - Generate Reply */ + if (success) + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::SUCCESS); + } + else + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::FAILED); + status->set_msg(errorMsg); + } + + std::string outmsg; + if (!resp.SerializeToString(&outmsg)) + { + std::cerr << "RpcProtoChat::processReqCreateLobbies() ERROR SerialiseToString()"; + std::cerr << std::endl; + return 0; + } + + // Correctly Name Message. + uint32_t out_msg_id = constructMsgId(rsctrl::core::CORE, rsctrl::core::CHAT, + rsctrl::chat::MsgId_ResponseRegisterEvents, true); + + // queue it. + queueResponse(chan_id, out_msg_id, req_id, outmsg); + + return 1; +} + + + +int RpcProtoChat::processReqSendMessage(uint32_t chan_id, uint32_t /*msg_id*/, uint32_t req_id, const std::string &msg) +{ + std::cerr << "RpcProtoChat::processReqSendMessage()"; + std::cerr << std::endl; + + // parse msg. + rsctrl::chat::RequestSendMessage req; + if (!req.ParseFromString(msg)) + { + std::cerr << "RpcProtoChat::processReqSendMessage() ERROR ParseFromString()"; + std::cerr << std::endl; + return 0; + } + + // response. + rsctrl::chat::ResponseSendMessage resp; + bool success = true; + std::string errorMsg; + + // Send the message. + bool priv_or_lobby = true; + std::string chat_id; + std::wstring chat_msg; + convertUTF8toWString(req.msg().msg(), chat_msg); + + std::cerr << "Chat Message is: " << req.msg().msg(); + std::cerr << std::endl; + + /* switch depending on type */ + switch(req.msg().id().chat_type()) + { + case rsctrl::chat::TYPE_PRIVATE: + // easy one. + chat_id = req.msg().id().chat_id(); + priv_or_lobby = true; + + std::cerr << "Sending Private Chat"; + std::cerr << std::endl; + + + break; + case rsctrl::chat::TYPE_LOBBY: + { + std::cerr << "Sending Lobby Chat"; + std::cerr << std::endl; + + /* convert string->ChatLobbyId */ + ChatLobbyId lobby_id; + if (!convertStringToLobbyId(req.msg().id().chat_id(), lobby_id)) + { + std::cerr << "ERROR Failed conversion of Lobby Id"; + std::cerr << std::endl; + + success = false; + errorMsg = "Failed Conversion of Lobby Id"; + } + /* convert lobby id to virtual peer id */ + else if (!rsMsgs->getVirtualPeerId(lobby_id, chat_id)) + { + std::cerr << "ERROR Invalid Lobby Id"; + std::cerr << std::endl; + + success = false; + errorMsg = "Invalid Lobby Id"; + } + priv_or_lobby = true; + break; + } + case rsctrl::chat::TYPE_GROUP: + + std::cerr << "Sending Group Chat"; + std::cerr << std::endl; + + priv_or_lobby = false; + break; + default: + + std::cerr << "ERROR Chat Type invalid"; + std::cerr << std::endl; + + success = false; + errorMsg = "Invalid Chat Type"; + break; + } + + if (success) + { + if (priv_or_lobby) + { + rsMsgs->sendPrivateChat(chat_id, chat_msg); + } + else + { + rsMsgs->sendPublicChat(chat_msg); + } + } + + /* DONE - Generate Reply */ + + if (success) + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::SUCCESS); + } + else + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::FAILED); + status->set_msg(errorMsg); + } + + std::string outmsg; + if (!resp.SerializeToString(&outmsg)) + { + std::cerr << "RpcProtoChat::processReqSendMessage() ERROR SerialiseToString()"; + std::cerr << std::endl; + return 0; + } + + // Correctly Name Message. + uint32_t out_msg_id = constructMsgId(rsctrl::core::CORE, rsctrl::core::CHAT, + rsctrl::chat::MsgId_ResponseSendMessage, true); + + // queue it. + queueResponse(chan_id, out_msg_id, req_id, outmsg); + + return 1; +} + + // EVENTS. +int RpcProtoChat::locked_checkForEvents(uint32_t event, const std::list ®istered, std::list &events) +{ + /* Wow - here already! */ + std::cerr << "locked_checkForEvents()"; + std::cerr << std::endl; + + /* only one event type for now */ + if (event != REGISTRATION_EVENT_CHAT) + { + std::cerr << "ERROR Invalid Chat Event Type"; + std::cerr << std::endl; + + /* error */ + return 0; + } + + /* possible events */ + /* TODO lobby invites. how do we make sure these are only sent once? */ + + // Likewise with Chat Queues -> We'll have to track which items have been sent + // to which Chan Ids.... a bit painful. + + /* public chat queues */ + if (rsMsgs->getPublicChatQueueCount() > 0) + { + std::cerr << "Fetching Public Chat Queue"; + std::cerr << std::endl; + + std::list chats; + rsMsgs->getPublicChatQueue(chats); + std::list::iterator it; + for(it = chats.begin(); it != chats.end(); it++) + { + std::cerr << "Public Chat from : " << it->rsid; + std::cerr << " name: " << it->peer_nickname; + std::cerr << std::endl; + { + std::string msg_utf8; + librs::util::ConvertUtf16ToUtf8(it->msg, msg_utf8); + std::cerr << " Msg: " << msg_utf8; + std::cerr << std::endl; + } + + /* must send to all registered clients */ + std::list::const_iterator rit; + for(rit = registered.begin(); rit != registered.end(); rit++) + { + RpcQueuedMsg qmsg; + rsctrl::chat::ChatType ctype = rsctrl::chat::TYPE_GROUP; + std::string chat_id = ""; // No ID for group. + + if (createQueuedEventSendMsg(*it, ctype, chat_id, *rit, qmsg)) + { + std::cerr << "Created MsgEvent"; + std::cerr << std::endl; + + events.push_back(qmsg); + } + else + { + std::cerr << "ERROR Creating MsgEvent"; + std::cerr << std::endl; + } + } + } + } + + + /* private chat queues */ + bool incoming = true; // ignore outgoing for now. (client can request that some other way) + if (rsMsgs->getPrivateChatQueueCount(incoming) > 0) + { + std::cerr << "Fetching Private Chat Queues"; + std::cerr << std::endl; + + std::list priv_chat_ids; + std::list::iterator cit; + rsMsgs->getPrivateChatQueueIds(incoming, priv_chat_ids); + for(cit = priv_chat_ids.begin(); cit != priv_chat_ids.end(); cit++) + { + std::list chats; + rsMsgs->getPrivateChatQueue(incoming, *cit, chats); + rsMsgs->clearPrivateChatQueue(incoming, *cit); + + // Default to Private. + rsctrl::chat::ChatType ctype = rsctrl::chat::TYPE_PRIVATE; + std::string chat_id = *cit; + + + // Check if its actually a LobbyId. + ChatLobbyId lobby_id; + if (rsMsgs->isLobbyId(*cit, lobby_id)) + { + ctype = rsctrl::chat::TYPE_LOBBY; + chat_id.clear(); + convertLobbyIdToString(lobby_id, chat_id); + + std::cerr << "Lobby Chat Queue: " << chat_id; + std::cerr << std::endl; + } + else + { + std::cerr << "Private Chat Queue: " << *cit; + std::cerr << std::endl; + } + + std::list::iterator it; + for(it = chats.begin(); it != chats.end(); it++) + { + std::cerr << "Private Chat from : " << it->rsid; + std::cerr << " name: " << it->peer_nickname; + std::cerr << std::endl; + { + std::string msg_utf8; + librs::util::ConvertUtf16ToUtf8(it->msg, msg_utf8); + std::cerr << " Msg: " << msg_utf8; + std::cerr << std::endl; + } + /* must send to all registered clients */ + std::list::const_iterator rit; + for(rit = registered.begin(); rit != registered.end(); rit++) + { + RpcQueuedMsg qmsg; + if (createQueuedEventSendMsg(*it, ctype, chat_id, *rit, qmsg)) + { + std::cerr << "Created MsgEvent"; + std::cerr << std::endl; + + events.push_back(qmsg); + } + else + { + std::cerr << "ERROR Creating MsgEvent"; + std::cerr << std::endl; + } + } + } + } + } + + return 1; +} + + +/***** HELPER FUNCTIONS *****/ + + + +bool fillLobbyInfoFromChatLobbyInfo(const ChatLobbyInfo &cli, rsctrl::chat::ChatLobbyInfo *lobby) +{ + /* convert info into response */ + std::string chat_id; + convertLobbyIdToString(cli.lobby_id, chat_id); + lobby->set_lobby_id(chat_id); + lobby->set_lobby_name(cli.lobby_name); + lobby->set_lobby_topic(cli.lobby_topic); + + /* see if there's a specific nickname for here */ + std::string nick; + if (!rsMsgs->getNickNameForChatLobby(cli.lobby_id,nick)) + { + rsMsgs->getDefaultNickNameForChatLobby(nick); + } + + lobby->set_lobby_nickname(nick); + + // Could be Private or Public. + if (cli.lobby_privacy_level & RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE) + { + lobby->set_privacy_level(rsctrl::chat::PRIVACY_PRIVATE); + } + else + { + lobby->set_privacy_level(rsctrl::chat::PRIVACY_PUBLIC); + } + lobby->set_lobby_state(rsctrl::chat::ChatLobbyInfo::LOBBYSTATE_JOINED); + + lobby->set_no_peers(cli.nick_names.size()); + + lobby->set_last_report_time(0); + lobby->set_last_activity(cli.last_activity); + + std::set::const_iterator pit; + for(pit = cli.participating_friends.begin(); pit != cli.participating_friends.begin(); pit++) + { + lobby->add_participating_friends(*pit); + } + + std::map::const_iterator mit; + for(mit = cli.nick_names.begin(); mit != cli.nick_names.begin(); mit++) + { + lobby->add_nicknames(mit->first); + } + return true; +} + + +bool fillLobbyInfoFromPublicChatLobbyRecord(const PublicChatLobbyRecord &pclr, rsctrl::chat::ChatLobbyInfo *lobby) +{ + /* convert info into response */ + std::string chat_id; + convertLobbyIdToString(pclr.lobby_id, chat_id); + lobby->set_lobby_id(chat_id); + lobby->set_lobby_name(pclr.lobby_name); + lobby->set_lobby_topic(pclr.lobby_topic); + + /* see if there's a specific nickname for here */ + std::string nick; + if (!rsMsgs->getNickNameForChatLobby(pclr.lobby_id,nick)) + { + rsMsgs->getDefaultNickNameForChatLobby(nick); + } + + lobby->set_lobby_nickname(nick); + + lobby->set_privacy_level(rsctrl::chat::PRIVACY_PUBLIC); + lobby->set_lobby_state(rsctrl::chat::ChatLobbyInfo::LOBBYSTATE_PUBLIC); + + lobby->set_no_peers(pclr.total_number_of_peers); + + lobby->set_last_report_time(pclr.last_report_time); + lobby->set_last_activity(0); // Unknown. + + std::set::const_iterator it; + for(it = pclr.participating_friends.begin(); it != pclr.participating_friends.begin(); it++) + { + lobby->add_participating_friends(*it); + } + + //lobby->add_nicknames(); // Unknown. + return true; +} + + +bool fillLobbyInfoFromChatLobbyInvite(const ChatLobbyInvite &cli, rsctrl::chat::ChatLobbyInfo *lobby) +{ + /* convert info into response */ + std::string chat_id; + convertLobbyIdToString(cli.lobby_id, chat_id); + lobby->set_lobby_id(chat_id); + lobby->set_lobby_name(cli.lobby_name); + lobby->set_lobby_topic(cli.lobby_topic); + + /* see if there's a specific nickname for here */ + std::string nick; + if (!rsMsgs->getNickNameForChatLobby(cli.lobby_id,nick)) + { + rsMsgs->getDefaultNickNameForChatLobby(nick); + } + + lobby->set_lobby_nickname(nick); + + // Can be invited to both Public and Private. + if (cli.lobby_privacy_level & RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE) + { + lobby->set_privacy_level(rsctrl::chat::PRIVACY_PRIVATE); + } + else + { + lobby->set_privacy_level(rsctrl::chat::PRIVACY_PUBLIC); + } + lobby->set_lobby_state(rsctrl::chat::ChatLobbyInfo::LOBBYSTATE_INVITED); + + lobby->set_no_peers(0); // Unknown. + + lobby->set_last_report_time(0); // Unknown + lobby->set_last_activity(0); // Unknown + + // Unknown, but we can fill in the inviting party here (the only one we know). + lobby->add_participating_friends(cli.peer_id); + //lobby->add_nicknames(); // Unknown. + return true; +} + + +bool createQueuedEventSendMsg(const ChatInfo &chatinfo, rsctrl::chat::ChatType ctype, + std::string chat_id, const RpcEventRegister &ereg, RpcQueuedMsg &qmsg) +{ + + rsctrl::chat::EventChatMessage event; + rsctrl::chat::ChatMessage *msg = event.mutable_msg(); + rsctrl::chat::ChatId *id = msg->mutable_id(); + + id->set_chat_type(ctype); + id->set_chat_id(chat_id); + + msg->set_peer_nickname(chatinfo.peer_nickname); + msg->set_chat_flags(chatinfo.chatflags); + msg->set_send_time(chatinfo.sendTime); + msg->set_recv_time(chatinfo.recvTime); + + std::string msg_utf8; + if (!convertWStringToUTF8(chatinfo.msg, msg_utf8)) + { + std::cerr << "RpcProtoChat::createQueuedEventSendMsg() ERROR Converting Msg"; + std::cerr << std::endl; + return false; + } + + msg->set_msg(msg_utf8); + + /* DONE - Generate Reply */ + std::string outmsg; + if (!event.SerializeToString(&outmsg)) + { + std::cerr << "RpcProtoChat::createQueuedEventSendMsg() ERROR SerialiseToString()"; + std::cerr << std::endl; + return false; + } + + // Correctly Name Message. + qmsg.mMsgId = constructMsgId(rsctrl::core::CORE, rsctrl::core::CHAT, + rsctrl::chat::MsgId_EventChatMessage, true); + + qmsg.mChanId = ereg.mChanId; + qmsg.mReqId = ereg.mReqId; + qmsg.mMsg = outmsg; + + return true; +} + +bool convertUTF8toWString(const std::string &msg_utf8, std::wstring &msg_wstr) +{ + return librs::util::ConvertUtf8ToUtf16(msg_utf8, msg_wstr); +} + +bool convertWStringToUTF8(const std::wstring &msg_wstr, std::string &msg_utf8) +{ + return librs::util::ConvertUtf16ToUtf8(msg_wstr, msg_utf8); +} + + +/* dependent on ChatLobbyId definition as uint64_t */ +bool convertStringToLobbyId(const std::string &chat_id, ChatLobbyId &lobby_id) +{ + if (1 != sscanf(chat_id.c_str(), UINT64FMT, &lobby_id)) + { + return false; + } + return true; +} + +bool convertLobbyIdToString(const ChatLobbyId &lobby_id, std::string &chat_id) +{ + rs_sprintf(chat_id, UINT64FMT, lobby_id); + return true; +} + + diff --git a/retroshare-nogui/src/rpc/proto/rpcprotochat.h b/retroshare-nogui/src/rpc/proto/rpcprotochat.h new file mode 100644 index 000000000..d42ab37de --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/rpcprotochat.h @@ -0,0 +1,53 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + + +#ifndef RS_RPC_PROTO_CHAT_H +#define RS_RPC_PROTO_CHAT_H + +#include "rpc/rpcserver.h" + +// Registrations. +#define REGISTRATION_EVENT_CHAT 1 + +class RpcProtoChat: public RpcQueueService +{ +public: + RpcProtoChat(uint32_t serviceId); + virtual int processMsg(uint32_t chan_id, uint32_t msgId, uint32_t req_id, const std::string &msg); + +protected: + + int processReqChatLobbies(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); + int processReqCreateLobby(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); + int processReqJoinOrLeaveLobby(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); + int processReqSetLobbyNickname(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); + int processReqRegisterEvents(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); + int processReqSendMessage(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); + + // EVENTS. + virtual int locked_checkForEvents(uint32_t event, const std::list ®istered, std::list &events); +}; + + +#endif /* RS_PROTO_CHAT_H */ diff --git a/retroshare-nogui/src/rpc/rpcserver.cc b/retroshare-nogui/src/rpc/rpcserver.cc index 4b796097b..484a7576e 100644 --- a/retroshare-nogui/src/rpc/rpcserver.cc +++ b/retroshare-nogui/src/rpc/rpcserver.cc @@ -27,6 +27,16 @@ #include + + +bool operator<(const RpcUniqueId &a, const RpcUniqueId &b) +{ + if (a.mChanId == b.mChanId) + return (a.mReqId < b.mReqId); + return (a.mChanId < b.mChanId); +} + + RpcServer::RpcServer(RpcMediator *med) :mMediator(med), mRpcMtx("RpcMtx") { @@ -91,12 +101,13 @@ int RpcServer::processMsg(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, co return 0; } -int RpcServer::queueRequest_locked(uint32_t /* chan_id */, uint32_t /* msgId */, uint32_t req_id, RpcService *service) +int RpcServer::queueRequest_locked(uint32_t chan_id, uint32_t /* msgId */, uint32_t req_id, RpcService *service) { std::cerr << "RpcServer::queueRequest_locked() req_id: " << req_id; std::cerr << std::endl; RpcQueuedObj obj; + obj.mChanId = chan_id; obj.mReqId = req_id; obj.mService = service; @@ -118,7 +129,7 @@ bool RpcServer::checkPending() std::list::iterator it; for(it = mRpcQueue.begin(); it != mRpcQueue.end();) { - uint32_t out_chan_id = 0; + uint32_t out_chan_id = it->mChanId; uint32_t out_msg_id = 0; uint32_t out_req_id = it->mReqId; std::string out_msg; @@ -216,10 +227,10 @@ void RpcQueueService::reset(uint32_t chan_id) RsStackMutex stack(mQueueMtx); /********** LOCKED MUTEX ***************/ - std::list toRemove; + std::list toRemove; // iterate through and remove only chan_id items. - std::map::iterator mit; + std::map::iterator mit; for(mit = mResponses.begin(); mit != mResponses.end(); mit++) { if (mit->second.mChanId == chan_id) @@ -227,7 +238,7 @@ void RpcQueueService::reset(uint32_t chan_id) } /* remove items */ - std::list::iterator rit; + std::list::iterator rit; for(rit = toRemove.begin(); rit != toRemove.end(); rit++) { mit = mResponses.find(*rit); @@ -242,15 +253,16 @@ int RpcQueueService::getResponse(uint32_t &chan_id, uint32_t &msg_id, uint32_t & { RsStackMutex stack(mQueueMtx); /********** LOCKED MUTEX ***************/ - std::map::iterator it; + std::map::iterator it; - it = mResponses.find(req_id); + RpcUniqueId uid(chan_id, req_id); + it = mResponses.find(uid); if (it == mResponses.end()) { return 0; } - chan_id = it->second.mChanId; + // chan_id & req_id are already set. msg_id = it->second.mMsgId; msg = it->second.mMsg; @@ -269,7 +281,8 @@ int RpcQueueService::queueResponse(uint32_t chan_id, uint32_t msg_id, uint32_t r qmsg.mReqId = req_id; qmsg.mMsg = msg; - mResponses[req_id] = qmsg; + RpcUniqueId uid(chan_id, req_id); + mResponses[uid] = qmsg; return 1; } @@ -297,7 +310,7 @@ int RpcQueueService::getEvents(std::list &events) return 1; } -int RpcQueueService::locked_checkForEvents(uint32_t event, const std::list ®istered, std::list &events) +int RpcQueueService::locked_checkForEvents(uint32_t event, const std::list ®istered, std::list & /* events */) { std::cerr << "RpcQueueService::locked_checkForEvents() NOT IMPLEMENTED"; std::cerr << std::endl; diff --git a/retroshare-nogui/src/rpc/rpcserver.h b/retroshare-nogui/src/rpc/rpcserver.h index f92b4b5aa..47c90ca29 100644 --- a/retroshare-nogui/src/rpc/rpcserver.h +++ b/retroshare-nogui/src/rpc/rpcserver.h @@ -45,6 +45,19 @@ uint32_t constructMsgId(uint8_t ext, uint16_t service, uint8_t submsg, bool is_r * Also allows a natural seperation of the full interface into sections. */ +// The Combination of ChanId & ReqId must be unique for each RPC call. +// This is used as an map index, so failure to make it unique, will lead to lost entries. +class RpcUniqueId +{ + public: + RpcUniqueId():mChanId(0), mReqId(0) {return;} + RpcUniqueId(uint32_t chan_id, uint32_t req_id):mChanId(chan_id), mReqId(req_id) {return;} + uint32_t mChanId; + uint32_t mReqId; +}; + +bool operator<(const RpcUniqueId &a, const RpcUniqueId &b); + class RpcQueuedMsg { public: @@ -67,6 +80,7 @@ public: virtual int getEvents(std::list & /* events */) { return 0; } /* 0 = none, optional feature */ }; + class RpcEventRegister { public: @@ -98,7 +112,7 @@ virtual int locked_checkForEvents(uint32_t event, const std::list mResponses; + std::map mResponses; std::map > mEventRegister; }; @@ -107,6 +121,7 @@ private: class RpcQueuedObj { public: + uint32_t mChanId; uint32_t mReqId; RpcService *mService; }; diff --git a/retroshare-nogui/src/rpc/rpcsetup.cc b/retroshare-nogui/src/rpc/rpcsetup.cc index 5451d7196..528f5b425 100644 --- a/retroshare-nogui/src/rpc/rpcsetup.cc +++ b/retroshare-nogui/src/rpc/rpcsetup.cc @@ -26,6 +26,7 @@ #include "rpc/proto/rpcprotopeers.h" #include "rpc/proto/rpcprotosystem.h" +#include "rpc/proto/rpcprotochat.h" #include "rpc/rpcecho.h" @@ -41,6 +42,9 @@ RpcMediator *CreateRpcSystem(RpcComms *comms) RpcProtoSystem *system = new RpcProtoSystem(1); server->addService(system); + RpcProtoChat *chat = new RpcProtoChat(1); + server->addService(chat); + /* Finally an Echo Service - which will echo back any unprocesses commands. */ RpcEcho *echo = new RpcEcho(1); server->addService(echo); diff --git a/retroshare-nogui/src/ssh/rssshd.cc b/retroshare-nogui/src/ssh/rssshd.cc index 94360baed..ff1ca5294 100644 --- a/retroshare-nogui/src/ssh/rssshd.cc +++ b/retroshare-nogui/src/ssh/rssshd.cc @@ -500,6 +500,8 @@ int RsSshd::doRpcSystem() } } + mRpcSystem->reset(dummy_chan_id); // cleanup old channel items. + std::cerr << "RsSshd::doRpcSystem() Finished"; std::cerr << std::endl; From 08904bf82f0626f4445dc5bd0da3f9ee766d86e3 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Tue, 4 Sep 2012 22:32:52 +0000 Subject: [PATCH 051/222] Improved token service interface with more obvious request calls (grpIds and msgIds list being empty is not implicit of retrieving all ids) Updated GXS tests and applied fixes started transfering flags to gxs flags header file git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5513 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsdataservice.h | 1 + libretroshare/src/gxs/rsgds.h | 2 +- libretroshare/src/gxs/rsgenexchange.cc | 1 + libretroshare/src/gxs/rsgxs.h | 1 + libretroshare/src/gxs/rsgxsdataaccess.cc | 190 ++++++++++++++---- libretroshare/src/gxs/rsgxsdataaccess.h | 43 ++-- libretroshare/src/gxs/rsgxsflags.h | 31 ++- libretroshare/src/gxs/rsgxsnetservice.cc | 31 ++- libretroshare/src/gxs/rsgxsnetservice.h | 56 +++--- libretroshare/src/gxs/rstokenservice.h | 25 ++- libretroshare/src/rsserver/rsinit.cc | 2 + .../src/tests/gxs/genexchangetester.cpp | 10 +- libretroshare/src/tests/gxs/nxsnet_test.pro | 92 +++++++++ .../src/tests/gxs/rsdataservice_test.cc | 14 +- libretroshare/src/tests/gxs/rsdummyservices.h | 2 +- 15 files changed, 387 insertions(+), 114 deletions(-) create mode 100644 libretroshare/src/tests/gxs/nxsnet_test.pro diff --git a/libretroshare/src/gxs/rsdataservice.h b/libretroshare/src/gxs/rsdataservice.h index 8af15dc4e..3ef293c95 100644 --- a/libretroshare/src/gxs/rsdataservice.h +++ b/libretroshare/src/gxs/rsdataservice.h @@ -29,6 +29,7 @@ #include "gxs/rsgds.h" #include "util/retrodb.h" + class RsDataService : public RsGeneralDataService { public: diff --git a/libretroshare/src/gxs/rsgds.h b/libretroshare/src/gxs/rsgds.h index 1ea61233b..2abf2c982 100644 --- a/libretroshare/src/gxs/rsgds.h +++ b/libretroshare/src/gxs/rsgds.h @@ -151,7 +151,7 @@ public: * @param cache whether to store retrieval in mem for faster later retrieval * @return error code */ - virtual int retrieveGxsMsgMetaData(GxsMsgReq& grpIds, GxsMsgMetaResult& msgMeta) = 0; + virtual int retrieveGxsMsgMetaData(GxsMsgReq& msgIds, GxsMsgMetaResult& msgMeta) = 0; /*! * remove msgs in data store listed in msgIds param diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index afe021242..ff39da0ff 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -32,6 +32,7 @@ #include "rsgenexchange.h" #include "gxssecurity.h" #include "util/contentvalue.h" +#include "rsgxsflags.h" RsGenExchange::RsGenExchange(RsGeneralDataService *gds, RsNetworkExchangeService *ns, RsSerialType *serviceSerialiser, uint16_t servType) diff --git a/libretroshare/src/gxs/rsgxs.h b/libretroshare/src/gxs/rsgxs.h index 14d3cce77..4bb9a4cdf 100644 --- a/libretroshare/src/gxs/rsgxs.h +++ b/libretroshare/src/gxs/rsgxs.h @@ -32,6 +32,7 @@ #include #include #include +#include /* data types used throughout Gxs from netservice to genexchange */ diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index b00454fd1..6166f23e5 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -65,43 +65,88 @@ RsGxsDataAccess::RsGxsDataAccess(RsGeneralDataService* ds) bool RsGxsDataAccess::requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const std::list &groupIds) { - GxsRequest* req = NULL; - uint32_t reqType = opts.mReqType; + if(groupIds.empty()) + { + std::cerr << "Group Id list is empty" << std::endl; + return false; + } - if(reqType & GXS_REQUEST_TYPE_GROUP_META) - { - GroupMetaReq* gmr = new GroupMetaReq(); - gmr->mGroupIds = groupIds; - req = gmr; - } - else if(reqType & GXS_REQUEST_TYPE_GROUP_DATA) - { - GroupDataReq* gdr = new GroupDataReq(); - gdr->mGroupIds = groupIds; - req = gdr; - } - else if(reqType & GXS_REQUEST_TYPE_GROUP_IDS) - { - GroupIdReq* gir = new GroupIdReq(); - gir->mGroupIds = groupIds; - req = gir; - } + GxsRequest* req = NULL; + uint32_t reqType = opts.mReqType; - if(req == NULL) - { - std::cerr << "RsGxsDataAccess::requestMsgInfo() request type not recognised, type " - << reqType << std::endl; - return false; - }else - { - generateToken(token); - std::cerr << "RsGxsDataAccess::requestMsgInfo() gets Token: " << token << std::endl; - } + if(reqType & GXS_REQUEST_TYPE_GROUP_META) + { + GroupMetaReq* gmr = new GroupMetaReq(); + gmr->mGroupIds = groupIds; + req = gmr; + } + else if(reqType & GXS_REQUEST_TYPE_GROUP_DATA) + { + GroupDataReq* gdr = new GroupDataReq(); + gdr->mGroupIds = groupIds; + req = gdr; + } + else if(reqType & GXS_REQUEST_TYPE_GROUP_IDS) + { + GroupIdReq* gir = new GroupIdReq(); + gir->mGroupIds = groupIds; + req = gir; + } - setReq(req, token, ansType, opts); - storeRequest(req); + if(req == NULL) + { + std::cerr << "RsGxsDataAccess::requestMsgInfo() request type not recognised, type " + << reqType << std::endl; + return false; + }else + { + generateToken(token); + std::cerr << "RsGxsDataAccess::requestMsgInfo() gets Token: " << token << std::endl; + } - return true; + setReq(req, token, ansType, opts); + storeRequest(req); + + return true; +} + +bool RsGxsDataAccess::requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts) +{ + + GxsRequest* req = NULL; + uint32_t reqType = opts.mReqType; + + if(reqType & GXS_REQUEST_TYPE_GROUP_META) + { + GroupMetaReq* gmr = new GroupMetaReq(); + req = gmr; + } + else if(reqType & GXS_REQUEST_TYPE_GROUP_DATA) + { + GroupDataReq* gdr = new GroupDataReq(); + req = gdr; + } + else if(reqType & GXS_REQUEST_TYPE_GROUP_IDS) + { + GroupIdReq* gir = new GroupIdReq(); + req = gir; + } + + if(req == NULL) + { + std::cerr << "RsGxsDataAccess::requestMsgInfo() request type not recognised, type " + << reqType << std::endl; + return false; + }else + { + generateToken(token); + std::cerr << "RsGxsDataAccess::requestMsgInfo() gets Token: " << token << std::endl; + } + + setReq(req, token, ansType, opts); + storeRequest(req); + + return true; } void RsGxsDataAccess::generateToken(uint32_t &token) @@ -121,21 +166,41 @@ bool RsGxsDataAccess::requestMsgInfo(uint32_t &token, uint32_t ansType, GxsRequest* req = NULL; uint32_t reqType = opts.mReqType; + // remove all empty grpId entries + GxsMsgReq::const_iterator mit = msgIds.begin(); + std::vector toRemove; + + for(; mit != msgIds.end(); mit++) + { + if(mit->second.empty()) + toRemove.push_back(mit->first); + } + + std::vector::const_iterator vit = toRemove.begin(); + + GxsMsgReq filteredMsgIds = msgIds; + + for(; vit != toRemove.end(); vit++) + filteredMsgIds.erase(*vit); + if(reqType & GXS_REQUEST_TYPE_MSG_META) { MsgMetaReq* mmr = new MsgMetaReq(); - mmr->mMsgIds = msgIds; + mmr->mMsgIds = filteredMsgIds; req = mmr; + }else if(reqType & GXS_REQUEST_TYPE_MSG_DATA) { MsgDataReq* mdr = new MsgDataReq(); - mdr->mMsgIds = msgIds; + mdr->mMsgIds = filteredMsgIds; req = mdr; + }else if(reqType & GXS_REQUEST_TYPE_MSG_IDS) { MsgIdReq* mir = new MsgIdReq(); - mir->mMsgIds = msgIds; + mir->mMsgIds = filteredMsgIds; req = mir; + } if(req == NULL) @@ -154,8 +219,58 @@ bool RsGxsDataAccess::requestMsgInfo(uint32_t &token, uint32_t ansType, return true; } +bool RsGxsDataAccess::requestMsgInfo(uint32_t &token, uint32_t ansType, + const RsTokReqOptionsV2 &opts, const std::list& grpIds) +{ + GxsRequest* req = NULL; + uint32_t reqType = opts.mReqType; -bool RsGxsDataAccess::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq& msgIds) + std::list::const_iterator lit = grpIds.begin(); + + if(reqType & GXS_REQUEST_TYPE_MSG_META) + { + MsgMetaReq* mmr = new MsgMetaReq(); + + for(; lit != grpIds.end(); lit++) + mmr->mMsgIds[*lit] = std::vector(); + + req = mmr; + }else if(reqType & GXS_REQUEST_TYPE_MSG_DATA) + { + MsgDataReq* mdr = new MsgDataReq(); + + for(; lit != grpIds.end(); lit++) + mdr->mMsgIds[*lit] = std::vector(); + + req = mdr; + }else if(reqType & GXS_REQUEST_TYPE_MSG_IDS) + { + MsgIdReq* mir = new MsgIdReq(); + + for(; lit != grpIds.end(); lit++) + mir->mMsgIds[*lit] = std::vector(); + + req = mir; + } + + if(req == NULL) + { + std::cerr << "RsGxsDataAccess::requestMsgInfo() request type not recognised, type " + << reqType << std::endl; + return false; + }else + { + generateToken(token); + std::cerr << "RsGxsDataAccess::requestMsgInfo() gets Token: " << token << std::endl; + } + + setReq(req, token, ansType, opts); + storeRequest(req); + return true; +} + +bool RsGxsDataAccess::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, + const GxsMsgReq& msgIds) { MsgRelatedInfoReq* req = new MsgRelatedInfoReq(); @@ -166,7 +281,6 @@ bool RsGxsDataAccess::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, c setReq(req, token, ansType, opts); storeRequest(req); - return true; } diff --git a/libretroshare/src/gxs/rsgxsdataaccess.h b/libretroshare/src/gxs/rsgxsdataaccess.h index 94c5d4403..c1261ff55 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.h +++ b/libretroshare/src/gxs/rsgxsdataaccess.h @@ -44,24 +44,43 @@ public: /** S: RsTokenService **/ /*! - * - * @param token - * @param ansType - * @param opts - * @param groupIds + * Use this to request group related information + * @param token The token returned for the request, store this value to pool for request completion + * @param ansType The type of result (e.g. group data, meta, ids) + * @param opts Additional option that affect outcome of request. Please see specific services, for valid values + * @param groupIds group id to request info for * @return */ bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const std::list &groupIds); /*! - * For requesting info on all messages of one or more groups - * @param token - * @param ansType - * @param opts - * @param groupIds + * Use this to request all group related info + * @param token The token returned for the request, store this value to pool for request completion + * @param ansType The type of result (e.g. group data, meta, ids) + * @param opts Additional option that affect outcome of request. Please see specific services, for valid values * @return */ - bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq&); + bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts); + + /*! + * Use this to get msg related information, store this value to pole for request completion + * @param token The token returned for the request + * @param ansType The type of result wanted + * @param opts Additional option that affect outcome of request. Please see specific services, for valid values + * @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs + * @return true if request successful false otherwise + */ + bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq& msgIds); + + /*! + * Use this to get msg related information, store this value to pole for request completion + * @param token The token returned for the request + * @param ansType The type of result wanted + * @param opts Additional option that affect outcome of request. Please see specific services, for valid values + * @param groupIds The ids of the groups to get, this retrieve all the msgs info for each grpId in list + * @return true if request successful false otherwise + */ + bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const std::list& grpIds); /*! * For requesting msgs related to a given msg id within a group @@ -71,7 +90,7 @@ public: * @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs * @return true if request successful false otherwise */ - bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq&); + bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq& msgIds); /* Poll */ uint32_t requestStatus(const uint32_t token); diff --git a/libretroshare/src/gxs/rsgxsflags.h b/libretroshare/src/gxs/rsgxsflags.h index c85d7a033..d124bde5f 100644 --- a/libretroshare/src/gxs/rsgxsflags.h +++ b/libretroshare/src/gxs/rsgxsflags.h @@ -3,6 +3,8 @@ #include "inttypes.h" +// this serves a single point of call for definining grp and msg modes +// GXS. These modes say namespace GXS_SERV { @@ -10,30 +12,30 @@ namespace GXS_SERV { /* type of group */ - static const uint32_t FLAG_GRP_TYPE_MASK; + static const uint32_t FLAG_GRP_TYPE_MASK = 0; // pub key encrypted - static const uint32_t FLAG_GRP_TYPE_PRIVATE; + static const uint32_t FLAG_GRP_TYPE_PRIVATE = 0; // single publisher, read only - static const uint32_t FLAG_GRP_TYPE_RESTRICTED; + static const uint32_t FLAG_GRP_TYPE_RESTRICTED = 0; // anyone can publish - static const uint32_t FLAG_GRP_TYPE_PUBLIC; + static const uint32_t FLAG_GRP_TYPE_PUBLIC = 0; /* type of msgs allowed */ - static const uint32_t FLAG_MSG_TYPE_MASK; + static const uint32_t FLAG_MSG_TYPE_MASK = 0; // only signee can edit, and sign required - static const uint32_t FLAG_MSG_TYPE_SIGNED; + static const uint32_t FLAG_MSG_TYPE_SIGNED = 0; // no sign required, but signee can edit if signed - static const uint32_t FLAG_MSG_TYPE_ANON; + static const uint32_t FLAG_MSG_TYPE_ANON = 0; // anyone can mod but sign must be provided (needed for wikis) - static const uint32_t FLAG_MSG_TYPE_SIGNED_SHARED; + static const uint32_t FLAG_MSG_TYPE_SIGNED_SHARED = 0; /*** GROUP FLAGS ***/ @@ -42,13 +44,22 @@ namespace GXS_SERV { /*** MESSAGE FLAGS ***/ // indicates message edits an existing message - static const uint32_t FLAG_MSG_EDIT; + static const uint32_t FLAG_MSG_EDIT = 0; // indicates msg is id signed - static const uint32_t FLAG_MSG_ID_SIGNED; + static const uint32_t FLAG_MSG_ID_SIGNED = 0; /*** MESSAGE FLAGS ***/ + + // Subscription Flags. (LOCAL) + + static const uint32_t RSGXS_GROUP_SUBSCRIBE_ADMIN = 0x00000001; + static const uint32_t RSGXS_GROUP_SUBSCRIBE_PUBLISH = 0x00000002; + static const uint32_t RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED = 0x00000004; + static const uint32_t RSGXS_GROUP_SUBSCRIBE_MONITOR = 0x00000008; + static const uint32_t RSGXS_GROUP_SUBSCRIBE_MASK = 0x0000000f; + } diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 5becd34ec..875f42b48 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -25,6 +25,7 @@ */ #include "rsgxsnetservice.h" +#include "rsgxsflags.h" #define NXS_NET_DEBUG @@ -85,24 +86,40 @@ void RsGxsNetService::syncWithPeers() sendItem(grp); } + std::map grpMeta; + mDataStore->retrieveGxsGrpMetaData(grpMeta); + + std::map::iterator + mit = grpMeta.begin(); + + std::vector grpIds; + + for(; mit != grpMeta.end(); mit++) + { + RsGxsGrpMetaData* meta = mit->second; + + if(meta->mSubscribeFlags & GXS_SERV::RSGXS_GROUP_SUBSCRIBE_MASK) + grpIds.push_back(mit->first); + } + sit = peers.begin(); + // TODO msgs for(; sit != peers.end(); sit++) { RsStackMutex stack(mNxsMutex); - std::set::iterator sit_grp = mGroupSubscribedTo.begin(); + std::vector::iterator vit = grpIds.begin(); - for(; sit_grp != mGroupSubscribedTo.end(); sit_grp++) + for(; vit != grpIds.end(); vit++) { RsNxsSyncMsg* msg = new RsNxsSyncMsg(mServType); msg->clear(); - msg->PeerId(*sit); - msg->grpId = *sit_grp; + msg->PeerId(*sit); + msg->grpId = *vit; sendItem(msg); } } - } bool RsGxsNetService::loadList(std::list& load) @@ -600,10 +617,6 @@ void RsGxsNetService::locked_processCompletedIncomingTrans(NxsTransaction* tr) { tr->mItems.pop_front(); grps.push_back(grp); - - //TODO: remove subscription should be handled - // outside netservice - mGroupSubscribedTo.insert(grp->grpId); } else { diff --git a/libretroshare/src/gxs/rsgxsnetservice.h b/libretroshare/src/gxs/rsgxsnetservice.h index 096e5c8c7..fc1f9bf38 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.h +++ b/libretroshare/src/gxs/rsgxsnetservice.h @@ -290,44 +290,44 @@ private: * of msgs received from peer stored in passed transaction * @param tr transaction responsible for generating msg request */ - void locked_genReqMsgTransaction(NxsTransaction* tr); + void locked_genReqMsgTransaction(NxsTransaction* tr); /*! * Generates new transaction to send grp requests based on list * of grps received from peer stored in passed transaction * @param tr transaction responsible for generating grp request */ - void locked_genReqGrpTransaction(NxsTransaction* tr); + void locked_genReqGrpTransaction(NxsTransaction* tr); - /*! - * Generates new transaction to send msg data based on list - * of grpids received from peer stored in passed transaction - * @param tr transaction responsible for generating grp request - */ - void locked_genSendMsgsTransaction(NxsTransaction* tr); + /*! + * Generates new transaction to send msg data based on list + * of grpids received from peer stored in passed transaction + * @param tr transaction responsible for generating grp request + */ + void locked_genSendMsgsTransaction(NxsTransaction* tr); - /*! - * Generates new transaction to send grp data based on list - * of grps received from peer stored in passed transaction - * @param tr transaction responsible for generating grp request - */ - void locked_genSendGrpsTransaction(NxsTransaction* tr); + /*! + * Generates new transaction to send grp data based on list + * of grps received from peer stored in passed transaction + * @param tr transaction responsible for generating grp request + */ + void locked_genSendGrpsTransaction(NxsTransaction* tr); - /*! - * convenience function to add a transaction to list - * @param tr transaction to add - */ - bool locked_addTransaction(NxsTransaction* tr); + /*! + * convenience function to add a transaction to list + * @param tr transaction to add + */ + bool locked_addTransaction(NxsTransaction* tr); - void cleanTransactionItems(NxsTransaction* tr) const; + void cleanTransactionItems(NxsTransaction* tr) const; - /*! - * @param tr the transaction to check for timeout - * @return false if transaction has timed out, true otherwise - */ - bool locked_checkTransacTimedOut(NxsTransaction* tr); + /*! + * @param tr the transaction to check for timeout + * @return false if transaction has timed out, true otherwise + */ + bool locked_checkTransacTimedOut(NxsTransaction* tr); - /** E: Transaction processing **/ + /** E: Transaction processing **/ /** S: item handlers **/ @@ -395,9 +395,7 @@ private: RsMutex mNxsMutex; uint32_t mSyncTs; - // TODO: remove, temp, for testing. - // subscription handled outside netservice - std::set mGroupSubscribedTo; + const uint32_t mSYNC_PERIOD; }; diff --git a/libretroshare/src/gxs/rstokenservice.h b/libretroshare/src/gxs/rstokenservice.h index d0e562dc6..ec86e3814 100644 --- a/libretroshare/src/gxs/rstokenservice.h +++ b/libretroshare/src/gxs/rstokenservice.h @@ -114,18 +114,27 @@ public: RsTokenServiceV2() { return; } virtual ~RsTokenServiceV2() { return; } - /* Data Requests */ + /* Data Requests */ /*! * Use this to request group related information * @param token The token returned for the request, store this value to pool for request completion * @param ansType The type of result (e.g. group data, meta, ids) * @param opts Additional option that affect outcome of request. Please see specific services, for valid values - * @param groupIds group id to request info for. Leave empty to get info on all groups, + * @param groupIds group id to request info for * @return */ virtual bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const std::list &groupIds) = 0; + /*! + * Use this to request all group related info + * @param token The token returned for the request, store this value to pool for request completion + * @param ansType The type of result (e.g. group data, meta, ids) + * @param opts Additional option that affect outcome of request. Please see specific services, for valid values + * @return + */ + virtual bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts) = 0; + /*! * Use this to get msg related information, store this value to pole for request completion * @param token The token returned for the request @@ -136,6 +145,16 @@ public: */ virtual bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq& msgIds) = 0; + /*! + * Use this to get msg related information, store this value to pole for request completion + * @param token The token returned for the request + * @param ansType The type of result wanted + * @param opts Additional option that affect outcome of request. Please see specific services, for valid values + * @param groupIds The ids of the groups to get, this retrieve all the msgs info for each grpId in list + * @return true if request successful false otherwise + */ + virtual bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const std::list& msgIds) = 0; + /*! * For requesting msgs related to a given msg id within a group * @param token The token returned for the request @@ -147,7 +166,7 @@ public: virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq& msgIds) = 0; - /* Poll */ + /* Poll */ /*! * Request the status of ongoing request. diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index ebc9241bb..c708eb0de 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -2274,6 +2274,8 @@ int RsServer::StartupRetroShare() RsGeneralDataService* photo_ds = new RsDataService("./", "photoV2_db", RS_SERVICE_TYPE_PHOTO, NULL); + photo_ds->resetDataStore(); + // TODO need net manager //RsGxsNetService* photo_ns = new RsGxsNetService( // RS_SERVICE_TYPE_PHOTO, photo_ds, NULL, mPhotoV2); diff --git a/libretroshare/src/tests/gxs/genexchangetester.cpp b/libretroshare/src/tests/gxs/genexchangetester.cpp index 4434a4ab8..5f41f2022 100644 --- a/libretroshare/src/tests/gxs/genexchangetester.cpp +++ b/libretroshare/src/tests/gxs/genexchangetester.cpp @@ -175,7 +175,7 @@ bool GenExchangeTester::testGrpSubmissionRetrieval() opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; std::list grpIds; - mTokenService->requestGroupInfo(token, 0, opts, grpIds); + mTokenService->requestGroupInfo(token, 0, opts); pollForToken(token, opts); @@ -272,7 +272,7 @@ bool GenExchangeTester::testGrpMetaRetrieval() opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; std::list grpIds; - mTokenService->requestGroupInfo(token, 0, opts, grpIds); + mTokenService->requestGroupInfo(token, 0, opts); pollForToken(token, opts); @@ -319,7 +319,7 @@ bool GenExchangeTester::testGrpIdRetrieval() opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; uint32_t token; std::list grpIds; - mTokenService->requestGroupInfo(token, 0, opts, grpIds); + mTokenService->requestGroupInfo(token, 0, opts); pollForToken(token, opts); @@ -676,13 +676,13 @@ bool GenExchangeTester::testMsgIdRetrieval() // now do ask of all msg ids - GxsMsgReq req; + std::list req; opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; // use empty grp ids request types, non specific msgs ids for(int i=0; i < mRandGrpIds.size(); i++) { - req[mRandGrpIds[i]] = std::vector(); + req.push_back(mRandGrpIds[i]); } mTokenService->requestMsgInfo(token, 0, opts, req); diff --git a/libretroshare/src/tests/gxs/nxsnet_test.pro b/libretroshare/src/tests/gxs/nxsnet_test.pro new file mode 100644 index 000000000..054938374 --- /dev/null +++ b/libretroshare/src/tests/gxs/nxsnet_test.pro @@ -0,0 +1,92 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2012-05-06T09:19:26 +# +#------------------------------------------------- + +QT += core network + +QT -= gui + +TARGET = rs_test +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +CONFIG += debug + +debug { +# DEFINES *= DEBUG +# DEFINES *= OPENDHT_DEBUG DHT_DEBUG CONN_DEBUG DEBUG_UDP_SORTER P3DISC_DEBUG DEBUG_UDP_LAYER FT_DEBUG EXTADDRSEARCH_DEBUG +# DEFINES *= CONTROL_DEBUG FT_DEBUG DEBUG_FTCHUNK P3TURTLE_DEBUG +# DEFINES *= P3TURTLE_DEBUG +# DEFINES *= NET_DEBUG +# DEFINES *= DISTRIB_DEBUG +# DEFINES *= P3TURTLE_DEBUG FT_DEBUG DEBUG_FTCHUNK MPLEX_DEBUG +# DEFINES *= STATUS_DEBUG SERV_DEBUG RSSERIAL_DEBUG #CONN_DEBUG + + QMAKE_CXXFLAGS -= -O2 -fomit-frame-pointer + QMAKE_CXXFLAGS *= -g -fno-omit-frame-pointer +} +################################# Linux ########################################## +# Put lib dir in QMAKE_LFLAGS so it appears before -L/usr/lib +linux-* { + #CONFIG += version_detail_bash_script + QMAKE_CXXFLAGS *= -D_FILE_OFFSET_BITS=64 + + system(which gpgme-config >/dev/null 2>&1) { + INCLUDEPATH += $$system(gpgme-config --cflags | sed -e "s/-I//g") + } else { + message(Could not find gpgme-config on your system, assuming gpgme.h is in /usr/include) + } + + PRE_TARGETDEPS *= /home/crispy/workspace/v0.5-gxs-b1/libretroshare/src/lib/libretroshare.a + + LIBS += /home/crispy/workspace/v0.5-gxs-b1/libretroshare/src/lib/libretroshare.a + LIBS += /home/crispy/workspace/v0.5-gxs-b1/libbitdht/src/lib/libbitdht.a + LIBS += /home/crispy/workspace/v0.5-gxs-b1/openpgpsdk/src/lib/libops.a + LIBS += -lssl -lgpgme -lupnp -lixml -lgnome-keyring -lsqlite3 -lbz2 + LIBS *= -rdynamic -frtti + DEFINES *= HAVE_XSS # for idle time, libx screensaver extensions + DEFINES *= UBUNTU +} + +linux-g++ { + OBJECTS_DIR = temp/linux-g++/obj +} + +linux-g++-64 { + OBJECTS_DIR = temp/linux-g++-64/obj +} + +version_detail_bash_script { + DEFINES += ADD_LIBRETROSHARE_VERSION_INFO + QMAKE_EXTRA_TARGETS += write_version_detail + PRE_TARGETDEPS = write_version_detail + write_version_detail.commands = ./version_detail.sh +} + +install_rs { + INSTALLS += binary_rs + binary_rs.path = $$(PREFIX)/usr/bin + binary_rs.files = ./RetroShare +} + + +SOURCES += \ + /home/crispy/workspace/v0.5-gxs-b1/libretroshare/src/tests/gxs/data_support.cc \ + /home/crispy/workspace/v0.5-gxs-b1/libretroshare/src/tests/gxs/nxstesthub.cc \ + /home/crispy/workspace/v0.5-gxs-b1/libretroshare/src/tests/gxs/nxstestscenario.cc \ + /home/crispy/workspace/v0.5-gxs-b1/libretroshare/src/tests/gxs/rsgxsnetservice_test.cc \ + /home/crispy/workspace/v0.5-gxs-b1/libretroshare/src/tests/gxs/support.cc + + +HEADERS += \ + /home/crispy/workspace/v0.5-gxs-b1/libretroshare/src/tests/gxs/data_support.h \ + /home/crispy/workspace/v0.5-gxs-b1/libretroshare/src/tests/gxs/nxstesthub.h \ + /home/crispy/workspace/v0.5-gxs-b1/libretroshare/src/tests/gxs/nxstestscenario.h \ + /home/crispy/workspace/v0.5-gxs-b1/libretroshare/src/tests/gxs/support.h + +INCLUDEPATH += /home/crispy/workspace/v0.5-gxs-b1/libretroshare/src + diff --git a/libretroshare/src/tests/gxs/rsdataservice_test.cc b/libretroshare/src/tests/gxs/rsdataservice_test.cc index 790a265c2..af5155773 100644 --- a/libretroshare/src/tests/gxs/rsdataservice_test.cc +++ b/libretroshare/src/tests/gxs/rsdataservice_test.cc @@ -2,6 +2,7 @@ #include "support.h" #include "data_support.h" #include "rsdataservice_test.h" +#include "gxs/rsgds.h" #include "gxs/rsdataservice.h" #define DATA_BASE_NAME "msg_grp_Store" @@ -57,9 +58,9 @@ void test_groupStoreAndRetrieve(){ dStore->storeGroup(grps); - std::map gR; - std::map grpMetaR; - dStore->retrieveNxsGrps(gR, false); + std::map gR; + std::map grpMetaR; + dStore->retrieveNxsGrps(gR, false, false); dStore->retrieveGxsGrpMetaData(grpMetaR); std::map::iterator mit = grps.begin(); @@ -164,7 +165,7 @@ void test_messageStoresAndRetrieve() const std::string& grpId = grpV[chosen]; if(chosen) - req[grpId].insert(msg->msgId); + req[grpId].push_back(msg->msgId); msgMeta->mMsgId = msg->msgId; msgMeta->mGroupId = msg->grpId = grpId; @@ -189,7 +190,7 @@ void test_messageStoresAndRetrieve() msgs.insert(p); } - req[grpV[0]] = std::set(); // assign empty list for other + req[grpV[0]] = std::vector(); // assign empty list for other dStore->storeMessage(msgs); @@ -199,7 +200,8 @@ void test_messageStoresAndRetrieve() GxsMsgResult msgResult; GxsMsgMetaResult msgMetaResult; dStore->retrieveNxsMsgs(req, msgResult, false); - dStore->retrieveGxsMsgMetaData(grpV, msgMetaResult); + + dStore->retrieveGxsMsgMetaData(req, msgMetaResult); // now look at result for grpId 1 std::vector& result0 = msgResult[grpId0]; diff --git a/libretroshare/src/tests/gxs/rsdummyservices.h b/libretroshare/src/tests/gxs/rsdummyservices.h index 854c6b4c8..e727b9767 100644 --- a/libretroshare/src/tests/gxs/rsdummyservices.h +++ b/libretroshare/src/tests/gxs/rsdummyservices.h @@ -69,7 +69,7 @@ public: RsDummySerialiser() - :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_DUMMY) + : RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_DUMMY) { return; } virtual ~RsDummySerialiser() { return; } From c7ed9c6df72dbea9ae132b0c482ced8eb140c8c8 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Tue, 4 Sep 2012 23:53:04 +0000 Subject: [PATCH 052/222] FeedReader plugin - reserved service id - reworked error codes - added xpath manipulation and basic gui elements in preview dialog git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5514 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/serialiser/rsserviceids.h | 1 + plugins/FeedReader/FeedReader.pro | 6 +- plugins/FeedReader/FeedReaderPlugin.h | 3 +- plugins/FeedReader/gui/AddFeedDialog.cpp | 37 +- plugins/FeedReader/gui/AddFeedDialog.h | 4 + .../FeedReader/gui/FeedReaderStringDefs.cpp | 52 +- plugins/FeedReader/gui/FeedReaderStringDefs.h | 1 + plugins/FeedReader/gui/PreviewFeedDialog.cpp | 447 +++++++++++++-- plugins/FeedReader/gui/PreviewFeedDialog.h | 21 +- plugins/FeedReader/gui/PreviewFeedDialog.ui | 417 ++++++++++---- plugins/FeedReader/interface/rsFeedReader.h | 34 +- plugins/FeedReader/services/p3FeedReader.cc | 154 +++--- plugins/FeedReader/services/p3FeedReader.h | 17 +- .../FeedReader/services/p3FeedReaderThread.cc | 509 ++++++++++++++---- .../FeedReader/services/p3FeedReaderThread.h | 27 +- .../FeedReader/services/rsFeedReaderItems.cc | 37 +- .../FeedReader/services/rsFeedReaderItems.h | 10 +- plugins/FeedReader/util/HTMLWrapper.cpp | 17 +- plugins/FeedReader/util/HTMLWrapper.h | 4 + plugins/FeedReader/util/XMLWrapper.cpp | 58 +- plugins/FeedReader/util/XMLWrapper.h | 16 +- plugins/FeedReader/util/XPathWrapper.cpp | 102 ++++ plugins/FeedReader/util/XPathWrapper.h | 51 ++ 23 files changed, 1595 insertions(+), 430 deletions(-) create mode 100644 plugins/FeedReader/util/XPathWrapper.cpp create mode 100644 plugins/FeedReader/util/XPathWrapper.h diff --git a/libretroshare/src/serialiser/rsserviceids.h b/libretroshare/src/serialiser/rsserviceids.h index f5cbf16ab..c6cdd6870 100644 --- a/libretroshare/src/serialiser/rsserviceids.h +++ b/libretroshare/src/serialiser/rsserviceids.h @@ -65,6 +65,7 @@ const uint16_t RS_SERVICE_TYPE_STATUS = 0xf020; const uint16_t RS_SERVICE_TYPE_PLUGIN_ARADO_ID = 0x0401; const uint16_t RS_SERVICE_TYPE_PLUGIN_QCHESS_ID = 0x0402; +const uint16_t RS_SERVICE_TYPE_PLUGIN_FEEDREADER = 0x0403; /****************** BELOW ARE ONLY THEORETICAL (CAN BE CHANGED) *****/ diff --git a/plugins/FeedReader/FeedReader.pro b/plugins/FeedReader/FeedReader.pro index 3974acbae..450ea6d66 100644 --- a/plugins/FeedReader/FeedReader.pro +++ b/plugins/FeedReader/FeedReader.pro @@ -14,7 +14,8 @@ SOURCES = FeedReaderPlugin.cpp \ gui/FeedReaderStringDefs.cpp \ util/CURLWrapper.cpp \ util/XMLWrapper.cpp \ - util/HTMLWrapper.cpp + util/HTMLWrapper.cpp \ + util/XPathWrapper.cpp HEADERS = FeedReaderPlugin.h \ interface/rsFeedReader.h \ @@ -29,7 +30,8 @@ HEADERS = FeedReaderPlugin.h \ gui/FeedReaderStringDefs.h \ util/CURLWrapper.h \ util/XMLWrapper.h \ - util/HTMLWrapper.h + util/HTMLWrapper.h \ + util/XPathWrapper.h FORMS = gui/FeedReaderDialog.ui \ gui/AddFeedDialog.ui \ diff --git a/plugins/FeedReader/FeedReaderPlugin.h b/plugins/FeedReader/FeedReaderPlugin.h index dffcfa7b4..2c4fd5d81 100644 --- a/plugins/FeedReader/FeedReaderPlugin.h +++ b/plugins/FeedReader/FeedReaderPlugin.h @@ -21,6 +21,7 @@ #pragma once +#include #include #include #include "services/p3FeedReader.h" @@ -33,7 +34,7 @@ class FeedReaderPlugin: public RsPlugin public: FeedReaderPlugin(); - virtual uint16_t rs_service_id() const { return RS_PKT_TYPE_FEEDREADER_CONFIG; } + virtual uint16_t rs_service_id() const { return RS_SERVICE_TYPE_PLUGIN_FEEDREADER; } virtual RsPQIService *rs_pqi_service() const; virtual void stop(); diff --git a/plugins/FeedReader/gui/AddFeedDialog.cpp b/plugins/FeedReader/gui/AddFeedDialog.cpp index f4f4064b1..fcfb3c947 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.cpp +++ b/plugins/FeedReader/gui/AddFeedDialog.cpp @@ -27,6 +27,7 @@ #include "ui_AddFeedDialog.h" #include "PreviewFeedDialog.h" #include "FeedReaderStringDefs.h" +#include "gui/settings/rsharesettings.h" #include "retroshare/rsforums.h" @@ -36,7 +37,7 @@ bool sortForumInfo(const ForumInfo& info1, const ForumInfo& info2) } AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, QWidget *parent) - : QDialog(parent), mFeedReader(feedReader), mNotify(notify), ui(new Ui::AddFeedDialog) + : QDialog(parent, Qt::Window), mFeedReader(feedReader), mNotify(notify), ui(new Ui::AddFeedDialog) { ui->setupUi(this); @@ -93,13 +94,37 @@ AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, validate(); ui->urlLineEdit->setFocus(); + + /* load settings */ + processSettings(true); } AddFeedDialog::~AddFeedDialog() { + /* save settings */ + processSettings(false); + delete ui; } +void AddFeedDialog::processSettings(bool load) +{ + Settings->beginGroup(QString("AddFeedDialog")); + + if (load) { + // load settings + QByteArray geometry = Settings->value("Geometry").toByteArray(); + if (!geometry.isEmpty()) { + restoreGeometry(geometry); + } + } else { + // save settings + Settings->setValue("Geometry", saveGeometry()); + } + + Settings->endGroup(); +} + void AddFeedDialog::authenticationToggled() { bool checked = ui->useAuthenticationCheckBox->isChecked(); @@ -234,6 +259,9 @@ bool AddFeedDialog::fillFeed(const std::string &feedId) ui->useStandardStorageTimeCheckBox->setChecked(feedInfo.flag.standardStorageTime); ui->storageTimeSpinBox->setValue(feedInfo.storageTime / (60 * 60 *24)); + + mXPathsToUse = feedInfo.xpathsToUse; + mXPathsToRemove = feedInfo.xpathsToRemove; } return true; @@ -274,6 +302,9 @@ void AddFeedDialog::getFeedInfo(FeedInfo &feedInfo) feedInfo.flag.standardStorageTime = ui->useStandardStorageTimeCheckBox->isChecked(); feedInfo.storageTime = ui->storageTimeSpinBox->value() * 60 *60 * 24; + + feedInfo.xpathsToUse = mXPathsToUse; + feedInfo.xpathsToRemove = mXPathsToRemove; } void AddFeedDialog::createFeed() @@ -310,5 +341,7 @@ void AddFeedDialog::preview() getFeedInfo(feedInfo); PreviewFeedDialog dialog(mFeedReader, mNotify, feedInfo, this); - dialog.exec(); + if (dialog.exec() == QDialog::Accepted) { + dialog.getXPaths(mXPathsToUse, mXPathsToRemove); + } } diff --git a/plugins/FeedReader/gui/AddFeedDialog.h b/plugins/FeedReader/gui/AddFeedDialog.h index 92841c93b..44066c522 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.h +++ b/plugins/FeedReader/gui/AddFeedDialog.h @@ -55,6 +55,7 @@ private slots: void preview(); private: + void processSettings(bool load); void getFeedInfo(FeedInfo &feedInfo); RsFeedReader *mFeedReader; @@ -62,6 +63,9 @@ private: std::string mFeedId; std::string mParentId; + std::list mXPathsToUse; + std::list mXPathsToRemove; + Ui::AddFeedDialog *ui; }; diff --git a/plugins/FeedReader/gui/FeedReaderStringDefs.cpp b/plugins/FeedReader/gui/FeedReaderStringDefs.cpp index 37dc1dc78..d7cd8d502 100644 --- a/plugins/FeedReader/gui/FeedReaderStringDefs.cpp +++ b/plugins/FeedReader/gui/FeedReaderStringDefs.cpp @@ -76,55 +76,73 @@ QString FeedReaderStringDefs::workState(FeedInfo::WorkState state) QString FeedReaderStringDefs::errorString(const FeedInfo &feedInfo) { - QString errorState; - switch (feedInfo.errorState) { + return errorString(feedInfo.errorState, feedInfo.errorString); +} + +QString FeedReaderStringDefs::errorString(RsFeedReaderErrorState errorState, const std::string &errorString) +{ + QString errorText; + switch (errorState) { case RS_FEED_ERRORSTATE_OK: break; /* download */ case RS_FEED_ERRORSTATE_DOWNLOAD_INTERNAL_ERROR: - errorState = QApplication::translate("FeedReaderStringDefs", "Internal download error"); + errorText = QApplication::translate("FeedReaderStringDefs", "Internal download error"); break; case RS_FEED_ERRORSTATE_DOWNLOAD_ERROR: - errorState = QApplication::translate("FeedReaderStringDefs", "Download error"); + errorText = QApplication::translate("FeedReaderStringDefs", "Download error"); break; case RS_FEED_ERRORSTATE_DOWNLOAD_UNKNOWN_CONTENT_TYPE: - errorState = QApplication::translate("FeedReaderStringDefs", "Unknown content type"); + errorText = QApplication::translate("FeedReaderStringDefs", "Unknown content type"); break; case RS_FEED_ERRORSTATE_DOWNLOAD_NOT_FOUND: - errorState = QApplication::translate("FeedReaderStringDefs", "Download not found"); + errorText = QApplication::translate("FeedReaderStringDefs", "Download not found"); break; case RS_FEED_ERRORSTATE_DOWNLOAD_UNKOWN_RESPONSE_CODE: - errorState = QApplication::translate("FeedReaderStringDefs", "Unknown response code"); + errorText = QApplication::translate("FeedReaderStringDefs", "Unknown response code"); break; /* process */ case RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR: - errorState = QApplication::translate("FeedReaderStringDefs", "Internal process error"); + errorText = QApplication::translate("FeedReaderStringDefs", "Internal process error"); break; case RS_FEED_ERRORSTATE_PROCESS_UNKNOWN_FORMAT: - errorState = QApplication::translate("FeedReaderStringDefs", "Unknown XML format"); + errorText = QApplication::translate("FeedReaderStringDefs", "Unknown XML format"); break; case RS_FEED_ERRORSTATE_PROCESS_FORUM_CREATE: - errorState = QApplication::translate("FeedReaderStringDefs", "Can't create forum"); + errorText = QApplication::translate("FeedReaderStringDefs", "Can't create forum"); break; case RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_FOUND: - errorState = QApplication::translate("FeedReaderStringDefs", "Forum not found"); + errorText = QApplication::translate("FeedReaderStringDefs", "Forum not found"); break; case RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_ADMIN: - errorState = QApplication::translate("FeedReaderStringDefs", "You are not admin of the forum"); + errorText = QApplication::translate("FeedReaderStringDefs", "You are not admin of the forum"); break; case RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_ANONYMOUS: - errorState = QApplication::translate("FeedReaderStringDefs", "The forum is no anonymous forum"); + errorText = QApplication::translate("FeedReaderStringDefs", "The forum is no anonymous forum"); + break; + + case RS_FEED_ERRORSTATE_PROCESS_HTML_ERROR: + errorText = QApplication::translate("FeedReaderStringDefs", "Can't read html"); + break; + case RS_FEED_ERRORSTATE_PROCESS_XPATH_INTERNAL_ERROR: + errorText = QApplication::translate("FeedReaderStringDefs", "Internal XPath error"); + break; + case RS_FEED_ERRORSTATE_PROCESS_XPATH_WRONG_EXPRESSION: + errorText = QApplication::translate("FeedReaderStringDefs", "Wrong XPath expression"); + break; + case RS_FEED_ERRORSTATE_PROCESS_XPATH_NO_RESULT: + errorText = QApplication::translate("FeedReaderStringDefs", "Empty XPath result"); break; default: - errorState = QApplication::translate("FeedReaderStringDefs", "Unknown error"); + errorText = QApplication::translate("FeedReaderStringDefs", "Unknown error"); } - if (!feedInfo.errorString.empty()) { - errorState += QString(" (%1)").arg(QString::fromUtf8(feedInfo.errorString.c_str())); + if (!errorString.empty()) { + errorText += QString(" (%1)").arg(QString::fromUtf8(errorString.c_str())); } - return errorState; + return errorText; } diff --git a/plugins/FeedReader/gui/FeedReaderStringDefs.h b/plugins/FeedReader/gui/FeedReaderStringDefs.h index d94103cfc..13f9afa30 100644 --- a/plugins/FeedReader/gui/FeedReaderStringDefs.h +++ b/plugins/FeedReader/gui/FeedReaderStringDefs.h @@ -34,6 +34,7 @@ public: static bool showError(QWidget *parent, RsFeedAddResult result, const QString &title, const QString &text); static QString workState(FeedInfo::WorkState state); static QString errorString(const FeedInfo &feedInfo); + static QString errorString(RsFeedReaderErrorState errorState, const std::string &errorString); }; #endif diff --git a/plugins/FeedReader/gui/PreviewFeedDialog.cpp b/plugins/FeedReader/gui/PreviewFeedDialog.cpp index 76bd2c7da..947057798 100644 --- a/plugins/FeedReader/gui/PreviewFeedDialog.cpp +++ b/plugins/FeedReader/gui/PreviewFeedDialog.cpp @@ -19,13 +19,16 @@ * Boston, MA 02110-1301, USA. ****************************************************************/ -#include +//#include +#include +#include #include "PreviewFeedDialog.h" #include "ui_PreviewFeedDialog.h" #include "FeedReaderNotify.h" #include "FeedReaderStringDefs.h" #include "util/HandleRichText.h" +#include "gui/settings/rsharesettings.h" #include "interface/rsFeedReader.h" #include "retroshare/rsiface.h" @@ -138,33 +141,67 @@ //} PreviewFeedDialog::PreviewFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, const FeedInfo &feedInfo, QWidget *parent) : - QDialog(parent), mFeedReader(feedReader), mNotify(notify), ui(new Ui::PreviewFeedDialog) + QDialog(parent, Qt::Window), mFeedReader(feedReader), mNotify(notify), ui(new Ui::PreviewFeedDialog) { ui->setupUi(this); ui->feedNameLabel->clear(); - ui->feedInfoLabel->clear(); + ui->useXPathCheckBox->setChecked(true); /* connect signals */ connect(ui->previousPushButton, SIGNAL(clicked()), this, SLOT(previousMsg())); connect(ui->nextPushButton, SIGNAL(clicked()), this, SLOT(nextMsg())); - connect(ui->documentButton, SIGNAL(toggled(bool)), this, SLOT(showDocumentFrame(bool))); + connect(ui->closeStructureButton, SIGNAL(clicked()), this, SLOT(showStructureFrame())); + connect(ui->structureButton, SIGNAL(toggled(bool)), this, SLOT(showStructureFrame(bool))); + connect(ui->xpathPushButton, SIGNAL(toggled(bool)), this, SLOT(showXPathFrame(bool))); + connect(ui->useXPathCheckBox, SIGNAL(toggled(bool)), this, SLOT(fillStructureTree())); + connect(ui->xpathUseListWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(xpathListCustomPopupMenu(QPoint))); + connect(ui->xpathRemoveListWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(xpathListCustomPopupMenu(QPoint))); + connect(ui->xpathUseListWidget->itemDelegate(), SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)), this, SLOT(xpathCloseEditor(QWidget*,QAbstractItemDelegate::EndEditHint))); + connect(ui->xpathRemoveListWidget->itemDelegate(), SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)), this, SLOT(xpathCloseEditor(QWidget*,QAbstractItemDelegate::EndEditHint))); connect(mNotify, SIGNAL(notifyFeedChanged(QString,int)), this, SLOT(feedChanged(QString,int))); connect(mNotify, SIGNAL(notifyMsgChanged(QString,QString,int)), this, SLOT(msgChanged(QString,QString,int))); // ui->documentTreeWidget->setItemDelegate(new PreviewItemDelegate(ui->documentTreeWidget)); - showDocumentFrame(false); + ui->structureFrame->hide(); - if (!mFeedReader->addPreviewFeed(feedInfo, mFeedId)) { - setInfo(tr("Cannot create preview")); + if (mFeedReader->addPreviewFeed(feedInfo, mFeedId)) { + setFeedInfo(""); + } else { + setFeedInfo(tr("Cannot create preview")); + } + setXPathInfo(""); + showXPathFrame(true); + + /* fill xpath expressions */ + QListWidgetItem *item; + std::string xpath; + foreach(xpath, feedInfo.xpathsToUse){ + item = new QListWidgetItem(QString::fromUtf8(xpath.c_str())); + item->setFlags(item->flags() | Qt::ItemIsEditable); + ui->xpathUseListWidget->addItem(item); + } + foreach(xpath, feedInfo.xpathsToRemove){ + item = new QListWidgetItem(QString::fromUtf8(xpath.c_str())); + item->setFlags(item->flags() | Qt::ItemIsEditable); + ui->xpathRemoveListWidget->addItem(item); } updateMsgCount(); + + ui->xpathUseListWidget->installEventFilter(this); + ui->xpathRemoveListWidget->installEventFilter(this); + + /* load settings */ + processSettings(true); } PreviewFeedDialog::~PreviewFeedDialog() { + /* save settings */ + processSettings(false); + disconnect(mNotify); disconnect(mNotify); @@ -175,6 +212,51 @@ PreviewFeedDialog::~PreviewFeedDialog() delete ui; } +void PreviewFeedDialog::processSettings(bool load) +{ + Settings->beginGroup(QString("PreviewFeedDialog")); + + if (load) { + // load settings + QByteArray geometry = Settings->value("Geometry").toByteArray(); + if (!geometry.isEmpty()) { + restoreGeometry(geometry); + } + } else { + // save settings + Settings->setValue("Geometry", saveGeometry()); + } + + Settings->endGroup(); +} + +bool PreviewFeedDialog::eventFilter(QObject *obj, QEvent *event) +{ + long todo_here; + + if (event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(event); + if (keyEvent) { + if (keyEvent->key() == Qt::Key_Delete) { + /* Delete pressed */ + if (obj == ui->xpathUseListWidget || obj == ui->xpathRemoveListWidget) { + QListWidget *listWidget = dynamic_cast(obj); + if (listWidget) { + QListWidgetItem *item = listWidget->currentItem(); + if (item) { + delete(item); + processXPath(); + } + return true; // eat event + } + } + } + } + } + /* pass the event on to the parent class */ + return QDialog::eventFilter(obj, event); +} + void PreviewFeedDialog::feedChanged(const QString &feedId, int type) { if (feedId.isEmpty()) { @@ -251,22 +333,139 @@ void PreviewFeedDialog::msgChanged(const QString &feedId, const QString &msgId, updateMsgCount(); } -void PreviewFeedDialog::showDocumentFrame(bool show) +void PreviewFeedDialog::showStructureFrame(bool show) { - ui->documentFrame->setVisible(show); - ui->documentButton->setChecked(show); + ui->structureButton->setChecked(show); + ui->structureFrame->setVisible(show); if (show) { - ui->documentButton->setToolTip(tr("Hide tree")); - ui->documentButton->setIcon(QIcon(":images/hide_toolbox_frame.png")); - - fillDocumentTree(); - } else { - ui->documentButton->setToolTip(tr("Show tree")); - ui->documentButton->setIcon(QIcon(":images/show_toolbox_frame.png")); + fillStructureTree(); } } +void PreviewFeedDialog::showXPathFrame(bool show) +{ + ui->xpathFrame->setVisible(show); + + if (show) { + ui->xpathPushButton->setToolTip(tr("Hide XPath expressions")); + ui->xpathPushButton->setIcon(QIcon(":images/show_toolbox_frame.png")); + } else { + ui->xpathPushButton->setToolTip(tr("Show XPath expressions")); + ui->xpathPushButton->setIcon(QIcon(":images/hide_toolbox_frame.png")); + } +} + +void PreviewFeedDialog::xpathListCustomPopupMenu(QPoint /*point*/) +{ + QListWidgetItem *item = NULL; + + if (sender() == ui->xpathUseListWidget) { + item = ui->xpathUseListWidget->currentItem(); + } else if (sender() == ui->xpathRemoveListWidget) { + item = ui->xpathRemoveListWidget->currentItem(); + } else { + return; + } + + QMenu contextMnu(this); + + QAction *action = contextMnu.addAction(QIcon(), tr("Add"), this, SLOT(addXPath())); + action->setData(QVariant::fromValue(sender())); + + action = contextMnu.addAction(QIcon(), tr("Edit"), this, SLOT(editXPath())); + action->setData(QVariant::fromValue(sender())); + if (!item) { + action->setEnabled(false); + } + + action = contextMnu.addAction(QIcon(), tr("Delete"), this, SLOT(removeXPath())); + action->setData(QVariant::fromValue(sender())); + if (!item) { + action->setEnabled(false); + } + + contextMnu.exec(QCursor::pos()); +} + + +void PreviewFeedDialog::xpathCloseEditor(QWidget */*editor*/, QAbstractItemDelegate::EndEditHint /*hint*/) +{ + processXPath(); +} + +void PreviewFeedDialog::addXPath() +{ + QAction *action = dynamic_cast(sender()); + if (!action) { + return; + } + + QObject *source = action->data().value(); + + QListWidget *listWidget; + if (source == ui->xpathUseListWidget) { + listWidget = ui->xpathUseListWidget; + } else if (source == ui->xpathRemoveListWidget) { + listWidget = ui->xpathRemoveListWidget; + } else { + return; + } + + QListWidgetItem *item = new QListWidgetItem(); + item->setFlags(item->flags() | Qt::ItemIsEditable); + listWidget->addItem(item); + + listWidget->editItem(item); +} + +void PreviewFeedDialog::editXPath() +{ + QAction *action = dynamic_cast(sender()); + if (!action) { + return; + } + + QObject *source = action->data().value(); + + QListWidget *listWidget; + if (source == ui->xpathUseListWidget) { + listWidget = ui->xpathUseListWidget; + } else if (source == ui->xpathRemoveListWidget) { + listWidget = ui->xpathRemoveListWidget; + } else { + return; + } + + listWidget->editItem(listWidget->currentItem()); +} + +void PreviewFeedDialog::removeXPath() +{ + QAction *action = dynamic_cast(sender()); + if (!action) { + return; + } + + QObject *source = action->data().value(); + + QListWidget *listWidget; + if (source == ui->xpathUseListWidget) { + listWidget = ui->xpathUseListWidget; + } else if (source == ui->xpathRemoveListWidget) { + listWidget = ui->xpathRemoveListWidget; + } else { + return; + } + + QListWidgetItem *item = listWidget->currentItem(); + if (item) { + delete(item); + } + + processXPath(); +} + int PreviewFeedDialog::getMsgPos() { int pos = -1; @@ -281,14 +480,18 @@ int PreviewFeedDialog::getMsgPos() return pos; } -void PreviewFeedDialog::setInfo(const QString &info) +void PreviewFeedDialog::setFeedInfo(const QString &info) { ui->feedInfoLabel->setText(info); - - ui->infoLabel->setVisible(!info.isEmpty()); ui->feedInfoLabel->setVisible(!info.isEmpty()); } +void PreviewFeedDialog::setXPathInfo(const QString &info) +{ + ui->xpathInfoLabel->setText(info); + ui->xpathInfoLabel->setVisible(!info.isEmpty()); +} + void PreviewFeedDialog::fillFeedInfo(const FeedInfo &feedInfo) { QString name = feedInfo.name.empty() ? tr("No name") : QString::fromUtf8(feedInfo.name.c_str()); @@ -299,7 +502,7 @@ void PreviewFeedDialog::fillFeedInfo(const FeedInfo &feedInfo) } ui->feedNameLabel->setText(name); - setInfo(FeedReaderStringDefs::errorString(feedInfo)); + setFeedInfo(FeedReaderStringDefs::errorString(feedInfo)); } void PreviewFeedDialog::previousMsg() @@ -344,24 +547,23 @@ void PreviewFeedDialog::updateMsg() ui->msgTitle->clear(); ui->msgText->clear(); mDescription.clear(); + mDescriptionXPath.clear(); return; } - mDescription = msgInfo.description; - QString msgTxt = RsHtml().formatText(ui->msgText->document(), QString::fromUtf8(mDescription.c_str()), RSHTML_FORMATTEXT_EMBED_LINKS); - - ui->msgText->setHtml(msgTxt); ui->msgTitle->setText(QString::fromUtf8(msgInfo.title.c_str())); - ui->documentTreeWidget->clear(); - fillDocumentTree(); + /* store description */ + mDescription = msgInfo.description; + + /* process xpath */ + processXPath(); } -static void examineChildElements(QTreeWidget *treeWidget, HTMLWrapper &html, xmlNodePtr node, QTreeWidgetItem *parentItem) +static void buildNodeText(HTMLWrapper &html, xmlNodePtr node, QString &text) { - QTreeWidgetItem *item = new QTreeWidgetItem; - QString text; - if (node->type == XML_ELEMENT_NODE) { + switch (node->type) { + case XML_ELEMENT_NODE: text = QString("<%1 ").arg(QString::fromUtf8(html.nodeName(node).c_str())); for (xmlAttrPtr attr = node->properties; attr; attr = attr->next) { @@ -372,48 +574,148 @@ static void examineChildElements(QTreeWidget *treeWidget, HTMLWrapper &html, xml text += QString("%1=\"%2\" ").arg(QString::fromUtf8(html.attrName(attr).c_str()), value); } text = text.trimmed() + ">"; - } else { - std::string content; - if (html.getContent(node, content)) { - text = QString::fromUtf8(content.c_str()); - } else { - text = QApplication::translate("PreviewFeedDialog", "Error getting content"); + + if (node->children && !node->children->next && node->children->type == XML_TEXT_NODE) { + /* only one text node as child */ + std::string content; + if (html.getContent(node->children, content)) { + text += QString::fromUtf8(content.c_str()); + } else { + text += QApplication::translate("PreviewFeedDialog", "Error getting content"); + } + text += QString("<%1>").arg(QString::fromUtf8(html.nodeName(node).c_str())); + + xmlUnlinkNode(node->children); + xmlFreeNode(node->children); } + break; + case XML_TEXT_NODE: + case XML_COMMENT_NODE: + { + if (node->type == XML_COMMENT_NODE) { + text = ""; + } + } + break; + case XML_ATTRIBUTE_NODE: + case XML_CDATA_SECTION_NODE: + case XML_ENTITY_REF_NODE: + case XML_ENTITY_NODE: + case XML_PI_NODE: + case XML_DOCUMENT_NODE: + case XML_DOCUMENT_TYPE_NODE: + case XML_DOCUMENT_FRAG_NODE: + case XML_NOTATION_NODE: + case XML_HTML_DOCUMENT_NODE: + case XML_DTD_NODE: + case XML_ELEMENT_DECL: + case XML_ATTRIBUTE_DECL: + case XML_ENTITY_DECL: + case XML_NAMESPACE_DECL: + case XML_XINCLUDE_START: + case XML_XINCLUDE_END: +#ifdef LIBXML_DOCB_ENABLED + case XML_DOCB_DOCUMENT_NODE: +#endif + break; + } +} + +static void examineChildElements(QTreeWidget *treeWidget, HTMLWrapper &html, QList &nodes, QTreeWidgetItem *parentItem) +{ + int childIndex = 0; + int childCount; + + QList > nodeItems; + foreach (xmlNodePtr node, nodes) { + QString text; + buildNodeText(html, node, text); + + QList itemsToDelete; + QTreeWidgetItem *item = NULL; + + childCount = parentItem->childCount(); + for (int index = childIndex; index < childCount; ++index) { + QTreeWidgetItem *childItem = parentItem->child(index); + if (childItem->text(0) == text) { + /* reuse item */ + item = childItem; + break; + } + itemsToDelete.push_back(childItem); + } + + if (item) { + /* delete old items */ + foreach (QTreeWidgetItem *item, itemsToDelete) { + delete(item); + } + ++childIndex; + } else { + item = new QTreeWidgetItem; + item->setText(0, text); + parentItem->insertChild(childIndex, item); + item->setExpanded(true); + + ++childIndex; + } + + nodeItems.push_back(QPair(node, item)); + } + + /* delete not used items */ + while (childIndex < parentItem->childCount()) { + delete(parentItem->child(childIndex)); + } + + QList >::iterator nodeItem; + for (nodeItem = nodeItems.begin(); nodeItem != nodeItems.end(); ++nodeItem) { + QList childNodes; + for (xmlNodePtr childNode = nodeItem->first->children; childNode; childNode = childNode->next) { + childNodes.push_back(childNode); + } + examineChildElements(treeWidget, html, childNodes, nodeItem->second); } - item->setText(0, text); - parentItem->addChild(item); // QLabel *label = new QLabel(text); // label->setTextFormat(Qt::PlainText); // label->setWordWrap(true); // treeWidget->setItemWidget(item, 0, label); - - item->setExpanded(true); - - for (xmlNodePtr child = node->children; child; child = child->next) { - examineChildElements(treeWidget, html, child, item); - } } -void PreviewFeedDialog::fillDocumentTree() +void PreviewFeedDialog::fillStructureTree() { - if (!ui->documentTreeWidget->isVisible()) { + if (!ui->structureTreeWidget->isVisible()) { return; } - if (ui->documentTreeWidget->topLevelItemCount() > 0) { +// if (ui->structureTreeWidget->topLevelItemCount() > 0) { +// return; +// } + + if (mDescriptionXPath.empty()) { + ui->structureTreeWidget->clear(); return; } - if (mDescription.empty()) { - return; - } + bool useXPath = ui->useXPathCheckBox->isChecked(); HTMLWrapper html; - if (!html.readHTML(mDescription.c_str(), "")) { + if (!html.readHTML(useXPath ? mDescriptionXPath.c_str() : mDescription.c_str(), "")) { QTreeWidgetItem *item = new QTreeWidgetItem; item->setText(0, tr("Error parsing document")); - ui->documentTreeWidget->addTopLevelItem(item); + ui->structureTreeWidget->addTopLevelItem(item); return; } @@ -423,5 +725,42 @@ void PreviewFeedDialog::fillDocumentTree() return; } - examineChildElements(ui->documentTreeWidget, html, root, ui->documentTreeWidget->invisibleRootItem()); + QList nodes; + nodes.push_back(root); + examineChildElements(ui->structureTreeWidget, html, nodes, ui->structureTreeWidget->invisibleRootItem()); + ui->structureTreeWidget->resizeColumnToContents(0); +} + +void PreviewFeedDialog::getXPaths(std::list &xpathsToUse, std::list &xpathsToRemove) +{ + int row; + int rowCount = ui->xpathUseListWidget->count(); + for (row = 0; row < rowCount; ++row) { + xpathsToUse.push_back(ui->xpathUseListWidget->item(row)->text().toUtf8().constData()); + } + + rowCount = ui->xpathRemoveListWidget->count(); + for (row = 0; row < rowCount; ++row) { + xpathsToRemove.push_back(ui->xpathRemoveListWidget->item(row)->text().toUtf8().constData()); + } +} + +void PreviewFeedDialog::processXPath() +{ + std::list xpathsToUse; + std::list xpathsToRemove; + + getXPaths(xpathsToUse, xpathsToRemove); + + mDescriptionXPath = mDescription; + std::string errorString; + RsFeedReaderErrorState result = mFeedReader->processXPath(xpathsToUse, xpathsToRemove, mDescriptionXPath, errorString); + setXPathInfo(FeedReaderStringDefs::errorString(result, errorString)); + + /* fill message */ + QString msgTxt = RsHtml().formatText(ui->msgText->document(), QString::fromUtf8(mDescriptionXPath.c_str()), RSHTML_FORMATTEXT_EMBED_LINKS); + ui->msgText->setHtml(msgTxt); + + /* fill structure */ + fillStructureTree(); } diff --git a/plugins/FeedReader/gui/PreviewFeedDialog.h b/plugins/FeedReader/gui/PreviewFeedDialog.h index a801577bc..d6c7e3da9 100644 --- a/plugins/FeedReader/gui/PreviewFeedDialog.h +++ b/plugins/FeedReader/gui/PreviewFeedDialog.h @@ -59,22 +59,36 @@ public: PreviewFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, const FeedInfo &feedInfo, QWidget *parent = 0); ~PreviewFeedDialog(); + void getXPaths(std::list &xpathsToUse, std::list &xpathsToRemove); + +protected: + bool eventFilter(QObject *obj, QEvent *ev); + private slots: void previousMsg(); void nextMsg(); - void showDocumentFrame(bool show); + void showStructureFrame(bool show = false); + void showXPathFrame(bool show); + void xpathListCustomPopupMenu(QPoint point); + void xpathCloseEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint); + void addXPath(); + void editXPath(); + void removeXPath(); + void fillStructureTree(); /* FeedReaderNotify */ void feedChanged(const QString &feedId, int type); void msgChanged(const QString &feedId, const QString &msgId, int type); private: + void processSettings(bool load); int getMsgPos(); - void setInfo(const QString &info); + void setFeedInfo(const QString &info); + void setXPathInfo(const QString &info); void fillFeedInfo(const FeedInfo &feedInfo); void updateMsgCount(); void updateMsg(); - void fillDocumentTree(); + void processXPath(); RsFeedReader *mFeedReader; FeedReaderNotify *mNotify; @@ -82,6 +96,7 @@ private: std::string mMsgId; std::list mMsgIds; std::string mDescription; + std::string mDescriptionXPath; Ui::PreviewFeedDialog *ui; }; diff --git a/plugins/FeedReader/gui/PreviewFeedDialog.ui b/plugins/FeedReader/gui/PreviewFeedDialog.ui index 9b5d92570..21a2a89a5 100644 --- a/plugins/FeedReader/gui/PreviewFeedDialog.ui +++ b/plugins/FeedReader/gui/PreviewFeedDialog.ui @@ -6,8 +6,8 @@ 0 0 - 500 - 350 + 800 + 783 @@ -45,29 +45,103 @@ - - - - Information: - - - + + + + + + + 255 + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 118 + 116 + 108 + + + + + + - Information + Feed information true + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 118 + 116 + 108 + + + + + + + + XPath information + + + - + - + Qt::Horizontal @@ -119,7 +193,7 @@ - + Qt::Horizontal @@ -131,6 +205,16 @@ + + + + Structure + + + true + + + @@ -173,92 +257,241 @@ background: white;} - - - 0 + + + + 0 + 0 + - - + + QFrame::StyledPanel + + + QFrame::Raised + + + Qt::Vertical + + + false + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + - - - - 14 - 31 - + + + 0 - - - 14 - 31 - - - - - - - - 16 - 31 - - - - true - - + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 16 + 16 + + + + QToolButton +{ + border-image: url(:/images/closenormal.png) +} + +QToolButton:hover +{ +border-image: url(:/images/closehover.png) +} + +QToolButton:pressed { +border-image: url(:/images/closepressed.png) +} + + + ... + + + true + + + + - - - Qt::Vertical - - - - 12 - 329 - - - + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + Qt::Horizontal + + + false + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 0 + + + + + Use XPath + + + + + + + true + + + false + + + false + + + + 1 + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 0 + + + + + XPath use + + + + + + + Qt::CustomContextMenu + + + + + + + XPath remove + + + + + + + Qt::CustomContextMenu + + + + + + + + + + + + + + 14 + 31 + + + + + 14 + 31 + + + + true + + + + + + + Qt::Vertical + + + + 13 + 13 + + + + + + + - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - - - true - - - false - - - - 1 - - - - - - - - - - - + + diff --git a/plugins/FeedReader/interface/rsFeedReader.h b/plugins/FeedReader/interface/rsFeedReader.h index 4ea33cac4..dc3efd1b3 100644 --- a/plugins/FeedReader/interface/rsFeedReader.h +++ b/plugins/FeedReader/interface/rsFeedReader.h @@ -27,22 +27,27 @@ #include enum RsFeedReaderErrorState { - RS_FEED_ERRORSTATE_OK = 0, + RS_FEED_ERRORSTATE_OK = 0, /* download */ - RS_FEED_ERRORSTATE_DOWNLOAD_INTERNAL_ERROR = 1, - RS_FEED_ERRORSTATE_DOWNLOAD_ERROR = 2, - RS_FEED_ERRORSTATE_DOWNLOAD_UNKNOWN_CONTENT_TYPE = 3, - RS_FEED_ERRORSTATE_DOWNLOAD_NOT_FOUND = 4, - RS_FEED_ERRORSTATE_DOWNLOAD_UNKOWN_RESPONSE_CODE = 5, + RS_FEED_ERRORSTATE_DOWNLOAD_INTERNAL_ERROR = 1, + RS_FEED_ERRORSTATE_DOWNLOAD_ERROR = 2, + RS_FEED_ERRORSTATE_DOWNLOAD_UNKNOWN_CONTENT_TYPE = 3, + RS_FEED_ERRORSTATE_DOWNLOAD_NOT_FOUND = 4, + RS_FEED_ERRORSTATE_DOWNLOAD_UNKOWN_RESPONSE_CODE = 5, /* process */ - RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR = 50, - RS_FEED_ERRORSTATE_PROCESS_UNKNOWN_FORMAT = 51, - RS_FEED_ERRORSTATE_PROCESS_FORUM_CREATE = 100, - RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_FOUND = 101, - RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_ADMIN = 102, - RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_ANONYMOUS = 103 + RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR = 50, + RS_FEED_ERRORSTATE_PROCESS_UNKNOWN_FORMAT = 51, + RS_FEED_ERRORSTATE_PROCESS_FORUM_CREATE = 100, + RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_FOUND = 101, + RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_ADMIN = 102, + RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_ANONYMOUS = 103, + + RS_FEED_ERRORSTATE_PROCESS_HTML_ERROR = 150, + RS_FEED_ERRORSTATE_PROCESS_XPATH_INTERNAL_ERROR = 151, + RS_FEED_ERRORSTATE_PROCESS_XPATH_WRONG_EXPRESSION = 152, + RS_FEED_ERRORSTATE_PROCESS_XPATH_NO_RESULT = 153 }; @@ -111,6 +116,9 @@ public: RsFeedReaderErrorState errorState; std::string errorString; + std::list xpathsToUse; + std::list xpathsToRemove; + struct { bool folder : 1; bool infoFromFeed : 1; @@ -192,6 +200,8 @@ public: virtual bool getFeedMsgIdList(const std::string &feedId, std::list &msgIds) = 0; virtual bool processFeed(const std::string &feedId) = 0; virtual bool setMessageRead(const std::string &feedId, const std::string &msgId, bool read) = 0; + + virtual RsFeedReaderErrorState processXPath(const std::list &xpathsToUse, const std::list &xpathsToRemove, std::string &description, std::string &errorString) = 0; }; #endif diff --git a/plugins/FeedReader/services/p3FeedReader.cc b/plugins/FeedReader/services/p3FeedReader.cc index 6aaad1003..f4940048d 100644 --- a/plugins/FeedReader/services/p3FeedReader.cc +++ b/plugins/FeedReader/services/p3FeedReader.cc @@ -37,7 +37,7 @@ RsFeedReader *rsFeedReader = NULL; *********/ p3FeedReader::p3FeedReader(RsPluginHandler* pgHandler) - : RsPQIService(RS_PKT_TYPE_FEEDREADER_CONFIG, CONFIG_TYPE_FEEDREADER, 5, pgHandler), + : RsPQIService(RS_SERVICE_TYPE_PLUGIN_FEEDREADER, CONFIG_TYPE_FEEDREADER, 5, pgHandler), mFeedReaderMtx("p3FeedReader"), mDownloadMutex("p3FeedReaderDownload"), mProcessMutex("p3FeedReaderProcess"), mPreviewMutex("p3FeedReaderPreview") { mNextFeedId = 1; @@ -88,6 +88,9 @@ static void feedToInfo(const RsFeedReaderFeed *feed, FeedInfo &info) info.errorState = feed->errorState; info.errorString = feed->errorString; + info.xpathsToUse = feed->xpathsToUse.ids; + info.xpathsToRemove = feed->xpathsToRemove.ids; + info.flag.folder = (feed->flag & RS_FEED_FLAG_FOLDER); info.flag.infoFromFeed = (feed->flag & RS_FEED_FLAG_INFO_FROM_FEED); info.flag.standardStorageTime = (feed->flag & RS_FEED_FLAG_STANDARD_STORAGE_TIME); @@ -141,6 +144,9 @@ static void infoToFeed(const FeedInfo &info, RsFeedReaderFeed *feed, bool add) feed->forumId = info.forumId; } + feed->xpathsToUse.ids = info.xpathsToUse; + feed->xpathsToRemove.ids = info.xpathsToRemove; + // feed->preview = info.flag.preview; uint32_t oldFlag = feed->flag; @@ -512,11 +518,11 @@ void p3FeedReader::deleteAllMsgs_locked(RsFeedReaderFeed *fi) } std::map::iterator msgIt; - for (msgIt = fi->mMsgs.begin(); msgIt != fi->mMsgs.end(); ++msgIt) { + for (msgIt = fi->msgs.begin(); msgIt != fi->msgs.end(); ++msgIt) { delete(msgIt->second); } - fi->mMsgs.clear(); + fi->msgs.clear(); } bool p3FeedReader::removeFeed(const std::string &feedId) @@ -712,8 +718,8 @@ bool p3FeedReader::getMsgInfo(const std::string &feedId, const std::string &msgI RsFeedReaderFeed *fi = feedIt->second; std::map::iterator msgIt; - msgIt = fi->mMsgs.find(msgId); - if (msgIt == fi->mMsgs.end()) { + msgIt = fi->msgs.find(msgId); + if (msgIt == fi->msgs.end()) { #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::getMsgInfo - msg " << msgId << " not found" << std::endl; #endif @@ -744,8 +750,8 @@ bool p3FeedReader::removeMsg(const std::string &feedId, const std::string &msgId changed = !fi->preview; std::map::iterator msgIt; - msgIt = fi->mMsgs.find(msgId); - if (msgIt == fi->mMsgs.end()) { + msgIt = fi->msgs.find(msgId); + if (msgIt == fi->msgs.end()) { #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::removeMsg - msg " << msgId << " not found" << std::endl; #endif @@ -789,8 +795,8 @@ bool p3FeedReader::removeMsgs(const std::string &feedId, const std::list::const_iterator idIt; for (idIt = msgIds.begin(); idIt != msgIds.end(); ++idIt) { std::map::iterator msgIt; - msgIt = fi->mMsgs.find(*idIt); - if (msgIt == fi->mMsgs.end()) { + msgIt = fi->msgs.find(*idIt); + if (msgIt == fi->msgs.end()) { #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::removeMsgs - msg " << *idIt << " not found" << std::endl; #endif @@ -842,7 +848,7 @@ bool p3FeedReader::getMessageCount(const std::string &feedId, uint32_t *msgCount RsFeedReaderFeed *fi = feedIt->second; std::map::iterator msgIt; - for (msgIt = fi->mMsgs.begin(); msgIt != fi->mMsgs.end(); ++msgIt) { + for (msgIt = fi->msgs.begin(); msgIt != fi->msgs.end(); ++msgIt) { RsFeedReaderMsg *mi = msgIt->second; if (mi->flag & RS_FEEDMSG_FLAG_DELETED) { @@ -872,7 +878,7 @@ bool p3FeedReader::getFeedMsgList(const std::string &feedId, std::listsecond; std::map::iterator msgIt; - for (msgIt = fi->mMsgs.begin(); msgIt != fi->mMsgs.end(); ++msgIt) { + for (msgIt = fi->msgs.begin(); msgIt != fi->msgs.end(); ++msgIt) { RsFeedReaderMsg *mi = msgIt->second; if (mi->flag & RS_FEEDMSG_FLAG_DELETED) { @@ -902,7 +908,7 @@ bool p3FeedReader::getFeedMsgIdList(const std::string &feedId, std::listsecond; std::map::iterator msgIt; - for (msgIt = fi->mMsgs.begin(); msgIt != fi->mMsgs.end(); ++msgIt) { + for (msgIt = fi->msgs.begin(); msgIt != fi->msgs.end(); ++msgIt) { RsFeedReaderMsg *mi = msgIt->second; if (mi->flag & RS_FEEDMSG_FLAG_DELETED) { @@ -1060,8 +1066,8 @@ bool p3FeedReader::setMessageRead(const std::string &feedId, const std::string & RsFeedReaderFeed *fi = feedIt->second; std::map::iterator msgIt; - msgIt = fi->mMsgs.find(msgId); - if (msgIt == fi->mMsgs.end()) { + msgIt = fi->msgs.find(msgId); + if (msgIt == fi->msgs.end()) { #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::setMessageRead - msg " << msgId << " not found" << std::endl; #endif @@ -1092,6 +1098,11 @@ bool p3FeedReader::setMessageRead(const std::string &feedId, const std::string & return true; } +RsFeedReaderErrorState p3FeedReader::processXPath(const std::list &xpathsToUse, const std::list &xpathsToRemove, std::string &description, std::string &errorString) +{ + return p3FeedReaderThread::processXPath(xpathsToUse, xpathsToRemove, description, errorString); +} + /***************************************************************************/ /****************************** p3Service **********************************/ /***************************************************************************/ @@ -1185,7 +1196,7 @@ void p3FeedReader::cleanFeeds() uint32_t removedMsgs = 0; std::map::iterator msgIt; - for (msgIt = fi->mMsgs.begin(); msgIt != fi->mMsgs.end(); ) { + for (msgIt = fi->msgs.begin(); msgIt != fi->msgs.end(); ) { RsFeedReaderMsg *mi = msgIt->second; if (mi->flag & RS_FEEDMSG_FLAG_DELETED) { @@ -1193,7 +1204,7 @@ void p3FeedReader::cleanFeeds() removedMsgIds.push_back(std::pair (fi->feedId, mi->msgId)); delete(mi); std::map::iterator deleteIt = msgIt++; - fi->mMsgs.erase(deleteIt); + fi->msgs.erase(deleteIt); ++removedMsgs; continue; } @@ -1274,7 +1285,7 @@ bool p3FeedReader::saveList(bool &cleanup, std::list & saveData) saveData.push_back(fi); std::map::iterator it2; - for (it2 = fi->mMsgs.begin(); it2 != fi->mMsgs.end(); ++it2) { + for (it2 = fi->msgs.begin(); it2 != fi->msgs.end(); ++it2) { saveData.push_back(it2->second); } } @@ -1376,7 +1387,7 @@ bool p3FeedReader::loadList(std::list& load) delete it1->second; continue; } - it2->second->mMsgs[it1->first] = it1->second; + it2->second->msgs[it1->first] = it1->second; if (msgId + 1 > mNextMsgId) { mNextMsgId = msgId + 1; } @@ -1496,7 +1507,7 @@ void p3FeedReader::onDownloadSuccess(const std::string &feedId, const std::strin } } -void p3FeedReader::onDownloadError(const std::string &feedId, p3FeedReaderThread::DownloadResult result, const std::string &errorString) +void p3FeedReader::onDownloadError(const std::string &feedId, RsFeedReaderErrorState result, const std::string &errorString) { { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -1516,28 +1527,7 @@ void p3FeedReader::onDownloadError(const std::string &feedId, p3FeedReaderThread fi->lastUpdate = time(NULL); fi->content.clear(); - switch (result) { - case p3FeedReaderThread::DOWNLOAD_SUCCESS: - /* this should not happen */ - std::cerr << "p3FeedReader::onDownloadError - success given as error" << std::endl; - fi->errorState = RS_FEED_ERRORSTATE_DOWNLOAD_INTERNAL_ERROR; - break; - case p3FeedReaderThread::DOWNLOAD_ERROR: - fi->errorState = RS_FEED_ERRORSTATE_DOWNLOAD_ERROR; - break; - case p3FeedReaderThread::DOWNLOAD_UNKNOWN_CONTENT_TYPE: - fi->errorState = RS_FEED_ERRORSTATE_DOWNLOAD_UNKNOWN_CONTENT_TYPE; - break; - case p3FeedReaderThread::DOWNLOAD_NOT_FOUND: - fi->errorState = RS_FEED_ERRORSTATE_DOWNLOAD_NOT_FOUND; - break; - case p3FeedReaderThread::DOWNLOAD_UNKOWN_RESPONSE_CODE: - fi->errorState = RS_FEED_ERRORSTATE_DOWNLOAD_UNKOWN_RESPONSE_CODE; - break; - default: - fi->errorState = RS_FEED_ERRORSTATE_DOWNLOAD_INTERNAL_ERROR; - } - + fi->errorState = result; fi->errorString = errorString; #ifdef FEEDREADER_DEBUG @@ -1611,7 +1601,7 @@ bool p3FeedReader::getFeedToProcess(RsFeedReaderFeed &feed, const std::string &n return true; } -bool p3FeedReader::onProcessSuccess_filterMsg(const std::string &feedId, std::list &msgs) +void p3FeedReader::onProcessSuccess_filterMsg(const std::string &feedId, std::list &msgs) { #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::onProcessSuccess_filterMsg - feed " << feedId << " got " << msgs.size() << " messages" << std::endl; @@ -1627,7 +1617,7 @@ bool p3FeedReader::onProcessSuccess_filterMsg(const std::string &feedId, std::li #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::onProcessSuccess_filterMsg - feed " << feedId << " not found" << std::endl; #endif - return false; + return; } RsFeedReaderFeed *fi = it->second; @@ -1637,14 +1627,14 @@ bool p3FeedReader::onProcessSuccess_filterMsg(const std::string &feedId, std::li RsFeedReaderMsg *miNew = *newMsgIt; /* search for existing msg */ std::map::iterator msgIt; - for (msgIt = fi->mMsgs.begin(); msgIt != fi->mMsgs.end(); ++msgIt) { + for (msgIt = fi->msgs.begin(); msgIt != fi->msgs.end(); ++msgIt) { RsFeedReaderMsg *mi = msgIt->second; if (mi->title == miNew->title && mi->link == miNew->link && mi->author == miNew->author) { /* msg exist */ break; } } - if (msgIt != fi->mMsgs.end()) { + if (msgIt != fi->msgs.end()) { /* msg exists */ delete(miNew); newMsgIt = msgs.erase(newMsgIt); @@ -1660,11 +1650,9 @@ bool p3FeedReader::onProcessSuccess_filterMsg(const std::string &feedId, std::li IndicateConfigChanged(); } } - - return true; } -void p3FeedReader::onProcessSuccess_addMsgs(const std::string &feedId, bool result, std::list &msgs, bool single) +void p3FeedReader::onProcessSuccess_addMsgs(const std::string &feedId, std::list &msgs, bool single) { #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - feed " << feedId << " got " << msgs.size() << " messages" << std::endl; @@ -1691,7 +1679,7 @@ void p3FeedReader::onProcessSuccess_addMsgs(const std::string &feedId, bool resu bool forum = (fi->flag & RS_FEED_FLAG_FORUM) && !fi->preview; RsFeedReaderErrorState errorState = RS_FEED_ERRORSTATE_OK; - if (result && forum && !msgs.empty()) { + if (forum && !msgs.empty()) { if (fi->forumId.empty()) { /* create new forum */ std::wstring forumName; @@ -1751,35 +1739,33 @@ void p3FeedReader::onProcessSuccess_addMsgs(const std::string &feedId, bool resu uint32_t newMsgs = 0; #endif - if (result) { - std::list::iterator newMsgIt; - for (newMsgIt = msgs.begin(); newMsgIt != msgs.end(); ) { - RsFeedReaderMsg *miNew = *newMsgIt; - /* add new msg */ - if (fi->preview) { - rs_sprintf(miNew->msgId, "preview%d", mNextPreviewMsgId--); - } else { - rs_sprintf(miNew->msgId, "%lu", mNextMsgId++); - } - if (forum) { - miNew->flag = RS_FEEDMSG_FLAG_DELETED; - forumMsgs.push_back(*miNew); -// miNew->description.clear(); - } else { - miNew->flag = RS_FEEDMSG_FLAG_NEW; - addedMsgs.push_back(miNew->msgId); - } - fi->mMsgs[miNew->msgId] = miNew; - newMsgIt = msgs.erase(newMsgIt); + std::list::iterator newMsgIt; + for (newMsgIt = msgs.begin(); newMsgIt != msgs.end(); ) { + RsFeedReaderMsg *miNew = *newMsgIt; + /* add new msg */ + if (fi->preview) { + rs_sprintf(miNew->msgId, "preview%d", mNextPreviewMsgId--); + } else { + rs_sprintf(miNew->msgId, "%lu", mNextMsgId++); + } + if (forum) { + miNew->flag = RS_FEEDMSG_FLAG_DELETED; + forumMsgs.push_back(*miNew); +// miNew->description.clear(); + } else { + miNew->flag = RS_FEEDMSG_FLAG_NEW; + addedMsgs.push_back(miNew->msgId); + } + fi->msgs[miNew->msgId] = miNew; + newMsgIt = msgs.erase(newMsgIt); #ifdef FEEDREADER_DEBUG - ++newMsgs; -#endif - } -#ifdef FEEDREADER_DEBUG - std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - feed " << fi->feedId << " (" << fi->name << ") added " << newMsgs << "/" << msgs.size() << " messages" << std::endl; + ++newMsgs; #endif } +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - feed " << fi->feedId << " (" << fi->name << ") added " << newMsgs << "/" << msgs.size() << " messages" << std::endl; +#endif } if (!single) { @@ -1833,7 +1819,7 @@ void p3FeedReader::onProcessSuccess_addMsgs(const std::string &feedId, bool resu } } -void p3FeedReader::onProcessError(const std::string &feedId, p3FeedReaderThread::ProcessResult result, const std::string &errorString) +void p3FeedReader::onProcessError(const std::string &feedId, RsFeedReaderErrorState result, const std::string &errorString) { { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -1853,23 +1839,7 @@ void p3FeedReader::onProcessError(const std::string &feedId, p3FeedReaderThread: fi->lastUpdate = time(NULL); fi->content.clear(); - long todo; // sort error codes - switch (result) { - case p3FeedReaderThread::PROCESS_SUCCESS: - /* this should not happen */ - std::cerr << "p3FeedReader::onProcessError - success given as error" << std::endl; - fi->errorState = RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR; - break; - case p3FeedReaderThread::PROCESS_ERROR_INIT: - fi->errorState = RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR; - break; - case p3FeedReaderThread::PROCESS_UNKNOWN_FORMAT: - fi->errorState = RS_FEED_ERRORSTATE_PROCESS_UNKNOWN_FORMAT; - break; - default: - fi->errorState = RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR; - } - + fi->errorState = result; fi->errorString = errorString; #ifdef FEEDREADER_DEBUG diff --git a/plugins/FeedReader/services/p3FeedReader.h b/plugins/FeedReader/services/p3FeedReader.h index 2bced3c0f..34901620e 100644 --- a/plugins/FeedReader/services/p3FeedReader.h +++ b/plugins/FeedReader/services/p3FeedReader.h @@ -25,13 +25,10 @@ #include "retroshare/rsplugin.h" #include "plugins/rspqiservice.h" #include "interface/rsFeedReader.h" -#include "p3FeedReaderThread.h" class RsFeedReaderFeed; - -//TODO: get new id's -const uint8_t RS_PKT_TYPE_FEEDREADER_CONFIG = 0xf0; -const uint32_t CONFIG_TYPE_FEEDREADER = 0x0001; +class RsFeedReaderMsg; +class p3FeedReaderThread; class p3FeedReader : public RsPQIService, public RsFeedReader { @@ -66,16 +63,18 @@ public: virtual bool processFeed(const std::string &feedId); virtual bool setMessageRead(const std::string &feedId, const std::string &msgId, bool read); + virtual RsFeedReaderErrorState processXPath(const std::list &xpathsToUse, const std::list &xpathsToRemove, std::string &description, std::string &errorString); + /****************** p3Service STUFF ******************/ virtual int tick(); /****************** internal STUFF *******************/ bool getFeedToDownload(RsFeedReaderFeed &feed, const std::string &neededFeedId); void onDownloadSuccess(const std::string &feedId, const std::string &content, std::string &icon); - void onDownloadError(const std::string &feedId, p3FeedReaderThread::DownloadResult result, const std::string &errorString); - bool onProcessSuccess_filterMsg(const std::string &feedId, std::list &msgs); - void onProcessSuccess_addMsgs(const std::string &feedId, bool result, std::list &msgs, bool single); - void onProcessError(const std::string &feedId, p3FeedReaderThread::ProcessResult result, const std::string &errorString); + void onDownloadError(const std::string &feedId, RsFeedReaderErrorState result, const std::string &errorString); + void onProcessSuccess_filterMsg(const std::string &feedId, std::list &msgs); + void onProcessSuccess_addMsgs(const std::string &feedId, std::list &msgs, bool single); + void onProcessError(const std::string &feedId, RsFeedReaderErrorState result, const std::string &errorString); bool getFeedToProcess(RsFeedReaderFeed &feed, const std::string &neededFeedId); diff --git a/plugins/FeedReader/services/p3FeedReaderThread.cc b/plugins/FeedReader/services/p3FeedReaderThread.cc index 4ee228951..764491ea1 100644 --- a/plugins/FeedReader/services/p3FeedReaderThread.cc +++ b/plugins/FeedReader/services/p3FeedReaderThread.cc @@ -25,6 +25,7 @@ #include "util/CURLWrapper.h" #include "util/XMLWrapper.h" #include "util/HTMLWrapper.h" +#include "util/XPathWrapper.h" #include @@ -67,8 +68,8 @@ void p3FeedReaderThread::run() std::string icon; std::string errorString; - DownloadResult result = download(feed, content, icon, errorString); - if (result == DOWNLOAD_SUCCESS) { + RsFeedReaderErrorState result = download(feed, content, icon, errorString); + if (result == RS_FEED_ERRORSTATE_OK) { mFeedReader->onDownloadSuccess(feed.feedId, content, icon); } else { mFeedReader->onDownloadError(feed.feedId, result, errorString); @@ -84,37 +85,42 @@ void p3FeedReaderThread::run() std::string errorString; std::list::iterator it; - ProcessResult result = process(feed, msgs, errorString); - if (result == PROCESS_SUCCESS) { + RsFeedReaderErrorState result = process(feed, msgs, errorString); + if (result == RS_FEED_ERRORSTATE_OK) { /* first, filter the messages */ - bool result = mFeedReader->onProcessSuccess_filterMsg(feed.feedId, msgs); + mFeedReader->onProcessSuccess_filterMsg(feed.feedId, msgs); if (isRunning()) { - if (result) { - /* second, process the descriptions */ - for (it = msgs.begin(); it != msgs.end(); ) { - RsFeedReaderMsg *mi = *it; - processMsg(feed, mi); + /* second, process the descriptions */ + for (it = msgs.begin(); it != msgs.end(); ) { + RsFeedReaderMsg *mi = *it; + result = processMsg(feed, mi, errorString); + if (result != RS_FEED_ERRORSTATE_OK) { + break; + } - if (feed.preview) { - /* add every message */ - it = msgs.erase(it); + if (feed.preview) { + /* add every message */ + it = msgs.erase(it); - std::list msgSingle; - msgSingle.push_back(mi); - mFeedReader->onProcessSuccess_addMsgs(feed.feedId, result, msgSingle, true); + std::list msgSingle; + msgSingle.push_back(mi); + mFeedReader->onProcessSuccess_addMsgs(feed.feedId, msgSingle, true); - /* delete not accepted message */ - std::list::iterator it1; - for (it1 = msgSingle.begin(); it1 != msgSingle.end(); ++it1) { - delete (*it1); - } - } else { - ++it; + /* delete not accepted message */ + std::list::iterator it1; + for (it1 = msgSingle.begin(); it1 != msgSingle.end(); ++it1) { + delete (*it1); } + } else { + ++it; } } - /* third, add messages */ - mFeedReader->onProcessSuccess_addMsgs(feed.feedId, result, msgs, false); + if (result == RS_FEED_ERRORSTATE_OK) { + /* third, add messages */ + mFeedReader->onProcessSuccess_addMsgs(feed.feedId, msgs, false); + } else { + mFeedReader->onProcessError(feed.feedId, result, errorString); + } } } else { mFeedReader->onProcessError(feed.feedId, result, errorString); @@ -245,7 +251,7 @@ static bool getFavicon(CURLWrapper &CURL, const std::string &url, std::string &i return result; } -p3FeedReaderThread::DownloadResult p3FeedReaderThread::download(const RsFeedReaderFeed &feed, std::string &content, std::string &icon, std::string &error) +RsFeedReaderErrorState p3FeedReaderThread::download(const RsFeedReaderFeed &feed, std::string &content, std::string &icon, std::string &error) { #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReaderThread::download - feed " << feed.feedId << " (" << feed.name << ")" << std::endl; @@ -254,7 +260,7 @@ p3FeedReaderThread::DownloadResult p3FeedReaderThread::download(const RsFeedRead content.clear(); error.clear(); - DownloadResult result; + RsFeedReaderErrorState result; std::string proxy = getProxyForFeed(feed); CURLWrapper CURL(proxy); @@ -273,24 +279,24 @@ p3FeedReaderThread::DownloadResult p3FeedReaderThread::download(const RsFeedRead isContentType(contentType, "application/xml") || isContentType(contentType, "application/xhtml+xml")) { /* ok */ - result = DOWNLOAD_SUCCESS; + result = RS_FEED_ERRORSTATE_OK; } else { - result = DOWNLOAD_UNKNOWN_CONTENT_TYPE; + result = RS_FEED_ERRORSTATE_DOWNLOAD_UNKNOWN_CONTENT_TYPE; error = contentType; } } break; case 404: - result = DOWNLOAD_NOT_FOUND; + result = RS_FEED_ERRORSTATE_DOWNLOAD_NOT_FOUND; break; default: - result = DOWNLOAD_UNKOWN_RESPONSE_CODE; + result = RS_FEED_ERRORSTATE_DOWNLOAD_UNKOWN_RESPONSE_CODE; rs_sprintf(error, "%ld", responseCode); } getFavicon(CURL, feed.url, icon); } else { - result = DOWNLOAD_ERROR; + result = RS_FEED_ERRORSTATE_DOWNLOAD_ERROR; error = curl_easy_strerror(code); } @@ -326,7 +332,7 @@ static xmlNodePtr getNextItem(FeedFormat feedFormat, xmlNodePtr channel, xmlNode item = item->next; } for (; item; item = item->next) { - if (item->type == XML_ELEMENT_NODE && xmlStrcasecmp(item->name, (const xmlChar*) "item") == 0) { + if (item->type == XML_ELEMENT_NODE && xmlStrEqual(item->name, BAD_CAST"item")) { break; } } @@ -789,29 +795,29 @@ static time_t parseISO8601Date(const std::string &pubDate) return result; } -p3FeedReaderThread::ProcessResult p3FeedReaderThread::process(const RsFeedReaderFeed &feed, std::list &entries, std::string &error) +RsFeedReaderErrorState p3FeedReaderThread::process(const RsFeedReaderFeed &feed, std::list &entries, std::string &error) { #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReaderThread::process - feed " << feed.feedId << " (" << feed.name << ")" << std::endl; #endif - ProcessResult result = PROCESS_SUCCESS; + RsFeedReaderErrorState result = RS_FEED_ERRORSTATE_OK; XMLWrapper xml; if (xml.readXML(feed.content.c_str())) { xmlNodePtr root = xml.getRootElement(); if (root) { FeedFormat feedFormat; - if (xmlStrcasecmp(root->name, (const xmlChar*) "rss") == 0) { + if (xmlStrEqual(root->name, BAD_CAST"rss")) { feedFormat = FORMAT_RSS; - } else if (xmlStrcasecmp (root->name, (const xmlChar*) "rdf") != 0) { + } else if (xmlStrEqual (root->name, BAD_CAST"rdf")) { feedFormat = FORMAT_RDF; } else { - result = PROCESS_UNKNOWN_FORMAT; + result = RS_FEED_ERRORSTATE_PROCESS_UNKNOWN_FORMAT; error = "Only RSS or RDF supported"; } - if (result == PROCESS_SUCCESS) { + if (result == RS_FEED_ERRORSTATE_OK) { xmlNodePtr channel = xml.findNode(root->children, "channel"); if (channel) { /* import header info */ @@ -900,16 +906,16 @@ p3FeedReaderThread::ProcessResult p3FeedReaderThread::process(const RsFeedReader entries.push_back(item); } } else { - result = PROCESS_UNKNOWN_FORMAT; + result = RS_FEED_ERRORSTATE_PROCESS_UNKNOWN_FORMAT; error = "Channel not found"; } } } else { - result = PROCESS_UNKNOWN_FORMAT; + result = RS_FEED_ERRORSTATE_PROCESS_UNKNOWN_FORMAT; error = "Can't read document"; } } else { - result = PROCESS_ERROR_INIT; + result = RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR; } #ifdef FEEDREADER_DEBUG @@ -936,12 +942,15 @@ std::string p3FeedReaderThread::getProxyForFeed(const RsFeedReaderFeed &feed) return proxy; } -bool p3FeedReaderThread::processMsg(const RsFeedReaderFeed &feed, RsFeedReaderMsg *msg) +RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &feed, RsFeedReaderMsg *msg, std::string &errorString) { + long todo_fill_errorString; + if (!msg) { - return false; + return RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR; } + RsFeedReaderErrorState result = RS_FEED_ERRORSTATE_OK; std::string proxy = getProxyForFeed(feed); std::string url; @@ -953,14 +962,40 @@ bool p3FeedReaderThread::processMsg(const RsFeedReaderFeed &feed, RsFeedReaderMs CURLWrapper CURL(proxy); CURLcode code = CURL.downloadText(msg->link, content); - if (code == CURLE_OK && CURL.responseCode() == 200 && isContentType(CURL.contentType(), "text/html")) { - /* ok */ - msg->description = content; + if (code == CURLE_OK) { + long responseCode = CURL.responseCode(); + + switch (responseCode) { + case 200: + { + std::string contentType = CURL.contentType(); + + if (isContentType(CURL.contentType(), "text/html")) { + /* ok */ + msg->description = content; + } else { + result = RS_FEED_ERRORSTATE_DOWNLOAD_UNKNOWN_CONTENT_TYPE; + errorString = contentType; + } + } + break; + case 404: + result = RS_FEED_ERRORSTATE_DOWNLOAD_NOT_FOUND; + break; + default: + result = RS_FEED_ERRORSTATE_DOWNLOAD_UNKOWN_RESPONSE_CODE; + rs_sprintf(errorString, "%ld", responseCode); + } } else { + result = RS_FEED_ERRORSTATE_DOWNLOAD_ERROR; + errorString = curl_easy_strerror(code); + } + + if (result != RS_FEED_ERRORSTATE_OK) { #ifdef FEEDREADER_DEBUG - std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot download page, CURLCode = " << code << ", responseCode = " << CURL.responseCode() << ", contentType = " << CURL.contentType() << std::endl; + std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot download page, CURLCode = " << code << ", error = " << errorString << std::endl; #endif - return false; + return result; } /* get effective url (moved location) */ @@ -970,89 +1005,355 @@ bool p3FeedReaderThread::processMsg(const RsFeedReaderFeed &feed, RsFeedReaderMs /* check if string contains xml chars (very simple test) */ if (msg->description.find('<') == std::string::npos) { - return true; + return result; } - bool result = true; - /* process description */ long todo; // encoding HTMLWrapper html; if (html.readHTML(msg->description.c_str(), url.c_str())) { xmlNodePtr root = html.getRootElement(); if (root) { - /* process all children */ - std::list parents; - parents.push_back(root); + std::list nodesToDelete; - while (!parents.empty()) { + /* process all children */ + std::list nodes; + nodes.push_back(root); + + while (!nodes.empty()) { if (!isRunning()) { break; } - xmlNodePtr node = parents.front(); - parents.pop_front(); + xmlNodePtr node = nodes.front(); + nodes.pop_front(); - if (node->type == XML_ELEMENT_NODE) { - /* check for image */ - if (xmlStrcasecmp(node->name, (const xmlChar*) "img") == 0) { - bool removeImage = true; + switch (node->type) { + case XML_ELEMENT_NODE: + if (xmlStrEqual(node->name, BAD_CAST"img")) { + /* process images */ - if (feed.flag & RS_FEED_FLAG_EMBED_IMAGES) { - /* embed image */ - std::string src = html.getAttr(node, "src"); - if (!src.empty()) { - /* download image */ -#ifdef FEEDREADER_DEBUG - std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") download image " << src << std::endl; -#endif - std::vector data; - CURLWrapper CURL(proxy); - CURLcode code = CURL.downloadBinary(calculateLink(url, src), data); - if (code == CURLE_OK && CURL.responseCode() == 200) { - std::string contentType = CURL.contentType(); - if (isContentType(contentType, "image/")) { - std::string base64; - if (toBase64(data, base64)) { - std::string imageBase64; - rs_sprintf(imageBase64, "data:%s;base64,%s", contentType.c_str(), base64.c_str()); - if (html.setAttr(node, "src", imageBase64.c_str())) { - removeImage = false; - } - } - } - } - } - } - - if (removeImage) { + if ((feed.flag & RS_FEED_FLAG_EMBED_IMAGES) == 0) { /* remove image */ xmlUnlinkNode(node); - xmlFreeNode(node); + nodesToDelete.push_back(node); continue; } + } else if (xmlStrEqual(node->name, BAD_CAST"script")) { + /* remove script */ + xmlUnlinkNode(node); + nodesToDelete.push_back(node); + continue; } xmlNodePtr child; for (child = node->children; child; child = child->next) { - parents.push_back(child); + nodes.push_back(child); } + break; + + case XML_TEXT_NODE: + { + /* check for only space */ + std::string content; + if (html.getContent(node, content)) { + std::string newContent = content; + + /* trim left */ + std::string::size_type find = newContent.find_first_not_of(" \t\r\n"); + if (find != std::string::npos) { + newContent.erase(0, find); + + /* trim right */ + find = newContent.find_last_not_of(" \t\r\n"); + if (find != std::string::npos) { + newContent.erase(find + 1); + } + } else { + newContent.clear(); + } + + if (newContent.empty()) { + xmlUnlinkNode(node); + nodesToDelete.push_back(node); + } else { + if (content != newContent) { + html.setContent(node, newContent.c_str()); + } + } + } + } + break; + + case XML_COMMENT_NODE: +// xmlUnlinkNode(node); +// nodesToDelete.push_back(node); + break; + + case XML_ATTRIBUTE_NODE: + case XML_CDATA_SECTION_NODE: + case XML_ENTITY_REF_NODE: + case XML_ENTITY_NODE: + case XML_PI_NODE: + case XML_DOCUMENT_NODE: + case XML_DOCUMENT_TYPE_NODE: + case XML_DOCUMENT_FRAG_NODE: + case XML_NOTATION_NODE: + case XML_HTML_DOCUMENT_NODE: + case XML_DTD_NODE: + case XML_ELEMENT_DECL: + case XML_ATTRIBUTE_DECL: + case XML_ENTITY_DECL: + case XML_NAMESPACE_DECL: + case XML_XINCLUDE_START: + case XML_XINCLUDE_END: +#ifdef LIBXML_DOCB_ENABLED + case XML_DOCB_DOCUMENT_NODE: +#endif + break; } } - if (isRunning()) { - if (!html.saveHTML(msg->description)) { -#ifdef FEEDREADER_DEBUG - std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot dump html" << std::endl; -#endif - result = false; - } - } else { -#ifdef FEEDREADER_DEBUG - std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") no root element" << std::endl; -#endif - result = false; + std::list::iterator nodeIt; + for (nodeIt = nodesToDelete.begin(); nodeIt != nodesToDelete.end(); ++nodeIt) { + xmlFreeNode(*nodeIt); } + nodesToDelete.clear(); + + if (!feed.preview) { + result = processXPath(feed.xpathsToUse.ids, feed.xpathsToRemove.ids, html, errorString); + } + + if (result == RS_FEED_ERRORSTATE_OK) { + unsigned int xpathCount; + unsigned int xpathIndex; + XPathWrapper *xpath = html.createXPath(); + if (xpath) { + /* process images */ + if (xpath->compile("//img")) { + xpathCount = xpath->count(); + for (xpathIndex = 0; xpathIndex < xpathCount; ++xpathIndex) { + xmlNodePtr node = xpath->node(xpathIndex); + + if (node->type == XML_ELEMENT_NODE) { + bool removeImage = true; + + if (feed.flag & RS_FEED_FLAG_EMBED_IMAGES) { + /* embed image */ + std::string src = html.getAttr(node, "src"); + if (!src.empty()) { + /* download image */ +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") download image " << src << std::endl; +#endif + std::vector data; + CURLWrapper CURL(proxy); + CURLcode code = CURL.downloadBinary(calculateLink(url, src), data); + if (code == CURLE_OK && CURL.responseCode() == 200) { + std::string contentType = CURL.contentType(); + if (isContentType(contentType, "image/")) { + std::string base64; + if (toBase64(data, base64)) { + std::string imageBase64; + rs_sprintf(imageBase64, "data:%s;base64,%s", contentType.c_str(), base64.c_str()); + if (html.setAttr(node, "src", imageBase64.c_str())) { + removeImage = false; + } + } + } + } + } + } + + if (removeImage) { + /* remove image */ + xmlUnlinkNode(node); + nodesToDelete.push_back(node); + continue; + } + } + } + } else { + // unable to compile xpath expression + result = RS_FEED_ERRORSTATE_PROCESS_XPATH_INTERNAL_ERROR; + } + delete(xpath); + xpath = NULL; + } else { + // unable to create xpath object + result = RS_FEED_ERRORSTATE_PROCESS_XPATH_INTERNAL_ERROR; + std::cerr << "p3FeedReaderThread::process - feed " << feed.feedId << " (" << feed.name << "), unable to create xpath object" << std::endl; + } + } + + for (nodeIt = nodesToDelete.begin(); nodeIt != nodesToDelete.end(); ++nodeIt) { + xmlFreeNode(*nodeIt); + } + nodesToDelete.clear(); + + if (result == RS_FEED_ERRORSTATE_OK) { + if (isRunning()) { + if (!html.saveHTML(msg->description)) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot dump html" << std::endl; +#endif + result = RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR; + } + } + } + } else { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") no root element" << std::endl; +#endif + result = RS_FEED_ERRORSTATE_PROCESS_HTML_ERROR; } + } else { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot read html" << std::endl; +#endif + result = RS_FEED_ERRORSTATE_PROCESS_HTML_ERROR; + } + + return result; +} + +RsFeedReaderErrorState p3FeedReaderThread::processXPath(const std::list &xpathsToUse, const std::list &xpathsToRemove, HTMLWrapper &html, std::string &errorString) +{ + long todo_fill_errorString; + + if (xpathsToUse.empty() && xpathsToRemove.empty()) { + return RS_FEED_ERRORSTATE_OK; + } + + XPathWrapper *xpath = html.createXPath(); + if (xpath == NULL) { + // unable to create xpath object + std::cerr << "p3FeedReaderThread::processXPath - unable to create xpath object" << std::endl; + return RS_FEED_ERRORSTATE_PROCESS_XPATH_INTERNAL_ERROR; + } + + RsFeedReaderErrorState result = RS_FEED_ERRORSTATE_OK; + + unsigned int xpathCount; + unsigned int xpathIndex; + std::list::const_iterator xpathIt; + + if (!xpathsToUse.empty()) { + HTMLWrapper htmlNew; + if (htmlNew.createHTML()) { + xmlNodePtr body = htmlNew.getBody(); + if (body) { + /* process use list */ + for (xpathIt = xpathsToUse.begin(); xpathIt != xpathsToUse.end(); ++xpathIt) { + if (xpath->compile(xpathIt->c_str())) { + xpathCount = xpath->count(); + if (xpathCount) { + for (xpathIndex = 0; xpathIndex < xpathCount; ++xpathIndex) { + xmlNodePtr node = xpath->node(xpathIndex); + xmlUnlinkNode(node); + xmlAddChild(body, node); + } + } else { + result = RS_FEED_ERRORSTATE_PROCESS_XPATH_NO_RESULT; + errorString = *xpathIt; + break; + } + } else { + // unable to process xpath expression +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::processXPath - unable to process xpath expression" << std::endl; +#endif + errorString = *xpathIt; + result = RS_FEED_ERRORSTATE_PROCESS_XPATH_WRONG_EXPRESSION; + } + } + } else { + result = RS_FEED_ERRORSTATE_PROCESS_HTML_ERROR; + } + } else { + result = RS_FEED_ERRORSTATE_PROCESS_HTML_ERROR; + } + + if (result == RS_FEED_ERRORSTATE_OK) { + html = htmlNew; + } + } + + if (result == RS_FEED_ERRORSTATE_OK) { + std::list nodesToDelete; + + /* process remove list */ + for (xpathIt = xpathsToRemove.begin(); xpathIt != xpathsToRemove.end(); ++xpathIt) { + if (xpath->compile(xpathIt->c_str())) { + xpathCount = xpath->count(); + if (xpathCount) { + for (xpathIndex = 0; xpathIndex < xpathCount; ++xpathIndex) { + xmlNodePtr node = xpath->node(xpathIndex); + + xmlUnlinkNode(node); + nodesToDelete.push_back(node); + } + } else { + result = RS_FEED_ERRORSTATE_PROCESS_XPATH_NO_RESULT; + errorString = *xpathIt; + break; + } + } else { + // unable to process xpath expression +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::processXPath - unable to process xpath expression" << std::endl; +#endif + errorString = *xpathIt; + return RS_FEED_ERRORSTATE_PROCESS_XPATH_WRONG_EXPRESSION; + } + } + + std::list::iterator nodeIt; + for (nodeIt = nodesToDelete.begin(); nodeIt != nodesToDelete.end(); ++nodeIt) { + xmlFreeNode(*nodeIt); + } + nodesToDelete.clear(); + } + + return result; +} + +RsFeedReaderErrorState p3FeedReaderThread::processXPath(const std::list &xpathsToUse, const std::list &xpathsToRemove, std::string &description, std::string &errorString) +{ + if (xpathsToUse.empty() && xpathsToRemove.empty()) { + return RS_FEED_ERRORSTATE_OK; + } + + RsFeedReaderErrorState result = RS_FEED_ERRORSTATE_OK; + + long todo_fill_errorString; + + /* process description */ + long todo; // encoding + HTMLWrapper html; + if (html.readHTML(description.c_str(), "")) { + xmlNodePtr root = html.getRootElement(); + if (root) { + result = processXPath(xpathsToUse, xpathsToRemove, html, errorString); + + if (result == RS_FEED_ERRORSTATE_OK) { + if (!html.saveHTML(description)) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::processXPath - cannot dump html" << std::endl; +#endif + result = RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR; + } + } + } else { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::processXPath - no root element" << std::endl; +#endif + result = RS_FEED_ERRORSTATE_PROCESS_HTML_ERROR; + } + } else { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::processXPath - cannot read html" << std::endl; +#endif + result = RS_FEED_ERRORSTATE_PROCESS_HTML_ERROR; } return result; diff --git a/plugins/FeedReader/services/p3FeedReaderThread.h b/plugins/FeedReader/services/p3FeedReaderThread.h index 5da053fd0..9e3e926b9 100644 --- a/plugins/FeedReader/services/p3FeedReaderThread.h +++ b/plugins/FeedReader/services/p3FeedReaderThread.h @@ -22,12 +22,16 @@ #ifndef P3_FEEDREADERTHREAD #define P3_FEEDREADERTHREAD +#include "interface/rsFeedReader.h" + #include "util/rsthreads.h" #include class p3FeedReader; class RsFeedReaderFeed; class RsFeedReaderMsg; +class HTMLWrapper; +class RsFeedReaderXPath; class p3FeedReaderThread : public RsThread { @@ -37,20 +41,6 @@ public: DOWNLOAD, PROCESS }; - enum DownloadResult - { - DOWNLOAD_SUCCESS, - DOWNLOAD_ERROR, - DOWNLOAD_UNKNOWN_CONTENT_TYPE, - DOWNLOAD_NOT_FOUND, - DOWNLOAD_UNKOWN_RESPONSE_CODE - }; - enum ProcessResult - { - PROCESS_SUCCESS, - PROCESS_ERROR_INIT, - PROCESS_UNKNOWN_FORMAT - }; public: p3FeedReaderThread(p3FeedReader *feedReader, Type type, const std::string &feedId); @@ -58,14 +48,17 @@ public: std::string getFeedId() { return mFeedId; } + static RsFeedReaderErrorState processXPath(const std::list &xpathsToUse, const std::list &xpathsToRemove, std::string &description, std::string &errorString); + static RsFeedReaderErrorState processXPath(const std::list &xpathsToUse, const std::list &xpathsToRemove, HTMLWrapper &html, std::string &errorString); + private: virtual void run(); - DownloadResult download(const RsFeedReaderFeed &feed, std::string &content, std::string &icon, std::string &error); - ProcessResult process(const RsFeedReaderFeed &feed, std::list &entries, std::string &error); + RsFeedReaderErrorState download(const RsFeedReaderFeed &feed, std::string &content, std::string &icon, std::string &error); + RsFeedReaderErrorState process(const RsFeedReaderFeed &feed, std::list &entries, std::string &error); std::string getProxyForFeed(const RsFeedReaderFeed &feed); - bool processMsg(const RsFeedReaderFeed &feed, RsFeedReaderMsg *msg); + RsFeedReaderErrorState processMsg(const RsFeedReaderFeed &feed, RsFeedReaderMsg *msg, std::string &errorString); p3FeedReader *mFeedReader; Type mType; diff --git a/plugins/FeedReader/services/rsFeedReaderItems.cc b/plugins/FeedReader/services/rsFeedReaderItems.cc index 2183ffcdd..1d5f60cdd 100644 --- a/plugins/FeedReader/services/rsFeedReaderItems.cc +++ b/plugins/FeedReader/services/rsFeedReaderItems.cc @@ -25,7 +25,9 @@ /*************************************************************************/ -RsFeedReaderFeed::RsFeedReaderFeed() : RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_FEEDREADER_CONFIG, RS_PKT_SUBTYPE_FEEDREADER_FEED) +RsFeedReaderFeed::RsFeedReaderFeed() + : RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_PLUGIN_FEEDREADER, RS_PKT_SUBTYPE_FEEDREADER_FEED), + xpathsToUse(TLV_TYPE_STRINGSET), xpathsToRemove(TLV_TYPE_STRINGSET) { clear(); } @@ -49,6 +51,8 @@ void RsFeedReaderFeed::clear() icon.clear(); errorState = RS_FEED_ERRORSTATE_OK; errorString.clear(); + xpathsToUse.ids.clear(); + xpathsToRemove.ids.clear(); preview = false; workstate = WAITING; @@ -63,6 +67,7 @@ std::ostream &RsFeedReaderFeed::print(std::ostream &out, uint16_t /*indent*/) uint32_t RsFeedReaderSerialiser::sizeFeed(RsFeedReaderFeed *item) { uint32_t s = 8; /* header */ + s += 2; /* version */ s += GetTlvStringSize(item->feedId); s += GetTlvStringSize(item->parentId); s += GetTlvStringSize(item->url); @@ -80,6 +85,8 @@ uint32_t RsFeedReaderSerialiser::sizeFeed(RsFeedReaderFeed *item) s += GetTlvStringSize(item->forumId); s += sizeof(uint32_t); /* errorstate */ s += GetTlvStringSize(item->errorString); + s += item->xpathsToUse.TlvSize(); + s += item->xpathsToRemove.TlvSize(); return s; } @@ -103,6 +110,7 @@ bool RsFeedReaderSerialiser::serialiseFeed(RsFeedReaderFeed *item, void *data, u offset += 8; /* add values */ + ok &= setRawUInt16(data, tlvsize, &offset, 0); /* version */ ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_GENID, item->feedId); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->parentId); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_LINK, item->url); @@ -120,6 +128,8 @@ bool RsFeedReaderSerialiser::serialiseFeed(RsFeedReaderFeed *item, void *data, u ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->forumId); ok &= setRawUInt32(data, tlvsize, &offset, item->errorState); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->errorString); + ok &= item->xpathsToUse.SetTlv(data, tlvsize, &offset); + ok &= item->xpathsToRemove.SetTlv(data, tlvsize, &offset); if (offset != tlvsize) { @@ -138,9 +148,8 @@ RsFeedReaderFeed *RsFeedReaderSerialiser::deserialiseFeed(void *data, uint32_t * uint32_t offset = 0; - if ((RS_PKT_VERSION1 != getRsItemVersion(rstype)) || - (RS_PKT_CLASS_CONFIG != getRsItemClass(rstype)) || - (RS_PKT_TYPE_FEEDREADER_CONFIG != getRsItemType(rstype)) || + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_TYPE_PLUGIN_FEEDREADER != getRsItemService(rstype)) || (RS_PKT_SUBTYPE_FEEDREADER_FEED != getRsItemSubType(rstype))) { return NULL; /* wrong type */ @@ -162,6 +171,8 @@ RsFeedReaderFeed *RsFeedReaderSerialiser::deserialiseFeed(void *data, uint32_t * offset += 8; /* get values */ + uint16_t version = 0; + ok &= getRawUInt16(data, rssize, &offset, &version); ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_GENID, item->feedId); ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_VALUE, item->parentId); ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_LINK, item->url); @@ -181,6 +192,8 @@ RsFeedReaderFeed *RsFeedReaderSerialiser::deserialiseFeed(void *data, uint32_t * ok &= getRawUInt32(data, rssize, &offset, &errorState); item->errorState = (RsFeedReaderErrorState) errorState; ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_VALUE, item->errorString); + ok &= item->xpathsToUse.GetTlv(data, rssize, &offset); + ok &= item->xpathsToRemove.GetTlv(data, rssize, &offset); if (offset != rssize) { @@ -200,7 +213,7 @@ RsFeedReaderFeed *RsFeedReaderSerialiser::deserialiseFeed(void *data, uint32_t * /*************************************************************************/ -RsFeedReaderMsg::RsFeedReaderMsg() : RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_FEEDREADER_CONFIG, RS_PKT_SUBTYPE_FEEDREADER_MSG) +RsFeedReaderMsg::RsFeedReaderMsg() : RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_PLUGIN_FEEDREADER, RS_PKT_SUBTYPE_FEEDREADER_MSG) { clear(); } @@ -225,6 +238,7 @@ std::ostream &RsFeedReaderMsg::print(std::ostream &out, uint16_t /*indent*/) uint32_t RsFeedReaderSerialiser::sizeMsg(RsFeedReaderMsg *item) { uint32_t s = 8; /* header */ + s += 2; /* version */ s += GetTlvStringSize(item->msgId); s += GetTlvStringSize(item->feedId); s += GetTlvStringSize(item->title); @@ -256,6 +270,7 @@ bool RsFeedReaderSerialiser::serialiseMsg(RsFeedReaderMsg *item, void *data, uin offset += 8; /* add values */ + ok &= setRawUInt16(data, tlvsize, &offset, 0); /* version */ ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_GENID, item->msgId); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->feedId); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, item->title); @@ -282,9 +297,8 @@ RsFeedReaderMsg *RsFeedReaderSerialiser::deserialiseMsg(void *data, uint32_t *pk uint32_t offset = 0; - if ((RS_PKT_VERSION1 != getRsItemVersion(rstype)) || - (RS_PKT_CLASS_CONFIG != getRsItemClass(rstype)) || - (RS_PKT_TYPE_FEEDREADER_CONFIG != getRsItemType(rstype)) || + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_TYPE_PLUGIN_FEEDREADER != getRsItemService(rstype)) || (RS_PKT_SUBTYPE_FEEDREADER_MSG != getRsItemSubType(rstype))) { return NULL; /* wrong type */ @@ -306,6 +320,8 @@ RsFeedReaderMsg *RsFeedReaderSerialiser::deserialiseMsg(void *data, uint32_t *pk offset += 8; /* get values */ + uint16_t version = 0; + ok &= getRawUInt16(data, rssize, &offset, &version); ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_GENID, item->msgId); ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_VALUE, item->feedId); ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, item->title); @@ -372,9 +388,8 @@ RsItem *RsFeedReaderSerialiser::deserialise(void *data, uint32_t *pktsize) /* get the type and size */ uint32_t rstype = getRsItemId(data); - if ((RS_PKT_VERSION1 != getRsItemVersion(rstype)) || - (RS_PKT_CLASS_CONFIG != getRsItemClass(rstype)) || - (RS_PKT_TYPE_FEEDREADER_CONFIG != getRsItemType(rstype))) + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_TYPE_PLUGIN_FEEDREADER != getRsItemService(rstype))) { return NULL; /* wrong type */ } diff --git a/plugins/FeedReader/services/rsFeedReaderItems.h b/plugins/FeedReader/services/rsFeedReaderItems.h index 3a2e720c3..847034456 100644 --- a/plugins/FeedReader/services/rsFeedReaderItems.h +++ b/plugins/FeedReader/services/rsFeedReaderItems.h @@ -22,11 +22,14 @@ #ifndef RS_FEEDREADER_ITEMS_H #define RS_FEEDREADER_ITEMS_H +#include "serialiser/rsserviceids.h" #include "serialiser/rsserial.h" #include "serialiser/rstlvtypes.h" #include "p3FeedReader.h" +const uint32_t CONFIG_TYPE_FEEDREADER = 0x0001; // is this correct? + const uint8_t RS_PKT_SUBTYPE_FEEDREADER_FEED = 0x02; const uint8_t RS_PKT_SUBTYPE_FEEDREADER_MSG = 0x03; @@ -80,12 +83,15 @@ public: RsFeedReaderErrorState errorState; std::string errorString; + RsTlvStringSet xpathsToUse; + RsTlvStringSet xpathsToRemove; + /* Not Serialised */ bool preview; WorkState workstate; std::string content; - std::map mMsgs; + std::map msgs; }; #define RS_FEEDMSG_FLAG_DELETED 1 @@ -114,7 +120,7 @@ public: class RsFeedReaderSerialiser: public RsSerialType { public: - RsFeedReaderSerialiser() : RsSerialType(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_FEEDREADER_CONFIG) {} + RsFeedReaderSerialiser() : RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_PLUGIN_FEEDREADER) {} virtual ~RsFeedReaderSerialiser() {} virtual uint32_t size(RsItem *item); diff --git a/plugins/FeedReader/util/HTMLWrapper.cpp b/plugins/FeedReader/util/HTMLWrapper.cpp index 2722af72e..12c7c727a 100644 --- a/plugins/FeedReader/util/HTMLWrapper.cpp +++ b/plugins/FeedReader/util/HTMLWrapper.cpp @@ -32,7 +32,7 @@ bool HTMLWrapper::readHTML(const char *html, const char *url) { cleanup(); - mDocument = htmlReadMemory(html, strlen(html), url, "", HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING/* | HTML_PARSE_COMPACT*/); + mDocument = htmlReadMemory(html, strlen(html), url, "", HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING | HTML_PARSE_COMPACT | HTML_PARSE_NONET | HTML_PARSE_NOBLANKS); if (mDocument) { return true; } @@ -58,3 +58,18 @@ bool HTMLWrapper::saveHTML(std::string &html) return false; } + +bool HTMLWrapper::createHTML() +{ + /* easy way */ + return readHTML("", ""); +} + +xmlNodePtr HTMLWrapper::getBody() +{ + xmlNodePtr root = getRootElement(); + if (!root) { + return NULL; + } + return findNode(root->children, "body", false); +} diff --git a/plugins/FeedReader/util/HTMLWrapper.h b/plugins/FeedReader/util/HTMLWrapper.h index e93552da8..a19b8313f 100644 --- a/plugins/FeedReader/util/HTMLWrapper.h +++ b/plugins/FeedReader/util/HTMLWrapper.h @@ -31,6 +31,10 @@ public: bool readHTML(const char *html, const char *url); bool saveHTML(std::string &html); + + bool createHTML(); + + xmlNodePtr getBody(); }; #endif diff --git a/plugins/FeedReader/util/XMLWrapper.cpp b/plugins/FeedReader/util/XMLWrapper.cpp index ddb5a02fc..c1a4b2143 100644 --- a/plugins/FeedReader/util/XMLWrapper.cpp +++ b/plugins/FeedReader/util/XMLWrapper.cpp @@ -23,6 +23,7 @@ #include #include "XMLWrapper.h" +#include "XPathWrapper.h" XMLWrapper::XMLWrapper() { @@ -41,6 +42,18 @@ XMLWrapper::~XMLWrapper() xmlCharEncCloseFunc(mCharEncodingHandler); } +XMLWrapper &XMLWrapper::operator=(const XMLWrapper &xml) +{ + cleanup(); + + const xmlDocPtr document = xml.getDocument(); + if (document) { + mDocument = xmlCopyDoc(document, 1); + } + + return *this; +} + void XMLWrapper::cleanup() { if (mDocument) { @@ -73,7 +86,7 @@ bool XMLWrapper::convertFromString(const char *text, xmlChar *&xmlText) xmlBufferPtr in = xmlBufferCreateStatic((void*) text, strlen(text)); xmlBufferPtr out = xmlBufferCreate(); - int ret = xmlCharEncOutFunc(mCharEncodingHandler, out, in); + int ret = xmlCharEncInFunc(mCharEncodingHandler, out, in); if (ret >= 0) { result = true; xmlText = xmlBufferDetach(out); @@ -85,7 +98,12 @@ bool XMLWrapper::convertFromString(const char *text, xmlChar *&xmlText) return result; } -xmlNodePtr XMLWrapper::getRootElement() +xmlDocPtr XMLWrapper::getDocument() const +{ + return mDocument; +} + +xmlNodePtr XMLWrapper::getRootElement() const { if (mDocument) { return xmlDocGetRootElement(mDocument); @@ -98,7 +116,7 @@ bool XMLWrapper::readXML(const char *xml) { cleanup(); - mDocument = xmlReadDoc((const xmlChar*) xml, "", NULL, XML_PARSE_NOERROR | XML_PARSE_NOWARNING/* | XML_PARSE_COMPACT | XML_PARSE_NOCDATA*/); + mDocument = xmlReadDoc(BAD_CAST xml, "", NULL, XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_COMPACT | XML_PARSE_NOENT | XML_PARSE_NOCDATA); if (mDocument) { return true; } @@ -114,7 +132,7 @@ bool XMLWrapper::getContent(xmlNodePtr node, std::string &content) return false; } - xmlChar *xmlContent = xmlNodeListGetString(mDocument, node, 1); + xmlChar *xmlContent = xmlNodeGetContent(node); if (!xmlContent) { return true; } @@ -125,6 +143,23 @@ bool XMLWrapper::getContent(xmlNodePtr node, std::string &content) return result; } +bool XMLWrapper::setContent(xmlNodePtr node, const char *content) +{ + if (!node) { + return false; + } + + xmlChar *xmlContent; + if (!convertFromString(content, xmlContent)) { + return false; + } + + xmlNodeSetContent(node, xmlContent); + xmlFree(xmlContent); + + return true; +} + std::string XMLWrapper::nodeName(xmlNodePtr node) { std::string name; @@ -150,7 +185,7 @@ std::string XMLWrapper::attrName(xmlAttrPtr attr) xmlNodePtr XMLWrapper::findNode(xmlNodePtr node, const char *name, bool children) { if (node->name) { - if (xmlStrcasecmp(node->name, (xmlChar*) name) == 0) { + if (xmlStrEqual(node->name, BAD_CAST name)) { return node; } } @@ -218,7 +253,7 @@ std::string XMLWrapper::getAttr(xmlNodePtr node, const char *name) std::string value; - xmlChar *xmlValue = xmlGetProp(node, (const xmlChar*) name); + xmlChar *xmlValue = xmlGetProp(node, BAD_CAST name); if (xmlValue) { convertToString(xmlValue, value); xmlFree(xmlValue); @@ -238,8 +273,17 @@ bool XMLWrapper::setAttr(xmlNodePtr node, const char *name, const char *value) return false; } - xmlAttrPtr xmlAttr = xmlSetProp (node, (const xmlChar*) name, xmlValue); + xmlAttrPtr xmlAttr = xmlSetProp (node, BAD_CAST name, xmlValue); xmlFree(xmlValue); return xmlAttr != NULL; } + +XPathWrapper *XMLWrapper::createXPath() +{ + if (mDocument) { + return new XPathWrapper(*this); + } + + return NULL; +} diff --git a/plugins/FeedReader/util/XMLWrapper.h b/plugins/FeedReader/util/XMLWrapper.h index 8a896d44c..6b94ea796 100644 --- a/plugins/FeedReader/util/XMLWrapper.h +++ b/plugins/FeedReader/util/XMLWrapper.h @@ -25,16 +25,23 @@ #include #include +class XPathWrapper; + class XMLWrapper { public: XMLWrapper(); ~XMLWrapper(); + XMLWrapper &operator=(const XMLWrapper &xml); + void cleanup(); bool readXML(const char *xml); + xmlDocPtr getDocument() const; + xmlNodePtr getRootElement() const; + std::string nodeName(xmlNodePtr node); std::string attrName(xmlAttrPtr attr); @@ -42,19 +49,20 @@ public: bool getChildText(xmlNodePtr node, const char *childName, std::string &text); bool getContent(xmlNodePtr node, std::string &content); + bool setContent(xmlNodePtr node, const char *content); std::string getAttr(xmlNodePtr node, xmlAttrPtr attr); std::string getAttr(xmlNodePtr node, const char *name); bool setAttr(xmlNodePtr node, const char *name, const char *value); - xmlNodePtr getRootElement(); + XPathWrapper *createXPath(); + + bool convertToString(const xmlChar *xmlText, std::string &text); + bool convertFromString(const char *text, xmlChar *&xmlText); protected: xmlDocPtr mDocument; xmlCharEncodingHandlerPtr mCharEncodingHandler; - - bool convertToString(const xmlChar *xmlText, std::string &text); - bool convertFromString(const char *text, xmlChar *&xmlText); }; #endif diff --git a/plugins/FeedReader/util/XPathWrapper.cpp b/plugins/FeedReader/util/XPathWrapper.cpp new file mode 100644 index 000000000..103790493 --- /dev/null +++ b/plugins/FeedReader/util/XPathWrapper.cpp @@ -0,0 +1,102 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include "XPathWrapper.h" +#include "XMLWrapper.h" + +XPathWrapper::XPathWrapper(XMLWrapper &xmlWrapper) : mXMLWrapper(xmlWrapper) +{ + mContext = NULL; + mResult = NULL; +} + +XPathWrapper::~XPathWrapper() +{ + cleanup(); +} + +void XPathWrapper::cleanup() +{ + if (mResult) { + xmlXPathFreeObject(mResult); + mResult = NULL; + } + if (mContext) { + xmlXPathFreeContext(mContext); + mContext = NULL; + } +} + +bool XPathWrapper::compile(const char *expression) +{ + cleanup(); + + xmlDocPtr document = mXMLWrapper.getDocument(); + if (!document) { + return false; + } + + mContext = xmlXPathNewContext(document); + if (!mContext) { + cleanup(); + return false; + } + + xmlChar *xmlExpression = NULL; + if (!mXMLWrapper.convertFromString(expression, xmlExpression)) { + cleanup(); + return false; + } + mResult = xmlXPathEvalExpression(xmlExpression, mContext); + xmlFree(xmlExpression); + + return true; +} + +unsigned int XPathWrapper::count() +{ + if (!mResult) { + return 0; + } + + if (xmlXPathNodeSetIsEmpty(mResult->nodesetval)) { + return 0; + } + + return mResult->nodesetval->nodeNr; +} + +xmlNodePtr XPathWrapper::node(unsigned int index) +{ + if (!mResult) { + return NULL; + } + + if (xmlXPathNodeSetIsEmpty(mResult->nodesetval)) { + return NULL; + } + + if (index >= (unsigned int) mResult->nodesetval->nodeNr) { + return NULL; + } + + return mResult->nodesetval->nodeTab[index]; +} diff --git a/plugins/FeedReader/util/XPathWrapper.h b/plugins/FeedReader/util/XPathWrapper.h new file mode 100644 index 000000000..1c30df1aa --- /dev/null +++ b/plugins/FeedReader/util/XPathWrapper.h @@ -0,0 +1,51 @@ +/**************************************************************** + * RetroShare GUI is distributed under the following license: + * + * Copyright (C) 2012 by Thunder + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#ifndef XPATHWRAPPER +#define XPATHWRAPPER + +#include + +class XMLWrapper; + +class XPathWrapper +{ + friend class XMLWrapper; + +public: + ~XPathWrapper(); + + void cleanup(); + + bool compile(const char *expression); + + unsigned int count(); + xmlNodePtr node(unsigned int index); + +protected: + XPathWrapper(XMLWrapper &xmlWrapper); + + XMLWrapper &mXMLWrapper; + xmlXPathContextPtr mContext; + xmlXPathObjectPtr mResult; +}; + +#endif From 3cbef49b8eec32c655b98d9444c541fdac20bb92 Mon Sep 17 00:00:00 2001 From: drbob Date: Sat, 8 Sep 2012 10:35:40 +0000 Subject: [PATCH 053/222] Restored libretroshare.pro, Sorry Chris - your cleaned-up version breaks my build. removed some debug out from rsdir / and dht. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5525 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/dht/p3bitdht_peernet.cc | 2 + libretroshare/src/libretroshare.pro | 355 ++++++++++++---------- libretroshare/src/util/rsdir.cc | 4 +- 3 files changed, 199 insertions(+), 162 deletions(-) diff --git a/libretroshare/src/dht/p3bitdht_peernet.cc b/libretroshare/src/dht/p3bitdht_peernet.cc index f1fd4c945..16f73e269 100644 --- a/libretroshare/src/dht/p3bitdht_peernet.cc +++ b/libretroshare/src/dht/p3bitdht_peernet.cc @@ -1111,6 +1111,7 @@ int p3BitDht::minuteTick() double denom = deltaT; +#ifdef SHOW_RATES std::cerr << "p3BitDht::minuteTick() "; std::cerr << "DhtRead: " << dhtRead / denom << " kB/s "; std::cerr << "DhtWrite: " << dhtWrite / denom << " kB/s "; @@ -1121,6 +1122,7 @@ int p3BitDht::minuteTick() std::cerr << "RelayWrite: " << relayWrite / denom << " kB/s "; std::cerr << "RelayRelayed: " << relayRelayed / denom << " kB/s "; std::cerr << std::endl; +#endif // SHOW_RATES RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 5a7277aa7..376abf581 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -1,176 +1,211 @@ TEMPLATE = lib -#CONFIG += staticlib release -#CONFIG += staticlib testnetwork -CONFIG += staticlib bitdht newcache newservices + +# CONFIG += staticlib release +# CONFIG += staticlib testnetwork +CONFIG += staticlib \ + bitdht CONFIG -= qt TARGET = retroshare -#DEFINES += RSSERIAL_DEBUG CONFIG += test_voip +# GXS Stuff. +CONFIG += newcache +CONFIG += newservices + # Beware: All data of the stripped services are lost -#CONFIG += minimal DEFINES *= PQI_DISABLE_TUNNEL -#ENABLE_CACHE_OPT -minimal { - CONFIG -= use_blogs - - DEFINES += MINIMAL_LIBRS +# ENABLE_CACHE_OPT +profiling { + QMAKE_CXXFLAGS -= -fomit-frame-pointer + QMAKE_CXXFLAGS *= -pg \ + -g \ + -fno-omit-frame-pointer } +release: -profiling { - QMAKE_CXXFLAGS -= -fomit-frame-pointer - QMAKE_CXXFLAGS *= -pg -g -fno-omit-frame-pointer +# UDP and TUNNEL dont work anymore. +# DEFINES *= PQI_DISABLE_UDP +# treat warnings as error for better removing +# QMAKE_CFLAGS += -Werror +# QMAKE_CXXFLAGS += -Werror +testnetwork { + # used in rsserver/rsinit.cc Enabled Port Restrictions, and makes Proxy Port next to Dht Port. + DEFINES *= LOCALNET_TESTING + + # used in tcponudp/udprelay.cc Debugging Info for Relays. + DEFINES *= DEBUG_UDP_RELAY + + # used in tcponudp/udpstunner.[h | cc] enables local stun (careful - modifies class variables). + DEFINES *= UDPSTUN_ALLOW_LOCALNET + + # used in pqi/p3linkmgr.cc prints out extra debug. + DEFINES *= LINKMGR_DEBUG_LINKTYPE + + # used in dht/connectstatebox to reduce connection times and display debug. + # DEFINES *= TESTING_PERIODS + # DEFINES *= DEBUG_CONNECTBOX + QMAKE_CXXFLAGS -= -fomit-frame-pointer + QMAKE_CXXFLAGS -= -O2 + QMAKE_CXXFLAGS *= -g \ + -fno-omit-frame-pointer } - -release { - # UDP and TUNNEL dont work anymore. - #DEFINES *= PQI_DISABLE_UDP -} - - - -testnetwork { - #DEFINES *= PQI_DISABLE_UDP - DEFINES *= PQI_DISABLE_TUNNEL - - # DEFINES *= AUTHSSL_DEBUG GPG_DEBUG - # DEFINES *= CONN_DEBUG - # DEFINES *= P3DISC_DEBUG - - # DEFINES *= PGRP_DEBUG - # DEFINES *= PERSON_DEBUG - - #DEFINES *= DEBUG_UDP_SORTER DEBUG_UDP_LAYER EXTADDRSEARCH_DEBUG - - QMAKE_CXXFLAGS -= -fomit-frame-pointer - QMAKE_CXXFLAGS -= -O2 - QMAKE_CXXFLAGS *= -g -fno-omit-frame-pointer -} - - CONFIG += debug -debug { -# DEFINES *= DEBUG -# DEFINES *= OPENDHT_DEBUG DHT_DEBUG CONN_DEBUG DEBUG_UDP_SORTER P3DISC_DEBUG DEBUG_UDP_LAYER FT_DEBUG EXTADDRSEARCH_DEBUG -# DEFINES *= CONTROL_DEBUG FT_DEBUG DEBUG_FTCHUNK P3TURTLE_DEBUG -# DEFINES *= P3TURTLE_DEBUG -# DEFINES *= NET_DEBUG -# DEFINES *= DISTRIB_DEBUG -# DEFINES *= P3TURTLE_DEBUG FT_DEBUG DEBUG_FTCHUNK MPLEX_DEBUG -# DEFINES *= STATUS_DEBUG SERV_DEBUG RSSERIAL_DEBUG #CONN_DEBUG - - QMAKE_CXXFLAGS -= -O2 -fomit-frame-pointer - QMAKE_CXXFLAGS *= -g -fno-omit-frame-pointer +debug { + # DEFINES *= DEBUG + # DEFINES *= OPENDHT_DEBUG DHT_DEBUG CONN_DEBUG DEBUG_UDP_SORTER P3DISC_DEBUG DEBUG_UDP_LAYER FT_DEBUG EXTADDRSEARCH_DEBUG + # DEFINES *= CONTROL_DEBUG FT_DEBUG DEBUG_FTCHUNK P3TURTLE_DEBUG + # DEFINES *= P3TURTLE_DEBUG + # DEFINES *= NET_DEBUG + # DEFINES *= DISTRIB_DEBUG + # DEFINES *= P3TURTLE_DEBUG FT_DEBUG DEBUG_FTCHUNK MPLEX_DEBUG + # DEFINES *= STATUS_DEBUG SERV_DEBUG RSSERIAL_DEBUG #CONN_DEBUG + QMAKE_CXXFLAGS -= -O2 \ + -fomit-frame-pointer + QMAKE_CXXFLAGS *= -g \ + -fno-omit-frame-pointer +} +bitdht { + HEADERS += dht/p3bitdht.h \ + dht/connectstatebox.h \ + dht/stunaddrassist.h + SOURCES += dht/p3bitdht.cc \ + dht/p3bitdht_interface.cc \ + dht/p3bitdht_peers.cc \ + dht/p3bitdht_peernet.cc \ + dht/p3bitdht_relay.cc \ + dht/connectstatebox.cc + HEADERS += tcponudp/udppeer.h \ + tcponudp/bio_tou.h \ + tcponudp/tcppacket.h \ + tcponudp/tcpstream.h \ + tcponudp/tou.h \ + tcponudp/udpstunner.h \ + tcponudp/udprelay.h + SOURCES += tcponudp/udppeer.cc \ + tcponudp/tcppacket.cc \ + tcponudp/tcpstream.cc \ + tcponudp/tou.cc \ + tcponudp/bss_tou.c \ + tcponudp/udpstunner.cc \ + tcponudp/udprelay.cc + + # These two aren't actually used (and don't compile) .... + # but could be useful later + # tcponudp/udpstunner.h \ + # tcponudp/udpstunner.cc \ + BITDHT_DIR = ../../libbitdht/src + INCLUDEPATH += . \ + $${BITDHT_DIR} + + # The next line if for compliance with debian packages. Keep it! + INCLUDEPATH += ../libbitdht + DEFINES *= RS_USE_BITDHT +} +test_bitdht { + # DISABLE TCP CONNECTIONS... + DEFINES *= P3CONNMGR_NO_TCP_CONNECTIONS + + # NO AUTO CONNECTIONS??? FOR TESTING DHT STATUS. + DEFINES *= P3CONNMGR_NO_AUTO_CONNECTION } -bitdht { - -HEADERS += dht/p3bitdht.h \ - dht/connectstatebox.h \ - dht/stunaddrassist.h - -SOURCES += dht/p3bitdht.cc \ - dht/p3bitdht_interface.cc \ - dht/p3bitdht_peers.cc \ - dht/p3bitdht_peernet.cc \ - dht/p3bitdht_relay.cc \ - dht/connectstatebox.cc - -HEADERS += tcponudp/udppeer.h \ - tcponudp/bio_tou.h \ - tcponudp/tcppacket.h \ - tcponudp/tcpstream.h \ - tcponudp/tou.h \ - tcponudp/udpstunner.h \ - tcponudp/udprelay.h \ - -SOURCES += tcponudp/udppeer.cc \ - tcponudp/tcppacket.cc \ - tcponudp/tcpstream.cc \ - tcponudp/tou.cc \ - tcponudp/bss_tou.c \ - tcponudp/udpstunner.cc \ - tcponudp/udprelay.cc \ - -# These two aren't actually used (and don't compile) .... -# but could be useful later -# -# tcponudp/udpstunner.h \ -# tcponudp/udpstunner.cc \ -# - - - BITDHT_DIR = ../../libbitdht/src - INCLUDEPATH += . $${BITDHT_DIR} - # The next line if for compliance with debian packages. Keep it! - INCLUDEPATH += ../libbitdht - DEFINES *= RS_USE_BITDHT +# ENABLED UDP NOW. +use_blogs { + HEADERS += services/p3blogs.h + SOURCES += services/p3blogs.cc + DEFINES *= RS_USE_BLOGS } - - - -test_bitdht { - # DISABLE TCP CONNECTIONS... - DEFINES *= P3CONNMGR_NO_TCP_CONNECTIONS - - # NO AUTO CONNECTIONS??? FOR TESTING DHT STATUS. - DEFINES *= P3CONNMGR_NO_AUTO_CONNECTION - - # ENABLED UDP NOW. -} - - - - -use_blogs { - - HEADERS += services/p3blogs.h - SOURCES += services/p3blogs.cc - - DEFINES *= RS_USE_BLOGS -} - - - -PUBLIC_HEADERS = retroshare/rsblogs.h \ - retroshare/rschannels.h \ - retroshare/rsdisc.h \ - retroshare/rsdistrib.h \ - retroshare/rsexpr.h \ - retroshare/rsfiles.h \ - retroshare/rsforums.h \ - retroshare/rshistory.h \ - retroshare/rsiface.h \ - retroshare/rsinit.h \ - retroshare/rsplugin.h \ - retroshare/rsloginhandler.h \ - retroshare/rsmsgs.h \ - retroshare/rsnotify.h \ - retroshare/rspeers.h \ - retroshare/rsrank.h \ - retroshare/rsstatus.h \ - retroshare/rsturtle.h \ - retroshare/rstypes.h \ - retroshare/rsdht.h \ - retroshare/rsdsdv.h \ - retroshare/rsconfig.h - +PUBLIC_HEADERS = retroshare/rsblogs.h \ + retroshare/rschannels.h \ + retroshare/rsdisc.h \ + retroshare/rsdistrib.h \ + retroshare/rsexpr.h \ + retroshare/rsfiles.h \ + retroshare/rsforums.h \ + retroshare/rshistory.h \ + retroshare/rsiface.h \ + retroshare/rsinit.h \ + retroshare/rsplugin.h \ + retroshare/rsloginhandler.h \ + retroshare/rsmsgs.h \ + retroshare/rsnotify.h \ + retroshare/rspeers.h \ + retroshare/rsrank.h \ + retroshare/rsstatus.h \ + retroshare/rsturtle.h \ + retroshare/rstypes.h \ + retroshare/rsdht.h \ + retroshare/rsdsdv.h \ + retroshare/rsconfig.h HEADERS += plugins/pluginmanager.h \ - plugins/dlfcn_win32.h \ - serialiser/rspluginitems.h - - - + plugins/dlfcn_win32.h \ + serialiser/rspluginitems.h HEADERS += $$PUBLIC_HEADERS # public headers to be... -HEADERS += retroshare/rsgame.h \ - retroshare/rsphoto.h - +HEADERS += retroshare/rsgame.h \ + retroshare/rsphoto.h # ################################ Linux ########################################## +linux-*:isEmpty(PREFIX) { + PREFIX = /usr \ + } + isEmpty(INC_DIR) { + INC_DIR = $${PREFIX}/include/retroshare/ \ + } + isEmpty(LIB_DIR) { + LIB_DIR = $${PREFIX}/lib/ \ + } + + # These two lines fixe compilation on ubuntu natty. Probably a ubuntu packaging error. + INCLUDEPATH *= /usr/lib/x86_64-linux-gnu/glib-2.0/include/ + INCLUDEPATH *= /usr/lib/i386-linux-gnu/glib-2.0/include/ + OPENPGPSDK_DIR = ../../openpgpsdk/src + INCLUDEPATH *= $${OPENPGPSDK_DIR} \ + ../openpgpsdk + DESTDIR = lib + QMAKE_CXXFLAGS *= -Wall \ + -D_FILE_OFFSET_BITS=64 + QMAKE_CC = g++ + SSL_DIR = /usr/include/openssl + UPNP_DIR = /usr/include/upnp + INCLUDEPATH += . \ + $${SSL_DIR} \ + $${UPNP_DIR} + + # gpg files + system(which gpg-error-config >/dev/null 2>&1):INCLUDEPATH += $$system(gpg-error-config --cflags | sed -e "s/-I//g") + else:message(Could not find gpg-error-config on your system, assuming gpg-error.h is in /usr/include) + system(which gpgme-config >/dev/null 2>&1):INCLUDEPATH += $$system(gpgme-config --cflags | sed -e "s/-I//g") + else:message(Could not find gpgme-config on your system, assuming gpgme.h is in /usr/include) + + # libupnp implementation files + HEADERS += upnp/UPnPBase.h + SOURCES += upnp/UPnPBase.cpp + + # where to put the shared library itself + target.path = $$LIB_DIR + INSTALLS *= target + + # where to put the library's interface + include_rsiface.path = $${INC_DIR} + include_rsiface.files = $$PUBLIC_HEADERS + INSTALLS += include_rsiface + + # CONFIG += version_detail_bash_script + DEFINES *= UBUNTU + INCLUDEPATH += /usr/include/glib-2.0/ \ + /usr/lib/glib-2.0/include + LIBS *= -lgnome-keyring + linux-g++:OBJECTS_DIR = temp/linux-g++/obj + linux-g++-64:OBJECTS_DIR = temp/linux-g++-64/obj + version_detail_bash_script { + QMAKE_EXTRA_TARGETS += write_version_detail + PRE_TARGETDEPS = write_version_detail + write_version_detail.commands = ./version_detail.sh + } # ################### Cross compilation for windows under Linux #################### win32-x-g++ { @@ -227,14 +262,11 @@ HEADERS += retroshare/rsgame.h \ # miniupnp implementation files HEADERS += upnp/upnputil.h SOURCES += upnp/upnputil.c - UPNPC_DIR = ../../../lib/miniupnpc-1.3 - GPG_ERROR_DIR = ../../../lib/libgpg-error-1.7 - GPGME_DIR = ../../../lib/gpgme-1.1.8 - - PTHREADS_DIR = ../../../lib/pthreads-w32-2-8-0-release - ZLIB_DIR = ../../../lib/zlib-1.2.7 - SSL_DIR = ../../../OpenSSL - OPENPGPSDK_DIR = ../../openpgpsdk/src + UPNPC_DIR = ../../../miniupnpc-1.3 + PTHREADS_DIR = ../../../pthreads-w32-2-8-0-release + ZLIB_DIR = ../../../zlib-1.2.3 + SSL_DIR = ../../../openssl-1.0.1c + OPENPGPSDK_DIR = ../../openpgpsdk/src INCLUDEPATH += . \ $${SSL_DIR}/include \ $${UPNPC_DIR} \ @@ -242,7 +274,7 @@ HEADERS += retroshare/rsgame.h \ $${ZLIB_DIR} \ $${OPENPGPSDK_DIR} newcache { - SQLITE_DIR = ../../../../Libraries/sqlite/sqlite-autoconf-3070900 + SQLITE_DIR = ../../../sqlite-autoconf-3071300 INCLUDEPATH += . \ $${SQLITE_DIR} } @@ -596,6 +628,7 @@ HEADERS += retroshare/rsgame.h \ util/contentvalue.h \ gxs/gxscoreserver.h \ gxs/gxssecurity.h + SOURCES += serialiser/rsnxsitems.cc \ gxs/rsdataservice.cc \ gxs/rsgenexchange.cc \ @@ -610,6 +643,7 @@ HEADERS += retroshare/rsgame.h \ gxs/gxscoreserver.cc \ gxs/gxssecurity.cc } + newservices { HEADERS += services/p3photoservice.h \ serialiser/rsphotoitems.h \ @@ -627,6 +661,7 @@ HEADERS += retroshare/rsgame.h \ services/p3posted.h \ services/p3photoserviceV2.h \ retroshare/rsphotoV2.h + SOURCES += services/p3photoservice.cc \ serialiser/rsphotoitems.cc \ services/p3gxsservice.cc \ diff --git a/libretroshare/src/util/rsdir.cc b/libretroshare/src/util/rsdir.cc index ef166eab0..8d8f4765e 100644 --- a/libretroshare/src/util/rsdir.cc +++ b/libretroshare/src/util/rsdir.cc @@ -953,12 +953,12 @@ RsStackFileLock::RsStackFileLock(const std::string& file_path) sleep(1) ; #endif } - std::cerr << "Acquired file handle " << _file_handle << ", lock file:" << file_path << std::endl; + //std::cerr << "Acquired file handle " << _file_handle << ", lock file:" << file_path << std::endl; } RsStackFileLock::~RsStackFileLock() { RsDirUtil::releaseLockFile(_file_handle) ; - std::cerr << "Released file lock with handle " << _file_handle << std::endl; + //std::cerr << "Released file lock with handle " << _file_handle << std::endl; } #if 0 // NOT ENABLED YET! From 138f462669157eed3722f207bb5d434c11493bf4 Mon Sep 17 00:00:00 2001 From: drbob Date: Sat, 8 Sep 2012 10:49:43 +0000 Subject: [PATCH 054/222] Added missing file, and linking to sqlite git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5526 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/RetroShare.pro | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index 4e3c47782..1c1e5c64f 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -10,6 +10,7 @@ CONFIG += posted CONFIG += unfinished CONFIG += gxsgui +#CONFIG += pluginmgr # Other Disabled Bits. #CONFIG += framecatcher @@ -53,6 +54,7 @@ linux-* { LIBS += ../../libretroshare/src/lib/libretroshare.a LIBS += ../../openpgpsdk/src/lib/libops.a -lbz2 LIBS += -lssl -lupnp -lixml -lXss -lgnome-keyring + LIBS += -lsqlite3 LIBS *= -rdynamic DEFINES *= HAVE_XSS # for idle time, libx screensaver extensions DEFINES *= UBUNTU @@ -858,6 +860,7 @@ photoshare { gui/PhotoShare/PhotoDetailsDialog.h \ gui/PhotoShare/PhotoDrop.h \ gui/PhotoShare/PhotoSlideShow.h \ + util/TokenQueueV2.h \ FORMS += gui/PhotoShare/PhotoItem.ui \ gui/PhotoShare/PhotoDialog.ui \ @@ -871,6 +874,7 @@ photoshare { gui/PhotoShare/PhotoDetailsDialog.cpp \ gui/PhotoShare/PhotoDrop.cpp \ gui/PhotoShare/PhotoSlideShow.cpp \ + util/TokenQueueV2.cpp \ } From 277b8e66aecf9f84e25c227cc83fd1258f8840cb Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 9 Sep 2012 11:43:59 +0000 Subject: [PATCH 055/222] Updated proto files: * Added TransferList & Control Download to files.proto * Added Search functionality to search.proto * Cleaned up core a little. * Added Partial Success code. NOTE: Incompatible Changes - be sure to refresh all generated files. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5527 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- rsctrl/src/Makefile | 4 +- rsctrl/src/definition/core.proto | 19 ++- rsctrl/src/definition/files.proto | 214 +++++++++-------------------- rsctrl/src/definition/search.proto | 120 ++++++++++++++++ rsctrl/src/definition/system.proto | 26 +++- 5 files changed, 224 insertions(+), 159 deletions(-) create mode 100644 rsctrl/src/definition/search.proto diff --git a/rsctrl/src/Makefile b/rsctrl/src/Makefile index 103370652..e4353a659 100644 --- a/rsctrl/src/Makefile +++ b/rsctrl/src/Makefile @@ -1,7 +1,7 @@ EXEC = protoc -#PROTO = core.proto peers.proto system.proto chat.proto files.proto gxs.proto msgs.proto -PROTO = core.proto peers.proto system.proto chat.proto +#PROTO = core.proto peers.proto system.proto chat.proto search.proto files.proto gxs.proto msgs.proto +PROTO = core.proto peers.proto system.proto chat.proto search.proto files.proto PROTOPATH = ./definition #CDESTPATH = ./gencc diff --git a/rsctrl/src/definition/core.proto b/rsctrl/src/definition/core.proto index 58d550077..69443af5d 100644 --- a/rsctrl/src/definition/core.proto +++ b/rsctrl/src/definition/core.proto @@ -15,9 +15,11 @@ enum PackageId { PEERS = 1; SYSTEM = 2; CHAT = 3; + SEARCH = 4; + FILES = 5; // BELOW HERE IS STILL BEING DESIGNED. - //FILES = 4; //MSGS = 5; + //TRANSFER = 6; // THEORETICAL ONES. GXS = 1000; @@ -32,9 +34,11 @@ message Status { FAILED = 0; NO_IMPL_YET = 1; INVALID_QUERY = 2; - SUCCESS = 3; - READMSG = 4; + PARTIAL_SUCCESS = 3; + SUCCESS = 4; + READMSG = 5; } + required StatusCode code = 1; optional string msg = 2; } @@ -89,11 +93,12 @@ message Person { message File { required string name = 1; required string hash = 2; - required int64 size = 3; - - optional string path = 4; - optional string avail = 5; + required uint64 size = 3; + // THINK WE DONT WANT THESE HERE... + // BETTER TO KEEP File simple. + //optional string path = 4; + //optional string avail = 5; } message Dir { diff --git a/rsctrl/src/definition/files.proto b/rsctrl/src/definition/files.proto index 1c813b032..5546c2efc 100644 --- a/rsctrl/src/definition/files.proto +++ b/rsctrl/src/definition/files.proto @@ -3,197 +3,115 @@ package rsctrl.files; import "core.proto"; /////////////////////////////////////////////////////////////// -// Mirror most of rsFiles functionality. -// -// Share Directories. -// Searches // List Transfers. // Control Transfers. +// +// TODO: +// Share Directories. /////////////////////////////////////////////////////////////// enum RequestMsgIds { - MsgId_RequestPeers = 1; - MsgId_RequestAddPeer = 2; - MsgId_RequestModifyPeer = 3; + MsgId_RequestTransferList = 1; + MsgId_RequestControlDownload = 2; } enum ResponseMsgIds { - MsgId_ResponsePeerList = 1; - MsgId_ResponseAddPeer = 2; - MsgId_ResponseModifyPeer = 3; + MsgId_ResponseTransferList = 1; + MsgId_ResponseControlDownload = 2; } /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// -// SEARCH (start). -// REQUEST: RequestBasicSearch -message RequestBasicSearch { +// Building Blocks - repeated string terms = 1; +enum Direction { + DIRECTION_UPLOAD = 1; + DIRECTION_DOWNLOAD = 2; } -// REQUEST: RequestAdvSearch -message RequestAdvSearch { +message FileTransfer { - repeated string terms = 1; + required rsctrl.core.File file = 1; + required Direction direction = 2; + required float fraction = 3; + required float rate_kBs = 4; } +/////////////////////////////////////////////////////////////// +// Transfer List. -// RESPONSE: ResponseSearchId -message ResponseSearchId { +// REQUEST: RequestTransferList +message RequestTransferList { + required Direction direction = 1; +} + +// RESPONSE: ResponseTransferList +message ResponseTransferList { required rsctrl.core.Status status = 1; - required string search_id = 2; + repeated FileTransfer transfers = 2; + } /////////////////////////////////////////////////////////////// -// SEARCH (list) +// Download. +// REQUEST: RequestControlDownload +// START requires name, hash & size. +// other actions only require file hash. +message RequestControlDownload { -// REQUEST: RequestSearchResults -message RequestSearchResults { - - enum SetCmd { - ALLIDS = 1; // All - LISTED = 2; // Only Search Ids in the Vector. - } - - required SetCmd set = 1; - repeated string search_ids = 2; -} - -// Building Block -message SearchHit { - - enum LocFlag { - LOCAL = 1; // We Have it. - FRIEND = 2; // Browsable - NETWORK = 4; // Network. + enum Action { + ACTION_START = 1; // start download. + ACTION_CONTINUE = 2; // move to top of queue. + ACTION_WAIT = 3; // send to bottom of queue. + ACTION_PAUSE = 4; // hold indefinitely. + ACTION_RESTART = 5; // end pause, restart download. + ACTION_CHECK = 6; // force check. + ACTION_CANCEL = 7; // remove permenantly. } required rsctrl.core.File file = 1; - required uint32 no_hits = 2; - required LocFlag loc = 3; + required Action action = 2; } -message SearchSet { - - required string search_id = 1; - - enum SearchType { - BASIC = 1; // Stuff. - ADVANCED = 2; // Stuff. - } - - // One of these will be filled in depending on flag. - - required SearchType search_type = 2; - optional RequestBasicSearch basic_req = 3; - optional RequestAdvSearch adv_req = 4; - - repeated SearchHit hits = 5; - -} - -// RESPONSE: ResponseSearchResults -message ResponseSearchResults { - +// RESPONSE: ResponseControlDownload +message ResponseControlDownload { required rsctrl.core.Status status = 1; - repeated SearchSet searches = 2; } -/////////////////////////////////////////////////////////////// -// SEARCH (cancel) - -// REQUEST: RequestCloseSearch -message RequestCloseSearch { - - required string search_id = 2; -} - - -// RESPONSE: ResponseSearchId -// As before. - - /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// // SHARED FILES +// THIS STUFF IS NOT FINISHED YET! +// +//// REQUEST: RequestListShares +//message RequestListShares { +// +// required uint32 depth = 1; // HOW Many Directories to drill down. +// repeated string ShareLocation = 2; +//} +// +//message ShareLocation { +// required string ssl_id = 1; +// required string path = 2; +//} +// +// +// +//// REQUEST: RequestChangeShares +// +//// REQUEST: RequestLiCloseSearch +//// REQUEST: RequestCloseSearch +// -// REQUEST: RequestListShares -message RequestListShares { - - required uint32 depth = 1; // HOW Many Directories to drill down. - repeated string ShareLocation = 2; -} - -message ShareLocation { - required string ssl_id = 1; - required string path = 2; -} - - - -// REQUEST: RequestChangeShares - -// REQUEST: RequestLiCloseSearch -// REQUEST: RequestCloseSearch - - - - -// REQUEST: RequestAddPeer -message RequestAddPeer { - - enum AddCmd { - NOOP = 0; // No op. - ADD = 1; // Add existing from gpg_id. - REMOVE = 2; // Remove existing from gpg_id. - IMPORT = 3; // Import from cert, with gpg_id. - EXAMINE = 4; // Examine cert, but no action. - } - - required string gpg_id = 1; - required AddCmd cmd = 2; - optional string cert = 3; -} - -// RESPONSE: ResponseAddPeer -message ResponseAddPeer { - required rsctrl.core.Status status = 1; - repeated rsctrl.core.Person peers = 2; -} - /////////////////////////////////////////////////////////////// - -// REQUEST: RequestModifyPeer -message RequestModifyPeer { - - enum ModCmd { - NOOP = 0; - ADDRESS = 1; - DYNDNS = 2; - //SOMETHING_ELSE = 0x0000010; - //SOMETHING_ELSE = 0x0000020; - //SOMETHING_ELSE = 0x0000040; - //SOMETHING_ELSE = 0x0000080; - } - - required ModCmd cmd = 1; - //required int64 cmd = 1; // Could we OR the Cmds together? - repeated rsctrl.core.Person peers = 2; -} - -// RESPONSE: ResponseModifyPeer -message ResponseModifyPeer { - required rsctrl.core.Status status = 1; - repeated rsctrl.core.Person peers = 2; -} - +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// diff --git a/rsctrl/src/definition/search.proto b/rsctrl/src/definition/search.proto new file mode 100644 index 000000000..6aecdb49f --- /dev/null +++ b/rsctrl/src/definition/search.proto @@ -0,0 +1,120 @@ +package rsctrl.search; + +import "core.proto"; + +/////////////////////////////////////////////////////////////// +// Searches +/////////////////////////////////////////////////////////////// + +enum RequestMsgIds { + MsgId_RequestBasicSearch = 1; + //MsgId_RequestAdvSearch = 2; // NOT IMPLEMENTED YET. + MsgId_RequestCloseSearch = 3; + MsgId_RequestListSearches = 4; + MsgId_RequestSearchResults = 5; +} + +enum ResponseMsgIds { + MsgId_ResponseSearchIds = 1; + MsgId_ResponseSearchResults = 5; +} + +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +// Building Block +message SearchHit { + + enum LocFlag { + LOCAL = 1; // We Have it. + FRIEND = 2; // Browsable + NETWORK = 4; // Network. + } + + required rsctrl.core.File file = 1; + required uint32 loc = 2; // OR of LocFlag so uint field + required uint32 no_hits = 3; // NOT USED YET. + +} + +message SearchSet { + + required uint32 search_id = 1; + repeated SearchHit hits = 2; + +} + +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +// SEARCH (start). + +// REQUEST: RequestBasicSearch +message RequestBasicSearch { + + repeated string terms = 1; +} + +// REQUEST: RequestAdvSearch +message RequestAdvSearch { + + repeated string terms = 1; +} + + +// RESPONSE: ResponseSearchIds +message ResponseSearchIds { + + required rsctrl.core.Status status = 1; + repeated uint32 search_id = 2; +} + + +/////////////////////////////////////////////////////////////// +// SEARCH (cancel) + +// REQUEST: RequestCloseSearch +message RequestCloseSearch { + + required uint32 search_id = 1; +} + + +// RESPONSE: ResponseSearchIds +// As before. + +/////////////////////////////////////////////////////////////// +// SEARCH (list) + +// REQUEST: RequestListSearches +message RequestListSearches { + // Nothing here. +} + +// RESPONSE: ResponseSearchIds +// As before. + +/////////////////////////////////////////////////////////////// +// SEARCH (list) + + +// REQUEST: RequestSearchResults +// Empty search_ids => all results. +message RequestSearchResults { + + repeated uint32 search_ids = 2; + +} + +// RESPONSE: ResponseSearchResults +message ResponseSearchResults { + + required rsctrl.core.Status status = 1; + repeated SearchSet searches = 2; +} + + +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// + diff --git a/rsctrl/src/definition/system.proto b/rsctrl/src/definition/system.proto index 73ed8da8a..e24e42b29 100644 --- a/rsctrl/src/definition/system.proto +++ b/rsctrl/src/definition/system.proto @@ -8,12 +8,12 @@ import "core.proto"; enum RequestMsgIds { MsgId_RequestSystemStatus = 1; - //MsgId_RequestNetConfig = 2; + MsgId_RequestSystemQuit = 2; } enum ResponseMsgIds { MsgId_ResponseSystemStatus = 1; - //MsgId_ResponseNetConfig = 2; + MsgId_ResponseSystemQuit = 2; } /////////////////////////////////////////////////////////////// @@ -51,6 +51,28 @@ message ResponseSystemStatus { required rsctrl.core.Bandwidth bw_total = 5; } +/////////////////////////////////////////////////////////////// + +// REQUEST: RequestSystemQuit +message RequestSystemQuit { + + enum QuitCode { + CLOSE_CHANNEL = 1; + SHUTDOWN_RS = 2; // NOT RECOMMENDED (but some people might like it) + } + + required QuitCode quit_code = 1; +} + +// RESPONSE: ResponseSystemQuit +// Effect potentially immediate (with loss of connection) - only expect a response error. +// Shutdown takes longer - so you should get a response. +message ResponseSystemQuit { + + // Status of response. + required rsctrl.core.Status status = 1; +} + /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// From a9f95289d047b37838ecc444ae9e029f4a26d1cd Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 9 Sep 2012 11:48:25 +0000 Subject: [PATCH 056/222] Added more RPC functionality: * System: Quit & shutdown. * Search: New Search, List Searches, Close Search, Search Results. * Files: TranferLists, ControlDownloads (Start, Stop, Pause, etc). Changed the way NotifyTxt records search results. * Must register searchId for results to be saved. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5528 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/menu/menus.cc | 17 +- retroshare-nogui/src/menu/menus.h | 6 +- retroshare-nogui/src/notifytxt.cc | 40 +- retroshare-nogui/src/notifytxt.h | 9 +- retroshare-nogui/src/retroshare-nogui.pro | 8 + retroshare-nogui/src/retroshare.cc | 2 +- .../src/rpc/proto/gencc/core.pb.cc | 206 +- .../src/rpc/proto/gencc/core.pb.h | 170 +- .../src/rpc/proto/gencc/files.pb.cc | 1594 +++++++++++ .../src/rpc/proto/gencc/files.pb.h | 930 +++++++ .../src/rpc/proto/gencc/search.pb.cc | 2437 +++++++++++++++++ .../src/rpc/proto/gencc/search.pb.h | 1370 +++++++++ .../src/rpc/proto/gencc/system.pb.cc | 515 +++- .../src/rpc/proto/gencc/system.pb.h | 284 +- .../src/rpc/proto/rpcprotofiles.cc | 344 +++ .../src/rpc/proto/rpcprotofiles.h | 44 + .../src/rpc/proto/rpcprotosearch.cc | 593 ++++ .../src/rpc/proto/rpcprotosearch.h | 64 + .../src/rpc/proto/rpcprotosystem.cc | 71 + .../src/rpc/proto/rpcprotosystem.h | 1 + retroshare-nogui/src/rpc/rpc.cc | 5 + retroshare-nogui/src/rpc/rpc.h | 1 + retroshare-nogui/src/rpc/rpcserver.cc | 5 + retroshare-nogui/src/rpc/rpcserver.h | 9 +- retroshare-nogui/src/rpc/rpcsetup.cc | 10 +- retroshare-nogui/src/rpc/rpcsetup.h | 4 +- 26 files changed, 8402 insertions(+), 337 deletions(-) create mode 100644 retroshare-nogui/src/rpc/proto/gencc/files.pb.cc create mode 100644 retroshare-nogui/src/rpc/proto/gencc/files.pb.h create mode 100644 retroshare-nogui/src/rpc/proto/gencc/search.pb.cc create mode 100644 retroshare-nogui/src/rpc/proto/gencc/search.pb.h create mode 100644 retroshare-nogui/src/rpc/proto/rpcprotofiles.cc create mode 100644 retroshare-nogui/src/rpc/proto/rpcprotofiles.h create mode 100644 retroshare-nogui/src/rpc/proto/rpcprotosearch.cc create mode 100644 retroshare-nogui/src/rpc/proto/rpcprotosearch.h diff --git a/retroshare-nogui/src/menu/menus.cc b/retroshare-nogui/src/menu/menus.cc index fc3b95105..46e044aa6 100644 --- a/retroshare-nogui/src/menu/menus.cc +++ b/retroshare-nogui/src/menu/menus.cc @@ -84,7 +84,7 @@ Menu *CreateMenuStructure(NotifyTxt *notify) MenuList *search = new MenuListSearch(notify); MenuList *searchlist = new MenuListSearchList(notify); - search->addMenuItem(MENU_SEARCH_KEY_ADD, new MenuOpSearchNew()); + search->addMenuItem(MENU_SEARCH_KEY_ADD, new MenuOpSearchNew(notify)); //search->addMenuItem(MENU_SEARCH_KEY_REMOVE, new MenuOpSearchDelete()); search->addMenuItem(MENU_SEARCH_KEY_VIEW, searchlist); searchlist->addMenuItem(MENU_SEARCH_KEY_DOWNLOAD, new MenuOpSearchListDownload()); @@ -362,11 +362,17 @@ int MenuListSearch::removeSearch(std::string strSearchId) it = mSearchIds.find(strSearchId); if (it != mSearchIds.end()) { - /* cleanup local maps */ /* cancel search */ + // CAN'T DO!!! /* clear results from Notify Collector */ + mNotify->clearSearchId(it->second); + + /* cleanup local maps */ + mSearchIds.erase(it); + + /* cleanup terms maps (TODO) */ } return 1; @@ -392,6 +398,7 @@ uint32_t MenuOpSearchNew::process_lines(std::string input) std::string search = input.substr(0, input.size() - 1); // remove \n. uint32_t searchId = (uint32_t) rsTurtle->turtleSearch(search); + mNotify->collectSearchResults(searchId); /* store request in parent */ MenuListSearch *ms = dynamic_cast(parent()); @@ -645,7 +652,7 @@ int MenuListShared::getEntryDesc(int idx, std::string &desc) rsFiles->getSharedDirectories(dirs); std::list::iterator it; std::string shareflag; - unsigned int i=0; + int i=0; for (it = dirs.begin(); (i < idx) && (it != dirs.end()); it++, i++); if (it != dirs.end()) { @@ -675,7 +682,7 @@ int MenuListShared::unshareSelected() std::list dirs; rsFiles->getSharedDirectories(dirs); std::list::iterator it; - unsigned int i=0; + int i=0; for (it = dirs.begin(); (i < mSelectIdx) && (it != dirs.end()); it++, i++); if (it != dirs.end()) { @@ -696,7 +703,7 @@ int MenuListShared::toggleFlagSelected(uint32_t shareflags) std::list dirs; rsFiles->getSharedDirectories(dirs); std::list::iterator it; - unsigned int i=0; + int i=0; for (it = dirs.begin(); (i < mSelectIdx) && (it != dirs.end()); it++, i++); if (it != dirs.end()) { diff --git a/retroshare-nogui/src/menu/menus.h b/retroshare-nogui/src/menu/menus.h index 53ed00a46..757ae208d 100644 --- a/retroshare-nogui/src/menu/menus.h +++ b/retroshare-nogui/src/menu/menus.h @@ -159,11 +159,13 @@ class MenuOpSearchNew: public MenuOpLineInput { public: - MenuOpSearchNew() :MenuOpLineInput("New") { return; } + MenuOpSearchNew(NotifyTxt *notify) + :MenuOpLineInput("New"), mNotify(notify) { return; } virtual uint32_t process_lines(std::string input); virtual uint32_t drawPage(uint32_t drawFlags, std::string &buffer); - +private: + NotifyTxt *mNotify; }; diff --git a/retroshare-nogui/src/notifytxt.cc b/retroshare-nogui/src/notifytxt.cc index 9bc01d1a4..9995d3ba3 100644 --- a/retroshare-nogui/src/notifytxt.cc +++ b/retroshare-nogui/src/notifytxt.cc @@ -230,8 +230,15 @@ void NotifyTxt::notifyTurtleSearchResult(uint32_t search_id,const std::listsecond.size(); } - -int NotifyTxt::clearSearchId(uint32_t searchId) + // only collect results for selected searches. + // will drop others. +int NotifyTxt::collectSearchResults(uint32_t searchId) { + std::cerr << "NotifyTxt::collectSearchResult(" << searchId << ")"; + std::cerr << std::endl; + RsStackMutex stack(mNotifyMtx); /****** LOCKED *****/ std::map >::iterator it; it = mSearchResults.find(searchId); if (it == mSearchResults.end()) { + std::list emptyList; + mSearchResults[searchId] = emptyList; + return 1; + } + + std::cerr << "NotifyTxt::collectSearchResult() ERROR Id exists"; + std::cerr << std::endl; + return 1; +} + +int NotifyTxt::clearSearchId(uint32_t searchId) +{ + std::cerr << "NotifyTxt::clearSearchId(" << searchId << ")"; + std::cerr << std::endl; + + RsStackMutex stack(mNotifyMtx); /****** LOCKED *****/ + + std::map >::iterator it; + it = mSearchResults.find(searchId); + if (it == mSearchResults.end()) + { + std::cerr << "NotifyTxt::clearSearchId() ERROR Id not there"; + std::cerr << std::endl; return 0; } diff --git a/retroshare-nogui/src/notifytxt.h b/retroshare-nogui/src/notifytxt.h index 373f01339..58af71be3 100644 --- a/retroshare-nogui/src/notifytxt.h +++ b/retroshare-nogui/src/notifytxt.h @@ -48,9 +48,14 @@ class NotifyTxt: public NotifyBase /* interface for handling SearchResults */ void getSearchIds(std::list &searchIds); - int getSearchResults(uint32_t id, std::list &searchResults); - int clearSearchId(uint32_t searchId); + int getSearchResultCount(uint32_t id); + int getSearchResults(uint32_t id, std::list &searchResults); + + // only collect results for selected searches. + // will drop others. + int collectSearchResults(uint32_t searchId); + int clearSearchId(uint32_t searchId); private: diff --git a/retroshare-nogui/src/retroshare-nogui.pro b/retroshare-nogui/src/retroshare-nogui.pro index 619531b37..2b9a0a4be 100644 --- a/retroshare-nogui/src/retroshare-nogui.pro +++ b/retroshare-nogui/src/retroshare-nogui.pro @@ -187,21 +187,29 @@ protorpc { HEADERS += rpc/proto/rpcprotopeers.h \ rpc/proto/rpcprotosystem.h \ rpc/proto/rpcprotochat.h \ + rpc/proto/rpcprotosearch.h \ + rpc/proto/rpcprotofiles.h \ SOURCES += rpc/proto/rpcprotopeers.cc \ rpc/proto/rpcprotosystem.cc \ rpc/proto/rpcprotochat.cc \ + rpc/proto/rpcprotosearch.cc \ + rpc/proto/rpcprotofiles.cc \ # Generated ProtoBuf Code the RPC System HEADERS += rpc/proto/gencc/core.pb.h \ rpc/proto/gencc/peers.pb.h \ rpc/proto/gencc/system.pb.h \ rpc/proto/gencc/chat.pb.h \ + rpc/proto/gencc/search.pb.h \ + rpc/proto/gencc/files.pb.h \ SOURCES += rpc/proto/gencc/core.pb.cc \ rpc/proto/gencc/peers.pb.cc \ rpc/proto/gencc/system.pb.cc \ rpc/proto/gencc/chat.pb.cc \ + rpc/proto/gencc/search.pb.cc \ + rpc/proto/gencc/files.pb.cc \ QMAKE_CFLAGS += -pthread QMAKE_CXXFLAGS += -pthread diff --git a/retroshare-nogui/src/retroshare.cc b/retroshare-nogui/src/retroshare.cc index 36fd0172e..d1b6a5abd 100644 --- a/retroshare-nogui/src/retroshare.cc +++ b/retroshare-nogui/src/retroshare.cc @@ -388,7 +388,7 @@ int main(int argc, char **argv) if (enableRpc) { /* Build RPC Server */ - RpcMediator *med = CreateRpcSystem(ssh); + RpcMediator *med = CreateRpcSystem(ssh, notify); ssh->setRpcSystem(med); ssh->setSleepPeriods(0.01, 0.1); } diff --git a/retroshare-nogui/src/rpc/proto/gencc/core.pb.cc b/retroshare-nogui/src/rpc/proto/gencc/core.pb.cc index e95575c67..cb1061f88 100644 --- a/retroshare-nogui/src/rpc/proto/gencc/core.pb.cc +++ b/retroshare-nogui/src/rpc/proto/gencc/core.pb.cc @@ -134,12 +134,10 @@ void protobuf_AssignDesc_core_2eproto() { sizeof(Person)); Person_Relationship_descriptor_ = Person_descriptor_->enum_type(0); File_descriptor_ = file->message_type(4); - static const int File_offsets_[5] = { + static const int File_offsets_[3] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, hash_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, size_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, path_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, avail_), }; File_reflection_ = new ::google::protobuf::internal::GeneratedMessageReflection( @@ -283,39 +281,39 @@ void protobuf_AddDesc_core_2eproto() { GOOGLE_PROTOBUF_VERIFY_VERSION; ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( - "\n\ncore.proto\022\013rsctrl.core\"\233\001\n\006Status\022,\n\004" + "\n\ncore.proto\022\013rsctrl.core\"\260\001\n\006Status\022,\n\004" "code\030\001 \002(\0162\036.rsctrl.core.Status.StatusCo" - "de\022\013\n\003msg\030\002 \001(\t\"V\n\nStatusCode\022\n\n\006FAILED\020" - "\000\022\017\n\013NO_IMPL_YET\020\001\022\021\n\rINVALID_QUERY\020\002\022\013\n" - "\007SUCCESS\020\003\022\013\n\007READMSG\020\004\")\n\006IpAddr\022\016\n\004add" - "r\030\001 \002(\t:\000\022\017\n\004port\030\002 \002(\r:\0010\"\303\001\n\010Location\022" - "\016\n\006ssl_id\030\001 \002(\t\022\020\n\010location\030\002 \002(\t\022&\n\tloc" - "aladdr\030\003 \002(\0132\023.rsctrl.core.IpAddr\022$\n\007ext" - "addr\030\004 \002(\0132\023.rsctrl.core.IpAddr\022\r\n\005state" - "\030\005 \002(\r\"8\n\nStateFlags\022\n\n\006ONLINE\020\001\022\r\n\tCONN" - "ECTED\020\002\022\017\n\013UNREACHABLE\020\004\"\340\001\n\006Person\022\016\n\006g" - "pg_id\030\001 \002(\t\022\014\n\004name\030\002 \002(\t\0222\n\010relation\030\003 " - "\002(\0162 .rsctrl.core.Person.Relationship\022(\n" - "\tlocations\030\004 \003(\0132\025.rsctrl.core.Location\"" - "Z\n\014Relationship\022\n\n\006FRIEND\020\001\022\032\n\026FRIEND_OF" - "_MANY_FRIENDS\020\002\022\025\n\021FRIEND_OF_FRIENDS\020\003\022\013" - "\n\007UNKNOWN\020\004\"M\n\004File\022\014\n\004name\030\001 \002(\t\022\014\n\004has" - "h\030\002 \002(\t\022\014\n\004size\030\003 \002(\003\022\014\n\004path\030\004 \001(\t\022\r\n\005a" - "vail\030\005 \001(\t\"f\n\003Dir\022\014\n\004name\030\001 \002(\t\022\014\n\004path\030" - "\002 \002(\t\022!\n\007subdirs\030\003 \003(\0132\020.rsctrl.core.Dir" - "\022 \n\005files\030\004 \003(\0132\021.rsctrl.core.File\"\372\001\n\014S" - "ystemStatus\0225\n\nnet_status\030\001 \002(\0162!.rsctrl" - ".core.SystemStatus.NetCode\022\013\n\003msg\030\002 \001(\t\"" - "\245\001\n\007NetCode\022\017\n\013BAD_UNKNOWN\020\000\022\017\n\013BAD_OFFL" - "INE\020\001\022\016\n\nBAD_NATSYM\020\002\022\021\n\rBAD_NODHT_NAT\020\003" - "\022\023\n\017WARNING_RESTART\020\004\022\022\n\016WARNING_NATTED\020" - "\005\022\021\n\rWARNING_NODHT\020\006\022\010\n\004GOOD\020\007\022\017\n\013ADV_FO" - "RWARD\020\010\"3\n\tBandwidth\022\n\n\002up\030\001 \002(\002\022\014\n\004down" - "\030\002 \002(\002\022\014\n\004name\030\003 \001(\t\":\n\014BandwidthSet\022*\n\n" - "bandwidths\030\001 \003(\0132\026.rsctrl.core.Bandwidth" - "*\027\n\013ExtensionId\022\010\n\004CORE\020\000*6\n\tPackageId\022\t" - "\n\005PEERS\020\001\022\n\n\006SYSTEM\020\002\022\010\n\004CHAT\020\003\022\010\n\003GXS\020\350" - "\007", 1281); + "de\022\013\n\003msg\030\002 \001(\t\"k\n\nStatusCode\022\n\n\006FAILED\020" + "\000\022\017\n\013NO_IMPL_YET\020\001\022\021\n\rINVALID_QUERY\020\002\022\023\n" + "\017PARTIAL_SUCCESS\020\003\022\013\n\007SUCCESS\020\004\022\013\n\007READM" + "SG\020\005\")\n\006IpAddr\022\016\n\004addr\030\001 \002(\t:\000\022\017\n\004port\030\002" + " \002(\r:\0010\"\303\001\n\010Location\022\016\n\006ssl_id\030\001 \002(\t\022\020\n\010" + "location\030\002 \002(\t\022&\n\tlocaladdr\030\003 \002(\0132\023.rsct" + "rl.core.IpAddr\022$\n\007extaddr\030\004 \002(\0132\023.rsctrl" + ".core.IpAddr\022\r\n\005state\030\005 \002(\r\"8\n\nStateFlag" + "s\022\n\n\006ONLINE\020\001\022\r\n\tCONNECTED\020\002\022\017\n\013UNREACHA" + "BLE\020\004\"\340\001\n\006Person\022\016\n\006gpg_id\030\001 \002(\t\022\014\n\004name" + "\030\002 \002(\t\0222\n\010relation\030\003 \002(\0162 .rsctrl.core.P" + "erson.Relationship\022(\n\tlocations\030\004 \003(\0132\025." + "rsctrl.core.Location\"Z\n\014Relationship\022\n\n\006" + "FRIEND\020\001\022\032\n\026FRIEND_OF_MANY_FRIENDS\020\002\022\025\n\021" + "FRIEND_OF_FRIENDS\020\003\022\013\n\007UNKNOWN\020\004\"0\n\004File" + "\022\014\n\004name\030\001 \002(\t\022\014\n\004hash\030\002 \002(\t\022\014\n\004size\030\003 \002" + "(\004\"f\n\003Dir\022\014\n\004name\030\001 \002(\t\022\014\n\004path\030\002 \002(\t\022!\n" + "\007subdirs\030\003 \003(\0132\020.rsctrl.core.Dir\022 \n\005file" + "s\030\004 \003(\0132\021.rsctrl.core.File\"\372\001\n\014SystemSta" + "tus\0225\n\nnet_status\030\001 \002(\0162!.rsctrl.core.Sy" + "stemStatus.NetCode\022\013\n\003msg\030\002 \001(\t\"\245\001\n\007NetC" + "ode\022\017\n\013BAD_UNKNOWN\020\000\022\017\n\013BAD_OFFLINE\020\001\022\016\n" + "\nBAD_NATSYM\020\002\022\021\n\rBAD_NODHT_NAT\020\003\022\023\n\017WARN" + "ING_RESTART\020\004\022\022\n\016WARNING_NATTED\020\005\022\021\n\rWAR" + "NING_NODHT\020\006\022\010\n\004GOOD\020\007\022\017\n\013ADV_FORWARD\020\010\"" + "3\n\tBandwidth\022\n\n\002up\030\001 \002(\002\022\014\n\004down\030\002 \002(\002\022\014" + "\n\004name\030\003 \001(\t\":\n\014BandwidthSet\022*\n\nbandwidt" + "hs\030\001 \003(\0132\026.rsctrl.core.Bandwidth*\027\n\013Exte" + "nsionId\022\010\n\004CORE\020\000*M\n\tPackageId\022\t\n\005PEERS\020" + "\001\022\n\n\006SYSTEM\020\002\022\010\n\004CHAT\020\003\022\n\n\006SEARCH\020\004\022\t\n\005F" + "ILES\020\005\022\010\n\003GXS\020\350\007", 1296); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "core.proto", &protobuf_RegisterTypes); Status::default_instance_ = new Status(); @@ -368,6 +366,8 @@ bool PackageId_IsValid(int value) { case 1: case 2: case 3: + case 4: + case 5: case 1000: return true; default: @@ -389,6 +389,7 @@ bool Status_StatusCode_IsValid(int value) { case 2: case 3: case 4: + case 5: return true; default: return false; @@ -399,6 +400,7 @@ bool Status_StatusCode_IsValid(int value) { const Status_StatusCode Status::FAILED; const Status_StatusCode Status::NO_IMPL_YET; const Status_StatusCode Status::INVALID_QUERY; +const Status_StatusCode Status::PARTIAL_SUCCESS; const Status_StatusCode Status::SUCCESS; const Status_StatusCode Status::READMSG; const Status_StatusCode Status::StatusCode_MIN; @@ -1782,8 +1784,6 @@ void Person::Swap(Person* other) { const int File::kNameFieldNumber; const int File::kHashFieldNumber; const int File::kSizeFieldNumber; -const int File::kPathFieldNumber; -const int File::kAvailFieldNumber; #endif // !_MSC_VER File::File() @@ -1804,9 +1804,7 @@ void File::SharedCtor() { _cached_size_ = 0; name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); hash_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); - size_ = GOOGLE_LONGLONG(0); - path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); - avail_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + size_ = GOOGLE_ULONGLONG(0); ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -1821,12 +1819,6 @@ void File::SharedDtor() { if (hash_ != &::google::protobuf::internal::kEmptyString) { delete hash_; } - if (path_ != &::google::protobuf::internal::kEmptyString) { - delete path_; - } - if (avail_ != &::google::protobuf::internal::kEmptyString) { - delete avail_; - } if (this != default_instance_) { } } @@ -1863,17 +1855,7 @@ void File::Clear() { hash_->clear(); } } - size_ = GOOGLE_LONGLONG(0); - if (has_path()) { - if (path_ != &::google::protobuf::internal::kEmptyString) { - path_->clear(); - } - } - if (has_avail()) { - if (avail_ != &::google::protobuf::internal::kEmptyString) { - avail_->clear(); - } - } + size_ = GOOGLE_ULONGLONG(0); } ::memset(_has_bits_, 0, sizeof(_has_bits_)); mutable_unknown_fields()->Clear(); @@ -1918,52 +1900,18 @@ bool File::MergePartialFromCodedStream( break; } - // required int64 size = 3; + // required uint64 size = 3; case 3: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { parse_size: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( input, &size_))); set_has_size(); } else { goto handle_uninterpreted; } - if (input->ExpectTag(34)) goto parse_path; - break; - } - - // optional string path = 4; - case 4: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_path: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_path())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->path().data(), this->path().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(42)) goto parse_avail; - break; - } - - // optional string avail = 5; - case 5: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_avail: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_avail())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->avail().data(), this->avail().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } if (input->ExpectAtEnd()) return true; break; } @@ -2004,27 +1952,9 @@ void File::SerializeWithCachedSizes( 2, this->hash(), output); } - // required int64 size = 3; + // required uint64 size = 3; if (has_size()) { - ::google::protobuf::internal::WireFormatLite::WriteInt64(3, this->size(), output); - } - - // optional string path = 4; - if (has_path()) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->path().data(), this->path().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 4, this->path(), output); - } - - // optional string avail = 5; - if (has_avail()) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->avail().data(), this->avail().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 5, this->avail(), output); + ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->size(), output); } if (!unknown_fields().empty()) { @@ -2055,29 +1985,9 @@ void File::SerializeWithCachedSizes( 2, this->hash(), target); } - // required int64 size = 3; + // required uint64 size = 3; if (has_size()) { - target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(3, this->size(), target); - } - - // optional string path = 4; - if (has_path()) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->path().data(), this->path().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 4, this->path(), target); - } - - // optional string avail = 5; - if (has_avail()) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->avail().data(), this->avail().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 5, this->avail(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->size(), target); } if (!unknown_fields().empty()) { @@ -2105,27 +2015,13 @@ int File::ByteSize() const { this->hash()); } - // required int64 size = 3; + // required uint64 size = 3; if (has_size()) { total_size += 1 + - ::google::protobuf::internal::WireFormatLite::Int64Size( + ::google::protobuf::internal::WireFormatLite::UInt64Size( this->size()); } - // optional string path = 4; - if (has_path()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->path()); - } - - // optional string avail = 5; - if (has_avail()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->avail()); - } - } if (!unknown_fields().empty()) { total_size += @@ -2162,12 +2058,6 @@ void File::MergeFrom(const File& from) { if (from.has_size()) { set_size(from.size()); } - if (from.has_path()) { - set_path(from.path()); - } - if (from.has_avail()) { - set_avail(from.avail()); - } } mutable_unknown_fields()->MergeFrom(from.unknown_fields()); } @@ -2195,8 +2085,6 @@ void File::Swap(File* other) { std::swap(name_, other->name_); std::swap(hash_, other->hash_); std::swap(size_, other->size_); - std::swap(path_, other->path_); - std::swap(avail_, other->avail_); std::swap(_has_bits_[0], other->_has_bits_[0]); _unknown_fields_.Swap(&other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); diff --git a/retroshare-nogui/src/rpc/proto/gencc/core.pb.h b/retroshare-nogui/src/rpc/proto/gencc/core.pb.h index 8ed3d8e2d..fda22264a 100644 --- a/retroshare-nogui/src/rpc/proto/gencc/core.pb.h +++ b/retroshare-nogui/src/rpc/proto/gencc/core.pb.h @@ -47,8 +47,9 @@ enum Status_StatusCode { Status_StatusCode_FAILED = 0, Status_StatusCode_NO_IMPL_YET = 1, Status_StatusCode_INVALID_QUERY = 2, - Status_StatusCode_SUCCESS = 3, - Status_StatusCode_READMSG = 4 + Status_StatusCode_PARTIAL_SUCCESS = 3, + Status_StatusCode_SUCCESS = 4, + Status_StatusCode_READMSG = 5 }; bool Status_StatusCode_IsValid(int value); const Status_StatusCode Status_StatusCode_StatusCode_MIN = Status_StatusCode_FAILED; @@ -154,6 +155,8 @@ enum PackageId { PEERS = 1, SYSTEM = 2, CHAT = 3, + SEARCH = 4, + FILES = 5, GXS = 1000 }; bool PackageId_IsValid(int value); @@ -229,6 +232,7 @@ class Status : public ::google::protobuf::Message { static const StatusCode FAILED = Status_StatusCode_FAILED; static const StatusCode NO_IMPL_YET = Status_StatusCode_NO_IMPL_YET; static const StatusCode INVALID_QUERY = Status_StatusCode_INVALID_QUERY; + static const StatusCode PARTIAL_SUCCESS = Status_StatusCode_PARTIAL_SUCCESS; static const StatusCode SUCCESS = Status_StatusCode_SUCCESS; static const StatusCode READMSG = Status_StatusCode_READMSG; static inline bool StatusCode_IsValid(int value) { @@ -774,34 +778,12 @@ class File : public ::google::protobuf::Message { inline ::std::string* mutable_hash(); inline ::std::string* release_hash(); - // required int64 size = 3; + // required uint64 size = 3; inline bool has_size() const; inline void clear_size(); static const int kSizeFieldNumber = 3; - inline ::google::protobuf::int64 size() const; - inline void set_size(::google::protobuf::int64 value); - - // optional string path = 4; - inline bool has_path() const; - inline void clear_path(); - static const int kPathFieldNumber = 4; - inline const ::std::string& path() const; - inline void set_path(const ::std::string& value); - inline void set_path(const char* value); - inline void set_path(const char* value, size_t size); - inline ::std::string* mutable_path(); - inline ::std::string* release_path(); - - // optional string avail = 5; - inline bool has_avail() const; - inline void clear_avail(); - static const int kAvailFieldNumber = 5; - inline const ::std::string& avail() const; - inline void set_avail(const ::std::string& value); - inline void set_avail(const char* value); - inline void set_avail(const char* value, size_t size); - inline ::std::string* mutable_avail(); - inline ::std::string* release_avail(); + inline ::google::protobuf::uint64 size() const; + inline void set_size(::google::protobuf::uint64 value); // @@protoc_insertion_point(class_scope:rsctrl.core.File) private: @@ -811,21 +793,15 @@ class File : public ::google::protobuf::Message { inline void clear_has_hash(); inline void set_has_size(); inline void clear_has_size(); - inline void set_has_path(); - inline void clear_has_path(); - inline void set_has_avail(); - inline void clear_has_avail(); ::google::protobuf::UnknownFieldSet _unknown_fields_; ::std::string* name_; ::std::string* hash_; - ::google::protobuf::int64 size_; - ::std::string* path_; - ::std::string* avail_; + ::google::protobuf::uint64 size_; mutable int _cached_size_; - ::google::protobuf::uint32 _has_bits_[(5 + 31) / 32]; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; friend void protobuf_AddDesc_core_2eproto(); friend void protobuf_AssignDesc_core_2eproto(); @@ -1938,7 +1914,7 @@ inline ::std::string* File::release_hash() { } } -// required int64 size = 3; +// required uint64 size = 3; inline bool File::has_size() const { return (_has_bits_[0] & 0x00000004u) != 0; } @@ -1949,133 +1925,17 @@ inline void File::clear_has_size() { _has_bits_[0] &= ~0x00000004u; } inline void File::clear_size() { - size_ = GOOGLE_LONGLONG(0); + size_ = GOOGLE_ULONGLONG(0); clear_has_size(); } -inline ::google::protobuf::int64 File::size() const { +inline ::google::protobuf::uint64 File::size() const { return size_; } -inline void File::set_size(::google::protobuf::int64 value) { +inline void File::set_size(::google::protobuf::uint64 value) { set_has_size(); size_ = value; } -// optional string path = 4; -inline bool File::has_path() const { - return (_has_bits_[0] & 0x00000008u) != 0; -} -inline void File::set_has_path() { - _has_bits_[0] |= 0x00000008u; -} -inline void File::clear_has_path() { - _has_bits_[0] &= ~0x00000008u; -} -inline void File::clear_path() { - if (path_ != &::google::protobuf::internal::kEmptyString) { - path_->clear(); - } - clear_has_path(); -} -inline const ::std::string& File::path() const { - return *path_; -} -inline void File::set_path(const ::std::string& value) { - set_has_path(); - if (path_ == &::google::protobuf::internal::kEmptyString) { - path_ = new ::std::string; - } - path_->assign(value); -} -inline void File::set_path(const char* value) { - set_has_path(); - if (path_ == &::google::protobuf::internal::kEmptyString) { - path_ = new ::std::string; - } - path_->assign(value); -} -inline void File::set_path(const char* value, size_t size) { - set_has_path(); - if (path_ == &::google::protobuf::internal::kEmptyString) { - path_ = new ::std::string; - } - path_->assign(reinterpret_cast(value), size); -} -inline ::std::string* File::mutable_path() { - set_has_path(); - if (path_ == &::google::protobuf::internal::kEmptyString) { - path_ = new ::std::string; - } - return path_; -} -inline ::std::string* File::release_path() { - clear_has_path(); - if (path_ == &::google::protobuf::internal::kEmptyString) { - return NULL; - } else { - ::std::string* temp = path_; - path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); - return temp; - } -} - -// optional string avail = 5; -inline bool File::has_avail() const { - return (_has_bits_[0] & 0x00000010u) != 0; -} -inline void File::set_has_avail() { - _has_bits_[0] |= 0x00000010u; -} -inline void File::clear_has_avail() { - _has_bits_[0] &= ~0x00000010u; -} -inline void File::clear_avail() { - if (avail_ != &::google::protobuf::internal::kEmptyString) { - avail_->clear(); - } - clear_has_avail(); -} -inline const ::std::string& File::avail() const { - return *avail_; -} -inline void File::set_avail(const ::std::string& value) { - set_has_avail(); - if (avail_ == &::google::protobuf::internal::kEmptyString) { - avail_ = new ::std::string; - } - avail_->assign(value); -} -inline void File::set_avail(const char* value) { - set_has_avail(); - if (avail_ == &::google::protobuf::internal::kEmptyString) { - avail_ = new ::std::string; - } - avail_->assign(value); -} -inline void File::set_avail(const char* value, size_t size) { - set_has_avail(); - if (avail_ == &::google::protobuf::internal::kEmptyString) { - avail_ = new ::std::string; - } - avail_->assign(reinterpret_cast(value), size); -} -inline ::std::string* File::mutable_avail() { - set_has_avail(); - if (avail_ == &::google::protobuf::internal::kEmptyString) { - avail_ = new ::std::string; - } - return avail_; -} -inline ::std::string* File::release_avail() { - clear_has_avail(); - if (avail_ == &::google::protobuf::internal::kEmptyString) { - return NULL; - } else { - ::std::string* temp = avail_; - avail_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); - return temp; - } -} - // ------------------------------------------------------------------- // Dir diff --git a/retroshare-nogui/src/rpc/proto/gencc/files.pb.cc b/retroshare-nogui/src/rpc/proto/gencc/files.pb.cc new file mode 100644 index 000000000..692a89dec --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/gencc/files.pb.cc @@ -0,0 +1,1594 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "files.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace rsctrl { +namespace files { + +namespace { + +const ::google::protobuf::Descriptor* FileTransfer_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FileTransfer_reflection_ = NULL; +const ::google::protobuf::Descriptor* RequestTransferList_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestTransferList_reflection_ = NULL; +const ::google::protobuf::Descriptor* ResponseTransferList_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ResponseTransferList_reflection_ = NULL; +const ::google::protobuf::Descriptor* RequestControlDownload_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestControlDownload_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* RequestControlDownload_Action_descriptor_ = NULL; +const ::google::protobuf::Descriptor* ResponseControlDownload_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ResponseControlDownload_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* Direction_descriptor_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_files_2eproto() { + protobuf_AddDesc_files_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "files.proto"); + GOOGLE_CHECK(file != NULL); + FileTransfer_descriptor_ = file->message_type(0); + static const int FileTransfer_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileTransfer, file_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileTransfer, direction_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileTransfer, fraction_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileTransfer, rate_kbs_), + }; + FileTransfer_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + FileTransfer_descriptor_, + FileTransfer::default_instance_, + FileTransfer_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileTransfer, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileTransfer, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(FileTransfer)); + RequestTransferList_descriptor_ = file->message_type(1); + static const int RequestTransferList_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestTransferList, direction_), + }; + RequestTransferList_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestTransferList_descriptor_, + RequestTransferList::default_instance_, + RequestTransferList_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestTransferList, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestTransferList, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestTransferList)); + ResponseTransferList_descriptor_ = file->message_type(2); + static const int ResponseTransferList_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseTransferList, status_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseTransferList, transfers_), + }; + ResponseTransferList_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ResponseTransferList_descriptor_, + ResponseTransferList::default_instance_, + ResponseTransferList_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseTransferList, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseTransferList, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ResponseTransferList)); + RequestControlDownload_descriptor_ = file->message_type(3); + static const int RequestControlDownload_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestControlDownload, file_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestControlDownload, action_), + }; + RequestControlDownload_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestControlDownload_descriptor_, + RequestControlDownload::default_instance_, + RequestControlDownload_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestControlDownload, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestControlDownload, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestControlDownload)); + RequestControlDownload_Action_descriptor_ = RequestControlDownload_descriptor_->enum_type(0); + ResponseControlDownload_descriptor_ = file->message_type(4); + static const int ResponseControlDownload_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseControlDownload, status_), + }; + ResponseControlDownload_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ResponseControlDownload_descriptor_, + ResponseControlDownload::default_instance_, + ResponseControlDownload_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseControlDownload, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseControlDownload, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ResponseControlDownload)); + RequestMsgIds_descriptor_ = file->enum_type(0); + ResponseMsgIds_descriptor_ = file->enum_type(1); + Direction_descriptor_ = file->enum_type(2); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_files_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FileTransfer_descriptor_, &FileTransfer::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestTransferList_descriptor_, &RequestTransferList::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ResponseTransferList_descriptor_, &ResponseTransferList::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestControlDownload_descriptor_, &RequestControlDownload::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ResponseControlDownload_descriptor_, &ResponseControlDownload::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_files_2eproto() { + delete FileTransfer::default_instance_; + delete FileTransfer_reflection_; + delete RequestTransferList::default_instance_; + delete RequestTransferList_reflection_; + delete ResponseTransferList::default_instance_; + delete ResponseTransferList_reflection_; + delete RequestControlDownload::default_instance_; + delete RequestControlDownload_reflection_; + delete ResponseControlDownload::default_instance_; + delete ResponseControlDownload_reflection_; +} + +void protobuf_AddDesc_files_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::rsctrl::core::protobuf_AddDesc_core_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\013files.proto\022\014rsctrl.files\032\ncore.proto\"" + "\177\n\014FileTransfer\022\037\n\004file\030\001 \002(\0132\021.rsctrl.c" + "ore.File\022*\n\tdirection\030\002 \002(\0162\027.rsctrl.fil" + "es.Direction\022\020\n\010fraction\030\003 \002(\002\022\020\n\010rate_k" + "Bs\030\004 \002(\002\"A\n\023RequestTransferList\022*\n\tdirec" + "tion\030\001 \002(\0162\027.rsctrl.files.Direction\"j\n\024R" + "esponseTransferList\022#\n\006status\030\001 \002(\0132\023.rs" + "ctrl.core.Status\022-\n\ttransfers\030\002 \003(\0132\032.rs" + "ctrl.files.FileTransfer\"\204\002\n\026RequestContr" + "olDownload\022\037\n\004file\030\001 \002(\0132\021.rsctrl.core.F" + "ile\022;\n\006action\030\002 \002(\0162+.rsctrl.files.Reque" + "stControlDownload.Action\"\213\001\n\006Action\022\020\n\014A" + "CTION_START\020\001\022\023\n\017ACTION_CONTINUE\020\002\022\017\n\013AC" + "TION_WAIT\020\003\022\020\n\014ACTION_PAUSE\020\004\022\022\n\016ACTION_" + "RESTART\020\005\022\020\n\014ACTION_CHECK\020\006\022\021\n\rACTION_CA" + "NCEL\020\007\">\n\027ResponseControlDownload\022#\n\006sta" + "tus\030\001 \002(\0132\023.rsctrl.core.Status*P\n\rReques" + "tMsgIds\022\035\n\031MsgId_RequestTransferList\020\001\022 " + "\n\034MsgId_RequestControlDownload\020\002*S\n\016Resp" + "onseMsgIds\022\036\n\032MsgId_ResponseTransferList" + "\020\001\022!\n\035MsgId_ResponseControlDownload\020\002*9\n" + "\tDirection\022\024\n\020DIRECTION_UPLOAD\020\001\022\026\n\022DIRE" + "CTION_DOWNLOAD\020\002", 896); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "files.proto", &protobuf_RegisterTypes); + FileTransfer::default_instance_ = new FileTransfer(); + RequestTransferList::default_instance_ = new RequestTransferList(); + ResponseTransferList::default_instance_ = new ResponseTransferList(); + RequestControlDownload::default_instance_ = new RequestControlDownload(); + ResponseControlDownload::default_instance_ = new ResponseControlDownload(); + FileTransfer::default_instance_->InitAsDefaultInstance(); + RequestTransferList::default_instance_->InitAsDefaultInstance(); + ResponseTransferList::default_instance_->InitAsDefaultInstance(); + RequestControlDownload::default_instance_->InitAsDefaultInstance(); + ResponseControlDownload::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_files_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_files_2eproto { + StaticDescriptorInitializer_files_2eproto() { + protobuf_AddDesc_files_2eproto(); + } +} static_descriptor_initializer_files_2eproto_; + +const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestMsgIds_descriptor_; +} +bool RequestMsgIds_IsValid(int value) { + switch(value) { + case 1: + case 2: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor() { + protobuf_AssignDescriptorsOnce(); + return ResponseMsgIds_descriptor_; +} +bool ResponseMsgIds_IsValid(int value) { + switch(value) { + case 1: + case 2: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* Direction_descriptor() { + protobuf_AssignDescriptorsOnce(); + return Direction_descriptor_; +} +bool Direction_IsValid(int value) { + switch(value) { + case 1: + case 2: + return true; + default: + return false; + } +} + + +// =================================================================== + +#ifndef _MSC_VER +const int FileTransfer::kFileFieldNumber; +const int FileTransfer::kDirectionFieldNumber; +const int FileTransfer::kFractionFieldNumber; +const int FileTransfer::kRateKBsFieldNumber; +#endif // !_MSC_VER + +FileTransfer::FileTransfer() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void FileTransfer::InitAsDefaultInstance() { + file_ = const_cast< ::rsctrl::core::File*>(&::rsctrl::core::File::default_instance()); +} + +FileTransfer::FileTransfer(const FileTransfer& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void FileTransfer::SharedCtor() { + _cached_size_ = 0; + file_ = NULL; + direction_ = 1; + fraction_ = 0; + rate_kbs_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +FileTransfer::~FileTransfer() { + SharedDtor(); +} + +void FileTransfer::SharedDtor() { + if (this != default_instance_) { + delete file_; + } +} + +void FileTransfer::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FileTransfer::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FileTransfer_descriptor_; +} + +const FileTransfer& FileTransfer::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_files_2eproto(); return *default_instance_; +} + +FileTransfer* FileTransfer::default_instance_ = NULL; + +FileTransfer* FileTransfer::New() const { + return new FileTransfer; +} + +void FileTransfer::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file()) { + if (file_ != NULL) file_->::rsctrl::core::File::Clear(); + } + direction_ = 1; + fraction_ = 0; + rate_kbs_ = 0; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool FileTransfer::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.core.File file = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_direction; + break; + } + + // required .rsctrl.files.Direction direction = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_direction: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (rsctrl::files::Direction_IsValid(value)) { + set_direction(static_cast< rsctrl::files::Direction >(value)); + } else { + mutable_unknown_fields()->AddVarint(2, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(29)) goto parse_fraction; + break; + } + + // required float fraction = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_fraction: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, &fraction_))); + set_has_fraction(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(37)) goto parse_rate_kBs; + break; + } + + // required float rate_kBs = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + parse_rate_kBs: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, &rate_kbs_))); + set_has_rate_kbs(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void FileTransfer::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.core.File file = 1; + if (has_file()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file(), output); + } + + // required .rsctrl.files.Direction direction = 2; + if (has_direction()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 2, this->direction(), output); + } + + // required float fraction = 3; + if (has_fraction()) { + ::google::protobuf::internal::WireFormatLite::WriteFloat(3, this->fraction(), output); + } + + // required float rate_kBs = 4; + if (has_rate_kbs()) { + ::google::protobuf::internal::WireFormatLite::WriteFloat(4, this->rate_kbs(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* FileTransfer::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.core.File file = 1; + if (has_file()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file(), target); + } + + // required .rsctrl.files.Direction direction = 2; + if (has_direction()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 2, this->direction(), target); + } + + // required float fraction = 3; + if (has_fraction()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(3, this->fraction(), target); + } + + // required float rate_kBs = 4; + if (has_rate_kbs()) { + target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(4, this->rate_kbs(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int FileTransfer::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.core.File file = 1; + if (has_file()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file()); + } + + // required .rsctrl.files.Direction direction = 2; + if (has_direction()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->direction()); + } + + // required float fraction = 3; + if (has_fraction()) { + total_size += 1 + 4; + } + + // required float rate_kBs = 4; + if (has_rate_kbs()) { + total_size += 1 + 4; + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FileTransfer::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const FileTransfer* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FileTransfer::MergeFrom(const FileTransfer& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file()) { + mutable_file()->::rsctrl::core::File::MergeFrom(from.file()); + } + if (from.has_direction()) { + set_direction(from.direction()); + } + if (from.has_fraction()) { + set_fraction(from.fraction()); + } + if (from.has_rate_kbs()) { + set_rate_kbs(from.rate_kbs()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void FileTransfer::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FileTransfer::CopyFrom(const FileTransfer& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FileTransfer::IsInitialized() const { + if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false; + + if (has_file()) { + if (!this->file().IsInitialized()) return false; + } + return true; +} + +void FileTransfer::Swap(FileTransfer* other) { + if (other != this) { + std::swap(file_, other->file_); + std::swap(direction_, other->direction_); + std::swap(fraction_, other->fraction_); + std::swap(rate_kbs_, other->rate_kbs_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata FileTransfer::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FileTransfer_descriptor_; + metadata.reflection = FileTransfer_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int RequestTransferList::kDirectionFieldNumber; +#endif // !_MSC_VER + +RequestTransferList::RequestTransferList() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RequestTransferList::InitAsDefaultInstance() { +} + +RequestTransferList::RequestTransferList(const RequestTransferList& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RequestTransferList::SharedCtor() { + _cached_size_ = 0; + direction_ = 1; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RequestTransferList::~RequestTransferList() { + SharedDtor(); +} + +void RequestTransferList::SharedDtor() { + if (this != default_instance_) { + } +} + +void RequestTransferList::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestTransferList::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestTransferList_descriptor_; +} + +const RequestTransferList& RequestTransferList::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_files_2eproto(); return *default_instance_; +} + +RequestTransferList* RequestTransferList::default_instance_ = NULL; + +RequestTransferList* RequestTransferList::New() const { + return new RequestTransferList; +} + +void RequestTransferList::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + direction_ = 1; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestTransferList::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.files.Direction direction = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (rsctrl::files::Direction_IsValid(value)) { + set_direction(static_cast< rsctrl::files::Direction >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void RequestTransferList::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.files.Direction direction = 1; + if (has_direction()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->direction(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RequestTransferList::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.files.Direction direction = 1; + if (has_direction()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->direction(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RequestTransferList::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.files.Direction direction = 1; + if (has_direction()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->direction()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestTransferList::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestTransferList* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestTransferList::MergeFrom(const RequestTransferList& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_direction()) { + set_direction(from.direction()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestTransferList::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestTransferList::CopyFrom(const RequestTransferList& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestTransferList::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void RequestTransferList::Swap(RequestTransferList* other) { + if (other != this) { + std::swap(direction_, other->direction_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestTransferList::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestTransferList_descriptor_; + metadata.reflection = RequestTransferList_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ResponseTransferList::kStatusFieldNumber; +const int ResponseTransferList::kTransfersFieldNumber; +#endif // !_MSC_VER + +ResponseTransferList::ResponseTransferList() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ResponseTransferList::InitAsDefaultInstance() { + status_ = const_cast< ::rsctrl::core::Status*>(&::rsctrl::core::Status::default_instance()); +} + +ResponseTransferList::ResponseTransferList(const ResponseTransferList& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ResponseTransferList::SharedCtor() { + _cached_size_ = 0; + status_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ResponseTransferList::~ResponseTransferList() { + SharedDtor(); +} + +void ResponseTransferList::SharedDtor() { + if (this != default_instance_) { + delete status_; + } +} + +void ResponseTransferList::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ResponseTransferList::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ResponseTransferList_descriptor_; +} + +const ResponseTransferList& ResponseTransferList::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_files_2eproto(); return *default_instance_; +} + +ResponseTransferList* ResponseTransferList::default_instance_ = NULL; + +ResponseTransferList* ResponseTransferList::New() const { + return new ResponseTransferList; +} + +void ResponseTransferList::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_status()) { + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); + } + } + transfers_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ResponseTransferList::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.core.Status status = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_status())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_transfers; + break; + } + + // repeated .rsctrl.files.FileTransfer transfers = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_transfers: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_transfers())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_transfers; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ResponseTransferList::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->status(), output); + } + + // repeated .rsctrl.files.FileTransfer transfers = 2; + for (int i = 0; i < this->transfers_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->transfers(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ResponseTransferList::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->status(), target); + } + + // repeated .rsctrl.files.FileTransfer transfers = 2; + for (int i = 0; i < this->transfers_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->transfers(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ResponseTransferList::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->status()); + } + + } + // repeated .rsctrl.files.FileTransfer transfers = 2; + total_size += 1 * this->transfers_size(); + for (int i = 0; i < this->transfers_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->transfers(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ResponseTransferList::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ResponseTransferList* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ResponseTransferList::MergeFrom(const ResponseTransferList& from) { + GOOGLE_CHECK_NE(&from, this); + transfers_.MergeFrom(from.transfers_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_status()) { + mutable_status()->::rsctrl::core::Status::MergeFrom(from.status()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ResponseTransferList::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ResponseTransferList::CopyFrom(const ResponseTransferList& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ResponseTransferList::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_status()) { + if (!this->status().IsInitialized()) return false; + } + for (int i = 0; i < transfers_size(); i++) { + if (!this->transfers(i).IsInitialized()) return false; + } + return true; +} + +void ResponseTransferList::Swap(ResponseTransferList* other) { + if (other != this) { + std::swap(status_, other->status_); + transfers_.Swap(&other->transfers_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ResponseTransferList::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ResponseTransferList_descriptor_; + metadata.reflection = ResponseTransferList_reflection_; + return metadata; +} + + +// =================================================================== + +const ::google::protobuf::EnumDescriptor* RequestControlDownload_Action_descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestControlDownload_Action_descriptor_; +} +bool RequestControlDownload_Action_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const RequestControlDownload_Action RequestControlDownload::ACTION_START; +const RequestControlDownload_Action RequestControlDownload::ACTION_CONTINUE; +const RequestControlDownload_Action RequestControlDownload::ACTION_WAIT; +const RequestControlDownload_Action RequestControlDownload::ACTION_PAUSE; +const RequestControlDownload_Action RequestControlDownload::ACTION_RESTART; +const RequestControlDownload_Action RequestControlDownload::ACTION_CHECK; +const RequestControlDownload_Action RequestControlDownload::ACTION_CANCEL; +const RequestControlDownload_Action RequestControlDownload::Action_MIN; +const RequestControlDownload_Action RequestControlDownload::Action_MAX; +const int RequestControlDownload::Action_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int RequestControlDownload::kFileFieldNumber; +const int RequestControlDownload::kActionFieldNumber; +#endif // !_MSC_VER + +RequestControlDownload::RequestControlDownload() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RequestControlDownload::InitAsDefaultInstance() { + file_ = const_cast< ::rsctrl::core::File*>(&::rsctrl::core::File::default_instance()); +} + +RequestControlDownload::RequestControlDownload(const RequestControlDownload& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RequestControlDownload::SharedCtor() { + _cached_size_ = 0; + file_ = NULL; + action_ = 1; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RequestControlDownload::~RequestControlDownload() { + SharedDtor(); +} + +void RequestControlDownload::SharedDtor() { + if (this != default_instance_) { + delete file_; + } +} + +void RequestControlDownload::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestControlDownload::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestControlDownload_descriptor_; +} + +const RequestControlDownload& RequestControlDownload::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_files_2eproto(); return *default_instance_; +} + +RequestControlDownload* RequestControlDownload::default_instance_ = NULL; + +RequestControlDownload* RequestControlDownload::New() const { + return new RequestControlDownload; +} + +void RequestControlDownload::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file()) { + if (file_ != NULL) file_->::rsctrl::core::File::Clear(); + } + action_ = 1; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestControlDownload::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.core.File file = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_action; + break; + } + + // required .rsctrl.files.RequestControlDownload.Action action = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_action: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::rsctrl::files::RequestControlDownload_Action_IsValid(value)) { + set_action(static_cast< ::rsctrl::files::RequestControlDownload_Action >(value)); + } else { + mutable_unknown_fields()->AddVarint(2, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void RequestControlDownload::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.core.File file = 1; + if (has_file()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file(), output); + } + + // required .rsctrl.files.RequestControlDownload.Action action = 2; + if (has_action()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 2, this->action(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RequestControlDownload::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.core.File file = 1; + if (has_file()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file(), target); + } + + // required .rsctrl.files.RequestControlDownload.Action action = 2; + if (has_action()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 2, this->action(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RequestControlDownload::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.core.File file = 1; + if (has_file()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file()); + } + + // required .rsctrl.files.RequestControlDownload.Action action = 2; + if (has_action()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->action()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestControlDownload::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestControlDownload* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestControlDownload::MergeFrom(const RequestControlDownload& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file()) { + mutable_file()->::rsctrl::core::File::MergeFrom(from.file()); + } + if (from.has_action()) { + set_action(from.action()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestControlDownload::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestControlDownload::CopyFrom(const RequestControlDownload& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestControlDownload::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + if (has_file()) { + if (!this->file().IsInitialized()) return false; + } + return true; +} + +void RequestControlDownload::Swap(RequestControlDownload* other) { + if (other != this) { + std::swap(file_, other->file_); + std::swap(action_, other->action_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestControlDownload::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestControlDownload_descriptor_; + metadata.reflection = RequestControlDownload_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ResponseControlDownload::kStatusFieldNumber; +#endif // !_MSC_VER + +ResponseControlDownload::ResponseControlDownload() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ResponseControlDownload::InitAsDefaultInstance() { + status_ = const_cast< ::rsctrl::core::Status*>(&::rsctrl::core::Status::default_instance()); +} + +ResponseControlDownload::ResponseControlDownload(const ResponseControlDownload& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ResponseControlDownload::SharedCtor() { + _cached_size_ = 0; + status_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ResponseControlDownload::~ResponseControlDownload() { + SharedDtor(); +} + +void ResponseControlDownload::SharedDtor() { + if (this != default_instance_) { + delete status_; + } +} + +void ResponseControlDownload::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ResponseControlDownload::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ResponseControlDownload_descriptor_; +} + +const ResponseControlDownload& ResponseControlDownload::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_files_2eproto(); return *default_instance_; +} + +ResponseControlDownload* ResponseControlDownload::default_instance_ = NULL; + +ResponseControlDownload* ResponseControlDownload::New() const { + return new ResponseControlDownload; +} + +void ResponseControlDownload::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_status()) { + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ResponseControlDownload::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.core.Status status = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_status())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ResponseControlDownload::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->status(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ResponseControlDownload::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->status(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ResponseControlDownload::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->status()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ResponseControlDownload::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ResponseControlDownload* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ResponseControlDownload::MergeFrom(const ResponseControlDownload& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_status()) { + mutable_status()->::rsctrl::core::Status::MergeFrom(from.status()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ResponseControlDownload::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ResponseControlDownload::CopyFrom(const ResponseControlDownload& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ResponseControlDownload::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_status()) { + if (!this->status().IsInitialized()) return false; + } + return true; +} + +void ResponseControlDownload::Swap(ResponseControlDownload* other) { + if (other != this) { + std::swap(status_, other->status_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ResponseControlDownload::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ResponseControlDownload_descriptor_; + metadata.reflection = ResponseControlDownload_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace files +} // namespace rsctrl + +// @@protoc_insertion_point(global_scope) diff --git a/retroshare-nogui/src/rpc/proto/gencc/files.pb.h b/retroshare-nogui/src/rpc/proto/gencc/files.pb.h new file mode 100644 index 000000000..39a7b8c44 --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/gencc/files.pb.h @@ -0,0 +1,930 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: files.proto + +#ifndef PROTOBUF_files_2eproto__INCLUDED +#define PROTOBUF_files_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2004000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2004001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include "core.pb.h" +// @@protoc_insertion_point(includes) + +namespace rsctrl { +namespace files { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_files_2eproto(); +void protobuf_AssignDesc_files_2eproto(); +void protobuf_ShutdownFile_files_2eproto(); + +class FileTransfer; +class RequestTransferList; +class ResponseTransferList; +class RequestControlDownload; +class ResponseControlDownload; + +enum RequestControlDownload_Action { + RequestControlDownload_Action_ACTION_START = 1, + RequestControlDownload_Action_ACTION_CONTINUE = 2, + RequestControlDownload_Action_ACTION_WAIT = 3, + RequestControlDownload_Action_ACTION_PAUSE = 4, + RequestControlDownload_Action_ACTION_RESTART = 5, + RequestControlDownload_Action_ACTION_CHECK = 6, + RequestControlDownload_Action_ACTION_CANCEL = 7 +}; +bool RequestControlDownload_Action_IsValid(int value); +const RequestControlDownload_Action RequestControlDownload_Action_Action_MIN = RequestControlDownload_Action_ACTION_START; +const RequestControlDownload_Action RequestControlDownload_Action_Action_MAX = RequestControlDownload_Action_ACTION_CANCEL; +const int RequestControlDownload_Action_Action_ARRAYSIZE = RequestControlDownload_Action_Action_MAX + 1; + +const ::google::protobuf::EnumDescriptor* RequestControlDownload_Action_descriptor(); +inline const ::std::string& RequestControlDownload_Action_Name(RequestControlDownload_Action value) { + return ::google::protobuf::internal::NameOfEnum( + RequestControlDownload_Action_descriptor(), value); +} +inline bool RequestControlDownload_Action_Parse( + const ::std::string& name, RequestControlDownload_Action* value) { + return ::google::protobuf::internal::ParseNamedEnum( + RequestControlDownload_Action_descriptor(), name, value); +} +enum RequestMsgIds { + MsgId_RequestTransferList = 1, + MsgId_RequestControlDownload = 2 +}; +bool RequestMsgIds_IsValid(int value); +const RequestMsgIds RequestMsgIds_MIN = MsgId_RequestTransferList; +const RequestMsgIds RequestMsgIds_MAX = MsgId_RequestControlDownload; +const int RequestMsgIds_ARRAYSIZE = RequestMsgIds_MAX + 1; + +const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor(); +inline const ::std::string& RequestMsgIds_Name(RequestMsgIds value) { + return ::google::protobuf::internal::NameOfEnum( + RequestMsgIds_descriptor(), value); +} +inline bool RequestMsgIds_Parse( + const ::std::string& name, RequestMsgIds* value) { + return ::google::protobuf::internal::ParseNamedEnum( + RequestMsgIds_descriptor(), name, value); +} +enum ResponseMsgIds { + MsgId_ResponseTransferList = 1, + MsgId_ResponseControlDownload = 2 +}; +bool ResponseMsgIds_IsValid(int value); +const ResponseMsgIds ResponseMsgIds_MIN = MsgId_ResponseTransferList; +const ResponseMsgIds ResponseMsgIds_MAX = MsgId_ResponseControlDownload; +const int ResponseMsgIds_ARRAYSIZE = ResponseMsgIds_MAX + 1; + +const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor(); +inline const ::std::string& ResponseMsgIds_Name(ResponseMsgIds value) { + return ::google::protobuf::internal::NameOfEnum( + ResponseMsgIds_descriptor(), value); +} +inline bool ResponseMsgIds_Parse( + const ::std::string& name, ResponseMsgIds* value) { + return ::google::protobuf::internal::ParseNamedEnum( + ResponseMsgIds_descriptor(), name, value); +} +enum Direction { + DIRECTION_UPLOAD = 1, + DIRECTION_DOWNLOAD = 2 +}; +bool Direction_IsValid(int value); +const Direction Direction_MIN = DIRECTION_UPLOAD; +const Direction Direction_MAX = DIRECTION_DOWNLOAD; +const int Direction_ARRAYSIZE = Direction_MAX + 1; + +const ::google::protobuf::EnumDescriptor* Direction_descriptor(); +inline const ::std::string& Direction_Name(Direction value) { + return ::google::protobuf::internal::NameOfEnum( + Direction_descriptor(), value); +} +inline bool Direction_Parse( + const ::std::string& name, Direction* value) { + return ::google::protobuf::internal::ParseNamedEnum( + Direction_descriptor(), name, value); +} +// =================================================================== + +class FileTransfer : public ::google::protobuf::Message { + public: + FileTransfer(); + virtual ~FileTransfer(); + + FileTransfer(const FileTransfer& from); + + inline FileTransfer& operator=(const FileTransfer& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FileTransfer& default_instance(); + + void Swap(FileTransfer* other); + + // implements Message ---------------------------------------------- + + FileTransfer* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FileTransfer& from); + void MergeFrom(const FileTransfer& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .rsctrl.core.File file = 1; + inline bool has_file() const; + inline void clear_file(); + static const int kFileFieldNumber = 1; + inline const ::rsctrl::core::File& file() const; + inline ::rsctrl::core::File* mutable_file(); + inline ::rsctrl::core::File* release_file(); + + // required .rsctrl.files.Direction direction = 2; + inline bool has_direction() const; + inline void clear_direction(); + static const int kDirectionFieldNumber = 2; + inline rsctrl::files::Direction direction() const; + inline void set_direction(rsctrl::files::Direction value); + + // required float fraction = 3; + inline bool has_fraction() const; + inline void clear_fraction(); + static const int kFractionFieldNumber = 3; + inline float fraction() const; + inline void set_fraction(float value); + + // required float rate_kBs = 4; + inline bool has_rate_kbs() const; + inline void clear_rate_kbs(); + static const int kRateKBsFieldNumber = 4; + inline float rate_kbs() const; + inline void set_rate_kbs(float value); + + // @@protoc_insertion_point(class_scope:rsctrl.files.FileTransfer) + private: + inline void set_has_file(); + inline void clear_has_file(); + inline void set_has_direction(); + inline void clear_has_direction(); + inline void set_has_fraction(); + inline void clear_has_fraction(); + inline void set_has_rate_kbs(); + inline void clear_has_rate_kbs(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::rsctrl::core::File* file_; + int direction_; + float fraction_; + float rate_kbs_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; + + friend void protobuf_AddDesc_files_2eproto(); + friend void protobuf_AssignDesc_files_2eproto(); + friend void protobuf_ShutdownFile_files_2eproto(); + + void InitAsDefaultInstance(); + static FileTransfer* default_instance_; +}; +// ------------------------------------------------------------------- + +class RequestTransferList : public ::google::protobuf::Message { + public: + RequestTransferList(); + virtual ~RequestTransferList(); + + RequestTransferList(const RequestTransferList& from); + + inline RequestTransferList& operator=(const RequestTransferList& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestTransferList& default_instance(); + + void Swap(RequestTransferList* other); + + // implements Message ---------------------------------------------- + + RequestTransferList* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestTransferList& from); + void MergeFrom(const RequestTransferList& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .rsctrl.files.Direction direction = 1; + inline bool has_direction() const; + inline void clear_direction(); + static const int kDirectionFieldNumber = 1; + inline rsctrl::files::Direction direction() const; + inline void set_direction(rsctrl::files::Direction value); + + // @@protoc_insertion_point(class_scope:rsctrl.files.RequestTransferList) + private: + inline void set_has_direction(); + inline void clear_has_direction(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + int direction_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_files_2eproto(); + friend void protobuf_AssignDesc_files_2eproto(); + friend void protobuf_ShutdownFile_files_2eproto(); + + void InitAsDefaultInstance(); + static RequestTransferList* default_instance_; +}; +// ------------------------------------------------------------------- + +class ResponseTransferList : public ::google::protobuf::Message { + public: + ResponseTransferList(); + virtual ~ResponseTransferList(); + + ResponseTransferList(const ResponseTransferList& from); + + inline ResponseTransferList& operator=(const ResponseTransferList& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ResponseTransferList& default_instance(); + + void Swap(ResponseTransferList* other); + + // implements Message ---------------------------------------------- + + ResponseTransferList* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ResponseTransferList& from); + void MergeFrom(const ResponseTransferList& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .rsctrl.core.Status status = 1; + inline bool has_status() const; + inline void clear_status(); + static const int kStatusFieldNumber = 1; + inline const ::rsctrl::core::Status& status() const; + inline ::rsctrl::core::Status* mutable_status(); + inline ::rsctrl::core::Status* release_status(); + + // repeated .rsctrl.files.FileTransfer transfers = 2; + inline int transfers_size() const; + inline void clear_transfers(); + static const int kTransfersFieldNumber = 2; + inline const ::rsctrl::files::FileTransfer& transfers(int index) const; + inline ::rsctrl::files::FileTransfer* mutable_transfers(int index); + inline ::rsctrl::files::FileTransfer* add_transfers(); + inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::files::FileTransfer >& + transfers() const; + inline ::google::protobuf::RepeatedPtrField< ::rsctrl::files::FileTransfer >* + mutable_transfers(); + + // @@protoc_insertion_point(class_scope:rsctrl.files.ResponseTransferList) + private: + inline void set_has_status(); + inline void clear_has_status(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::rsctrl::core::Status* status_; + ::google::protobuf::RepeatedPtrField< ::rsctrl::files::FileTransfer > transfers_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_files_2eproto(); + friend void protobuf_AssignDesc_files_2eproto(); + friend void protobuf_ShutdownFile_files_2eproto(); + + void InitAsDefaultInstance(); + static ResponseTransferList* default_instance_; +}; +// ------------------------------------------------------------------- + +class RequestControlDownload : public ::google::protobuf::Message { + public: + RequestControlDownload(); + virtual ~RequestControlDownload(); + + RequestControlDownload(const RequestControlDownload& from); + + inline RequestControlDownload& operator=(const RequestControlDownload& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestControlDownload& default_instance(); + + void Swap(RequestControlDownload* other); + + // implements Message ---------------------------------------------- + + RequestControlDownload* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestControlDownload& from); + void MergeFrom(const RequestControlDownload& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef RequestControlDownload_Action Action; + static const Action ACTION_START = RequestControlDownload_Action_ACTION_START; + static const Action ACTION_CONTINUE = RequestControlDownload_Action_ACTION_CONTINUE; + static const Action ACTION_WAIT = RequestControlDownload_Action_ACTION_WAIT; + static const Action ACTION_PAUSE = RequestControlDownload_Action_ACTION_PAUSE; + static const Action ACTION_RESTART = RequestControlDownload_Action_ACTION_RESTART; + static const Action ACTION_CHECK = RequestControlDownload_Action_ACTION_CHECK; + static const Action ACTION_CANCEL = RequestControlDownload_Action_ACTION_CANCEL; + static inline bool Action_IsValid(int value) { + return RequestControlDownload_Action_IsValid(value); + } + static const Action Action_MIN = + RequestControlDownload_Action_Action_MIN; + static const Action Action_MAX = + RequestControlDownload_Action_Action_MAX; + static const int Action_ARRAYSIZE = + RequestControlDownload_Action_Action_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + Action_descriptor() { + return RequestControlDownload_Action_descriptor(); + } + static inline const ::std::string& Action_Name(Action value) { + return RequestControlDownload_Action_Name(value); + } + static inline bool Action_Parse(const ::std::string& name, + Action* value) { + return RequestControlDownload_Action_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // required .rsctrl.core.File file = 1; + inline bool has_file() const; + inline void clear_file(); + static const int kFileFieldNumber = 1; + inline const ::rsctrl::core::File& file() const; + inline ::rsctrl::core::File* mutable_file(); + inline ::rsctrl::core::File* release_file(); + + // required .rsctrl.files.RequestControlDownload.Action action = 2; + inline bool has_action() const; + inline void clear_action(); + static const int kActionFieldNumber = 2; + inline ::rsctrl::files::RequestControlDownload_Action action() const; + inline void set_action(::rsctrl::files::RequestControlDownload_Action value); + + // @@protoc_insertion_point(class_scope:rsctrl.files.RequestControlDownload) + private: + inline void set_has_file(); + inline void clear_has_file(); + inline void set_has_action(); + inline void clear_has_action(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::rsctrl::core::File* file_; + int action_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_files_2eproto(); + friend void protobuf_AssignDesc_files_2eproto(); + friend void protobuf_ShutdownFile_files_2eproto(); + + void InitAsDefaultInstance(); + static RequestControlDownload* default_instance_; +}; +// ------------------------------------------------------------------- + +class ResponseControlDownload : public ::google::protobuf::Message { + public: + ResponseControlDownload(); + virtual ~ResponseControlDownload(); + + ResponseControlDownload(const ResponseControlDownload& from); + + inline ResponseControlDownload& operator=(const ResponseControlDownload& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ResponseControlDownload& default_instance(); + + void Swap(ResponseControlDownload* other); + + // implements Message ---------------------------------------------- + + ResponseControlDownload* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ResponseControlDownload& from); + void MergeFrom(const ResponseControlDownload& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .rsctrl.core.Status status = 1; + inline bool has_status() const; + inline void clear_status(); + static const int kStatusFieldNumber = 1; + inline const ::rsctrl::core::Status& status() const; + inline ::rsctrl::core::Status* mutable_status(); + inline ::rsctrl::core::Status* release_status(); + + // @@protoc_insertion_point(class_scope:rsctrl.files.ResponseControlDownload) + private: + inline void set_has_status(); + inline void clear_has_status(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::rsctrl::core::Status* status_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_files_2eproto(); + friend void protobuf_AssignDesc_files_2eproto(); + friend void protobuf_ShutdownFile_files_2eproto(); + + void InitAsDefaultInstance(); + static ResponseControlDownload* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// FileTransfer + +// required .rsctrl.core.File file = 1; +inline bool FileTransfer::has_file() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FileTransfer::set_has_file() { + _has_bits_[0] |= 0x00000001u; +} +inline void FileTransfer::clear_has_file() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FileTransfer::clear_file() { + if (file_ != NULL) file_->::rsctrl::core::File::Clear(); + clear_has_file(); +} +inline const ::rsctrl::core::File& FileTransfer::file() const { + return file_ != NULL ? *file_ : *default_instance_->file_; +} +inline ::rsctrl::core::File* FileTransfer::mutable_file() { + set_has_file(); + if (file_ == NULL) file_ = new ::rsctrl::core::File; + return file_; +} +inline ::rsctrl::core::File* FileTransfer::release_file() { + clear_has_file(); + ::rsctrl::core::File* temp = file_; + file_ = NULL; + return temp; +} + +// required .rsctrl.files.Direction direction = 2; +inline bool FileTransfer::has_direction() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FileTransfer::set_has_direction() { + _has_bits_[0] |= 0x00000002u; +} +inline void FileTransfer::clear_has_direction() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FileTransfer::clear_direction() { + direction_ = 1; + clear_has_direction(); +} +inline rsctrl::files::Direction FileTransfer::direction() const { + return static_cast< rsctrl::files::Direction >(direction_); +} +inline void FileTransfer::set_direction(rsctrl::files::Direction value) { + GOOGLE_DCHECK(rsctrl::files::Direction_IsValid(value)); + set_has_direction(); + direction_ = value; +} + +// required float fraction = 3; +inline bool FileTransfer::has_fraction() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FileTransfer::set_has_fraction() { + _has_bits_[0] |= 0x00000004u; +} +inline void FileTransfer::clear_has_fraction() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FileTransfer::clear_fraction() { + fraction_ = 0; + clear_has_fraction(); +} +inline float FileTransfer::fraction() const { + return fraction_; +} +inline void FileTransfer::set_fraction(float value) { + set_has_fraction(); + fraction_ = value; +} + +// required float rate_kBs = 4; +inline bool FileTransfer::has_rate_kbs() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FileTransfer::set_has_rate_kbs() { + _has_bits_[0] |= 0x00000008u; +} +inline void FileTransfer::clear_has_rate_kbs() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FileTransfer::clear_rate_kbs() { + rate_kbs_ = 0; + clear_has_rate_kbs(); +} +inline float FileTransfer::rate_kbs() const { + return rate_kbs_; +} +inline void FileTransfer::set_rate_kbs(float value) { + set_has_rate_kbs(); + rate_kbs_ = value; +} + +// ------------------------------------------------------------------- + +// RequestTransferList + +// required .rsctrl.files.Direction direction = 1; +inline bool RequestTransferList::has_direction() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void RequestTransferList::set_has_direction() { + _has_bits_[0] |= 0x00000001u; +} +inline void RequestTransferList::clear_has_direction() { + _has_bits_[0] &= ~0x00000001u; +} +inline void RequestTransferList::clear_direction() { + direction_ = 1; + clear_has_direction(); +} +inline rsctrl::files::Direction RequestTransferList::direction() const { + return static_cast< rsctrl::files::Direction >(direction_); +} +inline void RequestTransferList::set_direction(rsctrl::files::Direction value) { + GOOGLE_DCHECK(rsctrl::files::Direction_IsValid(value)); + set_has_direction(); + direction_ = value; +} + +// ------------------------------------------------------------------- + +// ResponseTransferList + +// required .rsctrl.core.Status status = 1; +inline bool ResponseTransferList::has_status() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ResponseTransferList::set_has_status() { + _has_bits_[0] |= 0x00000001u; +} +inline void ResponseTransferList::clear_has_status() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ResponseTransferList::clear_status() { + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); + clear_has_status(); +} +inline const ::rsctrl::core::Status& ResponseTransferList::status() const { + return status_ != NULL ? *status_ : *default_instance_->status_; +} +inline ::rsctrl::core::Status* ResponseTransferList::mutable_status() { + set_has_status(); + if (status_ == NULL) status_ = new ::rsctrl::core::Status; + return status_; +} +inline ::rsctrl::core::Status* ResponseTransferList::release_status() { + clear_has_status(); + ::rsctrl::core::Status* temp = status_; + status_ = NULL; + return temp; +} + +// repeated .rsctrl.files.FileTransfer transfers = 2; +inline int ResponseTransferList::transfers_size() const { + return transfers_.size(); +} +inline void ResponseTransferList::clear_transfers() { + transfers_.Clear(); +} +inline const ::rsctrl::files::FileTransfer& ResponseTransferList::transfers(int index) const { + return transfers_.Get(index); +} +inline ::rsctrl::files::FileTransfer* ResponseTransferList::mutable_transfers(int index) { + return transfers_.Mutable(index); +} +inline ::rsctrl::files::FileTransfer* ResponseTransferList::add_transfers() { + return transfers_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::files::FileTransfer >& +ResponseTransferList::transfers() const { + return transfers_; +} +inline ::google::protobuf::RepeatedPtrField< ::rsctrl::files::FileTransfer >* +ResponseTransferList::mutable_transfers() { + return &transfers_; +} + +// ------------------------------------------------------------------- + +// RequestControlDownload + +// required .rsctrl.core.File file = 1; +inline bool RequestControlDownload::has_file() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void RequestControlDownload::set_has_file() { + _has_bits_[0] |= 0x00000001u; +} +inline void RequestControlDownload::clear_has_file() { + _has_bits_[0] &= ~0x00000001u; +} +inline void RequestControlDownload::clear_file() { + if (file_ != NULL) file_->::rsctrl::core::File::Clear(); + clear_has_file(); +} +inline const ::rsctrl::core::File& RequestControlDownload::file() const { + return file_ != NULL ? *file_ : *default_instance_->file_; +} +inline ::rsctrl::core::File* RequestControlDownload::mutable_file() { + set_has_file(); + if (file_ == NULL) file_ = new ::rsctrl::core::File; + return file_; +} +inline ::rsctrl::core::File* RequestControlDownload::release_file() { + clear_has_file(); + ::rsctrl::core::File* temp = file_; + file_ = NULL; + return temp; +} + +// required .rsctrl.files.RequestControlDownload.Action action = 2; +inline bool RequestControlDownload::has_action() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void RequestControlDownload::set_has_action() { + _has_bits_[0] |= 0x00000002u; +} +inline void RequestControlDownload::clear_has_action() { + _has_bits_[0] &= ~0x00000002u; +} +inline void RequestControlDownload::clear_action() { + action_ = 1; + clear_has_action(); +} +inline ::rsctrl::files::RequestControlDownload_Action RequestControlDownload::action() const { + return static_cast< ::rsctrl::files::RequestControlDownload_Action >(action_); +} +inline void RequestControlDownload::set_action(::rsctrl::files::RequestControlDownload_Action value) { + GOOGLE_DCHECK(::rsctrl::files::RequestControlDownload_Action_IsValid(value)); + set_has_action(); + action_ = value; +} + +// ------------------------------------------------------------------- + +// ResponseControlDownload + +// required .rsctrl.core.Status status = 1; +inline bool ResponseControlDownload::has_status() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ResponseControlDownload::set_has_status() { + _has_bits_[0] |= 0x00000001u; +} +inline void ResponseControlDownload::clear_has_status() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ResponseControlDownload::clear_status() { + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); + clear_has_status(); +} +inline const ::rsctrl::core::Status& ResponseControlDownload::status() const { + return status_ != NULL ? *status_ : *default_instance_->status_; +} +inline ::rsctrl::core::Status* ResponseControlDownload::mutable_status() { + set_has_status(); + if (status_ == NULL) status_ = new ::rsctrl::core::Status; + return status_; +} +inline ::rsctrl::core::Status* ResponseControlDownload::release_status() { + clear_has_status(); + ::rsctrl::core::Status* temp = status_; + status_ = NULL; + return temp; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace files +} // namespace rsctrl + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::files::RequestControlDownload_Action>() { + return ::rsctrl::files::RequestControlDownload_Action_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< rsctrl::files::RequestMsgIds>() { + return rsctrl::files::RequestMsgIds_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< rsctrl::files::ResponseMsgIds>() { + return rsctrl::files::ResponseMsgIds_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< rsctrl::files::Direction>() { + return rsctrl::files::Direction_descriptor(); +} + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_files_2eproto__INCLUDED diff --git a/retroshare-nogui/src/rpc/proto/gencc/search.pb.cc b/retroshare-nogui/src/rpc/proto/gencc/search.pb.cc new file mode 100644 index 000000000..7f41f346d --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/gencc/search.pb.cc @@ -0,0 +1,2437 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "search.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace rsctrl { +namespace search { + +namespace { + +const ::google::protobuf::Descriptor* SearchHit_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + SearchHit_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* SearchHit_LocFlag_descriptor_ = NULL; +const ::google::protobuf::Descriptor* SearchSet_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + SearchSet_reflection_ = NULL; +const ::google::protobuf::Descriptor* RequestBasicSearch_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestBasicSearch_reflection_ = NULL; +const ::google::protobuf::Descriptor* RequestAdvSearch_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestAdvSearch_reflection_ = NULL; +const ::google::protobuf::Descriptor* ResponseSearchIds_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ResponseSearchIds_reflection_ = NULL; +const ::google::protobuf::Descriptor* RequestCloseSearch_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestCloseSearch_reflection_ = NULL; +const ::google::protobuf::Descriptor* RequestListSearches_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestListSearches_reflection_ = NULL; +const ::google::protobuf::Descriptor* RequestSearchResults_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestSearchResults_reflection_ = NULL; +const ::google::protobuf::Descriptor* ResponseSearchResults_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ResponseSearchResults_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_search_2eproto() { + protobuf_AddDesc_search_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "search.proto"); + GOOGLE_CHECK(file != NULL); + SearchHit_descriptor_ = file->message_type(0); + static const int SearchHit_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SearchHit, file_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SearchHit, loc_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SearchHit, no_hits_), + }; + SearchHit_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + SearchHit_descriptor_, + SearchHit::default_instance_, + SearchHit_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SearchHit, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SearchHit, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(SearchHit)); + SearchHit_LocFlag_descriptor_ = SearchHit_descriptor_->enum_type(0); + SearchSet_descriptor_ = file->message_type(1); + static const int SearchSet_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SearchSet, search_id_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SearchSet, hits_), + }; + SearchSet_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + SearchSet_descriptor_, + SearchSet::default_instance_, + SearchSet_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SearchSet, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SearchSet, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(SearchSet)); + RequestBasicSearch_descriptor_ = file->message_type(2); + static const int RequestBasicSearch_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestBasicSearch, terms_), + }; + RequestBasicSearch_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestBasicSearch_descriptor_, + RequestBasicSearch::default_instance_, + RequestBasicSearch_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestBasicSearch, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestBasicSearch, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestBasicSearch)); + RequestAdvSearch_descriptor_ = file->message_type(3); + static const int RequestAdvSearch_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestAdvSearch, terms_), + }; + RequestAdvSearch_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestAdvSearch_descriptor_, + RequestAdvSearch::default_instance_, + RequestAdvSearch_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestAdvSearch, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestAdvSearch, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestAdvSearch)); + ResponseSearchIds_descriptor_ = file->message_type(4); + static const int ResponseSearchIds_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSearchIds, status_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSearchIds, search_id_), + }; + ResponseSearchIds_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ResponseSearchIds_descriptor_, + ResponseSearchIds::default_instance_, + ResponseSearchIds_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSearchIds, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSearchIds, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ResponseSearchIds)); + RequestCloseSearch_descriptor_ = file->message_type(5); + static const int RequestCloseSearch_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestCloseSearch, search_id_), + }; + RequestCloseSearch_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestCloseSearch_descriptor_, + RequestCloseSearch::default_instance_, + RequestCloseSearch_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestCloseSearch, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestCloseSearch, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestCloseSearch)); + RequestListSearches_descriptor_ = file->message_type(6); + static const int RequestListSearches_offsets_[1] = { + }; + RequestListSearches_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestListSearches_descriptor_, + RequestListSearches::default_instance_, + RequestListSearches_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestListSearches, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestListSearches, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestListSearches)); + RequestSearchResults_descriptor_ = file->message_type(7); + static const int RequestSearchResults_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestSearchResults, search_ids_), + }; + RequestSearchResults_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestSearchResults_descriptor_, + RequestSearchResults::default_instance_, + RequestSearchResults_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestSearchResults, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestSearchResults, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestSearchResults)); + ResponseSearchResults_descriptor_ = file->message_type(8); + static const int ResponseSearchResults_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSearchResults, status_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSearchResults, searches_), + }; + ResponseSearchResults_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ResponseSearchResults_descriptor_, + ResponseSearchResults::default_instance_, + ResponseSearchResults_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSearchResults, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSearchResults, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ResponseSearchResults)); + RequestMsgIds_descriptor_ = file->enum_type(0); + ResponseMsgIds_descriptor_ = file->enum_type(1); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_search_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + SearchHit_descriptor_, &SearchHit::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + SearchSet_descriptor_, &SearchSet::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestBasicSearch_descriptor_, &RequestBasicSearch::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestAdvSearch_descriptor_, &RequestAdvSearch::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ResponseSearchIds_descriptor_, &ResponseSearchIds::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestCloseSearch_descriptor_, &RequestCloseSearch::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestListSearches_descriptor_, &RequestListSearches::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestSearchResults_descriptor_, &RequestSearchResults::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ResponseSearchResults_descriptor_, &ResponseSearchResults::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_search_2eproto() { + delete SearchHit::default_instance_; + delete SearchHit_reflection_; + delete SearchSet::default_instance_; + delete SearchSet_reflection_; + delete RequestBasicSearch::default_instance_; + delete RequestBasicSearch_reflection_; + delete RequestAdvSearch::default_instance_; + delete RequestAdvSearch_reflection_; + delete ResponseSearchIds::default_instance_; + delete ResponseSearchIds_reflection_; + delete RequestCloseSearch::default_instance_; + delete RequestCloseSearch_reflection_; + delete RequestListSearches::default_instance_; + delete RequestListSearches_reflection_; + delete RequestSearchResults::default_instance_; + delete RequestSearchResults_reflection_; + delete ResponseSearchResults::default_instance_; + delete ResponseSearchResults_reflection_; +} + +void protobuf_AddDesc_search_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::rsctrl::core::protobuf_AddDesc_core_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\014search.proto\022\rrsctrl.search\032\ncore.prot" + "o\"y\n\tSearchHit\022\037\n\004file\030\001 \002(\0132\021.rsctrl.co" + "re.File\022\013\n\003loc\030\002 \002(\r\022\017\n\007no_hits\030\003 \002(\r\"-\n" + "\007LocFlag\022\t\n\005LOCAL\020\001\022\n\n\006FRIEND\020\002\022\013\n\007NETWO" + "RK\020\004\"F\n\tSearchSet\022\021\n\tsearch_id\030\001 \002(\r\022&\n\004" + "hits\030\002 \003(\0132\030.rsctrl.search.SearchHit\"#\n\022" + "RequestBasicSearch\022\r\n\005terms\030\001 \003(\t\"!\n\020Req" + "uestAdvSearch\022\r\n\005terms\030\001 \003(\t\"K\n\021Response" + "SearchIds\022#\n\006status\030\001 \002(\0132\023.rsctrl.core." + "Status\022\021\n\tsearch_id\030\002 \003(\r\"\'\n\022RequestClos" + "eSearch\022\021\n\tsearch_id\030\001 \002(\r\"\025\n\023RequestLis" + "tSearches\"*\n\024RequestSearchResults\022\022\n\nsea" + "rch_ids\030\002 \003(\r\"h\n\025ResponseSearchResults\022#" + "\n\006status\030\001 \002(\0132\023.rsctrl.core.Status\022*\n\010s" + "earches\030\002 \003(\0132\030.rsctrl.search.SearchSet*" + "\212\001\n\rRequestMsgIds\022\034\n\030MsgId_RequestBasicS" + "earch\020\001\022\034\n\030MsgId_RequestCloseSearch\020\003\022\035\n" + "\031MsgId_RequestListSearches\020\004\022\036\n\032MsgId_Re" + "questSearchResults\020\005*N\n\016ResponseMsgIds\022\033" + "\n\027MsgId_ResponseSearchIds\020\001\022\037\n\033MsgId_Res" + "ponseSearchResults\020\005", 820); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "search.proto", &protobuf_RegisterTypes); + SearchHit::default_instance_ = new SearchHit(); + SearchSet::default_instance_ = new SearchSet(); + RequestBasicSearch::default_instance_ = new RequestBasicSearch(); + RequestAdvSearch::default_instance_ = new RequestAdvSearch(); + ResponseSearchIds::default_instance_ = new ResponseSearchIds(); + RequestCloseSearch::default_instance_ = new RequestCloseSearch(); + RequestListSearches::default_instance_ = new RequestListSearches(); + RequestSearchResults::default_instance_ = new RequestSearchResults(); + ResponseSearchResults::default_instance_ = new ResponseSearchResults(); + SearchHit::default_instance_->InitAsDefaultInstance(); + SearchSet::default_instance_->InitAsDefaultInstance(); + RequestBasicSearch::default_instance_->InitAsDefaultInstance(); + RequestAdvSearch::default_instance_->InitAsDefaultInstance(); + ResponseSearchIds::default_instance_->InitAsDefaultInstance(); + RequestCloseSearch::default_instance_->InitAsDefaultInstance(); + RequestListSearches::default_instance_->InitAsDefaultInstance(); + RequestSearchResults::default_instance_->InitAsDefaultInstance(); + ResponseSearchResults::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_search_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_search_2eproto { + StaticDescriptorInitializer_search_2eproto() { + protobuf_AddDesc_search_2eproto(); + } +} static_descriptor_initializer_search_2eproto_; + +const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestMsgIds_descriptor_; +} +bool RequestMsgIds_IsValid(int value) { + switch(value) { + case 1: + case 3: + case 4: + case 5: + return true; + default: + return false; + } +} + +const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor() { + protobuf_AssignDescriptorsOnce(); + return ResponseMsgIds_descriptor_; +} +bool ResponseMsgIds_IsValid(int value) { + switch(value) { + case 1: + case 5: + return true; + default: + return false; + } +} + + +// =================================================================== + +const ::google::protobuf::EnumDescriptor* SearchHit_LocFlag_descriptor() { + protobuf_AssignDescriptorsOnce(); + return SearchHit_LocFlag_descriptor_; +} +bool SearchHit_LocFlag_IsValid(int value) { + switch(value) { + case 1: + case 2: + case 4: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const SearchHit_LocFlag SearchHit::LOCAL; +const SearchHit_LocFlag SearchHit::FRIEND; +const SearchHit_LocFlag SearchHit::NETWORK; +const SearchHit_LocFlag SearchHit::LocFlag_MIN; +const SearchHit_LocFlag SearchHit::LocFlag_MAX; +const int SearchHit::LocFlag_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int SearchHit::kFileFieldNumber; +const int SearchHit::kLocFieldNumber; +const int SearchHit::kNoHitsFieldNumber; +#endif // !_MSC_VER + +SearchHit::SearchHit() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void SearchHit::InitAsDefaultInstance() { + file_ = const_cast< ::rsctrl::core::File*>(&::rsctrl::core::File::default_instance()); +} + +SearchHit::SearchHit(const SearchHit& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void SearchHit::SharedCtor() { + _cached_size_ = 0; + file_ = NULL; + loc_ = 0u; + no_hits_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +SearchHit::~SearchHit() { + SharedDtor(); +} + +void SearchHit::SharedDtor() { + if (this != default_instance_) { + delete file_; + } +} + +void SearchHit::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* SearchHit::descriptor() { + protobuf_AssignDescriptorsOnce(); + return SearchHit_descriptor_; +} + +const SearchHit& SearchHit::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_search_2eproto(); return *default_instance_; +} + +SearchHit* SearchHit::default_instance_ = NULL; + +SearchHit* SearchHit::New() const { + return new SearchHit; +} + +void SearchHit::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_file()) { + if (file_ != NULL) file_->::rsctrl::core::File::Clear(); + } + loc_ = 0u; + no_hits_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool SearchHit::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.core.File file = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_file())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_loc; + break; + } + + // required uint32 loc = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_loc: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &loc_))); + set_has_loc(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(24)) goto parse_no_hits; + break; + } + + // required uint32 no_hits = 3; + case 3: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_no_hits: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &no_hits_))); + set_has_no_hits(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void SearchHit::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.core.File file = 1; + if (has_file()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->file(), output); + } + + // required uint32 loc = 2; + if (has_loc()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->loc(), output); + } + + // required uint32 no_hits = 3; + if (has_no_hits()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->no_hits(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* SearchHit::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.core.File file = 1; + if (has_file()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->file(), target); + } + + // required uint32 loc = 2; + if (has_loc()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->loc(), target); + } + + // required uint32 no_hits = 3; + if (has_no_hits()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->no_hits(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int SearchHit::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.core.File file = 1; + if (has_file()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->file()); + } + + // required uint32 loc = 2; + if (has_loc()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->loc()); + } + + // required uint32 no_hits = 3; + if (has_no_hits()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->no_hits()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void SearchHit::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const SearchHit* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void SearchHit::MergeFrom(const SearchHit& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_file()) { + mutable_file()->::rsctrl::core::File::MergeFrom(from.file()); + } + if (from.has_loc()) { + set_loc(from.loc()); + } + if (from.has_no_hits()) { + set_no_hits(from.no_hits()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void SearchHit::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void SearchHit::CopyFrom(const SearchHit& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool SearchHit::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + if (has_file()) { + if (!this->file().IsInitialized()) return false; + } + return true; +} + +void SearchHit::Swap(SearchHit* other) { + if (other != this) { + std::swap(file_, other->file_); + std::swap(loc_, other->loc_); + std::swap(no_hits_, other->no_hits_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata SearchHit::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = SearchHit_descriptor_; + metadata.reflection = SearchHit_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int SearchSet::kSearchIdFieldNumber; +const int SearchSet::kHitsFieldNumber; +#endif // !_MSC_VER + +SearchSet::SearchSet() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void SearchSet::InitAsDefaultInstance() { +} + +SearchSet::SearchSet(const SearchSet& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void SearchSet::SharedCtor() { + _cached_size_ = 0; + search_id_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +SearchSet::~SearchSet() { + SharedDtor(); +} + +void SearchSet::SharedDtor() { + if (this != default_instance_) { + } +} + +void SearchSet::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* SearchSet::descriptor() { + protobuf_AssignDescriptorsOnce(); + return SearchSet_descriptor_; +} + +const SearchSet& SearchSet::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_search_2eproto(); return *default_instance_; +} + +SearchSet* SearchSet::default_instance_ = NULL; + +SearchSet* SearchSet::New() const { + return new SearchSet; +} + +void SearchSet::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + search_id_ = 0u; + } + hits_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool SearchSet::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint32 search_id = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &search_id_))); + set_has_search_id(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_hits; + break; + } + + // repeated .rsctrl.search.SearchHit hits = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_hits: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_hits())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_hits; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void SearchSet::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required uint32 search_id = 1; + if (has_search_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->search_id(), output); + } + + // repeated .rsctrl.search.SearchHit hits = 2; + for (int i = 0; i < this->hits_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->hits(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* SearchSet::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required uint32 search_id = 1; + if (has_search_id()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->search_id(), target); + } + + // repeated .rsctrl.search.SearchHit hits = 2; + for (int i = 0; i < this->hits_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->hits(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int SearchSet::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required uint32 search_id = 1; + if (has_search_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->search_id()); + } + + } + // repeated .rsctrl.search.SearchHit hits = 2; + total_size += 1 * this->hits_size(); + for (int i = 0; i < this->hits_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->hits(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void SearchSet::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const SearchSet* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void SearchSet::MergeFrom(const SearchSet& from) { + GOOGLE_CHECK_NE(&from, this); + hits_.MergeFrom(from.hits_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_search_id()) { + set_search_id(from.search_id()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void SearchSet::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void SearchSet::CopyFrom(const SearchSet& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool SearchSet::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + for (int i = 0; i < hits_size(); i++) { + if (!this->hits(i).IsInitialized()) return false; + } + return true; +} + +void SearchSet::Swap(SearchSet* other) { + if (other != this) { + std::swap(search_id_, other->search_id_); + hits_.Swap(&other->hits_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata SearchSet::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = SearchSet_descriptor_; + metadata.reflection = SearchSet_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int RequestBasicSearch::kTermsFieldNumber; +#endif // !_MSC_VER + +RequestBasicSearch::RequestBasicSearch() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RequestBasicSearch::InitAsDefaultInstance() { +} + +RequestBasicSearch::RequestBasicSearch(const RequestBasicSearch& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RequestBasicSearch::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RequestBasicSearch::~RequestBasicSearch() { + SharedDtor(); +} + +void RequestBasicSearch::SharedDtor() { + if (this != default_instance_) { + } +} + +void RequestBasicSearch::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestBasicSearch::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestBasicSearch_descriptor_; +} + +const RequestBasicSearch& RequestBasicSearch::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_search_2eproto(); return *default_instance_; +} + +RequestBasicSearch* RequestBasicSearch::default_instance_ = NULL; + +RequestBasicSearch* RequestBasicSearch::New() const { + return new RequestBasicSearch; +} + +void RequestBasicSearch::Clear() { + terms_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestBasicSearch::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated string terms = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_terms: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_terms())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->terms(0).data(), this->terms(0).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_terms; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void RequestBasicSearch::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated string terms = 1; + for (int i = 0; i < this->terms_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->terms(i).data(), this->terms(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->terms(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RequestBasicSearch::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated string terms = 1; + for (int i = 0; i < this->terms_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->terms(i).data(), this->terms(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(1, this->terms(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RequestBasicSearch::ByteSize() const { + int total_size = 0; + + // repeated string terms = 1; + total_size += 1 * this->terms_size(); + for (int i = 0; i < this->terms_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->terms(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestBasicSearch::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestBasicSearch* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestBasicSearch::MergeFrom(const RequestBasicSearch& from) { + GOOGLE_CHECK_NE(&from, this); + terms_.MergeFrom(from.terms_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestBasicSearch::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestBasicSearch::CopyFrom(const RequestBasicSearch& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestBasicSearch::IsInitialized() const { + + return true; +} + +void RequestBasicSearch::Swap(RequestBasicSearch* other) { + if (other != this) { + terms_.Swap(&other->terms_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestBasicSearch::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestBasicSearch_descriptor_; + metadata.reflection = RequestBasicSearch_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int RequestAdvSearch::kTermsFieldNumber; +#endif // !_MSC_VER + +RequestAdvSearch::RequestAdvSearch() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RequestAdvSearch::InitAsDefaultInstance() { +} + +RequestAdvSearch::RequestAdvSearch(const RequestAdvSearch& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RequestAdvSearch::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RequestAdvSearch::~RequestAdvSearch() { + SharedDtor(); +} + +void RequestAdvSearch::SharedDtor() { + if (this != default_instance_) { + } +} + +void RequestAdvSearch::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestAdvSearch::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestAdvSearch_descriptor_; +} + +const RequestAdvSearch& RequestAdvSearch::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_search_2eproto(); return *default_instance_; +} + +RequestAdvSearch* RequestAdvSearch::default_instance_ = NULL; + +RequestAdvSearch* RequestAdvSearch::New() const { + return new RequestAdvSearch; +} + +void RequestAdvSearch::Clear() { + terms_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestAdvSearch::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated string terms = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_terms: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_terms())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->terms(0).data(), this->terms(0).length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_terms; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void RequestAdvSearch::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated string terms = 1; + for (int i = 0; i < this->terms_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->terms(i).data(), this->terms(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->terms(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RequestAdvSearch::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated string terms = 1; + for (int i = 0; i < this->terms_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->terms(i).data(), this->terms(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(1, this->terms(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RequestAdvSearch::ByteSize() const { + int total_size = 0; + + // repeated string terms = 1; + total_size += 1 * this->terms_size(); + for (int i = 0; i < this->terms_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->terms(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestAdvSearch::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestAdvSearch* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestAdvSearch::MergeFrom(const RequestAdvSearch& from) { + GOOGLE_CHECK_NE(&from, this); + terms_.MergeFrom(from.terms_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestAdvSearch::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestAdvSearch::CopyFrom(const RequestAdvSearch& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestAdvSearch::IsInitialized() const { + + return true; +} + +void RequestAdvSearch::Swap(RequestAdvSearch* other) { + if (other != this) { + terms_.Swap(&other->terms_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestAdvSearch::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestAdvSearch_descriptor_; + metadata.reflection = RequestAdvSearch_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ResponseSearchIds::kStatusFieldNumber; +const int ResponseSearchIds::kSearchIdFieldNumber; +#endif // !_MSC_VER + +ResponseSearchIds::ResponseSearchIds() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ResponseSearchIds::InitAsDefaultInstance() { + status_ = const_cast< ::rsctrl::core::Status*>(&::rsctrl::core::Status::default_instance()); +} + +ResponseSearchIds::ResponseSearchIds(const ResponseSearchIds& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ResponseSearchIds::SharedCtor() { + _cached_size_ = 0; + status_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ResponseSearchIds::~ResponseSearchIds() { + SharedDtor(); +} + +void ResponseSearchIds::SharedDtor() { + if (this != default_instance_) { + delete status_; + } +} + +void ResponseSearchIds::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ResponseSearchIds::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ResponseSearchIds_descriptor_; +} + +const ResponseSearchIds& ResponseSearchIds::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_search_2eproto(); return *default_instance_; +} + +ResponseSearchIds* ResponseSearchIds::default_instance_ = NULL; + +ResponseSearchIds* ResponseSearchIds::New() const { + return new ResponseSearchIds; +} + +void ResponseSearchIds::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_status()) { + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); + } + } + search_id_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ResponseSearchIds::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.core.Status status = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_status())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_search_id; + break; + } + + // repeated uint32 search_id = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_search_id: + DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + 1, 16, input, this->mutable_search_id()))); + } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) + == ::google::protobuf::internal::WireFormatLite:: + WIRETYPE_LENGTH_DELIMITED) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, this->mutable_search_id()))); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_search_id; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ResponseSearchIds::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->status(), output); + } + + // repeated uint32 search_id = 2; + for (int i = 0; i < this->search_id_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32( + 2, this->search_id(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ResponseSearchIds::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->status(), target); + } + + // repeated uint32 search_id = 2; + for (int i = 0; i < this->search_id_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteUInt32ToArray(2, this->search_id(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ResponseSearchIds::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->status()); + } + + } + // repeated uint32 search_id = 2; + { + int data_size = 0; + for (int i = 0; i < this->search_id_size(); i++) { + data_size += ::google::protobuf::internal::WireFormatLite:: + UInt32Size(this->search_id(i)); + } + total_size += 1 * this->search_id_size() + data_size; + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ResponseSearchIds::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ResponseSearchIds* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ResponseSearchIds::MergeFrom(const ResponseSearchIds& from) { + GOOGLE_CHECK_NE(&from, this); + search_id_.MergeFrom(from.search_id_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_status()) { + mutable_status()->::rsctrl::core::Status::MergeFrom(from.status()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ResponseSearchIds::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ResponseSearchIds::CopyFrom(const ResponseSearchIds& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ResponseSearchIds::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_status()) { + if (!this->status().IsInitialized()) return false; + } + return true; +} + +void ResponseSearchIds::Swap(ResponseSearchIds* other) { + if (other != this) { + std::swap(status_, other->status_); + search_id_.Swap(&other->search_id_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ResponseSearchIds::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ResponseSearchIds_descriptor_; + metadata.reflection = ResponseSearchIds_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int RequestCloseSearch::kSearchIdFieldNumber; +#endif // !_MSC_VER + +RequestCloseSearch::RequestCloseSearch() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RequestCloseSearch::InitAsDefaultInstance() { +} + +RequestCloseSearch::RequestCloseSearch(const RequestCloseSearch& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RequestCloseSearch::SharedCtor() { + _cached_size_ = 0; + search_id_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RequestCloseSearch::~RequestCloseSearch() { + SharedDtor(); +} + +void RequestCloseSearch::SharedDtor() { + if (this != default_instance_) { + } +} + +void RequestCloseSearch::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestCloseSearch::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestCloseSearch_descriptor_; +} + +const RequestCloseSearch& RequestCloseSearch::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_search_2eproto(); return *default_instance_; +} + +RequestCloseSearch* RequestCloseSearch::default_instance_ = NULL; + +RequestCloseSearch* RequestCloseSearch::New() const { + return new RequestCloseSearch; +} + +void RequestCloseSearch::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + search_id_ = 0u; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestCloseSearch::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint32 search_id = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &search_id_))); + set_has_search_id(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void RequestCloseSearch::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required uint32 search_id = 1; + if (has_search_id()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->search_id(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RequestCloseSearch::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required uint32 search_id = 1; + if (has_search_id()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->search_id(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RequestCloseSearch::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required uint32 search_id = 1; + if (has_search_id()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->search_id()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestCloseSearch::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestCloseSearch* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestCloseSearch::MergeFrom(const RequestCloseSearch& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_search_id()) { + set_search_id(from.search_id()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestCloseSearch::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestCloseSearch::CopyFrom(const RequestCloseSearch& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestCloseSearch::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void RequestCloseSearch::Swap(RequestCloseSearch* other) { + if (other != this) { + std::swap(search_id_, other->search_id_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestCloseSearch::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestCloseSearch_descriptor_; + metadata.reflection = RequestCloseSearch_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +#endif // !_MSC_VER + +RequestListSearches::RequestListSearches() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RequestListSearches::InitAsDefaultInstance() { +} + +RequestListSearches::RequestListSearches(const RequestListSearches& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RequestListSearches::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RequestListSearches::~RequestListSearches() { + SharedDtor(); +} + +void RequestListSearches::SharedDtor() { + if (this != default_instance_) { + } +} + +void RequestListSearches::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestListSearches::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestListSearches_descriptor_; +} + +const RequestListSearches& RequestListSearches::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_search_2eproto(); return *default_instance_; +} + +RequestListSearches* RequestListSearches::default_instance_ = NULL; + +RequestListSearches* RequestListSearches::New() const { + return new RequestListSearches; +} + +void RequestListSearches::Clear() { + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestListSearches::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + } + return true; +#undef DO_ +} + +void RequestListSearches::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RequestListSearches::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RequestListSearches::ByteSize() const { + int total_size = 0; + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestListSearches::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestListSearches* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestListSearches::MergeFrom(const RequestListSearches& from) { + GOOGLE_CHECK_NE(&from, this); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestListSearches::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestListSearches::CopyFrom(const RequestListSearches& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestListSearches::IsInitialized() const { + + return true; +} + +void RequestListSearches::Swap(RequestListSearches* other) { + if (other != this) { + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestListSearches::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestListSearches_descriptor_; + metadata.reflection = RequestListSearches_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int RequestSearchResults::kSearchIdsFieldNumber; +#endif // !_MSC_VER + +RequestSearchResults::RequestSearchResults() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RequestSearchResults::InitAsDefaultInstance() { +} + +RequestSearchResults::RequestSearchResults(const RequestSearchResults& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RequestSearchResults::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RequestSearchResults::~RequestSearchResults() { + SharedDtor(); +} + +void RequestSearchResults::SharedDtor() { + if (this != default_instance_) { + } +} + +void RequestSearchResults::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestSearchResults::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestSearchResults_descriptor_; +} + +const RequestSearchResults& RequestSearchResults::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_search_2eproto(); return *default_instance_; +} + +RequestSearchResults* RequestSearchResults::default_instance_ = NULL; + +RequestSearchResults* RequestSearchResults::New() const { + return new RequestSearchResults; +} + +void RequestSearchResults::Clear() { + search_ids_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestSearchResults::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated uint32 search_ids = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_search_ids: + DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + 1, 16, input, this->mutable_search_ids()))); + } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) + == ::google::protobuf::internal::WireFormatLite:: + WIRETYPE_LENGTH_DELIMITED) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, this->mutable_search_ids()))); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(16)) goto parse_search_ids; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void RequestSearchResults::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated uint32 search_ids = 2; + for (int i = 0; i < this->search_ids_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32( + 2, this->search_ids(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RequestSearchResults::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated uint32 search_ids = 2; + for (int i = 0; i < this->search_ids_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteUInt32ToArray(2, this->search_ids(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RequestSearchResults::ByteSize() const { + int total_size = 0; + + // repeated uint32 search_ids = 2; + { + int data_size = 0; + for (int i = 0; i < this->search_ids_size(); i++) { + data_size += ::google::protobuf::internal::WireFormatLite:: + UInt32Size(this->search_ids(i)); + } + total_size += 1 * this->search_ids_size() + data_size; + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestSearchResults::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestSearchResults* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestSearchResults::MergeFrom(const RequestSearchResults& from) { + GOOGLE_CHECK_NE(&from, this); + search_ids_.MergeFrom(from.search_ids_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestSearchResults::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestSearchResults::CopyFrom(const RequestSearchResults& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestSearchResults::IsInitialized() const { + + return true; +} + +void RequestSearchResults::Swap(RequestSearchResults* other) { + if (other != this) { + search_ids_.Swap(&other->search_ids_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestSearchResults::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestSearchResults_descriptor_; + metadata.reflection = RequestSearchResults_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ResponseSearchResults::kStatusFieldNumber; +const int ResponseSearchResults::kSearchesFieldNumber; +#endif // !_MSC_VER + +ResponseSearchResults::ResponseSearchResults() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ResponseSearchResults::InitAsDefaultInstance() { + status_ = const_cast< ::rsctrl::core::Status*>(&::rsctrl::core::Status::default_instance()); +} + +ResponseSearchResults::ResponseSearchResults(const ResponseSearchResults& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ResponseSearchResults::SharedCtor() { + _cached_size_ = 0; + status_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ResponseSearchResults::~ResponseSearchResults() { + SharedDtor(); +} + +void ResponseSearchResults::SharedDtor() { + if (this != default_instance_) { + delete status_; + } +} + +void ResponseSearchResults::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ResponseSearchResults::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ResponseSearchResults_descriptor_; +} + +const ResponseSearchResults& ResponseSearchResults::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_search_2eproto(); return *default_instance_; +} + +ResponseSearchResults* ResponseSearchResults::default_instance_ = NULL; + +ResponseSearchResults* ResponseSearchResults::New() const { + return new ResponseSearchResults; +} + +void ResponseSearchResults::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_status()) { + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); + } + } + searches_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ResponseSearchResults::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.core.Status status = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_status())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_searches; + break; + } + + // repeated .rsctrl.search.SearchSet searches = 2; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_searches: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_searches())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_searches; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ResponseSearchResults::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->status(), output); + } + + // repeated .rsctrl.search.SearchSet searches = 2; + for (int i = 0; i < this->searches_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->searches(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ResponseSearchResults::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->status(), target); + } + + // repeated .rsctrl.search.SearchSet searches = 2; + for (int i = 0; i < this->searches_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->searches(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ResponseSearchResults::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->status()); + } + + } + // repeated .rsctrl.search.SearchSet searches = 2; + total_size += 1 * this->searches_size(); + for (int i = 0; i < this->searches_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->searches(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ResponseSearchResults::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ResponseSearchResults* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ResponseSearchResults::MergeFrom(const ResponseSearchResults& from) { + GOOGLE_CHECK_NE(&from, this); + searches_.MergeFrom(from.searches_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_status()) { + mutable_status()->::rsctrl::core::Status::MergeFrom(from.status()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ResponseSearchResults::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ResponseSearchResults::CopyFrom(const ResponseSearchResults& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ResponseSearchResults::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_status()) { + if (!this->status().IsInitialized()) return false; + } + for (int i = 0; i < searches_size(); i++) { + if (!this->searches(i).IsInitialized()) return false; + } + return true; +} + +void ResponseSearchResults::Swap(ResponseSearchResults* other) { + if (other != this) { + std::swap(status_, other->status_); + searches_.Swap(&other->searches_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ResponseSearchResults::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ResponseSearchResults_descriptor_; + metadata.reflection = ResponseSearchResults_reflection_; + return metadata; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace search +} // namespace rsctrl + +// @@protoc_insertion_point(global_scope) diff --git a/retroshare-nogui/src/rpc/proto/gencc/search.pb.h b/retroshare-nogui/src/rpc/proto/gencc/search.pb.h new file mode 100644 index 000000000..d006025cb --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/gencc/search.pb.h @@ -0,0 +1,1370 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: search.proto + +#ifndef PROTOBUF_search_2eproto__INCLUDED +#define PROTOBUF_search_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 2004000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 2004001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include "core.pb.h" +// @@protoc_insertion_point(includes) + +namespace rsctrl { +namespace search { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_search_2eproto(); +void protobuf_AssignDesc_search_2eproto(); +void protobuf_ShutdownFile_search_2eproto(); + +class SearchHit; +class SearchSet; +class RequestBasicSearch; +class RequestAdvSearch; +class ResponseSearchIds; +class RequestCloseSearch; +class RequestListSearches; +class RequestSearchResults; +class ResponseSearchResults; + +enum SearchHit_LocFlag { + SearchHit_LocFlag_LOCAL = 1, + SearchHit_LocFlag_FRIEND = 2, + SearchHit_LocFlag_NETWORK = 4 +}; +bool SearchHit_LocFlag_IsValid(int value); +const SearchHit_LocFlag SearchHit_LocFlag_LocFlag_MIN = SearchHit_LocFlag_LOCAL; +const SearchHit_LocFlag SearchHit_LocFlag_LocFlag_MAX = SearchHit_LocFlag_NETWORK; +const int SearchHit_LocFlag_LocFlag_ARRAYSIZE = SearchHit_LocFlag_LocFlag_MAX + 1; + +const ::google::protobuf::EnumDescriptor* SearchHit_LocFlag_descriptor(); +inline const ::std::string& SearchHit_LocFlag_Name(SearchHit_LocFlag value) { + return ::google::protobuf::internal::NameOfEnum( + SearchHit_LocFlag_descriptor(), value); +} +inline bool SearchHit_LocFlag_Parse( + const ::std::string& name, SearchHit_LocFlag* value) { + return ::google::protobuf::internal::ParseNamedEnum( + SearchHit_LocFlag_descriptor(), name, value); +} +enum RequestMsgIds { + MsgId_RequestBasicSearch = 1, + MsgId_RequestCloseSearch = 3, + MsgId_RequestListSearches = 4, + MsgId_RequestSearchResults = 5 +}; +bool RequestMsgIds_IsValid(int value); +const RequestMsgIds RequestMsgIds_MIN = MsgId_RequestBasicSearch; +const RequestMsgIds RequestMsgIds_MAX = MsgId_RequestSearchResults; +const int RequestMsgIds_ARRAYSIZE = RequestMsgIds_MAX + 1; + +const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor(); +inline const ::std::string& RequestMsgIds_Name(RequestMsgIds value) { + return ::google::protobuf::internal::NameOfEnum( + RequestMsgIds_descriptor(), value); +} +inline bool RequestMsgIds_Parse( + const ::std::string& name, RequestMsgIds* value) { + return ::google::protobuf::internal::ParseNamedEnum( + RequestMsgIds_descriptor(), name, value); +} +enum ResponseMsgIds { + MsgId_ResponseSearchIds = 1, + MsgId_ResponseSearchResults = 5 +}; +bool ResponseMsgIds_IsValid(int value); +const ResponseMsgIds ResponseMsgIds_MIN = MsgId_ResponseSearchIds; +const ResponseMsgIds ResponseMsgIds_MAX = MsgId_ResponseSearchResults; +const int ResponseMsgIds_ARRAYSIZE = ResponseMsgIds_MAX + 1; + +const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor(); +inline const ::std::string& ResponseMsgIds_Name(ResponseMsgIds value) { + return ::google::protobuf::internal::NameOfEnum( + ResponseMsgIds_descriptor(), value); +} +inline bool ResponseMsgIds_Parse( + const ::std::string& name, ResponseMsgIds* value) { + return ::google::protobuf::internal::ParseNamedEnum( + ResponseMsgIds_descriptor(), name, value); +} +// =================================================================== + +class SearchHit : public ::google::protobuf::Message { + public: + SearchHit(); + virtual ~SearchHit(); + + SearchHit(const SearchHit& from); + + inline SearchHit& operator=(const SearchHit& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const SearchHit& default_instance(); + + void Swap(SearchHit* other); + + // implements Message ---------------------------------------------- + + SearchHit* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const SearchHit& from); + void MergeFrom(const SearchHit& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef SearchHit_LocFlag LocFlag; + static const LocFlag LOCAL = SearchHit_LocFlag_LOCAL; + static const LocFlag FRIEND = SearchHit_LocFlag_FRIEND; + static const LocFlag NETWORK = SearchHit_LocFlag_NETWORK; + static inline bool LocFlag_IsValid(int value) { + return SearchHit_LocFlag_IsValid(value); + } + static const LocFlag LocFlag_MIN = + SearchHit_LocFlag_LocFlag_MIN; + static const LocFlag LocFlag_MAX = + SearchHit_LocFlag_LocFlag_MAX; + static const int LocFlag_ARRAYSIZE = + SearchHit_LocFlag_LocFlag_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + LocFlag_descriptor() { + return SearchHit_LocFlag_descriptor(); + } + static inline const ::std::string& LocFlag_Name(LocFlag value) { + return SearchHit_LocFlag_Name(value); + } + static inline bool LocFlag_Parse(const ::std::string& name, + LocFlag* value) { + return SearchHit_LocFlag_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // required .rsctrl.core.File file = 1; + inline bool has_file() const; + inline void clear_file(); + static const int kFileFieldNumber = 1; + inline const ::rsctrl::core::File& file() const; + inline ::rsctrl::core::File* mutable_file(); + inline ::rsctrl::core::File* release_file(); + + // required uint32 loc = 2; + inline bool has_loc() const; + inline void clear_loc(); + static const int kLocFieldNumber = 2; + inline ::google::protobuf::uint32 loc() const; + inline void set_loc(::google::protobuf::uint32 value); + + // required uint32 no_hits = 3; + inline bool has_no_hits() const; + inline void clear_no_hits(); + static const int kNoHitsFieldNumber = 3; + inline ::google::protobuf::uint32 no_hits() const; + inline void set_no_hits(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:rsctrl.search.SearchHit) + private: + inline void set_has_file(); + inline void clear_has_file(); + inline void set_has_loc(); + inline void clear_has_loc(); + inline void set_has_no_hits(); + inline void clear_has_no_hits(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::rsctrl::core::File* file_; + ::google::protobuf::uint32 loc_; + ::google::protobuf::uint32 no_hits_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; + + friend void protobuf_AddDesc_search_2eproto(); + friend void protobuf_AssignDesc_search_2eproto(); + friend void protobuf_ShutdownFile_search_2eproto(); + + void InitAsDefaultInstance(); + static SearchHit* default_instance_; +}; +// ------------------------------------------------------------------- + +class SearchSet : public ::google::protobuf::Message { + public: + SearchSet(); + virtual ~SearchSet(); + + SearchSet(const SearchSet& from); + + inline SearchSet& operator=(const SearchSet& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const SearchSet& default_instance(); + + void Swap(SearchSet* other); + + // implements Message ---------------------------------------------- + + SearchSet* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const SearchSet& from); + void MergeFrom(const SearchSet& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint32 search_id = 1; + inline bool has_search_id() const; + inline void clear_search_id(); + static const int kSearchIdFieldNumber = 1; + inline ::google::protobuf::uint32 search_id() const; + inline void set_search_id(::google::protobuf::uint32 value); + + // repeated .rsctrl.search.SearchHit hits = 2; + inline int hits_size() const; + inline void clear_hits(); + static const int kHitsFieldNumber = 2; + inline const ::rsctrl::search::SearchHit& hits(int index) const; + inline ::rsctrl::search::SearchHit* mutable_hits(int index); + inline ::rsctrl::search::SearchHit* add_hits(); + inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::search::SearchHit >& + hits() const; + inline ::google::protobuf::RepeatedPtrField< ::rsctrl::search::SearchHit >* + mutable_hits(); + + // @@protoc_insertion_point(class_scope:rsctrl.search.SearchSet) + private: + inline void set_has_search_id(); + inline void clear_has_search_id(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::rsctrl::search::SearchHit > hits_; + ::google::protobuf::uint32 search_id_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_search_2eproto(); + friend void protobuf_AssignDesc_search_2eproto(); + friend void protobuf_ShutdownFile_search_2eproto(); + + void InitAsDefaultInstance(); + static SearchSet* default_instance_; +}; +// ------------------------------------------------------------------- + +class RequestBasicSearch : public ::google::protobuf::Message { + public: + RequestBasicSearch(); + virtual ~RequestBasicSearch(); + + RequestBasicSearch(const RequestBasicSearch& from); + + inline RequestBasicSearch& operator=(const RequestBasicSearch& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestBasicSearch& default_instance(); + + void Swap(RequestBasicSearch* other); + + // implements Message ---------------------------------------------- + + RequestBasicSearch* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestBasicSearch& from); + void MergeFrom(const RequestBasicSearch& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated string terms = 1; + inline int terms_size() const; + inline void clear_terms(); + static const int kTermsFieldNumber = 1; + inline const ::std::string& terms(int index) const; + inline ::std::string* mutable_terms(int index); + inline void set_terms(int index, const ::std::string& value); + inline void set_terms(int index, const char* value); + inline void set_terms(int index, const char* value, size_t size); + inline ::std::string* add_terms(); + inline void add_terms(const ::std::string& value); + inline void add_terms(const char* value); + inline void add_terms(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& terms() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_terms(); + + // @@protoc_insertion_point(class_scope:rsctrl.search.RequestBasicSearch) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::std::string> terms_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_search_2eproto(); + friend void protobuf_AssignDesc_search_2eproto(); + friend void protobuf_ShutdownFile_search_2eproto(); + + void InitAsDefaultInstance(); + static RequestBasicSearch* default_instance_; +}; +// ------------------------------------------------------------------- + +class RequestAdvSearch : public ::google::protobuf::Message { + public: + RequestAdvSearch(); + virtual ~RequestAdvSearch(); + + RequestAdvSearch(const RequestAdvSearch& from); + + inline RequestAdvSearch& operator=(const RequestAdvSearch& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestAdvSearch& default_instance(); + + void Swap(RequestAdvSearch* other); + + // implements Message ---------------------------------------------- + + RequestAdvSearch* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestAdvSearch& from); + void MergeFrom(const RequestAdvSearch& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated string terms = 1; + inline int terms_size() const; + inline void clear_terms(); + static const int kTermsFieldNumber = 1; + inline const ::std::string& terms(int index) const; + inline ::std::string* mutable_terms(int index); + inline void set_terms(int index, const ::std::string& value); + inline void set_terms(int index, const char* value); + inline void set_terms(int index, const char* value, size_t size); + inline ::std::string* add_terms(); + inline void add_terms(const ::std::string& value); + inline void add_terms(const char* value); + inline void add_terms(const char* value, size_t size); + inline const ::google::protobuf::RepeatedPtrField< ::std::string>& terms() const; + inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_terms(); + + // @@protoc_insertion_point(class_scope:rsctrl.search.RequestAdvSearch) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::std::string> terms_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_search_2eproto(); + friend void protobuf_AssignDesc_search_2eproto(); + friend void protobuf_ShutdownFile_search_2eproto(); + + void InitAsDefaultInstance(); + static RequestAdvSearch* default_instance_; +}; +// ------------------------------------------------------------------- + +class ResponseSearchIds : public ::google::protobuf::Message { + public: + ResponseSearchIds(); + virtual ~ResponseSearchIds(); + + ResponseSearchIds(const ResponseSearchIds& from); + + inline ResponseSearchIds& operator=(const ResponseSearchIds& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ResponseSearchIds& default_instance(); + + void Swap(ResponseSearchIds* other); + + // implements Message ---------------------------------------------- + + ResponseSearchIds* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ResponseSearchIds& from); + void MergeFrom(const ResponseSearchIds& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .rsctrl.core.Status status = 1; + inline bool has_status() const; + inline void clear_status(); + static const int kStatusFieldNumber = 1; + inline const ::rsctrl::core::Status& status() const; + inline ::rsctrl::core::Status* mutable_status(); + inline ::rsctrl::core::Status* release_status(); + + // repeated uint32 search_id = 2; + inline int search_id_size() const; + inline void clear_search_id(); + static const int kSearchIdFieldNumber = 2; + inline ::google::protobuf::uint32 search_id(int index) const; + inline void set_search_id(int index, ::google::protobuf::uint32 value); + inline void add_search_id(::google::protobuf::uint32 value); + inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >& + search_id() const; + inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >* + mutable_search_id(); + + // @@protoc_insertion_point(class_scope:rsctrl.search.ResponseSearchIds) + private: + inline void set_has_status(); + inline void clear_has_status(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::rsctrl::core::Status* status_; + ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > search_id_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_search_2eproto(); + friend void protobuf_AssignDesc_search_2eproto(); + friend void protobuf_ShutdownFile_search_2eproto(); + + void InitAsDefaultInstance(); + static ResponseSearchIds* default_instance_; +}; +// ------------------------------------------------------------------- + +class RequestCloseSearch : public ::google::protobuf::Message { + public: + RequestCloseSearch(); + virtual ~RequestCloseSearch(); + + RequestCloseSearch(const RequestCloseSearch& from); + + inline RequestCloseSearch& operator=(const RequestCloseSearch& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestCloseSearch& default_instance(); + + void Swap(RequestCloseSearch* other); + + // implements Message ---------------------------------------------- + + RequestCloseSearch* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestCloseSearch& from); + void MergeFrom(const RequestCloseSearch& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint32 search_id = 1; + inline bool has_search_id() const; + inline void clear_search_id(); + static const int kSearchIdFieldNumber = 1; + inline ::google::protobuf::uint32 search_id() const; + inline void set_search_id(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:rsctrl.search.RequestCloseSearch) + private: + inline void set_has_search_id(); + inline void clear_has_search_id(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::uint32 search_id_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_search_2eproto(); + friend void protobuf_AssignDesc_search_2eproto(); + friend void protobuf_ShutdownFile_search_2eproto(); + + void InitAsDefaultInstance(); + static RequestCloseSearch* default_instance_; +}; +// ------------------------------------------------------------------- + +class RequestListSearches : public ::google::protobuf::Message { + public: + RequestListSearches(); + virtual ~RequestListSearches(); + + RequestListSearches(const RequestListSearches& from); + + inline RequestListSearches& operator=(const RequestListSearches& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestListSearches& default_instance(); + + void Swap(RequestListSearches* other); + + // implements Message ---------------------------------------------- + + RequestListSearches* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestListSearches& from); + void MergeFrom(const RequestListSearches& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // @@protoc_insertion_point(class_scope:rsctrl.search.RequestListSearches) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[1]; + + friend void protobuf_AddDesc_search_2eproto(); + friend void protobuf_AssignDesc_search_2eproto(); + friend void protobuf_ShutdownFile_search_2eproto(); + + void InitAsDefaultInstance(); + static RequestListSearches* default_instance_; +}; +// ------------------------------------------------------------------- + +class RequestSearchResults : public ::google::protobuf::Message { + public: + RequestSearchResults(); + virtual ~RequestSearchResults(); + + RequestSearchResults(const RequestSearchResults& from); + + inline RequestSearchResults& operator=(const RequestSearchResults& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestSearchResults& default_instance(); + + void Swap(RequestSearchResults* other); + + // implements Message ---------------------------------------------- + + RequestSearchResults* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestSearchResults& from); + void MergeFrom(const RequestSearchResults& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated uint32 search_ids = 2; + inline int search_ids_size() const; + inline void clear_search_ids(); + static const int kSearchIdsFieldNumber = 2; + inline ::google::protobuf::uint32 search_ids(int index) const; + inline void set_search_ids(int index, ::google::protobuf::uint32 value); + inline void add_search_ids(::google::protobuf::uint32 value); + inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >& + search_ids() const; + inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >* + mutable_search_ids(); + + // @@protoc_insertion_point(class_scope:rsctrl.search.RequestSearchResults) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > search_ids_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_search_2eproto(); + friend void protobuf_AssignDesc_search_2eproto(); + friend void protobuf_ShutdownFile_search_2eproto(); + + void InitAsDefaultInstance(); + static RequestSearchResults* default_instance_; +}; +// ------------------------------------------------------------------- + +class ResponseSearchResults : public ::google::protobuf::Message { + public: + ResponseSearchResults(); + virtual ~ResponseSearchResults(); + + ResponseSearchResults(const ResponseSearchResults& from); + + inline ResponseSearchResults& operator=(const ResponseSearchResults& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ResponseSearchResults& default_instance(); + + void Swap(ResponseSearchResults* other); + + // implements Message ---------------------------------------------- + + ResponseSearchResults* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ResponseSearchResults& from); + void MergeFrom(const ResponseSearchResults& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .rsctrl.core.Status status = 1; + inline bool has_status() const; + inline void clear_status(); + static const int kStatusFieldNumber = 1; + inline const ::rsctrl::core::Status& status() const; + inline ::rsctrl::core::Status* mutable_status(); + inline ::rsctrl::core::Status* release_status(); + + // repeated .rsctrl.search.SearchSet searches = 2; + inline int searches_size() const; + inline void clear_searches(); + static const int kSearchesFieldNumber = 2; + inline const ::rsctrl::search::SearchSet& searches(int index) const; + inline ::rsctrl::search::SearchSet* mutable_searches(int index); + inline ::rsctrl::search::SearchSet* add_searches(); + inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::search::SearchSet >& + searches() const; + inline ::google::protobuf::RepeatedPtrField< ::rsctrl::search::SearchSet >* + mutable_searches(); + + // @@protoc_insertion_point(class_scope:rsctrl.search.ResponseSearchResults) + private: + inline void set_has_status(); + inline void clear_has_status(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::rsctrl::core::Status* status_; + ::google::protobuf::RepeatedPtrField< ::rsctrl::search::SearchSet > searches_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void protobuf_AddDesc_search_2eproto(); + friend void protobuf_AssignDesc_search_2eproto(); + friend void protobuf_ShutdownFile_search_2eproto(); + + void InitAsDefaultInstance(); + static ResponseSearchResults* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +// SearchHit + +// required .rsctrl.core.File file = 1; +inline bool SearchHit::has_file() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void SearchHit::set_has_file() { + _has_bits_[0] |= 0x00000001u; +} +inline void SearchHit::clear_has_file() { + _has_bits_[0] &= ~0x00000001u; +} +inline void SearchHit::clear_file() { + if (file_ != NULL) file_->::rsctrl::core::File::Clear(); + clear_has_file(); +} +inline const ::rsctrl::core::File& SearchHit::file() const { + return file_ != NULL ? *file_ : *default_instance_->file_; +} +inline ::rsctrl::core::File* SearchHit::mutable_file() { + set_has_file(); + if (file_ == NULL) file_ = new ::rsctrl::core::File; + return file_; +} +inline ::rsctrl::core::File* SearchHit::release_file() { + clear_has_file(); + ::rsctrl::core::File* temp = file_; + file_ = NULL; + return temp; +} + +// required uint32 loc = 2; +inline bool SearchHit::has_loc() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void SearchHit::set_has_loc() { + _has_bits_[0] |= 0x00000002u; +} +inline void SearchHit::clear_has_loc() { + _has_bits_[0] &= ~0x00000002u; +} +inline void SearchHit::clear_loc() { + loc_ = 0u; + clear_has_loc(); +} +inline ::google::protobuf::uint32 SearchHit::loc() const { + return loc_; +} +inline void SearchHit::set_loc(::google::protobuf::uint32 value) { + set_has_loc(); + loc_ = value; +} + +// required uint32 no_hits = 3; +inline bool SearchHit::has_no_hits() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void SearchHit::set_has_no_hits() { + _has_bits_[0] |= 0x00000004u; +} +inline void SearchHit::clear_has_no_hits() { + _has_bits_[0] &= ~0x00000004u; +} +inline void SearchHit::clear_no_hits() { + no_hits_ = 0u; + clear_has_no_hits(); +} +inline ::google::protobuf::uint32 SearchHit::no_hits() const { + return no_hits_; +} +inline void SearchHit::set_no_hits(::google::protobuf::uint32 value) { + set_has_no_hits(); + no_hits_ = value; +} + +// ------------------------------------------------------------------- + +// SearchSet + +// required uint32 search_id = 1; +inline bool SearchSet::has_search_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void SearchSet::set_has_search_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void SearchSet::clear_has_search_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void SearchSet::clear_search_id() { + search_id_ = 0u; + clear_has_search_id(); +} +inline ::google::protobuf::uint32 SearchSet::search_id() const { + return search_id_; +} +inline void SearchSet::set_search_id(::google::protobuf::uint32 value) { + set_has_search_id(); + search_id_ = value; +} + +// repeated .rsctrl.search.SearchHit hits = 2; +inline int SearchSet::hits_size() const { + return hits_.size(); +} +inline void SearchSet::clear_hits() { + hits_.Clear(); +} +inline const ::rsctrl::search::SearchHit& SearchSet::hits(int index) const { + return hits_.Get(index); +} +inline ::rsctrl::search::SearchHit* SearchSet::mutable_hits(int index) { + return hits_.Mutable(index); +} +inline ::rsctrl::search::SearchHit* SearchSet::add_hits() { + return hits_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::search::SearchHit >& +SearchSet::hits() const { + return hits_; +} +inline ::google::protobuf::RepeatedPtrField< ::rsctrl::search::SearchHit >* +SearchSet::mutable_hits() { + return &hits_; +} + +// ------------------------------------------------------------------- + +// RequestBasicSearch + +// repeated string terms = 1; +inline int RequestBasicSearch::terms_size() const { + return terms_.size(); +} +inline void RequestBasicSearch::clear_terms() { + terms_.Clear(); +} +inline const ::std::string& RequestBasicSearch::terms(int index) const { + return terms_.Get(index); +} +inline ::std::string* RequestBasicSearch::mutable_terms(int index) { + return terms_.Mutable(index); +} +inline void RequestBasicSearch::set_terms(int index, const ::std::string& value) { + terms_.Mutable(index)->assign(value); +} +inline void RequestBasicSearch::set_terms(int index, const char* value) { + terms_.Mutable(index)->assign(value); +} +inline void RequestBasicSearch::set_terms(int index, const char* value, size_t size) { + terms_.Mutable(index)->assign( + reinterpret_cast(value), size); +} +inline ::std::string* RequestBasicSearch::add_terms() { + return terms_.Add(); +} +inline void RequestBasicSearch::add_terms(const ::std::string& value) { + terms_.Add()->assign(value); +} +inline void RequestBasicSearch::add_terms(const char* value) { + terms_.Add()->assign(value); +} +inline void RequestBasicSearch::add_terms(const char* value, size_t size) { + terms_.Add()->assign(reinterpret_cast(value), size); +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +RequestBasicSearch::terms() const { + return terms_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +RequestBasicSearch::mutable_terms() { + return &terms_; +} + +// ------------------------------------------------------------------- + +// RequestAdvSearch + +// repeated string terms = 1; +inline int RequestAdvSearch::terms_size() const { + return terms_.size(); +} +inline void RequestAdvSearch::clear_terms() { + terms_.Clear(); +} +inline const ::std::string& RequestAdvSearch::terms(int index) const { + return terms_.Get(index); +} +inline ::std::string* RequestAdvSearch::mutable_terms(int index) { + return terms_.Mutable(index); +} +inline void RequestAdvSearch::set_terms(int index, const ::std::string& value) { + terms_.Mutable(index)->assign(value); +} +inline void RequestAdvSearch::set_terms(int index, const char* value) { + terms_.Mutable(index)->assign(value); +} +inline void RequestAdvSearch::set_terms(int index, const char* value, size_t size) { + terms_.Mutable(index)->assign( + reinterpret_cast(value), size); +} +inline ::std::string* RequestAdvSearch::add_terms() { + return terms_.Add(); +} +inline void RequestAdvSearch::add_terms(const ::std::string& value) { + terms_.Add()->assign(value); +} +inline void RequestAdvSearch::add_terms(const char* value) { + terms_.Add()->assign(value); +} +inline void RequestAdvSearch::add_terms(const char* value, size_t size) { + terms_.Add()->assign(reinterpret_cast(value), size); +} +inline const ::google::protobuf::RepeatedPtrField< ::std::string>& +RequestAdvSearch::terms() const { + return terms_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +RequestAdvSearch::mutable_terms() { + return &terms_; +} + +// ------------------------------------------------------------------- + +// ResponseSearchIds + +// required .rsctrl.core.Status status = 1; +inline bool ResponseSearchIds::has_status() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ResponseSearchIds::set_has_status() { + _has_bits_[0] |= 0x00000001u; +} +inline void ResponseSearchIds::clear_has_status() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ResponseSearchIds::clear_status() { + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); + clear_has_status(); +} +inline const ::rsctrl::core::Status& ResponseSearchIds::status() const { + return status_ != NULL ? *status_ : *default_instance_->status_; +} +inline ::rsctrl::core::Status* ResponseSearchIds::mutable_status() { + set_has_status(); + if (status_ == NULL) status_ = new ::rsctrl::core::Status; + return status_; +} +inline ::rsctrl::core::Status* ResponseSearchIds::release_status() { + clear_has_status(); + ::rsctrl::core::Status* temp = status_; + status_ = NULL; + return temp; +} + +// repeated uint32 search_id = 2; +inline int ResponseSearchIds::search_id_size() const { + return search_id_.size(); +} +inline void ResponseSearchIds::clear_search_id() { + search_id_.Clear(); +} +inline ::google::protobuf::uint32 ResponseSearchIds::search_id(int index) const { + return search_id_.Get(index); +} +inline void ResponseSearchIds::set_search_id(int index, ::google::protobuf::uint32 value) { + search_id_.Set(index, value); +} +inline void ResponseSearchIds::add_search_id(::google::protobuf::uint32 value) { + search_id_.Add(value); +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >& +ResponseSearchIds::search_id() const { + return search_id_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >* +ResponseSearchIds::mutable_search_id() { + return &search_id_; +} + +// ------------------------------------------------------------------- + +// RequestCloseSearch + +// required uint32 search_id = 1; +inline bool RequestCloseSearch::has_search_id() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void RequestCloseSearch::set_has_search_id() { + _has_bits_[0] |= 0x00000001u; +} +inline void RequestCloseSearch::clear_has_search_id() { + _has_bits_[0] &= ~0x00000001u; +} +inline void RequestCloseSearch::clear_search_id() { + search_id_ = 0u; + clear_has_search_id(); +} +inline ::google::protobuf::uint32 RequestCloseSearch::search_id() const { + return search_id_; +} +inline void RequestCloseSearch::set_search_id(::google::protobuf::uint32 value) { + set_has_search_id(); + search_id_ = value; +} + +// ------------------------------------------------------------------- + +// RequestListSearches + +// ------------------------------------------------------------------- + +// RequestSearchResults + +// repeated uint32 search_ids = 2; +inline int RequestSearchResults::search_ids_size() const { + return search_ids_.size(); +} +inline void RequestSearchResults::clear_search_ids() { + search_ids_.Clear(); +} +inline ::google::protobuf::uint32 RequestSearchResults::search_ids(int index) const { + return search_ids_.Get(index); +} +inline void RequestSearchResults::set_search_ids(int index, ::google::protobuf::uint32 value) { + search_ids_.Set(index, value); +} +inline void RequestSearchResults::add_search_ids(::google::protobuf::uint32 value) { + search_ids_.Add(value); +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >& +RequestSearchResults::search_ids() const { + return search_ids_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::uint32 >* +RequestSearchResults::mutable_search_ids() { + return &search_ids_; +} + +// ------------------------------------------------------------------- + +// ResponseSearchResults + +// required .rsctrl.core.Status status = 1; +inline bool ResponseSearchResults::has_status() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ResponseSearchResults::set_has_status() { + _has_bits_[0] |= 0x00000001u; +} +inline void ResponseSearchResults::clear_has_status() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ResponseSearchResults::clear_status() { + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); + clear_has_status(); +} +inline const ::rsctrl::core::Status& ResponseSearchResults::status() const { + return status_ != NULL ? *status_ : *default_instance_->status_; +} +inline ::rsctrl::core::Status* ResponseSearchResults::mutable_status() { + set_has_status(); + if (status_ == NULL) status_ = new ::rsctrl::core::Status; + return status_; +} +inline ::rsctrl::core::Status* ResponseSearchResults::release_status() { + clear_has_status(); + ::rsctrl::core::Status* temp = status_; + status_ = NULL; + return temp; +} + +// repeated .rsctrl.search.SearchSet searches = 2; +inline int ResponseSearchResults::searches_size() const { + return searches_.size(); +} +inline void ResponseSearchResults::clear_searches() { + searches_.Clear(); +} +inline const ::rsctrl::search::SearchSet& ResponseSearchResults::searches(int index) const { + return searches_.Get(index); +} +inline ::rsctrl::search::SearchSet* ResponseSearchResults::mutable_searches(int index) { + return searches_.Mutable(index); +} +inline ::rsctrl::search::SearchSet* ResponseSearchResults::add_searches() { + return searches_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::rsctrl::search::SearchSet >& +ResponseSearchResults::searches() const { + return searches_; +} +inline ::google::protobuf::RepeatedPtrField< ::rsctrl::search::SearchSet >* +ResponseSearchResults::mutable_searches() { + return &searches_; +} + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace search +} // namespace rsctrl + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::search::SearchHit_LocFlag>() { + return ::rsctrl::search::SearchHit_LocFlag_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< rsctrl::search::RequestMsgIds>() { + return rsctrl::search::RequestMsgIds_descriptor(); +} +template <> +inline const EnumDescriptor* GetEnumDescriptor< rsctrl::search::ResponseMsgIds>() { + return rsctrl::search::ResponseMsgIds_descriptor(); +} + +} // namespace google +} // namespace protobuf +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_search_2eproto__INCLUDED diff --git a/retroshare-nogui/src/rpc/proto/gencc/system.pb.cc b/retroshare-nogui/src/rpc/proto/gencc/system.pb.cc index ca729ce8f..915d6affd 100644 --- a/retroshare-nogui/src/rpc/proto/gencc/system.pb.cc +++ b/retroshare-nogui/src/rpc/proto/gencc/system.pb.cc @@ -25,6 +25,13 @@ const ::google::protobuf::Descriptor* ResponseSystemStatus_descriptor_ = NULL; const ::google::protobuf::internal::GeneratedMessageReflection* ResponseSystemStatus_reflection_ = NULL; const ::google::protobuf::EnumDescriptor* ResponseSystemStatus_NetCode_descriptor_ = NULL; +const ::google::protobuf::Descriptor* RequestSystemQuit_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestSystemQuit_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* RequestSystemQuit_QuitCode_descriptor_ = NULL; +const ::google::protobuf::Descriptor* ResponseSystemQuit_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ResponseSystemQuit_reflection_ = NULL; const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor_ = NULL; const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor_ = NULL; @@ -71,6 +78,37 @@ void protobuf_AssignDesc_system_2eproto() { ::google::protobuf::MessageFactory::generated_factory(), sizeof(ResponseSystemStatus)); ResponseSystemStatus_NetCode_descriptor_ = ResponseSystemStatus_descriptor_->enum_type(0); + RequestSystemQuit_descriptor_ = file->message_type(2); + static const int RequestSystemQuit_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestSystemQuit, quit_code_), + }; + RequestSystemQuit_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestSystemQuit_descriptor_, + RequestSystemQuit::default_instance_, + RequestSystemQuit_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestSystemQuit, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestSystemQuit, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestSystemQuit)); + RequestSystemQuit_QuitCode_descriptor_ = RequestSystemQuit_descriptor_->enum_type(0); + ResponseSystemQuit_descriptor_ = file->message_type(3); + static const int ResponseSystemQuit_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSystemQuit, status_), + }; + ResponseSystemQuit_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ResponseSystemQuit_descriptor_, + ResponseSystemQuit::default_instance_, + ResponseSystemQuit_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSystemQuit, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSystemQuit, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ResponseSystemQuit)); RequestMsgIds_descriptor_ = file->enum_type(0); ResponseMsgIds_descriptor_ = file->enum_type(1); } @@ -89,6 +127,10 @@ void protobuf_RegisterTypes(const ::std::string&) { RequestSystemStatus_descriptor_, &RequestSystemStatus::default_instance()); ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( ResponseSystemStatus_descriptor_, &ResponseSystemStatus::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestSystemQuit_descriptor_, &RequestSystemQuit::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ResponseSystemQuit_descriptor_, &ResponseSystemQuit::default_instance()); } } // namespace @@ -98,6 +140,10 @@ void protobuf_ShutdownFile_system_2eproto() { delete RequestSystemStatus_reflection_; delete ResponseSystemStatus::default_instance_; delete ResponseSystemStatus_reflection_; + delete RequestSystemQuit::default_instance_; + delete RequestSystemQuit_reflection_; + delete ResponseSystemQuit::default_instance_; + delete ResponseSystemQuit_reflection_; } void protobuf_AddDesc_system_2eproto() { @@ -119,15 +165,25 @@ void protobuf_AddDesc_system_2eproto() { "\016\n\nBAD_NATSYM\020\002\022\021\n\rBAD_NODHT_NAT\020\003\022\023\n\017WA" "RNING_RESTART\020\004\022\022\n\016WARNING_NATTED\020\005\022\021\n\rW" "ARNING_NODHT\020\006\022\010\n\004GOOD\020\007\022\017\n\013ADV_FORWARD\020" - "\010*.\n\rRequestMsgIds\022\035\n\031MsgId_RequestSyste" - "mStatus\020\001*0\n\016ResponseMsgIds\022\036\n\032MsgId_Res" - "ponseSystemStatus\020\001", 539); + "\010\"\201\001\n\021RequestSystemQuit\022<\n\tquit_code\030\001 \002" + "(\0162).rsctrl.system.RequestSystemQuit.Qui" + "tCode\".\n\010QuitCode\022\021\n\rCLOSE_CHANNEL\020\001\022\017\n\013" + "SHUTDOWN_RS\020\002\"9\n\022ResponseSystemQuit\022#\n\006s" + "tatus\030\001 \002(\0132\023.rsctrl.core.Status*K\n\rRequ" + "estMsgIds\022\035\n\031MsgId_RequestSystemStatus\020\001" + "\022\033\n\027MsgId_RequestSystemQuit\020\002*N\n\016Respons" + "eMsgIds\022\036\n\032MsgId_ResponseSystemStatus\020\001\022" + "\034\n\030MsgId_ResponseSystemQuit\020\002", 789); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "system.proto", &protobuf_RegisterTypes); RequestSystemStatus::default_instance_ = new RequestSystemStatus(); ResponseSystemStatus::default_instance_ = new ResponseSystemStatus(); + RequestSystemQuit::default_instance_ = new RequestSystemQuit(); + ResponseSystemQuit::default_instance_ = new ResponseSystemQuit(); RequestSystemStatus::default_instance_->InitAsDefaultInstance(); ResponseSystemStatus::default_instance_->InitAsDefaultInstance(); + RequestSystemQuit::default_instance_->InitAsDefaultInstance(); + ResponseSystemQuit::default_instance_->InitAsDefaultInstance(); ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_system_2eproto); } @@ -145,6 +201,7 @@ const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor() { bool RequestMsgIds_IsValid(int value) { switch(value) { case 1: + case 2: return true; default: return false; @@ -158,6 +215,7 @@ const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor() { bool ResponseMsgIds_IsValid(int value) { switch(value) { case 1: + case 2: return true; default: return false; @@ -745,6 +803,457 @@ void ResponseSystemStatus::Swap(ResponseSystemStatus* other) { } +// =================================================================== + +const ::google::protobuf::EnumDescriptor* RequestSystemQuit_QuitCode_descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestSystemQuit_QuitCode_descriptor_; +} +bool RequestSystemQuit_QuitCode_IsValid(int value) { + switch(value) { + case 1: + case 2: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const RequestSystemQuit_QuitCode RequestSystemQuit::CLOSE_CHANNEL; +const RequestSystemQuit_QuitCode RequestSystemQuit::SHUTDOWN_RS; +const RequestSystemQuit_QuitCode RequestSystemQuit::QuitCode_MIN; +const RequestSystemQuit_QuitCode RequestSystemQuit::QuitCode_MAX; +const int RequestSystemQuit::QuitCode_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int RequestSystemQuit::kQuitCodeFieldNumber; +#endif // !_MSC_VER + +RequestSystemQuit::RequestSystemQuit() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RequestSystemQuit::InitAsDefaultInstance() { +} + +RequestSystemQuit::RequestSystemQuit(const RequestSystemQuit& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RequestSystemQuit::SharedCtor() { + _cached_size_ = 0; + quit_code_ = 1; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RequestSystemQuit::~RequestSystemQuit() { + SharedDtor(); +} + +void RequestSystemQuit::SharedDtor() { + if (this != default_instance_) { + } +} + +void RequestSystemQuit::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestSystemQuit::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestSystemQuit_descriptor_; +} + +const RequestSystemQuit& RequestSystemQuit::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_system_2eproto(); return *default_instance_; +} + +RequestSystemQuit* RequestSystemQuit::default_instance_ = NULL; + +RequestSystemQuit* RequestSystemQuit::New() const { + return new RequestSystemQuit; +} + +void RequestSystemQuit::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + quit_code_ = 1; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestSystemQuit::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.system.RequestSystemQuit.QuitCode quit_code = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::rsctrl::system::RequestSystemQuit_QuitCode_IsValid(value)) { + set_quit_code(static_cast< ::rsctrl::system::RequestSystemQuit_QuitCode >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void RequestSystemQuit::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.system.RequestSystemQuit.QuitCode quit_code = 1; + if (has_quit_code()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->quit_code(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RequestSystemQuit::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.system.RequestSystemQuit.QuitCode quit_code = 1; + if (has_quit_code()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->quit_code(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RequestSystemQuit::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.system.RequestSystemQuit.QuitCode quit_code = 1; + if (has_quit_code()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->quit_code()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestSystemQuit::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestSystemQuit* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestSystemQuit::MergeFrom(const RequestSystemQuit& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_quit_code()) { + set_quit_code(from.quit_code()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestSystemQuit::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestSystemQuit::CopyFrom(const RequestSystemQuit& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestSystemQuit::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void RequestSystemQuit::Swap(RequestSystemQuit* other) { + if (other != this) { + std::swap(quit_code_, other->quit_code_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestSystemQuit::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestSystemQuit_descriptor_; + metadata.reflection = RequestSystemQuit_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ResponseSystemQuit::kStatusFieldNumber; +#endif // !_MSC_VER + +ResponseSystemQuit::ResponseSystemQuit() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ResponseSystemQuit::InitAsDefaultInstance() { + status_ = const_cast< ::rsctrl::core::Status*>(&::rsctrl::core::Status::default_instance()); +} + +ResponseSystemQuit::ResponseSystemQuit(const ResponseSystemQuit& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ResponseSystemQuit::SharedCtor() { + _cached_size_ = 0; + status_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ResponseSystemQuit::~ResponseSystemQuit() { + SharedDtor(); +} + +void ResponseSystemQuit::SharedDtor() { + if (this != default_instance_) { + delete status_; + } +} + +void ResponseSystemQuit::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ResponseSystemQuit::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ResponseSystemQuit_descriptor_; +} + +const ResponseSystemQuit& ResponseSystemQuit::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_system_2eproto(); return *default_instance_; +} + +ResponseSystemQuit* ResponseSystemQuit::default_instance_ = NULL; + +ResponseSystemQuit* ResponseSystemQuit::New() const { + return new ResponseSystemQuit; +} + +void ResponseSystemQuit::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_status()) { + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ResponseSystemQuit::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.core.Status status = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_status())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ResponseSystemQuit::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->status(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ResponseSystemQuit::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->status(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ResponseSystemQuit::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->status()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ResponseSystemQuit::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ResponseSystemQuit* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ResponseSystemQuit::MergeFrom(const ResponseSystemQuit& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_status()) { + mutable_status()->::rsctrl::core::Status::MergeFrom(from.status()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ResponseSystemQuit::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ResponseSystemQuit::CopyFrom(const ResponseSystemQuit& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ResponseSystemQuit::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_status()) { + if (!this->status().IsInitialized()) return false; + } + return true; +} + +void ResponseSystemQuit::Swap(ResponseSystemQuit* other) { + if (other != this) { + std::swap(status_, other->status_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ResponseSystemQuit::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ResponseSystemQuit_descriptor_; + metadata.reflection = ResponseSystemQuit_reflection_; + return metadata; +} + + // @@protoc_insertion_point(namespace_scope) } // namespace system diff --git a/retroshare-nogui/src/rpc/proto/gencc/system.pb.h b/retroshare-nogui/src/rpc/proto/gencc/system.pb.h index 8a294713d..92ff1cb6a 100644 --- a/retroshare-nogui/src/rpc/proto/gencc/system.pb.h +++ b/retroshare-nogui/src/rpc/proto/gencc/system.pb.h @@ -36,6 +36,8 @@ void protobuf_ShutdownFile_system_2eproto(); class RequestSystemStatus; class ResponseSystemStatus; +class RequestSystemQuit; +class ResponseSystemQuit; enum ResponseSystemStatus_NetCode { ResponseSystemStatus_NetCode_BAD_UNKNOWN = 0, @@ -63,12 +65,32 @@ inline bool ResponseSystemStatus_NetCode_Parse( return ::google::protobuf::internal::ParseNamedEnum( ResponseSystemStatus_NetCode_descriptor(), name, value); } +enum RequestSystemQuit_QuitCode { + RequestSystemQuit_QuitCode_CLOSE_CHANNEL = 1, + RequestSystemQuit_QuitCode_SHUTDOWN_RS = 2 +}; +bool RequestSystemQuit_QuitCode_IsValid(int value); +const RequestSystemQuit_QuitCode RequestSystemQuit_QuitCode_QuitCode_MIN = RequestSystemQuit_QuitCode_CLOSE_CHANNEL; +const RequestSystemQuit_QuitCode RequestSystemQuit_QuitCode_QuitCode_MAX = RequestSystemQuit_QuitCode_SHUTDOWN_RS; +const int RequestSystemQuit_QuitCode_QuitCode_ARRAYSIZE = RequestSystemQuit_QuitCode_QuitCode_MAX + 1; + +const ::google::protobuf::EnumDescriptor* RequestSystemQuit_QuitCode_descriptor(); +inline const ::std::string& RequestSystemQuit_QuitCode_Name(RequestSystemQuit_QuitCode value) { + return ::google::protobuf::internal::NameOfEnum( + RequestSystemQuit_QuitCode_descriptor(), value); +} +inline bool RequestSystemQuit_QuitCode_Parse( + const ::std::string& name, RequestSystemQuit_QuitCode* value) { + return ::google::protobuf::internal::ParseNamedEnum( + RequestSystemQuit_QuitCode_descriptor(), name, value); +} enum RequestMsgIds { - MsgId_RequestSystemStatus = 1 + MsgId_RequestSystemStatus = 1, + MsgId_RequestSystemQuit = 2 }; bool RequestMsgIds_IsValid(int value); const RequestMsgIds RequestMsgIds_MIN = MsgId_RequestSystemStatus; -const RequestMsgIds RequestMsgIds_MAX = MsgId_RequestSystemStatus; +const RequestMsgIds RequestMsgIds_MAX = MsgId_RequestSystemQuit; const int RequestMsgIds_ARRAYSIZE = RequestMsgIds_MAX + 1; const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor(); @@ -82,11 +104,12 @@ inline bool RequestMsgIds_Parse( RequestMsgIds_descriptor(), name, value); } enum ResponseMsgIds { - MsgId_ResponseSystemStatus = 1 + MsgId_ResponseSystemStatus = 1, + MsgId_ResponseSystemQuit = 2 }; bool ResponseMsgIds_IsValid(int value); const ResponseMsgIds ResponseMsgIds_MIN = MsgId_ResponseSystemStatus; -const ResponseMsgIds ResponseMsgIds_MAX = MsgId_ResponseSystemStatus; +const ResponseMsgIds ResponseMsgIds_MAX = MsgId_ResponseSystemQuit; const int ResponseMsgIds_ARRAYSIZE = ResponseMsgIds_MAX + 1; const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor(); @@ -326,6 +349,195 @@ class ResponseSystemStatus : public ::google::protobuf::Message { void InitAsDefaultInstance(); static ResponseSystemStatus* default_instance_; }; +// ------------------------------------------------------------------- + +class RequestSystemQuit : public ::google::protobuf::Message { + public: + RequestSystemQuit(); + virtual ~RequestSystemQuit(); + + RequestSystemQuit(const RequestSystemQuit& from); + + inline RequestSystemQuit& operator=(const RequestSystemQuit& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const RequestSystemQuit& default_instance(); + + void Swap(RequestSystemQuit* other); + + // implements Message ---------------------------------------------- + + RequestSystemQuit* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const RequestSystemQuit& from); + void MergeFrom(const RequestSystemQuit& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef RequestSystemQuit_QuitCode QuitCode; + static const QuitCode CLOSE_CHANNEL = RequestSystemQuit_QuitCode_CLOSE_CHANNEL; + static const QuitCode SHUTDOWN_RS = RequestSystemQuit_QuitCode_SHUTDOWN_RS; + static inline bool QuitCode_IsValid(int value) { + return RequestSystemQuit_QuitCode_IsValid(value); + } + static const QuitCode QuitCode_MIN = + RequestSystemQuit_QuitCode_QuitCode_MIN; + static const QuitCode QuitCode_MAX = + RequestSystemQuit_QuitCode_QuitCode_MAX; + static const int QuitCode_ARRAYSIZE = + RequestSystemQuit_QuitCode_QuitCode_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + QuitCode_descriptor() { + return RequestSystemQuit_QuitCode_descriptor(); + } + static inline const ::std::string& QuitCode_Name(QuitCode value) { + return RequestSystemQuit_QuitCode_Name(value); + } + static inline bool QuitCode_Parse(const ::std::string& name, + QuitCode* value) { + return RequestSystemQuit_QuitCode_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // required .rsctrl.system.RequestSystemQuit.QuitCode quit_code = 1; + inline bool has_quit_code() const; + inline void clear_quit_code(); + static const int kQuitCodeFieldNumber = 1; + inline ::rsctrl::system::RequestSystemQuit_QuitCode quit_code() const; + inline void set_quit_code(::rsctrl::system::RequestSystemQuit_QuitCode value); + + // @@protoc_insertion_point(class_scope:rsctrl.system.RequestSystemQuit) + private: + inline void set_has_quit_code(); + inline void clear_has_quit_code(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + int quit_code_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_system_2eproto(); + friend void protobuf_AssignDesc_system_2eproto(); + friend void protobuf_ShutdownFile_system_2eproto(); + + void InitAsDefaultInstance(); + static RequestSystemQuit* default_instance_; +}; +// ------------------------------------------------------------------- + +class ResponseSystemQuit : public ::google::protobuf::Message { + public: + ResponseSystemQuit(); + virtual ~ResponseSystemQuit(); + + ResponseSystemQuit(const ResponseSystemQuit& from); + + inline ResponseSystemQuit& operator=(const ResponseSystemQuit& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ResponseSystemQuit& default_instance(); + + void Swap(ResponseSystemQuit* other); + + // implements Message ---------------------------------------------- + + ResponseSystemQuit* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ResponseSystemQuit& from); + void MergeFrom(const ResponseSystemQuit& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required .rsctrl.core.Status status = 1; + inline bool has_status() const; + inline void clear_status(); + static const int kStatusFieldNumber = 1; + inline const ::rsctrl::core::Status& status() const; + inline ::rsctrl::core::Status* mutable_status(); + inline ::rsctrl::core::Status* release_status(); + + // @@protoc_insertion_point(class_scope:rsctrl.system.ResponseSystemQuit) + private: + inline void set_has_status(); + inline void clear_has_status(); + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::rsctrl::core::Status* status_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void protobuf_AddDesc_system_2eproto(); + friend void protobuf_AssignDesc_system_2eproto(); + friend void protobuf_ShutdownFile_system_2eproto(); + + void InitAsDefaultInstance(); + static ResponseSystemQuit* default_instance_; +}; // =================================================================== @@ -462,6 +674,66 @@ inline ::rsctrl::core::Bandwidth* ResponseSystemStatus::release_bw_total() { return temp; } +// ------------------------------------------------------------------- + +// RequestSystemQuit + +// required .rsctrl.system.RequestSystemQuit.QuitCode quit_code = 1; +inline bool RequestSystemQuit::has_quit_code() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void RequestSystemQuit::set_has_quit_code() { + _has_bits_[0] |= 0x00000001u; +} +inline void RequestSystemQuit::clear_has_quit_code() { + _has_bits_[0] &= ~0x00000001u; +} +inline void RequestSystemQuit::clear_quit_code() { + quit_code_ = 1; + clear_has_quit_code(); +} +inline ::rsctrl::system::RequestSystemQuit_QuitCode RequestSystemQuit::quit_code() const { + return static_cast< ::rsctrl::system::RequestSystemQuit_QuitCode >(quit_code_); +} +inline void RequestSystemQuit::set_quit_code(::rsctrl::system::RequestSystemQuit_QuitCode value) { + GOOGLE_DCHECK(::rsctrl::system::RequestSystemQuit_QuitCode_IsValid(value)); + set_has_quit_code(); + quit_code_ = value; +} + +// ------------------------------------------------------------------- + +// ResponseSystemQuit + +// required .rsctrl.core.Status status = 1; +inline bool ResponseSystemQuit::has_status() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ResponseSystemQuit::set_has_status() { + _has_bits_[0] |= 0x00000001u; +} +inline void ResponseSystemQuit::clear_has_status() { + _has_bits_[0] &= ~0x00000001u; +} +inline void ResponseSystemQuit::clear_status() { + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); + clear_has_status(); +} +inline const ::rsctrl::core::Status& ResponseSystemQuit::status() const { + return status_ != NULL ? *status_ : *default_instance_->status_; +} +inline ::rsctrl::core::Status* ResponseSystemQuit::mutable_status() { + set_has_status(); + if (status_ == NULL) status_ = new ::rsctrl::core::Status; + return status_; +} +inline ::rsctrl::core::Status* ResponseSystemQuit::release_status() { + clear_has_status(); + ::rsctrl::core::Status* temp = status_; + status_ = NULL; + return temp; +} + // @@protoc_insertion_point(namespace_scope) @@ -477,6 +749,10 @@ inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::system::ResponseSystem return ::rsctrl::system::ResponseSystemStatus_NetCode_descriptor(); } template <> +inline const EnumDescriptor* GetEnumDescriptor< ::rsctrl::system::RequestSystemQuit_QuitCode>() { + return ::rsctrl::system::RequestSystemQuit_QuitCode_descriptor(); +} +template <> inline const EnumDescriptor* GetEnumDescriptor< rsctrl::system::RequestMsgIds>() { return rsctrl::system::RequestMsgIds_descriptor(); } diff --git a/retroshare-nogui/src/rpc/proto/rpcprotofiles.cc b/retroshare-nogui/src/rpc/proto/rpcprotofiles.cc new file mode 100644 index 000000000..60488fc37 --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/rpcprotofiles.cc @@ -0,0 +1,344 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "rpc/proto/rpcprotofiles.h" +#include "rpc/proto/gencc/files.pb.h" + +#include + +#include "util/rsstring.h" + +#include + +#include +#include + +#include + + +RpcProtoFiles::RpcProtoFiles(uint32_t serviceId) + :RpcQueueService(serviceId) +{ + return; +} + +int RpcProtoFiles::processMsg(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg) +{ + /* check the msgId */ + uint8_t topbyte = getRpcMsgIdExtension(msg_id); + uint16_t service = getRpcMsgIdService(msg_id); + uint8_t submsg = getRpcMsgIdSubMsg(msg_id); + bool isResponse = isRpcMsgIdResponse(msg_id); + + + std::cerr << "RpcProtoFiles::processMsg() topbyte: " << (int32_t) topbyte; + std::cerr << " service: " << (int32_t) service << " submsg: " << (int32_t) submsg; + std::cerr << std::endl; + + if (isResponse) + { + std::cerr << "RpcProtoFiles::processMsg() isResponse() - not processing"; + std::cerr << std::endl; + return 0; + } + + if (topbyte != (uint8_t) rsctrl::core::CORE) + { + std::cerr << "RpcProtoFiles::processMsg() Extension Mismatch - not processing"; + std::cerr << std::endl; + return 0; + } + + if (service != (uint16_t) rsctrl::core::FILES) + { + std::cerr << "RpcProtoFiles::processMsg() Service Mismatch - not processing"; + std::cerr << std::endl; + return 0; + } + + if (!rsctrl::files::RequestMsgIds_IsValid(submsg)) + { + std::cerr << "RpcProtoFiles::processMsg() SubMsg Mismatch - not processing"; + std::cerr << std::endl; + return 0; + } + + switch(submsg) + { + case rsctrl::files::MsgId_RequestTransferList: + processReqTransferList(chan_id, msg_id, req_id, msg); + break; + + case rsctrl::files::MsgId_RequestControlDownload: + processReqControlDownload(chan_id, msg_id, req_id, msg); + break; + + default: + std::cerr << "RpcProtoFiles::processMsg() ERROR should never get here"; + std::cerr << std::endl; + return 0; + } + + /* must have matched id to get here */ + return 1; +} + + + +int RpcProtoFiles::processReqTransferList(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg) +{ + std::cerr << "RpcProtoFiles::processReqTransferList()"; + std::cerr << std::endl; + + // parse msg. + rsctrl::files::RequestTransferList req; + if (!req.ParseFromString(msg)) + { + std::cerr << "RpcProtoFiles::processReqTransferList() ERROR ParseFromString()"; + std::cerr << std::endl; + return 0; + } + + // response. + rsctrl::files::ResponseTransferList resp; + bool success = true; + std::string errorMsg; + + std::list file_list; + int hints = 0; + + /* convert msg parameters into local ones */ + switch(req.direction()) + { + case rsctrl::files::DIRECTION_UPLOAD: + { + rsFiles->FileUploads(file_list); + hints = RS_FILE_HINTS_UPLOAD; + break; + } + case rsctrl::files::DIRECTION_DOWNLOAD: + { + rsFiles->FileDownloads(file_list); + hints = RS_FILE_HINTS_DOWNLOAD; + break; + } + default: + std::cerr << "RpcProtoFiles::processReqTransferList() ERROR Unknown Dir"; + std::cerr << std::endl; + success = false; + errorMsg = "Unknown Direction"; + break; + } + + std::list::iterator lit; + for(lit = file_list.begin(); lit != file_list.end(); lit++) + { + rsctrl::files::FileTransfer *transfer = resp.add_transfers(); + transfer->set_direction(req.direction()); + + FileInfo info; + if (!rsFiles->FileDetails(*lit, hints, info)) + { + /* error */ + continue; + } + + /* copy file details */ + rsctrl::core::File *filedetails = transfer->mutable_file(); + filedetails->set_hash(info.hash); + filedetails->set_size(info.size); + filedetails->set_name(info.fname); + + transfer->set_fraction( (float) info.transfered / info.size ); + transfer->set_rate_kbs( info.tfRate ); + } + + /* DONE - Generate Reply */ + if (success) + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::SUCCESS); + } + else + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::FAILED); + status->set_msg(errorMsg); + } + + std::string outmsg; + if (!resp.SerializeToString(&outmsg)) + { + std::cerr << "RpcProtoFiles::processReqTransferList() ERROR SerialiseToString()"; + std::cerr << std::endl; + return 0; + } + + // Correctly Name Message. + uint32_t out_msg_id = constructMsgId(rsctrl::core::CORE, rsctrl::core::FILES, + rsctrl::files::MsgId_ResponseTransferList, true); + + // queue it. + queueResponse(chan_id, out_msg_id, req_id, outmsg); + + return 1; +} + +int RpcProtoFiles::processReqControlDownload(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg) +{ + std::cerr << "RpcProtoFiles::processReqControlDownload()"; + std::cerr << std::endl; + + // parse msg. + rsctrl::files::RequestControlDownload req; + if (!req.ParseFromString(msg)) + { + std::cerr << "RpcProtoFiles::processReqControlDownload() ERROR ParseFromString()"; + std::cerr << std::endl; + return 0; + } + + // response. + rsctrl::files::ResponseControlDownload resp; + bool success = true; + std::string errorMsg; + + std::string filehash = req.file().hash(); + switch(req.action()) + { + case rsctrl::files::RequestControlDownload::ACTION_START: + { + std::list srcIds; + + std::string filename = req.file().name(); + uint64_t filesize = req.file().size(); + + // We Set NETWORK_WIDE flag here -> as files will be found via search. + // If this changes, we might be adjust flag (or pass it in!) + if (!rsFiles -> FileRequest(filename, filehash, filesize, + "", RS_FILE_HINTS_NETWORK_WIDE, srcIds)) + { + success = false; + errorMsg = "FileRequest ERROR"; + } + break; + } + case rsctrl::files::RequestControlDownload::ACTION_CONTINUE: + { + if (!rsFiles->changeQueuePosition(filehash,QUEUE_TOP)) + { + success = false; + errorMsg = "File QueuePosition(Top) ERROR"; + } + break; + } + case rsctrl::files::RequestControlDownload::ACTION_WAIT: + { + if (!rsFiles->changeQueuePosition(filehash,QUEUE_BOTTOM)) + { + success = false; + errorMsg = "File QueuePosition(Bottom) ERROR"; + + } + break; + } + case rsctrl::files::RequestControlDownload::ACTION_PAUSE: + { + if (!rsFiles->FileControl(filehash,RS_FILE_CTRL_PAUSE)) + { + success = false; + errorMsg = "FileControl(Pause) ERROR"; + + } + break; + } + case rsctrl::files::RequestControlDownload::ACTION_RESTART: + { + if (!rsFiles->FileControl(filehash,RS_FILE_CTRL_START)) + { + success = false; + errorMsg = "FileControl(Start) ERROR"; + + } + break; + } + case rsctrl::files::RequestControlDownload::ACTION_CHECK: + { + if (!rsFiles->FileControl(filehash,RS_FILE_CTRL_FORCE_CHECK)) + { + success = false; + errorMsg = "FileControl(Check) ERROR"; + + } + break; + } + case rsctrl::files::RequestControlDownload::ACTION_CANCEL: + { + if (!rsFiles->FileCancel(filehash)) + { + success = false; + errorMsg = "FileCancel ERROR"; + } + break; + } + default: + success = false; + errorMsg = "Invalid Action"; + break; + } + + + /* DONE - Generate Reply */ + if (success) + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::SUCCESS); + } + else + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::FAILED); + status->set_msg(errorMsg); + } + + std::string outmsg; + if (!resp.SerializeToString(&outmsg)) + { + std::cerr << "RpcProtoFiles::processReqControlDownload() ERROR SerialiseToString()"; + std::cerr << std::endl; + return 0; + } + + // Correctly Name Message. + uint32_t out_msg_id = constructMsgId(rsctrl::core::CORE, rsctrl::core::FILES, + rsctrl::files::MsgId_ResponseControlDownload, true); + + // queue it. + queueResponse(chan_id, out_msg_id, req_id, outmsg); + + return 1; +} + + +/***** HELPER FUNCTIONS *****/ + diff --git a/retroshare-nogui/src/rpc/proto/rpcprotofiles.h b/retroshare-nogui/src/rpc/proto/rpcprotofiles.h new file mode 100644 index 000000000..89f8d17f9 --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/rpcprotofiles.h @@ -0,0 +1,44 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + + +#ifndef RS_RPC_PROTO_FILES_H +#define RS_RPC_PROTO_FILES_H + +#include "rpc/rpcserver.h" + +class RpcProtoFiles: public RpcQueueService +{ +public: + RpcProtoFiles(uint32_t serviceId); + + virtual int processMsg(uint32_t chan_id, uint32_t msgId, uint32_t req_id, const std::string &msg); + +protected: + + int processReqTransferList(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); + int processReqControlDownload(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); + +}; + +#endif /* RS_PROTO_FILES_H */ diff --git a/retroshare-nogui/src/rpc/proto/rpcprotosearch.cc b/retroshare-nogui/src/rpc/proto/rpcprotosearch.cc new file mode 100644 index 000000000..31f97cd72 --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/rpcprotosearch.cc @@ -0,0 +1,593 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "rpc/proto/rpcprotosearch.h" +#include "rpc/proto/gencc/search.pb.h" + +#include "notifytxt.h" + +#include +#include + +#include "util/rsstring.h" + +#include + +#include +#include + +#include + + +RpcProtoSearch::RpcProtoSearch(uint32_t serviceId, NotifyTxt *notify) + :RpcQueueService(serviceId), mNotify(notify), searchMtx("RpcProtoSearch") +{ + return; +} + +void RpcProtoSearch::reset(uint32_t chan_id) +{ + RpcQueueService::reset(chan_id); + + /* must clear all searches */ + clear_searches(chan_id); +} + + +int RpcProtoSearch::processMsg(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg) +{ + /* check the msgId */ + uint8_t topbyte = getRpcMsgIdExtension(msg_id); + uint16_t service = getRpcMsgIdService(msg_id); + uint8_t submsg = getRpcMsgIdSubMsg(msg_id); + bool isResponse = isRpcMsgIdResponse(msg_id); + + + std::cerr << "RpcProtoSearch::processMsg() topbyte: " << (int32_t) topbyte; + std::cerr << " service: " << (int32_t) service << " submsg: " << (int32_t) submsg; + std::cerr << std::endl; + + if (isResponse) + { + std::cerr << "RpcProtoSearch::processMsg() isResponse() - not processing"; + std::cerr << std::endl; + return 0; + } + + if (topbyte != (uint8_t) rsctrl::core::CORE) + { + std::cerr << "RpcProtoSearch::processMsg() Extension Mismatch - not processing"; + std::cerr << std::endl; + return 0; + } + + if (service != (uint16_t) rsctrl::core::SEARCH) + { + std::cerr << "RpcProtoSearch::processMsg() Service Mismatch - not processing"; + std::cerr << std::endl; + return 0; + } + + if (!rsctrl::search::RequestMsgIds_IsValid(submsg)) + { + std::cerr << "RpcProtoSearch::processMsg() SubMsg Mismatch - not processing"; + std::cerr << std::endl; + return 0; + } + + switch(submsg) + { + case rsctrl::search::MsgId_RequestBasicSearch: + processReqBasicSearch(chan_id, msg_id, req_id, msg); + break; + + case rsctrl::search::MsgId_RequestCloseSearch: + processReqCloseSearch(chan_id, msg_id, req_id, msg); + break; + + case rsctrl::search::MsgId_RequestListSearches: + processReqListSearches(chan_id, msg_id, req_id, msg); + break; + + case rsctrl::search::MsgId_RequestSearchResults: + processReqSearchResults(chan_id, msg_id, req_id, msg); + break; + + default: + std::cerr << "RpcProtoSearch::processMsg() ERROR should never get here"; + std::cerr << std::endl; + return 0; + } + + /* must have matched id to get here */ + return 1; +} + + + +int RpcProtoSearch::processReqBasicSearch(uint32_t chan_id, uint32_t /* msg_id */, uint32_t req_id, const std::string &msg) +{ + std::cerr << "RpcProtoSearch::processReqBasicSearch()"; + std::cerr << std::endl; + + // parse msg. + rsctrl::search::RequestBasicSearch req; + if (!req.ParseFromString(msg)) + { + std::cerr << "RpcProtoSearch::processReqBasicSearch() ERROR ParseFromString()"; + std::cerr << std::endl; + return 0; + } + + // response. + rsctrl::search::ResponseSearchIds resp; + bool success = true; + std::string errorMsg; + + /* convert msg parameters into local ones */ + std::list terms; + + int no_terms = req.terms_size(); + for(int i = 0; i < no_terms; i++) + { + std::string term = req.terms(i); + /* check for valid term? */ + if (term.size() > 0) + { + terms.push_back(term); + } + } + + NameExpression nameexp(ContainsAllStrings, terms, true); + LinearizedExpression lexpr; + nameexp.linearize(lexpr); + + uint32_t searchId = (uint32_t) rsTurtle->turtleSearch(lexpr); + mNotify->collectSearchResults(searchId); + + /* add into search array */ + add_search(chan_id, searchId); + + /* add to answer */ + resp.add_search_id(searchId); + + /* DONE - Generate Reply */ + if (success) + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::SUCCESS); + } + else + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::FAILED); + status->set_msg(errorMsg); + } + + std::string outmsg; + if (!resp.SerializeToString(&outmsg)) + { + std::cerr << "RpcProtoSearch::processReqBasicSearch() ERROR SerialiseToString()"; + std::cerr << std::endl; + return 0; + } + + // Correctly Name Message. + uint32_t out_msg_id = constructMsgId(rsctrl::core::CORE, rsctrl::core::SEARCH, + rsctrl::search::MsgId_ResponseSearchIds, true); + + // queue it. + queueResponse(chan_id, out_msg_id, req_id, outmsg); + + return 1; +} + + +int RpcProtoSearch::processReqCloseSearch(uint32_t chan_id, uint32_t /* msg_id */, uint32_t req_id, const std::string &msg) +{ + std::cerr << "RpcProtoSearch::processReqCloseSearch()"; + std::cerr << std::endl; + + // parse msg. + rsctrl::search::RequestCloseSearch req; + if (!req.ParseFromString(msg)) + { + std::cerr << "RpcProtoSearch::processReqCloseSearch() ERROR ParseFromString()"; + std::cerr << std::endl; + return 0; + } + + // response. + rsctrl::search::ResponseSearchIds resp; + bool success = true; + std::string errorMsg; + + /* convert msg parameters into local ones */ + uint32_t searchId = req.search_id(); + + + /* remove into search array */ + if (!remove_search(chan_id, searchId)) + { + success = false; + errorMsg = "Unknown SearchId in List"; + } + + /* clear search results + * we cannot cancel a turtle search + * so we tell notify to ignore further results + */ + + if (success) + { + if (!mNotify->clearSearchId(searchId)) + { + success = false; + errorMsg = "Unknown SearchId in Notify"; + } + } + + /* add to answer */ + if (success) + { + resp.add_search_id(searchId); + } + + /* DONE - Generate Reply */ + if (success) + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::SUCCESS); + } + else + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::FAILED); + status->set_msg(errorMsg); + } + + std::string outmsg; + if (!resp.SerializeToString(&outmsg)) + { + std::cerr << "RpcProtoSearch::processReqCloseSearch() ERROR SerialiseToString()"; + std::cerr << std::endl; + return 0; + } + + // Correctly Name Message. + uint32_t out_msg_id = constructMsgId(rsctrl::core::CORE, rsctrl::core::SEARCH, + rsctrl::search::MsgId_ResponseSearchIds, true); + + // queue it. + queueResponse(chan_id, out_msg_id, req_id, outmsg); + + return 1; +} + + +int RpcProtoSearch::processReqListSearches(uint32_t chan_id, uint32_t /* msg_id */, uint32_t req_id, const std::string &msg) +{ + std::cerr << "RpcProtoSearch::processReqListSearches()"; + std::cerr << std::endl; + + // parse msg. + rsctrl::search::RequestListSearches req; + if (!req.ParseFromString(msg)) + { + std::cerr << "RpcProtoSearch::processReqListSearches() ERROR ParseFromString()"; + std::cerr << std::endl; + return 0; + } + + // response. + rsctrl::search::ResponseSearchIds resp; + bool success = true; + std::string errorMsg; + + /* convert msg parameters into local ones */ + // Nothing to do. + + std::list reg_search_ids; + std::list::iterator it; + if (!get_search_list(chan_id, reg_search_ids)) + { + /* warning */ + success = false; + errorMsg = "No Searches Active"; + } + + /* iterate through search array */ + for(it = reg_search_ids.begin(); it != reg_search_ids.end(); it++) + { + /* add to answer */ + resp.add_search_id(*it); + } + + /* DONE - Generate Reply */ + if (success) + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::SUCCESS); + } + else + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::FAILED); + status->set_msg(errorMsg); + } + + std::string outmsg; + if (!resp.SerializeToString(&outmsg)) + { + std::cerr << "RpcProtoSearch::processReqListSearches() ERROR SerialiseToString()"; + std::cerr << std::endl; + return 0; + } + + // Correctly Name Message. + uint32_t out_msg_id = constructMsgId(rsctrl::core::CORE, rsctrl::core::SEARCH, + rsctrl::search::MsgId_ResponseSearchIds, true); + + // queue it. + queueResponse(chan_id, out_msg_id, req_id, outmsg); + + return 1; +} + + +int RpcProtoSearch::processReqSearchResults(uint32_t chan_id, uint32_t /* msg_id */, uint32_t req_id, const std::string &msg) +{ + std::cerr << "RpcProtoSearch::processReqSearchResults()"; + std::cerr << std::endl; + + // parse msg. + rsctrl::search::RequestSearchResults req; + if (!req.ParseFromString(msg)) + { + std::cerr << "RpcProtoSearch::processReqSearchResults() ERROR ParseFromString()"; + std::cerr << std::endl; + return 0; + } + + // response. + rsctrl::search::ResponseSearchResults resp; + bool success = true; + std::string errorMsg; + + /* convert msg parameters into local ones */ + std::list reg_search_ids; + std::list requested_search_ids; + if (!get_search_list(chan_id, reg_search_ids)) + { + /* warning */ + } + + int no_searches = req.search_ids_size(); + if (no_searches) + { + /* painful check that they are our searches */ + for(int i = 0; i < no_searches; i++) + { + uint32_t search_id = req.search_ids(i); + + /* check that its in reg_search_ids */ + if (reg_search_ids.end() != std::find(reg_search_ids.begin(), reg_search_ids.end(), search_id)) + { + /* error */ + continue; + } + requested_search_ids.push_back(search_id); + } + } + else + { + /* all current searches */ + requested_search_ids = reg_search_ids; + } + + + std::list::iterator rit; + for(rit = requested_search_ids.begin(); + rit != requested_search_ids.end(); rit++) + { + rsctrl::search::SearchSet *set = resp.add_searches(); + /* add to answer */ + set->set_search_id(*rit); + /* no search details at the moment */ + + /* add into search array */ + std::list::iterator it; + std::list searchResults; + mNotify->getSearchResults(*rit, searchResults); + + /* convert into useful list */ + for(it = searchResults.begin(); it != searchResults.end(); it++) + { + /* add to answer */ + rsctrl::search::SearchHit *hit = set->add_hits(); + rsctrl::core::File *file = hit->mutable_file(); + + file->set_hash(it->hash); + file->set_name(it->name); + file->set_size(it->size); + + // Uhm not provided for now. default to NETWORK + hit->set_loc(rsctrl::search::SearchHit::NETWORK); + hit->set_no_hits(1); // No aggregation yet. + } + } + + /* DONE - Generate Reply */ + /* different to others - partial success possible */ + if (success) + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::SUCCESS); + } + else + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::FAILED); + status->set_msg(errorMsg); + } + + std::string outmsg; + if (!resp.SerializeToString(&outmsg)) + { + std::cerr << "RpcProtoSearch::processReqSearchResults() ERROR SerialiseToString()"; + std::cerr << std::endl; + return 0; + } + + // Correctly Name Message. + uint32_t out_msg_id = constructMsgId(rsctrl::core::CORE, rsctrl::core::SEARCH, + rsctrl::search::MsgId_ResponseSearchResults, true); + + // queue it. + queueResponse(chan_id, out_msg_id, req_id, outmsg); + + return 1; +} + + + +/***** HELPER FUNCTIONS *****/ + + // These private functions use Mutex below and manipulate mActiveSearches. +int RpcProtoSearch::get_search_list(uint32_t chan_id, std::list &search_ids) +{ + std::cerr << "RpcProtoSearch::get_search_list(" << chan_id << ")"; + std::cerr << std::endl; + + RsStackMutex stack(searchMtx); /******* LOCKED *********/ + + std::map >::iterator mit; + + mit = mActiveSearches.find(chan_id); + if (mit == mActiveSearches.end()) + { + return 0; + } + + search_ids = mit->second; + + return 1; +} + +int RpcProtoSearch::add_search(uint32_t chan_id, uint32_t search_id) +{ + std::cerr << "RpcProtoSearch::add_search(" << chan_id << ", " << search_id << ")"; + std::cerr << std::endl; + + RsStackMutex stack(searchMtx); /******* LOCKED *********/ + + std::map >::iterator mit; + + mit = mActiveSearches.find(chan_id); + if (mit == mActiveSearches.end()) + { + std::list emptyList; + mActiveSearches[chan_id] = emptyList; + + mit = mActiveSearches.find(chan_id); + } + + /* sanity check */ + if (mit->second.end() != std::find(mit->second.begin(), mit->second.end(), search_id)) + { + std::cerr << "RpcProtoSearch::add_search() ERROR search_id already exists"; + std::cerr << std::endl; + return 0; + } + + mit->second.push_back(search_id); + return 1; +} + +int RpcProtoSearch::remove_search(uint32_t chan_id, uint32_t search_id) +{ + std::cerr << "RpcProtoSearch::remove_search(" << chan_id << ", " << search_id << ")"; + std::cerr << std::endl; + + RsStackMutex stack(searchMtx); /******* LOCKED *********/ + + std::map >::iterator mit; + + mit = mActiveSearches.find(chan_id); + if (mit == mActiveSearches.end()) + { + std::cerr << "RpcProtoSearch::remove_search() ERROR search set doesn't exist"; + std::cerr << std::endl; + return 0; + } + + bool removed = false; + std::list::iterator lit; + for(lit = mit->second.begin(); lit != mit->second.end();) + { + if (*lit == search_id) + { + lit = mit->second.erase(lit); + if (removed) + { + std::cerr << "RpcProtoSearch::remove_search() ERROR removed multiple"; + std::cerr << std::endl; + } + removed = true; + } + else + { + lit++; + } + } + + if (removed) + return 1; + + std::cerr << "RpcProtoSearch::remove_search() ERROR search_id not found"; + std::cerr << std::endl; + + return 0; +} + +int RpcProtoSearch::clear_searches(uint32_t chan_id) +{ + std::cerr << "RpcProtoSearch::clear_searches(" << chan_id << ")"; + std::cerr << std::endl; + + RsStackMutex stack(searchMtx); /******* LOCKED *********/ + + std::map >::iterator mit; + + mit = mActiveSearches.find(chan_id); + if (mit == mActiveSearches.end()) + { + std::cerr << "RpcProtoSearch::clear_searches() WARNING search set not found"; + std::cerr << std::endl; + return 0; + } + + mActiveSearches.erase(mit); + return 1; +} + diff --git a/retroshare-nogui/src/rpc/proto/rpcprotosearch.h b/retroshare-nogui/src/rpc/proto/rpcprotosearch.h new file mode 100644 index 000000000..3ad77ce75 --- /dev/null +++ b/retroshare-nogui/src/rpc/proto/rpcprotosearch.h @@ -0,0 +1,64 @@ +/* + * RetroShare External Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + + +#ifndef RS_RPC_PROTO_SEARCH_H +#define RS_RPC_PROTO_SEARCH_H + +#include "rpc/rpcserver.h" + +class NotifyTxt; + +class RpcProtoSearch: public RpcQueueService +{ +public: + RpcProtoSearch(uint32_t serviceId, NotifyTxt *notify); + virtual void reset(uint32_t chan_id); + + virtual int processMsg(uint32_t chan_id, uint32_t msgId, uint32_t req_id, const std::string &msg); + +protected: + + int processReqBasicSearch(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); + int processReqCloseSearch(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); + int processReqListSearches(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); + int processReqSearchResults(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); + + +private: + // These private functions use Mutex below and manipulate mActiveSearches. + int get_search_list(uint32_t chan_id, std::list &search_ids); + int add_search(uint32_t chan_id, uint32_t search_id); + int remove_search(uint32_t chan_id, uint32_t search_id); + int clear_searches(uint32_t chan_id); + + NotifyTxt *mNotify; + + RsMutex searchMtx; + + /* must store list of active searches per channel */ + std::map > mActiveSearches; + +}; + +#endif /* RS_PROTO_SEARCH_H */ diff --git a/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc b/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc index 29c7c5cbc..66339d30c 100644 --- a/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc +++ b/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc @@ -86,6 +86,9 @@ int RpcProtoSystem::processMsg(uint32_t chan_id, uint32_t msg_id, uint32_t req_i case rsctrl::system::MsgId_RequestSystemStatus: processSystemStatus(chan_id, msg_id, req_id, msg); break; + case rsctrl::system::MsgId_RequestSystemQuit: + processSystemQuit(chan_id, msg_id, req_id, msg); + break; default: std::cerr << "RpcProtoSystem::processMsg() ERROR should never get here"; std::cerr << std::endl; @@ -211,3 +214,71 @@ int RpcProtoSystem::processSystemStatus(uint32_t chan_id, uint32_t msg_id, uint3 } + +int RpcProtoSystem::processSystemQuit(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg) +{ + std::cerr << "RpcProtoSystem::processSystemQuit()"; + std::cerr << std::endl; + + // parse msg. + rsctrl::system::RequestSystemQuit req; + if (!req.ParseFromString(msg)) + { + std::cerr << "RpcProtoSystem::processSystemQuit() ERROR ParseFromString()"; + std::cerr << std::endl; + return 0; + } + + // NO Options... so go straight to answer. + // response. + rsctrl::system::ResponseSystemQuit resp; + bool success = true; + + switch(req.quit_code()) + { + default: + case rsctrl::system::RequestSystemQuit::CLOSE_CHANNEL: + { + RpcServer *server = getRpcServer(); + server->error(chan_id, "CLOSE_CHANNEL"); + + break; + } + case rsctrl::system::RequestSystemQuit::SHUTDOWN_RS: + { + rsicontrol->rsGlobalShutDown(); + break; + } + } + + if (success) + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::SUCCESS); + } + else + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::FAILED); + status->set_msg("Unknown ERROR"); + } + + std::string outmsg; + if (!resp.SerializeToString(&outmsg)) + { + std::cerr << "RpcProtoSystem::processSystemQuit() ERROR SerialiseToString()"; + std::cerr << std::endl; + return 0; + } + + // Correctly Name Message. + uint32_t out_msg_id = constructMsgId(rsctrl::core::CORE, rsctrl::core::SYSTEM, + rsctrl::system::MsgId_ResponseSystemQuit, true); + + // queue it. + queueResponse(chan_id, out_msg_id, req_id, outmsg); + + return 1; +} + + diff --git a/retroshare-nogui/src/rpc/proto/rpcprotosystem.h b/retroshare-nogui/src/rpc/proto/rpcprotosystem.h index db29cf207..f1490fed5 100644 --- a/retroshare-nogui/src/rpc/proto/rpcprotosystem.h +++ b/retroshare-nogui/src/rpc/proto/rpcprotosystem.h @@ -35,6 +35,7 @@ public: virtual int processMsg(uint32_t chan_id, uint32_t msgId, uint32_t req_id, const std::string &msg); virtual int processSystemStatus(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); + virtual int processSystemQuit(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); }; diff --git a/retroshare-nogui/src/rpc/rpc.cc b/retroshare-nogui/src/rpc/rpc.cc index 6fd5a0b74..a1aa1683b 100644 --- a/retroshare-nogui/src/rpc/rpc.cc +++ b/retroshare-nogui/src/rpc/rpc.cc @@ -43,6 +43,11 @@ void RpcMediator::reset(uint32_t chan_id) mServer->reset(chan_id); } +int RpcMediator::error(uint32_t chan_id, std::string msg) +{ + return mComms->error(chan_id, msg); +} + int RpcMediator::tick() { diff --git a/retroshare-nogui/src/rpc/rpc.h b/retroshare-nogui/src/rpc/rpc.h index 33e9dec9e..bdc2e8a18 100644 --- a/retroshare-nogui/src/rpc/rpc.h +++ b/retroshare-nogui/src/rpc/rpc.h @@ -50,6 +50,7 @@ virtual int tick(); int recv_msg(uint32_t chan_id); int send(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg); + int error(uint32_t chan_id, std::string msg); // pass an error up to comms level. private: RpcComms *mComms; RpcServer *mServer; diff --git a/retroshare-nogui/src/rpc/rpcserver.cc b/retroshare-nogui/src/rpc/rpcserver.cc index 484a7576e..a879e08df 100644 --- a/retroshare-nogui/src/rpc/rpcserver.cc +++ b/retroshare-nogui/src/rpc/rpcserver.cc @@ -63,11 +63,16 @@ void RpcServer::reset(uint32_t chan_id) return; } +int RpcServer::error(uint32_t chan_id, std::string msg) +{ + return mMediator->error(chan_id, msg); +} int RpcServer::addService(RpcService *service) { RsStackMutex stack(mRpcMtx); /********** LOCKED MUTEX ***************/ + service->setRpcServer(this); mAllServices.push_back(service); return 1; diff --git a/retroshare-nogui/src/rpc/rpcserver.h b/retroshare-nogui/src/rpc/rpcserver.h index 47c90ca29..341086234 100644 --- a/retroshare-nogui/src/rpc/rpcserver.h +++ b/retroshare-nogui/src/rpc/rpcserver.h @@ -67,17 +67,23 @@ public: std::string mMsg; }; +class RpcServer; class RpcService { public: - RpcService(uint32_t /* serviceId */ ) { return; } + RpcService(uint32_t /* serviceId */ ):mRpcServer(NULL) { return; } virtual void reset(uint32_t /* chan_id */) { return; } virtual int msgsAccepted(std::list & /* msgIds */) { return 0; } /* not used at the moment */ virtual int processMsg(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg) = 0; /* returns 0 - not handled, > 0, accepted */ virtual int getResponse(uint32_t &chan_id, uint32_t &msgId, uint32_t &req_id, std::string &msg) = 0; /* 0 - not ready, > 0 heres the response */ virtual int getEvents(std::list & /* events */) { return 0; } /* 0 = none, optional feature */ + + void setRpcServer(RpcServer *server) {mRpcServer = server; } + RpcServer *getRpcServer() { return mRpcServer; } +private: + RpcServer *mRpcServer; }; @@ -140,6 +146,7 @@ public: bool checkEvents(); void reset(uint32_t chan_id); + int error(uint32_t chan_id, std::string msg); // pass an error to mediator. private: bool sendQueuedMsgs(std::list &msgs); diff --git a/retroshare-nogui/src/rpc/rpcsetup.cc b/retroshare-nogui/src/rpc/rpcsetup.cc index 528f5b425..015d72142 100644 --- a/retroshare-nogui/src/rpc/rpcsetup.cc +++ b/retroshare-nogui/src/rpc/rpcsetup.cc @@ -27,10 +27,12 @@ #include "rpc/proto/rpcprotopeers.h" #include "rpc/proto/rpcprotosystem.h" #include "rpc/proto/rpcprotochat.h" +#include "rpc/proto/rpcprotosearch.h" +#include "rpc/proto/rpcprotofiles.h" #include "rpc/rpcecho.h" -RpcMediator *CreateRpcSystem(RpcComms *comms) +RpcMediator *CreateRpcSystem(RpcComms *comms, NotifyTxt *notify) { RpcMediator *med = new RpcMediator(comms); RpcServer *server = new RpcServer(med); @@ -45,6 +47,12 @@ RpcMediator *CreateRpcSystem(RpcComms *comms) RpcProtoChat *chat = new RpcProtoChat(1); server->addService(chat); + RpcProtoSearch *search = new RpcProtoSearch(1, notify); + server->addService(search); + + RpcProtoFiles *files = new RpcProtoFiles(1); + server->addService(files); + /* Finally an Echo Service - which will echo back any unprocesses commands. */ RpcEcho *echo = new RpcEcho(1); server->addService(echo); diff --git a/retroshare-nogui/src/rpc/rpcsetup.h b/retroshare-nogui/src/rpc/rpcsetup.h index 4d847f089..b95193f87 100644 --- a/retroshare-nogui/src/rpc/rpcsetup.h +++ b/retroshare-nogui/src/rpc/rpcsetup.h @@ -28,7 +28,9 @@ #include "rpc/rpc.h" -RpcMediator *CreateRpcSystem(RpcComms *comms); +class NotifyTxt; + +RpcMediator *CreateRpcSystem(RpcComms *comms, NotifyTxt *notify); #endif From 7a55bbc02953ff490e66505364be50b1ad08fb0b Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 9 Sep 2012 14:40:21 +0000 Subject: [PATCH 057/222] removed annoying tick() printouts. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5530 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/services/p3forumsv2.cc | 4 +- libretroshare/src/services/p3idservice.cc | 4 +- libretroshare/src/services/p3posted.cc | 4 +- libretroshare/src/services/p3wikiservice.cc | 4 +- libretroshare/src/services/p3wire.cc | 345 +++++++++++++++++++- 5 files changed, 351 insertions(+), 10 deletions(-) diff --git a/libretroshare/src/services/p3forumsv2.cc b/libretroshare/src/services/p3forumsv2.cc index 837e21709..8f87c53e7 100644 --- a/libretroshare/src/services/p3forumsv2.cc +++ b/libretroshare/src/services/p3forumsv2.cc @@ -57,8 +57,8 @@ p3ForumsV2::p3ForumsV2(uint16_t type) int p3ForumsV2::tick() { - std::cerr << "p3ForumsV2::tick()"; - std::cerr << std::endl; + //std::cerr << "p3ForumsV2::tick()"; + //std::cerr << std::endl; fakeprocessrequests(); diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 1dc8bc3c0..7981eb70b 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -58,8 +58,8 @@ p3IdService::p3IdService(uint16_t type) int p3IdService::tick() { - std::cerr << "p3IdService::tick()"; - std::cerr << std::endl; + //std::cerr << "p3IdService::tick()"; + //std::cerr << std::endl; fakeprocessrequests(); // Disable for now. diff --git a/libretroshare/src/services/p3posted.cc b/libretroshare/src/services/p3posted.cc index 02458126f..0685205e7 100644 --- a/libretroshare/src/services/p3posted.cc +++ b/libretroshare/src/services/p3posted.cc @@ -73,8 +73,8 @@ p3PostedService::p3PostedService(uint16_t type) int p3PostedService::tick() { - std::cerr << "p3PostedService::tick()"; - std::cerr << std::endl; + //std::cerr << "p3PostedService::tick()"; + //std::cerr << std::endl; fakeprocessrequests(); diff --git a/libretroshare/src/services/p3wikiservice.cc b/libretroshare/src/services/p3wikiservice.cc index 94c45376f..e2469cdac 100644 --- a/libretroshare/src/services/p3wikiservice.cc +++ b/libretroshare/src/services/p3wikiservice.cc @@ -50,8 +50,8 @@ p3WikiService::p3WikiService(uint16_t type) int p3WikiService::tick() { - std::cerr << "p3WikiService::tick()"; - std::cerr << std::endl; + //std::cerr << "p3WikiService::tick()"; + //std::cerr << std::endl; fakeprocessrequests(); diff --git a/libretroshare/src/services/p3wire.cc b/libretroshare/src/services/p3wire.cc index c06c9e58b..c7953825d 100644 --- a/libretroshare/src/services/p3wire.cc +++ b/libretroshare/src/services/p3wire.cc @@ -50,8 +50,8 @@ p3Wire::p3Wire(uint16_t type) int p3Wire::tick() { - std::cerr << "p3Wire::tick()"; - std::cerr << std::endl; + //std::cerr << "p3Wire::tick()"; + //std::cerr << std::endl; fakeprocessrequests(); @@ -596,3 +596,344 @@ bool WireDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta) return true; } + + + +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ + + +#if 0 + +bool p3Wire::generateDummyData() +{ +#define MAX_GROUPS 100 +#define MAX_POSTS 1000 + +#define MAX_BASE_COMMENTS 1000 //10000 +#define MAX_COMMENTS 4000 //10000 + +#define MAX_VOTES 10000 //10000 + + std::list mGroups; + std::list::iterator git; + + std::list mPosts; + std::list::iterator pit; + + std::list mVotes; + std::list::iterator vit; + + std::list mComments; + std::list::iterator cit; + +#define DUMMY_NAME_MAX_LEN 10000 + char name[DUMMY_NAME_MAX_LEN]; + int i, j; + time_t now = time(NULL); + + for(i = 0; i < MAX_GROUPS; i++) + { + /* generate a new forum */ + RsPostedGroup group; + + snprintf(name, DUMMY_NAME_MAX_LEN, "TestTopic_%d", i+1); + + group.mMeta.mGroupId = genRandomId(); + group.mMeta.mGroupName = name; + + group.mMeta.mPublishTs = now - (RSRandom::random_f32() * 100000); + /* key fields to fill in: + * GroupId. + * Name. + * Flags. + * Pop. + */ + + + + /* use probability to decide which are subscribed / own / popularity. + */ + + float rnd = RSRandom::random_f32(); + if (rnd < 0.1) + { + group.mMeta.mSubscribeFlags = RSGXS_GROUP_SUBSCRIBE_ADMIN | RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED; + + } + else if (rnd < 0.3) + { + group.mMeta.mSubscribeFlags = RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED; + } + else + { + group.mMeta.mSubscribeFlags = 0; + } + + group.mMeta.mPop = (int) (RSRandom::random_f32() * 10.0); + mGroups.push_back(group); + + } + + for(i = 0; i < MAX_POSTS; i++) + { + /* generate a base thread */ + + /* rotate the Forum Groups Around, then pick one. + */ + + int rnd = (int) (RSRandom::random_f32() * 10.0); + + for(j = 0; j < rnd; j++) + { + RsPostedGroup head = mGroups.front(); + mGroups.pop_front(); + mGroups.push_back(head); + } + + RsPostedGroup group = mGroups.front(); + + /* now create a new thread */ + + RsPostedPost post; + + snprintf(name, DUMMY_NAME_MAX_LEN, "%s => Post_%d", group.mMeta.mGroupName.c_str(), i+1); + post.mMeta.mMsgName = name; + + post.mMeta.mGroupId = group.mMeta.mGroupId; + post.mMeta.mMsgId = genRandomId(); + post.mMeta.mOrigMsgId = post.mMeta.mMsgId; + post.mMeta.mThreadId = post.mMeta.mMsgId; + post.mMeta.mParentId = ""; + + post.mMeta.mPublishTs = group.mMeta.mPublishTs + (RSRandom::random_f32() * 10000); + if (post.mMeta.mPublishTs > now) + post.mMeta.mPublishTs = now - 1; + + mPosts.push_back(post); + + } + + for(i = 0; i < MAX_BASE_COMMENTS; i++) + { + /* generate a base thread */ + + /* rotate the Forum Groups Around, then pick one. + */ + + int rnd = (int) (RSRandom::random_f32() * 10.0); + + for(j = 0; j < rnd; j++) + { + RsPostedPost head = mPosts.front(); + mPosts.pop_front(); + mPosts.push_back(head); + } + + RsPostedPost parent = mPosts.front(); + + /* now create a new child msg */ + + RsPostedComment comment; + + /* fill in key data + * GroupId + * MsgId + * OrigMsgId + * ThreadId + * ParentId + * PublishTS (take Forum TS + a bit ). + * + * ChildTS ???? + */ + snprintf(name, DUMMY_NAME_MAX_LEN, "%s => Comment_%d", parent.mMeta.mMsgName.c_str(), i+1); + comment.mMeta.mMsgName = name; + //comment.mMsg = name; + + comment.mMeta.mGroupId = parent.mMeta.mGroupId; + comment.mMeta.mMsgId = genRandomId(); + comment.mMeta.mOrigMsgId = comment.mMeta.mMsgId; + comment.mMeta.mThreadId = parent.mMeta.mThreadId; + comment.mMeta.mParentId = parent.mMeta.mOrigMsgId; + + comment.mMeta.mPublishTs = parent.mMeta.mPublishTs + (RSRandom::random_f32() * 10000); + if (comment.mMeta.mPublishTs > now) + comment.mMeta.mPublishTs = now - 1; + + mComments.push_back(comment); + } + + + for(i = 0; i < MAX_COMMENTS; i++) + { + /* generate a base thread */ + + /* rotate the Forum Groups Around, then pick one. + */ + + int rnd = (int) (RSRandom::random_f32() * 10.0); + + for(j = 0; j < rnd; j++) + { + RsPostedComment head = mComments.front(); + mComments.pop_front(); + mComments.push_back(head); + } + + RsPostedComment parent = mComments.front(); + + /* now create a new child msg */ + + RsPostedComment comment; + + /* fill in key data + * GroupId + * MsgId + * OrigMsgId + * ThreadId + * ParentId + * PublishTS (take Forum TS + a bit ). + * + * ChildTS ???? + */ + snprintf(name, DUMMY_NAME_MAX_LEN, "%s => Comment_%d", parent.mMeta.mMsgName.c_str(), i+1); + comment.mMeta.mMsgName = name; + //comment.mMsg = name; + + comment.mMeta.mGroupId = parent.mMeta.mGroupId; + comment.mMeta.mMsgId = genRandomId(); + comment.mMeta.mOrigMsgId = comment.mMeta.mMsgId; + comment.mMeta.mThreadId = parent.mMeta.mThreadId; + comment.mMeta.mParentId = parent.mMeta.mOrigMsgId; + + comment.mMeta.mPublishTs = parent.mMeta.mPublishTs + (RSRandom::random_f32() * 10000); + if (comment.mMeta.mPublishTs > now) + comment.mMeta.mPublishTs = now - 1; + + mComments.push_back(comment); + } + + + for(i = 0; i < MAX_VOTES; i++) + { + /* generate a base thread */ + + /* rotate the Forum Groups Around, then pick one. + */ + + int rnd = (int) (RSRandom::random_f32() * 10.0); + + for(j = 0; j < rnd; j++) + { + RsPostedPost head = mPosts.front(); + mPosts.pop_front(); + mPosts.push_back(head); + } + + RsPostedPost parent = mPosts.front(); + + /* now create a new child msg */ + + RsPostedVote vote; + + snprintf(name, DUMMY_NAME_MAX_LEN, "%s => Vote_%d", parent.mMeta.mMsgName.c_str(), i+1); + vote.mMeta.mMsgName = name; + //vote.mMsg = name; + + vote.mMeta.mGroupId = parent.mMeta.mGroupId; + vote.mMeta.mMsgId = genRandomId(); + vote.mMeta.mOrigMsgId = vote.mMeta.mMsgId; + vote.mMeta.mThreadId = parent.mMeta.mThreadId; + vote.mMeta.mParentId = parent.mMeta.mOrigMsgId; + + vote.mMeta.mPublishTs = parent.mMeta.mPublishTs + (RSRandom::random_f32() * 10000); + if (vote.mMeta.mPublishTs > now) + vote.mMeta.mPublishTs = now - 1; + + mVotes.push_back(vote); + } + + + mUpdated = true; + + /* Then - at the end, we push them all into the Proxy */ + for(git = mGroups.begin(); git != mGroups.end(); git++) + { + /* pushback */ + mPostedProxy->addGroup(*git); + + } + + for(pit = mPosts.begin(); pit != mPosts.end(); pit++) + { + /* pushback */ + mPostedProxy->addPost(*pit); + } + + for(cit = mComments.begin(); cit != mComments.end(); cit++) + { + /* pushback */ +#define COMMENT_FRAC_FOR_LATER (0.70) + if (RSRandom::random_f32() > COMMENT_FRAC_FOR_LATER) + { + mPostedProxy->addComment(*cit); + } + else + { + mDummyLaterComments.push_back(*cit); + } + } + + + for(vit = mVotes.begin(); vit != mVotes.end(); vit++) + { + /* pushback */ + +#define VOTE_FRAC_FOR_LATER (0.70) + if (RSRandom::random_f32() > VOTE_FRAC_FOR_LATER) + { + mPostedProxy->addVote(*vit); + } + else + { + mDummyLaterVotes.push_back(*vit); + } + } + + return true; +} + +#define EXTRA_COMMENT_ADD (20) +#define EXTRA_VOTE_ADD (50) + +bool p3PostedService::addExtraDummyData() +{ + std::cerr << "p3PostedService::addExtraDummyData()"; + std::cerr << std::endl; + + int i = 0; + + std::list::iterator vit; + std::list::iterator cit; + + for(cit = mDummyLaterComments.begin(); (cit != mDummyLaterComments.end()) && (i < EXTRA_COMMENT_ADD); i++) + { + mPostedProxy->addComment(*cit); + cit = mDummyLaterComments.erase(cit); + } + + i = 0; + for(vit = mDummyLaterVotes.begin(); (vit != mDummyLaterVotes.end()) && (i < EXTRA_VOTE_ADD); i++) + { + mPostedProxy->addVote(*vit); + vit = mDummyLaterVotes.erase(vit); + } + + return true; +} + +#endif + + From b52f8dd2b11c87a230528463396f87983be01e05 Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 9 Sep 2012 16:10:33 +0000 Subject: [PATCH 058/222] disabled Quit / Exit RPC command - it is not functioning correctly. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5531 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/rpc/proto/rpcprotosystem.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc b/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc index 66339d30c..7a0e1e52a 100644 --- a/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc +++ b/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc @@ -86,9 +86,11 @@ int RpcProtoSystem::processMsg(uint32_t chan_id, uint32_t msg_id, uint32_t req_i case rsctrl::system::MsgId_RequestSystemStatus: processSystemStatus(chan_id, msg_id, req_id, msg); break; +#if 0 case rsctrl::system::MsgId_RequestSystemQuit: processSystemQuit(chan_id, msg_id, req_id, msg); break; +#endif default: std::cerr << "RpcProtoSystem::processMsg() ERROR should never get here"; std::cerr << std::endl; From 088e7d61fced9f434661291f125f4566b8ab9aa6 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Wed, 12 Sep 2012 21:43:41 +0000 Subject: [PATCH 059/222] Initial refreshing and refactoring of photoshare git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5544 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/gui/PhotoShare/AlbumCreateDialog.cpp | 48 ++ .../src/gui/PhotoShare/AlbumCreateDialog.h | 35 + .../src/gui/PhotoShare/AlbumCreateDialog.ui | 304 ++++++++ .../src/gui/PhotoShare/AlbumDialog.cpp | 14 + .../src/gui/PhotoShare/AlbumDialog.h | 22 + .../src/gui/PhotoShare/AlbumDialog.ui | 21 + .../src/gui/PhotoShare/AlbumItem.cpp | 29 + retroshare-gui/src/gui/PhotoShare/AlbumItem.h | 29 + .../src/gui/PhotoShare/AlbumItem.ui | 80 +++ .../src/gui/PhotoShare/PhotoAddDialog.cpp | 663 ------------------ .../src/gui/PhotoShare/PhotoAddDialog.h | 83 --- .../src/gui/PhotoShare/PhotoAddDialog.ui | 493 ------------- .../src/gui/PhotoShare/PhotoDetailsDialog.cpp | 521 -------------- .../src/gui/PhotoShare/PhotoDetailsDialog.h | 59 -- .../src/gui/PhotoShare/PhotoDetailsDialog.ui | 221 ------ .../src/gui/PhotoShare/PhotoDialog.cpp | 418 ++--------- .../src/gui/PhotoShare/PhotoDialog.h | 34 +- .../src/gui/PhotoShare/PhotoDialog.ui | 133 +--- .../src/gui/PhotoShare/PhotoDialog_v1.ui | 273 -------- .../src/gui/PhotoShare/PhotoDrop.cpp | 25 - retroshare-gui/src/gui/PhotoShare/PhotoDrop.h | 5 +- .../src/gui/PhotoShare/PhotoItem.cpp | 296 +------- retroshare-gui/src/gui/PhotoShare/PhotoItem.h | 114 +-- .../src/gui/PhotoShare/PhotoItem.ui | 289 ++------ .../src/gui/PhotoShare/PhotoSlideDetails.ui | 129 ---- 25 files changed, 755 insertions(+), 3583 deletions(-) create mode 100644 retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp create mode 100644 retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.h create mode 100644 retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui create mode 100644 retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp create mode 100644 retroshare-gui/src/gui/PhotoShare/AlbumDialog.h create mode 100644 retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui create mode 100644 retroshare-gui/src/gui/PhotoShare/AlbumItem.cpp create mode 100644 retroshare-gui/src/gui/PhotoShare/AlbumItem.h create mode 100644 retroshare-gui/src/gui/PhotoShare/AlbumItem.ui delete mode 100644 retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp delete mode 100644 retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.h delete mode 100644 retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.ui delete mode 100644 retroshare-gui/src/gui/PhotoShare/PhotoDetailsDialog.cpp delete mode 100644 retroshare-gui/src/gui/PhotoShare/PhotoDetailsDialog.h delete mode 100644 retroshare-gui/src/gui/PhotoShare/PhotoDetailsDialog.ui delete mode 100644 retroshare-gui/src/gui/PhotoShare/PhotoDialog_v1.ui delete mode 100644 retroshare-gui/src/gui/PhotoShare/PhotoSlideDetails.ui diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp new file mode 100644 index 000000000..63611383e --- /dev/null +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp @@ -0,0 +1,48 @@ +#include "AlbumCreateDialog.h" +#include "ui_AlbumCreateDialog.h" + +#include "util/misc.h" + +AlbumCreateDialog::AlbumCreateDialog(TokenQueueV2 *photoQueue, RsPhotoV2 *rs_photo, QWidget *parent): + QDialog(parent), + ui(new Ui::AlbumCreateDialog), mPhotoQueue(photoQueue), mRsPhoto(rs_photo) +{ + ui->setupUi(this); + + connect(ui->publishButton, SIGNAL(clicked()), this, SLOT(publishAlbum())); +} + +AlbumCreateDialog::~AlbumCreateDialog() +{ + delete ui; +} + +void AlbumCreateDialog::publishAlbum() +{ + // get fields for album to publish, publish and then exit dialog + RsPhotoAlbum album; + + album.mCaption = ui->lineEdit_Caption_2->text().toStdString(); + album.mPhotographer = ui->lineEdit_Photographer->text().toStdString(); + album.mMeta.mGroupName = ui->lineEdit_Title_2->text().toStdString(); + album.mDescription = ui->textEdit_Description->toPlainText().toStdString(); + album.mWhere = ui->lineEdit_Where->text().toStdString(); + + uint32_t token; + mRsPhoto->submitAlbumDetails(token, album); + mPhotoQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, 0); + close(); +} + +void AlbumCreateDialog::addAlbumThumbnail() +{ + QPixmap img = misc::getOpenThumbnailedPicture(this, tr("Load Album Thumbnail"), 64, 64); + + if (img.isNull()) + return; + + mThumbNail = img; + + // to show the selected + ui->AlbumThumbNail->setIcon(mThumbNail); +} diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.h b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.h new file mode 100644 index 000000000..d140432c7 --- /dev/null +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.h @@ -0,0 +1,35 @@ +#ifndef ALBUMCREATEDIALOG_H +#define ALBUMCREATEDIALOG_H + +#include +#include "util/TokenQueueV2.h" +#include "retroshare/rsphotoV2.h" + +namespace Ui { + class AlbumCreateDialog; +} + + +class AlbumCreateDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AlbumCreateDialog(TokenQueueV2* photoQueue, RsPhotoV2* rs_photo, QWidget *parent = 0); + ~AlbumCreateDialog(); + +private slots: + void publishAlbum(); + void addAlbumThumbnail(); + +private: + Ui::AlbumCreateDialog *ui; + + TokenQueueV2* mPhotoQueue; + RsPhotoV2* mRsPhoto; + QPixmap mThumbNail; +}; + + + +#endif // ALBUMCREATEDIALOG_H diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui new file mode 100644 index 000000000..035d084d5 --- /dev/null +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui @@ -0,0 +1,304 @@ + + + AlbumCreateDialog + + + + 0 + 0 + 465 + 347 + + + + Dialog + + + + + + + + + + + 18 + 75 + true + + + + Album Details + + + + + + + Album Name: + + + + + + + + + + Category: + + + + + + + + Travel + + + + + Holiday + + + + + Friends + + + + + Family + + + + + Work + + + + + Random + + + + + + + + + + + 64 + 64 + + + + + 64 + 64 + + + + +border: 2px solid white; +border-radius: 10px; + + + + + + + + :/images/channels.png:/images/channels.png + + + + 64 + 64 + + + + + + + + + + + + Caption: + + + + + + + + + + Photographer: + + + + + + + + + + Description + + + + + + + + + + Where: + + + + + + + + + + + + + + + 1 + 0 + + + + Share Options + + + + + + + 0 + 0 + + + + + Public + + + + + All Friends + + + + + Restricted + + + + + + + + + 0 + 0 + + + + + Resize Images (< 1Mb) + + + + + Resize Images (< 10Mb) + + + + + Send Original Images + + + + + + + + + 0 + 0 + + + + + No Comments Allowed + + + + + Authenticated Comments + + + + + Any Comments Allowed + + + + + + + + + 0 + 0 + + + + + Publish with Identity + + + + + + + + + + + Qt::Horizontal + + + + 598 + 20 + + + + + + + + Publish Album + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp new file mode 100644 index 000000000..be101b354 --- /dev/null +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp @@ -0,0 +1,14 @@ +#include "AlbumDialog.h" +#include "ui_AlbumDialog.h" + +AlbumDialog::AlbumDialog(QWidget *parent) : + QWidget(parent), + ui(new Ui::AlbumDialog) +{ + ui->setupUi(this); +} + +AlbumDialog::~AlbumDialog() +{ + delete ui; +} diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h new file mode 100644 index 000000000..9d56bd79a --- /dev/null +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h @@ -0,0 +1,22 @@ +#ifndef ALBUMDIALOG_H +#define ALBUMDIALOG_H + +#include + +namespace Ui { + class AlbumDialog; +} + +class AlbumDialog : public QWidget +{ + Q_OBJECT + +public: + explicit AlbumDialog(QWidget *parent = 0); + ~AlbumDialog(); + +private: + Ui::AlbumDialog *ui; +}; + +#endif // ALBUMDIALOG_H diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui new file mode 100644 index 000000000..2cce7089f --- /dev/null +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui @@ -0,0 +1,21 @@ + + + + + AlbumDialog + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumItem.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumItem.cpp new file mode 100644 index 000000000..387b28d51 --- /dev/null +++ b/retroshare-gui/src/gui/PhotoShare/AlbumItem.cpp @@ -0,0 +1,29 @@ +#include "AlbumItem.h" +#include "ui_AlbumItem.h" + +AlbumItem::AlbumItem(const RsPhotoAlbum& album, QWidget *parent) : + QWidget(parent), + ui(new Ui::AlbumItem), mAlbum(album) +{ + ui->setupUi(this); + setUp(); +} + +AlbumItem::~AlbumItem() +{ + delete ui; +} + +void AlbumItem::setUp() +{ + ui->label_AlbumTitle->setText(QString::fromStdString(mAlbum.mMeta.mGroupName)); + ui->label_Photographer->setText(QString::fromStdString(mAlbum.mPhotographer)); + QPixmap qtn; + qtn.loadFromData(mAlbum.mThumbnail.data, mAlbum.mThumbnail.size, mAlbum.mThumbnail.type.c_str()); + ui->label_Thumbnail->setPixmap(qtn); +} + +RsPhotoAlbum AlbumItem::getAlbum() +{ + return mAlbum; +} diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumItem.h b/retroshare-gui/src/gui/PhotoShare/AlbumItem.h new file mode 100644 index 000000000..1da374767 --- /dev/null +++ b/retroshare-gui/src/gui/PhotoShare/AlbumItem.h @@ -0,0 +1,29 @@ +#ifndef ALBUMITEM_H +#define ALBUMITEM_H + +#include +#include "string.h" +#include "retroshare/rsphotoV2.h" + +namespace Ui { + class AlbumItem; +} + +class AlbumItem : public QWidget +{ + Q_OBJECT + +public: + explicit AlbumItem(const RsPhotoAlbum& album, QWidget *parent = 0); + ~AlbumItem(); + + RsPhotoAlbum getAlbum(); + +private: + void setUp(); +private: + Ui::AlbumItem *ui; + RsPhotoAlbum mAlbum; +}; + +#endif // ALBUMITEM_H diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumItem.ui b/retroshare-gui/src/gui/PhotoShare/AlbumItem.ui new file mode 100644 index 000000000..a66fd9d90 --- /dev/null +++ b/retroshare-gui/src/gui/PhotoShare/AlbumItem.ui @@ -0,0 +1,80 @@ + + + AlbumItem + + + + 0 + 0 + 221 + 224 + + + + Form + + + + + + TextLabel + + + + + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Album Title:</span></p></body></html> + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Photographer:</span></p></body></html> + + + + + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp deleted file mode 100644 index eaab5a088..000000000 --- a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.cpp +++ /dev/null @@ -1,663 +0,0 @@ -/* - * Retroshare Photo Plugin. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "gui/PhotoShare/PhotoAddDialog.h" -#include "gui/PhotoShare/PhotoDetailsDialog.h" -#include "gui/PhotoShare/PhotoDrop.h" - -#include - -/** Constructor */ -PhotoAddDialog::PhotoAddDialog(TokenQueueV2 *parentQueue, QWidget *parent) -: QWidget(parent), mParentQueue(parentQueue) -{ - ui.setupUi(this); - - connect(ui.scrollAreaWidgetContents, SIGNAL( buttonStatus( uint32_t ) ), this, SLOT( updateMoveButtons( uint32_t ) ) ); - connect(ui.pushButton_ShiftLeft, SIGNAL( clicked( void ) ), ui.scrollAreaWidgetContents, SLOT( moveLeft( void ) ) ); - connect(ui.pushButton_ShiftRight, SIGNAL( clicked( void ) ), ui.scrollAreaWidgetContents, SLOT( moveRight( void ) ) ); - connect(ui.pushButton_EditPhotoDetails, SIGNAL( clicked( void ) ), this, SLOT( showPhotoDetails( void ) ) ); - connect(ui.pushButton_EditAlbumDetails, SIGNAL( clicked( void ) ), this, SLOT( showAlbumDetails( void ) ) ); - connect(ui.pushButton_DeleteAlbum, SIGNAL( clicked( void ) ), this, SLOT( deleteAlbum( void ) ) ); - connect(ui.pushButton_DeletePhoto, SIGNAL( clicked( void ) ), this, SLOT( deletePhoto( void ) ) ); - - connect(ui.pushButton_Publish, SIGNAL( clicked( void ) ), this, SLOT( publishAlbum( void ) ) ); - - mPhotoDetails = NULL; - - mPhotoQueue = new TokenQueueV2(rsPhotoV2->getTokenService(), this); - - ui.AlbumDrop->setSingleImage(); - connect(ui.AlbumDrop, SIGNAL( photosChanged( void ) ), this, SLOT( albumImageChanged( void ) ) ); - connect(ui.scrollAreaWidgetContents, SIGNAL( photosChanged( void ) ), this, SLOT( photoImageChanged( void ) ) ); -} - - -void PhotoAddDialog::updateMoveButtons(uint32_t status) -{ - std::cerr << "PhotoAddDialog::updateMoveButtons(" << status << ")"; - std::cerr << std::endl; - - switch(status) - { - case PHOTO_SHIFT_NO_BUTTONS: - ui.pushButton_ShiftLeft->setEnabled(false); - ui.pushButton_ShiftRight->setEnabled(false); - break; - case PHOTO_SHIFT_LEFT_ONLY: - ui.pushButton_ShiftLeft->setEnabled(true); - ui.pushButton_ShiftRight->setEnabled(false); - break; - case PHOTO_SHIFT_RIGHT_ONLY: - ui.pushButton_ShiftLeft->setEnabled(false); - ui.pushButton_ShiftRight->setEnabled(true); - break; - case PHOTO_SHIFT_BOTH: - ui.pushButton_ShiftLeft->setEnabled(true); - ui.pushButton_ShiftRight->setEnabled(true); - break; - } -} - - -bool PhotoAddDialog::updateAlbumDetails(const RsPhotoAlbum &album) -{ - std::cerr << "PhotoAddDialog::updateAlbumDetails()"; - std::cerr << " (Copy data to mAlbumData + Add PhotoItem)"; - std::cerr << std::endl; - // cleanup old image first. - mAlbumData.mThumbnail.deleteImage(); - mAlbumData = album; - - // copy photo too. - mAlbumData.mThumbnail.data = 0; - mAlbumData.mThumbnail.copyFrom(album.mThumbnail); - - /* show iterate through all the photos and update them too - except normally they haven't arrived yet */ - - ui.lineEdit_Title->setText(QString::fromUtf8(album.mMeta.mGroupName.c_str())); - ui.lineEdit_Caption->setText(QString::fromUtf8(album.mCaption.c_str())); - ui.lineEdit_Where->setText(QString::fromUtf8(album.mWhere.c_str())); - ui.lineEdit_When->setText(QString::fromUtf8(album.mWhen.c_str())); - - PhotoItem *item = new PhotoItem(NULL, mAlbumData); - ui.AlbumDrop->addPhotoItem(item); - - // called via callback AlbumChanged. - //setAlbumDataToPhotos(); - return true; -} - - -bool PhotoAddDialog::setAlbumDataToPhotos() -{ - std::cerr << "PhotoAddDialog::setAlbumDataToPhotos()"; - std::cerr << std::endl; - - int photoCount = ui.scrollAreaWidgetContents->getPhotoCount(); - - for(int i = 0; i < photoCount; i++) - { - PhotoItem *item = ui.scrollAreaWidgetContents->getPhotoIdx(i); - item->updateAlbumText(mAlbumData); - } - return true; -} - - -void PhotoAddDialog::showPhotoDetails() -{ - std::cerr << "PhotoAddDialog::showPhotoDetails()"; - std::cerr << std::endl; - - PhotoItem *item = ui.scrollAreaWidgetContents->getSelectedPhotoItem(); - if (item) - { - if (!mPhotoDetails) - { - mPhotoDetails = new PhotoDetailsDialog(NULL); - connect(mPhotoDetails, SIGNAL( editingDone( void ) ), this, SLOT( editingStageDone( void ) ) ); - } - mPhotoDetails->setPhotoItem(item); - mPhotoDetails->show(); - mEditingModeAlbum = false; - } -} - - -void PhotoAddDialog::showAlbumDetails() -{ - std::cerr << "PhotoAddDialog::showAlbumDetails()"; - std::cerr << std::endl; - - - /* grab the image from the AlbumDrop */ - PhotoItem *item = NULL; - if (ui.AlbumDrop->getPhotoCount() > 0) - { - item = ui.AlbumDrop->getPhotoIdx(0); - } - - if (item) - { - if (!mPhotoDetails) - { - mPhotoDetails = new PhotoDetailsDialog(NULL); - connect(mPhotoDetails, SIGNAL( editingDone( void ) ), this, SLOT( editingStageDone( void ) ) ); - } - mPhotoDetails->setPhotoItem(item); - mPhotoDetails->show(); - mEditingModeAlbum = true; - } - else - { - std::cerr << "PhotoAddDialog::showAlbumDetails() PhotoItem Invalid"; - std::cerr << std::endl; - } -} - -/* Callback when AlbumDrop gets new image */ -void PhotoAddDialog::albumImageChanged() -{ - std::cerr << "PhotoAddDialog::albumImageChanged()"; - std::cerr << std::endl; - - /* must update the data from the reference stuff */ - PhotoItem *item = NULL; - if (ui.AlbumDrop->getPhotoCount() > 0) - { - item = ui.AlbumDrop->getPhotoIdx(0); - } - - if (!item) - { - std::cerr << "PhotoAddDialog::albumImageChanged() ERROR no Album PhotoItem"; - std::cerr << std::endl; - return; - } - - std::cerr << "PhotoAddDialog::albumImageChanged() PRE: AlbumDrop: " << item->mAlbumDetails; - std::cerr << std::endl; - std::cerr << "PhotoAddDialog::albumImageChanged() PRE: mAlbumData: " << mAlbumData; - std::cerr << std::endl; - - - item->mIsPhoto = false; // Force to Album mode. - - /* now AlbumDrop has the image, but AlbumData has the other stuff */ - - item->getPhotoThumbnail(mAlbumData.mThumbnail); - item->updateAlbumText(mAlbumData); - - - - /* if we are in editing mode -> update it */ - if ((mEditingModeAlbum) && (mPhotoDetails)) - { - std::cerr << "PhotoAddDialog::albumImageChanged() Updating PhotoDetails -> PhotoItem"; - std::cerr << std::endl; - mPhotoDetails->setPhotoItem(item); - } - - std::cerr << "PhotoAddDialog::albumImageChanged() POST: AlbumDrop: " << item->mAlbumDetails; - std::cerr << std::endl; - std::cerr << "PhotoAddDialog::albumImageChanged() POST: mAlbumData: " << mAlbumData; - std::cerr << std::endl; - -} - - -/* This is called back once PhotoDetailsDialog Finishes */ -void PhotoAddDialog::editingStageDone() -{ - std::cerr << "PhotoAddDialog::editingStageDone()"; - std::cerr << std::endl; - - if (mEditingModeAlbum) - { - /* need to resolve Album Data, repopulate entries - */ - - /* grab the image from the AlbumDrop (This is where PhotoDetailsDialog stores the data) */ - PhotoItem *item = NULL; - if (ui.AlbumDrop->getPhotoCount() > 0) - { - item = ui.AlbumDrop->getPhotoIdx(0); - } - - if (!item) - { - std::cerr << "PhotoAddDialog::editingStageDone() ERROR no Album PhotoItem"; - std::cerr << std::endl; - } - - /* Total Hack here Copy from AlbumDrop to Reference Data */ - - // cleanup old image first. - mAlbumData.mThumbnail.deleteImage(); - mAlbumData = item->mAlbumDetails; - item->getPhotoThumbnail(mAlbumData.mThumbnail); - - // Push Back data -> to trigger Text Update. - item->updateAlbumText(mAlbumData); - mEditingModeAlbum = false; - - // Update GUI too. - ui.lineEdit_Title->setText(QString::fromUtf8(mAlbumData.mMeta.mGroupName.c_str())); - ui.lineEdit_Caption->setText(QString::fromUtf8(mAlbumData.mCaption.c_str())); - ui.lineEdit_Where->setText(QString::fromUtf8(mAlbumData.mWhere.c_str())); - ui.lineEdit_When->setText(QString::fromUtf8(mAlbumData.mWhen.c_str())); - - } - else - { - std::cerr << "PhotoAddDialog::editingStageDone() ERROR not EditingModeAlbum"; - std::cerr << std::endl; - } - - // This forces item update -> though the AlbumUpdate is only needed if we edited Album. - setAlbumDataToPhotos(); -} - - -/* Callback when PhotoDrop gets new image */ -void PhotoAddDialog::photoImageChanged() -{ - setAlbumDataToPhotos(); -} - - - -void PhotoAddDialog::publishAlbum() -{ - std::cerr << "PhotoAddDialog::publishAlbum()"; - std::cerr << std::endl; - - /* we need to iterate through each photoItem, and extract the details */ - - RsPhotoAlbum album = mAlbumData; - album.mThumbnail.data = 0; - - album.mShareOptions.mShareType = 0; - album.mShareOptions.mShareGroupId = "unknown"; - album.mShareOptions.mPublishKey = "unknown"; - album.mShareOptions.mCommentMode = 0; - album.mShareOptions.mResizeMode = 0; - - album.mMeta.mGroupName = ui.lineEdit_Title->text().toStdString(); - album.mCategory = "Unknown"; - album.mCaption = ui.lineEdit_Caption->text().toStdString(); - album.mWhere = ui.lineEdit_Where->text().toStdString(); - album.mWhen = ui.lineEdit_When->text().toStdString(); - - /* grab the image from the AlbumDrop */ - if (ui.AlbumDrop->getPhotoCount() > 0) - { - PhotoItem *item = ui.AlbumDrop->getPhotoIdx(0); - item->getPhotoThumbnail(album.mThumbnail); - } - - // For the moment, only submit albums Once. - if (mAlbumEdit) - { - std::cerr << "PhotoAddDialog::publishAlbum() AlbumEdit Mode"; - std::cerr << std::endl; - - /* call publishPhotos directly */ - publishPhotos(album.mMeta.mGroupId); - return; - } - - - std::cerr << "PhotoAddDialog::publishAlbum() New Album Mode Submitting....."; - std::cerr << std::endl; - uint32_t token; - rsPhotoV2->submitAlbumDetails(token, album); - mPhotoQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, 0); - -} - - - - -void PhotoAddDialog::publishPhotos(std::string albumId) -{ - /* now have path and album id */ - int photoCount = ui.scrollAreaWidgetContents->getPhotoCount(); - - for(int i = 0; i < photoCount; i++) - { - RsPhotoPhoto photo; - PhotoItem *item = ui.scrollAreaWidgetContents->getPhotoIdx(i); - - if (!item->mIsPhoto) - { - std::cerr << "PhotoAddDialog::publishAlbum() MAJOR ERROR!"; - std::cerr << std::endl; - } - - photo = item->mPhotoDetails; - photo.mThumbnail.data = 0; // do proper data copy. - item->getPhotoThumbnail(photo.mThumbnail); - - bool isNewPhoto = false; - bool isModifiedPhoto = false; - - if (mAlbumEdit) - { - // can have modFlags and be New... so the order is important. - if (photo.mMeta.mGroupId.length() < 1) - { - /* new photo - flag in mods */ - photo.mModFlags |= RSPHOTO_FLAGS_ATTRIB_PHOTO; - photo.mMeta.mGroupId = albumId; - isNewPhoto = true; - } - else if (photo.mModFlags) - { - isModifiedPhoto = true; - } - } - else - { - /* new album - update GroupId, all photos are new */ - photo.mMeta.mGroupId = albumId; - isNewPhoto = true; - } - - photo.mOrder = i; - - std::cerr << "PhotoAddDialog::publishAlbum() Photo(" << i << ")"; - std::cerr << " mSetFlags: " << photo.mSetFlags; - std::cerr << " mModFlags: " << photo.mModFlags; - std::cerr << std::endl; - -#if 0 - /* scale photo if needed */ - if (album.mShareOptions.mResizeMode) - { - /* */ - - } -#endif - - /* save image to album path */ - photo.path = "unknown"; - - uint32_t token; - - std::cerr << "PhotoAddDialog::publishAlbum() Photo(" << i << ") "; - std::cerr << "Is Updated"; - - rsPhotoV2->submitPhoto(token, photo); - mPhotoQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); - std::cerr << std::endl; - } - - clearDialog(); - - hide(); -} - - -void PhotoAddDialog::deleteAlbum() -{ - std::cerr << "PhotoAddDialog::deleteAlbum() Not Implemented Yet"; - std::cerr << std::endl; -} - - -void PhotoAddDialog::deletePhoto() -{ - std::cerr << "PhotoAddDialog::deletePhoto() Not Implemented Yet"; - std::cerr << std::endl; -} - - -void PhotoAddDialog::clearDialog() -{ - ui.lineEdit_Title->setText(QString("title")); - ui.lineEdit_Caption->setText(QString("Caption")); - ui.lineEdit_Where->setText(QString("Where")); - ui.lineEdit_When->setText(QString("When")); - - ui.scrollAreaWidgetContents->clearPhotos(); - ui.AlbumDrop->clearPhotos(); - - /* clean up album image */ - mAlbumData.mThumbnail.deleteImage(); - - RsPhotoAlbum emptyAlbum; - mAlbumData = emptyAlbum; - - /* add empty image */ - PhotoItem *item = new PhotoItem(NULL, mAlbumData); - ui.AlbumDrop->addPhotoItem(item); - - mAlbumEdit = false; -} - - -void PhotoAddDialog::loadAlbum(const std::string &albumId) -{ - /* much like main load fns */ - clearDialog(); - mAlbumEdit = true; - - RsTokReqOptionsV2 opts; - uint32_t token; - std::list albumIds; - albumIds.push_back(albumId); - - // We need both Album and Photo Data. - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, albumIds, 0); -} - - -bool PhotoAddDialog::loadPhotoData(const uint32_t &token) -{ - std::cerr << "PhotoAddDialog::loadPhotoData()"; - std::cerr << std::endl; - - PhotoResult res; - rsPhotoV2->getPhoto(token, res); - PhotoResult::iterator mit = res.begin(); - - - for(; mit != res.end(); mit++) - { - std::vector& photoV = mit->second; - std::vector::iterator vit = photoV.begin(); - - for(; vit != photoV.end(); vit++) - { - RsPhotoPhoto& photo = *vit; - PhotoItem *item = new PhotoItem(NULL, photo, mAlbumData); - ui.scrollAreaWidgetContents->addPhotoItem(item); - - std::cerr << "PhotoAddDialog::loadPhotoData() AlbumId: " << photo.mMeta.mGroupId; - std::cerr << " PhotoId: " << photo.mMeta.mMsgId; - std::cerr << std::endl; - } - } - - return true; -} - -bool PhotoAddDialog::loadAlbumData(const uint32_t &token) -{ - std::cerr << "PhotoAddDialog::loadAlbumData()"; - std::cerr << std::endl; - - std::vector albums; - rsPhotoV2->getAlbum(token, albums); - - std::vector::iterator vit = albums.begin(); - - GxsMsgReq req; - - for(; vit != albums.end(); vit++) - { - RsPhotoAlbum& album = *vit; - - std::cerr << "PhotoAddDialog::loadAlbumData() AlbumId: " << album.mMeta.mGroupId << std::endl; - updateAlbumDetails(album); - - uint32_t token; - std::list albumIds; - albumIds.push_back(album.mMeta.mGroupId); - req[album.mMeta.mGroupId] = std::vector(); - } - - RsTokReqOptionsV2 opts; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - uint32_t t; - mPhotoQueue->requestMsgInfo(t, RS_TOKREQ_ANSTYPE_DATA, opts, req, 0); - return true; -} - -bool PhotoAddDialog::loadCreatedAlbum(const uint32_t &token) -{ - std::cerr << "PhotoAddDialog::loadCreatedAlbum()"; - std::cerr << std::endl; - - std::list groupInfo; - if (!rsPhotoV2->getGroupSummary(token, groupInfo)) - { - std::cerr << "PhotoAddDialog::loadCreatedAlbum() ERROR Getting MetaData"; - std::cerr << std::endl; - return false; - } - - if (groupInfo.size() != 1) - { - std::cerr << "PhotoAddDialog::loadCreatedAlbum() ERROR Too much Info"; - std::cerr << std::endl; - return false; - } - - std::cerr << "PhotoAddDialog::loadCreatedAlbum() publishing Photos"; - std::cerr << std::endl; - - publishPhotos(groupInfo.front().mGroupId); - - return true; -} - -void PhotoAddDialog::acknowledgeGroup(const uint32_t &token) -{ - RsGxsGroupId grpId; - rsPhotoV2->acknowledgeGrp(token, grpId); - - if(!grpId.empty()) - { - std::list grpIds; - grpIds.push_back(grpId); - - RsTokReqOptionsV2 opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - uint32_t reqToken; - - // request for self - mPhotoQueue->requestGroupInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); - - // also request for parent - mParentQueue->requestGroupInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); - } -} - -void PhotoAddDialog::acknowledgeMessage(const uint32_t &token) -{ - std::pair p; - rsPhotoV2->acknowledgeMsg(token, p); - - if(!p.first.empty()) - { - GxsMsgReq req; - std::vector v; - v.push_back(p.second); - req[p.first] = v; - RsTokReqOptionsV2 opts; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - uint32_t reqToken; - mPhotoQueue->requestMsgInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, req, 0); - - mParentQueue->requestMsgInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, req, 0); - } -} - -void PhotoAddDialog::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req) -{ - std::cerr << "PhotoDialog::loadRequest()"; - std::cerr << std::endl; - - if (queue == mPhotoQueue) - { - /* now switch on req */ - switch(req.mType) - { - case TOKENREQ_GROUPINFO: - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_DATA: - loadAlbumData(req.mToken); - break; - case RS_TOKREQ_ANSTYPE_SUMMARY: - loadCreatedAlbum(req.mToken); - break; - case RS_TOKREQ_ANSTYPE_ACK: - acknowledgeGroup(req.mToken); - break; - default: - std::cerr << "PhotoAddDialog::loadRequest() ERROR: GROUP: INVALID ANS TYPE"; - std::cerr << std::endl; - } - break; - case TOKENREQ_MSGINFO: - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_DATA: - loadPhotoData(req.mToken); - break; - case RS_TOKREQ_ANSTYPE_ACK: - acknowledgeMessage(req.mToken); - break; - default: - std::cerr << "PhotoAddDialog::loadRequest() ERROR: MESSAGE: INVALID ANS TYPE"; - std::cerr << std::endl; - - } - break; - default: - std::cerr << "PhotoAddDialog::loadRequest() ERROR: INVALID TYPE"; - std::cerr << std::endl; - break; - } - } -} - - - - diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.h b/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.h deleted file mode 100644 index 8e2b407b5..000000000 --- a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Retroshare Photo Plugin. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#ifndef MRK_PHOTO_ADD_DIALOG_H -#define MRK_PHOTO_ADD_DIALOG_H - -#include "ui_PhotoAddDialog.h" - -#include -#include "util/TokenQueueV2.h" - -class PhotoDetailsDialog; - -class PhotoAddDialog : public QWidget, public TokenResponseV2 -{ - Q_OBJECT - -public: - PhotoAddDialog(TokenQueueV2 *parentQueue, QWidget *parent = 0); - - void loadAlbum(const std::string &albumId); -virtual void loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req); - - void clearDialog(); - -private slots: - void showPhotoDetails(); - void showAlbumDetails(); - void editingStageDone(); - - // From PhotoDrops... - void albumImageChanged(); - void photoImageChanged(); - void updateMoveButtons(uint32_t status); - - void publishAlbum(); - - void deleteAlbum(); - void deletePhoto(); -private: - - void publishPhotos(std::string albumId); - - bool updateAlbumDetails(const RsPhotoAlbum &album); - bool setAlbumDataToPhotos(); - bool loadPhotoData(const uint32_t &token); - bool loadAlbumData(const uint32_t &token); - bool loadCreatedAlbum(const uint32_t &token); - void acknowledgeGroup(const uint32_t &token); - void acknowledgeMessage(const uint32_t &token); - TokenQueueV2 *mPhotoQueue; -protected: - - bool mAlbumEdit; // Editing or New. - bool mEditingModeAlbum; // Changing Album or Photo Details. - RsPhotoAlbum mAlbumData; - PhotoDetailsDialog *mPhotoDetails; - Ui::PhotoAddDialog ui; - TokenQueueV2* mParentQueue; -}; - -#endif - diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.ui b/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.ui deleted file mode 100644 index bfb09f45e..000000000 --- a/retroshare-gui/src/gui/PhotoShare/PhotoAddDialog.ui +++ /dev/null @@ -1,493 +0,0 @@ - - - PhotoAddDialog - - - - 0 - 0 - 852 - 383 - - - - - - - - - - Qt::Vertical - - - - - - - - 1 - 0 - - - - Share Options - - - - - - - 0 - 0 - - - - - Public - - - - - All Friends - - - - - Restricted - - - - - - - - - 0 - 0 - - - - - N/A - - - - - University Friends - - - - - Family - - - - - This List Contains - - - - - All your Groups - - - - - - - - - 0 - 0 - - - - - Resize Images (< 1Mb) - - - - - Resize Images (< 10Mb) - - - - - Send Original Images - - - - - - - - - 0 - 0 - - - - - No Comments Allowed - - - - - Authenticated Comments - - - - - Any Comments Allowed - - - - - - - - - 0 - 0 - - - - - Publish with XXX Key - - - - - - - - - - - - 0 - 1 - - - - Album Thumbnail - - - - - - - - - - - - - - - 10 - 1 - - - - Summary - - - - - - false - - - - 0 - 0 - - - - - - - - Category: - - - - - - - false - - - - Travel - - - - - Holiday - - - - - Friends - - - - - Family - - - - - Work - - - - - Random - - - - - - - - Caption - - - - - - - false - - - - 0 - 0 - - - - - - - - Where: - - - - - - - false - - - - 0 - 0 - - - - - - - - false - - - - 0 - 0 - - - - - - - - Album Title: - - - - - - - When - - - - - - - - - - Delete Album - - - - - - - Qt::Horizontal - - - - 78 - 20 - - - - - - - - Edit Album Details - - - - - - - - - - - HELP: Drag & Drop to insert, and re-order pictures. Click on a picture to edit details below. - - - - - - - - 0 - 10 - - - - true - - - Qt::ScrollBarAsNeeded - - - true - - - Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - - - - - 0 - 0 - 830 - 83 - - - - QWidget#scrollAreaWidgetContents{border: none;} - - - - - - - - - - - - - - - Delete Photo - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Edit Photo Details - - - - - - - Qt::Horizontal - - - - 68 - 17 - - - - - - - - << - - - - - - - >> - - - - - - - Qt::Horizontal - - - - 68 - 17 - - - - - - - - Publish Album - - - - - - - - - - PhotoDrop - QWidget -

gui/PhotoShare/PhotoDrop.h
- 1 - - - - - - - diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDetailsDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDetailsDialog.cpp deleted file mode 100644 index 87f74184a..000000000 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDetailsDialog.cpp +++ /dev/null @@ -1,521 +0,0 @@ -/* - * Retroshare Photo Plugin. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "gui/PhotoShare/PhotoDetailsDialog.h" -#include "gui/PhotoShare/PhotoItem.h" - -#include - -/** Constructor */ -PhotoDetailsDialog::PhotoDetailsDialog(QWidget *parent) -: QWidget(parent) -{ - ui.setupUi(this); - connect( ui.pushButton_Update, SIGNAL( clicked() ), this, SLOT( updateDetails () ) ); - -} - - -void PhotoDetailsDialog::setPhotoItem(PhotoItem *item) -{ - if (mPhotoItem == item) - { - return; - } - - mPhotoItem = item; - - /* update fields from the edit fields */ - refreshDetails(); -} - - -void PhotoDetailsDialog::refreshDetails() -{ - blankDetails(); - if (!mPhotoItem) - { - return; - } - - ui.label_Headline->setText(QString("Photo Description")); - - //ui.comboBox_Category= mPhotoItem->mDetails.mCaption; - - if (mPhotoItem->mIsPhoto) - { - // THIS is tedious! - - RsPhotoPhoto &photo = mPhotoItem->mPhotoDetails; - RsPhotoAlbum &album = mPhotoItem->mAlbumDetails; - - if (photo.mSetFlags & RSPHOTO_FLAGS_ATTRIB_TITLE) - { - ui.lineEdit_Title->setText(QString::fromUtf8(photo.mMeta.mMsgName.c_str())); - } - else if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_TITLE) - { - ui.lineEdit_Title->setText(QString::fromUtf8(album.mMeta.mGroupName.c_str())); - } - - if (photo.mSetFlags & RSPHOTO_FLAGS_ATTRIB_CAPTION) - { - ui.lineEdit_Caption->setText(QString::fromUtf8(photo.mCaption.c_str())); - } - else if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_CAPTION) - { - ui.lineEdit_Caption->setText(QString::fromUtf8(album.mCaption.c_str())); - } - - if (photo.mSetFlags & RSPHOTO_FLAGS_ATTRIB_DESC) - { - ui.textEdit_Description->setText(QString::fromUtf8(photo.mDescription.c_str())); - } - else if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_DESC) - { - ui.textEdit_Description->setText(QString::fromUtf8(album.mDescription.c_str())); - } - - if (photo.mSetFlags & RSPHOTO_FLAGS_ATTRIB_PHOTOGRAPHER) - { - ui.lineEdit_Photographer->setText(QString::fromUtf8(photo.mPhotographer.c_str())); - } - else if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_PHOTOGRAPHER) - { - ui.lineEdit_Photographer->setText(QString::fromUtf8(album.mPhotographer.c_str())); - } - - if (photo.mSetFlags & RSPHOTO_FLAGS_ATTRIB_WHERE) - { - ui.lineEdit_Where->setText(QString::fromUtf8(photo.mWhere.c_str())); - } - else if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_WHERE) - { - ui.lineEdit_Where->setText(QString::fromUtf8(album.mWhere.c_str())); - } - - if (photo.mSetFlags & RSPHOTO_FLAGS_ATTRIB_WHEN) - { - ui.lineEdit_When->setText(QString::fromUtf8(photo.mWhen.c_str())); - } - else if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_WHEN) - { - ui.lineEdit_When->setText(QString::fromUtf8(album.mWhen.c_str())); - } - - if (photo.mSetFlags & RSPHOTO_FLAGS_ATTRIB_OTHER) - { - ui.lineEdit_Other->setText(QString::fromUtf8(photo.mOther.c_str())); - } - else if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_OTHER) - { - ui.lineEdit_Other->setText(QString::fromUtf8(album.mOther.c_str())); - } - - if (photo.mSetFlags & RSPHOTO_FLAGS_ATTRIB_HASHTAGS) - { - ui.lineEdit_HashTags->setText(QString::fromUtf8(photo.mHashTags.c_str())); - } - else if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_HASHTAGS) - { - ui.lineEdit_HashTags->setText(QString::fromUtf8(album.mHashTags.c_str())); - } - } - else - { - RsPhotoAlbum &album = mPhotoItem->mAlbumDetails; - - if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_TITLE) - { - ui.lineEdit_Title->setText(QString::fromUtf8(album.mMeta.mGroupName.c_str())); - } - - if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_CAPTION) - { - ui.lineEdit_Caption->setText(QString::fromUtf8(album.mCaption.c_str())); - } - - if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_DESC) - { - ui.textEdit_Description->setText(QString::fromUtf8(album.mDescription.c_str())); - } - - if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_PHOTOGRAPHER) - { - ui.lineEdit_Photographer->setText(QString::fromUtf8(album.mPhotographer.c_str())); - } - - if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_WHERE) - { - ui.lineEdit_Where->setText(QString::fromUtf8(album.mWhere.c_str())); - } - - if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_WHEN) - { - ui.lineEdit_When->setText(QString::fromUtf8(album.mWhen.c_str())); - } - - if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_OTHER) - { - ui.lineEdit_Other->setText(QString::fromUtf8(album.mOther.c_str())); - } - - if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_HASHTAGS) - { - ui.lineEdit_HashTags->setText(QString::fromUtf8(album.mHashTags.c_str())); - } - } - - const QPixmap *qtn = mPhotoItem->getPixmap(); - QPixmap cpy(*qtn); - ui.label_Photo->setPixmap(cpy); -} - -void PhotoDetailsDialog::blankDetails() -{ - ui.label_Headline->setText(QString("Nothing")); - - //ui.comboBox_Category= mPhotoItem->mDetails.mCaption; - - ui.lineEdit_Title->setText(QString("")); - ui.lineEdit_Caption->setText(QString("")); - ui.textEdit_Description->setText(QString("")); - ui.lineEdit_Photographer->setText(QString("")); - ui.lineEdit_Where->setText(QString("")); - ui.lineEdit_When->setText(QString("")); - ui.lineEdit_Other->setText(QString("")); - ui.lineEdit_HashTags->setText(QString("")); - - //QPixmap qtn = mPhotoItem->getPixmap(); - //ui.label_Photo->setPixmap(qtn); -} - - -void PhotoDetailsDialog::updateDetails() -{ - saveDetails(); - - // Notify Listeners. - editingDone(); - - hide(); -} - -void PhotoDetailsDialog::saveDetails() -{ - - if(!mPhotoItem) - { - return; - } - - RsPhotoPhoto &photo = mPhotoItem->mPhotoDetails; - RsPhotoAlbum &album = mPhotoItem->mAlbumDetails; - - std::string txt = ui.lineEdit_Title->text().toUtf8().constData(); - bool setName = false; - if ((mPhotoItem->mIsPhoto) && (photo.mSetFlags & RSPHOTO_FLAGS_ATTRIB_TITLE)) - { - if (txt != photo.mMeta.mMsgName) - setName = true; - } - else if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_TITLE) - { - if (txt != album.mMeta.mGroupName) - setName = true; - } - else if (txt.length() != 0) - { - setName = true; - } - - if (setName) - { - if (mPhotoItem->mIsPhoto) - { - photo.mSetFlags |= RSPHOTO_FLAGS_ATTRIB_TITLE; - photo.mModFlags |= RSPHOTO_FLAGS_ATTRIB_TITLE; - photo.mMeta.mMsgName = txt; - } - else - { - album.mSetFlags |= RSPHOTO_FLAGS_ATTRIB_TITLE; - album.mModFlags |= RSPHOTO_FLAGS_ATTRIB_TITLE; - album.mMeta.mGroupName = txt; - } - } - - - txt = ui.lineEdit_Caption->text().toUtf8().constData(); - setName = false; - if ((mPhotoItem->mIsPhoto) && (photo.mSetFlags & RSPHOTO_FLAGS_ATTRIB_CAPTION)) - { - if (txt != photo.mCaption) - setName = true; - } - else if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_CAPTION) - { - if (txt != album.mCaption) - setName = true; - } - else if (txt.length() != 0) - { - setName = true; - } - - if (setName) - { - if (mPhotoItem->mIsPhoto) - { - photo.mSetFlags |= RSPHOTO_FLAGS_ATTRIB_CAPTION; - photo.mModFlags |= RSPHOTO_FLAGS_ATTRIB_CAPTION; - photo.mCaption = txt; - } - else - { - album.mSetFlags |= RSPHOTO_FLAGS_ATTRIB_CAPTION; - album.mModFlags |= RSPHOTO_FLAGS_ATTRIB_CAPTION; - album.mCaption = txt; - } - } - - - txt = ui.textEdit_Description->toPlainText().toUtf8().constData(); - setName = false; - if ((mPhotoItem->mIsPhoto) && (photo.mSetFlags & RSPHOTO_FLAGS_ATTRIB_DESC)) - { - if (txt != photo.mDescription) - setName = true; - } - else if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_DESC) - { - if (txt != album.mDescription) - setName = true; - } - else if (txt.length() != 0) - { - setName = true; - } - - if (setName) - { - if (mPhotoItem->mIsPhoto) - { - photo.mSetFlags |= RSPHOTO_FLAGS_ATTRIB_DESC; - photo.mModFlags |= RSPHOTO_FLAGS_ATTRIB_DESC; - photo.mDescription = txt; - } - else - { - album.mSetFlags |= RSPHOTO_FLAGS_ATTRIB_DESC; - album.mModFlags |= RSPHOTO_FLAGS_ATTRIB_DESC; - album.mDescription = txt; - } - } - - - txt = ui.lineEdit_Photographer->text().toUtf8().constData(); - setName = false; - if ((mPhotoItem->mIsPhoto) && (photo.mSetFlags & RSPHOTO_FLAGS_ATTRIB_PHOTOGRAPHER)) - { - if (txt != photo.mPhotographer) - setName = true; - } - else if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_PHOTOGRAPHER) - { - if (txt != album.mPhotographer) - setName = true; - } - else if (txt.length() != 0) - { - setName = true; - } - - if (setName) - { - if (mPhotoItem->mIsPhoto) - { - photo.mSetFlags |= RSPHOTO_FLAGS_ATTRIB_PHOTOGRAPHER; - photo.mModFlags |= RSPHOTO_FLAGS_ATTRIB_PHOTOGRAPHER; - photo.mPhotographer = txt; - } - else - { - album.mSetFlags |= RSPHOTO_FLAGS_ATTRIB_PHOTOGRAPHER; - album.mModFlags |= RSPHOTO_FLAGS_ATTRIB_PHOTOGRAPHER; - album.mPhotographer = txt; - } - } - - - txt = ui.lineEdit_Where->text().toUtf8().constData(); - setName = false; - if ((mPhotoItem->mIsPhoto) && (photo.mSetFlags & RSPHOTO_FLAGS_ATTRIB_WHERE)) - { - if (txt != photo.mWhere) - setName = true; - } - else if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_WHERE) - { - if (txt != album.mWhere) - setName = true; - } - else if (txt.length() != 0) - { - setName = true; - } - - if (setName) - { - if (mPhotoItem->mIsPhoto) - { - photo.mSetFlags |= RSPHOTO_FLAGS_ATTRIB_WHERE; - photo.mModFlags |= RSPHOTO_FLAGS_ATTRIB_WHERE; - photo.mWhere = txt; - } - else - { - album.mSetFlags |= RSPHOTO_FLAGS_ATTRIB_WHERE; - album.mModFlags |= RSPHOTO_FLAGS_ATTRIB_WHERE; - album.mWhere = txt; - } - } - - txt = ui.lineEdit_When->text().toUtf8().constData(); - setName = false; - if ((mPhotoItem->mIsPhoto) && (photo.mSetFlags & RSPHOTO_FLAGS_ATTRIB_WHEN)) - { - if (txt != photo.mWhen) - setName = true; - } - else if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_WHEN) - { - if (txt != album.mWhen) - setName = true; - } - else if (txt.length() != 0) - { - setName = true; - } - - if (setName) - { - if (mPhotoItem->mIsPhoto) - { - photo.mSetFlags |= RSPHOTO_FLAGS_ATTRIB_WHEN; - photo.mModFlags |= RSPHOTO_FLAGS_ATTRIB_WHEN; - photo.mWhen = txt; - } - else - { - album.mSetFlags |= RSPHOTO_FLAGS_ATTRIB_WHEN; - album.mModFlags |= RSPHOTO_FLAGS_ATTRIB_WHEN; - album.mWhen = txt; - } - } - - - txt = ui.lineEdit_HashTags->text().toUtf8().constData(); - setName = false; - if ((mPhotoItem->mIsPhoto) && (photo.mSetFlags & RSPHOTO_FLAGS_ATTRIB_HASHTAGS)) - { - if (txt != photo.mHashTags) - setName = true; - } - else if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_HASHTAGS) - { - if (txt != album.mHashTags) - setName = true; - } - else if (txt.length() != 0) - { - setName = true; - } - - if (setName) - { - if (mPhotoItem->mIsPhoto) - { - photo.mSetFlags |= RSPHOTO_FLAGS_ATTRIB_HASHTAGS; - photo.mModFlags |= RSPHOTO_FLAGS_ATTRIB_HASHTAGS; - photo.mHashTags = txt; - } - else - { - album.mSetFlags |= RSPHOTO_FLAGS_ATTRIB_HASHTAGS; - album.mModFlags |= RSPHOTO_FLAGS_ATTRIB_HASHTAGS; - album.mHashTags = txt; - } - } - - - txt = ui.lineEdit_Other->text().toUtf8().constData(); - setName = false; - if ((mPhotoItem->mIsPhoto) && (photo.mSetFlags & RSPHOTO_FLAGS_ATTRIB_OTHER)) - { - if (txt != photo.mOther) - setName = true; - } - else if (album.mSetFlags & RSPHOTO_FLAGS_ATTRIB_OTHER) - { - if (txt != album.mOther) - setName = true; - } - else if (txt.length() != 0) - { - setName = true; - } - - if (setName) - { - if (mPhotoItem->mIsPhoto) - { - photo.mSetFlags |= RSPHOTO_FLAGS_ATTRIB_OTHER; - photo.mModFlags |= RSPHOTO_FLAGS_ATTRIB_OTHER; - photo.mOther = txt; - } - else - { - album.mSetFlags |= RSPHOTO_FLAGS_ATTRIB_OTHER; - album.mModFlags |= RSPHOTO_FLAGS_ATTRIB_OTHER; - album.mOther = txt; - } - } - - - - std::cerr << "PhotoDetailsDialog::saveDetails() "; - if (mPhotoItem->mIsPhoto) - { - std::cerr << " photo.mSetFlags: " << mPhotoItem->mPhotoDetails.mSetFlags; - std::cerr << " photo.mModFlags: " << mPhotoItem->mPhotoDetails.mModFlags; - } - std::cerr << " album.mSetFlags: " << mPhotoItem->mAlbumDetails.mSetFlags; - std::cerr << " album.mModFlags: " << mPhotoItem->mAlbumDetails.mModFlags; - std::cerr << std::endl; - - //QPixmap qtn = mPhotoItem->getPixmap(); - //ui.label_Photo->setPixmap(qtn); -} - - diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDetailsDialog.h b/retroshare-gui/src/gui/PhotoShare/PhotoDetailsDialog.h deleted file mode 100644 index dd3ea03df..000000000 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDetailsDialog.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Retroshare Photo Plugin. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#ifndef MRK_PHOTO_DETAILS_DIALOG_H -#define MRK_PHOTO_DETAILS_DIALOG_H - -#include "ui_PhotoDetailsDialog.h" - -class PhotoItem; - -class PhotoDetailsDialog : public QWidget -{ - Q_OBJECT - -public: - PhotoDetailsDialog(QWidget *parent = 0); - -void setPhotoItem(PhotoItem *item); - -signals: - void editingDone(); - -private: -void saveDetails(); -void refreshDetails(); - -private slots: -void updateDetails(); -void blankDetails(); - -private: - PhotoItem *mPhotoItem; - - Ui::PhotoDetailsDialog ui; - -}; - -#endif - diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDetailsDialog.ui b/retroshare-gui/src/gui/PhotoShare/PhotoDetailsDialog.ui deleted file mode 100644 index 45bc80d3f..000000000 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDetailsDialog.ui +++ /dev/null @@ -1,221 +0,0 @@ - - - PhotoDetailsDialog - - - - 0 - 0 - 683 - 415 - - - - - - - - - - - - - - - 18 - 75 - true - - - - Album Description - - - - - - - Album Name: - - - - - - - - - - Category: - - - - - - - - Travel - - - - - Holiday - - - - - Friends - - - - - Family - - - - - Work - - - - - Random - - - - - - - - - - Thumbnail -Here -Dummy -Text -1 -2 -3 -................................... - - - - - - - - - - - Caption: - - - - - - - - - - Photographer: - - - - - - - - - - Description - - - - - - - - - - Where: - - - - - - - - - - When - - - - - - - - - - Other 1: - - - - - - - - - - HashTags: - - - - - - - - - - Qt::Vertical - - - - 20 - 18 - - - - - - - - - - - - Qt::Horizontal - - - - 598 - 20 - - - - - - - - Update Details - - - - - - - - - - - - diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index f54108550..302c261e5 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -32,6 +32,9 @@ #include #include +#include "AlbumCreateDialog.h" +#include "AlbumItem.h" + /****** * #define PHOTO_DEBUG 1 *****/ @@ -64,13 +67,12 @@ PhotoDialog::PhotoDialog(QWidget *parent) { ui.setupUi(this); - mAddDialog = NULL; - mAlbumSelected = NULL; - mPhotoSelected = NULL; - mSlideShow = NULL; + mAlbumSelected = NULL; + mPhotoSelected = NULL; + mSlideShow = NULL; connect( ui.toolButton_NewAlbum, SIGNAL(clicked()), this, SLOT(OpenOrShowPhotoAddDialog())); - connect( ui.toolButton_EditAlbum, SIGNAL(clicked()), this, SLOT(OpenPhotoEditDialog())); + connect( ui.toolButton_ViewAlbum, SIGNAL(clicked()), this, SLOT(OpenPhotoEditDialog())); connect( ui.toolButton_SlideShow, SIGNAL(clicked()), this, SLOT(OpenSlideShow())); QTimer *timer = new QTimer(this); @@ -84,57 +86,6 @@ PhotoDialog::PhotoDialog(QWidget *parent) } -void PhotoDialog::notifySelection(PhotoItem *item, int ptype) -{ - std::cerr << "PhotoDialog::notifySelection() from : " << ptype << " " << item; - std::cerr << std::endl; - - switch(ptype) - { - default: - case PHOTO_ITEM_TYPE_ALBUM: - notifyAlbumSelection(item); - break; - case PHOTO_ITEM_TYPE_PHOTO: - notifyPhotoSelection(item); - break; - } -} - -void PhotoDialog::notifyAlbumSelection(PhotoItem *item) -{ - std::cerr << "PhotoDialog::notifyAlbumSelection() from : " << item; - std::cerr << std::endl; - - if (mAlbumSelected) - { - std::cerr << "PhotoDialog::notifyAlbumSelection() unselecting old one : " << mAlbumSelected; - std::cerr << std::endl; - - mAlbumSelected->setSelected(false); - } - - mAlbumSelected = item; - insertPhotosForSelectedAlbum(); -} - - -void PhotoDialog::notifyPhotoSelection(PhotoItem *item) -{ - std::cerr << "PhotoDialog::notifyPhotoSelection() from : " << item; - std::cerr << std::endl; - - if (mPhotoSelected) - { - std::cerr << "PhotoDialog::notifyPhotoSelection() unselecting old one : " << mPhotoSelected; - std::cerr << std::endl; - - mPhotoSelected->setSelected(false); - } - - mPhotoSelected = item; -} - void PhotoDialog::checkUpdate() { @@ -176,14 +127,7 @@ void PhotoDialog::OpenSlideShow() return; } - if (mAlbumSelected->mIsPhoto) - { - std::cerr << "PhotoDialog::OpenPhotoEditDialog() MAJOR ERROR!"; - std::cerr << std::endl; - return; - } - - std::string albumId = mAlbumSelected->mAlbumDetails.mMeta.mGroupId; + std::string albumId = mAlbumSelected->getAlbum().mMeta.mGroupId; if (mSlideShow) { @@ -201,63 +145,19 @@ void PhotoDialog::OpenSlideShow() /*************** New Photo Dialog ***************/ -void PhotoDialog::OpenOrShowPhotoAddDialog() +void PhotoDialog::createAlbum() { - if (mAddDialog) - { - mAddDialog->show(); - } - else - { - mAddDialog = new PhotoAddDialog(mPhotoQueue, NULL); - mAddDialog->show(); - } - mAddDialog->clearDialog(); + AlbumCreateDialog albumCreate(mPhotoQueue, rsPhotoV2, this); + albumCreate.exec(); } - -/*************** Edit Photo Dialog ***************/ - void PhotoDialog::OpenPhotoEditDialog() { - /* check if we have an album selected */ - // THE TWO MessageBoxes - should be handled by disabling the Button!. - // TODO. - if (!mAlbumSelected) - { - // ALERT. - int ret = QMessageBox::information(this, tr("PhotoShare"), - tr("Please select an album before\n" - "requesting to edit it!"), - QMessageBox::Ok); - return; - } - - if (mAlbumSelected->mIsPhoto) - { - std::cerr << "PhotoDialog::OpenPhotoEditDialog() MAJOR ERROR!"; - std::cerr << std::endl; - } - - std::string albumId = mAlbumSelected->mAlbumDetails.mMeta.mGroupId; -#if 0 - uint32_t flags = mAlbumSelected->mAlbumDetails.mMeta.mGroupFlags; - - if (!(flags & OWN)) - { - // ALERT. - int ret = QMessageBox::information(this, tr("PhotoShare"), - tr("Cannot Edit Someone Else's Album"), - QMessageBox::Ok); - return; - } -#endif - - OpenOrShowPhotoAddDialog(); - mAddDialog->loadAlbum(albumId); } +/*************** Edit Photo Dialog ***************/ + bool PhotoDialog::matchesAlbumFilter(const RsPhotoAlbum &album) { @@ -292,13 +192,7 @@ void PhotoDialog::insertPhotosForSelectedAlbum() //std::list albumIds; if (mAlbumSelected) { - if (mAlbumSelected->mIsPhoto) - { - std::cerr << "PhotoDialog::insertPhotosForSelectedAlbum() MAJOR ERROR!"; - std::cerr << std::endl; - } - - std::string albumId = mAlbumSelected->mAlbumDetails.mMeta.mGroupId; + std::string albumId = mAlbumSelected->getAlbum().mMeta.mGroupId; //albumIds.push_back(albumId); std::cerr << "PhotoDialog::insertPhotosForSelectedAlbum() AlbumId: " << albumId; @@ -311,45 +205,9 @@ void PhotoDialog::insertPhotosForSelectedAlbum() void PhotoDialog::clearAlbums() { - std::cerr << "PhotoDialog::clearAlbums()" << std::endl; - std::list photoItems; - std::list::iterator pit; - - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - int count = alayout->count(); - for(int i = 0; i < count; i++) - { - QLayoutItem *litem = alayout->itemAt(i); - if (!litem) - { - std::cerr << "PhotoDialog::clearAlbums() missing litem"; - std::cerr << std::endl; - continue; - } - - PhotoItem *item = dynamic_cast(litem->widget()); - if (item) - { - std::cerr << "PhotoDialog::clearAlbums() item: " << item; - std::cerr << std::endl; - - photoItems.push_back(item); - } - else - { - std::cerr << "PhotoDialog::clearAlbums() Found Child, which is not a PhotoItem???"; - std::cerr << std::endl; - } - } - - for(pit = photoItems.begin(); pit != photoItems.end(); pit++) - { - PhotoItem *item = *pit; - alayout->removeWidget(item); - delete item; - } - mAlbumSelected = NULL; + std::cerr << "PhotoDialog::clearAlbums()" << std::endl; + } @@ -357,43 +215,7 @@ void PhotoDialog::clearPhotos() { std::cerr << "PhotoDialog::clearPhotos()" << std::endl; - std::list photoItems; - std::list::iterator pit; - - QLayout *alayout = ui.scrollAreaWidgetContents_2->layout(); - int count = alayout->count(); - for(int i = 0; i < count; i++) - { - QLayoutItem *litem = alayout->itemAt(i); - if (!litem) - { - std::cerr << "PhotoDialog::clearPhotos() missing litem"; - std::cerr << std::endl; - continue; - } - - PhotoItem *item = dynamic_cast(litem->widget()); - if (item) - { - std::cerr << "PhotoDialog::clearPhotos() item: " << item; - std::cerr << std::endl; - - photoItems.push_back(item); - } - else - { - std::cerr << "PhotoDialog::clearPhotos() Found Child, which is not a PhotoItem???"; - std::cerr << std::endl; - } - } - - for(pit = photoItems.begin(); pit != photoItems.end(); pit++) - { - PhotoItem *item = *pit; - alayout->removeWidget(item); - delete item; - } - + mPhotoSelected = NULL; @@ -403,7 +225,7 @@ void PhotoDialog::addAlbum(const RsPhotoAlbum &album) { std::cerr << " PhotoDialog::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; - PhotoItem *item = new PhotoItem(this, album); + AlbumItem *item = new AlbumItem(album, this); QLayout *alayout = ui.scrollAreaWidgetContents->layout(); alayout->addWidget(item); } @@ -415,23 +237,8 @@ void PhotoDialog::addPhoto(const RsPhotoPhoto &photo) std::cerr << " PhotoId: " << photo.mMeta.mMsgId; std::cerr << std::endl; - RsPhotoAlbum dummyAlbum; - dummyAlbum.mSetFlags = 0; - - PhotoItem *item = new PhotoItem(this, photo, dummyAlbum); - QLayout *alayout = ui.scrollAreaWidgetContents_2->layout(); - alayout->addWidget(item); - } -void PhotoDialog::deletePhotoItem(PhotoItem *item, uint32_t type) -{ - - - return; -} - - /**************************** Request / Response Filling of Data ************************/ @@ -484,37 +291,38 @@ void PhotoDialog::requestAlbumData(std::list &ids) bool PhotoDialog::loadAlbumData(const uint32_t &token) { - std::cerr << "PhotoDialog::loadAlbumData()"; - std::cerr << std::endl; + std::cerr << "PhotoDialog::loadAlbumData()"; + std::cerr << std::endl; - std::vector albums; - rsPhotoV2->getAlbum(token, albums); + std::vector albums; + rsPhotoV2->getAlbum(token, albums); - std::vector::iterator vit = albums.begin(); + std::vector::iterator vit = albums.begin(); - for(; vit != albums.end(); vit++) - { - RsPhotoAlbum& album = *vit; + for(; vit != albums.end(); vit++) + { + RsPhotoAlbum& album = *vit; - std::cerr << " PhotoDialog::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; + std::cerr << " PhotoDialog::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; - PhotoItem *item = new PhotoItem(this, album); - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - alayout->addWidget(item); - } - return true; + AlbumItem *item = new AlbumItem(album, this); + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); + alayout->addWidget(item); + } + return true; } void PhotoDialog::requestPhotoList(const std::string &albumId) { - GxsMsgReq req; - req[albumId] = std::vector(); - RsTokReqOptionsV2 opts; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - uint32_t token; - mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, req, 0); + std::list grpIds; + grpIds.push_back(albumId); + RsTokReqOptionsV2 opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST; + uint32_t token; + mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, grpIds, 0); } @@ -560,16 +368,16 @@ void PhotoDialog::loadPhotoList(const uint32_t &token) std::cerr << std::endl; GxsMsgIdResult res; - GxsMsgReq req; rsPhotoV2->getMsgList(token, res); - requestPhotoData(req); + requestPhotoData(res); } void PhotoDialog::requestPhotoData(GxsMsgReq &photoIds) { RsTokReqOptionsV2 opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; uint32_t token; mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, photoIds, 0); } @@ -602,7 +410,7 @@ void PhotoDialog::loadPhotoData(const uint32_t &token) } -/********************************/ +/**************************** Request / Response Filling of Data ************************/ void PhotoDialog::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req) { @@ -673,145 +481,3 @@ void PhotoDialog::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &r /**************************** Request / Response Filling of Data ************************/ - -// OLD STUFF THAT CANNOT BE USED WITH NEW REQ/RESP -#if 0 - - -void PhotoDialog::insertAlbums() -{ - /* clear it all */ - clearAlbums(); - //ui.albumLayout->clear(); - - /* create a list of albums */ - - - std::list albumIds; - std::list filteredAlbumIds; - std::list::iterator it; - - rsPhotoV2->getGroupList(token, al); - - /* Filter Albums */ /* Sort Albums */ -#define MAX_ALBUMS 50 - - int count = MAX_ALBUMS; - FilterNSortAlbums(albumIds, filteredAlbumIds, count); - - for(it = filteredAlbumIds.begin(); it != filteredAlbumIds.end(); it++) - { - addAlbum(*it); - } - - insertPhotosForAlbum(filteredAlbumIds); -} - -void PhotoDialog::insertPhotosForAlbum(const std::list &albumIds) -{ - /* clear it all */ - clearPhotos(); - //ui.photoLayout->clear(); - - /* create a list of albums */ - - std::list ids; - std::list photoIds; - std::list filteredPhotoIds; - std::list::const_iterator it; - - for(it = albumIds.begin(); it != albumIds.end(); it++) - { - rsPhoto->getPhotoList(*it, photoIds); - } - - /* Filter Albums */ /* Sort Albums */ -#define MAX_PHOTOS 50 - - int count = MAX_PHOTOS; - - FilterNSortPhotos(photoIds, filteredPhotoIds, MAX_PHOTOS); - - for(it = filteredPhotoIds.begin(); it != filteredPhotoIds.end(); it++) - { - addPhoto(*it); - } -} - - -void PhotoDialog::insertPhotosForSelectedAlbum() -{ - std::cerr << "PhotoDialog::insertPhotosForSelectedAlbum()"; - std::cerr << std::endl; - - clearPhotos(); - - std::list albumIds; - if (mAlbumSelected) - { - albumIds.push_back(mAlbumSelected->mDetails.mAlbumId); - - std::cerr << "PhotoDialog::insertPhotosForSelectedAlbum() AlbumId: " << mAlbumSelected->mDetails.mAlbumId; - std::cerr << std::endl; - } - - insertPhotosForAlbum(albumIds); -} - -bool PhotoDialog::FilterNSortAlbums(const std::list &albumIds, std::list &filteredAlbumIds, int count) -{ - std::multimap sortedAlbums; - std::multimap::iterator sit; - std::list::const_iterator it; - - for(it = albumIds.begin(); it != albumIds.end(); it++) - { - RsPhotoAlbum album; - rsPhoto->getAlbum(*it, album); - - if (matchesAlbumFilter(album)) - { - double score = AlbumScore(album); - - sortedAlbums.insert(std::make_pair(score, *it)); - } - } - - int i; - for (sit = sortedAlbums.begin(), i = 0; (sit != sortedAlbums.end()) && (i < count); sit++, i++) - { - filteredAlbumIds.push_back(sit->second); - } - - return true; -} - - -bool PhotoDialog::FilterNSortPhotos(const std::list &photoIds, std::list &filteredPhotoIds, int count) -{ - std::multimap sortedPhotos; - std::multimap::iterator sit; - std::list::const_iterator it; - - int i = 0; - for(it = photoIds.begin(); it != photoIds.end(); it++, i++) - { - RsPhotoPhoto photo; - rsPhoto->getPhoto(*it, photo); - - if (matchesPhotoFilter(photo)) - { - double score = i; //PhotoScore(album); - sortedPhotos.insert(std::make_pair(score, *it)); - } - } - - for (sit = sortedPhotos.begin(), i = 0; (sit != sortedPhotos.end()) && (i < count); sit++, i++) - { - filteredPhotoIds.push_back(sit->second); - } - return true; -} - -#endif - diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h index ca808afaf..8618055f6 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h @@ -26,33 +26,29 @@ #include "retroshare-gui/mainpage.h" #include "ui_PhotoDialog.h" +#include "AlbumCreateDialog.h" +#include "AlbumDialog.h" +#include "AlbumItem.h" +#include "PhotoItem.h" +#include "PhotoSlideShow.h" #include #include -#include "gui/PhotoShare/PhotoItem.h" -#include "gui/PhotoShare/PhotoAddDialog.h" -#include "gui/PhotoShare/PhotoSlideShow.h" #include "util/TokenQueueV2.h" -class PhotoDialog : public MainPage, public PhotoHolder, public TokenResponseV2 +class PhotoDialog : public MainPage, public TokenResponseV2 { Q_OBJECT public: - PhotoDialog(QWidget *parent = 0); - -virtual void deletePhotoItem(PhotoItem *, uint32_t type); -virtual void notifySelection(PhotoItem *item, int ptype); - - void notifyAlbumSelection(PhotoItem *item); - void notifyPhotoSelection(PhotoItem *item); + PhotoDialog(QWidget *parent = 0); private slots: void checkUpdate(); - void OpenOrShowPhotoAddDialog(); + void createAlbum(); void OpenPhotoEditDialog(); void OpenSlideShow(); private: @@ -84,11 +80,6 @@ private: /* Grunt work of setting up the GUI */ - //bool FilterNSortAlbums(const std::list &albumIds, std::list &filteredAlbumIds, int count); - //bool FilterNSortPhotos(const std::list &photoIds, std::list &filteredPhotoIds, int count); - //void insertAlbums(); - //void insertPhotosForAlbum(const std::list &albumIds); - void insertPhotosForSelectedAlbum(); void addAlbum(const RsPhotoAlbum &album); @@ -97,11 +88,12 @@ private: void clearAlbums(); void clearPhotos(); - PhotoAddDialog *mAddDialog; - PhotoSlideShow *mSlideShow; +private: - PhotoItem *mAlbumSelected; - PhotoItem *mPhotoSelected; + + AlbumItem* mAlbumSelected; + PhotoItem* mPhotoSelected; + PhotoSlideShow* mSlideShow; TokenQueueV2 *mPhotoQueue; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui index 30217f6c8..d189026c5 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui @@ -11,97 +11,31 @@
- + Photo Share - - - + + + - Filter + Slide Show - - - - - - - Source - - - - - Category - - - - - Rating - - - - - - - - - - - [ - ] - - - - - - - [ + ] - - - - + + + + View Album / Add Photos + + - - - - - - - Source - - - - - Category - - - - - Rating - - - - - - - - - - - [ - ] - - - - - - - [ + ] - - - - + + + + Create Album + + @@ -123,7 +57,7 @@ 0 0 754 - 234 + 277 @@ -166,7 +100,7 @@ 0 0 754 - 233 + 277 @@ -191,35 +125,8 @@
- - - - - - Slide Show - - - - - - - Edit Album - - - - - - - New Album - - - - -
- - - + diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog_v1.ui b/retroshare-gui/src/gui/PhotoShare/PhotoDialog_v1.ui deleted file mode 100644 index 3e44e7d1f..000000000 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog_v1.ui +++ /dev/null @@ -1,273 +0,0 @@ - - - PhotoDialog - - - - 0 - 0 - 774 - 608 - - - - - - - - - - - - Filter - - - - - - - - - - Source - - - - - Category - - - - - Rating - - - - - - - - - - - [ - ] - - - - - - - [ + ] - - - - - - - - - - - - Source - - - - - Category - - - - - Rating - - - - - - - - - - - [ - ] - - - - - - - [ + ] - - - - - - - - - - - Qt::Vertical - - - - true - - - Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - - - - - 0 - 0 - 746 - 227 - - - - QWidget#scrollAreaWidgetContents{border: none;} - - - - - - - - - Album 1 - - - - - - - Album 2 - - - - - - - Album 3 - - - - - - - Album 4 - - - - - - - Qt::Horizontal - - - - 139 - 20 - - - - - - - - - - true - - - Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - - - - - 0 - 0 - 746 - 227 - - - - QWidget#scrollAreaWidgetContents{border: none;} - - - - - - - - - PICTURE 1 - - - - - - - Qt::Horizontal - - - - 426 - 20 - - - - - - - - - - - - - - - Remove Picture - - - - - - - Slide Show - - - - - - - Edit Album - - - - - - - Edit Picture Details - - - - - - - New Album - - - - - - - - - - - - diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDrop.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDrop.cpp index 49a316963..fbd4c9a97 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDrop.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDrop.cpp @@ -64,23 +64,6 @@ PhotoDrop::PhotoDrop(QWidget *parent) reorderPhotos(); } -void PhotoDrop::notifySelection(PhotoItem *item, int ptype) -{ - std::cerr << "PhotoDrop::notifySelection() from : " << ptype << " " << item; - std::cerr << std::endl; - - if (mSelected) - { - std::cerr << "PhotoDrop::notifySelection() unselecting old one : " << mSelected; - std::cerr << std::endl; - - mSelected->setSelected(false); - } - - mSelected = item; - checkMoveButtons(); -} - void PhotoDrop::clear() { @@ -98,11 +81,6 @@ PhotoItem *PhotoDrop::getSelectedPhotoItem() } -void PhotoDrop::deletePhotoItem(PhotoItem *, uint32_t type) -{ - return; -} - void PhotoDrop::resizeEvent ( QResizeEvent * event ) { @@ -637,9 +615,7 @@ void PhotoDrop::dropEvent(QDropEvent *event) std::cerr << "Whole URL: " << uit->toString().toStdString() << std::endl; std::cerr << "or As Local File: " << localpath.toStdString() << std::endl; - PhotoItem *item = new PhotoItem(this, localpath.toStdString()); - addPhotoItem(item); //mPhotos.push_back(item); //layout()->addWidget(item); } @@ -683,7 +659,6 @@ void PhotoDrop::addPhotoItem(PhotoItem *item) clearPhotos(); } - item->updateParent(this); layout()->addWidget(item); //checkMoveButtons(); diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDrop.h b/retroshare-gui/src/gui/PhotoShare/PhotoDrop.h index 881cf9ccd..8fcbedcf9 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDrop.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDrop.h @@ -43,7 +43,7 @@ QT_END_NAMESPACE #define PHOTO_SHIFT_BOTH 3 -class PhotoDrop : public QWidget, public PhotoHolder +class PhotoDrop : public QWidget { Q_OBJECT @@ -52,9 +52,6 @@ public: void clear(); void setSingleImage(); -virtual void deletePhotoItem(PhotoItem *, uint32_t type); -virtual void notifySelection(PhotoItem *item, int ptype); - PhotoItem *getSelectedPhotoItem(); int getPhotoCount(); PhotoItem *getPhotoIdx(int idx); diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp index 1553dad7b..f2eb58349 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp @@ -1,282 +1,14 @@ -/* - * Retroshare Photo Plugin. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - -#include -#include -#include -#include - -#include "PhotoItem.h" - -#include - -#include -#include - -/**** - * #define DEBUG_ITEM 1 - ****/ - -/** Constructor */ -PhotoItem::PhotoItem(PhotoHolder *parent, const RsPhotoAlbum &album) -:QWidget(NULL), mParent(parent), mType(PHOTO_ITEM_TYPE_ALBUM) -{ - setupUi(this); - - setAttribute ( Qt::WA_DeleteOnClose, true ); - - mIsPhoto = false; - setDummyText(); - updateAlbumText(album); // saves: mAlbumDetails = album; - updateImage(album.mThumbnail); - - setSelected(false); -} - - -PhotoItem::PhotoItem(PhotoHolder *parent, const RsPhotoPhoto &photo, const RsPhotoAlbum &album) -:QWidget(NULL), mParent(parent), mType(PHOTO_ITEM_TYPE_PHOTO) -{ - setupUi(this); - - setAttribute ( Qt::WA_DeleteOnClose, true ); - - mIsPhoto = true; - - setDummyText(); - updatePhotoText(photo); // saves: mPhotoDetails = photo; - updateAlbumText(album); // saves: mAlbumDetails = album; - - updateImage(photo.mThumbnail); - - setSelected(false); -} - - -PhotoItem::PhotoItem(PhotoHolder *parent, std::string path) // for new photos. -:QWidget(NULL), mParent(parent), mType(PHOTO_ITEM_TYPE_NEW) -{ - setupUi(this); - - setAttribute ( Qt::WA_DeleteOnClose, true ); - - setDummyText(); - mIsPhoto = true; - - int width = 120; - int height = 120; - - //QPixmap qtn = QPixmap(QString::fromStdString(path)).scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - QPixmap qtn = QPixmap(QString::fromStdString(path)).scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation); - imgLabel->setPixmap(qtn); - setSelected(false); -} - -void PhotoItem::updateParent(PhotoHolder *parent) // for external construction. -{ - mParent = parent; -} - - -void PhotoItem::setDummyText() -{ - titleLabel->setText(QString("Unknown")); - fromBoldLabel->setText(QString("By:")); - fromLabel->setText(QString("Unknown")); - statusBoldLabel->setText(QString("Where:")); - statusLabel->setText(QString("Unknown")); - dateBoldLabel->setText(QString("When:")); - dateLabel->setText(QString("Unknown")); -} - - -void PhotoItem::updateAlbumText(const RsPhotoAlbum &album) -{ - mAlbumDetails = album; - mAlbumDetails.mThumbnail.data = 0; - updateText(); -} - -void PhotoItem::updatePhotoText(const RsPhotoPhoto &photo) -{ - // Save new Photo details. - mPhotoDetails = photo; - mPhotoDetails.mThumbnail.data = 0; - updateText(); -} - - - -void PhotoItem::updateText() -{ - // SET Album Values first -> then overwrite with Photo Values. - if (mAlbumDetails.mSetFlags & RSPHOTO_FLAGS_ATTRIB_TITLE) - { - titleLabel->setText(QString::fromUtf8(mAlbumDetails.mMeta.mGroupName.c_str())); - } - - // This needs to be fixed!! TODO - fromLabel->setText(QString::fromStdString(mAlbumDetails.mMeta.mGroupId)); - if (mAlbumDetails.mSetFlags & RSPHOTO_FLAGS_ATTRIB_AUTHOR) - { - // This needs to be fixed!! TODO - fromLabel->setText(QString::fromStdString(mAlbumDetails.mPhotographer)); - } - - if (mAlbumDetails.mSetFlags & RSPHOTO_FLAGS_ATTRIB_WHERE) - { - statusLabel->setText(QString::fromUtf8(mAlbumDetails.mWhere.c_str())); - } - - if (mAlbumDetails.mSetFlags & RSPHOTO_FLAGS_ATTRIB_WHEN) - { - dateLabel->setText(QString::fromUtf8(mAlbumDetails.mWhen.c_str())); - } - - // NOW Photo Bits. - if (mIsPhoto) - { - if (mPhotoDetails.mSetFlags & RSPHOTO_FLAGS_ATTRIB_TITLE) - { - titleLabel->setText(QString::fromUtf8(mPhotoDetails.mMeta.mMsgName.c_str())); - } - - if (mPhotoDetails.mSetFlags & RSPHOTO_FLAGS_ATTRIB_AUTHOR) - { - // This needs to be fixed!! TODO - fromLabel->setText(QString::fromStdString(mPhotoDetails.mMeta.mAuthorId)); - } - - if (mPhotoDetails.mSetFlags & RSPHOTO_FLAGS_ATTRIB_WHERE) - { - statusLabel->setText(QString::fromUtf8(mPhotoDetails.mWhere.c_str())); - } - - if (mPhotoDetails.mSetFlags & RSPHOTO_FLAGS_ATTRIB_WHEN) - { - dateLabel->setText(QString::fromUtf8(mPhotoDetails.mWhen.c_str())); - } - } - -} - -void PhotoItem::updateImage(const RsPhotoThumbnail &thumbnail) -{ - if (thumbnail.data != NULL) - { - QPixmap qtn; - qtn.loadFromData(thumbnail.data, thumbnail.size, thumbnail.type.c_str()); - imgLabel->setPixmap(qtn); - } -} - -bool PhotoItem::getPhotoThumbnail(RsPhotoThumbnail &nail) -{ - const QPixmap *tmppix = imgLabel->pixmap(); - - QByteArray ba; - QBuffer buffer(&ba); - - if(!tmppix->isNull()) - { - // send chan image - - buffer.open(QIODevice::WriteOnly); - tmppix->save(&buffer, "PNG"); // writes image into ba in PNG format - - RsPhotoThumbnail tmpnail; - tmpnail.data = (uint8_t *) ba.data(); - tmpnail.size = ba.size(); - - nail.copyFrom(tmpnail); - - return true; - } - - nail.data = NULL; - nail.size = 0; - return false; -} - - -void PhotoItem::removeItem() -{ -#ifdef DEBUG_ITEM - std::cerr << "PhotoItem::removeItem()"; - std::cerr << std::endl; -#endif - hide(); - if (mParent) - { - mParent->deletePhotoItem(this, mType); - } -} - - -void PhotoItem::setSelected(bool on) -{ - mSelected = on; - if (mSelected) - { - mParent->notifySelection(this, mType); - frame->setStyleSheet("QFrame#frame{border: 2px solid #55CC55;\nbackground: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #55EE55, stop: 1 #CCCCCC);\nborder-radius: 10px}"); - } - else - { - frame->setStyleSheet("QFrame#frame{border: 2px solid #CCCCCC;\nbackground: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #EEEEEE, stop: 1 #CCCCCC);\nborder-radius: 10px}"); - } - update(); -} - -bool PhotoItem::isSelected() -{ - return mSelected; -} - - -void PhotoItem::mousePressEvent(QMouseEvent *event) -{ - /* We can be very cunning here? - * grab out position. - * flag ourselves as selected. - * then pass the mousePressEvent up for handling by the parent - */ - - QPoint pos = event->pos(); - - std::cerr << "PhotoItem::mousePressEvent(" << pos.x() << ", " << pos.y() << ")"; - std::cerr << std::endl; - - setSelected(true); - - QWidget::mousePressEvent(event); -} - - -const QPixmap *PhotoItem::getPixmap() -{ - return imgLabel->pixmap(); -} - - +#include "PhotoItem.h" +#include "ui_PhotoItem.h" + +PhotoItem::PhotoItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhotoItem) +{ + ui->setupUi(this); +} + +PhotoItem::~PhotoItem() +{ + delete ui; +} diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoItem.h b/retroshare-gui/src/gui/PhotoShare/PhotoItem.h index 136c15015..8a3842fe9 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoItem.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoItem.h @@ -1,92 +1,22 @@ -/* - * Retroshare Photo Plugin. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#ifndef MRK_PHOTO_PHOTO_ITEM_H -#define MRK_PHOTO_PHOTO_ITEM_H - -#include "ui_PhotoItem.h" - -#include - -class PhotoItem; - -class PhotoHolder -{ - public: -virtual void deletePhotoItem(PhotoItem *, uint32_t ptype) = 0; -virtual void notifySelection(PhotoItem *item, int ptype) = 0; -}; - - -#define PHOTO_ITEM_TYPE_ALBUM 0x0001 -#define PHOTO_ITEM_TYPE_PHOTO 0x0002 -#define PHOTO_ITEM_TYPE_NEW 0x0003 - -class PhotoItem : public QWidget, private Ui::PhotoItem -{ - Q_OBJECT - -public: - PhotoItem(PhotoHolder *parent, const RsPhotoAlbum &album); - PhotoItem(PhotoHolder *parent, const RsPhotoPhoto &photo, const RsPhotoAlbum &album); - PhotoItem(PhotoHolder *parent, std::string url); // for new photos. - - void setDummyText(); - void updateParent(PhotoHolder *parent); // for external construction. - void updateAlbumText(const RsPhotoAlbum &album); - void updatePhotoText(const RsPhotoPhoto &photo); - void updateText(); - bool getPhotoThumbnail(RsPhotoThumbnail &nail); - - void removeItem(); - - void setSelected(bool on); - bool isSelected(); - - const QPixmap *getPixmap(); - - // details are public - so that can be easily edited. - bool mIsPhoto; - bool mWasModified; - RsPhotoPhoto mPhotoDetails; - RsPhotoAlbum mAlbumDetails; - -//private slots: - - -protected: - void mousePressEvent(QMouseEvent *event); - -private: - void updateImage(const RsPhotoThumbnail &thumbnail); - - PhotoHolder *mParent; - uint32_t mType; - - - bool mSelected; -}; - - -#endif - +#ifndef PHOTOITEM_H +#define PHOTOITEM_H + +#include + +namespace Ui { + class PhotoItem; +} + +class PhotoItem : public QWidget +{ + Q_OBJECT + +public: + explicit PhotoItem(QWidget *parent = 0); + ~PhotoItem(); + +private: + Ui::PhotoItem *ui; +}; + +#endif // PHOTOITEM_H diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoItem.ui b/retroshare-gui/src/gui/PhotoShare/PhotoItem.ui index 8b7e990d9..bf6a3fe19 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoItem.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoItem.ui @@ -6,242 +6,75 @@ 0 0 - 166 - 216 + 253 + 222 - - - 9 - - - + Form - - - 6 - - - - - - 0 - 0 - + + + + + TextLabel - - QFrame#frame{border: 2px solid #CCCCCC; -background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #EEEEEE, stop: 1 #CCCCCC); -border-radius: 10px} - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - - - - 150 - 150 - - - - - 150 - 150 - - - - QLabel#label{border: 2px solid black; -background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #EEEEEE, stop: 1 #CCCCCC); -border-radius: 10px} - - - - - - :/images/konversation.png - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - - 9 - 75 - true - - - - Album: - - - - - - - - - - 0 - 0 - - - - - 9 - 75 - true - - - - From - - - - - - - - 0 - 0 - - - - - 9 - - - - Signed by - - - true - - - - - - - - - - - - 0 - 0 - - - - - 9 - 75 - true - - - - Status - - - - - - - - 0 - 0 - - - - - 9 - - - - You eyes only - - - true - - - - - - - - - - - - 0 - 0 - - - - - 9 - 75 - true - - - - Date - - - - - - - - 0 - 0 - - - - - 9 - - - - You eyes only - - - true - - - - - - + + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Photo Title:</span></p></body></html> + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Photographer:</span></p></body></html> + + + + + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + + + - - - + diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoSlideDetails.ui b/retroshare-gui/src/gui/PhotoShare/PhotoSlideDetails.ui deleted file mode 100644 index 985d7bd4d..000000000 --- a/retroshare-gui/src/gui/PhotoShare/PhotoSlideDetails.ui +++ /dev/null @@ -1,129 +0,0 @@ - - - PhotoSlideDetails - - - - 0 - 0 - 667 - 707 - - - - - - - - - - Qt::Vertical - - - - - - - Name - - - - - - - Caption: - - - - - - - - - - Photographer: - - - - - - - - - - Description - - - - - - - - - - Where: - - - - - - - - - - When - - - - - - - - - - Other 1: - - - - - - - - - - HashTags: - - - - - - - - - - Image # - - - - - - - - - - - - - - - - - - - - - - - - - From 9f20c75f83cdf6685169c174d5f2d4856fd46d4a Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Thu, 13 Sep 2012 22:58:42 +0000 Subject: [PATCH 060/222] about 70% done with PhotoDialog - can add album (with thumbnail!) - add photo (with photo!) - can subscribe, but not added to ui yet need to try some dummy msgs and bring up gxs_net git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5549 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgenexchange.cc | 3 + libretroshare/src/gxs/rsgxsflags.h | 10 +- libretroshare/src/gxs/rsgxsnetservice.cc | 2 +- libretroshare/src/retroshare/rsphotoV2.h | 39 +- libretroshare/src/rsserver/rsinit.cc | 4 + .../src/services/p3photoserviceV2.cc | 9 + libretroshare/src/services/p3photoserviceV2.h | 23 +- retroshare-gui/src/RetroShare.pro | 120 +++--- .../src/gui/PhotoShare/AlbumCreateDialog.cpp | 33 ++ .../src/gui/PhotoShare/AlbumCreateDialog.h | 3 + .../src/gui/PhotoShare/AlbumCreateDialog.ui | 14 + .../src/gui/PhotoShare/AlbumDialog.cpp | 80 +++- .../src/gui/PhotoShare/AlbumDialog.h | 25 +- .../src/gui/PhotoShare/AlbumDialog.ui | 349 +++++++++++++++++- .../src/gui/PhotoShare/AlbumItem.cpp | 38 +- retroshare-gui/src/gui/PhotoShare/AlbumItem.h | 13 +- .../src/gui/PhotoShare/AlbumItem.ui | 135 ++++--- .../src/gui/PhotoShare/PhotoDialog.cpp | 297 +++++++++++---- .../src/gui/PhotoShare/PhotoDialog.h | 35 +- .../src/gui/PhotoShare/PhotoDialog.ui | 72 +++- .../src/gui/PhotoShare/PhotoDrop.cpp | 36 +- retroshare-gui/src/gui/PhotoShare/PhotoDrop.h | 24 +- .../src/gui/PhotoShare/PhotoItem.cpp | 145 +++++++- retroshare-gui/src/gui/PhotoShare/PhotoItem.h | 34 +- .../src/gui/PhotoShare/PhotoItem.ui | 136 ++++--- .../src/gui/PhotoShare/PhotoShare.cpp | 14 + .../src/gui/PhotoShare/PhotoShare.h | 22 ++ .../src/gui/PhotoShare/PhotoShare.ui | 21 ++ .../gui/PhotoShare/PhotoShareItemHolder.cpp | 5 + .../src/gui/PhotoShare/PhotoShareItemHolder.h | 22 ++ .../src/gui/TheWire/PulseAddDialog.cpp | 1 - retroshare-gui/src/util/TokenQueueV2.cpp | 20 + retroshare-gui/src/util/TokenQueueV2.h | 20 +- 33 files changed, 1493 insertions(+), 311 deletions(-) create mode 100644 retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp create mode 100644 retroshare-gui/src/gui/PhotoShare/PhotoShare.h create mode 100644 retroshare-gui/src/gui/PhotoShare/PhotoShare.ui create mode 100644 retroshare-gui/src/gui/PhotoShare/PhotoShareItemHolder.cpp create mode 100644 retroshare-gui/src/gui/PhotoShare/PhotoShareItemHolder.h diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index ff39da0ff..42b36191f 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -632,6 +632,9 @@ void RsGenExchange::publishGrps() size = grp->metaData->serial_size(); char mData[size]; grp->metaData->mGroupId = grp->grpId; + + // indicate user is admin through local subscribe flag + grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; ok = grp->metaData->serialise(mData, size); grp->meta.setBinData(mData, size); diff --git a/libretroshare/src/gxs/rsgxsflags.h b/libretroshare/src/gxs/rsgxsflags.h index d124bde5f..a215a8809 100644 --- a/libretroshare/src/gxs/rsgxsflags.h +++ b/libretroshare/src/gxs/rsgxsflags.h @@ -54,11 +54,11 @@ namespace GXS_SERV { // Subscription Flags. (LOCAL) - static const uint32_t RSGXS_GROUP_SUBSCRIBE_ADMIN = 0x00000001; - static const uint32_t RSGXS_GROUP_SUBSCRIBE_PUBLISH = 0x00000002; - static const uint32_t RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED = 0x00000004; - static const uint32_t RSGXS_GROUP_SUBSCRIBE_MONITOR = 0x00000008; - static const uint32_t RSGXS_GROUP_SUBSCRIBE_MASK = 0x0000000f; + static const uint32_t GROUP_SUBSCRIBE_ADMIN = 0x00000001; + static const uint32_t GROUP_SUBSCRIBE_PUBLISH = 0x00000002; + static const uint32_t GROUP_SUBSCRIBE_SUBSCRIBED = 0x00000004; + static const uint32_t GROUP_SUBSCRIBE_MONITOR = 0x00000008; + static const uint32_t GROUP_SUBSCRIBE_MASK = 0x0000000f; } diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 875f42b48..19e22ca0f 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -98,7 +98,7 @@ void RsGxsNetService::syncWithPeers() { RsGxsGrpMetaData* meta = mit->second; - if(meta->mSubscribeFlags & GXS_SERV::RSGXS_GROUP_SUBSCRIBE_MASK) + if(meta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_MASK) grpIds.push_back(mit->first); } diff --git a/libretroshare/src/retroshare/rsphotoV2.h b/libretroshare/src/retroshare/rsphotoV2.h index c7d1c0936..60b095e77 100644 --- a/libretroshare/src/retroshare/rsphotoV2.h +++ b/libretroshare/src/retroshare/rsphotoV2.h @@ -254,24 +254,29 @@ public: /* details are updated in album - to choose Album ID, and storage path */ - /*! - * This RsGenExchange service will be alerted to this album as \n - * a new album. Do not keep the submitted album as representative, wait for - * notification telling of successful submission - * @param album The album to be submitted - * @return false if submission failed - */ - virtual bool submitAlbumDetails(uint32_t& token, RsPhotoAlbum &album) = 0; + /*! + * submits album, which returns a token that needs + * to be acknowledge to get album grp id + * @param token token to redeem for acknowledgement + * @param album album to be submitted + */ + virtual bool submitAlbumDetails(uint32_t& token, RsPhotoAlbum &album) = 0; - /*! - * This RsGenExchange service will be alerted to this photo as \n - * a new photo. Do not keep the submitted photo as representative, wait for new photo - * returned - * @param photo photo to submit - * @return - */ - virtual bool submitPhoto(uint32_t& token, RsPhotoPhoto &photo) = 0; + /*! + * submits photo, which returns a token that needs + * to be acknowledge to get photo msg-grp id pair + * @param token token to redeem for acknowledgement + * @param photo photo to be submitted + */ + virtual bool submitPhoto(uint32_t& token, RsPhotoPhoto &photo) = 0; + /*! + * subscribes to group, and returns token which can be used + * to be acknowledged to get group Id + * @param token token to redeem for acknowledgement + * @param grpId the id of the group to subscribe to + */ + virtual bool subscribeToAlbum(uint32_t& token, const RsGxsGroupId& grpId) = 0; /*! * This allows the client service to acknowledge that their msgs has @@ -282,6 +287,8 @@ public: */ virtual bool acknowledgeMsg(const uint32_t& token, std::pair& msgId) = 0; + + /*! * This allows the client service to acknowledge that their grps has * been created/modified and retrieve the create/modified grp ids diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index c708eb0de..14e0a7c2b 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -2295,6 +2295,10 @@ int RsServer::StartupRetroShare() // start up gxs core server createThread(*mGxsCore); + + // create some dummy items + + #endif #ifdef ENABLE_GXS_SERVICES diff --git a/libretroshare/src/services/p3photoserviceV2.cc b/libretroshare/src/services/p3photoserviceV2.cc index a460ff3b7..142234eab 100644 --- a/libretroshare/src/services/p3photoserviceV2.cc +++ b/libretroshare/src/services/p3photoserviceV2.cc @@ -1,5 +1,6 @@ #include "p3photoserviceV2.h" #include "serialiser/rsphotov2items.h" +#include "gxs/rsgxsflags.h" RsPhotoV2 *rsPhotoV2 = NULL; @@ -7,6 +8,7 @@ p3PhotoServiceV2::p3PhotoServiceV2(RsGeneralDataService* gds, RsNetworkExchangeS : RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_TYPE_PHOTO) { + } bool p3PhotoServiceV2::updated() @@ -146,6 +148,13 @@ bool p3PhotoServiceV2::submitAlbumDetails(uint32_t& token, RsPhotoAlbum& album) return true; } +bool p3PhotoServiceV2::subscribeToAlbum(uint32_t &token, const RsGxsGroupId &grpId) +{ + + RsGenExchange::setGroupSubscribeFlag(token, grpId, GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED); + return true; +} + void p3PhotoServiceV2::notifyChanges(std::vector& changes) diff --git a/libretroshare/src/services/p3photoserviceV2.h b/libretroshare/src/services/p3photoserviceV2.h index 50a597d3b..a55e4f710 100644 --- a/libretroshare/src/services/p3photoserviceV2.h +++ b/libretroshare/src/services/p3photoserviceV2.h @@ -39,7 +39,7 @@ public: public: /*! - * @return + * @return true if a change has occured */ bool updated(); @@ -78,9 +78,30 @@ public: /** Modifications **/ + /*! + * submits album, which returns a token that needs + * to be acknowledge to get album grp id + * @param token token to redeem for acknowledgement + * @param album album to be submitted + */ bool submitAlbumDetails(uint32_t& token, RsPhotoAlbum &album); + + /*! + * submits photo, which returns a token that needs + * to be acknowledge to get photo msg-grp id pair + * @param token token to redeem for acknowledgement + * @param photo photo to be submitted + */ bool submitPhoto(uint32_t& token, RsPhotoPhoto &photo); + /*! + * subscribes to group, and returns token which can be used + * to be acknowledged to get group Id + * @param token token to redeem for acknowledgement + * @param grpId the id of the group to subscribe to + */ + bool subscribeToAlbum(uint32_t& token, const RsGxsGroupId& grpId); + /*! * This allows the client service to acknowledge that their msgs has * been created/modified and retrieve the create/modified msg ids diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index 1c1e5c64f..70ae08b12 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -27,7 +27,7 @@ RCC_DIR = temp/qrc UI_DIR = temp/ui MOC_DIR = temp/moc -#CONFIG += debug +CONFIG += debug debug { QMAKE_CFLAGS += -g QMAKE_CXXFLAGS -= -O2 @@ -108,45 +108,46 @@ win32-x-g++ { #################################### Windows ##################################### win32 { - # Switch on extra warnings - QMAKE_CFLAGS += -Wextra - QMAKE_CXXFLAGS += -Wextra - # Switch off optimization for release version - QMAKE_CXXFLAGS_RELEASE -= -O2 - QMAKE_CXXFLAGS_RELEASE += -O0 - QMAKE_CFLAGS_RELEASE -= -O2 - QMAKE_CFLAGS_RELEASE += -O0 + # Switch on extra warnings + QMAKE_CFLAGS += -Wextra + QMAKE_CXXFLAGS += -Wextra - # Switch on optimization for debug version - #QMAKE_CXXFLAGS_DEBUG += -O2 - #QMAKE_CFLAGS_DEBUG += -O2 + # Switch off optimization for release version + QMAKE_CXXFLAGS_RELEASE -= -O2 + QMAKE_CXXFLAGS_RELEASE += -O0 + QMAKE_CFLAGS_RELEASE -= -O2 + QMAKE_CFLAGS_RELEASE += -O0 - OBJECTS_DIR = temp/obj - #LIBS += -L"D/Qt/2009.03/qt/plugins/imageformats" - #QTPLUGIN += qjpeg + # Switch on optimization for debug version + #QMAKE_CXXFLAGS_DEBUG += -O2 + #QMAKE_CFLAGS_DEBUG += -O2 - PRE_TARGETDEPS += ../../libretroshare/src/lib/libretroshare.a +# PRE_TARGETDEPS += ../../libretroshare/src/lib/libretroshare.a + PRE_TARGETDEPS += ../../libretroshare/libretroshare-build-desktop/lib/libretroshare.a - LIBS += ../../libretroshare/src/lib/libretroshare.a - LIBS += ../../openpgpsdk/src/lib/libops.a -lbz2 - LIBS += -L"../../../lib" - LIBS += -lssl -lcrypto -lpthreadGC2d -lminiupnpc -lz + LIBS += ../../libretroshare/libretroshare-build-desktop/lib/libretroshare.a + LIBS += C:\Development\Rs\v0.5-gxs-b1\openpgpsdk\openpgpsdk-build-desktop\lib\libops.a + LIBS += C:\Development\Libraries\sqlite\sqlite-autoconf-3070900\lib\libsqlite3.a + LIBS += -L"../../../lib" + LIBS += -lssl -lcrypto -lgpgme -lpthreadGC2d -lminiupnpc -lz -lbz2 # added after bitdht -# LIBS += -lws2_32 - LIBS += -luuid -lole32 -liphlpapi -lcrypt32-cygwin -lgdi32 - LIBS += -lole32 -lwinmm - RC_FILE = gui/images/retroshare_win.rc +# LIBS += -lws2_32 + LIBS += -luuid -lole32 -liphlpapi -lcrypt32-cygwin -lgdi32 + LIBS += -lole32 -lwinmm + RC_FILE = gui/images/retroshare_win.rc - # export symbols for the plugins - LIBS += -Wl,--export-all-symbols,--out-implib,lib/libretroshare-gui.a + # export symbols for the plugins + #LIBS += -Wl,--export-all-symbols,--out-implib,lib/libretroshare-gui.a + + GPG_ERROR_DIR = ../../../../libgpg-error-1.7 + GPGME_DIR = ../../../../gpgme-1.1.8 + GPG_ERROR_DIR = ../../../../lib/libgpg-error-1.7 + GPGME_DIR = ../../../../lib/gpgme-1.1.8 + INCLUDEPATH += . $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src - # create lib directory - QMAKE_PRE_LINK = $(CHK_DIR_EXISTS) lib $(MKDIR) lib - DEFINES += WINDOWS_SYS - INCLUDEPATH += . } ##################################### MacOS ###################################### @@ -192,8 +193,8 @@ freebsd-* { # ########################################### bitdht { - LIBS += ../../libbitdht/src/lib/libbitdht.a - PRE_TARGETDEPS *= ../../libbitdht/src/lib/libbitdht.a + LIBS += ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a + PRE_TARGETDEPS *= ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a } win32 { @@ -414,6 +415,7 @@ HEADERS += rshare.h \ gui/GetStartedDialog.h + FORMS += gui/StartDialog.ui \ gui/GenCertDialog.ui \ gui/AboutDialog.ui \ @@ -513,7 +515,7 @@ FORMS += gui/StartDialog.ui \ gui/style/StyleDialog.ui \ gui/dht/DhtWindow.ui \ gui/bwctrl/BwCtrlWindow.ui \ - gui/GetStartedDialog.ui + gui/GetStartedDialog.ui \ SOURCES += main.cpp \ rshare.cpp \ @@ -695,6 +697,7 @@ SOURCES += main.cpp \ gui/bwctrl/BwCtrlWindow.cpp \ gui/GetStartedDialog.cpp + RESOURCES += gui/images.qrc lang/lang.qrc gui/help/content/content.qrc TRANSLATIONS += \ @@ -854,28 +857,43 @@ SOURCES += gui/unfinished/ApplicationWindow.cpp \ photoshare { - HEADERS += gui/PhotoShare/PhotoItem.h \ - gui/PhotoShare/PhotoDialog.h \ - gui/PhotoShare/PhotoAddDialog.h \ - gui/PhotoShare/PhotoDetailsDialog.h \ + HEADERS += \ + gui/PhotoShare/PhotoDialog.h \ gui/PhotoShare/PhotoDrop.h \ gui/PhotoShare/PhotoSlideShow.h \ - util/TokenQueueV2.h \ + util/TokenQueueV2.h \ + gui/PhotoShare/AlbumDialog.h \ + gui/PhotoShare/AlbumItem.h \ + gui/PhotoShare/PhotoItem.h \ + gui/PhotoShare/AlbumCreateDialog.h \ + gui/PhotoShare/PhotoShareItemHolder.h \ + gui/PhotoShare/PhotoShare.h - FORMS += gui/PhotoShare/PhotoItem.ui \ - gui/PhotoShare/PhotoDialog.ui \ - gui/PhotoShare/PhotoAddDialog.ui \ - gui/PhotoShare/PhotoDetailsDialog.ui \ - gui/PhotoShare/PhotoSlideShow.ui \ - - SOURCES += gui/PhotoShare/PhotoItem.cpp \ - gui/PhotoShare/PhotoDialog.cpp \ - gui/PhotoShare/PhotoAddDialog.cpp \ - gui/PhotoShare/PhotoDetailsDialog.cpp \ +#gui/PhotoShare/PhotoDetailsDialog.h \ +# gui/PhotoShare/PhotoAddDialog.h \ + FORMS += \ + gui/PhotoShare/PhotoDialog.ui \ + gui/PhotoShare/PhotoSlideShow.ui \ + gui/PhotoShare/AlbumItem.ui \ + gui/PhotoShare/AlbumDialog.ui \ + gui/PhotoShare/PhotoItem.ui \ + gui/PhotoShare/AlbumCreateDialog.ui \ + gui/PhotoShare/PhotoShare.ui +# gui/PhotoShare/PhotoAddDialog.ui \1 +# gui/PhotoShare/PhotoDetailsDialog.ui \ + SOURCES += \ + gui/PhotoShare/PhotoDialog.cpp \ gui/PhotoShare/PhotoDrop.cpp \ gui/PhotoShare/PhotoSlideShow.cpp \ - util/TokenQueueV2.cpp \ - + gui/PhotoShare/AlbumDialog.cpp \ + util/TokenQueueV2.cpp \ + gui/PhotoShare/AlbumItem.cpp \ + gui/PhotoShare/PhotoItem.cpp \ + gui/PhotoShare/AlbumCreateDialog.cpp \ + gui/PhotoShare/PhotoShareItemHolder.cpp \ + gui/PhotoShare/PhotoShare.cpp +# gui/PhotoShare/PhotoAddDialog.cpp \ +# gui/PhotoShare/PhotoDetailsDialog.cpp \ } @@ -922,7 +940,7 @@ identities { FORMS += gui/Identity/IdDialog.ui \ gui/Identity/IdEditDialog.ui \ - SOURCES += util/TokenQueue.cpp \ + SOURCES += util/TokenQueue.cpp \ gui/Identity/IdDialog.cpp \ gui/Identity/IdEditDialog.cpp \ diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp index 63611383e..e40a46020 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp @@ -1,3 +1,5 @@ +#include + #include "AlbumCreateDialog.h" #include "ui_AlbumCreateDialog.h" @@ -10,6 +12,7 @@ AlbumCreateDialog::AlbumCreateDialog(TokenQueueV2 *photoQueue, RsPhotoV2 *rs_pho ui->setupUi(this); connect(ui->publishButton, SIGNAL(clicked()), this, SLOT(publishAlbum())); + connect(ui->AlbumThumbNail, SIGNAL(clicked()), this, SLOT(addAlbumThumbnail())); } AlbumCreateDialog::~AlbumCreateDialog() @@ -27,6 +30,8 @@ void AlbumCreateDialog::publishAlbum() album.mMeta.mGroupName = ui->lineEdit_Title_2->text().toStdString(); album.mDescription = ui->textEdit_Description->toPlainText().toStdString(); album.mWhere = ui->lineEdit_Where->text().toStdString(); + album.mPhotographer = ui->lineEdit_Photographer->text().toStdString(); + getAlbumThumbnail(album.mThumbnail); uint32_t token; mRsPhoto->submitAlbumDetails(token, album); @@ -34,6 +39,34 @@ void AlbumCreateDialog::publishAlbum() close(); } +bool AlbumCreateDialog::getAlbumThumbnail(RsPhotoThumbnail &nail) +{ + const QPixmap *tmppix = &mThumbNail; + + QByteArray ba; + QBuffer buffer(&ba); + + if(!tmppix->isNull()) + { + // send chan image + + buffer.open(QIODevice::WriteOnly); + tmppix->save(&buffer, "PNG"); // writes image into ba in PNG format + + RsPhotoThumbnail tmpnail; + tmpnail.data = (uint8_t *) ba.data(); + tmpnail.size = ba.size(); + + nail.copyFrom(tmpnail); + + return true; + } + + nail.data = NULL; + nail.size = 0; + return false; +} + void AlbumCreateDialog::addAlbumThumbnail() { QPixmap img = misc::getOpenThumbnailedPicture(this, tr("Load Album Thumbnail"), 64, 64); diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.h b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.h index d140432c7..d1562db69 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.h @@ -22,6 +22,9 @@ private slots: void publishAlbum(); void addAlbumThumbnail(); +private: + + bool getAlbumThumbnail(RsPhotoThumbnail &nail); private: Ui::AlbumCreateDialog *ui; diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui index 035d084d5..52e3c5d70 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui @@ -122,6 +122,13 @@ border-radius: 10px; + + + + Qt::Horizontal + + + @@ -166,6 +173,13 @@ border-radius: 10px; + + + + Qt::Horizontal + + + diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp index be101b354..301ac7671 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp @@ -1,14 +1,90 @@ +#include + #include "AlbumDialog.h" #include "ui_AlbumDialog.h" -AlbumDialog::AlbumDialog(QWidget *parent) : +AlbumDialog::AlbumDialog(const RsPhotoAlbum& album, TokenQueueV2* photoQueue, RsPhotoV2* rs_Photo, QWidget *parent) : QWidget(parent), - ui(new Ui::AlbumDialog) + ui(new Ui::AlbumDialog), mPhotoQueue(photoQueue), mRsPhoto(rs_Photo), mAlbum(album), mPhotoSelected(NULL) { ui->setupUi(this); + setAttribute ( Qt::WA_DeleteOnClose, true ); + + connect(ui->pushButton_PublishPhotos, SIGNAL(clicked()), this, SLOT(updateAlbumPhotos())); + connect(ui->pushButton_DeletePhoto, SIGNAL(clicked()), this, SLOT(deletePhoto())); + + mPhotoDrop = ui->scrollAreaWidgetContents; + mPhotoDrop->setPhotoItemHolder(this); + + setUp(); +} + + +void AlbumDialog::setUp() +{ + ui->lineEdit_Title->setText(QString::fromStdString(mAlbum.mMeta.mGroupName)); + ui->lineEdit_Caption->setText(QString::fromStdString(mAlbum.mCaption)); + ui->lineEdit_Category->setText(QString::fromStdString(mAlbum.mCategory)); + ui->lineEdit_Identity->setText(QString::fromStdString(mAlbum.mMeta.mAuthorId)); + + QPixmap qtn; + qtn.loadFromData(mAlbum.mThumbnail.data, mAlbum.mThumbnail.size, mAlbum.mThumbnail.type.c_str()); + ui->label_thumbNail->setPixmap(qtn); +} + +void AlbumDialog::updateAlbumPhotos(){ + QSet photos; + + mPhotoDrop->getPhotos(photos); + + QSetIterator sit(photos); + + while(sit.hasNext()) + { + PhotoItem* item = sit.next(); + uint32_t token; + RsPhotoPhoto photo = item->getPhotoDetails(); + photo.mMeta.mGroupId = mAlbum.mMeta.mGroupId; + mRsPhoto->submitPhoto(token, photo); + mPhotoQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); + } + close(); +} + +void AlbumDialog::deletePhoto(){ + + if(mPhotoSelected) + { + mPhotoSelected->setSelected(false); + mPhotoDrop->deletePhoto(mPhotoSelected); + } + +} + +void AlbumDialog::editPhoto() +{ + } AlbumDialog::~AlbumDialog() { delete ui; } + +void AlbumDialog::notifySelection(PhotoShareItem *selection) +{ + + PhotoItem* pItem = dynamic_cast(selection); + + if(mPhotoSelected == NULL) + { + return; + } + else + { + mPhotoSelected->setSelected(false); + mPhotoSelected = pItem; + } + + mPhotoSelected->setSelected(true); +} diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h index 9d56bd79a..73c58a2b5 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h @@ -2,21 +2,42 @@ #define ALBUMDIALOG_H #include +#include "retroshare/rsphotoV2.h" +#include "util/TokenQueueV2.h" +#include "PhotoShareItemHolder.h" +#include "PhotoItem.h" +#include "PhotoDrop.h" namespace Ui { class AlbumDialog; } -class AlbumDialog : public QWidget +class AlbumDialog : public QWidget, public PhotoShareItemHolder { Q_OBJECT public: - explicit AlbumDialog(QWidget *parent = 0); + explicit AlbumDialog(const RsPhotoAlbum& album, TokenQueueV2* photoQueue, RsPhotoV2* rs_Photo, QWidget *parent = 0); ~AlbumDialog(); + void notifySelection(PhotoShareItem* selection); + +private: + + void setUp(); + +private slots: + + void updateAlbumPhotos(); + void deletePhoto(); + void editPhoto(); private: Ui::AlbumDialog *ui; + RsPhotoV2* mRsPhoto; + TokenQueueV2* mPhotoQueue; + RsPhotoAlbum mAlbum; + PhotoDrop* mPhotoDrop; + PhotoItem* mPhotoSelected; }; #endif // ALBUMDIALOG_H diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui index 2cce7089f..a7f38e867 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui @@ -1,21 +1,358 @@ + - - - AlbumDialog 0 0 - 400 - 300 + 649 + 436 Form + + + + + Qt::Vertical + + + + + + + + 0 + 1 + + + + Album Thumbnail + + + + + + TextLabel + + + + + + + + + + + 10 + 1 + + + + Summary + + + + + + false + + + + 0 + 0 + + + + + + + + Category: + + + + + + + Caption + + + + + + + false + + + + 0 + 0 + + + + + + + + Where: + + + + + + + false + + + + 0 + 0 + + + + + + + + false + + + + 0 + 0 + + + + + + + + Album Title: + + + + + + + When + + + + + + + false + + + + 0 + 0 + + + + + + + + + + + + + + 10 + 1 + + + + Share Options + + + + + + false + + + + 0 + 0 + + + + + + + + Comments + + + + + + + Publish Identity + + + + + + + false + + + + 0 + 0 + + + + + + + + Visibility + + + + + + + false + + + + 0 + 0 + + + + + + + + + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;"> Drag &amp; Drop to insert pictures. Click on a picture to edit details below.</span></p></body></html> + + + + + + + + 0 + 10 + + + + true + + + Qt::ScrollBarAsNeeded + + + true + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + 0 + 0 + 627 + 116 + + + + QWidget#scrollAreaWidgetContents{border: none;} + + + + + + + + + + + + + + + Delete Photo + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Edit Photo + + + + + + + Qt::Horizontal + + + + 68 + 17 + + + + + + + + Publish Photos + + + + + + - + + + PhotoDrop + QWidget +
gui/PhotoShare/PhotoDrop.h
+ 1 +
+
+
diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumItem.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumItem.cpp index 387b28d51..1eff4ef9c 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumItem.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumItem.cpp @@ -1,9 +1,12 @@ #include "AlbumItem.h" #include "ui_AlbumItem.h" +#include -AlbumItem::AlbumItem(const RsPhotoAlbum& album, QWidget *parent) : - QWidget(parent), - ui(new Ui::AlbumItem), mAlbum(album) +#include + +AlbumItem::AlbumItem(const RsPhotoAlbum &album, PhotoShareItemHolder *albumHolder, QWidget *parent) : + QWidget(NULL), + ui(new Ui::AlbumItem), mAlbum(album), mAlbumHolder(albumHolder) { ui->setupUi(this); setUp(); @@ -23,6 +26,35 @@ void AlbumItem::setUp() ui->label_Thumbnail->setPixmap(qtn); } +void AlbumItem::mousePressEvent(QMouseEvent *event) +{ + QPoint pos = event->pos(); + + std::cerr << "AlbumItem::mousePressEvent(" << pos.x() << ", " << pos.y() << ")"; + std::cerr << std::endl; + + if(mAlbumHolder) + mAlbumHolder->notifySelection(this); + else + setSelected(true); + + QWidget::mousePressEvent(event); +} + +void AlbumItem::setSelected(bool on) +{ + mSelected = on; + if (mSelected) + { + ui->albumFrame->setStyleSheet("QFrame#albumFrame{border: 2px solid #55CC55;\nbackground: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #55EE55, stop: 1 #CCCCCC);\nborder-radius: 10px}"); + } + else + { + ui->albumFrame->setStyleSheet("QFrame#albumFrame{border: 2px solid #CCCCCC;\nbackground: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #EEEEEE, stop: 1 #CCCCCC);\nborder-radius: 10px}"); + } + update(); +} + RsPhotoAlbum AlbumItem::getAlbum() { return mAlbum; diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumItem.h b/retroshare-gui/src/gui/PhotoShare/AlbumItem.h index 1da374767..8f862dc9c 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumItem.h +++ b/retroshare-gui/src/gui/PhotoShare/AlbumItem.h @@ -4,26 +4,35 @@ #include #include "string.h" #include "retroshare/rsphotoV2.h" +#include "PhotoShareItemHolder.h" namespace Ui { class AlbumItem; } -class AlbumItem : public QWidget +class AlbumItem : public QWidget, public PhotoShareItem { Q_OBJECT public: - explicit AlbumItem(const RsPhotoAlbum& album, QWidget *parent = 0); + explicit AlbumItem(const RsPhotoAlbum& album, PhotoShareItemHolder* albumHolder, QWidget *parent = 0); ~AlbumItem(); RsPhotoAlbum getAlbum(); + bool isSelected() { return mSelected ;} + void setSelected(bool selected); + +protected: + void mousePressEvent(QMouseEvent *event); + private: void setUp(); private: Ui::AlbumItem *ui; RsPhotoAlbum mAlbum; + PhotoShareItemHolder* mAlbumHolder; + bool mSelected; }; #endif // ALBUMITEM_H diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumItem.ui b/retroshare-gui/src/gui/PhotoShare/AlbumItem.ui index a66fd9d90..0ab51b8d4 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumItem.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumItem.ui @@ -6,8 +6,8 @@ 0 0 - 221 - 224 + 229 + 234 @@ -15,64 +15,85 @@ - - - TextLabel + + + QFrame#albumFrame{border: 2px solid #CCCCCC; +background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0 #EEEEEE, stop: 1 #CCCCCC); +border-radius: 10px} + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + TextLabel + + + + + + + + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Album Title :</span></p></body></html> + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Photographer :</span></p></body></html> + + + + + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + + + + - - - - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Album Title:</span></p></body></html> - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Photographer:</span></p></body></html> - - - - - - - - - - - TextLabel - - - - - - - TextLabel - - - - - - - - - diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index 302c261e5..2b0ef1256 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -34,6 +35,7 @@ #include "AlbumCreateDialog.h" #include "AlbumItem.h" +#include "PhotoItem.h" /****** * #define PHOTO_DEBUG 1 @@ -58,7 +60,8 @@ * Will introduce a FullScreen SlideShow later... first get basics happening. */ - +#define IS_ALBUM_ADMIN(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) +#define IS_ALBUM_SUBSCRIBED(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) /** Constructor */ @@ -70,11 +73,18 @@ PhotoDialog::PhotoDialog(QWidget *parent) mAlbumSelected = NULL; mPhotoSelected = NULL; mSlideShow = NULL; + mAlbumDialog = NULL; - connect( ui.toolButton_NewAlbum, SIGNAL(clicked()), this, SLOT(OpenOrShowPhotoAddDialog())); - connect( ui.toolButton_ViewAlbum, SIGNAL(clicked()), this, SLOT(OpenPhotoEditDialog())); + connect( ui.toolButton_NewAlbum, SIGNAL(clicked()), this, SLOT(createAlbum())); + connect( ui.toolButton_ViewAlbum, SIGNAL(clicked()), this, SLOT(OpenAlbumDialog())); connect( ui.toolButton_SlideShow, SIGNAL(clicked()), this, SLOT(OpenSlideShow())); + connect( ui.pushButton_YourAlbums, SIGNAL(clicked()), this, SLOT(updateAlbums())); + connect( ui.pushButton_SharedAlbums, SIGNAL(clicked()), this, SLOT(updateAlbums())); + connect( ui.pushButton_SubscribedAlbums, SIGNAL(clicked()), this, SLOT(updateAlbums())); + + ui.pushButton_YourAlbums->setChecked(true); // default to your albums view + QTimer *timer = new QTimer(this); timer->connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate())); timer->start(1000); @@ -82,9 +92,73 @@ PhotoDialog::PhotoDialog(QWidget *parent) /* setup TokenQueue */ mPhotoQueue = new TokenQueueV2(rsPhotoV2->getTokenService(), this); - + requestAlbumData(); + updateAlbums(); } +void PhotoDialog::notifySelection(PhotoShareItem *selection) +{ + + AlbumItem* aItem; + PhotoItem* pItem; + + if((aItem = dynamic_cast(selection)) != NULL) + { + + if(mPhotoSelected) + mPhotoSelected->setSelected(false); + + clearPhotos(); + + if(mAlbumSelected == aItem) + { + mAlbumSelected->setSelected(true); + } + else + { + if(mAlbumSelected == NULL) + { + mAlbumSelected = aItem; + } + else + { + mAlbumSelected->setSelected(false); + mAlbumSelected = aItem; + } + + mAlbumSelected->setSelected(true); + + } + + updatePhotos(); + } + else if((pItem = dynamic_cast(selection)) != NULL) + { + if(mPhotoSelected == pItem) + { + mPhotoSelected->setSelected(true); + } + else + { + if(mPhotoSelected == NULL) + { + mPhotoSelected = pItem; + } + else + { + mPhotoSelected->setSelected(false); + mPhotoSelected = pItem; + } + + mPhotoSelected->setSelected(true); + } + } + else + { + + } + +} void PhotoDialog::checkUpdate() @@ -151,92 +225,176 @@ void PhotoDialog::createAlbum() albumCreate.exec(); } -void PhotoDialog::OpenPhotoEditDialog() +void PhotoDialog::OpenAlbumDialog() { + if(mAlbumSelected){ + if(mAlbumDialog == NULL) + { + mAlbumDialog = new AlbumDialog(mAlbumSelected->getAlbum(), mPhotoQueue, rsPhotoV2); + connect(mAlbumDialog, SIGNAL(destroyed()), this, SLOT(SetDialogClosed())); + mAlbumDialog->show(); + }else{ + // bring dialog to front + mAlbumDialog->raise(); + } + } + return; +} + +void PhotoDialog::SetDialogClosed() +{ + mAlbumDialog = NULL; } /*************** Edit Photo Dialog ***************/ - -bool PhotoDialog::matchesAlbumFilter(const RsPhotoAlbum &album) -{ - - return true; -} - -double PhotoDialog::AlbumScore(const RsPhotoAlbum &album) -{ - return 1; -} - - -bool PhotoDialog::matchesPhotoFilter(const RsPhotoPhoto &photo) -{ - - return true; -} - -double PhotoDialog::PhotoScore(const RsPhotoPhoto &photo) -{ - return 1; -} - -void PhotoDialog::insertPhotosForSelectedAlbum() -{ - std::cerr << "PhotoDialog::insertPhotosForSelectedAlbum()"; - std::cerr << std::endl; - - clearPhotos(); - - //std::list albumIds; - if (mAlbumSelected) - { - std::string albumId = mAlbumSelected->getAlbum().mMeta.mGroupId; - //albumIds.push_back(albumId); - - std::cerr << "PhotoDialog::insertPhotosForSelectedAlbum() AlbumId: " << albumId; - std::cerr << std::endl; - requestPhotoList(albumId); - } - //requestPhotoList(albumIds); -} - - void PhotoDialog::clearAlbums() { - std::cerr << "PhotoDialog::clearAlbums()" << std::endl; + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); + QSetIterator sit(mAlbumItems); + while(sit.hasNext()) + { + AlbumItem* item = sit.next(); + alayout->removeWidget(item); + item->setParent(NULL); + } + + clearPhotos(); } void PhotoDialog::clearPhotos() { - std::cerr << "PhotoDialog::clearPhotos()" << std::endl; + std::cerr << "PhotoDialog::clearPhotos()" << std::endl; + mPhotoSelected = NULL; + QLayout *layout = ui.scrollAreaWidgetContents_2->layout(); - mPhotoSelected = NULL; - - + if(mAlbumSelected) + { + const RsGxsGroupId& id = mAlbumSelected->getAlbum().mMeta.mGroupId; + + QSetIterator sit(mPhotoItems[id]); + + while(sit.hasNext()) + { + PhotoItem* item = sit.next(); + layout->removeWidget(item); + item->setParent(NULL); + } + } +} + +void PhotoDialog::updateAlbums() +{ + + clearAlbums(); + + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); + QSetIterator sit(mAlbumItems); + + if(ui.pushButton_YourAlbums->isChecked()) + { + + ui.toolButton_subscribe->setEnabled(false); + ui.toolButton_NewAlbum->setEnabled(true); + ui.toolButton_SlideShow->setEnabled(true); + + while(sit.hasNext()){ + + AlbumItem* item = sit.next(); + uint32_t flags = item->getAlbum().mMeta.mSubscribeFlags; + + if(IS_ALBUM_ADMIN(flags)) + alayout->addWidget(item); + } + }else if(ui.pushButton_SubscribedAlbums->isChecked()) + { + + ui.toolButton_subscribe->setEnabled(false); + ui.toolButton_NewAlbum->setEnabled(false); + ui.toolButton_SlideShow->setEnabled(true); + + while(sit.hasNext()){ + + AlbumItem* item = sit.next(); + uint32_t flags = item->getAlbum().mMeta.mSubscribeFlags; + + if(IS_ALBUM_SUBSCRIBED(flags)) + alayout->addWidget(item); + } + + }else if(ui.pushButton_SharedAlbums->isChecked()) + { + + ui.toolButton_subscribe->setEnabled(true); + ui.toolButton_NewAlbum->setEnabled(false); + ui.toolButton_SlideShow->setEnabled(false); + + while(sit.hasNext()){ + + AlbumItem* item = sit.next(); + uint32_t flags = item->getAlbum().mMeta.mSubscribeFlags; + + if(flags == 0) + alayout->addWidget(item); + + } + } } void PhotoDialog::addAlbum(const RsPhotoAlbum &album) { - std::cerr << " PhotoDialog::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; + std::cerr << " PhotoDialog::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; - AlbumItem *item = new AlbumItem(album, this); - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - alayout->addWidget(item); + AlbumItem *item = new AlbumItem(album, this, this); + mAlbumItems.insert(item); + clearAlbums(); + updateAlbums(); } void PhotoDialog::addPhoto(const RsPhotoPhoto &photo) { - std::cerr << "PhotoDialog::addPhoto() AlbumId: " << photo.mMeta.mGroupId; - std::cerr << " PhotoId: " << photo.mMeta.mMsgId; - std::cerr << std::endl; + std::cerr << "PhotoDialog::addPhoto() AlbumId: " << photo.mMeta.mGroupId; + std::cerr << " PhotoId: " << photo.mMeta.mMsgId; + std::cerr << std::endl; + PhotoItem* item = new PhotoItem(this, photo, this); + const RsGxsGroupId id = photo.mMeta.mGroupId; + + mPhotoItems[id].insert(item); +} + +void PhotoDialog::subscribeToAlbum() +{ + if(mAlbumSelected){ + RsGxsGroupId id = mAlbumSelected->getAlbum().mMeta.mGroupId; + uint32_t token; + rsPhotoV2->subscribeToAlbum(token, id); + mPhotoQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, 0); + } +} + +void PhotoDialog::updatePhotos() +{ + clearPhotos(); + + if(mAlbumSelected) + { + const RsGxsGroupId& grpId = mAlbumSelected->getAlbum().mMeta.mGroupId; + + QSetIterator sit(mPhotoItems[grpId]); + + while(sit.hasNext()) + { + QLayout *layout = ui.scrollAreaWidgetContents_2->layout(); + layout->addWidget(sit.next()); + } + } } /**************************** Request / Response Filling of Data ************************/ @@ -280,7 +438,7 @@ void PhotoDialog::loadAlbumList(const uint32_t &token) } -void PhotoDialog::requestAlbumData(std::list &ids) +void PhotoDialog::requestAlbumData(std::list &ids) { RsTokReqOptionsV2 opts; uint32_t token; @@ -288,6 +446,13 @@ void PhotoDialog::requestAlbumData(std::list &ids) mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, 0); } +void PhotoDialog::requestAlbumData() +{ + RsTokReqOptionsV2 opts; + uint32_t token; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, 0); +} bool PhotoDialog::loadAlbumData(const uint32_t &token) { @@ -305,10 +470,9 @@ bool PhotoDialog::loadAlbumData(const uint32_t &token) std::cerr << " PhotoDialog::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; - AlbumItem *item = new AlbumItem(album, this); - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - alayout->addWidget(item); + addAlbum(album); } + updateAlbums(); return true; } @@ -407,6 +571,7 @@ void PhotoDialog::loadPhotoData(const uint32_t &token) std::cerr << std::endl; } } + updatePhotos(); } diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h index 8618055f6..41c2b7c17 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h @@ -37,25 +37,37 @@ #include #include "util/TokenQueueV2.h" +#include "PhotoShareItemHolder.h" -class PhotoDialog : public MainPage, public TokenResponseV2 + +class PhotoDialog : public MainPage, public TokenResponseV2, public PhotoShareItemHolder { Q_OBJECT public: PhotoDialog(QWidget *parent = 0); + void notifySelection(PhotoShareItem* selection); + private slots: void checkUpdate(); void createAlbum(); - void OpenPhotoEditDialog(); + void OpenAlbumDialog(); void OpenSlideShow(); + void SetDialogClosed(); + void updateAlbums(); + void subscribeToAlbum(); private: /* Request Response Functions for loading data */ void requestAlbumList(std::list& ids); - void requestAlbumData(std::list &ids); + void requestAlbumData(std::list &ids); + + /*! + * request data for all groups + */ + void requestAlbumData(); void requestPhotoList(GxsMsgReq &albumIds); void requestPhotoList(const std::string &albumId); void requestPhotoData(GxsMsgReq &photoIds); @@ -69,24 +81,15 @@ private: void acknowledgeGroup(const uint32_t &token); void acknowledgeMessage(const uint32_t &token); - /* TODO: These functions must be filled in for proper filtering to work - * and tied to the GUI input - */ - - bool matchesAlbumFilter(const RsPhotoAlbum &album); - double AlbumScore(const RsPhotoAlbum &album); - bool matchesPhotoFilter(const RsPhotoPhoto &photo); - double PhotoScore(const RsPhotoPhoto &photo); /* Grunt work of setting up the GUI */ - void insertPhotosForSelectedAlbum(); - void addAlbum(const RsPhotoAlbum &album); - void addPhoto(const RsPhotoPhoto &photo); + void addPhoto(const RsPhotoPhoto &photo); void clearAlbums(); void clearPhotos(); + void updatePhotos(); private: @@ -94,12 +97,16 @@ private: AlbumItem* mAlbumSelected; PhotoItem* mPhotoSelected; PhotoSlideShow* mSlideShow; + AlbumDialog* mAlbumDialog; TokenQueueV2 *mPhotoQueue; /* UI - from Designer */ Ui::PhotoDialog ui; + QSet mAlbumItems; + QMap > mPhotoItems; + }; #endif diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui index d189026c5..c33d922b5 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui @@ -14,6 +14,67 @@ Photo Share + + + + + + false + + + + 6 + + + 0 + + + + + Your Albums + + + true + + + true + + + + + + + Subscribed Albums + + + true + + + true + + + + + + + Shared Albums + + + true + + + false + + + true + + + + + + + + @@ -30,6 +91,13 @@ + + + + Subscribe To Album + + + @@ -57,7 +125,7 @@ 0 0 754 - 277 + 261 @@ -100,7 +168,7 @@ 0 0 754 - 277 + 260 diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDrop.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDrop.cpp index fbd4c9a97..94f0fc31d 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDrop.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDrop.cpp @@ -57,7 +57,6 @@ PhotoDrop::PhotoDrop(QWidget *parent) : QWidget(parent) { setAcceptDrops(true); - mIsSingleImageDrop = false; mSelected = NULL; checkMoveButtons(); @@ -69,11 +68,6 @@ void PhotoDrop::clear() { } -void PhotoDrop::setSingleImage() -{ - mIsSingleImageDrop = true; -} - PhotoItem *PhotoDrop::getSelectedPhotoItem() { @@ -153,6 +147,10 @@ PhotoItem *PhotoDrop::getPhotoIdx(int idx) return NULL; } +void PhotoDrop::getPhotos(QSet &photos) +{ + photos = mPhotos; +} void PhotoDrop::reorderPhotos() @@ -615,9 +613,8 @@ void PhotoDrop::dropEvent(QDropEvent *event) std::cerr << "Whole URL: " << uit->toString().toStdString() << std::endl; std::cerr << "or As Local File: " << localpath.toStdString() << std::endl; - - //mPhotos.push_back(item); - //layout()->addWidget(item); + PhotoItem* item = new PhotoItem(mHolder, localpath); + addPhotoItem(item); } event->setDropAction(Qt::CopyAction); event->accept(); @@ -647,21 +644,30 @@ void PhotoDrop::mousePressEvent(QMouseEvent *event) QWidget::mousePressEvent(event); } - +void PhotoDrop::setPhotoItemHolder(PhotoShareItemHolder *holder) +{ + mHolder = holder; +} void PhotoDrop::addPhotoItem(PhotoItem *item) { std::cerr << "PhotoDrop::addPhotoItem()"; std::cerr << std::endl; - if (mIsSingleImageDrop) - { - clearPhotos(); - } - + mPhotos.insert(item); layout()->addWidget(item); //checkMoveButtons(); } +bool PhotoDrop::deletePhoto(PhotoItem *item) +{ + if(mPhotos.contains(item)){ + mPhotos.remove(item); + layout()->removeWidget(item); + delete item; + } + else + return false; +} diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDrop.h b/retroshare-gui/src/gui/PhotoShare/PhotoDrop.h index 8fcbedcf9..7bba5979b 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDrop.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDrop.h @@ -28,6 +28,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE class QDragEnterEvent; @@ -36,6 +37,7 @@ class QMouseEvent; QT_END_NAMESPACE #include "gui/PhotoShare/PhotoItem.h" +#include "PhotoShareItemHolder.h" #define PHOTO_SHIFT_NO_BUTTONS 0 #define PHOTO_SHIFT_LEFT_ONLY 1 @@ -48,14 +50,23 @@ class PhotoDrop : public QWidget Q_OBJECT public: + PhotoDrop(QWidget *parent = 0); void clear(); - void setSingleImage(); + PhotoItem *getSelectedPhotoItem(); + int getPhotoCount(); + PhotoItem *getPhotoIdx(int idx); + void getPhotos(QSet& photos); -PhotoItem *getSelectedPhotoItem(); -int getPhotoCount(); -PhotoItem *getPhotoIdx(int idx); -void addPhotoItem(PhotoItem *item); + void addPhotoItem(PhotoItem *item); + void setPhotoItemHolder(PhotoShareItemHolder* holder); + + /*! + * delete photo item held by photo drop + * @param item photo item to delete + * @return false if item could not be found + */ + bool deletePhoto(PhotoItem* item); public slots: void moveLeft(); @@ -83,7 +94,8 @@ private: PhotoItem *mSelected; int mColumns; - bool mIsSingleImageDrop; + PhotoShareItemHolder* mHolder; + QSet mPhotos; }; #endif diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp index f2eb58349..71b5dadc5 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp @@ -1,14 +1,155 @@ +#include +#include +#include +#include + #include "PhotoItem.h" #include "ui_PhotoItem.h" -PhotoItem::PhotoItem(QWidget *parent) : +PhotoItem::PhotoItem(PhotoShareItemHolder *holder, const RsPhotoPhoto &photo, QWidget *parent): QWidget(parent), - ui(new Ui::PhotoItem) + ui(new Ui::PhotoItem), mHolder(holder), mPhotoDetails(photo) +{ + + ui->setupUi(this); + setSelected(false); + + ui->lineEdit_PhotoGrapher->setEnabled(false); + ui->lineEdit_Title->setEnabled(false); + + ui->editLayOut->removeWidget(ui->lineEdit_Title); + ui->editLayOut->removeWidget(ui->lineEdit_PhotoGrapher); + + ui->lineEdit_Title->setVisible(false); + ui->lineEdit_PhotoGrapher->setVisible(false); + + setUp(); +} + +PhotoItem::PhotoItem(PhotoShareItemHolder *holder, const QString& path, QWidget *parent) : + QWidget(parent), + ui(new Ui::PhotoItem), mHolder(holder) { ui->setupUi(this); + + int width = 120; + int height = 120; + + QPixmap qtn = QPixmap(path).scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation); + ui->label_Thumbnail->setPixmap(qtn); + mThumbNail = qtn; + setSelected(false); + + getPhotoThumbnail(mPhotoDetails.mThumbnail); + + connect(ui->lineEdit_Title, SIGNAL(editingFinished()), this, SLOT(setTitle())); + connect(ui->lineEdit_PhotoGrapher, SIGNAL(editingFinished()), this, SLOT(setPhotoGrapher())); + +} + +void PhotoItem::setSelected(bool selected) +{ + mSelected = selected; + if (mSelected) + { + ui->photoFrame->setStyleSheet("QFrame#photoFrame{border: 2px solid #9562B8;\nbackground: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #55EE55, stop: 1 #CCCCCC);\nborder-radius: 10px}"); + } + else + { + ui->photoFrame->setStyleSheet("QFrame#photoFrame{border: 2px solid #CCCCCC;\nbackground: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #EEEEEE, stop: 1 #CCCCCC);\nborder-radius: 10px}"); + } + update(); +} + +bool PhotoItem::getPhotoThumbnail(RsPhotoThumbnail &nail) +{ + const QPixmap *tmppix = &mThumbNail; + + QByteArray ba; + QBuffer buffer(&ba); + + if(!tmppix->isNull()) + { + // send chan image + + buffer.open(QIODevice::WriteOnly); + tmppix->save(&buffer, "PNG"); // writes image into ba in PNG format + + RsPhotoThumbnail tmpnail; + tmpnail.data = (uint8_t *) ba.data(); + tmpnail.size = ba.size(); + + nail.copyFrom(tmpnail); + + return true; + } + + nail.data = NULL; + nail.size = 0; + return false; +} + + + +void PhotoItem::setTitle(){ + + mPhotoDetails.mMeta.mMsgName = ui->lineEdit_Title->text().toStdString(); +} + +void PhotoItem::setPhotoGrapher() +{ + mPhotoDetails.mPhotographer = ui->lineEdit_PhotoGrapher->text().toStdString(); +} + +const RsPhotoPhoto& PhotoItem::getPhotoDetails() +{ + return mPhotoDetails; } PhotoItem::~PhotoItem() { delete ui; } + +void PhotoItem::setUp() +{ + + mTitleLabel = new QLabel(); + mPhotoGrapherLabel = new QLabel(); + + mTitleLabel->setText(QString::fromStdString(mPhotoDetails.mMeta.mMsgName)); + mPhotoGrapherLabel->setText(QString::fromStdString(mPhotoDetails.mPhotographer)); + + + ui->editLayOut->addWidget(mPhotoGrapherLabel); + ui->editLayOut->addWidget(mTitleLabel); + + updateImage(mPhotoDetails.mThumbnail); +} + +void PhotoItem::updateImage(const RsPhotoThumbnail &thumbnail) +{ + if (thumbnail.data != NULL) + { + QPixmap qtn; + qtn.loadFromData(thumbnail.data, thumbnail.size, thumbnail.type.c_str()); + ui->label_Thumbnail->setPixmap(qtn); + mThumbNail = qtn; + } +} + +void PhotoItem::mousePressEvent(QMouseEvent *event) +{ + + QPoint pos = event->pos(); + + std::cerr << "PhotoItem::mousePressEvent(" << pos.x() << ", " << pos.y() << ")"; + std::cerr << std::endl; + + if(mHolder) + mHolder->notifySelection(this); + else + setSelected(true); + + QWidget::mousePressEvent(event); +} diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoItem.h b/retroshare-gui/src/gui/PhotoShare/PhotoItem.h index 8a3842fe9..c1f92e1d3 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoItem.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoItem.h @@ -2,21 +2,51 @@ #define PHOTOITEM_H #include +#include +#include "PhotoShareItemHolder.h" +#include "retroshare/rsphotoV2.h" namespace Ui { class PhotoItem; } -class PhotoItem : public QWidget +class PhotoItem : public QWidget, public PhotoShareItem { Q_OBJECT public: - explicit PhotoItem(QWidget *parent = 0); + + PhotoItem(PhotoShareItemHolder *holder, const RsPhotoPhoto& photo, QWidget* parent = 0); + PhotoItem(PhotoShareItemHolder *holder, const QString& path, QWidget* parent = 0); // for new photos. ~PhotoItem(); + void setSelected(bool selected); + bool isSelected(){ return mSelected; } + const RsPhotoPhoto& getPhotoDetails(); + bool getPhotoThumbnail(RsPhotoThumbnail &nail); + +protected: + void mousePressEvent(QMouseEvent *event); + +private: + void updateImage(const RsPhotoThumbnail &thumbnail); + void setUp(); + + private slots: + void setTitle(); + void setPhotoGrapher(); private: Ui::PhotoItem *ui; + + QPixmap mThumbNail; + + QPixmap getPixmap() { return mThumbNail; } + + bool mSelected; + RsPhotoPhoto mPhotoDetails; + PhotoShareItemHolder* mHolder; + + QLabel *mTitleLabel, *mPhotoGrapherLabel; }; #endif // PHOTOITEM_H diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoItem.ui b/retroshare-gui/src/gui/PhotoShare/PhotoItem.ui index bf6a3fe19..6101f39ae 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoItem.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoItem.ui @@ -13,66 +13,90 @@ Form - + - - - TextLabel + + + QFrame#photoFrame{border: 2px solid #CCCCCC; +background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0 #EEEEEE, stop: 1 #CCCCCC); +border-radius: 10px} + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + TextLabel + + + + + + + + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Photo Title :</span></p></body></html> + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Photographer :</span></p></body></html> + + + + + + + + + + + + + + Enter Title Here + + + + + + + Enter Photographer + + + + + + + + + + - - - - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Photo Title:</span></p></body></html> - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;">Photographer:</span></p></body></html> - - - - - - - - - - - TextLabel - - - - - - - TextLabel - - - - - - - - - diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp new file mode 100644 index 000000000..7d8cdd717 --- /dev/null +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp @@ -0,0 +1,14 @@ +#include "PhotoShare.h" +#include "ui_PhotoShare.h" + +PhotoShare::PhotoShare(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhotoShare) +{ + ui->setupUi(this); +} + +PhotoShare::~PhotoShare() +{ + delete ui; +} diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.h b/retroshare-gui/src/gui/PhotoShare/PhotoShare.h new file mode 100644 index 000000000..b66eaf387 --- /dev/null +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.h @@ -0,0 +1,22 @@ +#ifndef PHOTOSHARE_H +#define PHOTOSHARE_H + +#include + +namespace Ui { + class PhotoShare; +} + +class PhotoShare : public QWidget +{ + Q_OBJECT + +public: + explicit PhotoShare(QWidget *parent = 0); + ~PhotoShare(); + +private: + Ui::PhotoShare *ui; +}; + +#endif // PHOTOSHARE_H diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui new file mode 100644 index 000000000..b245267cb --- /dev/null +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui @@ -0,0 +1,21 @@ + + + + + PhotoShare + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShareItemHolder.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoShareItemHolder.cpp new file mode 100644 index 000000000..e5d3bae28 --- /dev/null +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShareItemHolder.cpp @@ -0,0 +1,5 @@ +#include "PhotoShareItemHolder.h" + +PhotoShareItemHolder::PhotoShareItemHolder() +{ +} diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShareItemHolder.h b/retroshare-gui/src/gui/PhotoShare/PhotoShareItemHolder.h new file mode 100644 index 000000000..91df3642a --- /dev/null +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShareItemHolder.h @@ -0,0 +1,22 @@ +#ifndef PHOTOSHAREITEMHOLDER_H +#define PHOTOSHAREITEMHOLDER_H + +class PhotoShareItem +{ + +public: + PhotoShareItem() { return; } + virtual ~PhotoShareItem(){ return; } + virtual bool isSelected() = 0; + virtual void setSelected(bool selected) = 0; +}; + +class PhotoShareItemHolder +{ +public: + PhotoShareItemHolder(); + + virtual void notifySelection(PhotoShareItem* selection) = 0; +}; + +#endif // PHOTOSHAREITEMHOLDER_H diff --git a/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp b/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp index f9be0fa38..0d38765fd 100644 --- a/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp +++ b/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp @@ -23,7 +23,6 @@ #include "gui/TheWire/PulseAddDialog.h" -#include "gui/PhotoShare/PhotoDetailsDialog.h" #include "gui/PhotoShare/PhotoDrop.h" #include diff --git a/retroshare-gui/src/util/TokenQueueV2.cpp b/retroshare-gui/src/util/TokenQueueV2.cpp index 3450aa8ad..e43e7da7a 100644 --- a/retroshare-gui/src/util/TokenQueueV2.cpp +++ b/retroshare-gui/src/util/TokenQueueV2.cpp @@ -48,6 +48,15 @@ bool TokenQueueV2::requestGroupInfo(uint32_t &token, uint32_t anstype, const RsT } +bool TokenQueueV2::requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, uint32_t usertype) +{ + uint32_t basictype = TOKENREQ_GROUPINFO; + mService->requestGroupInfo(token, anstype, opts); + queueRequest(token, basictype, anstype, usertype); + + return true; +} + bool TokenQueueV2::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, const GxsMsgReq& ids, uint32_t usertype) { uint32_t basictype = TOKENREQ_MSGINFO; @@ -58,6 +67,17 @@ bool TokenQueueV2::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTok } +bool TokenQueueV2::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, + const std::list &grpIds, uint32_t usertype) +{ + uint32_t basictype = TOKENREQ_MSGINFO; + mService->requestMsgInfo(token, anstype, opts, grpIds); + queueRequest(token, basictype, anstype, usertype); + + return true; +} + + void TokenQueueV2::queueRequest(uint32_t token, uint32_t basictype, uint32_t anstype, uint32_t usertype) { std::cerr << "TokenQueueV2::queueRequest() Token: " << token << " Type: " << basictype; diff --git a/retroshare-gui/src/util/TokenQueueV2.h b/retroshare-gui/src/util/TokenQueueV2.h index 52a0e0e94..0f19863dc 100644 --- a/retroshare-gui/src/util/TokenQueueV2.h +++ b/retroshare-gui/src/util/TokenQueueV2.h @@ -63,6 +63,11 @@ class TokenResponseV2 }; +/*! + * + * + * + */ class TokenQueueV2: public QWidget { Q_OBJECT @@ -71,10 +76,23 @@ public: TokenQueueV2(RsTokenServiceV2 *service, TokenResponseV2 *resp); /* generic handling of token / response update behaviour */ + + /*! + * + * @token the token to be redeem is assigned here + * + */ bool requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, std::list& ids, uint32_t usertype); + + bool requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, uint32_t usertype); + bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, - const GxsMsgReq& ids, uint32_t usertype); + const std::list& grpIds, uint32_t usertype); + + bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, + const GxsMsgReq& grpIds, uint32_t usertype); + bool cancelRequest(const uint32_t token); From bfef2c659fcb638d9436432c4e9b8fdc57cbc20c Mon Sep 17 00:00:00 2001 From: drbob Date: Sat, 15 Sep 2012 00:16:06 +0000 Subject: [PATCH 061/222] Reorganisation of the New GXS Services. * The Example services have been renamed eg. p3posted => p3postedVEG, to allow the real services to be added. * The ServiceIDs have been shifted, to allow both VEG and GXS versions of services to run side-by-side for now. * The DataTypes have not been renamed - but potentially should be in the future - if they cause clashes. * Interface variables have also been renamed. eg. rsPosted => rsPostedVEG. * This means that the GUI will not operate without changes too - TODO. Minor changes to GXS services to better seperate them from the VEG versions. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5551 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/libretroshare.pro | 52 +- .../{rsforumsv2.h => rsforumsVEG.h} | 12 +- libretroshare/src/retroshare/rsidentityVEG.h | 535 ++++++ libretroshare/src/retroshare/rsphotoV2.h | 2 +- .../retroshare/{rsphoto.h => rsphotoVEG.h} | 12 +- .../retroshare/{rsposted.h => rspostedVEG.h} | 12 +- .../src/retroshare/{rswiki.h => rswikiVEG.h} | 12 +- .../src/retroshare/{rswire.h => rswireVEG.h} | 58 +- libretroshare/src/rsserver/rsinit.cc | 63 +- libretroshare/src/serialiser/rsphotoitems.cc | 290 --- libretroshare/src/serialiser/rsphotoitems.h | 138 -- .../src/serialiser/rsphotov2items.cc | 14 +- libretroshare/src/serialiser/rsphotov2items.h | 11 +- libretroshare/src/serialiser/rsserviceids.h | 33 +- .../{p3forumsv2.cc => p3forumsVEG.cc} | 128 +- .../services/{p3forumsv2.h => p3forumsVEG.h} | 16 +- .../{p3gxsservice.cc => p3gxsserviceVEG.cc} | 184 +- .../{p3gxsservice.h => p3gxsserviceVEG.h} | 30 +- libretroshare/src/services/p3idserviceVEG.cc | 1552 +++++++++++++++++ libretroshare/src/services/p3idserviceVEG.h | 186 ++ .../src/services/p3photoserviceV2.cc | 2 +- ...p3photoservice.cc => p3photoserviceVEG.cc} | 120 +- .../{p3photoservice.h => p3photoserviceVEG.h} | 20 +- .../services/{p3posted.cc => p3postedVEG.cc} | 294 ++-- .../services/{p3posted.h => p3postedVEG.h} | 20 +- .../{p3wikiservice.cc => p3wikiserviceVEG.cc} | 120 +- .../{p3wikiservice.h => p3wikiserviceVEG.h} | 16 +- .../src/services/{p3wire.cc => p3wireVEG.cc} | 120 +- .../src/services/{p3wire.h => p3wireVEG.h} | 20 +- 29 files changed, 2994 insertions(+), 1078 deletions(-) rename libretroshare/src/retroshare/{rsforumsv2.h => rsforumsVEG.h} (92%) create mode 100644 libretroshare/src/retroshare/rsidentityVEG.h rename libretroshare/src/retroshare/{rsphoto.h => rsphotoVEG.h} (95%) rename libretroshare/src/retroshare/{rsposted.h => rspostedVEG.h} (95%) rename libretroshare/src/retroshare/{rswiki.h => rswikiVEG.h} (92%) rename libretroshare/src/retroshare/{rswire.h => rswireVEG.h} (66%) delete mode 100644 libretroshare/src/serialiser/rsphotoitems.cc delete mode 100644 libretroshare/src/serialiser/rsphotoitems.h rename libretroshare/src/services/{p3forumsv2.cc => p3forumsVEG.cc} (74%) rename libretroshare/src/services/{p3forumsv2.h => p3forumsVEG.h} (89%) rename libretroshare/src/services/{p3gxsservice.cc => p3gxsserviceVEG.cc} (77%) rename libretroshare/src/services/{p3gxsservice.h => p3gxsserviceVEG.h} (86%) create mode 100644 libretroshare/src/services/p3idserviceVEG.cc create mode 100644 libretroshare/src/services/p3idserviceVEG.h rename libretroshare/src/services/{p3photoservice.cc => p3photoserviceVEG.cc} (70%) rename libretroshare/src/services/{p3photoservice.h => p3photoserviceVEG.h} (88%) rename libretroshare/src/services/{p3posted.cc => p3postedVEG.cc} (78%) rename libretroshare/src/services/{p3posted.h => p3postedVEG.h} (91%) rename libretroshare/src/services/{p3wikiservice.cc => p3wikiserviceVEG.cc} (68%) rename libretroshare/src/services/{p3wikiservice.h => p3wikiserviceVEG.h} (89%) rename libretroshare/src/services/{p3wire.cc => p3wireVEG.cc} (80%) rename libretroshare/src/services/{p3wire.h => p3wireVEG.h} (87%) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 376abf581..0177de3a1 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -645,31 +645,35 @@ linux-*:isEmpty(PREFIX) { } newservices { - HEADERS += services/p3photoservice.h \ - serialiser/rsphotoitems.h \ - retroshare/rsphoto.h \ - services/p3gxsservice.h \ - retroshare/rsidentity.h \ - services/p3wikiservice.h \ - retroshare/rswiki.h \ - retroshare/rswire.h \ - services/p3wire.h \ - services/p3idservice.h \ - retroshare/rsforumsv2.h \ - services/p3forumsv2.h \ - retroshare/rsposted.h \ - services/p3posted.h \ - services/p3photoserviceV2.h \ - retroshare/rsphotoV2.h + HEADERS += services/p3photoserviceVEG.h \ + retroshare/rsphotoVEG.h \ + services/p3gxsserviceVEG.h \ + retroshare/rsidentityVEG.h \ + services/p3wikiserviceVEG.h \ + retroshare/rswikiVEG.h \ + retroshare/rswireVEG.h \ + services/p3wireVEG.h \ + services/p3idserviceVEG.h \ + retroshare/rsforumsVEG.h \ + services/p3forumsVEG.h \ + retroshare/rspostedVEG.h \ + services/p3postedVEG.h \ + services/p3photoserviceV2VEG.h \ + retroshare/rsphotoVEG.h - SOURCES += services/p3photoservice.cc \ - serialiser/rsphotoitems.cc \ - services/p3gxsservice.cc \ - services/p3wikiservice.cc \ - services/p3wire.cc \ - services/p3idservice.cc \ - services/p3forumsv2.cc \ - services/p3posted.cc + # Do I need this? + #serialiser/rsphotoitemsVEG.h \ + + SOURCES += services/p3photoserviceVEG.cc \ + services/p3gxsserviceVEG.cc \ + services/p3wikiserviceVEG.cc \ + services/p3wireVEG.cc \ + services/p3idserviceVEG.cc \ + services/p3forumsVEG.cc \ + services/p3postedVEG.cc + + # Do I need this? + # serialiser/rsphotoitemsVEG.cc \ } diff --git a/libretroshare/src/retroshare/rsforumsv2.h b/libretroshare/src/retroshare/rsforumsVEG.h similarity index 92% rename from libretroshare/src/retroshare/rsforumsv2.h rename to libretroshare/src/retroshare/rsforumsVEG.h index 7a6da888d..1f12377cc 100644 --- a/libretroshare/src/retroshare/rsforumsv2.h +++ b/libretroshare/src/retroshare/rsforumsVEG.h @@ -30,11 +30,11 @@ #include #include -#include +#include /* The Main Interface Class - for information about your Peers */ -class RsForumsV2; -extern RsForumsV2 *rsForumsV2; +class RsForumsVEG; +extern RsForumsVEG *rsForumsVEG; class RsForumV2Group { @@ -75,12 +75,12 @@ class RsForumV2Msg //std::string mHashTags; }; -class RsForumsV2: public RsTokenService +class RsForumsVEG: public RsTokenServiceVEG { public: - RsForumsV2() { return; } -virtual ~RsForumsV2() { return; } + RsForumsVEG() { return; } +virtual ~RsForumsVEG() { return; } /* Specific Service Data */ virtual bool getGroupData(const uint32_t &token, RsForumV2Group &group) = 0; diff --git a/libretroshare/src/retroshare/rsidentityVEG.h b/libretroshare/src/retroshare/rsidentityVEG.h new file mode 100644 index 000000000..06c736222 --- /dev/null +++ b/libretroshare/src/retroshare/rsidentityVEG.h @@ -0,0 +1,535 @@ +#ifndef RETROSHARE_IDENTITY_GUI_INTERFACE_H +#define RETROSHARE_IDENTITY_GUI_INTERFACE_H + +/* + * libretroshare/src/retroshare: rsidentity.h + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include +#include +#include + +// FLAGS WILL BE REUSED FROM RSDISTRIB -> FOR NOW. +#include + +/********** Generic Token Request Interface *********************** + * This is packaged here, as most TokenServices will require ID Services too. + * The requests can be generic, but the reponses are service specific (dependent on data types). + */ + +// This bit will be filled out over time. +#define RS_TOKREQOPT_MSG_VERSIONS 0x0001 // MSGRELATED: Returns All MsgIds with OrigMsgId = MsgId. +#define RS_TOKREQOPT_MSG_ORIGMSG 0x0002 // MSGLIST: All Unique OrigMsgIds in a Group. +#define RS_TOKREQOPT_MSG_LATEST 0x0004 // MSGLIST: All Latest MsgIds in Group. MSGRELATED: Latest MsgIds for Input Msgs. + +#define RS_TOKREQOPT_MSG_THREAD 0x0010 // MSGRELATED: All Msgs in Thread. MSGLIST: All Unique Thread Ids in Group. +#define RS_TOKREQOPT_MSG_PARENT 0x0020 // MSGRELATED: All Children Msgs. + +#define RS_TOKREQOPT_MSG_AUTHOR 0x0040 // MSGLIST: Messages from this AuthorId + + +// Status Filtering... should it be a different Option Field. +#define RS_TOKREQOPT_GROUP_UPDATED 0x0100 // GROUPLIST: Groups that have been updated. +#define RS_TOKREQOPT_MSG_UPDATED 0x0200 // MSGLIST: Msg that have been updated from specified groups. +#define RS_TOKREQOPT_MSG_UPDATED 0x0200 // MSGLIST: Msg that have been updated from specified groups. + + + +// Read Status. +#define RS_TOKREQOPT_READ 0x0001 +#define RS_TOKREQOPT_UNREAD 0x0002 + +#define RS_TOKREQ_ANSTYPE_LIST 0x0001 +#define RS_TOKREQ_ANSTYPE_SUMMARY 0x0002 +#define RS_TOKREQ_ANSTYPE_DATA 0x0003 +#define RS_TOKREQ_ANSTYPE_ACK 0x0004 + + + + +class RsTokReqOptionsVEG +{ + public: + RsTokReqOptionsVEG() + { + mOptions = 0; + mStatusFilter = 0; mStatusMask = 0; + mFlagsFilter = 0; mFlagsMask = 0; + mSubscribeFilter = 0; + mBefore = 0; mAfter = 0; + } + + uint32_t mOptions; + + // Request specific matches with Group / Message Status. + // Should be usable with any Options... applied afterwards. + uint32_t mStatusFilter; + uint32_t mStatusMask; + + // MsgFlags or GroupsFlags, depends on Request. + uint32_t mFlagsFilter; + uint32_t mFlagsMask; + + uint32_t mSubscribeFilter; // Only for Groups. + + // Time range... again applied after Options. + time_t mBefore; + time_t mAfter; +}; + + +/********************************************************* + * Documentation for Groups Definitions. + * + * A Group is defined by: + * - TWO RSA Keys. (Admin Key & Publish Key) + * - Publish TS: Used to select the latest definition. + * + * - Operating Mode: + * - Circle (Public, External, Private). + * - Publish Mode: Encrypted / All-Signed / Only ThreadHead / None Required. + * - AuthorId: GPG Required / Any Required / Only if no Publish Signature. + * + * - Description: + * - Name & Description. + * - Optional AuthorId. + * + * Most of this information is contained inside the GroupMetaData. + * except for Actual Admin / Publish Keys, which are maintained internally. + * + ******* + * - Group Definition must be signed by Admin Key, otherwise invalid. + * - Circle Definition controls distribution of Group and Messages, see section on this for more details. + * - Public parts of Keys are distributed with Definition. + * - Private parts can be distributed to select people via alternative channels. + * - A Message Requires at least one signature: publish or Author. This signature will be used as MsgId. + * + * Groups will operate in the following modes: + * 1) Public Forum: PublishMode = None Required, AuthorId: Required. + * 2) Closed Forum: PublishMode = All-Signed, AuthorId: Required. + * 3) Private Forum: PublishMode = Encrypted, AuthorId: Required. + * + * 4) Anon Channel: PublishMode = All-Signed, AuthorId: None. + * 5) Anon Channel with Comments: PublishMode = Only ThreadHead, AuthorId: If No Publish Signature. + * 6) Private Channel: PublishMode = Encrypted. + * + * 7) Personal Photos - with comments: PublishMode = Only ThreadHead, AuthorId: Required. + * 8) Personal Photos - no comments: PublishMode = All-Signed, AuthorId: Required. + * + * 9 ) Public Wiki: PublishMode = None Required, AuthorId: Required. + * 10) Closed Wiki: PublishMode = All-Signed, AuthorId: Required. + * 11) Private Wiki: PublishMode = Encrypted, AuthorId: Required. + * + * 12) Twitter: PublishMode = Only ThreadHead, AuthorId: Required. + * + * 13) Posted: PublishMode = None Required, AuthorId: Required. + * + * + ****** + * + * Additionally to this information. The MetaData also contains several fields which can + * be used to store local information for the benefit of the service. + * + * In Particular: MsgStatus & GroupStatus inform the service if the user has read the message or if anything has changed. + * + ***/ + + +// Control of Publish Signatures. +#define RSGXS_GROUP_SIGN_PUBLISH_MASK 0x000000ff +#define RSGXS_GROUP_SIGN_PUBLISH_ENCRYPTED 0x00000001 +#define RSGXS_GROUP_SIGN_PUBLISH_ALLSIGNED 0x00000002 +#define RSGXS_GROUP_SIGN_PUBLISH_THREADHEAD 0x00000004 +#define RSGXS_GROUP_SIGN_PUBLISH_NONEREQ 0x00000008 + +// Author Signature. +#define RSGXS_GROUP_SIGN_AUTHOR_MASK 0x0000ff00 +#define RSGXS_GROUP_SIGN_AUTHOR_GPG 0x00000100 +#define RSGXS_GROUP_SIGN_AUTHOR_REQUIRED 0x00000200 +#define RSGXS_GROUP_SIGN_AUTHOR_IFNOPUBSIGN 0x00000400 +#define RSGXS_GROUP_SIGN_AUTHOR_NONE 0x00000800 + +// NB: That one signature is required... +// so some combinations are not possible. e.g. +// SIGN_PUBLISH_NONEREQ && SIGN_AUTHOR_NONE is not allowed. +// SIGN_PUBLISH_THREADHEAD && SIGN_AUTHOR_NONE is also invalid. + +#define RSGXS_GROUP_SIGN_RESERVED_MASK 0xffff0000 + + +// STATUS FLAGS: There is space here for Service specific flags - if they so desire. +// +// Msgs: UNREAD_BY_USER & PROCESSED are useful. +// Groups: NEW_MESSAGES & GROUP_UPDATED. + +#define RSGXS_MSG_STATUS_MASK 0x0000000f +#define RSGXS_MSG_STATUS_READ 0x00000001 // New or Not New +#define RSGXS_MSG_STATUS_UNREAD_BY_USER 0x00000002 +#define RSGXS_MSG_STATUS_UNPROCESSED 0x00000004 // By the Service. + +#define RSGXS_MSG_STATUS_SERVICE_MASK 0xffff0000 + +#define RSGXS_GROUP_STATUS_MASK 0x0000000f +#define RSGXS_GROUP_STATUS_UPDATED 0x00000001 +#define RSGXS_GROUP_STATUS_NEWGROUP 0x00000002 +#define RSGXS_GROUP_STATUS_NEWMSG 0x00000004 + +#define RSGXS_GROUP_STATUS_SERVICE_MASK 0xffff0000 + + + +// Subscription Flags. (LOCAL) +#define RSGXS_GROUP_SUBSCRIBE_MASK 0x0000000f +#define RSGXS_GROUP_SUBSCRIBE_ADMIN 0x00000001 +#define RSGXS_GROUP_SUBSCRIBE_PUBLISH 0x00000002 +#define RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED 0x00000004 +#define RSGXS_GROUP_SUBSCRIBE_MONITOR 0x00000008 + + +// Some MACROS for EASE OF USE. (USED BY FORUMSV2 At the moment. +#define IS_MSG_UNREAD(status) ((status & RSGXS_MSG_STATUS_READ) == 0 || (status & RSGXS_MSG_STATUS_UNREAD_BY_USER)) +#define IS_GROUP_ADMIN(subscribeFlags) (subscribeFlags & RSGXS_GROUP_SUBSCRIBE_ADMIN) +#define IS_GROUP_SUBSCRIBED(subscribeFlags) (subscribeFlags & (RSGXS_GROUP_SUBSCRIBE_ADMIN | RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED)) + + + +#define RSGXS_MAX_SERVICE_STRING 200 // Sensible limit for dbase usage. + +#include "serialiser/rsgxsitems.h" + +//class RsGroupMetaData +//{ +// public: +// +// RsGroupMetaData() +// { +// mGroupFlags = 0; +// mSignFlags = 0; +// mSubscribeFlags = 0; +// +// mPop = 0; +// mMsgCount = 0; +// mLastPost = 0; +// mGroupStatus = 0; +// +// //mPublishTs = 0; +// } +// +// std::string mGroupId; +// std::string mGroupName; +// uint32_t mGroupFlags; // Service Specific Options ???? +// uint32_t mSignFlags; // Combination of RSGXS_GROUP_SIGN_PUBLISH_MASK & RSGXS_GROUP_SIGN_AUTHOR_MASK. +// +// time_t mPublishTs; // Mandatory. +// std::string mAuthorId; // Optional. +// +// // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. +// +// uint32_t mSubscribeFlags; +// +// uint32_t mPop; // HOW DO WE DO THIS NOW. +// uint32_t mMsgCount; // ??? +// time_t mLastPost; // ??? +// +// uint32_t mGroupStatus; +// +// std::string mServiceString; // Service Specific Free-Form extra storage. +//}; +// +// +// +// +//class RsMsgMetaData +//{ +// public: +// +// RsMsgMetaData() +// { +// mPublishTs = 0; +// mMsgFlags = 0; +// mMsgStatus = 0; +// mChildTs = 0; +// } +// +// std::string mGroupId; +// std::string mMsgId; +// +// std::string mThreadId; +// std::string mParentId; +// std::string mOrigMsgId; +// +// std::string mAuthorId; +// +// std::string mMsgName; +// time_t mPublishTs; +// +// uint32_t mMsgFlags; // Whats this for? (Optional Service Specific - e.g. flag MsgType) +// +// // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. +// // normally READ / UNREAD flags. LOCAL Data. +// uint32_t mMsgStatus; +// time_t mChildTs; +// +// std::string mServiceString; // Service Specific Free-Form extra storage. +// +//}; + +std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta); +std::ostream &operator<<(std::ostream &out, const RsMsgMetaData &meta); + +class RsTokenServiceVEG +{ + public: + + RsTokenServiceVEG() { return; } +virtual ~RsTokenServiceVEG() { return; } + + /* changed? */ +virtual bool updated() = 0; + + /* Data Requests */ +virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) = 0; +virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) = 0; +virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds) = 0; + + /* Generic Lists */ +virtual bool getGroupList( const uint32_t &token, std::list &groupIds) = 0; +virtual bool getMsgList( const uint32_t &token, std::list &msgIds) = 0; + + /* Generic Summary */ +virtual bool getGroupSummary( const uint32_t &token, std::list &groupInfo) = 0; +virtual bool getMsgSummary( const uint32_t &token, std::list &msgInfo) = 0; + + /* Actual Data -> specific to Interface */ + + + + /* Poll */ +virtual uint32_t requestStatus(const uint32_t token) = 0; + + /* Cancel Request */ +virtual bool cancelRequest(const uint32_t &token) = 0; + + + ////////////////////////////////////////////////////////////////////////////// + /* Functions from Forums -> need to be implemented generically */ + // Groups Changed is now part of requestGroupInfo request. +//virtual bool groupsChanged(std::list &groupIds) = 0; + + // Message/Group Status - is retrived via requests... + // These operations could have a token, but for the moment we are going to assume + // they are async and always succeed - (or fail silently). +virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask) = 0; +virtual bool setGroupStatus(const std::string &grpId, const uint32_t status, const uint32_t statusMask) = 0; + +virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) = 0; + +virtual bool setMessageServiceString(const std::string &msgId, const std::string &str) = 0; +virtual bool setGroupServiceString(const std::string &grpId, const std::string &str) = 0; + + // (FUTURE WORK). +virtual bool groupRestoreKeys(const std::string &groupId) = 0; +virtual bool groupShareKeys(const std::string &groupId, std::list& peers) = 0; + + + + +}; + + + + +/* The Main Interface Class - for information about your Peers */ +class RsIdentity; +extern RsIdentity *rsIdentity; + +#define RSID_TYPE_MASK 0xff00 +#define RSID_RELATION_MASK 0x00ff + +#define RSID_TYPE_REALID 0x0100 +#define RSID_TYPE_PSEUDONYM 0x0200 + +#define RSID_RELATION_YOURSELF 0x0001 +#define RSID_RELATION_FRIEND 0x0002 +#define RSID_RELATION_FOF 0x0004 +#define RSID_RELATION_OTHER 0x0008 +#define RSID_RELATION_UNKNOWN 0x0010 + +std::string rsIdTypeToString(uint32_t idtype); + +class RsIdGroup +{ + public: + + + RsGroupMetaData mMeta; + + // In GroupMetaData. + //std::string mNickname; (mGroupName) + //std::string mKeyId; (mGroupId) + + uint32_t mIdType; + + std::string mGpgIdHash; // SHA(KeyId + Gpg Fingerprint) -> can only be IDed if GPG known. + + // NOTE: These cannot be transmitted as part of underlying messages.... + // Must use ServiceString. + bool mGpgIdKnown; // if GpgIdHash has been identified. + std::string mGpgId; // if known. + std::string mGpgName; // if known. + std::string mGpgEmail; // if known. +}; + + + +class RsIdMsg +{ + public: + + RsMsgMetaData mMeta; + + // In MsgMetaData. + //std::string mKeyId; (mGroupId) + //std::string mPeerId; (mAuthorId) ??? + + int mOpinion; + double mReputation; + //int mRating; + //int mPeersRating; + //std::string mComment; +}; + + + +std::ostream &operator<<(std::ostream &out, const RsIdGroup &meta); +std::ostream &operator<<(std::ostream &out, const RsIdMsg &meta); + + + +#if 0 +class RsIdReputation +{ + public: + std::string mKeyId; + + int mYourRating; + int mPeersRating; + int mFofRating; + int mTotalRating; + + std::string mComment; +}; + +class RsIdOpinion +{ + public: + + std::string mKeyId; + std::string mPeerId; + + int mRating; + int mPeersRating; + std::string mComment; +}; + +#endif + + +class RsIdentityVEG: public RsTokenServiceVEG +{ + public: + + RsIdentityVEG() { return; } +virtual ~RsIdentityVEG() { return; } + + + /* INCLUDES INTERFACE FROM RS TOKEN SERVICE */ + ////////////////////////////////////////////////////////////////////////////// + + + /* Specific Service Data */ +virtual bool getGroupData(const uint32_t &token, RsIdGroup &group) = 0; +virtual bool getMsgData(const uint32_t &token, RsIdMsg &msg) = 0; + +virtual bool createGroup(uint32_t &token, RsIdGroup &group, bool isNew) = 0; +virtual bool createMsg(uint32_t &token, RsIdMsg &msg, bool isNew) = 0; + + /* In the Identity System - You don't access the Messages Directly. + * as they represent idividuals opinions.... + * This is reflected in the TokenService calls returning false. + * + * Below is the additional interface to look at reputation. + */ + + /* So we will want to cache much of the identity stuff, so that we have quick access to the results. + * The following bits of data will not use the request/response interface, and should be available immediately. + * + * ID => Nickname, knownGPG, reputation. + * + * This will require quite a bit of data... + * 20 Bytes + 50 + 1 + 4 Bytes? (< 100 Bytes). + * x 10,000 IDs. => ~1 MB of cache (Good). + * x 100,000 IDs. => ~10 MB of cache (Good). + * x 1,000,000 IDs. => ~100 MB of cache (Too Big). + * + * We also need to store quick access to your OwnIds. + */ + +//virtual uint32_t getIdDetails(const std::string &id, std::string &nickname, bool &isGpgKnown, +// uint32_t &ownOpinion, float &reputation); +//virtual uint32_t getOwnIds(std::list &ownIds); +//virtual bool setOpinion(const std::string &id, uint32_t opinion); + + +virtual void generateDummyData() = 0; + +#if 0 + + /* Data Requests */ +virtual bool requestIdentityList(uint32_t &token) = 0; +virtual bool requestIdentities(uint32_t &token, const std::list &ids) = 0; +virtual bool requestIdReputations(uint32_t &token, const std::list &ids) = 0; +virtual bool requestIdPeerOpinion(uint32_t &token, const std::string &aboutId, const std::string &peerId) = 0; +//virtual bool requestIdGpgDetails(uint32_t &token, const std::list &ids) = 0; + + /* Poll */ +virtual uint32_t requestStatus(const uint32_t token) = 0; + + /* Retrieve Data */ +virtual bool getIdentityList(const uint32_t token, std::list &ids) = 0; +virtual bool getIdentity(const uint32_t token, RsIdData &data) = 0; +virtual bool getIdReputation(const uint32_t token, RsIdReputation &reputation) = 0; +virtual bool getIdPeerOpinion(const uint32_t token, RsIdOpinion &opinion) = 0; + + /* Updates */ +virtual bool updateIdentity(RsIdData &data) = 0; +virtual bool updateOpinion(RsIdOpinion &opinion) = 0; + +#endif + +}; + + + +#endif diff --git a/libretroshare/src/retroshare/rsphotoV2.h b/libretroshare/src/retroshare/rsphotoV2.h index 60b095e77..c355fb173 100644 --- a/libretroshare/src/retroshare/rsphotoV2.h +++ b/libretroshare/src/retroshare/rsphotoV2.h @@ -30,7 +30,7 @@ #include #include #include "rsgxsservice.h" -#include "rsphoto.h" +#include "rsphotoVEG.h" /* The Main Interface Class - for information about your Peers */ class RsPhotoV2; diff --git a/libretroshare/src/retroshare/rsphoto.h b/libretroshare/src/retroshare/rsphotoVEG.h similarity index 95% rename from libretroshare/src/retroshare/rsphoto.h rename to libretroshare/src/retroshare/rsphotoVEG.h index 15f8a4f9c..5b67ea7a1 100644 --- a/libretroshare/src/retroshare/rsphoto.h +++ b/libretroshare/src/retroshare/rsphotoVEG.h @@ -29,11 +29,11 @@ #include #include #include -#include +#include /* The Main Interface Class - for information about your Peers */ -class RsPhoto; -extern RsPhoto *rsPhoto; +class RsPhotoVEG; +extern RsPhotoVEG *rsPhotoVEG; /******************* NEW STUFF FOR NEW CACHE SYSTEM *********/ @@ -159,12 +159,12 @@ std::ostream &operator<<(std::ostream &out, const RsPhotoPhoto &photo); std::ostream &operator<<(std::ostream &out, const RsPhotoAlbum &album); -class RsPhoto: public RsTokenService +class RsPhotoVEG: public RsTokenServiceVEG { public: - RsPhoto() { return; } -virtual ~RsPhoto() { return; } + RsPhotoVEG() { return; } +virtual ~RsPhotoVEG() { return; } /* Specific Service Data */ virtual bool getAlbum(const uint32_t &token, RsPhotoAlbum &album) = 0; diff --git a/libretroshare/src/retroshare/rsposted.h b/libretroshare/src/retroshare/rspostedVEG.h similarity index 95% rename from libretroshare/src/retroshare/rsposted.h rename to libretroshare/src/retroshare/rspostedVEG.h index e98fc8d2b..af617f10e 100644 --- a/libretroshare/src/retroshare/rsposted.h +++ b/libretroshare/src/retroshare/rspostedVEG.h @@ -29,11 +29,11 @@ #include #include #include -#include +#include /* The Main Interface Class - for information about your Peers */ -class RsPosted; -extern RsPosted *rsPosted; +class RsPostedVEG; +extern RsPostedVEG *rsPostedVEG; class RsPostedGroup @@ -113,12 +113,12 @@ std::ostream &operator<<(std::ostream &out, const RsPostedVote &vote); std::ostream &operator<<(std::ostream &out, const RsPostedComment &comment); -class RsPosted: public RsTokenService +class RsPostedVEG: public RsTokenServiceVEG { public: - RsPosted() { return; } -virtual ~RsPosted() { return; } + RsPostedVEG() { return; } +virtual ~RsPostedVEG() { return; } /* Specific Service Data */ virtual bool getGroup(const uint32_t &token, RsPostedGroup &group) = 0; diff --git a/libretroshare/src/retroshare/rswiki.h b/libretroshare/src/retroshare/rswikiVEG.h similarity index 92% rename from libretroshare/src/retroshare/rswiki.h rename to libretroshare/src/retroshare/rswikiVEG.h index 5d4d98e1c..75616c8d4 100644 --- a/libretroshare/src/retroshare/rswiki.h +++ b/libretroshare/src/retroshare/rswikiVEG.h @@ -30,11 +30,11 @@ #include #include -#include +#include /* The Main Interface Class - for information about your Peers */ -class RsWiki; -extern RsWiki *rsWiki; +class RsWikiVEG; +extern RsWikiVEG *rsWikiVEG; class RsWikiGroupShare { @@ -84,12 +84,12 @@ class RsWikiPage std::string mHashTags; }; -class RsWiki: public RsTokenService +class RsWikiVEG: public RsTokenServiceVEG { public: - RsWiki() { return; } -virtual ~RsWiki() { return; } + RsWikiVEG() { return; } +virtual ~RsWikiVEG() { return; } /* Specific Service Data */ virtual bool getGroupData(const uint32_t &token, RsWikiGroup &group) = 0; diff --git a/libretroshare/src/retroshare/rswire.h b/libretroshare/src/retroshare/rswireVEG.h similarity index 66% rename from libretroshare/src/retroshare/rswire.h rename to libretroshare/src/retroshare/rswireVEG.h index 0a5e1fda4..314e8dc1c 100644 --- a/libretroshare/src/retroshare/rswire.h +++ b/libretroshare/src/retroshare/rswireVEG.h @@ -30,11 +30,11 @@ #include #include -#include +#include /* The Main Interface Class - for information about your Peers */ -class RsWire; -extern RsWire *rsWire; +class RsWireVEG; +extern RsWireVEG *rsWireVEG; class RsWireGroupShare { @@ -64,6 +64,38 @@ class RsWireGroup RsWireGroupShare mShareOptions; }; + + +/*********************************************************************** + * So pulses operate in the following modes. + * + * => Standard, a post to your own group. + * => @User, gets duplicated on each user's group. + * => RT, duplicated as child of original post. + * + * From Twitter: + * twitter can be: embedded, replied to, favourited, unfavourited, + * retweeted, unretweeted and deleted + * + * See: https://dev.twitter.com/docs/platform-objects + * + * Format of message: .... + * + * #HashTags. + * @68769381495134 => ID of Sender. + * + * + ***********************************************************************/ + +class RsWirePlace +{ + public: + + + +}; + + class RsWirePulse { public: @@ -78,15 +110,27 @@ class RsWirePulse std::string mPulse; // all the text is stored here. - std::string mHashTags; + std::string mInReplyPulse; + + uint32_t mPulseFlags; + + std::list mMentions; + std::list mHashTags; + std::list mUrls; + + RsWirePlace mPlace; }; -class RsWire: public RsTokenService + + + + +class RsWireVEG: public RsTokenServiceVEG { public: - RsWire() { return; } -virtual ~RsWire() { return; } + RsWireVEG() { return; } +virtual ~RsWireVEG() { return; } /* Specific Service Data */ virtual bool getGroupData(const uint32_t &token, RsWireGroup &group) = 0; diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 14e0a7c2b..de9df7df6 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1806,7 +1806,7 @@ RsTurtle *rsTurtle = NULL ; #include "services/p3blogs.h" #include "turtle/p3turtle.h" -#define ENABLE_GXS_SERVICES 1 +#define ENABLE_GXS_VEG_SERVICES 1 #define ENABLE_GXS_CORE 1 #ifdef ENABLE_GXS_CORE @@ -1816,13 +1816,13 @@ RsTurtle *rsTurtle = NULL ; #include "gxs/rsgxsnetservice.h" #endif -#ifdef ENABLE_GXS_SERVICES -#include "services/p3photoservice.h" -#include "services/p3wikiservice.h" -#include "services/p3wire.h" -#include "services/p3idservice.h" -#include "services/p3forumsv2.h" -#include "services/p3posted.h" +#ifdef ENABLE_GXS_VEG_SERVICES +#include "services/p3photoserviceVEG.h" +#include "services/p3wikiserviceVEG.h" +#include "services/p3wireVEG.h" +#include "services/p3idserviceVEG.h" +#include "services/p3forumsVEG.h" +#include "services/p3postedVEG.h" #endif #ifndef PQI_DISABLE_TUNNEL @@ -2272,7 +2272,7 @@ int RsServer::StartupRetroShare() // first prep the core RsGeneralDataService* photo_ds = new RsDataService("./", "photoV2_db", - RS_SERVICE_TYPE_PHOTO, NULL); + RS_SERVICE_GXSV1_TYPE_PHOTO, NULL); photo_ds->resetDataStore(); @@ -2301,31 +2301,31 @@ int RsServer::StartupRetroShare() #endif -#ifdef ENABLE_GXS_SERVICES +#ifdef ENABLE_GXS_VEG_SERVICES // Testing New Cache Services. - p3PhotoService *mPhotos = new p3PhotoService(RS_SERVICE_TYPE_PHOTO); - pqih -> addService(mPhotos); + p3PhotoServiceVEG *mPhotosVEG = new p3PhotoServiceVEG(RS_SERVICE_VEG_TYPE_PHOTO); + pqih -> addService(mPhotosVEG); // Testing New Cache Services. - p3WikiService *mWikis = new p3WikiService(RS_SERVICE_TYPE_WIKI); - pqih -> addService(mWikis); + p3WikiServiceVEG *mWikisVEG = new p3WikiServiceVEG(RS_SERVICE_VEG_TYPE_WIKI); + pqih -> addService(mWikisVEG); // Testing New Cache Services. - p3Wire *mWire = new p3Wire(RS_SERVICE_TYPE_WIRE); - pqih -> addService(mWire); + p3WireVEG *mWireVEG = new p3WireVEG(RS_SERVICE_VEG_TYPE_WIRE); + pqih -> addService(mWireVEG); // Testing New Cache Services. - p3IdService *mIdentity = new p3IdService(RS_SERVICE_TYPE_IDENTITY); - pqih -> addService(mIdentity); + p3IdServiceVEG *mIdentityVEG = new p3IdServiceVEG(RS_SERVICE_VEG_TYPE_IDENTITY); + pqih -> addService(mIdentityVEG); // Testing New Cache Services. - p3ForumsV2 *mForumsV2 = new p3ForumsV2(RS_SERVICE_TYPE_FORUMSV2); - pqih -> addService(mForumsV2); + p3ForumsVEG *mForumsVEG = new p3ForumsVEG(RS_SERVICE_VEG_TYPE_FORUMS); + pqih -> addService(mForumsVEG); // Testing New Cache Services. - p3PostedService *mPosted = new p3PostedService(RS_SERVICE_TYPE_POSTED); - pqih -> addService(mPosted); -#endif // ENABLE_GXS_SERVICES + p3PostedServiceVEG *mPostedVEG = new p3PostedServiceVEG(RS_SERVICE_VEG_TYPE_POSTED); + pqih -> addService(mPostedVEG); +#endif // ENABLE_GXS_VEG_SERVICES #ifndef RS_RELEASE @@ -2586,15 +2586,18 @@ int RsServer::StartupRetroShare() #ifdef ENABLE_GXS_SERVICES // Testing of new cache system interfaces. - rsIdentity = mIdentity; - rsPhoto = mPhotos; - rsPhotoV2 = mPhotoV2; - rsWiki = mWikis; - rsWire = mWire; - rsForumsV2 = mForumsV2; - rsPosted = mPosted; + rsIdentityVEG = mIdentityVEG; + rsPhotoVEG = mPhotosVEG; + rsWikiVEG = mWikisVEG; + rsWireVEG = mWireVEG; + rsForumsVEG = mForumsVEG; + rsPostedVEG = mPostedVEG; + #endif // ENABLE_GXS_SERVICES +#ifdef ENABLE_GXS_CORE + rsPhotoV2 = mPhotoV2; +#endif // ENABLE_GXS_CORE #ifdef RS_USE_BLOGS rsBlogs = mBlogs; diff --git a/libretroshare/src/serialiser/rsphotoitems.cc b/libretroshare/src/serialiser/rsphotoitems.cc deleted file mode 100644 index 7216f95b4..000000000 --- a/libretroshare/src/serialiser/rsphotoitems.cc +++ /dev/null @@ -1,290 +0,0 @@ - -/* - * libretroshare/src/serialiser: rsphotoitems.cc - * - * RetroShare Serialiser. - * - * Copyright 2007-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "serialiser/rsbaseserial.h" -#include "serialiser/rsphotoitems.h" -#include "serialiser/rstlvbase.h" - -#define RSSERIAL_DEBUG 1 -#include - -/*************************************************************************/ - -void RsPhotoItem::clear() -{ - srcId.clear(); - photoId.clear(); - size = 0; - - name.clear(); - comment.clear(); - - location.clear(); - date.clear(); - - /* not serialised */ - isAvailable = false; - path.clear(); -} - -std::ostream &RsPhotoItem::print(std::ostream &out, uint16_t indent) -{ - printRsItemBase(out, "RsPhotoItem", indent); - uint16_t int_Indent = indent + 2; - printIndent(out, int_Indent); - out << "srcId: " << srcId << std::endl; - printIndent(out, int_Indent); - out << "photoId: " << photoId << std::endl; - printIndent(out, int_Indent); - out << "size: " << size << std::endl; - - printIndent(out, int_Indent); - out << "name: " << name << std::endl; - - printIndent(out, int_Indent); - std::string cnv_comment(comment.begin(), comment.end()); - out << "msg: " << cnv_comment << std::endl; - - printIndent(out, int_Indent); - out << "location: " << location << std::endl; - printIndent(out, int_Indent); - out << "date: " << date << std::endl; - - printIndent(out, int_Indent); - out << "(NS) isAvailable: " << isAvailable << std::endl; - printIndent(out, int_Indent); - out << "(NS) path: " << path << std::endl; - - printRsItemEnd(out, "RsPhotoItem", indent); - return out; -} - -/*************************************************************************/ -/*************************************************************************/ - -void RsPhotoShowItem::clear() -{ - showId.clear(); - name.clear(); - comment.clear(); - - location.clear(); - date.clear(); - - photos.clear(); -} - -std::ostream &RsPhotoShowItem::print(std::ostream &out, uint16_t indent) -{ - printRsItemBase(out, "RsPhotoShowItem", indent); - uint16_t int_Indent = indent + 2; - uint16_t int_Indent2 = int_Indent + 2; - - printIndent(out, int_Indent); - out << "showId: " << showId << std::endl; - printIndent(out, int_Indent); - out << "name: " << name << std::endl; - - printIndent(out, int_Indent); - std::string cnv_comment(comment.begin(), comment.end()); - out << "msg: " << cnv_comment << std::endl; - - printIndent(out, int_Indent); - out << "location: " << location << std::endl; - printIndent(out, int_Indent); - out << "date: " << date << std::endl; - - printIndent(out, int_Indent); - out << "Photos in Show: " << photos.size() << std::endl; - - std::list::iterator it; - for(it = photos.begin(); it != photos.end(); it++) - { - printIndent(out, int_Indent2); - out << "PhotoId: " << it->photoId << std::endl; - printIndent(out, int_Indent2 + 2); - std::string cnv_comment2(it->altComment.begin(), it->altComment.end()); - out << "AltComment: " << cnv_comment2 << std::endl; - printIndent(out, int_Indent2 + 2); - out << "Delta T: " << it->deltaT << std::endl; - } - - printRsItemEnd(out, "RsPhotoShowItem", indent); - return out; -} - -RsPhotoRefItem::RsPhotoRefItem() - :deltaT(0) -{ - return; -} - -/*************************************************************************/ -/*************************************************************************/ -/*************************************************************************/ - -/* TODO serialiser */ - -#if 0 - -uint32_t RsPhotoSerialiser::sizeLink(RsPhotoLinkMsg *item) -{ - uint32_t s = 8; /* header */ - s += GetTlvStringSize(item->rid); - s += 4; /* timestamp */ - s += GetTlvWideStringSize(item->title); - s += GetTlvWideStringSize(item->comment); - s += 4; /* linktype */ - s += GetTlvWideStringSize(item->link); - - return s; -} - -/* serialise the data to the buffer */ -bool RsPhotoSerialiser::serialiseLink(RsPhotoLinkMsg *item, void *data, uint32_t *pktsize) -{ - uint32_t tlvsize = sizeLink(item); - uint32_t offset = 0; - - if (*pktsize < tlvsize) - return false; /* not enough space */ - - *pktsize = tlvsize; - - bool ok = true; - - ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); - - std::cerr << "RsPhotoLinkSerialiser::serialiseLink() Header: " << ok << std::endl; - std::cerr << "RsPhotoLinkSerialiser::serialiseLink() Size: " << tlvsize << std::endl; - - /* skip the header */ - offset += 8; - - /* add mandatory parts first */ - ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_GENID, item->rid); - std::cerr << "RsPhotoLinkSerialiser::serialiseLink() rid: " << ok << std::endl; - - ok &= setRawUInt32(data, tlvsize, &offset, item->timestamp); - std::cerr << "RsPhotoLinkSerialiser::serialiseLink() timestamp: " << ok << std::endl; - - ok &= SetTlvWideString(data, tlvsize, &offset, TLV_TYPE_WSTR_TITLE, item->title); - std::cerr << "RsPhotoLinkSerialiser::serialiseLink() Title: " << ok << std::endl; - ok &= SetTlvWideString(data, tlvsize, &offset, TLV_TYPE_WSTR_COMMENT, item->comment); - std::cerr << "RsPhotoLinkSerialiser::serialiseLink() Comment: " << ok << std::endl; - - ok &= setRawUInt32(data, tlvsize, &offset, item->linktype); - std::cerr << "RsPhotoLinkSerialiser::serialiseLink() linktype: " << ok << std::endl; - - ok &= SetTlvWideString(data, tlvsize, &offset, TLV_TYPE_WSTR_LINK, item->link); - std::cerr << "RsPhotoLinkSerialiser::serialiseLink() Link: " << ok << std::endl; - - if (offset != tlvsize) - { - ok = false; - std::cerr << "RsPhotoLinkSerialiser::serialiseLink() Size Error! " << std::endl; - } - - return ok; -} - -RsPhotoLinkMsg *RsPhotoSerialiser::deserialiseLink(void *data, uint32_t *pktsize) -{ - /* get the type and size */ - uint32_t rstype = getRsItemId(data); - uint32_t rssize = getRsItemSize(data); - - uint32_t offset = 0; - - - if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_TYPE_RANK != getRsItemService(rstype)) || - (RS_PKT_SUBTYPE_RANK_LINK != getRsItemSubType(rstype))) - { - return NULL; /* wrong type */ - } - - if (*pktsize < rssize) /* check size */ - return NULL; /* not enough data */ - - /* set the packet length */ - *pktsize = rssize; - - bool ok = true; - - /* ready to load */ - RsPhotoLinkMsg *item = new RsPhotoLinkMsg(); - item->clear(); - - /* skip the header */ - offset += 8; - - /* get mandatory parts first */ - ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_GENID, item->rid); - ok &= getRawUInt32(data, rssize, &offset, &(item->timestamp)); - ok &= GetTlvWideString(data, rssize, &offset, TLV_TYPE_WSTR_TITLE, item->title); - ok &= GetTlvWideString(data, rssize, &offset, TLV_TYPE_WSTR_COMMENT, item->comment); - ok &= getRawUInt32(data, rssize, &offset, &(item->linktype)); - ok &= GetTlvWideString(data, rssize, &offset, TLV_TYPE_WSTR_LINK, item->link); - - if (offset != rssize) - { - /* error */ - delete item; - return NULL; - } - - if (!ok) - { - delete item; - return NULL; - } - - return item; -} - - -uint32_t RsPhotoSerialiser::size(RsItem *item) -{ - return sizeLink((RsPhotoLinkMsg *) item); -} - -bool RsPhotoSerialiser::serialise(RsItem *item, void *data, uint32_t *pktsize) -{ - return serialiseLink((RsPhotoLinkMsg *) item, data, pktsize); -} - -RsItem *RsPhotoSerialiser::deserialise(void *data, uint32_t *pktsize) -{ - return deserialiseLink(data, pktsize); -} - - -#endif - - -/*************************************************************************/ - diff --git a/libretroshare/src/serialiser/rsphotoitems.h b/libretroshare/src/serialiser/rsphotoitems.h deleted file mode 100644 index 8281af2f1..000000000 --- a/libretroshare/src/serialiser/rsphotoitems.h +++ /dev/null @@ -1,138 +0,0 @@ -#ifndef P3_PHOTO_ITEMS_H -#define P3_PHOTO_ITEMS_H - -/* - * libretroshare/src/serialiser: rsphotoitems.h - * - * RetroShare Serialiser. - * - * Copyright 2007-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include - -#include "serialiser/rsserviceids.h" -#include "serialiser/rsserial.h" -#include "serialiser/rstlvtypes.h" - -const uint8_t RS_PKT_SUBTYPE_PHOTO_ITEM = 0x02; -const uint8_t RS_PKT_SUBTYPE_PHOTO_SHOW_ITEM = 0x03; -const uint8_t RS_PKT_SUBTYPE_PHOTO_COMMENT_ITEM = 0x04; - -/**************************************************************************/ - -class RsPhotoItem; -class RsPhotoShowItem; -class RsPhotoCommentItem; - -class RsPhotoItem: public RsItem -{ - public: - - RsPhotoItem() - :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_PHOTO, - RS_PKT_SUBTYPE_PHOTO_ITEM) { return; } -virtual ~RsPhotoItem() { return; } -virtual void clear(); -virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); - - std::string srcId; - std::string photoId; /* same as hash */ - uint64_t size; /* file size */ - - std::string name; - std::wstring comment; - - std::string location; /* TODO: change to TLV */ - std::string date; /* TODO: change to TLV */ - - /* not serialised */ - bool isAvailable; - std::string path; -}; - -/* THIS must be turned into a TLV type + set (TOD) */ -class RsPhotoRefItem -{ - public: - RsPhotoRefItem(); - - std::string photoId; - std::wstring altComment; - uint32_t deltaT; /* in 100ths of sec? */ -}; - -class RsPhotoShowItem: public RsItem -{ - public: - RsPhotoShowItem() - :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_PHOTO, - RS_PKT_SUBTYPE_PHOTO_SHOW_ITEM) { return; } - -virtual ~RsPhotoShowItem() { return; } -virtual void clear(); -virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); - - std::string showId; - - std::string name; - std::wstring comment; - - std::string location; /* TODO -> TLV */ - std::string date; /* TODO -> TLV */ - std::list photos; /* list as ordered */ -}; - -class RsPhotoSerialiser: public RsSerialType -{ - public: - RsPhotoSerialiser() - :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_PHOTO) - { return; } -virtual ~RsPhotoSerialiser() - { return; } - -virtual uint32_t size(RsItem *) { return 0; } -virtual bool serialise (RsItem */*item*/, void */*data*/, uint32_t */*size*/) { return false; } -virtual RsItem * deserialise(void */*data*/, uint32_t */*size*/) { return NULL; } - - private: - - /* For RS_PKT_SUBTYPE_PHOTO_ITEM */ -//virtual uint32_t sizeLink(RsPhotoItem *); -//virtual bool serialiseLink (RsPhotoItem *item, void *data, uint32_t *size); -//virtual RsPhotoItem *deserialiseLink(void *data, uint32_t *size); - - /* For RS_PKT_SUBTYPE_PHOTO_SHOW_ITEM */ -//virtual uint32_t sizeLink(RsPhotoShowItem *); -//virtual bool serialiseLink (RsPhotoShowItem *item, void *data, uint32_t *size); -//virtual RsPhotoShowItem *deserialiseLink(void *data, uint32_t *size); - - /* For RS_PKT_SUBTYPE_PHOTO_COMMENT_ITEM */ -//virtual uint32_t sizeLink(RsPhotoCommentItem *); -//virtual bool serialiseLink (RsPhotoCommentItem *item, void *data, uint32_t *size); -//virtual RsPhotoCommentItem *deserialiseLink(void *data, uint32_t *size); - -}; - -/**************************************************************************/ - -#endif /* RS_PHOTO_ITEMS_H */ - diff --git a/libretroshare/src/serialiser/rsphotov2items.cc b/libretroshare/src/serialiser/rsphotov2items.cc index ac153ecba..360f3d819 100644 --- a/libretroshare/src/serialiser/rsphotov2items.cc +++ b/libretroshare/src/serialiser/rsphotov2items.cc @@ -88,7 +88,7 @@ RsItem* RsGxsPhotoSerialiser::deserialise(void* data, uint32_t* size) uint32_t rstype = getRsItemId(data); if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_TYPE_PHOTO != getRsItemService(rstype))) + (RS_SERVICE_GXSV1_TYPE_PHOTO != getRsItemService(rstype))) { return NULL; /* wrong type */ } @@ -175,7 +175,7 @@ bool RsGxsPhotoSerialiser::serialiseGxsPhotoAlbumItem(RsGxsPhotoAlbumItem* item, ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mWhen); ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mWhere); ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mThumbnail.type); - RsTlvBinaryData b(RS_SERVICE_TYPE_PHOTO); // TODO, need something more persisitent + RsTlvBinaryData b(RS_SERVICE_GXSV1_TYPE_PHOTO); // TODO, need something more persisitent b.setBinData(item->album.mThumbnail.data, item->album.mThumbnail.size); ok &= b.SetTlv(data, tlvsize, &offset); @@ -213,7 +213,7 @@ RsGxsPhotoAlbumItem* RsGxsPhotoSerialiser::deserialiseGxsPhotoAlbumItem(void* da if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_TYPE_PHOTO != getRsItemService(rstype)) || + (RS_SERVICE_GXSV1_TYPE_PHOTO != getRsItemService(rstype)) || (RS_PKT_SUBTYPE_PHOTO_ITEM != getRsItemSubType(rstype))) { #ifdef GXS_PHOTO_SERIAL_DEBUG @@ -251,7 +251,7 @@ RsGxsPhotoAlbumItem* RsGxsPhotoSerialiser::deserialiseGxsPhotoAlbumItem(void* da ok &= GetTlvString(data, rssize, &offset, 1, item->album.mWhere); ok &= GetTlvString(data, rssize, &offset, 1, item->album.mThumbnail.type); - RsTlvBinaryData b(RS_SERVICE_TYPE_PHOTO); // TODO, need something more persisitent + RsTlvBinaryData b(RS_SERVICE_GXSV1_TYPE_PHOTO); // TODO, need something more persisitent ok &= b.GetTlv(data, rssize, &offset); item->album.mThumbnail.data = (uint8_t*)b.bin_data; item->album.mThumbnail.size = b.bin_len; @@ -341,7 +341,7 @@ bool RsGxsPhotoSerialiser::serialiseGxsPhotoPhotoItem(RsGxsPhotoPhotoItem* item, ok &= SetTlvString(data, tlvsize, &offset, 1, item->photo.mWhen); ok &= SetTlvString(data, tlvsize, &offset, 1, item->photo.mWhere); ok &= SetTlvString(data, tlvsize, &offset, 1, item->photo.mThumbnail.type); - RsTlvBinaryData b(RS_SERVICE_TYPE_PHOTO); // TODO, need something more persisitent + RsTlvBinaryData b(RS_SERVICE_GXSV1_TYPE_PHOTO); // TODO, need something more persisitent b.setBinData(item->photo.mThumbnail.data, item->photo.mThumbnail.size); ok &= b.SetTlv(data, tlvsize, &offset); @@ -379,7 +379,7 @@ RsGxsPhotoPhotoItem* RsGxsPhotoSerialiser::deserialiseGxsPhotoPhotoItem(void* da if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_TYPE_PHOTO != getRsItemService(rstype)) || + (RS_SERVICE_GXSV1_TYPE_PHOTO != getRsItemService(rstype)) || (RS_PKT_SUBTYPE_PHOTO_SHOW_ITEM != getRsItemSubType(rstype))) { #ifdef GXS_PHOTO_SERIAL_DEBUG @@ -415,7 +415,7 @@ RsGxsPhotoPhotoItem* RsGxsPhotoSerialiser::deserialiseGxsPhotoPhotoItem(void* da ok &= GetTlvString(data, rssize, &offset, 1, item->photo.mWhere); ok &= GetTlvString(data, rssize, &offset, 1, item->photo.mThumbnail.type); - RsTlvBinaryData b(RS_SERVICE_TYPE_PHOTO); // TODO, need something more persisitent + RsTlvBinaryData b(RS_SERVICE_GXSV1_TYPE_PHOTO); // TODO, need something more persisitent ok &= b.GetTlv(data, rssize, &offset); item->photo.mThumbnail.data = (uint8_t*)(b.bin_data); item->photo.mThumbnail.size = b.bin_len; diff --git a/libretroshare/src/serialiser/rsphotov2items.h b/libretroshare/src/serialiser/rsphotov2items.h index b08571b5f..1cbba7dd5 100644 --- a/libretroshare/src/serialiser/rsphotov2items.h +++ b/libretroshare/src/serialiser/rsphotov2items.h @@ -33,16 +33,19 @@ #include "serialiser/rstlvtypes.h" #include "rsgxsitems.h" -#include "rsphotoitems.h" +//#include "rsphotoitems.h" #include "retroshare/rsphotoV2.h" +const uint8_t RS_PKT_SUBTYPE_PHOTO_ITEM = 0x02; +const uint8_t RS_PKT_SUBTYPE_PHOTO_SHOW_ITEM = 0x03; +const uint8_t RS_PKT_SUBTYPE_PHOTO_COMMENT_ITEM = 0x04; class RsGxsPhotoAlbumItem : public RsGxsGrpItem { public: - RsGxsPhotoAlbumItem(): RsGxsGrpItem(RS_SERVICE_TYPE_PHOTO, + RsGxsPhotoAlbumItem(): RsGxsGrpItem(RS_SERVICE_GXSV1_TYPE_PHOTO, RS_PKT_SUBTYPE_PHOTO_ITEM) { return;} virtual ~RsGxsPhotoAlbumItem() { return;} @@ -57,7 +60,7 @@ class RsGxsPhotoPhotoItem : public RsGxsMsgItem { public: - RsGxsPhotoPhotoItem(): RsGxsMsgItem(RS_SERVICE_TYPE_PHOTO, + RsGxsPhotoPhotoItem(): RsGxsMsgItem(RS_SERVICE_GXSV1_TYPE_PHOTO, RS_PKT_SUBTYPE_PHOTO_SHOW_ITEM) {return; } virtual ~RsGxsPhotoPhotoItem() { return;} void clear(); @@ -70,7 +73,7 @@ class RsGxsPhotoSerialiser : public RsSerialType public: RsGxsPhotoSerialiser() - :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_PHOTO) + :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXSV1_TYPE_PHOTO) { return; } virtual ~RsGxsPhotoSerialiser() { return; } diff --git a/libretroshare/src/serialiser/rsserviceids.h b/libretroshare/src/serialiser/rsserviceids.h index c6cdd6870..800116654 100644 --- a/libretroshare/src/serialiser/rsserviceids.h +++ b/libretroshare/src/serialiser/rsserviceids.h @@ -108,13 +108,6 @@ const uint16_t RS_SERVICE_TYPE_DSDV = 0xf050; const uint16_t RS_SERVICE_TYPE_BWCTRL = 0xf060; - /* New Cache Services */ -const uint16_t RS_SERVICE_TYPE_IDENTITY = 0xf100; -const uint16_t RS_SERVICE_TYPE_PHOTO = 0xf101; -const uint16_t RS_SERVICE_TYPE_WIKI = 0xf102; -const uint16_t RS_SERVICE_TYPE_WIRE = 0xf103; -const uint16_t RS_SERVICE_TYPE_FORUMSV2 = 0xf104; -const uint16_t RS_SERVICE_TYPE_POSTED = 0xf105; //const uint16_t RS_SERVICE_TYPE_DISTRIB = 0xf110; //const uint16_t RS_SERVICE_TYPE_FORUM = 0xf120; @@ -134,9 +127,33 @@ const uint16_t RS_SERVICE_TYPE_GAME_QGO = 0xf212; const uint16_t RS_SERVICE_TYPE_GAME_BIGTWO = 0xf213; const uint16_t RS_SERVICE_TYPE_GAME_POKER = 0xf214; + /* New Cache Services */ /* Rs Network Exchange Service */ -const uint16_t RS_SERVICE_TYPE_NXS = 0xf300; +const uint16_t RS_SERVICE_TYPE_NXS = 0xf300; +const uint16_t RS_SERVICE_GXSV1_TYPE_IDENTITY = 0xf301; +const uint16_t RS_SERVICE_GXSV1_TYPE_PHOTO = 0xf302; +const uint16_t RS_SERVICE_GXSV1_TYPE_WIKI = 0xf303; +const uint16_t RS_SERVICE_GXSV1_TYPE_WIRE = 0xf304; +const uint16_t RS_SERVICE_GXSV1_TYPE_FORUMS = 0xf305; +const uint16_t RS_SERVICE_GXSV1_TYPE_POSTED = 0xf306; +const uint16_t RS_SERVICE_GXSV1_TYPE_CHANNELS = 0xf307; + +const uint16_t RS_SERVICE_GXSV2_TYPE_IDENTITY = 0xf311; +const uint16_t RS_SERVICE_GXSV2_TYPE_PHOTO = 0xf312; +const uint16_t RS_SERVICE_GXSV2_TYPE_WIKI = 0xf313; +const uint16_t RS_SERVICE_GXSV2_TYPE_WIRE = 0xf314; +const uint16_t RS_SERVICE_GXSV2_TYPE_FORUMS = 0xf315; +const uint16_t RS_SERVICE_GXSV2_TYPE_POSTED = 0xf316; +const uint16_t RS_SERVICE_GXSV2_TYPE_CHANNELS = 0xf317; + + /* Example Versions (VEG) of New Cache Services */ +const uint16_t RS_SERVICE_VEG_TYPE_IDENTITY = 0xf320; +const uint16_t RS_SERVICE_VEG_TYPE_PHOTO = 0xf321; +const uint16_t RS_SERVICE_VEG_TYPE_WIKI = 0xf322; +const uint16_t RS_SERVICE_VEG_TYPE_WIRE = 0xf323; +const uint16_t RS_SERVICE_VEG_TYPE_FORUMS = 0xf324; +const uint16_t RS_SERVICE_VEG_TYPE_POSTED = 0xf325; /***************** IDS ALLOCATED FOR PLUGINS ******************/ diff --git a/libretroshare/src/services/p3forumsv2.cc b/libretroshare/src/services/p3forumsVEG.cc similarity index 74% rename from libretroshare/src/services/p3forumsv2.cc rename to libretroshare/src/services/p3forumsVEG.cc index 8f87c53e7..2e3a81ceb 100644 --- a/libretroshare/src/services/p3forumsv2.cc +++ b/libretroshare/src/services/p3forumsVEG.cc @@ -23,7 +23,7 @@ * */ -#include "services/p3forumsv2.h" +#include "services/p3forumsVEG.h" #include "util/rsrandom.h" #include @@ -32,7 +32,7 @@ * #define FORUMV2_DEBUG 1 ****/ -RsForumsV2 *rsForumsV2 = NULL; +RsForumsVEG *rsForumsVEG = NULL; @@ -40,8 +40,8 @@ RsForumsV2 *rsForumsV2 = NULL; /******************* Startup / Tick ******************************************/ /********************************************************************************/ -p3ForumsV2::p3ForumsV2(uint16_t type) - :p3GxsDataService(type, new ForumDataProxy()), mForumMtx("p3ForumsV2"), mUpdated(true) +p3ForumsVEG::p3ForumsVEG(uint16_t type) + :p3GxsDataServiceVEG(type, new ForumDataProxy()), mForumMtx("p3ForumsV2"), mUpdated(true) { { RsStackMutex stack(mForumMtx); /********** STACK LOCKED MTX ******/ @@ -55,9 +55,9 @@ p3ForumsV2::p3ForumsV2(uint16_t type) } -int p3ForumsV2::tick() +int p3ForumsVEG::tick() { - //std::cerr << "p3ForumsV2::tick()"; + //std::cerr << "p3ForumsVEG::tick()"; //std::cerr << std::endl; fakeprocessrequests(); @@ -65,7 +65,7 @@ int p3ForumsV2::tick() return 0; } -bool p3ForumsV2::updated() +bool p3ForumsVEG::updated() { RsStackMutex stack(mForumMtx); /********** STACK LOCKED MTX ******/ @@ -80,35 +80,35 @@ bool p3ForumsV2::updated() /* Data Requests */ -bool p3ForumsV2::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) +bool p3ForumsVEG::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) { generateToken(token); - std::cerr << "p3ForumsV2::requestGroupInfo() gets Token: " << token << std::endl; + std::cerr << "p3ForumsVEG::requestGroupInfo() gets Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); return true; } -bool p3ForumsV2::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) +bool p3ForumsVEG::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) { generateToken(token); - std::cerr << "p3ForumsV2::requestMsgInfo() gets Token: " << token << std::endl; + std::cerr << "p3ForumsVEG::requestMsgInfo() gets Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds); return true; } -bool p3ForumsV2::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds) +bool p3ForumsVEG::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds) { generateToken(token); - std::cerr << "p3ForumsV2::requestMsgRelatedInfo() gets Token: " << token << std::endl; + std::cerr << "p3ForumsVEG::requestMsgRelatedInfo() gets Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); return true; } /* Generic Lists */ -bool p3ForumsV2::getGroupList( const uint32_t &token, std::list &groupIds) +bool p3ForumsVEG::getGroupList( const uint32_t &token, std::list &groupIds) { uint32_t status; uint32_t reqtype; @@ -118,19 +118,19 @@ bool p3ForumsV2::getGroupList( const uint32_t &token, std::list &msgIds) +bool p3ForumsVEG::getMsgList( const uint32_t &token, std::list &msgIds) { uint32_t status; uint32_t reqtype; @@ -153,19 +153,19 @@ bool p3ForumsV2::getMsgList( const uint32_t &token, std::list &groupInfo) +bool p3ForumsVEG::getGroupSummary( const uint32_t &token, std::list &groupInfo) { uint32_t status; uint32_t reqtype; @@ -187,19 +187,19 @@ bool p3ForumsV2::getGroupSummary( const uint32_t &token, std::list &msgInfo) +bool p3ForumsVEG::getMsgSummary( const uint32_t &token, std::list &msgInfo) { uint32_t status; uint32_t reqtype; @@ -223,19 +223,19 @@ bool p3ForumsV2::getMsgSummary( const uint32_t &token, std::listsetMessageStatus(msgId, status, statusMask); } -bool p3ForumsV2::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask) +bool p3ForumsVEG::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask) { return mForumProxy->setGroupStatus(groupId, status, statusMask); } -bool p3ForumsV2::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) +bool p3ForumsVEG::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) { return mForumProxy->setGroupSubscribeFlags(groupId, subscribeFlags, subscribeMask); } -bool p3ForumsV2::setMessageServiceString(const std::string &msgId, const std::string &str) +bool p3ForumsVEG::setMessageServiceString(const std::string &msgId, const std::string &str) { return mForumProxy->setMessageServiceString(msgId, str); } -bool p3ForumsV2::setGroupServiceString(const std::string &grpId, const std::string &str) +bool p3ForumsVEG::setGroupServiceString(const std::string &grpId, const std::string &str) { return mForumProxy->setGroupServiceString(grpId, str); } -bool p3ForumsV2::groupRestoreKeys(const std::string &groupId) +bool p3ForumsVEG::groupRestoreKeys(const std::string &groupId) { return false; } -bool p3ForumsV2::groupShareKeys(const std::string &groupId, std::list& peers) +bool p3ForumsVEG::groupShareKeys(const std::string &groupId, std::list& peers) { return false; } @@ -398,7 +398,7 @@ bool p3ForumsV2::groupShareKeys(const std::string &groupId, std::list groupIds; groupIds.push_back(group.mMeta.mGroupId); // It will just return this one. - std::cerr << "p3ForumsV2::createGroup() Generating Request Token: " << token << std::endl; + std::cerr << "p3ForumsVEG::createGroup() Generating Request Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); return true; @@ -448,12 +448,12 @@ bool p3ForumsV2::createGroup(uint32_t &token, RsForumV2Group &group, bool isNew) -bool p3ForumsV2::createMsg(uint32_t &token, RsForumV2Msg &msg, bool isNew) +bool p3ForumsVEG::createMsg(uint32_t &token, RsForumV2Msg &msg, bool isNew) { if (msg.mMeta.mGroupId.empty()) { /* new photo */ - std::cerr << "p3ForumsV2::createForumMsg() Missing MsgID"; + std::cerr << "p3ForumsVEG::createForumMsg() Missing MsgID"; std::cerr << std::endl; return false; } @@ -461,7 +461,7 @@ bool p3ForumsV2::createMsg(uint32_t &token, RsForumV2Msg &msg, bool isNew) /* check if its a mod or new msg */ if (msg.mMeta.mOrigMsgId.empty()) { - std::cerr << "p3ForumsV2::createForumMsg() New Msg"; + std::cerr << "p3ForumsVEG::createForumMsg() New Msg"; std::cerr << std::endl; /* new msg, generate a new OrigMsgId */ @@ -470,18 +470,18 @@ bool p3ForumsV2::createMsg(uint32_t &token, RsForumV2Msg &msg, bool isNew) } else { - std::cerr << "p3ForumsV2::createForumMsg() Modified Msg"; + std::cerr << "p3ForumsVEG::createForumMsg() Modified Msg"; std::cerr << std::endl; /* mod msg, keep orig msg id, generate a new MsgId */ msg.mMeta.mMsgId = genRandomId(); } - std::cerr << "p3ForumsV2::createForumMsg() GroupId: " << msg.mMeta.mGroupId; + std::cerr << "p3ForumsVEG::createForumMsg() GroupId: " << msg.mMeta.mGroupId; std::cerr << std::endl; - std::cerr << "p3ForumsV2::createForumMsg() MsgId: " << msg.mMeta.mMsgId; + std::cerr << "p3ForumsVEG::createForumMsg() MsgId: " << msg.mMeta.mMsgId; std::cerr << std::endl; - std::cerr << "p3ForumsV2::createForumMsg() OrigMsgId: " << msg.mMeta.mOrigMsgId; + std::cerr << "p3ForumsVEG::createForumMsg() OrigMsgId: " << msg.mMeta.mOrigMsgId; std::cerr << std::endl; { @@ -494,11 +494,11 @@ bool p3ForumsV2::createMsg(uint32_t &token, RsForumV2Msg &msg, bool isNew) // Fake a request to return the MsgMetaData. generateToken(token); uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptions opts; // NULL is good. + RsTokReqOptionsVEG opts; // NULL is good. std::list msgIds; msgIds.push_back(msg.mMeta.mMsgId); // It will just return this one. - std::cerr << "p3ForumsV2::createMsg() Generating Request Token: " << token << std::endl; + std::cerr << "p3ForumsVEG::createMsg() Generating Request Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); return true; @@ -609,7 +609,7 @@ bool ForumDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta) -bool p3ForumsV2::generateDummyData() +bool p3ForumsVEG::generateDummyData() { /* so we want to generate 100's of forums */ #define MAX_FORUMS 10 //100 @@ -673,7 +673,7 @@ bool p3ForumsV2::generateDummyData() mGroups.push_back(forum); - //std::cerr << "p3ForumsV2::generateDummyData() Generated Forum: " << forum.mMeta; + //std::cerr << "p3ForumsVEG::generateDummyData() Generated Forum: " << forum.mMeta; //std::cerr << std::endl; } @@ -725,7 +725,7 @@ bool p3ForumsV2::generateDummyData() mMsgs.push_back(msg); - //std::cerr << "p3ForumsV2::generateDummyData() Generated Thread: " << msg.mMeta; + //std::cerr << "p3ForumsVEG::generateDummyData() Generated Thread: " << msg.mMeta; //std::cerr << std::endl; } @@ -778,7 +778,7 @@ bool p3ForumsV2::generateDummyData() mMsgs.push_back(msg); - //std::cerr << "p3ForumsV2::generateDummyData() Generated Child Msg: " << msg.mMeta; + //std::cerr << "p3ForumsVEG::generateDummyData() Generated Child Msg: " << msg.mMeta; //std::cerr << std::endl; } diff --git a/libretroshare/src/services/p3forumsv2.h b/libretroshare/src/services/p3forumsVEG.h similarity index 89% rename from libretroshare/src/services/p3forumsv2.h rename to libretroshare/src/services/p3forumsVEG.h index f6c8d627f..4bf01a5b1 100644 --- a/libretroshare/src/services/p3forumsv2.h +++ b/libretroshare/src/services/p3forumsVEG.h @@ -26,9 +26,9 @@ #ifndef P3_FORUMSV2_SERVICE_HEADER #define P3_FORUMSV2_SERVICE_HEADER -#include "services/p3gxsservice.h" +#include "services/p3gxsserviceVEG.h" -#include "retroshare/rsforumsv2.h" +#include "retroshare/rsforumsVEG.h" #include #include @@ -37,7 +37,7 @@ * */ -class ForumDataProxy: public GxsDataProxy +class ForumDataProxy: public GxsDataProxyVEG { public: @@ -57,11 +57,11 @@ virtual bool convertMsgToMetaData(void *msgData, RsMsgMetaData &meta); -class p3ForumsV2: public p3GxsDataService, public RsForumsV2 +class p3ForumsVEG: public p3GxsDataServiceVEG, public RsForumsVEG { public: - p3ForumsV2(uint16_t type); + p3ForumsVEG(uint16_t type); virtual int tick(); @@ -72,9 +72,9 @@ virtual bool updated(); /* Data Requests */ -virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds); -virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds); -virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds); +virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); +virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); +virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds); /* Generic Lists */ virtual bool getGroupList( const uint32_t &token, std::list &groupIds); diff --git a/libretroshare/src/services/p3gxsservice.cc b/libretroshare/src/services/p3gxsserviceVEG.cc similarity index 77% rename from libretroshare/src/services/p3gxsservice.cc rename to libretroshare/src/services/p3gxsserviceVEG.cc index 3d4e7e150..5cb5cffcf 100644 --- a/libretroshare/src/services/p3gxsservice.cc +++ b/libretroshare/src/services/p3gxsserviceVEG.cc @@ -23,16 +23,16 @@ * */ -#include "services/p3gxsservice.h" +#include "services/p3gxsserviceVEG.h" -p3GxsService::p3GxsService(uint16_t type) +p3GxsServiceVEG::p3GxsServiceVEG(uint16_t type) :p3Service(type), mReqMtx("p3GxsService") { mNextToken = 0; return; } -bool p3GxsService::generateToken(uint32_t &token) +bool p3GxsServiceVEG::generateToken(uint32_t &token) { RsStackMutex stack(mReqMtx); /****** LOCKED *****/ @@ -41,7 +41,7 @@ bool p3GxsService::generateToken(uint32_t &token) return true; } -bool p3GxsService::storeRequest(const uint32_t &token, const uint32_t &ansType, const RsTokReqOptions &opts, const uint32_t &type, const std::list &ids) +bool p3GxsServiceVEG::storeRequest(const uint32_t &token, const uint32_t &ansType, const RsTokReqOptionsVEG &opts, const uint32_t &type, const std::list &ids) { RsStackMutex stack(mReqMtx); /****** LOCKED *****/ @@ -60,7 +60,7 @@ bool p3GxsService::storeRequest(const uint32_t &token, const uint32_t &ansTyp } -bool p3GxsService::clearRequest(const uint32_t &token) +bool p3GxsServiceVEG::clearRequest(const uint32_t &token) { RsStackMutex stack(mReqMtx); /****** LOCKED *****/ @@ -77,7 +77,7 @@ bool p3GxsService::clearRequest(const uint32_t &token) return true; } -bool p3GxsService::updateRequestStatus(const uint32_t &token, const uint32_t &status) +bool p3GxsServiceVEG::updateRequestStatus(const uint32_t &token, const uint32_t &status) { RsStackMutex stack(mReqMtx); /****** LOCKED *****/ @@ -94,7 +94,7 @@ bool p3GxsService::updateRequestStatus(const uint32_t &token, const uint32_t &st return true; } -bool p3GxsService::updateRequestInList(const uint32_t &token, std::list ids) +bool p3GxsServiceVEG::updateRequestInList(const uint32_t &token, std::list ids) { RsStackMutex stack(mReqMtx); /****** LOCKED *****/ @@ -116,7 +116,7 @@ bool p3GxsService::updateRequestInList(const uint32_t &token, std::list ids) +bool p3GxsServiceVEG::updateRequestOutList(const uint32_t &token, std::list ids) { RsStackMutex stack(mReqMtx); /****** LOCKED *****/ @@ -138,7 +138,7 @@ bool p3GxsService::updateRequestOutList(const uint32_t &token, std::list data) +bool p3GxsServiceVEG::updateRequestData(const uint32_t &token, std::map data) { RsStackMutex stack(mReqMtx); /****** LOCKED *****/ @@ -160,7 +160,7 @@ bool p3GxsService::updateRequestData(const uint32_t &token, std::map &tokens) +bool p3GxsServiceVEG::tokenList(std::list &tokens) { RsStackMutex stack(mReqMtx); /****** LOCKED *****/ @@ -196,7 +196,7 @@ bool p3GxsService::tokenList(std::list &tokens) return true; } -bool p3GxsService::popRequestInList(const uint32_t &token, std::string &id) +bool p3GxsServiceVEG::popRequestInList(const uint32_t &token, std::string &id) { RsStackMutex stack(mReqMtx); /****** LOCKED *****/ @@ -220,7 +220,7 @@ bool p3GxsService::popRequestInList(const uint32_t &token, std::string &id) } -bool p3GxsService::popRequestOutList(const uint32_t &token, std::string &id) +bool p3GxsServiceVEG::popRequestOutList(const uint32_t &token, std::string &id) { RsStackMutex stack(mReqMtx); /****** LOCKED *****/ @@ -244,7 +244,7 @@ bool p3GxsService::popRequestOutList(const uint32_t &token, std::string &id) } -bool p3GxsService::loadRequestOutList(const uint32_t &token, std::list &ids) +bool p3GxsServiceVEG::loadRequestOutList(const uint32_t &token, std::list &ids) { RsStackMutex stack(mReqMtx); /****** LOCKED *****/ @@ -270,7 +270,7 @@ bool p3GxsService::loadRequestOutList(const uint32_t &token, std::list::iterator it; std::list tokens; @@ -287,7 +287,7 @@ bool p3GxsService::fakeprocessrequests() time_t ts; checkRequestStatus(token, status, reqtype, anstype, ts); - std::cerr << "p3GxsService::fakeprocessrequests() Token: " << token << " Status: " << status << " ReqType: " << reqtype << "Age: " << now - ts << std::endl; + std::cerr << "p3GxsServiceVEG::fakeprocessrequests() Token: " << token << " Status: " << status << " ReqType: " << reqtype << "Age: " << now - ts << std::endl; if (status == GXS_REQUEST_STATUS_PENDING) { @@ -299,13 +299,13 @@ bool p3GxsService::fakeprocessrequests() } else if (status == GXS_REQUEST_STATUS_DONE) { - std::cerr << "p3GxsService::fakeprocessrequests() Clearing Done Request Token: " << token; + std::cerr << "p3GxsServiceVEG::fakeprocessrequests() Clearing Done Request Token: " << token; std::cerr << std::endl; clearRequest(token); } else if (now - ts > MAX_REQUEST_AGE) { - std::cerr << "p3GxsService::fakeprocessrequests() Clearing Old Request Token: " << token; + std::cerr << "p3GxsServiceVEG::fakeprocessrequests() Clearing Old Request Token: " << token; std::cerr << std::endl; clearRequest(token); } @@ -334,14 +334,14 @@ bool p3GxsService::fakeprocessrequests() * ****/ -GxsDataProxy::GxsDataProxy() +GxsDataProxyVEG::GxsDataProxyVEG() :mDataMtx("GxsDataProxyMtx") { return; } -static bool checkGroupFilter(const RsTokReqOptions &opts, const RsGroupMetaData &group) +static bool checkGroupFilter(const RsTokReqOptionsVEG &opts, const RsGroupMetaData &group) { bool statusMatch = false; if (opts.mStatusMask) @@ -428,7 +428,7 @@ static bool checkGroupFilter(const RsTokReqOptions &opts, const RsGroupMetaData } -static bool checkMsgFilter(const RsTokReqOptions &opts, const RsMsgMetaData &msg) +static bool checkMsgFilter(const RsTokReqOptionsVEG &opts, const RsMsgMetaData &msg) { bool statusMatch = false; if (opts.mStatusMask) @@ -488,7 +488,7 @@ static bool checkMsgFilter(const RsTokReqOptions &opts, const RsMsgMetaData &msg } -bool GxsDataProxy::filterGroupList(const RsTokReqOptions &opts, std::list &groupIds) +bool GxsDataProxyVEG::filterGroupList(const RsTokReqOptionsVEG &opts, std::list &groupIds) { std::list::iterator it; for(it = groupIds.begin(); it != groupIds.end(); ) @@ -517,7 +517,7 @@ bool GxsDataProxy::filterGroupList(const RsTokReqOptions &opts, std::list &msgIds) +bool GxsDataProxyVEG::filterMsgList(const RsTokReqOptionsVEG &opts, std::list &msgIds) { std::list::iterator it; for(it = msgIds.begin(); it != msgIds.end(); ) @@ -547,14 +547,14 @@ bool GxsDataProxy::filterMsgList(const RsTokReqOptions &opts, std::list &groupIds, std::list &outGroupIds) +bool GxsDataProxyVEG::getGroupList( uint32_t &token, const RsTokReqOptionsVEG &opts, const std::list &groupIds, std::list &outGroupIds) { /* CASEs that this handles ... * 1) if groupIds is Empty... return all groupIds. * 2) else copy list. * */ - std::cerr << "GxsDataProxy::getGroupList()"; + std::cerr << "GxsDataProxyVEG::getGroupList()"; std::cerr << std::endl; if (groupIds.size() == 0) @@ -579,14 +579,14 @@ bool GxsDataProxy::getGroupList( uint32_t &token, const RsTokReqOptions &opt } -bool GxsDataProxy::getMsgList( uint32_t &token, const RsTokReqOptions &opts, const std::list &groupIds, std::list &outMsgIds) +bool GxsDataProxyVEG::getMsgList( uint32_t &token, const RsTokReqOptionsVEG &opts, const std::list &groupIds, std::list &outMsgIds) { /* CASEs this handles. * Input is groupList + Flags. * 1) No Flags => All Messages in those Groups. * */ - std::cerr << "GxsDataProxy::getMsgList()"; + std::cerr << "GxsDataProxyVEG::getMsgList()"; std::cerr << std::endl; @@ -597,20 +597,20 @@ bool GxsDataProxy::getMsgList( uint32_t &token, const RsTokReqOptions &opt // Can only choose one of these two. if (opts.mOptions & RS_TOKREQOPT_MSG_ORIGMSG) { - std::cerr << "GxsDataProxy::getMsgList() MSG_ORIGMSG"; + std::cerr << "GxsDataProxyVEG::getMsgList() MSG_ORIGMSG"; std::cerr << std::endl; onlyOrigMsgs = true; } else if (opts.mOptions & RS_TOKREQOPT_MSG_LATEST) { - std::cerr << "GxsDataProxy::getMsgList() MSG_LATEST"; + std::cerr << "GxsDataProxyVEG::getMsgList() MSG_LATEST"; std::cerr << std::endl; onlyLatestMsgs = true; } if (opts.mOptions & RS_TOKREQOPT_MSG_THREAD) { - std::cerr << "GxsDataProxy::getMsgList() MSG_THREAD"; + std::cerr << "GxsDataProxyVEG::getMsgList() MSG_THREAD"; std::cerr << std::endl; onlyThreadHeadMsgs = true; } @@ -648,7 +648,7 @@ bool GxsDataProxy::getMsgList( uint32_t &token, const RsTokReqOptions &opt bool addMsg = false; if (oit == origMsgTs.end()) { - std::cerr << "GxsDataProxy::getMsgList() Found New OrigMsgId: "; + std::cerr << "GxsDataProxyVEG::getMsgList() Found New OrigMsgId: "; std::cerr << mit->second.mOrigMsgId; std::cerr << " MsgId: " << mit->second.mMsgId; std::cerr << " TS: " << mit->second.mPublishTs; @@ -659,7 +659,7 @@ bool GxsDataProxy::getMsgList( uint32_t &token, const RsTokReqOptions &opt // check timestamps. else if (oit->second.second < mit->second.mPublishTs) { - std::cerr << "GxsDataProxy::getMsgList() Found Later Msg. OrigMsgId: "; + std::cerr << "GxsDataProxyVEG::getMsgList() Found Later Msg. OrigMsgId: "; std::cerr << mit->second.mOrigMsgId; std::cerr << " MsgId: " << mit->second.mMsgId; std::cerr << " TS: " << mit->second.mPublishTs; @@ -728,7 +728,7 @@ bool GxsDataProxy::getMsgList( uint32_t &token, const RsTokReqOptions &opt } -bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opts, const std::list &msgIds, std::list &outMsgIds) +bool GxsDataProxyVEG::getMsgRelatedList(uint32_t &token, const RsTokReqOptionsVEG &opts, const std::list &msgIds, std::list &outMsgIds) { /* CASEs this handles. * Input is msgList + Flags. @@ -736,7 +736,7 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt * */ - std::cerr << "GxsDataProxy::getMsgRelatedList()"; + std::cerr << "GxsDataProxyVEG::getMsgRelatedList()"; std::cerr << std::endl; bool onlyLatestMsgs = false; @@ -746,34 +746,34 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt if (opts.mOptions & RS_TOKREQOPT_MSG_LATEST) { - std::cerr << "GxsDataProxy::getMsgRelatedList() MSG_LATEST"; + std::cerr << "GxsDataProxyVEG::getMsgRelatedList() MSG_LATEST"; std::cerr << std::endl; onlyLatestMsgs = true; } else if (opts.mOptions & RS_TOKREQOPT_MSG_VERSIONS) { - std::cerr << "GxsDataProxy::getMsgRelatedList() MSG_VERSIONS"; + std::cerr << "GxsDataProxyVEG::getMsgRelatedList() MSG_VERSIONS"; std::cerr << std::endl; onlyAllVersions = true; } if (opts.mOptions & RS_TOKREQOPT_MSG_PARENT) { - std::cerr << "GxsDataProxy::getMsgRelatedList() MSG_PARENTS"; + std::cerr << "GxsDataProxyVEG::getMsgRelatedList() MSG_PARENTS"; std::cerr << std::endl; onlyChildMsgs = true; } if (opts.mOptions & RS_TOKREQOPT_MSG_THREAD) { - std::cerr << "GxsDataProxy::getMsgRelatedList() MSG_THREAD"; + std::cerr << "GxsDataProxyVEG::getMsgRelatedList() MSG_THREAD"; std::cerr << std::endl; onlyThreadMsgs = true; } if (onlyAllVersions && onlyChildMsgs) { - std::cerr << "GxsDataProxy::getMsgRelatedList() ERROR Incompatible FLAGS (VERSIONS & PARENT)"; + std::cerr << "GxsDataProxyVEG::getMsgRelatedList() ERROR Incompatible FLAGS (VERSIONS & PARENT)"; std::cerr << std::endl; return false; @@ -781,7 +781,7 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt if (onlyAllVersions && onlyThreadMsgs) { - std::cerr << "GxsDataProxy::getMsgRelatedList() ERROR Incompatible FLAGS (VERSIONS & THREAD)"; + std::cerr << "GxsDataProxyVEG::getMsgRelatedList() ERROR Incompatible FLAGS (VERSIONS & THREAD)"; std::cerr << std::endl; return false; @@ -789,7 +789,7 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt if ((!onlyLatestMsgs) && onlyChildMsgs) { - std::cerr << "GxsDataProxy::getMsgRelatedList() ERROR Incompatible FLAGS (!LATEST & PARENT)"; + std::cerr << "GxsDataProxyVEG::getMsgRelatedList() ERROR Incompatible FLAGS (!LATEST & PARENT)"; std::cerr << std::endl; return false; @@ -797,7 +797,7 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt if ((!onlyLatestMsgs) && onlyThreadMsgs) { - std::cerr << "GxsDataProxy::getMsgRelatedList() ERROR Incompatible FLAGS (!LATEST & THREAD)"; + std::cerr << "GxsDataProxyVEG::getMsgRelatedList() ERROR Incompatible FLAGS (!LATEST & THREAD)"; std::cerr << std::endl; return false; @@ -805,7 +805,7 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt if (onlyChildMsgs && onlyThreadMsgs) { - std::cerr << "GxsDataProxy::getMsgRelatedList() ERROR Incompatible FLAGS (PARENT & THREAD)"; + std::cerr << "GxsDataProxyVEG::getMsgRelatedList() ERROR Incompatible FLAGS (PARENT & THREAD)"; std::cerr << std::endl; return false; @@ -815,7 +815,7 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt /* FALL BACK OPTION */ if ((!onlyLatestMsgs) && (!onlyAllVersions) && (!onlyChildMsgs) && (!onlyThreadMsgs)) { - std::cerr << "GxsDataProxy::getMsgRelatedList() FALLBACK -> NO FLAGS -> JUST COPY"; + std::cerr << "GxsDataProxyVEG::getMsgRelatedList() FALLBACK -> NO FLAGS -> JUST COPY"; std::cerr << std::endl; /* just copy */ outMsgIds = msgIds; @@ -870,7 +870,7 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt bool addMsg = false; if (oit == origMsgTs.end()) { - std::cerr << "GxsDataProxy::getMsgRelatedList() Found New OrigMsgId: "; + std::cerr << "GxsDataProxyVEG::getMsgRelatedList() Found New OrigMsgId: "; std::cerr << mit->second.mOrigMsgId; std::cerr << " MsgId: " << mit->second.mMsgId; std::cerr << " TS: " << mit->second.mPublishTs; @@ -881,7 +881,7 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt // check timestamps. else if (oit->second.second < mit->second.mPublishTs) { - std::cerr << "GxsDataProxy::getMsgRelatedList() Found Later Msg. OrigMsgId: "; + std::cerr << "GxsDataProxyVEG::getMsgRelatedList() Found Later Msg. OrigMsgId: "; std::cerr << mit->second.mOrigMsgId; std::cerr << " MsgId: " << mit->second.mMsgId; std::cerr << " TS: " << mit->second.mPublishTs; @@ -941,14 +941,14 @@ bool GxsDataProxy::getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opt } -bool GxsDataProxy::createGroup(void *groupData) +bool GxsDataProxyVEG::createGroup(void *groupData) { RsGroupMetaData meta; if (convertGroupToMetaData(groupData, meta)) { if (!isUniqueGroup(meta.mGroupId)) { - std::cerr << "GxsDataProxy::createGroup() ERROR GroupId Clashes, discarding"; + std::cerr << "GxsDataProxyVEG::createGroup() ERROR GroupId Clashes, discarding"; std::cerr << std::endl; return false; } @@ -967,20 +967,20 @@ bool GxsDataProxy::createGroup(void *groupData) return true; } - std::cerr << "GxsDataProxy::createGroup() ERROR Failed to convert Data"; + std::cerr << "GxsDataProxyVEG::createGroup() ERROR Failed to convert Data"; std::cerr << std::endl; return false; } -bool GxsDataProxy::createMsg(void *msgData) +bool GxsDataProxyVEG::createMsg(void *msgData) { RsMsgMetaData meta; if (convertMsgToMetaData(msgData, meta)) { if (!isUniqueMsg(meta.mMsgId)) { - std::cerr << "GxsDataProxy::createMsg() ERROR MsgId Clashes, discarding"; + std::cerr << "GxsDataProxyVEG::createMsg() ERROR MsgId Clashes, discarding"; std::cerr << std::endl; return false; } @@ -993,7 +993,7 @@ bool GxsDataProxy::createMsg(void *msgData) git = mGroupMetaData.find(meta.mGroupId); if (git == mGroupMetaData.end()) { - std::cerr << "GxsDataProxy::createMsg() ERROR GroupId Doesn't exist, discarding"; + std::cerr << "GxsDataProxyVEG::createMsg() ERROR GroupId Doesn't exist, discarding"; std::cerr << std::endl; return false; } @@ -1013,14 +1013,14 @@ bool GxsDataProxy::createMsg(void *msgData) return true; } - std::cerr << "GxsDataProxy::createMsg() ERROR Failed to convert Data"; + std::cerr << "GxsDataProxyVEG::createMsg() ERROR Failed to convert Data"; std::cerr << std::endl; return false; } // Get Message Status - is retrived via MessageSummary. -bool GxsDataProxy::setMessageStatus(const std::string &msgId,const uint32_t status, const uint32_t statusMask) +bool GxsDataProxyVEG::setMessageStatus(const std::string &msgId,const uint32_t status, const uint32_t statusMask) { RsStackMutex stack(mDataMtx); /***** LOCKED *****/ @@ -1030,7 +1030,7 @@ bool GxsDataProxy::setMessageStatus(const std::string &msgId,const uint32_t stat if (mit == mMsgMetaData.end()) { // error. - std::cerr << "GxsDataProxy::getMsgSummary() Error Finding MsgId: " << msgId; + std::cerr << "GxsDataProxyVEG::getMsgSummary() Error Finding MsgId: " << msgId; std::cerr << std::endl; } else @@ -1044,7 +1044,7 @@ bool GxsDataProxy::setMessageStatus(const std::string &msgId,const uint32_t stat return true; } -bool GxsDataProxy::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask) +bool GxsDataProxyVEG::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask) { RsStackMutex stack(mDataMtx); /***** LOCKED *****/ @@ -1054,7 +1054,7 @@ bool GxsDataProxy::setGroupStatus(const std::string &groupId, const uint32_t sta if (git == mGroupMetaData.end()) { // error. - std::cerr << "GxsDataProxy::setGroupStatus() Error Finding GroupId: " << groupId; + std::cerr << "GxsDataProxyVEG::setGroupStatus() Error Finding GroupId: " << groupId; std::cerr << std::endl; } else @@ -1069,7 +1069,7 @@ bool GxsDataProxy::setGroupStatus(const std::string &groupId, const uint32_t sta } -bool GxsDataProxy::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) +bool GxsDataProxyVEG::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) { RsStackMutex stack(mDataMtx); /***** LOCKED *****/ @@ -1079,7 +1079,7 @@ bool GxsDataProxy::setGroupSubscribeFlags(const std::string &groupId, uint32_t s if (git == mGroupMetaData.end()) { // error. - std::cerr << "GxsDataProxy::setGroupSubscribeFlags() Error Finding GroupId: " << groupId; + std::cerr << "GxsDataProxyVEG::setGroupSubscribeFlags() Error Finding GroupId: " << groupId; std::cerr << std::endl; } else @@ -1093,7 +1093,7 @@ bool GxsDataProxy::setGroupSubscribeFlags(const std::string &groupId, uint32_t s return true; } -bool GxsDataProxy::setMessageServiceString(const std::string &msgId, const std::string &str) +bool GxsDataProxyVEG::setMessageServiceString(const std::string &msgId, const std::string &str) { RsStackMutex stack(mDataMtx); /***** LOCKED *****/ @@ -1103,7 +1103,7 @@ bool GxsDataProxy::setMessageServiceString(const std::string &msgId, const std:: if (mit == mMsgMetaData.end()) { // error. - std::cerr << "GxsDataProxy::setMessageServiceString() Error Finding MsgId: " << msgId; + std::cerr << "GxsDataProxyVEG::setMessageServiceString() Error Finding MsgId: " << msgId; std::cerr << std::endl; } else @@ -1115,7 +1115,7 @@ bool GxsDataProxy::setMessageServiceString(const std::string &msgId, const std:: return true; } -bool GxsDataProxy::setGroupServiceString(const std::string &groupId, const std::string &str) +bool GxsDataProxyVEG::setGroupServiceString(const std::string &groupId, const std::string &str) { RsStackMutex stack(mDataMtx); /***** LOCKED *****/ @@ -1125,7 +1125,7 @@ bool GxsDataProxy::setGroupServiceString(const std::string &groupId, const std:: if (git == mGroupMetaData.end()) { // error. - std::cerr << "GxsDataProxy::setGroupServiceString() Error Finding GroupId: " << groupId; + std::cerr << "GxsDataProxyVEG::setGroupServiceString() Error Finding GroupId: " << groupId; std::cerr << std::endl; } else @@ -1139,22 +1139,22 @@ bool GxsDataProxy::setGroupServiceString(const std::string &groupId, const std:: /* These Functions must be overloaded to complete the service */ -bool GxsDataProxy::convertGroupToMetaData(void *groupData, RsGroupMetaData &meta) +bool GxsDataProxyVEG::convertGroupToMetaData(void *groupData, RsGroupMetaData &meta) { - std::cerr << "GxsDataProxy::convert fn ... please implement!"; + std::cerr << "GxsDataProxyVEG::convert fn ... please implement!"; std::cerr << std::endl; return false; } -bool GxsDataProxy::convertMsgToMetaData(void *groupData, RsMsgMetaData &meta) +bool GxsDataProxyVEG::convertMsgToMetaData(void *groupData, RsMsgMetaData &meta) { - std::cerr << "GxsDataProxy::convert fn ... please implement!"; + std::cerr << "GxsDataProxyVEG::convert fn ... please implement!"; std::cerr << std::endl; return false; } /* extract Data */ -bool GxsDataProxy::getGroupSummary(const std::string &groupId, RsGroupMetaData &groupSummary) +bool GxsDataProxyVEG::getGroupSummary(const std::string &groupId, RsGroupMetaData &groupSummary) { RsStackMutex stack(mDataMtx); /***** LOCKED *****/ @@ -1164,7 +1164,7 @@ bool GxsDataProxy::getGroupSummary(const std::string &groupId, RsGroupMetaData & if (mit == mGroupMetaData.end()) { // error. - std::cerr << "GxsDataProxy::getGroupMetaData() Error Finding GroupId: " << groupId; + std::cerr << "GxsDataProxyVEG::getGroupMetaData() Error Finding GroupId: " << groupId; std::cerr << std::endl; return false; } @@ -1176,7 +1176,7 @@ bool GxsDataProxy::getGroupSummary(const std::string &groupId, RsGroupMetaData & } -bool GxsDataProxy::getMsgSummary(const std::string &msgId, RsMsgMetaData &msgSummary) +bool GxsDataProxyVEG::getMsgSummary(const std::string &msgId, RsMsgMetaData &msgSummary) { RsStackMutex stack(mDataMtx); /***** LOCKED *****/ @@ -1186,7 +1186,7 @@ bool GxsDataProxy::getMsgSummary(const std::string &msgId, RsMsgMetaData &msgSum if (mit == mMsgMetaData.end()) { // error. - std::cerr << "GxsDataProxy::getMsgSummary() Error Finding MsgId: " << msgId; + std::cerr << "GxsDataProxyVEG::getMsgSummary() Error Finding MsgId: " << msgId; std::cerr << std::endl; } else @@ -1198,7 +1198,7 @@ bool GxsDataProxy::getMsgSummary(const std::string &msgId, RsMsgMetaData &msgSum /* extract Data */ -bool GxsDataProxy::getGroupSummary(const std::list &groupIds, std::list &groupSummary) +bool GxsDataProxyVEG::getGroupSummary(const std::list &groupIds, std::list &groupSummary) { std::list::const_iterator it; for(it = groupIds.begin(); it != groupIds.end(); it++) @@ -1211,7 +1211,7 @@ bool GxsDataProxy::getGroupSummary(const std::list &groupIds, std:: if (mit == mGroupMetaData.end()) { // error. - std::cerr << "GxsDataProxy::getGroupMetaData() Error Finding GroupId: " << *it; + std::cerr << "GxsDataProxyVEG::getGroupMetaData() Error Finding GroupId: " << *it; std::cerr << std::endl; } else @@ -1223,7 +1223,7 @@ bool GxsDataProxy::getGroupSummary(const std::list &groupIds, std:: } -bool GxsDataProxy::getMsgSummary(const std::list &msgIds, std::list &msgSummary) +bool GxsDataProxyVEG::getMsgSummary(const std::list &msgIds, std::list &msgSummary) { std::list::const_iterator it; for(it = msgIds.begin(); it != msgIds.end(); it++) @@ -1236,7 +1236,7 @@ bool GxsDataProxy::getMsgSummary(const std::list &msgIds, std::list if (mit == mMsgMetaData.end()) { // error. - std::cerr << "GxsDataProxy::getMsgSummary() Error Finding MsgId: " << *it; + std::cerr << "GxsDataProxyVEG::getMsgSummary() Error Finding MsgId: " << *it; std::cerr << std::endl; } else @@ -1248,7 +1248,7 @@ bool GxsDataProxy::getMsgSummary(const std::list &msgIds, std::list } -bool GxsDataProxy::getGroupData(const std::string &groupId, void * &groupData) +bool GxsDataProxyVEG::getGroupData(const std::string &groupId, void * &groupData) { RsStackMutex stack(mDataMtx); /***** LOCKED *****/ @@ -1258,7 +1258,7 @@ bool GxsDataProxy::getGroupData(const std::string &groupId, void * &groupData) if (mit == mGroupData.end()) { // error. - std::cerr << "GxsDataProxy::getGroupData() Error Finding GroupId: " << groupId; + std::cerr << "GxsDataProxyVEG::getGroupData() Error Finding GroupId: " << groupId; std::cerr << std::endl; return false; } @@ -1269,7 +1269,7 @@ bool GxsDataProxy::getGroupData(const std::string &groupId, void * &groupData) return true; } -bool GxsDataProxy::getMsgData(const std::string &msgId, void * &msgData) +bool GxsDataProxyVEG::getMsgData(const std::string &msgId, void * &msgData) { RsStackMutex stack(mDataMtx); /***** LOCKED *****/ @@ -1279,7 +1279,7 @@ bool GxsDataProxy::getMsgData(const std::string &msgId, void * &msgData) if (mit == mMsgData.end()) { // error. - std::cerr << "GxsDataProxy::getMsgData() Error Finding MsgId: " << msgId; + std::cerr << "GxsDataProxyVEG::getMsgData() Error Finding MsgId: " << msgId; std::cerr << std::endl; return false; } @@ -1291,7 +1291,7 @@ bool GxsDataProxy::getMsgData(const std::string &msgId, void * &msgData) } #if 0 -bool GxsDataProxy::getGroupData(const std::list &groupIds, std::list &groupData) +bool GxsDataProxyVEG::getGroupData(const std::list &groupIds, std::list &groupData) { std::list::const_iterator it; for(it = groupIds.begin(); it != groupIds.end(); it++) @@ -1304,7 +1304,7 @@ bool GxsDataProxy::getGroupData(const std::list &groupIds, std::lis if (mit == mGroupData.end()) { // error. - std::cerr << "GxsDataProxy::getGroupData() Error Finding GroupId: " << *it; + std::cerr << "GxsDataProxyVEG::getGroupData() Error Finding GroupId: " << *it; std::cerr << std::endl; } else @@ -1315,7 +1315,7 @@ bool GxsDataProxy::getGroupData(const std::list &groupIds, std::lis return true; } -bool GxsDataProxy::getMsgData(const std::list &msgIds, std::list &msgData) +bool GxsDataProxyVEG::getMsgData(const std::list &msgIds, std::list &msgData) { std::list::const_iterator it; for(it = msgIds.begin(); it != msgIds.end(); it++) @@ -1328,7 +1328,7 @@ bool GxsDataProxy::getMsgData(const std::list &msgIds, std::list &msgIds, std::list toClear; std::list::iterator cit; @@ -1392,11 +1392,11 @@ bool p3GxsDataService::fakeprocessrequests() for(it = mRequests.begin(); it != mRequests.end(); it++) { - //std::cerr << "p3GxsDataService::fakeprocessrequests() Token: " << it->second.token << " Status: " << it->second.status << " ReqType: " << it->second.reqType << " Age: " << now - it->second.reqTime << std::endl; + //std::cerr << "p3GxsDataServiceVEG::fakeprocessrequests() Token: " << it->second.token << " Status: " << it->second.status << " ReqType: " << it->second.reqType << " Age: " << now - it->second.reqTime << std::endl; if (it->second.status == GXS_REQUEST_STATUS_PENDING) { - std::cerr << "p3GxsDataService::fakeprocessrequests() Processing Token: " << it->second.token << " Status: " << it->second.status << " ReqType: " << it->second.reqType << " Age: " << now - it->second.reqTime << std::endl; + std::cerr << "p3GxsDataServiceVEG::fakeprocessrequests() Processing Token: " << it->second.token << " Status: " << it->second.status << " ReqType: " << it->second.reqType << " Age: " << now - it->second.reqTime << std::endl; it->second.status = GXS_REQUEST_STATUS_PARTIAL; /* PROCESS REQUEST! */ switch(it->second.reqType) @@ -1421,13 +1421,13 @@ bool p3GxsDataService::fakeprocessrequests() } else if (it->second.status == GXS_REQUEST_STATUS_DONE) { - std::cerr << "p3GxsDataService::fakeprocessrequests() Clearing Done Request Token: " << it->second.token; + std::cerr << "p3GxsDataServiceVEG::fakeprocessrequests() Clearing Done Request Token: " << it->second.token; std::cerr << std::endl; toClear.push_back(it->second.token); } else if (now - it->second.reqTime > MAX_REQUEST_AGE) { - std::cerr << "p3GxsDataService::fakeprocessrequests() Clearing Old Request Token: " << it->second.token; + std::cerr << "p3GxsDataServiceVEG::fakeprocessrequests() Clearing Old Request Token: " << it->second.token; std::cerr << std::endl; toClear.push_back(it->second.token); } diff --git a/libretroshare/src/services/p3gxsservice.h b/libretroshare/src/services/p3gxsserviceVEG.h similarity index 86% rename from libretroshare/src/services/p3gxsservice.h rename to libretroshare/src/services/p3gxsserviceVEG.h index e1580aeef..096ebdfb0 100644 --- a/libretroshare/src/services/p3gxsservice.h +++ b/libretroshare/src/services/p3gxsserviceVEG.h @@ -27,7 +27,7 @@ #define P3_GXS_SERVICE_HEADER #include "services/p3service.h" -#include "retroshare/rsidentity.h" +#include "retroshare/rsidentityVEG.h" /* * This class provides useful generic support for GXS style services. @@ -54,7 +54,7 @@ class gxsRequest uint32_t ansType; uint32_t reqType; - RsTokReqOptions Options; + RsTokReqOptionsVEG Options; uint32_t status; @@ -64,18 +64,18 @@ class gxsRequest }; -class p3GxsService: public p3Service +class p3GxsServiceVEG: public p3Service { protected: - p3GxsService(uint16_t type); + p3GxsServiceVEG(uint16_t type); public: //virtual ~p3Service() { p3Service::~p3Service(); return; } bool generateToken(uint32_t &token); -bool storeRequest(const uint32_t &token, const uint32_t &ansType, const RsTokReqOptions &opts, const uint32_t &type, const std::list &ids); +bool storeRequest(const uint32_t &token, const uint32_t &ansType, const RsTokReqOptionsVEG &opts, const uint32_t &type, const std::list &ids); bool clearRequest(const uint32_t &token); bool updateRequestStatus(const uint32_t &token, const uint32_t &status); @@ -103,15 +103,15 @@ virtual bool fakeprocessrequests(); }; -class GxsDataProxy +class GxsDataProxyVEG { public: - GxsDataProxy(); + GxsDataProxyVEG(); -virtual bool getGroupList( uint32_t &token, const RsTokReqOptions &opts, const std::list &groupIds, std::list &outGroupIds); -virtual bool getMsgList( uint32_t &token, const RsTokReqOptions &opts, const std::list &groupIds, std::list &outMsgIds); -virtual bool getMsgRelatedList(uint32_t &token, const RsTokReqOptions &opts, const std::list &msgIds, std::list &outMsgIds); +virtual bool getGroupList( uint32_t &token, const RsTokReqOptionsVEG &opts, const std::list &groupIds, std::list &outGroupIds); +virtual bool getMsgList( uint32_t &token, const RsTokReqOptionsVEG &opts, const std::list &groupIds, std::list &outMsgIds); +virtual bool getMsgRelatedList(uint32_t &token, const RsTokReqOptionsVEG &opts, const std::list &msgIds, std::list &outMsgIds); /* This functions return a token - which can be used to retrieve the RsGroupMetaData, later @@ -157,8 +157,8 @@ virtual bool setGroupServiceString(const std::string &grpId, const std::string & protected: - bool filterGroupList(const RsTokReqOptions &opts, std::list &groupIds); - bool filterMsgList(const RsTokReqOptions &opts, std::list &msgIds); + bool filterGroupList(const RsTokReqOptionsVEG &opts, std::list &groupIds); + bool filterMsgList(const RsTokReqOptionsVEG &opts, std::list &msgIds); RsMutex mDataMtx; @@ -172,17 +172,17 @@ virtual bool setGroupServiceString(const std::string &grpId, const std::string & }; -class p3GxsDataService: public p3GxsService +class p3GxsDataServiceVEG: public p3GxsServiceVEG { public: - p3GxsDataService(uint16_t type, GxsDataProxy *proxy); + p3GxsDataServiceVEG(uint16_t type, GxsDataProxyVEG *proxy); virtual bool fakeprocessrequests(); protected: - GxsDataProxy *mProxy; + GxsDataProxyVEG *mProxy; }; diff --git a/libretroshare/src/services/p3idserviceVEG.cc b/libretroshare/src/services/p3idserviceVEG.cc new file mode 100644 index 000000000..27b16a6a4 --- /dev/null +++ b/libretroshare/src/services/p3idserviceVEG.cc @@ -0,0 +1,1552 @@ +/* + * libretroshare/src/services p3idservice.cc + * + * Id interface for RetroShare. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "services/p3idserviceVEG.h" + +#include "util/rsrandom.h" +#include +#include +#include + +/**** + * #define ID_DEBUG 1 + ****/ + +#define ID_REQUEST_LIST 0x0001 +#define ID_REQUEST_IDENTITY 0x0002 +#define ID_REQUEST_REPUTATION 0x0003 +#define ID_REQUEST_OPINION 0x0004 + +RsIdentityVEG *rsIdentityVEG = NULL; + + +/********************************************************************************/ +/******************* Startup / Tick ******************************************/ +/********************************************************************************/ + +p3IdServiceVEG::p3IdServiceVEG(uint16_t type) + :p3GxsDataServiceVEG(type, new IdDataProxy()), mIdMtx("p3IdService"), mUpdated(true) +{ + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + mIdProxy = (IdDataProxy *) mProxy; + return; +} + + +int p3IdServiceVEG::tick() +{ + //std::cerr << "p3IdServiceVEG::tick()"; + //std::cerr << std::endl; + + fakeprocessrequests(); + // Disable for now. + // background_tick(); + + return 0; +} + +bool p3IdServiceVEG::updated() +{ + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + if (mUpdated) + { + mUpdated = false; + return true; + } + return false; +} + + + + /* Data Requests */ +bool p3IdServiceVEG::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) +{ + generateToken(token); + std::cerr << "p3IdServiceVEG::requestGroupInfo() gets Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); + + return true; +} + +bool p3IdServiceVEG::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) +{ + generateToken(token); + std::cerr << "p3IdServiceVEG::requestMsgInfo() gets Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds); + + return true; +} + +bool p3IdServiceVEG::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds) +{ + generateToken(token); + std::cerr << "p3IdServiceVEG::requestMsgRelatedInfo() gets Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); + + return true; +} + + /* Generic Lists */ +bool p3IdServiceVEG::getGroupList( const uint32_t &token, std::list &groupIds) +{ + uint32_t status; + uint32_t reqtype; + uint32_t anstype; + time_t ts; + checkRequestStatus(token, status, reqtype, anstype, ts); + + if (anstype != RS_TOKREQ_ANSTYPE_LIST) + { + std::cerr << "p3IdServiceVEG::getGroupList() ERROR AnsType Wrong" << std::endl; + return false; + } + + if (reqtype != GXS_REQUEST_TYPE_GROUPS) + { + std::cerr << "p3IdServiceVEG::getGroupList() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3IdServiceVEG::getGroupList() ERROR Status Incomplete" << std::endl; + return false; + } + + bool ans = loadRequestOutList(token, groupIds); + updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + + return ans; +} + + + + +bool p3IdServiceVEG::getMsgList( const uint32_t &token, std::list &msgIds) +{ + uint32_t status; + uint32_t reqtype; + uint32_t anstype; + time_t ts; + checkRequestStatus(token, status, reqtype, anstype, ts); + + if (anstype != RS_TOKREQ_ANSTYPE_LIST) + { + std::cerr << "p3IdServiceVEG::getMsgList() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3IdServiceVEG::getMsgList() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3IdServiceVEG::getMsgList() ERROR Status Incomplete" << std::endl; + return false; + } + + bool ans = loadRequestOutList(token, msgIds); + updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + + return ans; +} + + + /* Generic Summary */ +bool p3IdServiceVEG::getGroupSummary( const uint32_t &token, std::list &groupInfo) +{ + uint32_t status; + uint32_t reqtype; + uint32_t anstype; + time_t ts; + checkRequestStatus(token, status, reqtype, anstype, ts); + + if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY) + { + std::cerr << "p3IdServiceVEG::getGroupSummary() ERROR AnsType Wrong" << std::endl; + return false; + } + + if (reqtype != GXS_REQUEST_TYPE_GROUPS) + { + std::cerr << "p3IdServiceVEG::getGroupSummary() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3IdServiceVEG::getGroupSummary() ERROR Status Incomplete" << std::endl; + return false; + } + + std::list groupIds; + bool ans = loadRequestOutList(token, groupIds); + updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + + /* convert to RsGroupMetaData */ + mProxy->getGroupSummary(groupIds, groupInfo); + + return ans; +} + +bool p3IdServiceVEG::getMsgSummary( const uint32_t &token, std::list &msgInfo) +{ + uint32_t status; + uint32_t reqtype; + uint32_t anstype; + time_t ts; + checkRequestStatus(token, status, reqtype, anstype, ts); + + if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY) + { + std::cerr << "p3IdServiceVEG::getMsgSummary() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3IdServiceVEG::getMsgSummary() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3IdServiceVEG::getMsgSummary() ERROR Status Incomplete" << std::endl; + return false; + } + + std::list msgIds; + bool ans = loadRequestOutList(token, msgIds); + updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + + /* convert to RsMsgMetaData */ + mProxy->getMsgSummary(msgIds, msgInfo); + + return ans; +} + + + /* Specific Service Data */ +bool p3IdServiceVEG::getGroupData(const uint32_t &token, RsIdGroup &group) +{ + uint32_t status; + uint32_t reqtype; + uint32_t anstype; + time_t ts; + checkRequestStatus(token, status, reqtype, anstype, ts); + + + if (anstype != RS_TOKREQ_ANSTYPE_DATA) + { + std::cerr << "p3IdServiceVEG::getGroupData() ERROR AnsType Wrong" << std::endl; + return false; + } + + if (reqtype != GXS_REQUEST_TYPE_GROUPS) + { + std::cerr << "p3IdServiceVEG::getGroupData() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3IdServiceVEG::getGroupData() ERROR Status Incomplete" << std::endl; + return false; + } + + std::string id; + if (!popRequestOutList(token, id)) + { + /* finished */ + updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + return false; + } + + /* convert to RsIdGroup */ + bool ans = mIdProxy->getGroup(id, group); + return ans; +} + + +bool p3IdServiceVEG::getMsgData(const uint32_t &token, RsIdMsg &msg) +{ + uint32_t status; + uint32_t reqtype; + uint32_t anstype; + time_t ts; + checkRequestStatus(token, status, reqtype, anstype, ts); + + + if (anstype != RS_TOKREQ_ANSTYPE_DATA) + { + std::cerr << "p3IdServiceVEG::getMsgData() ERROR AnsType Wrong" << std::endl; + return false; + } + + if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) + { + std::cerr << "p3IdServiceVEG::getMsgData() ERROR ReqType Wrong" << std::endl; + return false; + } + + if (status != GXS_REQUEST_STATUS_COMPLETE) + { + std::cerr << "p3IdServiceVEG::getMsgData() ERROR Status Incomplete" << std::endl; + return false; + } + + std::string id; + if (!popRequestOutList(token, id)) + { + /* finished */ + updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + return false; + } + + /* convert to RsIdMsg */ + bool ans = mIdProxy->getMsg(id, msg); + return ans; +} + + + + /* Poll */ +uint32_t p3IdServiceVEG::requestStatus(const uint32_t token) +{ + uint32_t status; + uint32_t reqtype; + uint32_t anstype; + time_t ts; + checkRequestStatus(token, status, reqtype, anstype, ts); + + return status; +} + + + /* Cancel Request */ +bool p3IdServiceVEG::cancelRequest(const uint32_t &token) +{ + return clearRequest(token); +} + + ////////////////////////////////////////////////////////////////////////////// +bool p3IdServiceVEG::setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask) +{ + return mIdProxy->setMessageStatus(msgId, status, statusMask); +} + +bool p3IdServiceVEG::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask) +{ + return mIdProxy->setGroupStatus(groupId, status, statusMask); +} + +bool p3IdServiceVEG::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) +{ + return mIdProxy->setGroupSubscribeFlags(groupId, subscribeFlags, subscribeMask); +} + +bool p3IdServiceVEG::setMessageServiceString(const std::string &msgId, const std::string &str) +{ + return mIdProxy->setMessageServiceString(msgId, str); +} + +bool p3IdServiceVEG::setGroupServiceString(const std::string &grpId, const std::string &str) +{ + return mIdProxy->setGroupServiceString(grpId, str); +} + + +bool p3IdServiceVEG::groupRestoreKeys(const std::string &groupId) +{ + return false; +} + +bool p3IdServiceVEG::groupShareKeys(const std::string &groupId, std::list& peers) +{ + return false; +} + + +/********************************************************************************************/ + + +std::string p3IdServiceVEG::genRandomId() +{ + std::string randomId; + for(int i = 0; i < 20; i++) + { + randomId += (char) ('a' + (RSRandom::random_u32() % 26)); + } + + return randomId; +} + +bool p3IdServiceVEG::createGroup(uint32_t &token, RsIdGroup &group, bool isNew) +{ + if (group.mMeta.mGroupId.empty()) + { + /* new photo */ + + /* generate a temp id */ + group.mMeta.mGroupId = genRandomId(); + } + else + { + std::cerr << "p3IdServiceVEG::createGroup() Group with existing Id... dropping"; + std::cerr << std::endl; + return false; + } + + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + mUpdated = true; + mIdProxy->addGroup(group); + } + + // Fake a request to return the GroupMetaData. + generateToken(token); + uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; + RsTokReqOptionsVEG opts; // NULL is good. + std::list groupIds; + groupIds.push_back(group.mMeta.mGroupId); // It will just return this one. + + std::cerr << "p3IdServiceVEG::createGroup() Generating Request Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); + + + return true; +} + + + + +bool p3IdServiceVEG::createMsg(uint32_t &token, RsIdMsg &msg, bool isNew) +{ + if (msg.mMeta.mGroupId.empty()) + { + /* new photo */ + std::cerr << "p3IdServiceVEG::createMsg() Missing MsgID"; + std::cerr << std::endl; + return false; + } + + /* check if its a mod or new msg */ + if (msg.mMeta.mOrigMsgId.empty()) + { + std::cerr << "p3IdServiceVEG::createMsg() New Msg"; + std::cerr << std::endl; + + /* new msg, generate a new OrigMsgId */ + msg.mMeta.mOrigMsgId = genRandomId(); + msg.mMeta.mMsgId = msg.mMeta.mOrigMsgId; + } + else + { + std::cerr << "p3IdServiceVEG::createMsg() Modified Msg"; + std::cerr << std::endl; + + /* mod msg, keep orig msg id, generate a new MsgId */ + msg.mMeta.mMsgId = genRandomId(); + } + + std::cerr << "p3IdServiceVEG::createMsg() GroupId: " << msg.mMeta.mGroupId; + std::cerr << std::endl; + std::cerr << "p3IdServiceVEG::createMsg() MsgId: " << msg.mMeta.mMsgId; + std::cerr << std::endl; + std::cerr << "p3IdServiceVEG::createMsg() OrigMsgId: " << msg.mMeta.mOrigMsgId; + std::cerr << std::endl; + + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + mUpdated = true; + mIdProxy->addMsg(msg); + } + + // Fake a request to return the MsgMetaData. + generateToken(token); + uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; + RsTokReqOptionsVEG opts; // NULL is good. + std::list msgIds; + msgIds.push_back(msg.mMeta.mMsgId); // It will just return this one. + + std::cerr << "p3IdServiceVEG::createMsg() Generating Request Token: " << token << std::endl; + storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); + + return true; +} + + + +/********************************************************************************************/ + + + +bool IdDataProxy::getGroup(const std::string &id, RsIdGroup &group) +{ + void *groupData = NULL; + RsGroupMetaData meta; + if (getGroupData(id, groupData) && getGroupSummary(id, meta)) + { + RsIdGroup *pG = (RsIdGroup *) groupData; + group = *pG; + + // update definitive version of the metadata. + group.mMeta = meta; + + std::cerr << "IdDataProxy::getGroup() Id: " << id; + std::cerr << " MetaData: " << meta << " DataPointer: " << groupData; + std::cerr << std::endl; + return true; + } + + std::cerr << "IdDataProxy::getGroup() FAILED Id: " << id; + std::cerr << std::endl; + + return false; +} + +bool IdDataProxy::getMsg(const std::string &id, RsIdMsg &msg) +{ + void *msgData = NULL; + RsMsgMetaData meta; + if (getMsgData(id, msgData) && getMsgSummary(id, meta)) + { + RsIdMsg *pM = (RsIdMsg *) msgData; + // Shallow copy of thumbnail. + msg = *pM; + + // update definitive version of the metadata. + msg.mMeta = meta; + + std::cerr << "IdDataProxy::getMsg() Id: " << id; + std::cerr << " MetaData: " << meta << " DataPointer: " << msgData; + std::cerr << std::endl; + return true; + } + + std::cerr << "IdDataProxy::getMsg() FAILED Id: " << id; + std::cerr << std::endl; + + return false; +} + +bool IdDataProxy::addGroup(const RsIdGroup &group) +{ + // Make duplicate. + RsIdGroup *pG = new RsIdGroup(); + *pG = group; + + std::cerr << "IdDataProxy::addGroup()"; + std::cerr << " MetaData: " << pG->mMeta << " DataPointer: " << pG; + std::cerr << std::endl; + + return createGroup(pG); +} + + +bool IdDataProxy::addMsg(const RsIdMsg &msg) +{ + // Make duplicate. + RsIdMsg *pM = new RsIdMsg(); + *pM = msg; + + std::cerr << "IdDataProxy::addMsg()"; + std::cerr << " MetaData: " << pM->mMeta << " DataPointer: " << pM; + std::cerr << std::endl; + + return createMsg(pM); +} + + + + /* These Functions must be overloaded to complete the service */ +bool IdDataProxy::convertGroupToMetaData(void *groupData, RsGroupMetaData &meta) +{ + RsIdGroup *group = (RsIdGroup *) groupData; + meta = group->mMeta; + + return true; +} + +bool IdDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta) +{ + RsIdMsg *page = (RsIdMsg *) msgData; + meta = page->mMeta; + + return true; +} + + + + +/************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ + +#if 0 + +/* details are updated */ +bool p3IdServiceVEG::updateIdentity(RsIdData &data) +{ + if (data.mKeyId.empty()) + { + /* new photo */ + + /* generate a temp id */ + data.mKeyId = genRandomId(); + + if (data.mIdType & RSID_TYPE_REALID) + { + data.mGpgIdHash = genRandomId(); + } + else + { + data.mGpgIdHash = ""; + } + + } + + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + mUpdated = true; + + /* add / modify */ + mIds[data.mKeyId] = data; + + return true; +} + + + + +bool p3IdServiceVEG::updateOpinion(RsIdOpinion &opinion) +{ + if (opinion.mKeyId.empty()) + { + /* new photo */ + std::cerr << "p3IdServiceVEG::updateOpinion() Missing KeyId"; + std::cerr << std::endl; + return false; + } + + /* check if its a mod or new page */ + if (opinion.mPeerId.empty()) + { + std::cerr << "p3IdServiceVEG::updateOpinion() Missing PeerId"; + std::cerr << std::endl; + return false; + } + + std::cerr << "p3IdServiceVEG::updateOpinion() KeyId: " << opinion.mKeyId; + std::cerr << std::endl; + std::cerr << "p3IdServiceVEG::updateOpinion() PeerId: " << opinion.mPeerId; + std::cerr << std::endl; + + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + mUpdated = true; + + std::map >::iterator it; + std::map::iterator oit; + + it = mOpinions.find(opinion.mKeyId); + if (it == mOpinions.end()) + { + std::map emptyMap; + mOpinions[opinion.mKeyId] = emptyMap; + + it = mOpinions.find(opinion.mKeyId); + } + + (it->second)[opinion.mPeerId] = opinion; + return true; +} + + +#endif + + + +void p3IdServiceVEG::generateDummyData() +{ + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + /* grab all the gpg ids... and make some ids */ + + std::list gpgids; + std::list::iterator it; + + rsPeers->getGPGAllList(gpgids); + + std::string ownId = rsPeers->getGPGOwnId(); + gpgids.push_back(ownId); + + int i; + for(it = gpgids.begin(); it != gpgids.end(); it++) + { + /* create one or two for each one */ + int nIds = 1 + (RSRandom::random_u32() % 2); + for(i = 0; i < nIds; i++) + { + RsIdGroup id; + + RsPeerDetails details; + + //id.mKeyId = genRandomId(); + id.mMeta.mGroupId = genRandomId(); + id.mIdType = RSID_TYPE_REALID; + id.mGpgIdHash = genRandomId(); + + if (rsPeers->getPeerDetails(*it, details)) + { + std::ostringstream out; + out << details.name << "_" << i + 1; + + //id.mNickname = out.str(); + id.mMeta.mGroupName = out.str(); + + id.mGpgIdKnown = true; + + id.mGpgId = *it; + id.mGpgName = details.name; + id.mGpgEmail = details.email; + + if (*it == ownId) + { + id.mIdType |= RSID_RELATION_YOURSELF; + } + else if (rsPeers->isGPGAccepted(*it)) + { + id.mIdType |= RSID_RELATION_FRIEND; + } + else + { + id.mIdType |= RSID_RELATION_OTHER; + } + + } + else + { + std::cerr << "p3IdServiceVEG::generateDummyData() missing" << std::endl; + std::cerr << std::endl; + + id.mIdType |= RSID_RELATION_OTHER; + //id.mNickname = genRandomId(); + id.mMeta.mGroupName = genRandomId(); + id.mGpgIdKnown = false; + } + + //mIds[id.mKeyId] = id; + mIdProxy->addGroup(id); + } + } + +#define MAX_RANDOM_GPGIDS 10 //1000 +#define MAX_RANDOM_PSEUDOIDS 50 //5000 + + int nFakeGPGs = (RSRandom::random_u32() % MAX_RANDOM_GPGIDS); + int nFakePseudoIds = (RSRandom::random_u32() % MAX_RANDOM_PSEUDOIDS); + + /* make some fake gpg ids */ + for(i = 0; i < nFakeGPGs; i++) + { + RsIdGroup id; + + RsPeerDetails details; + + //id.mKeyId = genRandomId(); + id.mMeta.mGroupId = genRandomId(); + id.mIdType = RSID_TYPE_REALID; + id.mGpgIdHash = genRandomId(); + + id.mIdType |= RSID_RELATION_OTHER; + //id.mNickname = genRandomId(); + id.mMeta.mGroupName = genRandomId(); + id.mGpgIdKnown = false; + id.mGpgId = ""; + id.mGpgName = ""; + id.mGpgEmail = ""; + + //mIds[id.mKeyId] = id; + mIdProxy->addGroup(id); + } + + /* make lots of pseudo ids */ + for(i = 0; i < nFakePseudoIds; i++) + { + RsIdGroup id; + + RsPeerDetails details; + + //id.mKeyId = genRandomId(); + id.mMeta.mGroupId = genRandomId(); + id.mIdType = RSID_TYPE_PSEUDONYM; + id.mGpgIdHash = ""; + + //id.mNickname = genRandomId(); + id.mMeta.mGroupName = genRandomId(); + id.mGpgIdKnown = false; + id.mGpgId = ""; + id.mGpgName = ""; + id.mGpgEmail = ""; + + //mIds[id.mKeyId] = id; + mIdProxy->addGroup(id); + } + + mUpdated = true; + + return; +} + + + +std::string rsIdTypeToString(uint32_t idtype) +{ + std::string str; + if (idtype & RSID_TYPE_REALID) + { + str += "GPGID "; + } + if (idtype & RSID_TYPE_PSEUDONYM) + { + str += "PSEUDO "; + } + if (idtype & RSID_RELATION_YOURSELF) + { + str += "YOURSELF "; + } + if (idtype & RSID_RELATION_FRIEND) + { + str += "FRIEND "; + } + if (idtype & RSID_RELATION_FOF) + { + str += "FOF "; + } + if (idtype & RSID_RELATION_OTHER) + { + str += "OTHER "; + } + if (idtype & RSID_RELATION_UNKNOWN) + { + str += "UNKNOWN "; + } + return str; +} + + + + + + + + +/************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ + + +/* here we are running a background process that calculates the reputation scores + * for each of the IDs.... + * + * As this class will be extensively used by many other threads... it is best + * that we don't block at all. This should be in a background thread. + * Perhaps a generic method to handle this will be advisable.... but we do that later. + * + * To start with we will work from the Posted service. + * + * + * + * So Reputation.... + * Three components: + * 1) Your Opinion: Should override everything else. + * 2) Implicit Factors: Know the associated GPG Key. + * 3) Your Friends Opinions: + * 4) Your Friends Calculated Reputation Scores. + * + * Must make sure that there is no Feedback loop in the Reputation calculation. + * + * So: Our Score + Friends Scores => Local Reputation. + * Local Reputation + Friends Reputations => Final Reputation? + * + * Do we need to 'ignore' Non-scores? + * ---> This becomes like the "Best Comment" algorithm from Reddit... + * Use a statistical mechanism to work out a lower bound on Reputation. + * + * But what if your opinion is wrong?.... well likely your friends will + * get their messages and reply... you'll see the missing message - request it - check reputation etc. + * + * So we are going to have three different scores (Own, Peers, (the neighbour) Hood)... + * + * So next question, when do we need to incrementally calculate the score? + * .... how often do we need to recalculate everything -> this could lead to a flux of messages. + * + * + * + * MORE NOTES: + * + * The Opinion Messages will have to be signed by PGP or SSL Keys, to guarantee that we don't + * multiple votes per person... As the message system doesn't handle uniqueness in this respect, + * we might have to do FULL_CALC for everything - This bit TODO. + * + * This will make IdService quite different to the other GXS services. + */ + +/************************************************************************************/ +/* + * Processing Algorithm: + * - Grab all Groups which have received messages. + * (opt 1)-> grab latest msgs for each of these and process => score. + * (opt 2)-> try incremental system (people probably won't change opinions often -> just set them once) + * --> if not possible, fallback to full calculation. + * + * + */ + + +#define ID_BACKGROUND_PERIOD 60 + +int p3IdServiceVEG::background_tick() +{ + std::cerr << "p3IdServiceVEG::background_tick()"; + std::cerr << std::endl; + + // Run Background Stuff. + background_checkTokenRequest(); + + /* every minute - run a background check */ + time_t now = time(NULL); + bool doCheck = false; + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + if (now - mLastBgCheck > ID_BACKGROUND_PERIOD) + { + doCheck = true; + mLastBgCheck = now; + } + } + + if (doCheck) + { + //addExtraDummyData(); + background_requestGroups(); + } + + + + // Add in new votes + comments. + return 0; +} + + + + +/***** Background Processing **** + * + * Process Each Message - as it arrives. + * + * Update + * + */ +#define ID_BG_IDLE 0 +#define ID_BG_REQUEST_GROUPS 1 +#define ID_BG_REQUEST_UNPROCESSED 2 +#define ID_BG_REQUEST_FULLCALC 3 + +bool p3IdServiceVEG::background_checkTokenRequest() +{ + uint32_t token = 0; + uint32_t phase = 0; + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + if (!mBgProcessing) + { + return false; + } + + token = mBgToken; + phase = mBgPhase; + } + + + uint32_t status; + uint32_t reqtype; + uint32_t anstype; + time_t ts; + checkRequestStatus(token, status, reqtype, anstype, ts); + + if (status == GXS_REQUEST_STATUS_COMPLETE) + { + switch(phase) + { + case ID_BG_REQUEST_GROUPS: + background_requestNewMessages(); + break; + case ID_BG_REQUEST_UNPROCESSED: + background_processNewMessages(); + break; + case ID_BG_REQUEST_FULLCALC: + background_processFullCalc(); + break; + default: + break; + } + } + return true; +} + + +bool p3IdServiceVEG::background_requestGroups() +{ + std::cerr << "p3IdServiceVEG::background_requestGroups()"; + std::cerr << std::endl; + + // grab all the subscribed groups. + uint32_t token = 0; + + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + if (mBgProcessing) + { + std::cerr << "p3IdServiceVEG::background_requestGroups() ERROR Already processing, Skip this cycle"; + std::cerr << std::endl; + return false; + } + + mBgProcessing = true; + mBgPhase = ID_BG_REQUEST_GROUPS; + mBgToken = 0; + } + + uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; + RsTokReqOptionsVEG opts; + std::list groupIds; + + opts.mStatusFilter = RSGXS_GROUP_STATUS_NEWMSG; + opts.mStatusMask = RSGXS_GROUP_STATUS_NEWMSG; + + requestGroupInfo(token, ansType, opts, groupIds); + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + mBgToken = token; + } + + return true; +} + + + +bool p3IdServiceVEG::background_requestNewMessages() +{ + std::cerr << "p3IdServiceVEG::background_requestNewMessages()"; + std::cerr << std::endl; + + std::list modGroupList; + std::list::iterator it; + + std::list groupIds; + uint32_t token = 0; + + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + token = mBgToken; + } + + if (!getGroupSummary(token, modGroupList)) + { + std::cerr << "p3IdServiceVEG::background_requestNewMessages() ERROR No Group List"; + std::cerr << std::endl; + background_cleanup(); + return false; + } + + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + mBgPhase = ID_BG_REQUEST_UNPROCESSED; + mBgToken = 0; + + /* now we process the modGroupList -> a map so we can use it easily later, and create id list too */ + for(it = modGroupList.begin(); it != modGroupList.end(); it++) + { + setGroupStatus(it->mGroupId, 0, RSGXS_GROUP_STATUS_NEWMSG); + + mBgGroupMap[it->mGroupId] = *it; + groupIds.push_back(it->mGroupId); + } + } + + uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; + RsTokReqOptionsVEG opts; + token = 0; + + opts.mStatusFilter = RSGXS_MSG_STATUS_UNPROCESSED; + opts.mStatusMask = RSGXS_MSG_STATUS_UNPROCESSED; + + requestMsgInfo(token, ansType, opts, groupIds); + + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + mBgToken = token; + } + return true; +} + + +bool p3IdServiceVEG::background_processNewMessages() +{ + std::cerr << "p3IdServiceVEG::background_processNewMessages()"; + std::cerr << std::endl; + + std::list newMsgList; + std::list::iterator it; + uint32_t token = 0; + + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + token = mBgToken; + } + + if (!getMsgSummary(token, newMsgList)) + { + std::cerr << "p3IdServiceVEG::background_processNewMessages() ERROR No New Msgs"; + std::cerr << std::endl; + background_cleanup(); + return false; + } + + + /* iterate through the msgs.. update the mBgGroupMap with new data, + * and flag these items as modified - so we rewrite them to the db later. + * + * If a message is not an original -> store groupId for requiring full analysis later. + */ + + std::map::iterator mit; + for(it = newMsgList.begin(); it != newMsgList.end(); it++) + { + std::cerr << "p3IdServiceVEG::background_processNewMessages() new MsgId: " << it->mMsgId; + std::cerr << std::endl; + + /* flag each new vote as processed */ + setMessageStatus(it->mMsgId, 0, RSGXS_MSG_STATUS_UNPROCESSED); + + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + mit = mBgGroupMap.find(it->mGroupId); + if (mit == mBgGroupMap.end()) + { + std::cerr << "p3IdServiceVEG::background_processNewMessages() ERROR missing GroupId: "; + std::cerr << it->mGroupId; + std::cerr << std::endl; + + /* error */ + continue; + } + + if (mit->second.mGroupStatus & ID_LOCAL_STATUS_FULL_CALC_FLAG) + { + std::cerr << "p3IdServiceVEG::background_processNewMessages() Group Already marked FULL_CALC"; + std::cerr << std::endl; + + /* already marked */ + continue; + } + + if (it->mMsgId != it->mOrigMsgId) + { + /* + * not original -> hard, redo calc (alt: could substract previous score) + */ + + std::cerr << "p3IdServiceVEG::background_processNewMessages() Update, mark for FULL_CALC"; + std::cerr << std::endl; + + mit->second.mGroupStatus |= ID_LOCAL_STATUS_FULL_CALC_FLAG; + } + else + { + /* + * Try incremental calculation. + * - extract parameters from group. + * - increment, & save back. + * - flag group as modified. + */ + + std::cerr << "p3IdServiceVEG::background_processNewMessages() NewOpt, Try Inc Calc"; + std::cerr << std::endl; + + mit->second.mGroupStatus |= ID_LOCAL_STATUS_INC_CALC_FLAG; + + std::string serviceString; + IdGroupServiceStrData ssData; + + if (!extractIdGroupCache(serviceString, ssData)) + { + /* error */ + std::cerr << "p3IdServiceVEG::background_processNewMessages() ERROR Extracting"; + std::cerr << std::endl; + } + + /* do calcs */ + std::cerr << "p3IdServiceVEG::background_processNewMessages() Extracted: "; + std::cerr << std::endl; + + /* store it back in */ + std::cerr << "p3IdServiceVEG::background_processNewMessages() Stored: "; + std::cerr << std::endl; + + if (!encodeIdGroupCache(serviceString, ssData)) + { + /* error */ + std::cerr << "p3IdServiceVEG::background_processNewMessages() ERROR Storing"; + std::cerr << std::endl; + } + } + } + + + /* now iterate through groups again + * -> update status as we go + * -> record one requiring a full analyssis + */ + + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + std::cerr << "p3IdServiceVEG::background_processNewMessages() Checking Groups for Calc Type"; + std::cerr << std::endl; + + for(mit = mBgGroupMap.begin(); mit != mBgGroupMap.end(); mit++) + { + if (mit->second.mGroupStatus & ID_LOCAL_STATUS_FULL_CALC_FLAG) + { + std::cerr << "p3IdServiceVEG::background_processNewMessages() FullCalc for: "; + std::cerr << mit->second.mGroupId; + std::cerr << std::endl; + + mBgFullCalcGroups.push_back(mit->second.mGroupId); + } + else if (mit->second.mGroupStatus & ID_LOCAL_STATUS_INC_CALC_FLAG) + { + std::cerr << "p3IdServiceVEG::background_processNewMessages() IncCalc done for: "; + std::cerr << mit->second.mGroupId; + std::cerr << std::endl; + + /* set Cache */ + setGroupServiceString(mit->second.mGroupId, mit->second.mServiceString); + } + else + { + /* why is it here? error. */ + std::cerr << "p3IdServiceVEG::background_processNewMessages() ERROR for: "; + std::cerr << mit->second.mGroupId; + std::cerr << std::endl; + } + } + } + + return background_FullCalcRequest(); +} + + +bool p3IdServiceVEG::encodeIdGroupCache(std::string &str, const IdGroupServiceStrData &data) +{ + char line[RSGXS_MAX_SERVICE_STRING]; + + snprintf(line, RSGXS_MAX_SERVICE_STRING, "v1 {%s} {Y:%d O:%d %d %f %f R:%d %d %f %f}", + data.pgpId.c_str(), data.ownScore, + data.opinion.count, data.opinion.nullcount, data.opinion.sum, data.opinion.sumsq, + data.reputation.count, data.reputation.nullcount, data.reputation.sum, data.reputation.sumsq); + + str = line; + return true; +} + + +bool p3IdServiceVEG::extractIdGroupCache(std::string &str, IdGroupServiceStrData &data) +{ + char pgpline[RSGXS_MAX_SERVICE_STRING]; + char scoreline[RSGXS_MAX_SERVICE_STRING]; + + uint32_t iOwnScore; + IdRepCumulScore iOpin; + IdRepCumulScore iRep; + + // split into two parts. + if (2 != sscanf(str.c_str(), "v1 {%[^}]} {%[^}]", pgpline, scoreline)) + { + std::cerr << "p3IdServiceVEG::extractIdGroupCache() Failed to extract Two Parts"; + std::cerr << std::endl; + return false; + } + + std::cerr << "p3IdServiceVEG::extractIdGroupCache() pgpline: " << pgpline; + std::cerr << std::endl; + std::cerr << "p3IdServiceVEG::extractIdGroupCache() scoreline: " << scoreline; + std::cerr << std::endl; + + std::string pgptmp = pgpline; + if (pgptmp.length() > 5) + { + std::cerr << "p3IdServiceVEG::extractIdGroupCache() Believe to have pgpId: " << pgptmp; + std::cerr << std::endl; + data.pgpIdKnown = true; + data.pgpId = pgptmp; + } + else + { + std::cerr << "p3IdServiceVEG::extractIdGroupCache() Think pgpId Invalid"; + std::cerr << std::endl; + data.pgpIdKnown = false; + } + + + if (9 == sscanf(scoreline, " Y:%d O:%d %d %lf %lf R:%d %d %lf %lf", &iOwnScore, + &(iOpin.count), &(iOpin.nullcount), &(iOpin.sum), &(iOpin.sumsq), + &(iRep.count), &(iRep.nullcount), &(iRep.sum), &(iRep.sumsq))) + { + data.ownScore = iOwnScore; + data.opinion = iOpin; + data.reputation = iRep; + return true; + } + + std::cerr << "p3IdServiceVEG::extractIdGroupCache() Failed to extract scores"; + std::cerr << std::endl; + + return false; +} + + + +bool p3IdServiceVEG::background_FullCalcRequest() +{ + /* + * grab an GroupId from List. + * - If empty, we are finished. + * - request all latest mesgs + */ + + std::list groupIds; + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + mBgPhase = ID_BG_REQUEST_FULLCALC; + mBgToken = 0; + mBgGroupMap.clear(); + + if (mBgFullCalcGroups.empty()) + { + /* finished! */ + background_cleanup(); + return true; + + } + + groupIds.push_back(mBgFullCalcGroups.front()); + mBgFullCalcGroups.pop_front(); + + } + + /* request the summary info from the parents */ + uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; + uint32_t token = 0; + RsTokReqOptionsVEG opts; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST; + + requestMsgInfo(token, ansType, opts, groupIds); + + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + mBgToken = token; + } + return true; +} + + + + +bool p3IdServiceVEG::background_processFullCalc() +{ + std::cerr << "p3IdServiceVEG::background_processFullCalc()"; + std::cerr << std::endl; + + std::list msgList; + std::list::iterator it; + + RsIdMsg msg; + + bool validmsgs = false; + + /* calc variables */ + uint32_t opinion_count = 0; + uint32_t opinion_nullcount = 0; + double opinion_sum = 0; + double opinion_sumsq = 0; + + uint32_t rep_count = 0; + uint32_t rep_nullcount = 0; + double rep_sum = 0; + double rep_sumsq = 0; + + while(getMsgData(mBgToken, msg)) + { + std::cerr << "p3IdServiceVEG::background_processFullCalc() Msg:"; + std::cerr << msg; + std::cerr << std::endl; + + validmsgs = true; + + /* for each msg ... extract score, and reputation */ + if (msg.mOpinion != 0) + { + opinion_count++; + opinion_sum += msg.mOpinion; + opinion_sum += (msg.mOpinion * msg.mOpinion); + } + else + { + opinion_nullcount++; + } + + + /* for each msg ... extract score, and reputation */ + if (msg.mReputation != 0) + { + rep_nullcount++; + rep_sum += msg.mReputation; + rep_sum += (msg.mReputation * msg.mReputation); + } + else + { + rep_nullcount++; + } + } + + double opinion_avg = 0; + double opinion_var = 0; + double opinion_frac = 0; + + double rep_avg = 0; + double rep_var = 0; + double rep_frac = 0; + + + if (opinion_count) + { + opinion_avg = opinion_sum / opinion_count; + opinion_var = (opinion_sumsq - opinion_count * opinion_avg * opinion_avg) / opinion_count; + opinion_frac = opinion_count / ((float) (opinion_count + opinion_nullcount)); + } + + if (rep_count) + { + rep_avg = rep_sum / rep_count; + rep_var = (rep_sumsq - rep_count * rep_avg * rep_avg) / rep_count; + rep_frac = rep_count / ((float) (rep_count + rep_nullcount)); + } + + + if (validmsgs) + { + std::string groupId = msg.mMeta.mGroupId; + + std::string serviceString; + IdGroupServiceStrData ssData; + + + if (!encodeIdGroupCache(serviceString, ssData)) + { + std::cerr << "p3IdServiceVEG::background_updateVoteCounts() Failed to encode Votes"; + std::cerr << std::endl; + } + else + { + std::cerr << "p3IdServiceVEG::background_updateVoteCounts() Encoded String: " << serviceString; + std::cerr << std::endl; + /* store new result */ + setGroupServiceString(it->mMsgId, serviceString); + } + } + + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + mBgPhase = ID_BG_IDLE; + mBgToken = 0; + } + + return background_FullCalcRequest(); +} + + +bool p3IdServiceVEG::background_cleanup() +{ + std::cerr << "p3IdServiceVEG::background_cleanup()"; + std::cerr << std::endl; + + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + // Cleanup. + mBgProcessing = false; + mBgPhase = ID_BG_IDLE; + mBgToken = 0; + mBgGroupMap.clear(); + mBgFullCalcGroups.clear(); + + return true; +} + + +std::ostream &operator<<(std::ostream &out, const RsIdGroup &grp) +{ + out << "RsIdGroup: Meta: " << grp.mMeta; + out << " IdType: " << grp.mIdType << " GpgIdHash: " << grp.mGpgIdHash; + out << "(((Unusable: ( GpgIdKnown: " << grp.mGpgIdKnown << " GpgId: " << grp.mGpgId; + out << " GpgName: " << grp.mGpgName << " GpgEmail: " << grp.mGpgEmail << ") )))"; + out << std::endl; + + return out; +} + +std::ostream &operator<<(std::ostream &out, const RsIdMsg &msg) +{ + out << "RsIdMsg: Meta: " << msg.mMeta; + //out << " IdType: " << grp.mIdType << " GpgIdHash: " << grp.mGpgIdHash; + out << std::endl; + + return out; +} + diff --git a/libretroshare/src/services/p3idserviceVEG.h b/libretroshare/src/services/p3idserviceVEG.h new file mode 100644 index 000000000..3553612a4 --- /dev/null +++ b/libretroshare/src/services/p3idserviceVEG.h @@ -0,0 +1,186 @@ +/* + * libretroshare/src/services: p3idservice.h + * + * Identity interface for RetroShare. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#ifndef P3_IDENTITY_SERVICE_HEADER +#define P3_IDENTITY_SERVICE_HEADER + +#include "services/p3service.h" +#include "services/p3gxsserviceVEG.h" + +#include "retroshare/rsidentityVEG.h" + +#include +#include + +/* + * Identity Service + * + */ + +class IdDataProxy: public GxsDataProxyVEG +{ + public: + + bool getGroup(const std::string &id, RsIdGroup &group); + bool getMsg(const std::string &id, RsIdMsg &msg); + + bool addGroup(const RsIdGroup &group); + bool addMsg(const RsIdMsg &msg); + + /* These Functions must be overloaded to complete the service */ +virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta); +virtual bool convertMsgToMetaData(void *msgData, RsMsgMetaData &meta); +}; + + + +// INTERNAL DATA TYPES... +// Describes data stored in GroupServiceString. +class IdRepCumulScore +{ +public: + uint32_t count; + uint32_t nullcount; + double sum; + double sumsq; + + // derived parameters: +}; + + +class IdGroupServiceStrData +{ +public: + IdGroupServiceStrData() { pgpIdKnown = false; } + bool pgpIdKnown; + std::string pgpId; + + uint32_t ownScore; + IdRepCumulScore opinion; + IdRepCumulScore reputation; + +}; + +#define ID_LOCAL_STATUS_FULL_CALC_FLAG 0x00010000 +#define ID_LOCAL_STATUS_INC_CALC_FLAG 0x00020000 + +class p3IdServiceVEG: public p3GxsDataServiceVEG, public RsIdentityVEG +{ + public: + + p3IdServiceVEG(uint16_t type); + +virtual int tick(); + + public: + + + /* changed? */ +virtual bool updated(); + + /* From RsTokenService */ + /* Data Requests */ +virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); +virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); +virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds); + + /* Generic Lists */ +virtual bool getGroupList( const uint32_t &token, std::list &groupIds); +virtual bool getMsgList( const uint32_t &token, std::list &msgIds); + + /* Generic Summary */ +virtual bool getGroupSummary( const uint32_t &token, std::list &groupInfo); +virtual bool getMsgSummary( const uint32_t &token, std::list &msgInfo); + + /* Actual Data -> specific to Interface */ +virtual bool getGroupData(const uint32_t &token, RsIdGroup &group); +virtual bool getMsgData(const uint32_t &token, RsIdMsg &msg); + + /* Poll */ +virtual uint32_t requestStatus(const uint32_t token); + + /* Cancel Request */ +virtual bool cancelRequest(const uint32_t &token); + + ////////////////////////////////////////////////////////////////////////////// +virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask); +virtual bool setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask); +virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask); +virtual bool setMessageServiceString(const std::string &msgId, const std::string &str); +virtual bool setGroupServiceString(const std::string &grpId, const std::string &str); + +virtual bool groupRestoreKeys(const std::string &groupId); +virtual bool groupShareKeys(const std::string &groupId, std::list& peers); + +virtual bool createGroup(uint32_t &token, RsIdGroup &group, bool isNew); +virtual bool createMsg(uint32_t &token, RsIdMsg &msg, bool isNew); + + + private: + +virtual void generateDummyData(); + +std::string genRandomId(); + + int background_tick(); + bool background_checkTokenRequest(); + bool background_requestGroups(); + bool background_requestNewMessages(); + bool background_processNewMessages(); + bool background_FullCalcRequest(); + bool background_processFullCalc(); + + bool background_cleanup(); + + bool encodeIdGroupCache(std::string &str, const IdGroupServiceStrData &data); + bool extractIdGroupCache(std::string &str, IdGroupServiceStrData &data); + + IdDataProxy *mIdProxy; + + RsMutex mIdMtx; + + /***** below here is locked *****/ + bool mLastBgCheck; + bool mBgProcessing; + + uint32_t mBgToken; + uint32_t mBgPhase; + + std::map mBgGroupMap; + std::list mBgFullCalcGroups; + + + bool mUpdated; + +#if 0 + std::map mIds; + std::map > mOpinions; + + std::map mReputations; // this is created locally. +#endif + +}; + +#endif diff --git a/libretroshare/src/services/p3photoserviceV2.cc b/libretroshare/src/services/p3photoserviceV2.cc index 142234eab..144a1eace 100644 --- a/libretroshare/src/services/p3photoserviceV2.cc +++ b/libretroshare/src/services/p3photoserviceV2.cc @@ -5,7 +5,7 @@ RsPhotoV2 *rsPhotoV2 = NULL; p3PhotoServiceV2::p3PhotoServiceV2(RsGeneralDataService* gds, RsNetworkExchangeService* nes) - : RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_TYPE_PHOTO) + : RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_GXSV1_TYPE_PHOTO) { diff --git a/libretroshare/src/services/p3photoservice.cc b/libretroshare/src/services/p3photoserviceVEG.cc similarity index 70% rename from libretroshare/src/services/p3photoservice.cc rename to libretroshare/src/services/p3photoserviceVEG.cc index ce37ec59a..ade88b459 100644 --- a/libretroshare/src/services/p3photoservice.cc +++ b/libretroshare/src/services/p3photoserviceVEG.cc @@ -23,22 +23,22 @@ * */ -#include "services/p3photoservice.h" +#include "services/p3photoserviceVEG.h" #include "util/rsrandom.h" /**** * #define PHOTO_DEBUG 1 ****/ -RsPhoto *rsPhoto = NULL; +RsPhotoVEG *rsPhotoVEG = NULL; /********************************************************************************/ /******************* Startup / Tick ******************************************/ /********************************************************************************/ -p3PhotoService::p3PhotoService(uint16_t type) - :p3GxsDataService(type, new PhotoDataProxy()), mPhotoMtx("p3PhotoService"), mUpdated(true) +p3PhotoServiceVEG::p3PhotoServiceVEG(uint16_t type) + :p3GxsDataServiceVEG(type, new PhotoDataProxy()), mPhotoMtx("p3PhotoService"), mUpdated(true) { RsStackMutex stack(mPhotoMtx); /********** STACK LOCKED MTX ******/ @@ -47,9 +47,9 @@ p3PhotoService::p3PhotoService(uint16_t type) } -int p3PhotoService::tick() +int p3PhotoServiceVEG::tick() { - //std::cerr << "p3PhotoService::tick()"; + //std::cerr << "p3PhotoServiceVEG::tick()"; //std::cerr << std::endl; fakeprocessrequests(); @@ -57,7 +57,7 @@ int p3PhotoService::tick() return 0; } -bool p3PhotoService::updated() +bool p3PhotoServiceVEG::updated() { RsStackMutex stack(mPhotoMtx); /********** STACK LOCKED MTX ******/ @@ -71,35 +71,35 @@ bool p3PhotoService::updated() /* Data Requests */ -bool p3PhotoService::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) +bool p3PhotoServiceVEG::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) { generateToken(token); - std::cerr << "p3PhotoService::requestGroupInfo() gets Token: " << token << std::endl; + std::cerr << "p3PhotoServiceVEG::requestGroupInfo() gets Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); return true; } -bool p3PhotoService::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) +bool p3PhotoServiceVEG::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) { generateToken(token); - std::cerr << "p3PhotoService::requestMsgInfo() gets Token: " << token << std::endl; + std::cerr << "p3PhotoServiceVEG::requestMsgInfo() gets Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds); return true; } -bool p3PhotoService::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds) +bool p3PhotoServiceVEG::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds) { generateToken(token); - std::cerr << "p3PhotoService::requestMsgRelatedInfo() gets Token: " << token << std::endl; + std::cerr << "p3PhotoServiceVEG::requestMsgRelatedInfo() gets Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); return true; } /* Generic Lists */ -bool p3PhotoService::getGroupList( const uint32_t &token, std::list &groupIds) +bool p3PhotoServiceVEG::getGroupList( const uint32_t &token, std::list &groupIds) { uint32_t status; uint32_t reqtype; @@ -109,19 +109,19 @@ bool p3PhotoService::getGroupList( const uint32_t &token, std::list &msgIds) +bool p3PhotoServiceVEG::getMsgList( const uint32_t &token, std::list &msgIds) { uint32_t status; uint32_t reqtype; @@ -144,19 +144,19 @@ bool p3PhotoService::getMsgList( const uint32_t &token, std::list &groupInfo) +bool p3PhotoServiceVEG::getGroupSummary( const uint32_t &token, std::list &groupInfo) { uint32_t status; uint32_t reqtype; @@ -178,19 +178,19 @@ bool p3PhotoService::getGroupSummary( const uint32_t &token, std::list &msgInfo) +bool p3PhotoServiceVEG::getMsgSummary( const uint32_t &token, std::list &msgInfo) { uint32_t status; uint32_t reqtype; @@ -214,19 +214,19 @@ bool p3PhotoService::getMsgSummary( const uint32_t &token, std::listsetMessageStatus(msgId, status, statusMask); } -bool p3PhotoService::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask) +bool p3PhotoServiceVEG::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask) { return mPhotoProxy->setGroupStatus(groupId, status, statusMask); } -bool p3PhotoService::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) +bool p3PhotoServiceVEG::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) { return mPhotoProxy->setGroupSubscribeFlags(groupId, subscribeFlags, subscribeMask); } -bool p3PhotoService::setMessageServiceString(const std::string &msgId, const std::string &str) +bool p3PhotoServiceVEG::setMessageServiceString(const std::string &msgId, const std::string &str) { return mPhotoProxy->setMessageServiceString(msgId, str); } -bool p3PhotoService::setGroupServiceString(const std::string &grpId, const std::string &str) +bool p3PhotoServiceVEG::setGroupServiceString(const std::string &grpId, const std::string &str) { return mPhotoProxy->setGroupServiceString(grpId, str); } -bool p3PhotoService::groupRestoreKeys(const std::string &groupId) +bool p3PhotoServiceVEG::groupRestoreKeys(const std::string &groupId) { return false; } -bool p3PhotoService::groupShareKeys(const std::string &groupId, std::list& peers) +bool p3PhotoServiceVEG::groupShareKeys(const std::string &groupId, std::list& peers) { return false; } @@ -390,7 +390,7 @@ bool p3PhotoService::groupShareKeys(const std::string &groupId, std::list groupIds; groupIds.push_back(album.mMeta.mGroupId); // It will just return this one. - std::cerr << "p3PhotoService::submitAlbumDetails() Generating Request Token: " << token << std::endl; + std::cerr << "p3PhotoServiceVEG::submitAlbumDetails() Generating Request Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); return true; } -bool p3PhotoService::submitPhoto(uint32_t &token, RsPhotoPhoto &photo, bool isNew) +bool p3PhotoServiceVEG::submitPhoto(uint32_t &token, RsPhotoPhoto &photo, bool isNew) { if (photo.mMeta.mGroupId.empty()) { /* new photo */ - std::cerr << "p3PhotoService::submitPhoto() Missing GroupID: ERROR"; + std::cerr << "p3PhotoServiceVEG::submitPhoto() Missing GroupID: ERROR"; std::cerr << std::endl; return false; } @@ -452,18 +452,18 @@ bool p3PhotoService::submitPhoto(uint32_t &token, RsPhotoPhoto &photo, bool isNe { /* new (Original Msg) photo */ photo.mMeta.mOrigMsgId = photo.mMeta.mMsgId; - std::cerr << "p3PhotoService::submitPhoto() New Msg"; + std::cerr << "p3PhotoServiceVEG::submitPhoto() New Msg"; std::cerr << std::endl; } else { - std::cerr << "p3PhotoService::submitPhoto() Updated Msg"; + std::cerr << "p3PhotoServiceVEG::submitPhoto() Updated Msg"; std::cerr << std::endl; } photo.mModFlags = 0; // These are always cleared. - std::cerr << "p3PhotoService::submitPhoto() OrigMsgId: " << photo.mMeta.mOrigMsgId; + std::cerr << "p3PhotoServiceVEG::submitPhoto() OrigMsgId: " << photo.mMeta.mOrigMsgId; std::cerr << " MsgId: " << photo.mMeta.mMsgId; std::cerr << std::endl; @@ -477,11 +477,11 @@ bool p3PhotoService::submitPhoto(uint32_t &token, RsPhotoPhoto &photo, bool isNe // Fake a request to return the MsgMetaData. generateToken(token); uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptions opts; // NULL is good. + RsTokReqOptionsVEG opts; // NULL is good. std::list msgIds; msgIds.push_back(photo.mMeta.mMsgId); // It will just return this one. - std::cerr << "p3PhotoService::submitPhoto() Generating Request Token: " << token << std::endl; + std::cerr << "p3PhotoServiceVEG::submitPhoto() Generating Request Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); return true; @@ -600,7 +600,7 @@ bool PhotoDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta) /********************************************************************************************/ -std::string p3PhotoService::genRandomId() +std::string p3PhotoServiceVEG::genRandomId() { std::string randomId; for(int i = 0; i < 20; i++) diff --git a/libretroshare/src/services/p3photoservice.h b/libretroshare/src/services/p3photoserviceVEG.h similarity index 88% rename from libretroshare/src/services/p3photoservice.h rename to libretroshare/src/services/p3photoserviceVEG.h index 16e4f2cc5..87dbaa9f7 100644 --- a/libretroshare/src/services/p3photoservice.h +++ b/libretroshare/src/services/p3photoserviceVEG.h @@ -23,11 +23,11 @@ * */ -#ifndef P3_PHOTO_SERVICE_HEADER -#define P3_PHOTO_SERVICE_HEADER +#ifndef P3_PHOTO_SERVICE_VEG_HEADER +#define P3_PHOTO_SERVICE_VEG_HEADER -#include "services/p3gxsservice.h" -#include "retroshare/rsphoto.h" +#include "services/p3gxsserviceVEG.h" +#include "retroshare/rsphotoVEG.h" #include #include @@ -48,7 +48,7 @@ */ -class PhotoDataProxy: public GxsDataProxy +class PhotoDataProxy: public GxsDataProxyVEG { public: @@ -66,11 +66,11 @@ virtual bool convertMsgToMetaData(void *groupData, RsMsgMetaData &meta); -class p3PhotoService: public p3GxsDataService, public RsPhoto +class p3PhotoServiceVEG: public p3GxsDataServiceVEG, public RsPhotoVEG { public: - p3PhotoService(uint16_t type); + p3PhotoServiceVEG(uint16_t type); virtual int tick(); @@ -83,9 +83,9 @@ virtual int tick(); virtual bool updated(); /* Data Requests */ -virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds); -virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds); -virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds); +virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); +virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); +virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds); /* Generic Lists */ virtual bool getGroupList( const uint32_t &token, std::list &groupIds); diff --git a/libretroshare/src/services/p3posted.cc b/libretroshare/src/services/p3postedVEG.cc similarity index 78% rename from libretroshare/src/services/p3posted.cc rename to libretroshare/src/services/p3postedVEG.cc index 0685205e7..63acd3cba 100644 --- a/libretroshare/src/services/p3posted.cc +++ b/libretroshare/src/services/p3postedVEG.cc @@ -23,7 +23,7 @@ * */ -#include "services/p3posted.h" +#include "services/p3postedVEG.h" #include "util/rsrandom.h" #include #include @@ -33,15 +33,15 @@ * #define POSTED_DEBUG 1 ****/ -RsPosted *rsPosted = NULL; +RsPostedVEG *rsPostedVEG = NULL; /********************************************************************************/ /******************* Startup / Tick ******************************************/ /********************************************************************************/ -p3PostedService::p3PostedService(uint16_t type) - :p3GxsDataService(type, new PostedDataProxy()), mPostedMtx("p3PostedService"), mUpdated(true) +p3PostedServiceVEG::p3PostedServiceVEG(uint16_t type) + :p3GxsDataServiceVEG(type, new PostedDataProxy()), mPostedMtx("p3PostedService"), mUpdated(true) { { RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ @@ -71,9 +71,9 @@ p3PostedService::p3PostedService(uint16_t type) #define POSTED_BACKGROUND_PERIOD 60 -int p3PostedService::tick() +int p3PostedServiceVEG::tick() { - //std::cerr << "p3PostedService::tick()"; + //std::cerr << "p3PostedServiceVEG::tick()"; //std::cerr << std::endl; fakeprocessrequests(); @@ -109,7 +109,7 @@ int p3PostedService::tick() return 0; } -bool p3PostedService::updated() +bool p3PostedServiceVEG::updated() { RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ @@ -124,35 +124,35 @@ bool p3PostedService::updated() /* Data Requests */ -bool p3PostedService::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) +bool p3PostedServiceVEG::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) { generateToken(token); - std::cerr << "p3PostedService::requestGroupInfo() gets Token: " << token << std::endl; + std::cerr << "p3PostedServiceVEG::requestGroupInfo() gets Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); return true; } -bool p3PostedService::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) +bool p3PostedServiceVEG::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) { generateToken(token); - std::cerr << "p3PostedService::requestMsgInfo() gets Token: " << token << std::endl; + std::cerr << "p3PostedServiceVEG::requestMsgInfo() gets Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds); return true; } -bool p3PostedService::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds) +bool p3PostedServiceVEG::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds) { generateToken(token); - std::cerr << "p3PostedService::requestMsgRelatedInfo() gets Token: " << token << std::endl; + std::cerr << "p3PostedServiceVEG::requestMsgRelatedInfo() gets Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); return true; } /* Generic Lists */ -bool p3PostedService::getGroupList( const uint32_t &token, std::list &groupIds) +bool p3PostedServiceVEG::getGroupList( const uint32_t &token, std::list &groupIds) { uint32_t status; uint32_t reqtype; @@ -162,19 +162,19 @@ bool p3PostedService::getGroupList( const uint32_t &token, std::list &msgIds) +bool p3PostedServiceVEG::getMsgList( const uint32_t &token, std::list &msgIds) { uint32_t status; uint32_t reqtype; @@ -197,19 +197,19 @@ bool p3PostedService::getMsgList( const uint32_t &token, std::list &groupInfo) +bool p3PostedServiceVEG::getGroupSummary( const uint32_t &token, std::list &groupInfo) { uint32_t status; uint32_t reqtype; @@ -231,19 +231,19 @@ bool p3PostedService::getGroupSummary( const uint32_t &token, std::list &msgInfo) +bool p3PostedServiceVEG::getMsgSummary( const uint32_t &token, std::list &msgInfo) { uint32_t status; uint32_t reqtype; @@ -267,19 +267,19 @@ bool p3PostedService::getMsgSummary( const uint32_t &token, std::listsetMessageStatus(msgId, status, statusMask); } -bool p3PostedService::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask) +bool p3PostedServiceVEG::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask) { return mPostedProxy->setGroupStatus(groupId, status, statusMask); } -bool p3PostedService::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) +bool p3PostedServiceVEG::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) { return mPostedProxy->setGroupSubscribeFlags(groupId, subscribeFlags, subscribeMask); } -bool p3PostedService::setMessageServiceString(const std::string &msgId, const std::string &str) +bool p3PostedServiceVEG::setMessageServiceString(const std::string &msgId, const std::string &str) { return mPostedProxy->setMessageServiceString(msgId, str); } -bool p3PostedService::setGroupServiceString(const std::string &grpId, const std::string &str) +bool p3PostedServiceVEG::setGroupServiceString(const std::string &grpId, const std::string &str) { return mPostedProxy->setGroupServiceString(grpId, str); } -bool p3PostedService::groupRestoreKeys(const std::string &groupId) +bool p3PostedServiceVEG::groupRestoreKeys(const std::string &groupId) { return false; } -bool p3PostedService::groupShareKeys(const std::string &groupId, std::list& peers) +bool p3PostedServiceVEG::groupShareKeys(const std::string &groupId, std::list& peers) { return false; } -bool p3PostedService::submitGroup(uint32_t &token, RsPostedGroup &group, bool isNew) +bool p3PostedServiceVEG::submitGroup(uint32_t &token, RsPostedGroup &group, bool isNew) { /* check if its a modification or a new album */ @@ -488,7 +488,7 @@ bool p3PostedService::submitGroup(uint32_t &token, RsPostedGroup &group, bool is group.mMeta.mGroupId = genRandomId(); group.mMeta.mPublishTs = time(NULL); - std::cerr << "p3PostedService::submitGroup() Generated New GroupID: " << group.mMeta.mGroupId; + std::cerr << "p3PostedServiceVEG::submitGroup() Generated New GroupID: " << group.mMeta.mGroupId; std::cerr << std::endl; } @@ -504,23 +504,23 @@ bool p3PostedService::submitGroup(uint32_t &token, RsPostedGroup &group, bool is // Fake a request to return the GroupMetaData. generateToken(token); uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptions opts; // NULL is good. + RsTokReqOptionsVEG opts; // NULL is good. std::list groupIds; groupIds.push_back(group.mMeta.mGroupId); // It will just return this one. - std::cerr << "p3PostedService::submitGroup() Generating Request Token: " << token << std::endl; + std::cerr << "p3PostedServiceVEG::submitGroup() Generating Request Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); return true; } -bool p3PostedService::submitPost(uint32_t &token, RsPostedPost &post, bool isNew) +bool p3PostedServiceVEG::submitPost(uint32_t &token, RsPostedPost &post, bool isNew) { if (post.mMeta.mGroupId.empty()) { /* new photo */ - std::cerr << "p3PostedService::submitPost() Missing GroupID: ERROR"; + std::cerr << "p3PostedServiceVEG::submitPost() Missing GroupID: ERROR"; std::cerr << std::endl; return false; } @@ -533,18 +533,18 @@ bool p3PostedService::submitPost(uint32_t &token, RsPostedPost &post, bool isNew { /* new (Original Msg) photo */ post.mMeta.mOrigMsgId = post.mMeta.mMsgId; - std::cerr << "p3PostedService::submitPost() New Msg"; + std::cerr << "p3PostedServiceVEG::submitPost() New Msg"; std::cerr << std::endl; } else { - std::cerr << "p3PostedService::submitPost() Updated Msg"; + std::cerr << "p3PostedServiceVEG::submitPost() Updated Msg"; std::cerr << std::endl; } //post.mModFlags = 0; // These are always cleared. - std::cerr << "p3PostedService::submitPost() OrigMsgId: " << post.mMeta.mOrigMsgId; + std::cerr << "p3PostedServiceVEG::submitPost() OrigMsgId: " << post.mMeta.mOrigMsgId; std::cerr << " MsgId: " << post.mMeta.mMsgId; std::cerr << std::endl; @@ -558,11 +558,11 @@ bool p3PostedService::submitPost(uint32_t &token, RsPostedPost &post, bool isNew // Fake a request to return the MsgMetaData. generateToken(token); uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptions opts; // NULL is good. + RsTokReqOptionsVEG opts; // NULL is good. std::list msgIds; msgIds.push_back(post.mMeta.mMsgId); // It will just return this one. - std::cerr << "p3PostedService::submitPost() Generating Request Token: " << token << std::endl; + std::cerr << "p3PostedServiceVEG::submitPost() Generating Request Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); return true; @@ -570,12 +570,12 @@ bool p3PostedService::submitPost(uint32_t &token, RsPostedPost &post, bool isNew -bool p3PostedService::submitVote(uint32_t &token, RsPostedVote &vote, bool isNew) +bool p3PostedServiceVEG::submitVote(uint32_t &token, RsPostedVote &vote, bool isNew) { if (vote.mMeta.mGroupId.empty()) { /* new photo */ - std::cerr << "p3PostedService::submitVote() Missing GroupID: ERROR"; + std::cerr << "p3PostedServiceVEG::submitVote() Missing GroupID: ERROR"; std::cerr << std::endl; return false; } @@ -588,18 +588,18 @@ bool p3PostedService::submitVote(uint32_t &token, RsPostedVote &vote, bool isNew { /* new (Original Msg) photo */ vote.mMeta.mOrigMsgId = vote.mMeta.mMsgId; - std::cerr << "p3PostedService::submitVote() New Msg"; + std::cerr << "p3PostedServiceVEG::submitVote() New Msg"; std::cerr << std::endl; } else { - std::cerr << "p3PostedService::submitVote() Updated Msg"; + std::cerr << "p3PostedServiceVEG::submitVote() Updated Msg"; std::cerr << std::endl; } //vote.mModFlags = 0; // These are always cleared. - std::cerr << "p3PostedService::submitVote() OrigMsgId: " << vote.mMeta.mOrigMsgId; + std::cerr << "p3PostedServiceVEG::submitVote() OrigMsgId: " << vote.mMeta.mOrigMsgId; std::cerr << " MsgId: " << vote.mMeta.mMsgId; std::cerr << std::endl; @@ -613,11 +613,11 @@ bool p3PostedService::submitVote(uint32_t &token, RsPostedVote &vote, bool isNew // Fake a request to return the MsgMetaData. generateToken(token); uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptions opts; // NULL is good. + RsTokReqOptionsVEG opts; // NULL is good. std::list msgIds; msgIds.push_back(vote.mMeta.mMsgId); // It will just return this one. - std::cerr << "p3PostedService::submitVote() Generating Request Token: " << token << std::endl; + std::cerr << "p3PostedServiceVEG::submitVote() Generating Request Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); @@ -625,12 +625,12 @@ bool p3PostedService::submitVote(uint32_t &token, RsPostedVote &vote, bool isNew } -bool p3PostedService::submitComment(uint32_t &token, RsPostedComment &comment, bool isNew) +bool p3PostedServiceVEG::submitComment(uint32_t &token, RsPostedComment &comment, bool isNew) { if (comment.mMeta.mGroupId.empty()) { /* new photo */ - std::cerr << "p3PostedService::submitPost() Missing GroupID: ERROR"; + std::cerr << "p3PostedServiceVEG::submitPost() Missing GroupID: ERROR"; std::cerr << std::endl; return false; } @@ -643,18 +643,18 @@ bool p3PostedService::submitComment(uint32_t &token, RsPostedComment &comment, b { /* new (Original Msg) photo */ comment.mMeta.mOrigMsgId = comment.mMeta.mMsgId; - std::cerr << "p3PostedService::submitComment() New Msg"; + std::cerr << "p3PostedServiceVEG::submitComment() New Msg"; std::cerr << std::endl; } else { - std::cerr << "p3PostedService::submitComment() Updated Msg"; + std::cerr << "p3PostedServiceVEG::submitComment() Updated Msg"; std::cerr << std::endl; } //comment.mModFlags = 0; // These are always cleared. - std::cerr << "p3PostedService::submitComment() OrigMsgId: " << comment.mMeta.mOrigMsgId; + std::cerr << "p3PostedServiceVEG::submitComment() OrigMsgId: " << comment.mMeta.mOrigMsgId; std::cerr << " MsgId: " << comment.mMeta.mMsgId; std::cerr << std::endl; @@ -668,11 +668,11 @@ bool p3PostedService::submitComment(uint32_t &token, RsPostedComment &comment, b // Fake a request to return the MsgMetaData. generateToken(token); uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptions opts; // NULL is good. + RsTokReqOptionsVEG opts; // NULL is good. std::list msgIds; msgIds.push_back(comment.mMeta.mMsgId); // It will just return this one. - std::cerr << "p3PostedService::submitComment() Generating Request Token: " << token << std::endl; + std::cerr << "p3PostedServiceVEG::submitComment() Generating Request Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); return true; @@ -900,7 +900,7 @@ bool PostedDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta) /********************************************************************************************/ -std::string p3PostedService::genRandomId() +std::string p3PostedServiceVEG::genRandomId() { std::string randomId; for(int i = 0; i < 20; i++) @@ -950,7 +950,7 @@ std::ostream &operator<<(std::ostream &out, const RsPostedGroup &group) /********************************************************************************************/ /********************************************************************************************/ -bool p3PostedService::generateDummyData() +bool p3PostedServiceVEG::generateDummyData() { #define MAX_GROUPS 10 //100 #define MAX_POSTS 50 //1000 @@ -1251,9 +1251,9 @@ bool p3PostedService::generateDummyData() #define EXTRA_COMMENT_ADD (20) #define EXTRA_VOTE_ADD (50) -bool p3PostedService::addExtraDummyData() +bool p3PostedServiceVEG::addExtraDummyData() { - std::cerr << "p3PostedService::addExtraDummyData()"; + std::cerr << "p3PostedServiceVEG::addExtraDummyData()"; std::cerr << std::endl; int i = 0; @@ -1295,9 +1295,9 @@ bool p3PostedService::addExtraDummyData() -bool p3PostedService::setViewMode(uint32_t mode) +bool p3PostedServiceVEG::setViewMode(uint32_t mode) { - std::cerr << "p3PostedService::setViewMode() : " << mode; + std::cerr << "p3PostedServiceVEG::setViewMode() : " << mode; std::cerr << std::endl; RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ @@ -1307,9 +1307,9 @@ bool p3PostedService::setViewMode(uint32_t mode) return true; } -bool p3PostedService::setViewPeriod(uint32_t period) +bool p3PostedServiceVEG::setViewPeriod(uint32_t period) { - std::cerr << "p3PostedService::setViewPeriod() : " << period; + std::cerr << "p3PostedServiceVEG::setViewPeriod() : " << period; std::cerr << std::endl; RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ @@ -1319,9 +1319,9 @@ bool p3PostedService::setViewPeriod(uint32_t period) return true; } -bool p3PostedService::setViewRange(uint32_t first, uint32_t count) +bool p3PostedServiceVEG::setViewRange(uint32_t first, uint32_t count) { - std::cerr << "p3PostedService::setViewRange() : " << first << " +" << count; + std::cerr << "p3PostedServiceVEG::setViewRange() : " << first << " +" << count; std::cerr << std::endl; RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ @@ -1332,7 +1332,7 @@ bool p3PostedService::setViewRange(uint32_t first, uint32_t count) return true; } -float p3PostedService::calcPostScore(const RsMsgMetaData &meta) +float p3PostedServiceVEG::calcPostScore(const RsMsgMetaData &meta) { RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ @@ -1415,9 +1415,9 @@ static uint32_t convertPeriodFlagToSeconds(uint32_t periodMode) #define POSTED_RANKINGS_DATA_DONE 4 /* Poll */ -uint32_t p3PostedService::requestStatus(const uint32_t token) +uint32_t p3PostedServiceVEG::requestStatus(const uint32_t token) { - std::cerr << "p3PostedService::requestStatus() Token: " << token; + std::cerr << "p3PostedServiceVEG::requestStatus() Token: " << token; std::cerr << std::endl; uint32_t status; @@ -1431,7 +1431,7 @@ uint32_t p3PostedService::requestStatus(const uint32_t token) RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ if ((mProcessingRanking) && (token == mRankingExternalToken)) { - std::cerr << "p3PostedService::requestStatus() is RankingToken"; + std::cerr << "p3PostedServiceVEG::requestStatus() is RankingToken"; std::cerr << std::endl; { @@ -1439,20 +1439,20 @@ uint32_t p3PostedService::requestStatus(const uint32_t token) { case POSTED_RANKINGS_INITIAL_CHECK: status = GXS_REQUEST_STATUS_PENDING; - std::cerr << "p3PostedService::requestStatus() RANKING PENDING"; + std::cerr << "p3PostedServiceVEG::requestStatus() RANKING PENDING"; std::cerr << std::endl; return status; break; case POSTED_RANKINGS_NODATA: status = GXS_REQUEST_STATUS_COMPLETE; - std::cerr << "p3PostedService::requestStatus() RANKING RETURNED NO DATA"; + std::cerr << "p3PostedServiceVEG::requestStatus() RANKING RETURNED NO DATA"; std::cerr << std::endl; return status; break; case POSTED_RANKINGS_DATA_REQUEST: // Switch to real token. int_token = mRankingInternalToken; - std::cerr << "p3PostedService::requestStatus() Flipping to Int Token: " << int_token; + std::cerr << "p3PostedServiceVEG::requestStatus() Flipping to Int Token: " << int_token; std::cerr << std::endl; break; @@ -1466,20 +1466,20 @@ uint32_t p3PostedService::requestStatus(const uint32_t token) return status; } -bool p3PostedService::getRankedPost(const uint32_t &token, RsPostedPost &post) +bool p3PostedServiceVEG::getRankedPost(const uint32_t &token, RsPostedPost &post) { RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ if (!mProcessingRanking) { - std::cerr << "p3PostedService::getRankedPost() ERROR not processing"; + std::cerr << "p3PostedServiceVEG::getRankedPost() ERROR not processing"; std::cerr << std::endl; return false; } if (token != mRankingExternalToken) { - std::cerr << "p3PostedService::getRankedPost() ERROR wrong token"; + std::cerr << "p3PostedServiceVEG::getRankedPost() ERROR wrong token"; std::cerr << std::endl; return false; @@ -1487,7 +1487,7 @@ bool p3PostedService::getRankedPost(const uint32_t &token, RsPostedPost &post) if (mRankingState == POSTED_RANKINGS_NODATA) { - std::cerr << "p3PostedService::getRankedPost() No Data for this request - sorry"; + std::cerr << "p3PostedServiceVEG::getRankedPost() No Data for this request - sorry"; std::cerr << std::endl; /* clean up */ @@ -1502,7 +1502,7 @@ bool p3PostedService::getRankedPost(const uint32_t &token, RsPostedPost &post) if (mRankingState != POSTED_RANKINGS_DATA_REQUEST) { - std::cerr << "p3PostedService::getRankedPost() ERROR wrong state"; + std::cerr << "p3PostedServiceVEG::getRankedPost() ERROR wrong state"; std::cerr << std::endl; return false; @@ -1512,7 +1512,7 @@ bool p3PostedService::getRankedPost(const uint32_t &token, RsPostedPost &post) if (!getPost(mRankingInternalToken, post)) { - std::cerr << "p3PostedService::getRankedPost() End of Posts for this token"; + std::cerr << "p3PostedServiceVEG::getRankedPost() End of Posts for this token"; std::cerr << std::endl; /* clean up */ @@ -1524,22 +1524,22 @@ bool p3PostedService::getRankedPost(const uint32_t &token, RsPostedPost &post) return false; } - std::cerr << "p3PostedService::getRankedPost() Got Post"; + std::cerr << "p3PostedServiceVEG::getRankedPost() Got Post"; std::cerr << std::endl; return true; } -bool p3PostedService::requestRanking(uint32_t &token, std::string groupId) +bool p3PostedServiceVEG::requestRanking(uint32_t &token, std::string groupId) { - std::cerr << "p3PostedService::requestRanking()"; + std::cerr << "p3PostedServiceVEG::requestRanking()"; std::cerr << std::endl; { RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ if (mProcessingRanking) { - std::cerr << "p3PostedService::requestRanking() ERROR Request already running - ignoring"; + std::cerr << "p3PostedServiceVEG::requestRanking() ERROR Request already running - ignoring"; std::cerr << std::endl; return false; @@ -1559,7 +1559,7 @@ bool p3PostedService::requestRanking(uint32_t &token, std::string groupId) uint32_t posttoken; uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptions opts; + RsTokReqOptionsVEG opts; opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; //uint32_t age = convertPeriodFlagToSeconds(mViewPeriod); @@ -1571,28 +1571,28 @@ bool p3PostedService::requestRanking(uint32_t &token, std::string groupId) { RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ - std::cerr << "p3PostedService::requestRanking() Saved Internal Token: " << posttoken; + std::cerr << "p3PostedServiceVEG::requestRanking() Saved Internal Token: " << posttoken; std::cerr << std::endl; mRankingInternalToken = posttoken; } return true; } -bool p3PostedService::checkRankingRequest() +bool p3PostedServiceVEG::checkRankingRequest() { uint32_t token = 0; { RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ if (!mProcessingRanking) { - //std::cerr << "p3PostedService::checkRankingRequest() Not Processing"; + //std::cerr << "p3PostedServiceVEG::checkRankingRequest() Not Processing"; //std::cerr << std::endl; return false; } if (mRankingState != POSTED_RANKINGS_INITIAL_CHECK) { - std::cerr << "p3PostedService::checkRankingRequest() Not in Initial Check"; + std::cerr << "p3PostedServiceVEG::checkRankingRequest() Not in Initial Check"; std::cerr << std::endl; return false; } @@ -1600,7 +1600,7 @@ bool p3PostedService::checkRankingRequest() /* here it actually running! */ token = mRankingInternalToken; - std::cerr << "p3PostedService::checkRankingRequest() Running with token: " << token; + std::cerr << "p3PostedServiceVEG::checkRankingRequest() Running with token: " << token; std::cerr << std::endl; } @@ -1611,19 +1611,19 @@ bool p3PostedService::checkRankingRequest() time_t ts; if (checkRequestStatus(token, status, reqtype, anstype, ts)) { - std::cerr << "p3PostedService::checkRankingRequest() checkRequestStatus => OK"; + std::cerr << "p3PostedServiceVEG::checkRankingRequest() checkRequestStatus => OK"; std::cerr << std::endl; } else { - std::cerr << "p3PostedService::checkRankingRequest() checkRequestStatus => ERROR"; + std::cerr << "p3PostedServiceVEG::checkRankingRequest() checkRequestStatus => ERROR"; std::cerr << std::endl; return false; } if (status == GXS_REQUEST_STATUS_COMPLETE) { - std::cerr << "p3PostedService::checkRankingRequest() Init Complete => processPosts"; + std::cerr << "p3PostedServiceVEG::checkRankingRequest() Init Complete => processPosts"; std::cerr << std::endl; processPosts(); @@ -1632,9 +1632,9 @@ bool p3PostedService::checkRankingRequest() } -bool p3PostedService::processPosts() +bool p3PostedServiceVEG::processPosts() { - std::cerr << "p3PostedService::processPosts()"; + std::cerr << "p3PostedServiceVEG::processPosts()"; std::cerr << std::endl; uint32_t token = 0; @@ -1642,7 +1642,7 @@ bool p3PostedService::processPosts() RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ if (!mProcessingRanking) { - std::cerr << "p3PostedService::processPosts() ERROR Ranking Request not running"; + std::cerr << "p3PostedServiceVEG::processPosts() ERROR Ranking Request not running"; std::cerr << std::endl; return false; @@ -1650,7 +1650,7 @@ bool p3PostedService::processPosts() if (mRankingState != POSTED_RANKINGS_INITIAL_CHECK) { - std::cerr << "p3PostedService::processPosts() ERROR Ranking Request not running"; + std::cerr << "p3PostedServiceVEG::processPosts() ERROR Ranking Request not running"; std::cerr << std::endl; return false; @@ -1664,7 +1664,7 @@ bool p3PostedService::processPosts() if (!getMsgSummary(token, postList)) { - std::cerr << "p3PostedService::processPosts() No Data for Request"; + std::cerr << "p3PostedServiceVEG::processPosts() No Data for Request"; std::cerr << std::endl; /* put it into a state, where the GUI will get to read an empty Queue */ @@ -1695,7 +1695,7 @@ bool p3PostedService::processPosts() unsigned int i = 0; for(mit = postMap.rbegin(); (mit != postMap.rend()) && (i < mViewStart); mit++, i++) { - std::cerr << "p3PostedService::processPosts() Skipping PostId: " << mit->second; + std::cerr << "p3PostedServiceVEG::processPosts() Skipping PostId: " << mit->second; std::cerr << " with score: " << mit->first; std::cerr << std::endl; } @@ -1703,7 +1703,7 @@ bool p3PostedService::processPosts() for(i = 0; (mit != postMap.rend()) && (i < mViewCount); mit++, i++) { - std::cerr << "p3PostedService::processPosts() Adding PostId: " << mit->second; + std::cerr << "p3PostedServiceVEG::processPosts() Adding PostId: " << mit->second; std::cerr << " with score: " << mit->first; std::cerr << std::endl; msgList.push_back(mit->second); @@ -1712,7 +1712,7 @@ bool p3PostedService::processPosts() token = 0; uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; - RsTokReqOptions opts; + RsTokReqOptionsVEG opts; requestMsgRelatedInfo(token, ansType, opts, msgList); @@ -1721,7 +1721,7 @@ bool p3PostedService::processPosts() mRankingState = POSTED_RANKINGS_DATA_REQUEST; mRankingInternalToken = token; - std::cerr << "p3PostedService::processPosts() Second Stage: token: " << token; + std::cerr << "p3PostedServiceVEG::processPosts() Second Stage: token: " << token; std::cerr << std::endl; } return true; @@ -1747,7 +1747,7 @@ bool p3PostedService::processPosts() #define POSTED_BG_REQUEST_PARENTS 3 #define POSTED_BG_PROCESS_VOTES 4 -bool p3PostedService::background_checkTokenRequest() +bool p3PostedServiceVEG::background_checkTokenRequest() { uint32_t token = 0; uint32_t phase = 0; @@ -1790,9 +1790,9 @@ bool p3PostedService::background_checkTokenRequest() } -bool p3PostedService::background_requestGroups() +bool p3PostedServiceVEG::background_requestGroups() { - std::cerr << "p3PostedService::background_requestGroups()"; + std::cerr << "p3PostedServiceVEG::background_requestGroups()"; std::cerr << std::endl; // grab all the subscribed groups. @@ -1807,7 +1807,7 @@ bool p3PostedService::background_requestGroups() } uint32_t ansType = RS_TOKREQ_ANSTYPE_LIST; - RsTokReqOptions opts; + RsTokReqOptionsVEG opts; std::list groupIds; opts.mSubscribeFilter = RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED; @@ -1822,9 +1822,9 @@ bool p3PostedService::background_requestGroups() } -bool p3PostedService::background_requestNewMessages() +bool p3PostedServiceVEG::background_requestNewMessages() { - std::cerr << "p3PostedService::background_requestNewMessages()"; + std::cerr << "p3PostedServiceVEG::background_requestNewMessages()"; std::cerr << std::endl; std::list groupIds; @@ -1837,7 +1837,7 @@ bool p3PostedService::background_requestNewMessages() if (!getGroupList(token, groupIds)) { - std::cerr << "p3PostedService::background_requestNewMessages() ERROR No Group List"; + std::cerr << "p3PostedServiceVEG::background_requestNewMessages() ERROR No Group List"; std::cerr << std::endl; background_cleanup(); return false; @@ -1850,7 +1850,7 @@ bool p3PostedService::background_requestNewMessages() } uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptions opts; + RsTokReqOptionsVEG opts; token = 0; opts.mStatusFilter = RSGXS_MSG_STATUS_UNPROCESSED; @@ -1866,9 +1866,9 @@ bool p3PostedService::background_requestNewMessages() } -bool p3PostedService::background_processNewMessages() +bool p3PostedServiceVEG::background_processNewMessages() { - std::cerr << "p3PostedService::background_processNewMessages()"; + std::cerr << "p3PostedServiceVEG::background_processNewMessages()"; std::cerr << std::endl; std::list newMsgList; @@ -1882,7 +1882,7 @@ bool p3PostedService::background_processNewMessages() if (!getMsgSummary(token, newMsgList)) { - std::cerr << "p3PostedService::background_processNewMessages() ERROR No New Msgs"; + std::cerr << "p3PostedServiceVEG::background_processNewMessages() ERROR No New Msgs"; std::cerr << std::endl; background_cleanup(); return false; @@ -1978,7 +1978,7 @@ bool p3PostedService::background_processNewMessages() else { /* unknown! */ - std::cerr << "p3PostedService::background_processNewMessages() ERROR Strange NEW Message:"; + std::cerr << "p3PostedServiceVEG::background_processNewMessages() ERROR Strange NEW Message:"; std::cerr << std::endl; std::cerr << "\t" << *it; std::cerr << std::endl; @@ -1993,7 +1993,7 @@ bool p3PostedService::background_processNewMessages() /* request the summary info from the parents */ uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; token = 0; - RsTokReqOptions opts; + RsTokReqOptionsVEG opts; requestMsgRelatedInfo(token, ansType, opts, parentList); { @@ -2004,7 +2004,7 @@ bool p3PostedService::background_processNewMessages() } -bool p3PostedService::encodePostedCache(std::string &str, uint32_t votes, uint32_t comments) +bool p3PostedServiceVEG::encodePostedCache(std::string &str, uint32_t votes, uint32_t comments) { char line[RSGXS_MAX_SERVICE_STRING]; @@ -2014,7 +2014,7 @@ bool p3PostedService::encodePostedCache(std::string &str, uint32_t votes, uint32 return true; } -bool p3PostedService::extractPostedCache(const std::string &str, uint32_t &votes, uint32_t &comments) +bool p3PostedServiceVEG::extractPostedCache(const std::string &str, uint32_t &votes, uint32_t &comments) { uint32_t ivotes, icomments; @@ -2029,9 +2029,9 @@ bool p3PostedService::extractPostedCache(const std::string &str, uint32_t &votes } -bool p3PostedService::background_updateVoteCounts() +bool p3PostedServiceVEG::background_updateVoteCounts() { - std::cerr << "p3PostedService::background_updateVoteCounts()"; + std::cerr << "p3PostedServiceVEG::background_updateVoteCounts()"; std::cerr << std::endl; std::list parentMsgList; @@ -2039,7 +2039,7 @@ bool p3PostedService::background_updateVoteCounts() if (!getMsgSummary(mBgToken, parentMsgList)) { - std::cerr << "p3PostedService::background_updateVoteCounts() ERROR"; + std::cerr << "p3PostedServiceVEG::background_updateVoteCounts() ERROR"; std::cerr << std::endl; background_cleanup(); return false; @@ -2061,7 +2061,7 @@ bool p3PostedService::background_updateVoteCounts() { if (!(it->mServiceString.empty())) { - std::cerr << "p3PostedService::background_updateVoteCounts() Failed to extract Votes"; + std::cerr << "p3PostedServiceVEG::background_updateVoteCounts() Failed to extract Votes"; std::cerr << std::endl; std::cerr << "\tFrom String: " << it->mServiceString; std::cerr << std::endl; @@ -2081,7 +2081,7 @@ bool p3PostedService::background_updateVoteCounts() else { // warning. - std::cerr << "p3PostedService::background_updateVoteCounts() Warning No New Votes found."; + std::cerr << "p3PostedServiceVEG::background_updateVoteCounts() Warning No New Votes found."; std::cerr << " For MsgId: " << it->mMsgId; std::cerr << std::endl; } @@ -2100,7 +2100,7 @@ bool p3PostedService::background_updateVoteCounts() else { // warning. - std::cerr << "p3PostedService::background_updateVoteCounts() Warning No New Comments found."; + std::cerr << "p3PostedServiceVEG::background_updateVoteCounts() Warning No New Comments found."; std::cerr << " For MsgId: " << it->mMsgId; std::cerr << std::endl; } @@ -2110,12 +2110,12 @@ bool p3PostedService::background_updateVoteCounts() std::string str; if (!encodePostedCache(str, votes, comments)) { - std::cerr << "p3PostedService::background_updateVoteCounts() Failed to encode Votes"; + std::cerr << "p3PostedServiceVEG::background_updateVoteCounts() Failed to encode Votes"; std::cerr << std::endl; } else { - std::cerr << "p3PostedService::background_updateVoteCounts() Encoded String: " << str; + std::cerr << "p3PostedServiceVEG::background_updateVoteCounts() Encoded String: " << str; std::cerr << std::endl; /* store new result */ setMessageServiceString(it->mMsgId, str); @@ -2129,9 +2129,9 @@ bool p3PostedService::background_updateVoteCounts() } -bool p3PostedService::background_cleanup() +bool p3PostedServiceVEG::background_cleanup() { - std::cerr << "p3PostedService::background_cleanup()"; + std::cerr << "p3PostedServiceVEG::background_cleanup()"; std::cerr << std::endl; RsStackMutex stack(mPostedMtx); /********** STACK LOCKED MTX ******/ diff --git a/libretroshare/src/services/p3posted.h b/libretroshare/src/services/p3postedVEG.h similarity index 91% rename from libretroshare/src/services/p3posted.h rename to libretroshare/src/services/p3postedVEG.h index 3466be7c4..f48bee9d0 100644 --- a/libretroshare/src/services/p3posted.h +++ b/libretroshare/src/services/p3postedVEG.h @@ -23,11 +23,11 @@ * */ -#ifndef P3_POSTED_SERVICE_HEADER -#define P3_POSTED_SERVICE_HEADER +#ifndef P3_POSTED_SERVICE_VEG_HEADER +#define P3_POSTED_SERVICE_VEG_HEADER -#include "services/p3gxsservice.h" -#include "retroshare/rsposted.h" +#include "services/p3gxsserviceVEG.h" +#include "retroshare/rspostedVEG.h" #include #include @@ -38,7 +38,7 @@ */ -class PostedDataProxy: public GxsDataProxy +class PostedDataProxy: public GxsDataProxyVEG { public: @@ -60,11 +60,11 @@ virtual bool convertMsgToMetaData(void *groupData, RsMsgMetaData &meta); -class p3PostedService: public p3GxsDataService, public RsPosted +class p3PostedServiceVEG: public p3GxsDataServiceVEG, public RsPostedVEG { public: - p3PostedService(uint16_t type); + p3PostedServiceVEG(uint16_t type); virtual int tick(); @@ -76,9 +76,9 @@ virtual int tick(); virtual bool updated(); /* Data Requests */ -virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds); -virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds); -virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds); +virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); +virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); +virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds); /* Generic Lists */ virtual bool getGroupList( const uint32_t &token, std::list &groupIds); diff --git a/libretroshare/src/services/p3wikiservice.cc b/libretroshare/src/services/p3wikiserviceVEG.cc similarity index 68% rename from libretroshare/src/services/p3wikiservice.cc rename to libretroshare/src/services/p3wikiserviceVEG.cc index e2469cdac..dc0a1f7b9 100644 --- a/libretroshare/src/services/p3wikiservice.cc +++ b/libretroshare/src/services/p3wikiserviceVEG.cc @@ -23,7 +23,7 @@ * */ -#include "services/p3wikiservice.h" +#include "services/p3wikiserviceVEG.h" #include "util/rsrandom.h" @@ -31,15 +31,15 @@ * #define WIKI_DEBUG 1 ****/ -RsWiki *rsWiki = NULL; +RsWikiVEG *rsWikiVEG = NULL; /********************************************************************************/ /******************* Startup / Tick ******************************************/ /********************************************************************************/ -p3WikiService::p3WikiService(uint16_t type) - :p3GxsDataService(type, new WikiDataProxy()), mWikiMtx("p3WikiService"), mUpdated(true) +p3WikiServiceVEG::p3WikiServiceVEG(uint16_t type) + :p3GxsDataServiceVEG(type, new WikiDataProxy()), mWikiMtx("p3WikiService"), mUpdated(true) { RsStackMutex stack(mWikiMtx); /********** STACK LOCKED MTX ******/ @@ -48,9 +48,9 @@ p3WikiService::p3WikiService(uint16_t type) } -int p3WikiService::tick() +int p3WikiServiceVEG::tick() { - //std::cerr << "p3WikiService::tick()"; + //std::cerr << "p3WikiServiceVEG::tick()"; //std::cerr << std::endl; fakeprocessrequests(); @@ -58,7 +58,7 @@ int p3WikiService::tick() return 0; } -bool p3WikiService::updated() +bool p3WikiServiceVEG::updated() { RsStackMutex stack(mWikiMtx); /********** STACK LOCKED MTX ******/ @@ -73,35 +73,35 @@ bool p3WikiService::updated() /* Data Requests */ -bool p3WikiService::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) +bool p3WikiServiceVEG::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) { generateToken(token); - std::cerr << "p3WikiService::requestGroupInfo() gets Token: " << token << std::endl; + std::cerr << "p3WikiServiceVEG::requestGroupInfo() gets Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); return true; } -bool p3WikiService::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) +bool p3WikiServiceVEG::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) { generateToken(token); - std::cerr << "p3WikiService::requestMsgInfo() gets Token: " << token << std::endl; + std::cerr << "p3WikiServiceVEG::requestMsgInfo() gets Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds); return true; } -bool p3WikiService::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds) +bool p3WikiServiceVEG::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds) { generateToken(token); - std::cerr << "p3WikiService::requestMsgRelatedInfo() gets Token: " << token << std::endl; + std::cerr << "p3WikiServiceVEG::requestMsgRelatedInfo() gets Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); return true; } /* Generic Lists */ -bool p3WikiService::getGroupList( const uint32_t &token, std::list &groupIds) +bool p3WikiServiceVEG::getGroupList( const uint32_t &token, std::list &groupIds) { uint32_t status; uint32_t reqtype; @@ -111,19 +111,19 @@ bool p3WikiService::getGroupList( const uint32_t &token, std::list &msgIds) +bool p3WikiServiceVEG::getMsgList( const uint32_t &token, std::list &msgIds) { uint32_t status; uint32_t reqtype; @@ -146,19 +146,19 @@ bool p3WikiService::getMsgList( const uint32_t &token, std::list &groupInfo) +bool p3WikiServiceVEG::getGroupSummary( const uint32_t &token, std::list &groupInfo) { uint32_t status; uint32_t reqtype; @@ -180,19 +180,19 @@ bool p3WikiService::getGroupSummary( const uint32_t &token, std::list &msgInfo) +bool p3WikiServiceVEG::getMsgSummary( const uint32_t &token, std::list &msgInfo) { uint32_t status; uint32_t reqtype; @@ -216,19 +216,19 @@ bool p3WikiService::getMsgSummary( const uint32_t &token, std::listsetMessageStatus(msgId, status, statusMask); } -bool p3WikiService::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask) +bool p3WikiServiceVEG::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask) { return mWikiProxy->setGroupStatus(groupId, status, statusMask); } -bool p3WikiService::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) +bool p3WikiServiceVEG::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) { return mWikiProxy->setGroupSubscribeFlags(groupId, subscribeFlags, subscribeMask); } -bool p3WikiService::setMessageServiceString(const std::string &msgId, const std::string &str) +bool p3WikiServiceVEG::setMessageServiceString(const std::string &msgId, const std::string &str) { return mWikiProxy->setMessageServiceString(msgId, str); } -bool p3WikiService::setGroupServiceString(const std::string &grpId, const std::string &str) +bool p3WikiServiceVEG::setGroupServiceString(const std::string &grpId, const std::string &str) { return mWikiProxy->setGroupServiceString(grpId, str); } -bool p3WikiService::groupRestoreKeys(const std::string &groupId) +bool p3WikiServiceVEG::groupRestoreKeys(const std::string &groupId) { return false; } -bool p3WikiService::groupShareKeys(const std::string &groupId, std::list& peers) +bool p3WikiServiceVEG::groupShareKeys(const std::string &groupId, std::list& peers) { return false; } @@ -388,7 +388,7 @@ bool p3WikiService::groupShareKeys(const std::string &groupId, std::list groupIds; groupIds.push_back(group.mMeta.mGroupId); // It will just return this one. - std::cerr << "p3WikiService::createGroup() Generating Request Token: " << token << std::endl; + std::cerr << "p3WikiServiceVEG::createGroup() Generating Request Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); return true; @@ -437,12 +437,12 @@ bool p3WikiService::createGroup(uint32_t &token, RsWikiGroup &group, bool isNew) -bool p3WikiService::createPage(uint32_t &token, RsWikiPage &page, bool isNew) +bool p3WikiServiceVEG::createPage(uint32_t &token, RsWikiPage &page, bool isNew) { if (page.mMeta.mGroupId.empty()) { /* new photo */ - std::cerr << "p3WikiService::createPage() Missing PageID"; + std::cerr << "p3WikiServiceVEG::createPage() Missing PageID"; std::cerr << std::endl; return false; } @@ -450,7 +450,7 @@ bool p3WikiService::createPage(uint32_t &token, RsWikiPage &page, bool isNew) /* check if its a mod or new page */ if (page.mMeta.mOrigMsgId.empty()) { - std::cerr << "p3WikiService::createPage() New Page"; + std::cerr << "p3WikiServiceVEG::createPage() New Page"; std::cerr << std::endl; /* new page, generate a new OrigPageId */ @@ -459,18 +459,18 @@ bool p3WikiService::createPage(uint32_t &token, RsWikiPage &page, bool isNew) } else { - std::cerr << "p3WikiService::createPage() Modified Page"; + std::cerr << "p3WikiServiceVEG::createPage() Modified Page"; std::cerr << std::endl; /* mod page, keep orig page id, generate a new PageId */ page.mMeta.mMsgId = genRandomId(); } - std::cerr << "p3WikiService::createPage() GroupId: " << page.mMeta.mGroupId; + std::cerr << "p3WikiServiceVEG::createPage() GroupId: " << page.mMeta.mGroupId; std::cerr << std::endl; - std::cerr << "p3WikiService::createPage() PageId: " << page.mMeta.mMsgId; + std::cerr << "p3WikiServiceVEG::createPage() PageId: " << page.mMeta.mMsgId; std::cerr << std::endl; - std::cerr << "p3WikiService::createPage() OrigPageId: " << page.mMeta.mOrigMsgId; + std::cerr << "p3WikiServiceVEG::createPage() OrigPageId: " << page.mMeta.mOrigMsgId; std::cerr << std::endl; { @@ -483,11 +483,11 @@ bool p3WikiService::createPage(uint32_t &token, RsWikiPage &page, bool isNew) // Fake a request to return the MsgMetaData. generateToken(token); uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptions opts; // NULL is good. + RsTokReqOptionsVEG opts; // NULL is good. std::list msgIds; msgIds.push_back(page.mMeta.mMsgId); // It will just return this one. - std::cerr << "p3WikiService::createPage() Generating Request Token: " << token << std::endl; + std::cerr << "p3WikiServiceVEG::createPage() Generating Request Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); return true; diff --git a/libretroshare/src/services/p3wikiservice.h b/libretroshare/src/services/p3wikiserviceVEG.h similarity index 89% rename from libretroshare/src/services/p3wikiservice.h rename to libretroshare/src/services/p3wikiserviceVEG.h index a7a2cbe04..4aba5345a 100644 --- a/libretroshare/src/services/p3wikiservice.h +++ b/libretroshare/src/services/p3wikiserviceVEG.h @@ -26,8 +26,8 @@ #ifndef P3_WIKI_SERVICE_HEADER #define P3_WIKI_SERVICE_HEADER -#include "services/p3gxsservice.h" -#include "retroshare/rswiki.h" +#include "services/p3gxsserviceVEG.h" +#include "retroshare/rswikiVEG.h" #include #include @@ -47,7 +47,7 @@ * */ -class WikiDataProxy: public GxsDataProxy +class WikiDataProxy: public GxsDataProxyVEG { public: @@ -63,11 +63,11 @@ virtual bool convertMsgToMetaData(void *msgData, RsMsgMetaData &meta); }; -class p3WikiService: public p3GxsDataService, public RsWiki +class p3WikiServiceVEG: public p3GxsDataServiceVEG, public RsWikiVEG { public: - p3WikiService(uint16_t type); + p3WikiServiceVEG(uint16_t type); virtual int tick(); @@ -77,9 +77,9 @@ virtual int tick(); virtual bool updated(); /* Data Requests */ -virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds); -virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds); -virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds); +virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); +virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); +virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds); /* Generic Lists */ virtual bool getGroupList( const uint32_t &token, std::list &groupIds); diff --git a/libretroshare/src/services/p3wire.cc b/libretroshare/src/services/p3wireVEG.cc similarity index 80% rename from libretroshare/src/services/p3wire.cc rename to libretroshare/src/services/p3wireVEG.cc index c7953825d..3aec51a0a 100644 --- a/libretroshare/src/services/p3wire.cc +++ b/libretroshare/src/services/p3wireVEG.cc @@ -23,7 +23,7 @@ * */ -#include "services/p3wire.h" +#include "services/p3wireVEG.h" #include "util/rsrandom.h" @@ -31,15 +31,15 @@ * #define WIKI_DEBUG 1 ****/ -RsWire *rsWire = NULL; +RsWireVEG *rsWireVEG = NULL; /********************************************************************************/ /******************* Startup / Tick ******************************************/ /********************************************************************************/ -p3Wire::p3Wire(uint16_t type) - :p3GxsDataService(type, new WireDataProxy()), mWireMtx("p3Wire"), mUpdated(true) +p3WireVEG::p3WireVEG(uint16_t type) + :p3GxsDataServiceVEG(type, new WireDataProxy()), mWireMtx("p3Wire"), mUpdated(true) { RsStackMutex stack(mWireMtx); /********** STACK LOCKED MTX ******/ @@ -48,9 +48,9 @@ p3Wire::p3Wire(uint16_t type) } -int p3Wire::tick() +int p3WireVEG::tick() { - //std::cerr << "p3Wire::tick()"; + //std::cerr << "p3WireVEG::tick()"; //std::cerr << std::endl; fakeprocessrequests(); @@ -58,7 +58,7 @@ int p3Wire::tick() return 0; } -bool p3Wire::updated() +bool p3WireVEG::updated() { RsStackMutex stack(mWireMtx); /********** STACK LOCKED MTX ******/ @@ -73,35 +73,35 @@ bool p3Wire::updated() /* Data Requests */ -bool p3Wire::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) +bool p3WireVEG::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) { generateToken(token); - std::cerr << "p3Wire::requestGroupInfo() gets Token: " << token << std::endl; + std::cerr << "p3WireVEG::requestGroupInfo() gets Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); return true; } -bool p3Wire::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) +bool p3WireVEG::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) { generateToken(token); - std::cerr << "p3Wire::requestMsgInfo() gets Token: " << token << std::endl; + std::cerr << "p3WireVEG::requestMsgInfo() gets Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds); return true; } -bool p3Wire::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds) +bool p3WireVEG::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds) { generateToken(token); - std::cerr << "p3Wire::requestMsgRelatedInfo() gets Token: " << token << std::endl; + std::cerr << "p3WireVEG::requestMsgRelatedInfo() gets Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); return true; } /* Generic Lists */ -bool p3Wire::getGroupList( const uint32_t &token, std::list &groupIds) +bool p3WireVEG::getGroupList( const uint32_t &token, std::list &groupIds) { uint32_t status; uint32_t reqtype; @@ -111,19 +111,19 @@ bool p3Wire::getGroupList( const uint32_t &token, std::list if (anstype != RS_TOKREQ_ANSTYPE_LIST) { - std::cerr << "p3Wire::getGroupList() ERROR AnsType Wrong" << std::endl; + std::cerr << "p3WireVEG::getGroupList() ERROR AnsType Wrong" << std::endl; return false; } if (reqtype != GXS_REQUEST_TYPE_GROUPS) { - std::cerr << "p3Wire::getGroupList() ERROR ReqType Wrong" << std::endl; + std::cerr << "p3WireVEG::getGroupList() ERROR ReqType Wrong" << std::endl; return false; } if (status != GXS_REQUEST_STATUS_COMPLETE) { - std::cerr << "p3Wire::getGroupList() ERROR Status Incomplete" << std::endl; + std::cerr << "p3WireVEG::getGroupList() ERROR Status Incomplete" << std::endl; return false; } @@ -136,7 +136,7 @@ bool p3Wire::getGroupList( const uint32_t &token, std::list -bool p3Wire::getMsgList( const uint32_t &token, std::list &msgIds) +bool p3WireVEG::getMsgList( const uint32_t &token, std::list &msgIds) { uint32_t status; uint32_t reqtype; @@ -146,19 +146,19 @@ bool p3Wire::getMsgList( const uint32_t &token, std::list if (anstype != RS_TOKREQ_ANSTYPE_LIST) { - std::cerr << "p3Wire::getMsgList() ERROR AnsType Wrong" << std::endl; + std::cerr << "p3WireVEG::getMsgList() ERROR AnsType Wrong" << std::endl; return false; } if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) { - std::cerr << "p3Wire::getMsgList() ERROR ReqType Wrong" << std::endl; + std::cerr << "p3WireVEG::getMsgList() ERROR ReqType Wrong" << std::endl; return false; } if (status != GXS_REQUEST_STATUS_COMPLETE) { - std::cerr << "p3Wire::getMsgList() ERROR Status Incomplete" << std::endl; + std::cerr << "p3WireVEG::getMsgList() ERROR Status Incomplete" << std::endl; return false; } @@ -170,7 +170,7 @@ bool p3Wire::getMsgList( const uint32_t &token, std::list /* Generic Summary */ -bool p3Wire::getGroupSummary( const uint32_t &token, std::list &groupInfo) +bool p3WireVEG::getGroupSummary( const uint32_t &token, std::list &groupInfo) { uint32_t status; uint32_t reqtype; @@ -180,19 +180,19 @@ bool p3Wire::getGroupSummary( const uint32_t &token, std::list &msgInfo) +bool p3WireVEG::getMsgSummary( const uint32_t &token, std::list &msgInfo) { uint32_t status; uint32_t reqtype; @@ -216,19 +216,19 @@ bool p3Wire::getMsgSummary( const uint32_t &token, std::listsetMessageStatus(msgId, status, statusMask); } -bool p3Wire::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask) +bool p3WireVEG::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask) { return mWireProxy->setGroupStatus(groupId, status, statusMask); } -bool p3Wire::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) +bool p3WireVEG::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) { return mWireProxy->setGroupSubscribeFlags(groupId, subscribeFlags, subscribeMask); } -bool p3Wire::setMessageServiceString(const std::string &msgId, const std::string &str) +bool p3WireVEG::setMessageServiceString(const std::string &msgId, const std::string &str) { return mWireProxy->setMessageServiceString(msgId, str); } -bool p3Wire::setGroupServiceString(const std::string &grpId, const std::string &str) +bool p3WireVEG::setGroupServiceString(const std::string &grpId, const std::string &str) { return mWireProxy->setGroupServiceString(grpId, str); } -bool p3Wire::groupRestoreKeys(const std::string &groupId) +bool p3WireVEG::groupRestoreKeys(const std::string &groupId) { return false; } -bool p3Wire::groupShareKeys(const std::string &groupId, std::list& peers) +bool p3WireVEG::groupShareKeys(const std::string &groupId, std::list& peers) { return false; } @@ -389,7 +389,7 @@ bool p3Wire::groupShareKeys(const std::string &groupId, std::list& /********************************************************************************************/ -std::string p3Wire::genRandomId() +std::string p3WireVEG::genRandomId() { std::string randomId; for(int i = 0; i < 20; i++) @@ -401,7 +401,7 @@ std::string p3Wire::genRandomId() } -bool p3Wire::createGroup(uint32_t &token, RsWireGroup &group, bool isNew) +bool p3WireVEG::createGroup(uint32_t &token, RsWireGroup &group, bool isNew) { if (group.mMeta.mGroupId.empty()) { @@ -412,7 +412,7 @@ bool p3Wire::createGroup(uint32_t &token, RsWireGroup &group, bool isNew) } else { - std::cerr << "p3Wire::createGroup() Group with existing Id... dropping"; + std::cerr << "p3WireVEG::createGroup() Group with existing Id... dropping"; std::cerr << std::endl; return false; } @@ -427,7 +427,7 @@ bool p3Wire::createGroup(uint32_t &token, RsWireGroup &group, bool isNew) // Fake a request to return the GroupMetaData. generateToken(token); uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptions opts; // NULL is good. + RsTokReqOptionsVEG opts; // NULL is good. std::list groupIds; groupIds.push_back(group.mMeta.mGroupId); // It will just return this one. @@ -440,12 +440,12 @@ bool p3Wire::createGroup(uint32_t &token, RsWireGroup &group, bool isNew) -bool p3Wire::createPulse(uint32_t &token, RsWirePulse &pulse, bool isNew) +bool p3WireVEG::createPulse(uint32_t &token, RsWirePulse &pulse, bool isNew) { if (pulse.mMeta.mGroupId.empty()) { /* new photo */ - std::cerr << "p3Wire::createPulse() Missing PulseID"; + std::cerr << "p3WireVEG::createPulse() Missing PulseID"; std::cerr << std::endl; return false; } @@ -453,7 +453,7 @@ bool p3Wire::createPulse(uint32_t &token, RsWirePulse &pulse, bool isNew) /* check if its a mod or new pulse */ if (pulse.mMeta.mOrigMsgId.empty()) { - std::cerr << "p3Wire::createPulse() New Pulse"; + std::cerr << "p3WireVEG::createPulse() New Pulse"; std::cerr << std::endl; /* new pulse, generate a new OrigPulseId */ @@ -462,18 +462,18 @@ bool p3Wire::createPulse(uint32_t &token, RsWirePulse &pulse, bool isNew) } else { - std::cerr << "p3Wire::createPulse() Modified Pulse"; + std::cerr << "p3WireVEG::createPulse() Modified Pulse"; std::cerr << std::endl; /* mod pulse, keep orig pulse id, generate a new PulseId */ pulse.mMeta.mMsgId = genRandomId(); } - std::cerr << "p3Wire::createPulse() GroupId: " << pulse.mMeta.mGroupId; + std::cerr << "p3WireVEG::createPulse() GroupId: " << pulse.mMeta.mGroupId; std::cerr << std::endl; - std::cerr << "p3Wire::createPulse() PulseId: " << pulse.mMeta.mMsgId; + std::cerr << "p3WireVEG::createPulse() PulseId: " << pulse.mMeta.mMsgId; std::cerr << std::endl; - std::cerr << "p3Wire::createPulse() OrigPulseId: " << pulse.mMeta.mOrigMsgId; + std::cerr << "p3WireVEG::createPulse() OrigPulseId: " << pulse.mMeta.mOrigMsgId; std::cerr << std::endl; { @@ -486,11 +486,11 @@ bool p3Wire::createPulse(uint32_t &token, RsWirePulse &pulse, bool isNew) // Fake a request to return the MsgMetaData. generateToken(token); uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptions opts; // NULL is good. + RsTokReqOptionsVEG opts; // NULL is good. std::list msgIds; msgIds.push_back(pulse.mMeta.mMsgId); // It will just return this one. - std::cerr << "p3Wire::createPulse() Generating Request Token: " << token << std::endl; + std::cerr << "p3WireVEG::createPulse() Generating Request Token: " << token << std::endl; storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); return true; @@ -607,7 +607,7 @@ bool WireDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta) #if 0 -bool p3Wire::generateDummyData() +bool p3WireVEG::generateDummyData() { #define MAX_GROUPS 100 #define MAX_POSTS 1000 diff --git a/libretroshare/src/services/p3wire.h b/libretroshare/src/services/p3wireVEG.h similarity index 87% rename from libretroshare/src/services/p3wire.h rename to libretroshare/src/services/p3wireVEG.h index 4e83131e6..b009b116f 100644 --- a/libretroshare/src/services/p3wire.h +++ b/libretroshare/src/services/p3wireVEG.h @@ -23,12 +23,12 @@ * */ -#ifndef P3_WIRE_SERVICE_HEADER -#define P3_WIRE_SERVICE_HEADER +#ifndef P3_WIRE_SERVICE_VEG_HEADER +#define P3_WIRE_SERVICE_VEG_HEADER -#include "services/p3gxsservice.h" +#include "services/p3gxsserviceVEG.h" -#include "retroshare/rswire.h" +#include "retroshare/rswireVEG.h" #include #include @@ -37,7 +37,7 @@ * Wire Service * */ -class WireDataProxy: public GxsDataProxy +class WireDataProxy: public GxsDataProxyVEG { public: @@ -53,11 +53,11 @@ virtual bool convertMsgToMetaData(void *msgData, RsMsgMetaData &meta); }; -class p3Wire: public p3GxsDataService, public RsWire +class p3WireVEG: public p3GxsDataServiceVEG, public RsWireVEG { public: - p3Wire(uint16_t type); + p3WireVEG(uint16_t type); virtual int tick(); @@ -67,9 +67,9 @@ virtual int tick(); virtual bool updated(); /* Data Requests */ -virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds); -virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds); -virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds); +virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); +virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); +virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds); /* Generic Lists */ virtual bool getGroupList( const uint32_t &token, std::list &groupIds); From ce992475a185c30595c62dcb5fc3ed936c3e28f6 Mon Sep 17 00:00:00 2001 From: drbob Date: Sat, 15 Sep 2012 00:17:23 +0000 Subject: [PATCH 062/222] Modifications to support the changes in libretroshare. * Disabled all the VEG services, until GUI has been tweaked to match new interface. * Deleted text from PhotoItem.ui - to compile with older version of Qt. * Fixes to Retroshare.pro (restore libdht path, disable compilation of VEG classes) git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5552 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/RetroShare.pro | 56 +++++++++---------- .../src/gui/PhotoShare/PhotoItem.ui | 6 -- .../src/gui/unfinished/ApplicationWindow.cpp | 10 ++++ 3 files changed, 38 insertions(+), 34 deletions(-) diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index 70ae08b12..590166f69 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -2,13 +2,13 @@ CONFIG += qt gui uic qrc resources uitools idle bitdht # Below is for GXS services. CONFIG += photoshare -CONFIG += wikipoos -CONFIG += thewire -CONFIG += identities -CONFIG += forumsv2 -CONFIG += posted +#CONFIG += wikipoos +#CONFIG += thewire +#CONFIG += identities +#CONFIG += forumsv2 +#CONFIG += posted CONFIG += unfinished -CONFIG += gxsgui +#CONFIG += gxsgui #CONFIG += pluginmgr @@ -193,8 +193,12 @@ freebsd-* { # ########################################### bitdht { - LIBS += ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a - PRE_TARGETDEPS *= ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a + LIBS += ../../libbitdht/src/lib/libbitdht.a + PRE_TARGETDEPS *= ../../libbitdht/src/lib/libbitdht.a + + # Chris version. + #LIBS += ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a + #PRE_TARGETDEPS *= ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a } win32 { @@ -860,40 +864,36 @@ photoshare { HEADERS += \ gui/PhotoShare/PhotoDialog.h \ gui/PhotoShare/PhotoDrop.h \ - gui/PhotoShare/PhotoSlideShow.h \ + gui/PhotoShare/AlbumItem.h \ + gui/PhotoShare/AlbumDialog.h \ + gui/PhotoShare/AlbumCreateDialog.h \ util/TokenQueueV2.h \ - gui/PhotoShare/AlbumDialog.h \ - gui/PhotoShare/AlbumItem.h \ gui/PhotoShare/PhotoItem.h \ - gui/PhotoShare/AlbumCreateDialog.h \ gui/PhotoShare/PhotoShareItemHolder.h \ - gui/PhotoShare/PhotoShare.h + gui/PhotoShare/PhotoShare.h \ + gui/PhotoShare/PhotoSlideShow.h \ -#gui/PhotoShare/PhotoDetailsDialog.h \ -# gui/PhotoShare/PhotoAddDialog.h \ FORMS += \ + gui/PhotoShare/PhotoItem.ui \ gui/PhotoShare/PhotoDialog.ui \ - gui/PhotoShare/PhotoSlideShow.ui \ gui/PhotoShare/AlbumItem.ui \ gui/PhotoShare/AlbumDialog.ui \ - gui/PhotoShare/PhotoItem.ui \ gui/PhotoShare/AlbumCreateDialog.ui \ - gui/PhotoShare/PhotoShare.ui -# gui/PhotoShare/PhotoAddDialog.ui \1 -# gui/PhotoShare/PhotoDetailsDialog.ui \ + gui/PhotoShare/PhotoShare.ui \ + gui/PhotoShare/PhotoSlideShow.ui \ + SOURCES += \ + gui/PhotoShare/PhotoItem.cpp \ gui/PhotoShare/PhotoDialog.cpp \ gui/PhotoShare/PhotoDrop.cpp \ - gui/PhotoShare/PhotoSlideShow.cpp \ - gui/PhotoShare/AlbumDialog.cpp \ + gui/PhotoShare/AlbumItem.cpp \ + gui/PhotoShare/AlbumDialog.cpp \ + gui/PhotoShare/AlbumCreateDialog.cpp \ util/TokenQueueV2.cpp \ - gui/PhotoShare/AlbumItem.cpp \ - gui/PhotoShare/PhotoItem.cpp \ - gui/PhotoShare/AlbumCreateDialog.cpp \ gui/PhotoShare/PhotoShareItemHolder.cpp \ - gui/PhotoShare/PhotoShare.cpp -# gui/PhotoShare/PhotoAddDialog.cpp \ -# gui/PhotoShare/PhotoDetailsDialog.cpp \ + gui/PhotoShare/PhotoShare.cpp \ + gui/PhotoShare/PhotoSlideShow.cpp \ + } diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoItem.ui b/retroshare-gui/src/gui/PhotoShare/PhotoItem.ui index 6101f39ae..b49b45ff3 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoItem.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoItem.ui @@ -76,16 +76,10 @@ p, li { white-space: pre-wrap; } - - Enter Title Here - - - Enter Photographer - diff --git a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp index d3002dc7c..8672b2103 100644 --- a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp +++ b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp @@ -33,11 +33,15 @@ #include #include "gui/PhotoShare/PhotoDialog.h" + +// THESE HAVE TO BE CONVERTED TO VEG FORMAT +#if USE_VEG_SERVICE #include "gui/WikiPoos/WikiDialog.h" #include "gui/TheWire/WireDialog.h" #include "gui/Identity/IdDialog.h" #include "gui/ForumsV2Dialog.h" #include "gui/Posted/PostedDialog.h" +#endif //#include "GamesDialog.h" //#include "CalDialog.h" @@ -93,14 +97,19 @@ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) //ui.stackPages->add(calDialog = new CalDialog(ui.stackPages), // createPageAction(QIcon(IMAGE_CALENDAR), tr("Shared Calendars"), grp)); +// THESE HAVE TO BE CONVERTED TO VEG FORMAT +#if USE_VEG_SERVICE IdDialog *idDialog = NULL; ui.stackPages->add(idDialog = new IdDialog(ui.stackPages), createPageAction(QIcon(IMAGE_LIBRARY), tr("Identities"), grp)); +#endif PhotoDialog *photoDialog = NULL; ui.stackPages->add(photoDialog = new PhotoDialog(ui.stackPages), createPageAction(QIcon(IMAGE_PHOTO), tr("Photo View"), grp)); +// THESE HAVE TO BE CONVERTED TO VEG FORMAT +#if USE_VEG_SERVICE WikiDialog *wikiDialog = NULL; ui.stackPages->add(wikiDialog = new WikiDialog(ui.stackPages), createPageAction(QIcon(IMAGE_LIBRARY), tr("Wiki Pages"), grp)); @@ -116,6 +125,7 @@ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) PostedDialog *postedDialog = NULL; ui.stackPages->add(postedDialog = new PostedDialog(ui.stackPages), createPageAction(QIcon(IMAGE_LIBRARY), tr("Posted Links"), grp)); +#endif /* Create the toolbar */ From 4f470090b2c4e806ecc88de525dd098eee5583cd Mon Sep 17 00:00:00 2001 From: drbob Date: Sat, 15 Sep 2012 00:26:33 +0000 Subject: [PATCH 063/222] Moved TokenQueue => TokenQueueVEG to make space for Real version. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5553 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/RetroShare.pro | 4 +-- .../{TokenQueue.cpp => TokenQueueVEG.cpp} | 36 +++++++++---------- .../util/{TokenQueue.h => TokenQueueVEG.h} | 30 ++++++++-------- 3 files changed, 35 insertions(+), 35 deletions(-) rename retroshare-gui/src/util/{TokenQueue.cpp => TokenQueueVEG.cpp} (69%) rename retroshare-gui/src/util/{TokenQueue.h => TokenQueueVEG.h} (81%) diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index 590166f69..73bac1f46 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -933,14 +933,14 @@ thewire { identities { - HEADERS += util/TokenQueue.h \ + HEADERS += util/TokenQueueVEG.h \ gui/Identity/IdDialog.h \ gui/Identity/IdEditDialog.h \ FORMS += gui/Identity/IdDialog.ui \ gui/Identity/IdEditDialog.ui \ - SOURCES += util/TokenQueue.cpp \ + SOURCES += util/TokenQueueVEG.cpp \ gui/Identity/IdDialog.cpp \ gui/Identity/IdEditDialog.cpp \ diff --git a/retroshare-gui/src/util/TokenQueue.cpp b/retroshare-gui/src/util/TokenQueueVEG.cpp similarity index 69% rename from retroshare-gui/src/util/TokenQueue.cpp rename to retroshare-gui/src/util/TokenQueueVEG.cpp index 1c0cf7a0f..5c11dca31 100644 --- a/retroshare-gui/src/util/TokenQueue.cpp +++ b/retroshare-gui/src/util/TokenQueueVEG.cpp @@ -21,7 +21,7 @@ * */ -#include "util/TokenQueue.h" +#include "util/TokenQueueVEG.h" #include #include @@ -31,13 +31,13 @@ *****/ /** Constructor */ -TokenQueue::TokenQueue(RsTokenService *service, TokenResponse *resp) +TokenQueueVEG::TokenQueueVEG(RsTokenServiceVEG *service, TokenResponseVEG *resp) :QWidget(NULL), mService(service), mResponder(resp) { return; } -bool TokenQueue::requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, std::list ids, uint32_t usertype) +bool TokenQueueVEG::requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsVEG &opts, std::list ids, uint32_t usertype) { uint32_t basictype = TOKENREQ_GROUPINFO; mService->requestGroupInfo(token, anstype, opts, ids); @@ -47,7 +47,7 @@ bool TokenQueue::requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTok } -bool TokenQueue::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, std::list ids, uint32_t usertype) +bool TokenQueueVEG::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsVEG &opts, std::list ids, uint32_t usertype) { uint32_t basictype = TOKENREQ_MSGINFO; mService->requestMsgInfo(token, anstype, opts, ids); @@ -57,7 +57,7 @@ bool TokenQueue::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokRe } -bool TokenQueue::requestMsgRelatedInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, std::list ids, uint32_t usertype) +bool TokenQueueVEG::requestMsgRelatedInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsVEG &opts, std::list ids, uint32_t usertype) { uint32_t basictype = TOKENREQ_MSGRELATEDINFO; mService->requestMsgRelatedInfo(token, anstype, opts, ids); @@ -67,13 +67,13 @@ bool TokenQueue::requestMsgRelatedInfo(uint32_t &token, uint32_t anstype, const } -void TokenQueue::queueRequest(uint32_t token, uint32_t basictype, uint32_t anstype, uint32_t usertype) +void TokenQueueVEG::queueRequest(uint32_t token, uint32_t basictype, uint32_t anstype, uint32_t usertype) { - std::cerr << "TokenQueue::queueRequest() Token: " << token << " Type: " << basictype; + std::cerr << "TokenQueueVEG::queueRequest() Token: " << token << " Type: " << basictype; std::cerr << " AnsType: " << anstype << " UserType: " << usertype; std::cerr << std::endl; - TokenRequest req; + TokenRequestVEG req; req.mToken = token; req.mType = basictype; req.mAnsType = anstype; @@ -91,7 +91,7 @@ void TokenQueue::queueRequest(uint32_t token, uint32_t basictype, uint32_t ansty } } -void TokenQueue::doPoll(float dt) +void TokenQueueVEG::doPoll(float dt) { /* single shot poll */ //mTrigger->singlesshot(dt * 1000); @@ -99,9 +99,9 @@ void TokenQueue::doPoll(float dt) } -void TokenQueue::pollRequests() +void TokenQueueVEG::pollRequests() { - std::list::iterator it; + std::list::iterator it; double pollPeriod = 1.0; // max poll period. for(it = mRequests.begin(); it != mRequests.end();) @@ -129,16 +129,16 @@ void TokenQueue::pollRequests() } -bool TokenQueue::checkForRequest(uint32_t token) +bool TokenQueueVEG::checkForRequest(uint32_t token) { /* check token */ return (COMPLETED_REQUEST == mService->requestStatus(token)); } -void TokenQueue::loadRequest(const TokenRequest &req) +void TokenQueueVEG::loadRequest(const TokenRequestVEG &req) { - std::cerr << "TokenQueue::loadRequest(): "; + std::cerr << "TokenQueueVEG::loadRequest(): "; std::cerr << "Token: " << req.mToken << " Type: " << req.mType; std::cerr << " AnsType: " << req.mAnsType << " UserType: " << req.mUserType; std::cerr << std::endl; @@ -149,12 +149,12 @@ void TokenQueue::loadRequest(const TokenRequest &req) } -bool TokenQueue::cancelRequest(const uint32_t token) +bool TokenQueueVEG::cancelRequest(const uint32_t token) { /* cancel at lower level first */ mService->cancelRequest(token); - std::list::iterator it; + std::list::iterator it; for(it = mRequests.begin(); it != mRequests.end(); it++) { @@ -162,14 +162,14 @@ bool TokenQueue::cancelRequest(const uint32_t token) { mRequests.erase(it); - std::cerr << "TokenQueue::cancelRequest() Cleared Request: " << token; + std::cerr << "TokenQueueVEG::cancelRequest() Cleared Request: " << token; std::cerr << std::endl; return true; } } - std::cerr << "TokenQueue::cancelRequest() Failed to Find Request: " << token; + std::cerr << "TokenQueueVEG::cancelRequest() Failed to Find Request: " << token; std::cerr << std::endl; return false; diff --git a/retroshare-gui/src/util/TokenQueue.h b/retroshare-gui/src/util/TokenQueueVEG.h similarity index 81% rename from retroshare-gui/src/util/TokenQueue.h rename to retroshare-gui/src/util/TokenQueueVEG.h index b11c131bb..4f6b5a667 100644 --- a/retroshare-gui/src/util/TokenQueue.h +++ b/retroshare-gui/src/util/TokenQueueVEG.h @@ -21,8 +21,8 @@ * */ -#ifndef MRK_TOKEN_QUEUE_H -#define MRK_TOKEN_QUEUE_H +#ifndef MRK_VEG_TOKEN_QUEUE_H +#define MRK_VEG_TOKEN_QUEUE_H #include #include @@ -30,7 +30,7 @@ #include #include #include -#include +#include #define COMPLETED_REQUEST 4 @@ -38,9 +38,9 @@ #define TOKENREQ_MSGINFO 2 #define TOKENREQ_MSGRELATEDINFO 3 -class TokenQueue; +class TokenQueueVEG; -class TokenRequest +class TokenRequestVEG { public: uint32_t mToken; @@ -51,7 +51,7 @@ class TokenRequest struct timeval mPollTs; }; -class TokenResponse +class TokenResponseVEG { public: //virtual ~TokenResponse() { return; } @@ -60,25 +60,25 @@ class TokenResponse }; -class TokenQueue: public QWidget +class TokenQueueVEG: public QWidget { Q_OBJECT public: - TokenQueue(RsTokenService *service, TokenResponse *resp); + TokenQueueVEG(RsTokenServiceVEG *service, TokenResponseVEG *resp); /* generic handling of token / response update behaviour */ - bool requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, + bool requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsVEG &opts, std::list ids, uint32_t usertype); - bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, + bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsVEG &opts, std::list ids, uint32_t usertype); - bool requestMsgRelatedInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, + bool requestMsgRelatedInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsVEG &opts, std::list ids, uint32_t usertype); bool cancelRequest(const uint32_t token); void queueRequest(uint32_t token, uint32_t basictype, uint32_t anstype, uint32_t usertype); bool checkForRequest(uint32_t token); - void loadRequest(const TokenRequest &req); + void loadRequest(const TokenRequestVEG &req); protected: void doPoll(float dt); @@ -88,10 +88,10 @@ private slots: private: /* Info for Data Requests */ - std::list mRequests; + std::list mRequests; - RsTokenService *mService; - TokenResponse *mResponder; + RsTokenServiceVEG *mService; + TokenResponseVEG *mResponder; QTimer *mTrigger; }; From eaa734216545ebb83a3eeb833d8f35fa61f0b2dd Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Mon, 17 Sep 2012 22:08:23 +0000 Subject: [PATCH 064/222] emergency commit, computer acting up bad! git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5565 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgenexchange.cc | 3 - libretroshare/src/gxs/rsgenexchange.h | 14 + libretroshare/src/gxs/rsgxsnetservice.cc | 2 +- libretroshare/src/gxs/rstokenservice.h | 7 +- libretroshare/src/libretroshare.pro | 73 +- libretroshare/src/retroshare/rsidentityVEG.h | 3 - libretroshare/src/retroshare/rsphotoV2.h | 420 ++++++----- libretroshare/src/retroshare/rsphotoVEG.h | 96 +-- libretroshare/src/rsserver/rsinit.cc | 67 +- .../src/serialiser/rsphotov2items.cc | 14 +- libretroshare/src/serialiser/rsphotov2items.h | 17 + libretroshare/src/services/p3idservice.cc | 4 +- .../src/services/p3photoserviceV2.cc | 11 +- libretroshare/src/services/p3photoserviceV2.h | 12 +- openpgpsdk/src/openpgpsdk.pro | 6 +- retroshare-gui/src/RetroShare.pro | 18 +- .../src/gui/PhotoShare/AlbumItem.cpp | 2 +- retroshare-gui/src/gui/PhotoShare/AlbumItem.h | 4 +- .../src/gui/PhotoShare/PhotoCommentItem.cpp | 14 + .../src/gui/PhotoShare/PhotoCommentItem.h | 22 + .../src/gui/PhotoShare/PhotoCommentItem.ui | 21 + .../src/gui/PhotoShare/PhotoDialog.cpp | 681 +---------------- .../src/gui/PhotoShare/PhotoDialog.h | 150 +--- .../src/gui/PhotoShare/PhotoDialog.ui | 359 +++++---- .../src/gui/PhotoShare/PhotoShare.cpp | 714 +++++++++++++++++- .../src/gui/PhotoShare/PhotoShare.h | 87 ++- .../src/gui/PhotoShare/PhotoShare.ui | 202 ++++- .../src/gui/unfinished/ApplicationWindow.cpp | 8 +- retroshare-gui/src/util/TokenQueueV2.cpp | 14 +- retroshare-gui/src/util/TokenQueueV2.h | 1 + retroshare-nogui/src/menu/menus.cc | 17 +- retroshare-nogui/src/notifytxt.cc | 36 +- retroshare-nogui/src/retroshare.cc | 2 +- .../src/rpc/proto/gencc/core.pb.cc | 206 +++-- .../src/rpc/proto/gencc/system.pb.cc | 515 +------------ .../src/rpc/proto/rpcprotosystem.cc | 73 -- retroshare-nogui/src/rpc/rpc.cc | 5 - retroshare-nogui/src/rpc/rpcserver.cc | 5 - retroshare-nogui/src/rpc/rpcsetup.cc | 10 +- 39 files changed, 1835 insertions(+), 2080 deletions(-) create mode 100644 retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.cpp create mode 100644 retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.h create mode 100644 retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 42b36191f..ff39da0ff 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -632,9 +632,6 @@ void RsGenExchange::publishGrps() size = grp->metaData->serial_size(); char mData[size]; grp->metaData->mGroupId = grp->grpId; - - // indicate user is admin through local subscribe flag - grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; ok = grp->metaData->serialise(mData, size); grp->meta.setBinData(mData, size); diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 0ca1be9c1..c2b20ea34 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -153,6 +153,13 @@ protected: */ bool getMsgData(const uint32_t &token, GxsMsgDataMap& msgItems); + + /*! + * @param grpItem + * @deprecated only here to temporarily to testing + */ + void createDummyGroup(RsGxsGrpItem* grpItem); + public: /*! @@ -259,6 +266,13 @@ private: void createGroup(RsNxsGrp* grp); bool createMessage(RsNxsMsg* msg); + + /*! + * check meta change is legal + * @return false if meta change is not legal + */ + bool locked_validateGrpMetaChange(GrpLocMetaData&); + private: RsMutex mGenMtx; diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 19e22ca0f..875f42b48 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -98,7 +98,7 @@ void RsGxsNetService::syncWithPeers() { RsGxsGrpMetaData* meta = mit->second; - if(meta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_MASK) + if(meta->mSubscribeFlags & GXS_SERV::RSGXS_GROUP_SUBSCRIBE_MASK) grpIds.push_back(mit->first); } diff --git a/libretroshare/src/gxs/rstokenservice.h b/libretroshare/src/gxs/rstokenservice.h index ec86e3814..408c93dd0 100644 --- a/libretroshare/src/gxs/rstokenservice.h +++ b/libretroshare/src/gxs/rstokenservice.h @@ -59,6 +59,8 @@ #define RS_TOKREQ_ANSTYPE_LIST 0x0001 #define RS_TOKREQ_ANSTYPE_SUMMARY 0x0002 #define RS_TOKREQ_ANSTYPE_DATA 0x0003 +#define RS_TOKREQ_ANSTYPE_ACK 0x0004 + @@ -72,7 +74,8 @@ public: RsTokReqOptionsV2() { mOptions = 0; - mStatusFilter = 0; mStatusMask = 0; mSubscribeFilter = 0; + mStatusFilter = 0; mStatusMask = 0; mSubscribeFilter = 0; + mMsgFlagMask = 0; mMsgFlagFilter = 0; mBefore = 0; mAfter = 0; mReqType = 0; } @@ -83,6 +86,8 @@ uint32_t mOptions; uint32_t mStatusFilter; uint32_t mStatusMask; +uint32_t mMsgFlagMask, mMsgFlagFilter; + uint32_t mReqType; uint32_t mSubscribeFilter; // Only for Groups. diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 0177de3a1..515b19d72 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -10,7 +10,7 @@ CONFIG += test_voip # GXS Stuff. CONFIG += newcache -CONFIG += newservices +#CONFIG += newservices # Beware: All data of the stripped services are lost DEFINES *= PQI_DISABLE_TUNNEL @@ -137,7 +137,8 @@ PUBLIC_HEADERS = retroshare/rsblogs.h \ retroshare/rstypes.h \ retroshare/rsdht.h \ retroshare/rsdsdv.h \ - retroshare/rsconfig.h + retroshare/rsconfig.h \ + retroshare/rsphotoV2.h HEADERS += plugins/pluginmanager.h \ plugins/dlfcn_win32.h \ serialiser/rspluginitems.h @@ -148,65 +149,7 @@ HEADERS += retroshare/rsgame.h \ retroshare/rsphoto.h # ################################ Linux ########################################## -linux-*:isEmpty(PREFIX) { - PREFIX = /usr \ - } - isEmpty(INC_DIR) { - INC_DIR = $${PREFIX}/include/retroshare/ \ - } - isEmpty(LIB_DIR) { - LIB_DIR = $${PREFIX}/lib/ \ - } - - # These two lines fixe compilation on ubuntu natty. Probably a ubuntu packaging error. - INCLUDEPATH *= /usr/lib/x86_64-linux-gnu/glib-2.0/include/ - INCLUDEPATH *= /usr/lib/i386-linux-gnu/glib-2.0/include/ - OPENPGPSDK_DIR = ../../openpgpsdk/src - INCLUDEPATH *= $${OPENPGPSDK_DIR} \ - ../openpgpsdk - DESTDIR = lib - QMAKE_CXXFLAGS *= -Wall \ - -D_FILE_OFFSET_BITS=64 - QMAKE_CC = g++ - SSL_DIR = /usr/include/openssl - UPNP_DIR = /usr/include/upnp - INCLUDEPATH += . \ - $${SSL_DIR} \ - $${UPNP_DIR} - - # gpg files - system(which gpg-error-config >/dev/null 2>&1):INCLUDEPATH += $$system(gpg-error-config --cflags | sed -e "s/-I//g") - else:message(Could not find gpg-error-config on your system, assuming gpg-error.h is in /usr/include) - system(which gpgme-config >/dev/null 2>&1):INCLUDEPATH += $$system(gpgme-config --cflags | sed -e "s/-I//g") - else:message(Could not find gpgme-config on your system, assuming gpgme.h is in /usr/include) - - # libupnp implementation files - HEADERS += upnp/UPnPBase.h - SOURCES += upnp/UPnPBase.cpp - - # where to put the shared library itself - target.path = $$LIB_DIR - INSTALLS *= target - - # where to put the library's interface - include_rsiface.path = $${INC_DIR} - include_rsiface.files = $$PUBLIC_HEADERS - INSTALLS += include_rsiface - - # CONFIG += version_detail_bash_script - DEFINES *= UBUNTU - INCLUDEPATH += /usr/include/glib-2.0/ \ - /usr/lib/glib-2.0/include - LIBS *= -lgnome-keyring - linux-g++:OBJECTS_DIR = temp/linux-g++/obj - linux-g++-64:OBJECTS_DIR = temp/linux-g++-64/obj - version_detail_bash_script { - QMAKE_EXTRA_TARGETS += write_version_detail - PRE_TARGETDEPS = write_version_detail - write_version_detail.commands = ./version_detail.sh - } - # ################### Cross compilation for windows under Linux #################### win32-x-g++ { OBJECTS_DIR = temp/win32xgcc/obj @@ -262,10 +205,10 @@ linux-*:isEmpty(PREFIX) { # miniupnp implementation files HEADERS += upnp/upnputil.h SOURCES += upnp/upnputil.c - UPNPC_DIR = ../../../miniupnpc-1.3 - PTHREADS_DIR = ../../../pthreads-w32-2-8-0-release - ZLIB_DIR = ../../../zlib-1.2.3 - SSL_DIR = ../../../openssl-1.0.1c + UPNPC_DIR = ../../../lib/miniupnpc-1.3 + PTHREADS_DIR = ../../../lib/pthreads-w32-2-8-0-release + ZLIB_DIR = ../../../lib/zlib-1.2.3 + SSL_DIR = ../../../OpenSSL OPENPGPSDK_DIR = ../../openpgpsdk/src INCLUDEPATH += . \ $${SSL_DIR}/include \ @@ -274,7 +217,7 @@ linux-*:isEmpty(PREFIX) { $${ZLIB_DIR} \ $${OPENPGPSDK_DIR} newcache { - SQLITE_DIR = ../../../sqlite-autoconf-3071300 + SQLITE_DIR = ../../../../Libraries/sqlite/sqlite-autoconf-3070900 INCLUDEPATH += . \ $${SQLITE_DIR} } diff --git a/libretroshare/src/retroshare/rsidentityVEG.h b/libretroshare/src/retroshare/rsidentityVEG.h index 06c736222..9a58ab96d 100644 --- a/libretroshare/src/retroshare/rsidentityVEG.h +++ b/libretroshare/src/retroshare/rsidentityVEG.h @@ -62,9 +62,6 @@ #define RS_TOKREQ_ANSTYPE_LIST 0x0001 #define RS_TOKREQ_ANSTYPE_SUMMARY 0x0002 -#define RS_TOKREQ_ANSTYPE_DATA 0x0003 -#define RS_TOKREQ_ANSTYPE_ACK 0x0004 - diff --git a/libretroshare/src/retroshare/rsphotoV2.h b/libretroshare/src/retroshare/rsphotoV2.h index c355fb173..838843134 100644 --- a/libretroshare/src/retroshare/rsphotoV2.h +++ b/libretroshare/src/retroshare/rsphotoV2.h @@ -30,7 +30,6 @@ #include #include #include "rsgxsservice.h" -#include "rsphotoVEG.h" /* The Main Interface Class - for information about your Peers */ class RsPhotoV2; @@ -42,21 +41,20 @@ extern RsPhotoV2 *rsPhotoV2; #define RSPHOTO_MODE_OWN 2 #define RSPHOTO_MODE_REMOTE 3 -//class RsPhotoThumbnail -//{ -// public: -// RsPhotoThumbnail() -// :data(NULL), size(0), type("N/A") { return; } -// -// bool deleteImage(); -// bool copyFrom(const RsPhotoThumbnail &nail); -// -// // Holds Thumbnail image. -// uint8_t *data; -// int size; -// std::string type; -//}; +class RsPhotoThumbnail +{ + public: + RsPhotoThumbnail() + :data(NULL), size(0), type("N/A") { return; } + bool deleteImage(); + bool copyFrom(const RsPhotoThumbnail &nail); + + // Holds Thumbnail image. + uint8_t *data; + int size; + std::string type; +}; /* If these flags are no set - the Photo inherits values from the Album */ @@ -76,85 +74,95 @@ extern RsPhotoV2 *rsPhotoV2; #define RSPHOTO_FLAGS_ATTRIB_AUTHOR 0x1000 // PUSH UP ORDER #define RSPHOTO_FLAGS_ATTRIB_PHOTO 0x2000 // PUSH UP ORDER. +class RsPhotoPhoto +{ + public: -//class RsPhotoPhoto -//{ -// public: -// -// RsMsgMetaData mMeta; -// -// RsPhotoPhoto(); -// -// // THESE ARE IN THE META DATA. -// //std::string mAlbumId; -// //std::string mId; -// //std::string mTitle; // only used by Album. -// std::string mCaption; -// std::string mDescription; -// std::string mPhotographer; -// std::string mWhere; -// std::string mWhen; -// std::string mOther; -// std::string mCategory; -// -// std::string mHashTags; -// -// uint32_t mSetFlags; -// -// int mOrder; -// -// RsPhotoThumbnail mThumbnail; -// -// int mMode; -// -// // These are not saved. -// std::string path; // if in Mode NEW. -// uint32_t mModFlags; -//}; + RsMsgMetaData mMeta; -//class RsPhotoAlbumShare -//{ -// public: -// -// uint32_t mShareType; -// std::string mShareGroupId; -// std::string mPublishKey; -// uint32_t mCommentMode; -// uint32_t mResizeMode; -//}; -// -//class RsPhotoAlbum -//{ -// public: -// RsPhotoAlbum(); -// -// RsGroupMetaData mMeta; -// -// // THESE ARE IN THE META DATA. -// //std::string mAlbumId; -// //std::string mTitle; // only used by Album. -// -// std::string mCaption; -// std::string mDescription; -// std::string mPhotographer; -// std::string mWhere; -// std::string mWhen; -// std::string mOther; -// std::string mCategory; -// -// std::string mHashTags; -// -// RsPhotoThumbnail mThumbnail; -// -// int mMode; -// -// std::string mPhotoPath; -// RsPhotoAlbumShare mShareOptions; -// -// // These aren't saved. -// uint32_t mSetFlags; -// uint32_t mModFlags; -//}; + RsPhotoPhoto(); + + // THESE ARE IN THE META DATA. + //std::string mAlbumId; + //std::string mId; + //std::string mTitle; // only used by Album. + std::string mCaption; + std::string mDescription; + std::string mPhotographer; + std::string mWhere; + std::string mWhen; + std::string mOther; + std::string mCategory; + + std::string mHashTags; + + uint32_t mSetFlags; + + int mOrder; + + RsPhotoThumbnail mThumbnail; + + int mMode; + + // These are not saved. + std::string path; // if in Mode NEW. + uint32_t mModFlags; +}; + +class RsPhotoAlbumShare +{ + public: + + uint32_t mShareType; + std::string mShareGroupId; + std::string mPublishKey; + uint32_t mCommentMode; + uint32_t mResizeMode; +}; + +class RsPhotoAlbum +{ + public: + RsPhotoAlbum(); + + RsGroupMetaData mMeta; + + // THESE ARE IN THE META DATA. + //std::string mAlbumId; + //std::string mTitle; // only used by Album. + + std::string mCaption; + std::string mDescription; + std::string mPhotographer; + std::string mWhere; + std::string mWhen; + std::string mOther; + std::string mCategory; + + std::string mHashTags; + + RsPhotoThumbnail mThumbnail; + + int mMode; + + std::string mPhotoPath; + RsPhotoAlbumShare mShareOptions; + + // These aren't saved. + uint32_t mSetFlags; + uint32_t mModFlags; +}; + +class RsPhotoComment +{ +public: + RsPhotoComment(); + + RsMsgMetaData mMeta; + + std::string mComment; + uint32_t mCommentFlag; +}; std::ostream &operator<<(std::ostream &out, const RsPhotoPhoto &photo); std::ostream &operator<<(std::ostream &out, const RsPhotoAlbum &album); @@ -167,136 +175,150 @@ class RsPhotoV2 public: + static const uint32_t FLAG_MSG_TYPE_PHOTO_POST; + static const uint32_t FLAG_MSG_TYPE_PHOTO_COMMENT; + static const uint32_t FLAG_MSG_TYPE_MASK; - RsPhotoV2() { return; } - virtual ~RsPhotoV2() { return; } + RsPhotoV2() { return; } - /*! - * Use to enquire if groups or msgs have changed - * Poll regularly, particularly after a photo submission - * @return true if msgs or groups have changed - */ - virtual bool updated() = 0; + virtual ~RsPhotoV2() { return; } - /*! - * - * @param grpIds - */ - virtual void groupsChanged(std::list& grpIds) = 0; + /*! + * Use to enquire if groups or msgs have changed + * Poll regularly, particularly after a photo submission + * @return true if msgs or groups have changed + */ + virtual bool updated() = 0; - /*! - * - * @param msgs - */ - virtual void msgsChanged(GxsMsgIdResult& msgs) = 0; + /*! + * + * @param grpIds + */ + virtual void groupsChanged(std::list& grpIds) = 0; - /*! - * To acquire a handle to token service handler - * needed to make requests to the service - * @return handle to token service for this gxs service - */ - virtual RsTokenServiceV2* getTokenService() = 0; + /*! + * + * @param msgs + */ + virtual void msgsChanged(GxsMsgIdResult& msgs) = 0; - /* Generic Lists */ + /*! + * To acquire a handle to token service handler + * needed to make requests to the service + * @return handle to token service for this gxs service + */ + virtual RsTokenServiceV2* getTokenService() = 0; - /*! - * - * @param token token to be redeemed for this request - * @param groupIds the ids return for given request token - * @return false if request token is invalid, check token status for error report - */ - virtual bool getGroupList(const uint32_t &token, - std::list &groupIds) = 0; + /* Generic Lists */ - /*! - * @param token token to be redeemed for this request - * @param msgIds the ids return for given request token - * @return false if request token is invalid, check token status for error report - */ - virtual bool getMsgList(const uint32_t &token, - GxsMsgIdResult &msgIds) = 0; + /*! + * + * @param token token to be redeemed for this request + * @param groupIds the ids return for given request token + * @return false if request token is invalid, check token status for error report + */ + virtual bool getGroupList(const uint32_t &token, + std::list &groupIds) = 0; - /* Generic Summary */ + /*! + * @param token token to be redeemed for this request + * @param msgIds the ids return for given request token + * @return false if request token is invalid, check token status for error report + */ + virtual bool getMsgList(const uint32_t &token, + GxsMsgIdResult &msgIds) = 0; - /*! - * @param token token to be redeemed for group summary request - * @param groupInfo the ids returned for given request token - * @return false if request token is invalid, check token status for error report - */ - virtual bool getGroupSummary(const uint32_t &token, - std::list &groupInfo) = 0; + /* Generic Summary */ - /*! - * @param token token to be redeemed for message summary request - * @param msgInfo the message metadata returned for given request token - * @return false if request token is invalid, check token status for error report - */ - virtual bool getMsgSummary(const uint32_t &token, - MsgMetaResult &msgInfo) = 0; + /*! + * @param token token to be redeemed for group summary request + * @param groupInfo the ids returned for given request token + * @return false if request token is invalid, check token status for error report + */ + virtual bool getGroupSummary(const uint32_t &token, + std::list &groupInfo) = 0; - /* Specific Service Data */ + /*! + * @param token token to be redeemed for message summary request + * @param msgInfo the message metadata returned for given request token + * @return false if request token is invalid, check token status for error report + */ + virtual bool getMsgSummary(const uint32_t &token, + MsgMetaResult &msgInfo) = 0; - /*! - * @param token token to be redeemed for album request - * @param album the album returned for given request token - * @return false if request token is invalid, check token status for error report - */ - virtual bool getAlbum(const uint32_t &token, std::vector &album) = 0; + /* Specific Service Data */ - /*! - * @param token token to be redeemed for photo request - * @param photo the photo returned for given request token - * @return false if request token is invalid, check token status for error report - */ - virtual bool getPhoto(const uint32_t &token, - PhotoResult &photo) = 0; + /*! + * @param token token to be redeemed for album request + * @param album the album returned for given request token + * @return false if request token is invalid, check token status for error report + */ + virtual bool getAlbum(const uint32_t &token, std::vector &album) = 0; - /* details are updated in album - to choose Album ID, and storage path */ + /*! + * @param token token to be redeemed for photo request + * @param photo the photo returned for given request token + * @return false if request token is invalid, check token status for error report + */ + virtual bool getPhoto(const uint32_t &token, + PhotoResult &photo) = 0; - /*! - * submits album, which returns a token that needs - * to be acknowledge to get album grp id - * @param token token to redeem for acknowledgement - * @param album album to be submitted - */ - virtual bool submitAlbumDetails(uint32_t& token, RsPhotoAlbum &album) = 0; + /* details are updated in album - to choose Album ID, and storage path */ - /*! - * submits photo, which returns a token that needs - * to be acknowledge to get photo msg-grp id pair - * @param token token to redeem for acknowledgement - * @param photo photo to be submitted - */ - virtual bool submitPhoto(uint32_t& token, RsPhotoPhoto &photo) = 0; + /*! + * submits album, which returns a token that needs + * to be acknowledge to get album grp id + * @param token token to redeem for acknowledgement + * @param album album to be submitted + */ + virtual bool submitAlbumDetails(uint32_t& token, RsPhotoAlbum &album) = 0; - /*! - * subscribes to group, and returns token which can be used - * to be acknowledged to get group Id - * @param token token to redeem for acknowledgement - * @param grpId the id of the group to subscribe to - */ - virtual bool subscribeToAlbum(uint32_t& token, const RsGxsGroupId& grpId) = 0; + /*! + * submits photo, which returns a token that needs + * to be acknowledged to get photo msg-grp id pair + * @param token token to redeem for acknowledgement + * @param photo photo to be submitted + */ + virtual bool submitPhoto(uint32_t& token, RsPhotoPhoto &photo) = 0; - /*! - * This allows the client service to acknowledge that their msgs has - * been created/modified and retrieve the create/modified msg ids - * @param token the token related to modification/create request - * @param msgIds map of grpid->msgIds of message created/modified - * @return true if token exists false otherwise - */ - virtual bool acknowledgeMsg(const uint32_t& token, std::pair& msgId) = 0; + /*! + * submits photo comment, which returns a token that needs + * to be acknowledged to get photo msg-grp id pair + * The mParentId needs to be set to an existing msg for which + * commenting is enabled + * @param token token to redeem for acknowledgement + * @param comment comment to be submitted + */ + virtual bool submitComment(uint32_t& token, RsPhotoComment &photo) = 0; + + /*! + * subscribes to group, and returns token which can be used + * to be acknowledged to get group Id + * @param token token to redeem for acknowledgement + * @param grpId the id of the group to subscribe to + */ + virtual bool subscribeToAlbum(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe) = 0; + + /*! + * This allows the client service to acknowledge that their msgs has + * been created/modified and retrieve the create/modified msg ids + * @param token the token related to modification/create request + * @param msgIds map of grpid->msgIds of message created/modified + * @return true if token exists false otherwise + */ + virtual bool acknowledgeMsg(const uint32_t& token, std::pair& msgId) = 0; - /*! - * This allows the client service to acknowledge that their grps has - * been created/modified and retrieve the create/modified grp ids - * @param token the token related to modification/create request - * @param msgIds vector of ids of groups created/modified - * @return true if token exists false otherwise - */ - virtual bool acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId) = 0; + /*! + * This allows the client service to acknowledge that their grps has + * been created/modified and retrieve the create/modified grp ids + * @param token the token related to modification/create request + * @param msgIds vector of ids of groups created/modified + * @return true if token exists false otherwise + */ + virtual bool acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId) = 0; }; diff --git a/libretroshare/src/retroshare/rsphotoVEG.h b/libretroshare/src/retroshare/rsphotoVEG.h index 5b67ea7a1..13c7da7ac 100644 --- a/libretroshare/src/retroshare/rsphotoVEG.h +++ b/libretroshare/src/retroshare/rsphotoVEG.h @@ -30,6 +30,7 @@ #include #include #include +#include "rsphotoV2.h" /* The Main Interface Class - for information about your Peers */ class RsPhotoVEG; @@ -41,22 +42,6 @@ extern RsPhotoVEG *rsPhotoVEG; #define RSPHOTO_MODE_OWN 2 #define RSPHOTO_MODE_REMOTE 3 -class RsPhotoThumbnail -{ - public: - RsPhotoThumbnail() - :data(NULL), size(0), type("N/A") { return; } - - bool deleteImage(); - bool copyFrom(const RsPhotoThumbnail &nail); - - // Holds Thumbnail image. - uint8_t *data; - int size; - std::string type; -}; - - /* If these flags are no set - the Photo inherits values from the Album */ @@ -76,85 +61,6 @@ class RsPhotoThumbnail #define RSPHOTO_FLAGS_ATTRIB_PHOTO 0x2000 // PUSH UP ORDER. -class RsPhotoPhoto -{ - public: - - RsMsgMetaData mMeta; - - RsPhotoPhoto(); - - // THESE ARE IN THE META DATA. - //std::string mAlbumId; - //std::string mId; - //std::string mTitle; // only used by Album. - std::string mCaption; - std::string mDescription; - std::string mPhotographer; - std::string mWhere; - std::string mWhen; - std::string mOther; - std::string mCategory; - - std::string mHashTags; - - uint32_t mSetFlags; - - int mOrder; - - RsPhotoThumbnail mThumbnail; - - int mMode; - - // These are not saved. - std::string path; // if in Mode NEW. - uint32_t mModFlags; -}; - -class RsPhotoAlbumShare -{ - public: - - uint32_t mShareType; - std::string mShareGroupId; - std::string mPublishKey; - uint32_t mCommentMode; - uint32_t mResizeMode; -}; - -class RsPhotoAlbum -{ - public: - RsPhotoAlbum(); - - RsGroupMetaData mMeta; - - // THESE ARE IN THE META DATA. - //std::string mAlbumId; - //std::string mTitle; // only used by Album. - - std::string mCaption; - std::string mDescription; - std::string mPhotographer; - std::string mWhere; - std::string mWhen; - std::string mOther; - std::string mCategory; - - std::string mHashTags; - - RsPhotoThumbnail mThumbnail; - - int mMode; - - std::string mPhotoPath; - RsPhotoAlbumShare mShareOptions; - - // These aren't saved. - uint32_t mSetFlags; - uint32_t mModFlags; -}; - std::ostream &operator<<(std::ostream &out, const RsPhotoPhoto &photo); std::ostream &operator<<(std::ostream &out, const RsPhotoAlbum &album); diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index de9df7df6..c708eb0de 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1806,7 +1806,7 @@ RsTurtle *rsTurtle = NULL ; #include "services/p3blogs.h" #include "turtle/p3turtle.h" -#define ENABLE_GXS_VEG_SERVICES 1 +#define ENABLE_GXS_SERVICES 1 #define ENABLE_GXS_CORE 1 #ifdef ENABLE_GXS_CORE @@ -1816,13 +1816,13 @@ RsTurtle *rsTurtle = NULL ; #include "gxs/rsgxsnetservice.h" #endif -#ifdef ENABLE_GXS_VEG_SERVICES -#include "services/p3photoserviceVEG.h" -#include "services/p3wikiserviceVEG.h" -#include "services/p3wireVEG.h" -#include "services/p3idserviceVEG.h" -#include "services/p3forumsVEG.h" -#include "services/p3postedVEG.h" +#ifdef ENABLE_GXS_SERVICES +#include "services/p3photoservice.h" +#include "services/p3wikiservice.h" +#include "services/p3wire.h" +#include "services/p3idservice.h" +#include "services/p3forumsv2.h" +#include "services/p3posted.h" #endif #ifndef PQI_DISABLE_TUNNEL @@ -2272,7 +2272,7 @@ int RsServer::StartupRetroShare() // first prep the core RsGeneralDataService* photo_ds = new RsDataService("./", "photoV2_db", - RS_SERVICE_GXSV1_TYPE_PHOTO, NULL); + RS_SERVICE_TYPE_PHOTO, NULL); photo_ds->resetDataStore(); @@ -2295,37 +2295,33 @@ int RsServer::StartupRetroShare() // start up gxs core server createThread(*mGxsCore); - - // create some dummy items - - #endif -#ifdef ENABLE_GXS_VEG_SERVICES +#ifdef ENABLE_GXS_SERVICES // Testing New Cache Services. - p3PhotoServiceVEG *mPhotosVEG = new p3PhotoServiceVEG(RS_SERVICE_VEG_TYPE_PHOTO); - pqih -> addService(mPhotosVEG); + p3PhotoService *mPhotos = new p3PhotoService(RS_SERVICE_TYPE_PHOTO); + pqih -> addService(mPhotos); // Testing New Cache Services. - p3WikiServiceVEG *mWikisVEG = new p3WikiServiceVEG(RS_SERVICE_VEG_TYPE_WIKI); - pqih -> addService(mWikisVEG); + p3WikiService *mWikis = new p3WikiService(RS_SERVICE_TYPE_WIKI); + pqih -> addService(mWikis); // Testing New Cache Services. - p3WireVEG *mWireVEG = new p3WireVEG(RS_SERVICE_VEG_TYPE_WIRE); - pqih -> addService(mWireVEG); + p3Wire *mWire = new p3Wire(RS_SERVICE_TYPE_WIRE); + pqih -> addService(mWire); // Testing New Cache Services. - p3IdServiceVEG *mIdentityVEG = new p3IdServiceVEG(RS_SERVICE_VEG_TYPE_IDENTITY); - pqih -> addService(mIdentityVEG); + p3IdService *mIdentity = new p3IdService(RS_SERVICE_TYPE_IDENTITY); + pqih -> addService(mIdentity); // Testing New Cache Services. - p3ForumsVEG *mForumsVEG = new p3ForumsVEG(RS_SERVICE_VEG_TYPE_FORUMS); - pqih -> addService(mForumsVEG); + p3ForumsV2 *mForumsV2 = new p3ForumsV2(RS_SERVICE_TYPE_FORUMSV2); + pqih -> addService(mForumsV2); // Testing New Cache Services. - p3PostedServiceVEG *mPostedVEG = new p3PostedServiceVEG(RS_SERVICE_VEG_TYPE_POSTED); - pqih -> addService(mPostedVEG); -#endif // ENABLE_GXS_VEG_SERVICES + p3PostedService *mPosted = new p3PostedService(RS_SERVICE_TYPE_POSTED); + pqih -> addService(mPosted); +#endif // ENABLE_GXS_SERVICES #ifndef RS_RELEASE @@ -2586,18 +2582,15 @@ int RsServer::StartupRetroShare() #ifdef ENABLE_GXS_SERVICES // Testing of new cache system interfaces. - rsIdentityVEG = mIdentityVEG; - rsPhotoVEG = mPhotosVEG; - rsWikiVEG = mWikisVEG; - rsWireVEG = mWireVEG; - rsForumsVEG = mForumsVEG; - rsPostedVEG = mPostedVEG; - + rsIdentity = mIdentity; + rsPhoto = mPhotos; + rsPhotoV2 = mPhotoV2; + rsWiki = mWikis; + rsWire = mWire; + rsForumsV2 = mForumsV2; + rsPosted = mPosted; #endif // ENABLE_GXS_SERVICES -#ifdef ENABLE_GXS_CORE - rsPhotoV2 = mPhotoV2; -#endif // ENABLE_GXS_CORE #ifdef RS_USE_BLOGS rsBlogs = mBlogs; diff --git a/libretroshare/src/serialiser/rsphotov2items.cc b/libretroshare/src/serialiser/rsphotov2items.cc index 360f3d819..ac153ecba 100644 --- a/libretroshare/src/serialiser/rsphotov2items.cc +++ b/libretroshare/src/serialiser/rsphotov2items.cc @@ -88,7 +88,7 @@ RsItem* RsGxsPhotoSerialiser::deserialise(void* data, uint32_t* size) uint32_t rstype = getRsItemId(data); if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_GXSV1_TYPE_PHOTO != getRsItemService(rstype))) + (RS_SERVICE_TYPE_PHOTO != getRsItemService(rstype))) { return NULL; /* wrong type */ } @@ -175,7 +175,7 @@ bool RsGxsPhotoSerialiser::serialiseGxsPhotoAlbumItem(RsGxsPhotoAlbumItem* item, ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mWhen); ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mWhere); ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mThumbnail.type); - RsTlvBinaryData b(RS_SERVICE_GXSV1_TYPE_PHOTO); // TODO, need something more persisitent + RsTlvBinaryData b(RS_SERVICE_TYPE_PHOTO); // TODO, need something more persisitent b.setBinData(item->album.mThumbnail.data, item->album.mThumbnail.size); ok &= b.SetTlv(data, tlvsize, &offset); @@ -213,7 +213,7 @@ RsGxsPhotoAlbumItem* RsGxsPhotoSerialiser::deserialiseGxsPhotoAlbumItem(void* da if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_GXSV1_TYPE_PHOTO != getRsItemService(rstype)) || + (RS_SERVICE_TYPE_PHOTO != getRsItemService(rstype)) || (RS_PKT_SUBTYPE_PHOTO_ITEM != getRsItemSubType(rstype))) { #ifdef GXS_PHOTO_SERIAL_DEBUG @@ -251,7 +251,7 @@ RsGxsPhotoAlbumItem* RsGxsPhotoSerialiser::deserialiseGxsPhotoAlbumItem(void* da ok &= GetTlvString(data, rssize, &offset, 1, item->album.mWhere); ok &= GetTlvString(data, rssize, &offset, 1, item->album.mThumbnail.type); - RsTlvBinaryData b(RS_SERVICE_GXSV1_TYPE_PHOTO); // TODO, need something more persisitent + RsTlvBinaryData b(RS_SERVICE_TYPE_PHOTO); // TODO, need something more persisitent ok &= b.GetTlv(data, rssize, &offset); item->album.mThumbnail.data = (uint8_t*)b.bin_data; item->album.mThumbnail.size = b.bin_len; @@ -341,7 +341,7 @@ bool RsGxsPhotoSerialiser::serialiseGxsPhotoPhotoItem(RsGxsPhotoPhotoItem* item, ok &= SetTlvString(data, tlvsize, &offset, 1, item->photo.mWhen); ok &= SetTlvString(data, tlvsize, &offset, 1, item->photo.mWhere); ok &= SetTlvString(data, tlvsize, &offset, 1, item->photo.mThumbnail.type); - RsTlvBinaryData b(RS_SERVICE_GXSV1_TYPE_PHOTO); // TODO, need something more persisitent + RsTlvBinaryData b(RS_SERVICE_TYPE_PHOTO); // TODO, need something more persisitent b.setBinData(item->photo.mThumbnail.data, item->photo.mThumbnail.size); ok &= b.SetTlv(data, tlvsize, &offset); @@ -379,7 +379,7 @@ RsGxsPhotoPhotoItem* RsGxsPhotoSerialiser::deserialiseGxsPhotoPhotoItem(void* da if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_GXSV1_TYPE_PHOTO != getRsItemService(rstype)) || + (RS_SERVICE_TYPE_PHOTO != getRsItemService(rstype)) || (RS_PKT_SUBTYPE_PHOTO_SHOW_ITEM != getRsItemSubType(rstype))) { #ifdef GXS_PHOTO_SERIAL_DEBUG @@ -415,7 +415,7 @@ RsGxsPhotoPhotoItem* RsGxsPhotoSerialiser::deserialiseGxsPhotoPhotoItem(void* da ok &= GetTlvString(data, rssize, &offset, 1, item->photo.mWhere); ok &= GetTlvString(data, rssize, &offset, 1, item->photo.mThumbnail.type); - RsTlvBinaryData b(RS_SERVICE_GXSV1_TYPE_PHOTO); // TODO, need something more persisitent + RsTlvBinaryData b(RS_SERVICE_TYPE_PHOTO); // TODO, need something more persisitent ok &= b.GetTlv(data, rssize, &offset); item->photo.mThumbnail.data = (uint8_t*)(b.bin_data); item->photo.mThumbnail.size = b.bin_len; diff --git a/libretroshare/src/serialiser/rsphotov2items.h b/libretroshare/src/serialiser/rsphotov2items.h index 1cbba7dd5..c636ab5bc 100644 --- a/libretroshare/src/serialiser/rsphotov2items.h +++ b/libretroshare/src/serialiser/rsphotov2items.h @@ -68,6 +68,20 @@ public: RsPhotoPhoto photo; }; +class RsGxsPhotoCommentItem : public RsGxsMsgItem +{ +public: + + RsGxsPhotoCommentItem(): RsGxsMsgItem(RS_SERVICE_GXSV1_TYPE_PHOTO, + RS_PKT_SUBTYPE_PHOTO_COMMENT_ITEM) { return; } + virtual ~RsGxsPhotoCommentItem() { return; } + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + RsPhotoComment comment; + + +}; + class RsGxsPhotoSerialiser : public RsSerialType { public: @@ -91,6 +105,9 @@ public: bool serialiseGxsPhotoPhotoItem (RsGxsPhotoPhotoItem *item, void *data, uint32_t *size); RsGxsPhotoPhotoItem * deserialiseGxsPhotoPhotoItem(void *data, uint32_t *size); + uint32_t sizeGxsPhotoCommentItem(RsGxsPhotoCommentItem *item); + bool serialiseGxsPhotoCommentItem (RsGxsPhotoCommentItem *item, void *data, uint32_t *size); + RsGxsPhotoCommentItem * deserialiseGxsPhotoCommentItem(void *data, uint32_t *size); }; diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 7981eb70b..1dc8bc3c0 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -58,8 +58,8 @@ p3IdService::p3IdService(uint16_t type) int p3IdService::tick() { - //std::cerr << "p3IdService::tick()"; - //std::cerr << std::endl; + std::cerr << "p3IdService::tick()"; + std::cerr << std::endl; fakeprocessrequests(); // Disable for now. diff --git a/libretroshare/src/services/p3photoserviceV2.cc b/libretroshare/src/services/p3photoserviceV2.cc index 144a1eace..a460ff3b7 100644 --- a/libretroshare/src/services/p3photoserviceV2.cc +++ b/libretroshare/src/services/p3photoserviceV2.cc @@ -1,14 +1,12 @@ #include "p3photoserviceV2.h" #include "serialiser/rsphotov2items.h" -#include "gxs/rsgxsflags.h" RsPhotoV2 *rsPhotoV2 = NULL; p3PhotoServiceV2::p3PhotoServiceV2(RsGeneralDataService* gds, RsNetworkExchangeService* nes) - : RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_GXSV1_TYPE_PHOTO) + : RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_TYPE_PHOTO) { - } bool p3PhotoServiceV2::updated() @@ -148,13 +146,6 @@ bool p3PhotoServiceV2::submitAlbumDetails(uint32_t& token, RsPhotoAlbum& album) return true; } -bool p3PhotoServiceV2::subscribeToAlbum(uint32_t &token, const RsGxsGroupId &grpId) -{ - - RsGenExchange::setGroupSubscribeFlag(token, grpId, GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED); - return true; -} - void p3PhotoServiceV2::notifyChanges(std::vector& changes) diff --git a/libretroshare/src/services/p3photoserviceV2.h b/libretroshare/src/services/p3photoserviceV2.h index a55e4f710..fe58dab07 100644 --- a/libretroshare/src/services/p3photoserviceV2.h +++ b/libretroshare/src/services/p3photoserviceV2.h @@ -94,13 +94,23 @@ public: */ bool submitPhoto(uint32_t& token, RsPhotoPhoto &photo); + /*! + * submits photo comment, which returns a token that needs + * to be acknowledged to get photo msg-grp id pair + * The mParentId needs to be set to an existing msg for which + * commenting is enabled + * @param token token to redeem for acknowledgement + * @param comment comment to be submitted + */ + bool submitComment(uint32_t& token, RsPhotoComment &photo); + /*! * subscribes to group, and returns token which can be used * to be acknowledged to get group Id * @param token token to redeem for acknowledgement * @param grpId the id of the group to subscribe to */ - bool subscribeToAlbum(uint32_t& token, const RsGxsGroupId& grpId); + bool subscribeToAlbum(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe); /*! * This allows the client service to acknowledge that their msgs has diff --git a/openpgpsdk/src/openpgpsdk.pro b/openpgpsdk/src/openpgpsdk.pro index 41b84219d..90f99b446 100644 --- a/openpgpsdk/src/openpgpsdk.pro +++ b/openpgpsdk/src/openpgpsdk.pro @@ -17,9 +17,9 @@ linux-* { } win32 { - SSL_DIR = ../../../openssl-1.0.1c - ZLIB_DIR = ../../../zlib-1.2.3 - BZIP_DIR = ../../../bzip2-1.0.6 + SSL_DIR = ../../../OpenSSL + ZLIB_DIR = ../../../lib/zlib-1.2.3 + BZIP_DIR = ../../../lib/bzip2-1.0.6 INCLUDEPATH += $${SSL_DIR}/include $${ZLIB_DIR} $${BZIP_DIR} } diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index 73bac1f46..a67c0a0e5 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -193,8 +193,8 @@ freebsd-* { # ########################################### bitdht { - LIBS += ../../libbitdht/src/lib/libbitdht.a - PRE_TARGETDEPS *= ../../libbitdht/src/lib/libbitdht.a + LIBS += C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a + PRE_TARGETDEPS *= C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a # Chris version. #LIBS += ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a @@ -416,7 +416,8 @@ HEADERS += rshare.h \ gui/groups/CreateGroup.h \ gui/dht/DhtWindow.h \ gui/bwctrl/BwCtrlWindow.h \ - gui/GetStartedDialog.h + gui/GetStartedDialog.h \ + gui/PhotoShare/PhotoCommentItem.h @@ -520,7 +521,7 @@ FORMS += gui/StartDialog.ui \ gui/dht/DhtWindow.ui \ gui/bwctrl/BwCtrlWindow.ui \ gui/GetStartedDialog.ui \ - + gui/PhotoShare/PhotoCommentItem.ui SOURCES += main.cpp \ rshare.cpp \ gui/notifyqt.cpp \ @@ -699,7 +700,8 @@ SOURCES += main.cpp \ gui/groups/CreateGroup.cpp \ gui/dht/DhtWindow.cpp \ gui/bwctrl/BwCtrlWindow.cpp \ - gui/GetStartedDialog.cpp + gui/GetStartedDialog.cpp \ + gui/PhotoShare/PhotoCommentItem.cpp RESOURCES += gui/images.qrc lang/lang.qrc gui/help/content/content.qrc @@ -862,7 +864,6 @@ SOURCES += gui/unfinished/ApplicationWindow.cpp \ photoshare { HEADERS += \ - gui/PhotoShare/PhotoDialog.h \ gui/PhotoShare/PhotoDrop.h \ gui/PhotoShare/AlbumItem.h \ gui/PhotoShare/AlbumDialog.h \ @@ -872,6 +873,7 @@ photoshare { gui/PhotoShare/PhotoShareItemHolder.h \ gui/PhotoShare/PhotoShare.h \ gui/PhotoShare/PhotoSlideShow.h \ + gui/PhotoShare/PhotoDialog.h FORMS += \ gui/PhotoShare/PhotoItem.ui \ @@ -880,7 +882,7 @@ photoshare { gui/PhotoShare/AlbumDialog.ui \ gui/PhotoShare/AlbumCreateDialog.ui \ gui/PhotoShare/PhotoShare.ui \ - gui/PhotoShare/PhotoSlideShow.ui \ + gui/PhotoShare/PhotoSlideShow.ui SOURCES += \ gui/PhotoShare/PhotoItem.cpp \ @@ -892,7 +894,7 @@ photoshare { util/TokenQueueV2.cpp \ gui/PhotoShare/PhotoShareItemHolder.cpp \ gui/PhotoShare/PhotoShare.cpp \ - gui/PhotoShare/PhotoSlideShow.cpp \ + gui/PhotoShare/PhotoSlideShow.cpp } diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumItem.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumItem.cpp index 1eff4ef9c..ab9de9797 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumItem.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumItem.cpp @@ -55,7 +55,7 @@ void AlbumItem::setSelected(bool on) update(); } -RsPhotoAlbum AlbumItem::getAlbum() +const RsPhotoAlbum& AlbumItem::getAlbum() { return mAlbum; } diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumItem.h b/retroshare-gui/src/gui/PhotoShare/AlbumItem.h index 8f862dc9c..5cabfba17 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumItem.h +++ b/retroshare-gui/src/gui/PhotoShare/AlbumItem.h @@ -16,9 +16,9 @@ class AlbumItem : public QWidget, public PhotoShareItem public: explicit AlbumItem(const RsPhotoAlbum& album, PhotoShareItemHolder* albumHolder, QWidget *parent = 0); - ~AlbumItem(); + virtual ~AlbumItem(); - RsPhotoAlbum getAlbum(); + const RsPhotoAlbum& getAlbum(); bool isSelected() { return mSelected ;} void setSelected(bool selected); diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.cpp new file mode 100644 index 000000000..c85d55b65 --- /dev/null +++ b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.cpp @@ -0,0 +1,14 @@ +#include "PhotoCommentItem.h" +#include "ui_PhotoCommentItem.h" + +PhotoCommentItem::PhotoCommentItem(QWidget *parent) : + QWidget(parent), + ui(new Ui::PhotoCommentItem) +{ + ui->setupUi(this); +} + +PhotoCommentItem::~PhotoCommentItem() +{ + delete ui; +} diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.h b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.h new file mode 100644 index 000000000..5480c685e --- /dev/null +++ b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.h @@ -0,0 +1,22 @@ +#ifndef PHOTOCOMMENTITEM_H +#define PHOTOCOMMENTITEM_H + +#include + +namespace Ui { + class PhotoCommentItem; +} + +class PhotoCommentItem : public QWidget +{ + Q_OBJECT + +public: + explicit PhotoCommentItem(QWidget *parent = 0); + ~PhotoCommentItem(); + +private: + Ui::PhotoCommentItem *ui; +}; + +#endif // PHOTOCOMMENTITEM_H diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui new file mode 100644 index 000000000..a0a27b3d1 --- /dev/null +++ b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui @@ -0,0 +1,21 @@ + + + + + PhotoCommentItem + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index 2b0ef1256..8035fb525 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -1,648 +1,33 @@ -/* - * Retroshare Photo Plugin. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "PhotoDialog.h" - -#include -#include -#include - -#include -#include - -#include -#include - -#include "AlbumCreateDialog.h" -#include "AlbumItem.h" -#include "PhotoItem.h" - -/****** - * #define PHOTO_DEBUG 1 - *****/ - - -/**************************************************************** - * New Photo Display Widget. - * - * This has two 'lists'. - * Top list shows Albums. - * Lower list is photos from the selected Album. - * - * Notes: - * Each Item will be an AlbumItem, which contains a thumbnail & random details. - * We will limit Items to < 100. With a 'Filter to see more message. - * - * Thumbnails will come from Service. - * Option to Share albums / pictures onward (if permissions allow). - * Option to Download the albums to a specified directory. (is this required if sharing an album?) - * - * Will introduce a FullScreen SlideShow later... first get basics happening. - */ - -#define IS_ALBUM_ADMIN(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) -#define IS_ALBUM_SUBSCRIBED(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) - - -/** Constructor */ -PhotoDialog::PhotoDialog(QWidget *parent) -: MainPage(parent) -{ - ui.setupUi(this); - - mAlbumSelected = NULL; - mPhotoSelected = NULL; - mSlideShow = NULL; - mAlbumDialog = NULL; - - connect( ui.toolButton_NewAlbum, SIGNAL(clicked()), this, SLOT(createAlbum())); - connect( ui.toolButton_ViewAlbum, SIGNAL(clicked()), this, SLOT(OpenAlbumDialog())); - connect( ui.toolButton_SlideShow, SIGNAL(clicked()), this, SLOT(OpenSlideShow())); - - connect( ui.pushButton_YourAlbums, SIGNAL(clicked()), this, SLOT(updateAlbums())); - connect( ui.pushButton_SharedAlbums, SIGNAL(clicked()), this, SLOT(updateAlbums())); - connect( ui.pushButton_SubscribedAlbums, SIGNAL(clicked()), this, SLOT(updateAlbums())); - - ui.pushButton_YourAlbums->setChecked(true); // default to your albums view - - QTimer *timer = new QTimer(this); - timer->connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate())); - timer->start(1000); - - - /* setup TokenQueue */ - mPhotoQueue = new TokenQueueV2(rsPhotoV2->getTokenService(), this); - requestAlbumData(); - updateAlbums(); -} - -void PhotoDialog::notifySelection(PhotoShareItem *selection) -{ - - AlbumItem* aItem; - PhotoItem* pItem; - - if((aItem = dynamic_cast(selection)) != NULL) - { - - if(mPhotoSelected) - mPhotoSelected->setSelected(false); - - clearPhotos(); - - if(mAlbumSelected == aItem) - { - mAlbumSelected->setSelected(true); - } - else - { - if(mAlbumSelected == NULL) - { - mAlbumSelected = aItem; - } - else - { - mAlbumSelected->setSelected(false); - mAlbumSelected = aItem; - } - - mAlbumSelected->setSelected(true); - - } - - updatePhotos(); - } - else if((pItem = dynamic_cast(selection)) != NULL) - { - if(mPhotoSelected == pItem) - { - mPhotoSelected->setSelected(true); - } - else - { - if(mPhotoSelected == NULL) - { - mPhotoSelected = pItem; - } - else - { - mPhotoSelected->setSelected(false); - mPhotoSelected = pItem; - } - - mPhotoSelected->setSelected(true); - } - } - else - { - - } - -} - - -void PhotoDialog::checkUpdate() -{ - /* update */ - if (!rsPhotoV2) - return; - - if (rsPhotoV2->updated()) - { - //insertAlbums(); - std::list grpIds; - rsPhotoV2->groupsChanged(grpIds); - if(!grpIds.empty()) - requestAlbumList(grpIds); - - GxsMsgIdResult res; - rsPhotoV2->msgsChanged(res); - if(!res.empty()) - requestPhotoList(res); - } - - return; -} - - -/*************** New Photo Dialog ***************/ - -void PhotoDialog::OpenSlideShow() -{ - - // TODO. - if (!mAlbumSelected) - { - // ALERT. - int ret = QMessageBox::information(this, tr("PhotoShare"), - tr("Please select an album before\n" - "requesting to edit it!"), - QMessageBox::Ok); - return; - } - - std::string albumId = mAlbumSelected->getAlbum().mMeta.mGroupId; - - if (mSlideShow) - { - mSlideShow->show(); - } - else - { - mSlideShow = new PhotoSlideShow(NULL); - mSlideShow->show(); - } - mSlideShow->loadAlbum(albumId); - -} - - -/*************** New Photo Dialog ***************/ - -void PhotoDialog::createAlbum() -{ - AlbumCreateDialog albumCreate(mPhotoQueue, rsPhotoV2, this); - albumCreate.exec(); -} - -void PhotoDialog::OpenAlbumDialog() -{ - if(mAlbumSelected){ - - if(mAlbumDialog == NULL) - { - mAlbumDialog = new AlbumDialog(mAlbumSelected->getAlbum(), mPhotoQueue, rsPhotoV2); - connect(mAlbumDialog, SIGNAL(destroyed()), this, SLOT(SetDialogClosed())); - mAlbumDialog->show(); - }else{ - // bring dialog to front - mAlbumDialog->raise(); - } - } - return; -} - -void PhotoDialog::SetDialogClosed() -{ - mAlbumDialog = NULL; -} - -/*************** Edit Photo Dialog ***************/ - -void PhotoDialog::clearAlbums() -{ - std::cerr << "PhotoDialog::clearAlbums()" << std::endl; - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - - QSetIterator sit(mAlbumItems); - - while(sit.hasNext()) - { - AlbumItem* item = sit.next(); - alayout->removeWidget(item); - item->setParent(NULL); - } - - clearPhotos(); -} - -void PhotoDialog::clearPhotos() -{ - std::cerr << "PhotoDialog::clearPhotos()" << std::endl; - mPhotoSelected = NULL; - - QLayout *layout = ui.scrollAreaWidgetContents_2->layout(); - - if(mAlbumSelected) - { - const RsGxsGroupId& id = mAlbumSelected->getAlbum().mMeta.mGroupId; - - QSetIterator sit(mPhotoItems[id]); - - while(sit.hasNext()) - { - PhotoItem* item = sit.next(); - layout->removeWidget(item); - item->setParent(NULL); - } - } -} - -void PhotoDialog::updateAlbums() -{ - - clearAlbums(); - - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - QSetIterator sit(mAlbumItems); - - if(ui.pushButton_YourAlbums->isChecked()) - { - - ui.toolButton_subscribe->setEnabled(false); - ui.toolButton_NewAlbum->setEnabled(true); - ui.toolButton_SlideShow->setEnabled(true); - - while(sit.hasNext()){ - - AlbumItem* item = sit.next(); - uint32_t flags = item->getAlbum().mMeta.mSubscribeFlags; - - if(IS_ALBUM_ADMIN(flags)) - alayout->addWidget(item); - } - }else if(ui.pushButton_SubscribedAlbums->isChecked()) - { - - ui.toolButton_subscribe->setEnabled(false); - ui.toolButton_NewAlbum->setEnabled(false); - ui.toolButton_SlideShow->setEnabled(true); - - while(sit.hasNext()){ - - AlbumItem* item = sit.next(); - uint32_t flags = item->getAlbum().mMeta.mSubscribeFlags; - - if(IS_ALBUM_SUBSCRIBED(flags)) - alayout->addWidget(item); - } - - }else if(ui.pushButton_SharedAlbums->isChecked()) - { - - ui.toolButton_subscribe->setEnabled(true); - ui.toolButton_NewAlbum->setEnabled(false); - ui.toolButton_SlideShow->setEnabled(false); - - while(sit.hasNext()){ - - AlbumItem* item = sit.next(); - uint32_t flags = item->getAlbum().mMeta.mSubscribeFlags; - - if(flags == 0) - alayout->addWidget(item); - - } - } -} - -void PhotoDialog::addAlbum(const RsPhotoAlbum &album) -{ - std::cerr << " PhotoDialog::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; - - AlbumItem *item = new AlbumItem(album, this, this); - mAlbumItems.insert(item); - clearAlbums(); - updateAlbums(); -} - - -void PhotoDialog::addPhoto(const RsPhotoPhoto &photo) -{ - std::cerr << "PhotoDialog::addPhoto() AlbumId: " << photo.mMeta.mGroupId; - std::cerr << " PhotoId: " << photo.mMeta.mMsgId; - std::cerr << std::endl; - - PhotoItem* item = new PhotoItem(this, photo, this); - const RsGxsGroupId id = photo.mMeta.mGroupId; - - mPhotoItems[id].insert(item); -} - -void PhotoDialog::subscribeToAlbum() -{ - if(mAlbumSelected){ - RsGxsGroupId id = mAlbumSelected->getAlbum().mMeta.mGroupId; - uint32_t token; - rsPhotoV2->subscribeToAlbum(token, id); - mPhotoQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, 0); - } -} - -void PhotoDialog::updatePhotos() -{ - clearPhotos(); - - if(mAlbumSelected) - { - const RsGxsGroupId& grpId = mAlbumSelected->getAlbum().mMeta.mGroupId; - - QSetIterator sit(mPhotoItems[grpId]); - - while(sit.hasNext()) - { - QLayout *layout = ui.scrollAreaWidgetContents_2->layout(); - layout->addWidget(sit.next()); - } - } -} - -/**************************** Request / Response Filling of Data ************************/ - - -void PhotoDialog::requestAlbumList(std::list& ids) -{ - RsTokReqOptionsV2 opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; - uint32_t token; - mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, ids, 0); -} - -void PhotoDialog::requestPhotoList(GxsMsgReq& req) -{ - RsTokReqOptionsV2 opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; - uint32_t token; - mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, req, 0); - return; -} - - -void PhotoDialog::loadAlbumList(const uint32_t &token) -{ - std::cerr << "PhotoDialog::loadAlbumList()"; - std::cerr << std::endl; - - std::list albumIds; - rsPhotoV2->getGroupList(token, albumIds); - - requestAlbumData(albumIds); - - clearPhotos(); - - std::list::iterator it; - for(it = albumIds.begin(); it != albumIds.end(); it++) - { - requestPhotoList(*it); - } -} - - -void PhotoDialog::requestAlbumData(std::list &ids) -{ - RsTokReqOptionsV2 opts; - uint32_t token; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, 0); -} - -void PhotoDialog::requestAlbumData() -{ - RsTokReqOptionsV2 opts; - uint32_t token; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, 0); -} - -bool PhotoDialog::loadAlbumData(const uint32_t &token) -{ - std::cerr << "PhotoDialog::loadAlbumData()"; - std::cerr << std::endl; - - std::vector albums; - rsPhotoV2->getAlbum(token, albums); - - std::vector::iterator vit = albums.begin(); - - for(; vit != albums.end(); vit++) - { - RsPhotoAlbum& album = *vit; - - std::cerr << " PhotoDialog::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; - - addAlbum(album); - } - updateAlbums(); - return true; -} - - -void PhotoDialog::requestPhotoList(const std::string &albumId) -{ - - std::list grpIds; - grpIds.push_back(albumId); - RsTokReqOptionsV2 opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - uint32_t token; - mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, grpIds, 0); -} - - -void PhotoDialog::acknowledgeGroup(const uint32_t &token) -{ - RsGxsGroupId grpId; - rsPhotoV2->acknowledgeGrp(token, grpId); - - if(!grpId.empty()) - { - std::list grpIds; - grpIds.push_back(grpId); - - RsTokReqOptionsV2 opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - uint32_t reqToken; - mPhotoQueue->requestGroupInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); - } -} - -void PhotoDialog::acknowledgeMessage(const uint32_t &token) -{ - std::pair p; - rsPhotoV2->acknowledgeMsg(token, p); - - if(!p.first.empty()) - { - GxsMsgReq req; - std::vector v; - v.push_back(p.second); - req[p.first] = v; - RsTokReqOptionsV2 opts; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - uint32_t reqToken; - mPhotoQueue->requestMsgInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, req, 0); - } -} - -void PhotoDialog::loadPhotoList(const uint32_t &token) -{ - std::cerr << "PhotoDialog::loadPhotoList()"; - std::cerr << std::endl; - - GxsMsgIdResult res; - - rsPhotoV2->getMsgList(token, res); - requestPhotoData(res); -} - - -void PhotoDialog::requestPhotoData(GxsMsgReq &photoIds) -{ - RsTokReqOptionsV2 opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - uint32_t token; - mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, photoIds, 0); -} - - -void PhotoDialog::loadPhotoData(const uint32_t &token) -{ - std::cerr << "PhotoDialog::loadPhotoData()"; - std::cerr << std::endl; - - PhotoResult res; - rsPhotoV2->getPhoto(token, res); - PhotoResult::iterator mit = res.begin(); - - - for(; mit != res.end(); mit++) - { - std::vector& photoV = mit->second; - std::vector::iterator vit = photoV.begin(); - - for(; vit != photoV.end(); vit++) - { - RsPhotoPhoto& photo = *vit; - addPhoto(photo); - std::cerr << "PhotoDialog::loadPhotoData() AlbumId: " << photo.mMeta.mGroupId; - std::cerr << " PhotoId: " << photo.mMeta.mMsgId; - std::cerr << std::endl; - } - } - updatePhotos(); -} - - -/**************************** Request / Response Filling of Data ************************/ - -void PhotoDialog::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req) -{ - std::cerr << "PhotoDialog::loadRequest()"; - std::cerr << std::endl; - - if (queue == mPhotoQueue) - { - /* now switch on req */ - switch(req.mType) - { - case TOKENREQ_GROUPINFO: - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_LIST: - loadAlbumList(req.mToken); - break; - case RS_TOKREQ_ANSTYPE_DATA: - loadAlbumData(req.mToken); - break; - case RS_TOKREQ_ANSTYPE_ACK: - acknowledgeGroup(req.mToken); - break; - default: - std::cerr << "PhotoDialog::loadRequest() ERROR: GROUP: INVALID ANS TYPE"; - std::cerr << std::endl; - break; - } - break; - case TOKENREQ_MSGINFO: - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_LIST: - loadPhotoList(req.mToken); - break; - case RS_TOKREQ_ANSTYPE_ACK: - acknowledgeMessage(req.mToken); - break; - case RS_TOKREQ_ANSTYPE_DATA: - loadPhotoData(req.mToken); - break; - default: - std::cerr << "PhotoDialog::loadRequest() ERROR: MSG: INVALID ANS TYPE"; - std::cerr << std::endl; - break; - } - break; - case TOKENREQ_MSGRELATEDINFO: - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_DATA: - loadPhotoData(req.mToken); - break; - default: - std::cerr << "PhotoDialog::loadRequest() ERROR: MSG: INVALID ANS TYPE"; - std::cerr << std::endl; - break; - } - break; - default: - std::cerr << "PhotoDialog::loadRequest() ERROR: INVALID TYPE"; - std::cerr << std::endl; - break; - } - } -} - - -/**************************** Request / Response Filling of Data ************************/ - +#include "PhotoDialog.h" +#include "ui_PhotoDialog.h" + +PhotoDialog::PhotoDialog(RsPhotoV2 *rs_photo, const RsPhotoPhoto &photo, QWidget *parent) : + QDialog(parent), + ui(new Ui::PhotoDialog), mRsPhoto(rs_photo), mPhotoQueue(new TokenQueueV2(mRsPhoto->getTokenService(), this)), + mPhotoDetails(photo) + +{ + ui->setupUi(this); + setAttribute ( Qt::WA_DeleteOnClose, true ); + setUp(); +} + +PhotoDialog::~PhotoDialog() +{ + delete ui; + delete mPhotoQueue; +} + +void PhotoDialog::setUp() +{ + QPixmap qtn; + qtn.loadFromData(mPhotoDetails.mThumbnail.data, mPhotoDetails.mThumbnail.size, mPhotoDetails.mThumbnail.type.c_str()); + ui->label_Photo->setPixmap(qtn); + ui->lineEdit_Title->setText(QString::fromStdString(mPhotoDetails.mMeta.mMsgName)); +} + + +void PhotoDialog::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req) +{ + +} diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h index 41c2b7c17..4d3750ca9 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h @@ -1,113 +1,37 @@ -/* - * Retroshare Photo Plugin. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#ifndef MRK_PHOTO_DIALOG_H -#define MRK_PHOTO_DIALOG_H - -#include "retroshare-gui/mainpage.h" -#include "ui_PhotoDialog.h" -#include "AlbumCreateDialog.h" -#include "AlbumDialog.h" -#include "AlbumItem.h" -#include "PhotoItem.h" -#include "PhotoSlideShow.h" - -#include - -#include - -#include "util/TokenQueueV2.h" -#include "PhotoShareItemHolder.h" - - -class PhotoDialog : public MainPage, public TokenResponseV2, public PhotoShareItemHolder -{ - Q_OBJECT - -public: - PhotoDialog(QWidget *parent = 0); - - void notifySelection(PhotoShareItem* selection); - -private slots: - - void checkUpdate(); - void createAlbum(); - void OpenAlbumDialog(); - void OpenSlideShow(); - void SetDialogClosed(); - void updateAlbums(); - void subscribeToAlbum(); -private: - - /* Request Response Functions for loading data */ - void requestAlbumList(std::list& ids); - void requestAlbumData(std::list &ids); - - /*! - * request data for all groups - */ - void requestAlbumData(); - void requestPhotoList(GxsMsgReq &albumIds); - void requestPhotoList(const std::string &albumId); - void requestPhotoData(GxsMsgReq &photoIds); - - void loadAlbumList(const uint32_t &token); - bool loadAlbumData(const uint32_t &token); - void loadPhotoList(const uint32_t &token); - void loadPhotoData(const uint32_t &token); - - void loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req); - - void acknowledgeGroup(const uint32_t &token); - void acknowledgeMessage(const uint32_t &token); - - /* Grunt work of setting up the GUI */ - - void addAlbum(const RsPhotoAlbum &album); - void addPhoto(const RsPhotoPhoto &photo); - - void clearAlbums(); - void clearPhotos(); - void updatePhotos(); - -private: - - - AlbumItem* mAlbumSelected; - PhotoItem* mPhotoSelected; - PhotoSlideShow* mSlideShow; - AlbumDialog* mAlbumDialog; - - TokenQueueV2 *mPhotoQueue; - - /* UI - from Designer */ - Ui::PhotoDialog ui; - - QSet mAlbumItems; - QMap > mPhotoItems; - -}; - -#endif - +#ifndef PHOTODIALOG_H +#define PHOTODIALOG_H + +#include +#include "retroshare/rsphotoV2.h" +#include "util/TokenQueueV2.h" + +namespace Ui { + class PhotoDialog; +} + +class PhotoDialog : public QDialog, public TokenResponseV2 +{ + Q_OBJECT + +public: + explicit PhotoDialog(RsPhotoV2* rs_photo, const RsPhotoPhoto& photo, QWidget *parent = 0); + ~PhotoDialog(); + +private slots: + + void addComment(); + +public: + void loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req); +private: + void setUp(); +private: + Ui::PhotoDialog *ui; + + RsPhotoV2* mRsPhoto; + TokenQueueV2* mPhotoQueue; + RsPhotoPhoto mPhotoDetails; + +}; + +#endif // PHOTODIALOG_H diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui index c33d922b5..6b1ff2dba 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui @@ -1,195 +1,234 @@ PhotoDialog - + 0 0 - 774 - 608 + 516 + 449 - Photo Share + Dialog - + - + - - - false - - - - 6 - - - 0 - - - - - Your Albums - - - true - - - true - - - - - - - Subscribed Albums - - - true - - - true - - - - - - - Shared Albums - - - true - - - false - - - true - - - - - + + + + + + 0 + 1 + + + + Photo + + + + + + + 0 + 0 + + + + + 200 + 300 + + + + TextLabel + + + + + + + + + + + 0 + 0 + + + + + 50 + 200 + + + + Summary + + + + + + false + + + + 0 + 0 + + + + + + + + Caption + + + + + + + false + + + + 0 + 0 + + + + + + + + Where: + + + + + + + false + + + + 0 + 0 + + + + + + + + false + + + + 0 + 0 + + + + + + + + Photo Title: + + + + + + + When + + + + + + + - + - + + + Qt::Horizontal + + + + 40 + 20 + + + + + + - Slide Show + Add Comment - - - View Album / Add Photos + + + Qt::Horizontal - - - - - - Subscribe To Album + + + 40 + 20 + - - - - - - Create Album - - + - - - Qt::Vertical + + + true - - - true + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + 0 + 0 + 496 + 69 + - - Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + QWidget#scrollAreaWidgetContents{border: none;} - - - - 0 - 0 - 754 - 261 - - - - QWidget#scrollAreaWidgetContents{border: none;} - - - - - - - - - - - - - Qt::Horizontal - - - - 139 - 20 - - - - - - - - - - true - - - Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - - - - - 0 - 0 - 754 - 260 - - - - QWidget#scrollAreaWidgetContents{border: none;} - - - - - - Qt::Horizontal - - - - 426 - 20 - - - - - - + + + + + Qt::Vertical + + + + 20 + 40 + + + + + diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp index 7d8cdd717..d3cae9452 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp @@ -1,14 +1,716 @@ + +/* + * Retroshare Photo Plugin. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + #include "PhotoShare.h" #include "ui_PhotoShare.h" -PhotoShare::PhotoShare(QWidget *parent) : - QWidget(parent), - ui(new Ui::PhotoShare) +#include +#include +#include + +#include +#include + +#include +#include + +#include "AlbumCreateDialog.h" +#include "AlbumItem.h" +#include "PhotoItem.h" + +/****** + * #define PHOTO_DEBUG 1 + *****/ + + +/**************************************************************** + * New Photo Display Widget. + * + * This has two 'lists'. + * Top list shows Albums. + * Lower list is photos from the selected Album. + * + * Notes: + * Each Item will be an AlbumItem, which contains a thumbnail & random details. + * We will limit Items to < 100. With a 'Filter to see more message. + * + * Thumbnails will come from Service. + * Option to Share albums / pictures onward (if permissions allow). + * Option to Download the albums to a specified directory. (is this required if sharing an album?) + * + * Will introduce a FullScreen SlideShow later... first get basics happening. + */ + +#define IS_ALBUM_ADMIN(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) +#define IS_ALBUM_SUBSCRIBED(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) +#define IS_ALBUM_N_SUBSCR_OR_ADMIN(subscribeFlags) ((subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_MASK) == 0) + + +/** Constructor */ +PhotoShare::PhotoShare(QWidget *parent) +: MainPage(parent) { - ui->setupUi(this); + ui.setupUi(this); + + mAlbumSelected = NULL; + mPhotoSelected = NULL; + mSlideShow = NULL; + mAlbumDialog = NULL; + mPhotoDialog = NULL; + + connect( ui.toolButton_NewAlbum, SIGNAL(clicked()), this, SLOT(createAlbum())); + connect( ui.toolButton_ViewAlbum, SIGNAL(clicked()), this, SLOT(OpenAlbumDialog())); + connect( ui.toolButton_SlideShow, SIGNAL(clicked()), this, SLOT(OpenSlideShow())); + connect( ui.toolButton_subscribe, SIGNAL(clicked()), this, SLOT(subscribeToAlbum())); + connect(ui.toolButton_ViewPhoto, SIGNAL(clicked()), this, SLOT(OpenPhotoDialog())); + + connect( ui.pushButton_YourAlbums, SIGNAL(clicked()), this, SLOT(updateAlbums())); + connect( ui.pushButton_SharedAlbums, SIGNAL(clicked()), this, SLOT(updateAlbums())); + connect( ui.pushButton_SubscribedAlbums, SIGNAL(clicked()), this, SLOT(updateAlbums())); + + ui.pushButton_YourAlbums->setChecked(true); // default to your albums view + + QTimer *timer = new QTimer(this); + timer->connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate())); + timer->start(1000); + + + /* setup TokenQueue */ + mPhotoQueue = new TokenQueueV2(rsPhotoV2->getTokenService(), this); + requestAlbumData(); + updateAlbums(); } -PhotoShare::~PhotoShare() +void PhotoShare::notifySelection(PhotoShareItem *selection) { - delete ui; + + AlbumItem* aItem; + PhotoItem* pItem; + + if((aItem = dynamic_cast(selection)) != NULL) + { + + if(mPhotoSelected) + mPhotoSelected->setSelected(false); + + clearPhotos(); + + if(mAlbumSelected == aItem) + { + mAlbumSelected->setSelected(true); + } + else + { + if(mAlbumSelected == NULL) + { + mAlbumSelected = aItem; + } + else + { + mAlbumSelected->setSelected(false); + mAlbumSelected = aItem; + } + + mAlbumSelected->setSelected(true); + + } + + updatePhotos(); + } + else if((pItem = dynamic_cast(selection)) != NULL) + { + if(mPhotoSelected == pItem) + { + mPhotoSelected->setSelected(true); + } + else + { + if(mPhotoSelected == NULL) + { + mPhotoSelected = pItem; + } + else + { + mPhotoSelected->setSelected(false); + mPhotoSelected = pItem; + } + + mPhotoSelected->setSelected(true); + } + } + else + { + + } + } + + +void PhotoShare::checkUpdate() +{ + /* update */ + if (!rsPhotoV2) + return; + + if (rsPhotoV2->updated()) + { + //insertAlbums(); + std::list grpIds; + rsPhotoV2->groupsChanged(grpIds); + if(!grpIds.empty()) + requestAlbumList(grpIds); + + GxsMsgIdResult res; + rsPhotoV2->msgsChanged(res); + if(!res.empty()) + requestPhotoList(res); + } + + return; +} + + +/*************** New Photo Dialog ***************/ + +void PhotoShare::OpenSlideShow() +{ + + // TODO. + if (!mAlbumSelected) + { + // ALERT. + int ret = QMessageBox::information(this, tr("PhotoShare"), + tr("Please select an album before\n" + "requesting to edit it!"), + QMessageBox::Ok); + return; + } + + std::string albumId = mAlbumSelected->getAlbum().mMeta.mGroupId; + + if (mSlideShow) + { + mSlideShow->show(); + } + else + { + mSlideShow = new PhotoSlideShow(NULL); + mSlideShow->show(); + } + mSlideShow->loadAlbum(albumId); + +} + + +/*************** New Photo Dialog ***************/ + +void PhotoShare::createAlbum() +{ + AlbumCreateDialog albumCreate(mPhotoQueue, rsPhotoV2, this); + albumCreate.exec(); +} + +void PhotoShare::OpenAlbumDialog() +{ + if(mAlbumSelected){ + + if(mAlbumDialog == NULL) + { + mAlbumDialog = new AlbumDialog(mAlbumSelected->getAlbum(), mPhotoQueue, rsPhotoV2); + connect(mAlbumDialog, SIGNAL(destroyed()), this, SLOT(SetAlbumDialogClosed())); + mAlbumDialog->show(); + }else{ + // bring dialog to front + mAlbumDialog->raise(); + } + } + return; +} + +void PhotoShare::OpenPhotoDialog() +{ + if(mPhotoSelected) + { + if(mPhotoDialog == NULL) + { + mPhotoDialog = new PhotoDialog(rsPhotoV2, mPhotoSelected->getPhotoDetails()); + connect(mPhotoDialog, SIGNAL(destroyed()), this, SLOT(SetPhotoDialogClosed())); + mPhotoDialog->show(); + } + else + { + mPhotoDialog->raise(); + } + } +} + +void PhotoShare::SetAlbumDialogClosed() +{ + mAlbumDialog = NULL; +} + +void PhotoShare::SetPhotoDialogClosed() +{ + mPhotoDialog = NULL; +} + +/*************** Edit Photo Dialog ***************/ + +void PhotoShare::clearAlbums() +{ + std::cerr << "PhotoShare::clearAlbums()" << std::endl; + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); + + QSetIterator sit(mAlbumItems); + + while(sit.hasNext()) + { + AlbumItem* item = sit.next(); + alayout->removeWidget(item); + item->setParent(NULL); + } + + clearPhotos(); + + // set no albums to be selected + if(mAlbumSelected) + { + mAlbumSelected->setSelected(false); + mAlbumSelected = NULL; + } +} + +void PhotoShare::deleteAlbums() +{ + std::cerr << "PhotoShare::clearAlbums()" << std::endl; + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); + + QSetIterator sit(mAlbumItems); + + while(sit.hasNext()) + { + AlbumItem* item = sit.next(); + alayout->removeWidget(item); + delete item; + } + + mAlbumItems.clear(); + + mAlbumSelected = NULL; +} + + +void PhotoShare::clearPhotos() +{ + std::cerr << "PhotoShare::clearPhotos()" << std::endl; + mPhotoSelected = NULL; + + QLayout *layout = ui.scrollAreaWidgetContents_2->layout(); + + if(mAlbumSelected) + { + const RsGxsGroupId& id = mAlbumSelected->getAlbum().mMeta.mGroupId; + + QSetIterator sit(mPhotoItems[id]); + + while(sit.hasNext()) + { + PhotoItem* item = sit.next(); + layout->removeWidget(item); + item->setParent(NULL); + } + } +} + +void PhotoShare::updateAlbums() +{ + + clearAlbums(); + + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); + QSetIterator sit(mAlbumItems); + + if(ui.pushButton_YourAlbums->isChecked()) + { + + ui.toolButton_subscribe->setEnabled(false); + ui.toolButton_NewAlbum->setEnabled(true); + ui.toolButton_SlideShow->setEnabled(true); + + while(sit.hasNext()){ + + AlbumItem* item = sit.next(); + uint32_t flags = item->getAlbum().mMeta.mSubscribeFlags; + + if(IS_ALBUM_ADMIN(flags)) + alayout->addWidget(item); + } + }else if(ui.pushButton_SubscribedAlbums->isChecked()) + { + + ui.toolButton_subscribe->setEnabled(true); + ui.toolButton_subscribe->setText("Unsubscribe From Album"); + ui.toolButton_NewAlbum->setEnabled(false); + ui.toolButton_SlideShow->setEnabled(true); + + while(sit.hasNext()){ + + AlbumItem* item = sit.next(); + uint32_t flags = item->getAlbum().mMeta.mSubscribeFlags; + + if(IS_ALBUM_SUBSCRIBED(flags)) + alayout->addWidget(item); + } + + }else if(ui.pushButton_SharedAlbums->isChecked()) + { + + ui.toolButton_subscribe->setEnabled(true); + ui.toolButton_subscribe->setText("Subscribe To Album"); + ui.toolButton_NewAlbum->setEnabled(false); + ui.toolButton_SlideShow->setEnabled(false); + + while(sit.hasNext()){ + + AlbumItem* item = sit.next(); + uint32_t flags = item->getAlbum().mMeta.mSubscribeFlags; + + if(IS_ALBUM_N_SUBSCR_OR_ADMIN(flags)) + alayout->addWidget(item); + + } + } +} + +void PhotoShare::addAlbum(const RsPhotoAlbum &album) +{ + std::cerr << " PhotoShare::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; + + AlbumItem *item = new AlbumItem(album, this, this); + mAlbumItems.insert(item); +} + + +void PhotoShare::addPhoto(const RsPhotoPhoto &photo) +{ + std::cerr << "PhotoShare::addPhoto() AlbumId: " << photo.mMeta.mGroupId; + std::cerr << " PhotoId: " << photo.mMeta.mMsgId; + std::cerr << std::endl; + + PhotoItem* item = new PhotoItem(this, photo, this); + const RsGxsGroupId id = photo.mMeta.mGroupId; + + mPhotoItems[id].insert(item); +} + +void PhotoShare::subscribeToAlbum() +{ + if(mAlbumSelected){ + RsGxsGroupId id = mAlbumSelected->getAlbum().mMeta.mGroupId; + uint32_t token; + + if(IS_ALBUM_SUBSCRIBED(mAlbumSelected->getAlbum().mMeta.mSubscribeFlags)) + rsPhotoV2->subscribeToAlbum(token, id, false); + else if(IS_ALBUM_ADMIN(mAlbumSelected->getAlbum().mMeta.mSubscribeFlags)) + return; + else if(IS_ALBUM_N_SUBSCR_OR_ADMIN( + mAlbumSelected->getAlbum().mMeta.mSubscribeFlags)) + rsPhotoV2->subscribeToAlbum(token, id, true); + else + return; + + mPhotoQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, 0); + } +} + +void PhotoShare::updatePhotos() +{ + clearPhotos(); + + if(mAlbumSelected) + { + const RsGxsGroupId& grpId = mAlbumSelected->getAlbum().mMeta.mGroupId; + + QSetIterator sit(mPhotoItems[grpId]); + + while(sit.hasNext()) + { + QLayout *layout = ui.scrollAreaWidgetContents_2->layout(); + layout->addWidget(sit.next()); + } + } +} + +/**************************** Request / Response Filling of Data ************************/ + + +void PhotoShare::requestAlbumList(std::list& ids) +{ + RsTokReqOptionsV2 opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; + uint32_t token; + mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, ids, 0); +} + +void PhotoShare::requestPhotoList(GxsMsgReq& req) +{ + RsTokReqOptionsV2 opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; + uint32_t token; + mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, req, 0); + return; +} + + +void PhotoShare::loadAlbumList(const uint32_t &token) +{ + std::cerr << "PhotoShare::loadAlbumList()"; + std::cerr << std::endl; + + std::list albumIds; + rsPhotoV2->getGroupList(token, albumIds); + + requestAlbumData(albumIds); + + clearPhotos(); + + std::list::iterator it; + for(it = albumIds.begin(); it != albumIds.end(); it++) + { + requestPhotoList(*it); + } +} + + +void PhotoShare::requestAlbumData(std::list &ids) +{ + RsTokReqOptionsV2 opts; + uint32_t token; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, 0); +} + +void PhotoShare::requestAlbumData() +{ + RsTokReqOptionsV2 opts; + uint32_t token; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, 0); +} + +bool PhotoShare::loadAlbumData(const uint32_t &token) +{ + + deleteAlbums(); + + std::cerr << "PhotoShare::loadAlbumData()"; + std::cerr << std::endl; + + std::vector albums; + rsPhotoV2->getAlbum(token, albums); + + std::vector::iterator vit = albums.begin(); + + for(; vit != albums.end(); vit++) + { + RsPhotoAlbum& album = *vit; + + std::cerr << " PhotoShare::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; + + addAlbum(album); + } + updateAlbums(); + return true; +} + + +void PhotoShare::requestPhotoList(const std::string &albumId) +{ + + std::list grpIds; + grpIds.push_back(albumId); + RsTokReqOptionsV2 opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST; + uint32_t token; + mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, grpIds, 0); +} + + +void PhotoShare::acknowledgeGroup(const uint32_t &token) +{ + RsGxsGroupId grpId; + rsPhotoV2->acknowledgeGrp(token, grpId); + + if(!grpId.empty()) + { + std::list grpIds; + grpIds.push_back(grpId); + + RsTokReqOptionsV2 opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + uint32_t reqToken; + mPhotoQueue->requestGroupInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, 0); + } +} + +void PhotoShare::acknowledgeMessage(const uint32_t &token) +{ + std::pair p; + rsPhotoV2->acknowledgeMsg(token, p); + + if(!p.first.empty()) + { + GxsMsgReq req; + std::vector v; + v.push_back(p.second); + req[p.first] = v; + RsTokReqOptionsV2 opts; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + uint32_t reqToken; + mPhotoQueue->requestMsgInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, req, 0); + } +} + +void PhotoShare::loadPhotoList(const uint32_t &token) +{ + std::cerr << "PhotoShare::loadPhotoList()"; + std::cerr << std::endl; + + GxsMsgIdResult res; + + rsPhotoV2->getMsgList(token, res); + requestPhotoData(res); +} + + +void PhotoShare::requestPhotoData(GxsMsgReq &photoIds) +{ + RsTokReqOptionsV2 opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + uint32_t token; + mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, photoIds, 0); +} + + +void PhotoShare::loadPhotoData(const uint32_t &token) +{ + std::cerr << "PhotoShare::loadPhotoData()"; + std::cerr << std::endl; + + PhotoResult res; + rsPhotoV2->getPhoto(token, res); + PhotoResult::iterator mit = res.begin(); + + + for(; mit != res.end(); mit++) + { + std::vector& photoV = mit->second; + std::vector::iterator vit = photoV.begin(); + + for(; vit != photoV.end(); vit++) + { + RsPhotoPhoto& photo = *vit; + addPhoto(photo); + std::cerr << "PhotoShare::loadPhotoData() AlbumId: " << photo.mMeta.mGroupId; + std::cerr << " PhotoId: " << photo.mMeta.mMsgId; + std::cerr << std::endl; + } + } + updatePhotos(); +} + + +/**************************** Request / Response Filling of Data ************************/ + +void PhotoShare::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req) +{ + std::cerr << "PhotoShare::loadRequest()"; + std::cerr << std::endl; + + if (queue == mPhotoQueue) + { + /* now switch on req */ + switch(req.mType) + { + case TOKENREQ_GROUPINFO: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_LIST: + loadAlbumList(req.mToken); + break; + case RS_TOKREQ_ANSTYPE_DATA: + loadAlbumData(req.mToken); + break; + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgeGroup(req.mToken); + break; + default: + std::cerr << "PhotoShare::loadRequest() ERROR: GROUP: INVALID ANS TYPE"; + std::cerr << std::endl; + break; + } + break; + case TOKENREQ_MSGINFO: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_LIST: + loadPhotoList(req.mToken); + break; + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgeMessage(req.mToken); + break; + case RS_TOKREQ_ANSTYPE_DATA: + loadPhotoData(req.mToken); + break; + default: + std::cerr << "PhotoShare::loadRequest() ERROR: MSG: INVALID ANS TYPE"; + std::cerr << std::endl; + break; + } + break; + case TOKENREQ_MSGRELATEDINFO: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_DATA: + loadPhotoData(req.mToken); + break; + default: + std::cerr << "PhotoShare::loadRequest() ERROR: MSG: INVALID ANS TYPE"; + std::cerr << std::endl; + break; + } + break; + default: + std::cerr << "PhotoShare::loadRequest() ERROR: INVALID TYPE"; + std::cerr << std::endl; + break; + } + } +} + + +/**************************** Request / Response Filling of Data ************************/ + diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.h b/retroshare-gui/src/gui/PhotoShare/PhotoShare.h index b66eaf387..8d20d05f1 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.h @@ -2,21 +2,98 @@ #define PHOTOSHARE_H #include +#include +#include "ui_PhotoShare.h" + +#include "retroshare/rsphotoV2.h" +#include "retroshare-gui/mainpage.h" + +#include "AlbumCreateDialog.h" +#include "AlbumDialog.h" +#include "PhotoDialog.h" + +#include "AlbumItem.h" +#include "PhotoItem.h" +#include "PhotoSlideShow.h" + +#include "util/TokenQueueV2.h" +#include "PhotoShareItemHolder.h" namespace Ui { class PhotoShare; } -class PhotoShare : public QWidget +class PhotoShare : public MainPage, public TokenResponseV2, public PhotoShareItemHolder { - Q_OBJECT + Q_OBJECT public: - explicit PhotoShare(QWidget *parent = 0); - ~PhotoShare(); + PhotoShare(QWidget *parent = 0); + + void notifySelection(PhotoShareItem* selection); + +private slots: + + void checkUpdate(); + void createAlbum(); + void OpenAlbumDialog(); + void OpenPhotoDialog(); + void OpenSlideShow(); + void SetAlbumDialogClosed(); + void SetPhotoDialogClosed(); + void updateAlbums(); + void subscribeToAlbum(); +private: + + /* Request Response Functions for loading data */ + void requestAlbumList(std::list& ids); + void requestAlbumData(std::list &ids); + + /*! + * request data for all groups + */ + void requestAlbumData(); + void requestPhotoList(GxsMsgReq &albumIds); + void requestPhotoList(const std::string &albumId); + void requestPhotoData(GxsMsgReq &photoIds); + + void loadAlbumList(const uint32_t &token); + bool loadAlbumData(const uint32_t &token); + void loadPhotoList(const uint32_t &token); + void loadPhotoData(const uint32_t &token); + + void loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req); + + void acknowledgeGroup(const uint32_t &token); + void acknowledgeMessage(const uint32_t &token); + + /* Grunt work of setting up the GUI */ + + void addAlbum(const RsPhotoAlbum &album); + void addPhoto(const RsPhotoPhoto &photo); + + void clearAlbums(); + void clearPhotos(); + void deleteAlbums(); + void updatePhotos(); private: - Ui::PhotoShare *ui; + + + AlbumItem* mAlbumSelected; + PhotoItem* mPhotoSelected; + PhotoSlideShow* mSlideShow; + AlbumDialog* mAlbumDialog; + PhotoDialog* mPhotoDialog; + + TokenQueueV2 *mPhotoQueue; + + /* UI - from Designer */ + Ui::PhotoShare ui; + + QSet mAlbumItems; + QMap > mPhotoItems; + }; #endif // PHOTOSHARE_H diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui index b245267cb..73592cef6 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui @@ -1,21 +1,211 @@ + - - - PhotoShare 0 0 - 400 - 300 + 824 + 569 Form + + + + + + + false + + + + 6 + + + 0 + + + + + Your Albums + + + true + + + true + + + + + + + Subscribed Albums + + + true + + + true + + + + + + + Shared Albums + + + true + + + false + + + true + + + + + + + + + + + + + + Slide Show + + + + + + + View Album / Add Photos + + + + + + + Subscribe To Album + + + + + + + Create Album + + + + + + + + + Qt::Vertical + + + + true + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + 0 + 0 + 804 + 228 + + + + QWidget#scrollAreaWidgetContents{border: none;} + + + + + + + + + + + + + Qt::Horizontal + + + + 139 + 20 + + + + + + + + + + true + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + 0 + 0 + 804 + 227 + + + + QWidget#scrollAreaWidgetContents{border: none;} + + + + + + Qt::Horizontal + + + + 426 + 20 + + + + + + + + + + + + + + + View Photo + + + + + + - + diff --git a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp index 8672b2103..dd1cc2c60 100644 --- a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp +++ b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp @@ -32,7 +32,7 @@ #include -#include "gui/PhotoShare/PhotoDialog.h" +#include "gui/PhotoShare/PhotoShare.h" // THESE HAVE TO BE CONVERTED TO VEG FORMAT #if USE_VEG_SERVICE @@ -104,9 +104,9 @@ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) createPageAction(QIcon(IMAGE_LIBRARY), tr("Identities"), grp)); #endif - PhotoDialog *photoDialog = NULL; - ui.stackPages->add(photoDialog = new PhotoDialog(ui.stackPages), - createPageAction(QIcon(IMAGE_PHOTO), tr("Photo View"), grp)); + PhotoShare *photoShare = NULL; + ui.stackPages->add(photoShare = new PhotoShare(ui.stackPages), + createPageAction(QIcon(IMAGE_PHOTO), tr("Photo Share"), grp)); // THESE HAVE TO BE CONVERTED TO VEG FORMAT #if USE_VEG_SERVICE diff --git a/retroshare-gui/src/util/TokenQueueV2.cpp b/retroshare-gui/src/util/TokenQueueV2.cpp index e43e7da7a..10c45c86d 100644 --- a/retroshare-gui/src/util/TokenQueueV2.cpp +++ b/retroshare-gui/src/util/TokenQueueV2.cpp @@ -66,6 +66,16 @@ bool TokenQueueV2::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTok return true; } +bool TokenQueueV2::requestMsgRelatedInfo(uint32_t &token, const RsTokReqOptionsV2 &opts, const std::list &grpIds, uint32_t usertype) +{ + uint32_t basictype = TOKENREQ_MSGINFO; + uint32_t anstype = RS_TOKREQ_ANSTYPE_LIST; // always a list answer + mService->requestMsgRelatedInfo(token, anstype, opts, ids); + queueRequest(token, basictype, anstype, usertype); + + return true; +} + bool TokenQueueV2::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, const std::list &grpIds, uint32_t usertype) @@ -143,7 +153,9 @@ void TokenQueueV2::pollRequests() bool TokenQueueV2::checkForRequest(uint32_t token) { /* check token */ - return (RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE == mService->requestStatus(token)); + uint32_t status = mService->requestStatus(token); + return ( (RsTokenServiceV2::GXS_REQUEST_STATUS_FAILED == status) || + (RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE == status) ); } diff --git a/retroshare-gui/src/util/TokenQueueV2.h b/retroshare-gui/src/util/TokenQueueV2.h index 0f19863dc..2f37a10b9 100644 --- a/retroshare-gui/src/util/TokenQueueV2.h +++ b/retroshare-gui/src/util/TokenQueueV2.h @@ -93,6 +93,7 @@ public: bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, const GxsMsgReq& grpIds, uint32_t usertype); + bool requestMsgRelatedInfo(uint32_t &token, const RsTokReqOptionsV2 &opts, const std::list& grpIds, uint32_t usertype); bool cancelRequest(const uint32_t token); diff --git a/retroshare-nogui/src/menu/menus.cc b/retroshare-nogui/src/menu/menus.cc index 46e044aa6..fc3b95105 100644 --- a/retroshare-nogui/src/menu/menus.cc +++ b/retroshare-nogui/src/menu/menus.cc @@ -84,7 +84,7 @@ Menu *CreateMenuStructure(NotifyTxt *notify) MenuList *search = new MenuListSearch(notify); MenuList *searchlist = new MenuListSearchList(notify); - search->addMenuItem(MENU_SEARCH_KEY_ADD, new MenuOpSearchNew(notify)); + search->addMenuItem(MENU_SEARCH_KEY_ADD, new MenuOpSearchNew()); //search->addMenuItem(MENU_SEARCH_KEY_REMOVE, new MenuOpSearchDelete()); search->addMenuItem(MENU_SEARCH_KEY_VIEW, searchlist); searchlist->addMenuItem(MENU_SEARCH_KEY_DOWNLOAD, new MenuOpSearchListDownload()); @@ -362,17 +362,11 @@ int MenuListSearch::removeSearch(std::string strSearchId) it = mSearchIds.find(strSearchId); if (it != mSearchIds.end()) { + /* cleanup local maps */ /* cancel search */ - // CAN'T DO!!! /* clear results from Notify Collector */ - mNotify->clearSearchId(it->second); - - /* cleanup local maps */ - mSearchIds.erase(it); - - /* cleanup terms maps (TODO) */ } return 1; @@ -398,7 +392,6 @@ uint32_t MenuOpSearchNew::process_lines(std::string input) std::string search = input.substr(0, input.size() - 1); // remove \n. uint32_t searchId = (uint32_t) rsTurtle->turtleSearch(search); - mNotify->collectSearchResults(searchId); /* store request in parent */ MenuListSearch *ms = dynamic_cast(parent()); @@ -652,7 +645,7 @@ int MenuListShared::getEntryDesc(int idx, std::string &desc) rsFiles->getSharedDirectories(dirs); std::list::iterator it; std::string shareflag; - int i=0; + unsigned int i=0; for (it = dirs.begin(); (i < idx) && (it != dirs.end()); it++, i++); if (it != dirs.end()) { @@ -682,7 +675,7 @@ int MenuListShared::unshareSelected() std::list dirs; rsFiles->getSharedDirectories(dirs); std::list::iterator it; - int i=0; + unsigned int i=0; for (it = dirs.begin(); (i < mSelectIdx) && (it != dirs.end()); it++, i++); if (it != dirs.end()) { @@ -703,7 +696,7 @@ int MenuListShared::toggleFlagSelected(uint32_t shareflags) std::list dirs; rsFiles->getSharedDirectories(dirs); std::list::iterator it; - int i=0; + unsigned int i=0; for (it = dirs.begin(); (i < mSelectIdx) && (it != dirs.end()); it++, i++); if (it != dirs.end()) { diff --git a/retroshare-nogui/src/notifytxt.cc b/retroshare-nogui/src/notifytxt.cc index 9995d3ba3..9bc01d1a4 100644 --- a/retroshare-nogui/src/notifytxt.cc +++ b/retroshare-nogui/src/notifytxt.cc @@ -230,15 +230,8 @@ void NotifyTxt::notifyTurtleSearchResult(uint32_t search_id,const std::listsecond.size(); } - // only collect results for selected searches. - // will drop others. -int NotifyTxt::collectSearchResults(uint32_t searchId) -{ - std::cerr << "NotifyTxt::collectSearchResult(" << searchId << ")"; - std::cerr << std::endl; - - RsStackMutex stack(mNotifyMtx); /****** LOCKED *****/ - - std::map >::iterator it; - it = mSearchResults.find(searchId); - if (it == mSearchResults.end()) - { - std::list emptyList; - mSearchResults[searchId] = emptyList; - return 1; - } - - std::cerr << "NotifyTxt::collectSearchResult() ERROR Id exists"; - std::cerr << std::endl; - return 1; -} int NotifyTxt::clearSearchId(uint32_t searchId) { - std::cerr << "NotifyTxt::clearSearchId(" << searchId << ")"; - std::cerr << std::endl; - RsStackMutex stack(mNotifyMtx); /****** LOCKED *****/ std::map >::iterator it; it = mSearchResults.find(searchId); if (it == mSearchResults.end()) { - std::cerr << "NotifyTxt::clearSearchId() ERROR Id not there"; - std::cerr << std::endl; return 0; } diff --git a/retroshare-nogui/src/retroshare.cc b/retroshare-nogui/src/retroshare.cc index d1b6a5abd..36fd0172e 100644 --- a/retroshare-nogui/src/retroshare.cc +++ b/retroshare-nogui/src/retroshare.cc @@ -388,7 +388,7 @@ int main(int argc, char **argv) if (enableRpc) { /* Build RPC Server */ - RpcMediator *med = CreateRpcSystem(ssh, notify); + RpcMediator *med = CreateRpcSystem(ssh); ssh->setRpcSystem(med); ssh->setSleepPeriods(0.01, 0.1); } diff --git a/retroshare-nogui/src/rpc/proto/gencc/core.pb.cc b/retroshare-nogui/src/rpc/proto/gencc/core.pb.cc index cb1061f88..e95575c67 100644 --- a/retroshare-nogui/src/rpc/proto/gencc/core.pb.cc +++ b/retroshare-nogui/src/rpc/proto/gencc/core.pb.cc @@ -134,10 +134,12 @@ void protobuf_AssignDesc_core_2eproto() { sizeof(Person)); Person_Relationship_descriptor_ = Person_descriptor_->enum_type(0); File_descriptor_ = file->message_type(4); - static const int File_offsets_[3] = { + static const int File_offsets_[5] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, hash_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, size_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, avail_), }; File_reflection_ = new ::google::protobuf::internal::GeneratedMessageReflection( @@ -281,39 +283,39 @@ void protobuf_AddDesc_core_2eproto() { GOOGLE_PROTOBUF_VERIFY_VERSION; ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( - "\n\ncore.proto\022\013rsctrl.core\"\260\001\n\006Status\022,\n\004" + "\n\ncore.proto\022\013rsctrl.core\"\233\001\n\006Status\022,\n\004" "code\030\001 \002(\0162\036.rsctrl.core.Status.StatusCo" - "de\022\013\n\003msg\030\002 \001(\t\"k\n\nStatusCode\022\n\n\006FAILED\020" - "\000\022\017\n\013NO_IMPL_YET\020\001\022\021\n\rINVALID_QUERY\020\002\022\023\n" - "\017PARTIAL_SUCCESS\020\003\022\013\n\007SUCCESS\020\004\022\013\n\007READM" - "SG\020\005\")\n\006IpAddr\022\016\n\004addr\030\001 \002(\t:\000\022\017\n\004port\030\002" - " \002(\r:\0010\"\303\001\n\010Location\022\016\n\006ssl_id\030\001 \002(\t\022\020\n\010" - "location\030\002 \002(\t\022&\n\tlocaladdr\030\003 \002(\0132\023.rsct" - "rl.core.IpAddr\022$\n\007extaddr\030\004 \002(\0132\023.rsctrl" - ".core.IpAddr\022\r\n\005state\030\005 \002(\r\"8\n\nStateFlag" - "s\022\n\n\006ONLINE\020\001\022\r\n\tCONNECTED\020\002\022\017\n\013UNREACHA" - "BLE\020\004\"\340\001\n\006Person\022\016\n\006gpg_id\030\001 \002(\t\022\014\n\004name" - "\030\002 \002(\t\0222\n\010relation\030\003 \002(\0162 .rsctrl.core.P" - "erson.Relationship\022(\n\tlocations\030\004 \003(\0132\025." - "rsctrl.core.Location\"Z\n\014Relationship\022\n\n\006" - "FRIEND\020\001\022\032\n\026FRIEND_OF_MANY_FRIENDS\020\002\022\025\n\021" - "FRIEND_OF_FRIENDS\020\003\022\013\n\007UNKNOWN\020\004\"0\n\004File" - "\022\014\n\004name\030\001 \002(\t\022\014\n\004hash\030\002 \002(\t\022\014\n\004size\030\003 \002" - "(\004\"f\n\003Dir\022\014\n\004name\030\001 \002(\t\022\014\n\004path\030\002 \002(\t\022!\n" - "\007subdirs\030\003 \003(\0132\020.rsctrl.core.Dir\022 \n\005file" - "s\030\004 \003(\0132\021.rsctrl.core.File\"\372\001\n\014SystemSta" - "tus\0225\n\nnet_status\030\001 \002(\0162!.rsctrl.core.Sy" - "stemStatus.NetCode\022\013\n\003msg\030\002 \001(\t\"\245\001\n\007NetC" - "ode\022\017\n\013BAD_UNKNOWN\020\000\022\017\n\013BAD_OFFLINE\020\001\022\016\n" - "\nBAD_NATSYM\020\002\022\021\n\rBAD_NODHT_NAT\020\003\022\023\n\017WARN" - "ING_RESTART\020\004\022\022\n\016WARNING_NATTED\020\005\022\021\n\rWAR" - "NING_NODHT\020\006\022\010\n\004GOOD\020\007\022\017\n\013ADV_FORWARD\020\010\"" - "3\n\tBandwidth\022\n\n\002up\030\001 \002(\002\022\014\n\004down\030\002 \002(\002\022\014" - "\n\004name\030\003 \001(\t\":\n\014BandwidthSet\022*\n\nbandwidt" - "hs\030\001 \003(\0132\026.rsctrl.core.Bandwidth*\027\n\013Exte" - "nsionId\022\010\n\004CORE\020\000*M\n\tPackageId\022\t\n\005PEERS\020" - "\001\022\n\n\006SYSTEM\020\002\022\010\n\004CHAT\020\003\022\n\n\006SEARCH\020\004\022\t\n\005F" - "ILES\020\005\022\010\n\003GXS\020\350\007", 1296); + "de\022\013\n\003msg\030\002 \001(\t\"V\n\nStatusCode\022\n\n\006FAILED\020" + "\000\022\017\n\013NO_IMPL_YET\020\001\022\021\n\rINVALID_QUERY\020\002\022\013\n" + "\007SUCCESS\020\003\022\013\n\007READMSG\020\004\")\n\006IpAddr\022\016\n\004add" + "r\030\001 \002(\t:\000\022\017\n\004port\030\002 \002(\r:\0010\"\303\001\n\010Location\022" + "\016\n\006ssl_id\030\001 \002(\t\022\020\n\010location\030\002 \002(\t\022&\n\tloc" + "aladdr\030\003 \002(\0132\023.rsctrl.core.IpAddr\022$\n\007ext" + "addr\030\004 \002(\0132\023.rsctrl.core.IpAddr\022\r\n\005state" + "\030\005 \002(\r\"8\n\nStateFlags\022\n\n\006ONLINE\020\001\022\r\n\tCONN" + "ECTED\020\002\022\017\n\013UNREACHABLE\020\004\"\340\001\n\006Person\022\016\n\006g" + "pg_id\030\001 \002(\t\022\014\n\004name\030\002 \002(\t\0222\n\010relation\030\003 " + "\002(\0162 .rsctrl.core.Person.Relationship\022(\n" + "\tlocations\030\004 \003(\0132\025.rsctrl.core.Location\"" + "Z\n\014Relationship\022\n\n\006FRIEND\020\001\022\032\n\026FRIEND_OF" + "_MANY_FRIENDS\020\002\022\025\n\021FRIEND_OF_FRIENDS\020\003\022\013" + "\n\007UNKNOWN\020\004\"M\n\004File\022\014\n\004name\030\001 \002(\t\022\014\n\004has" + "h\030\002 \002(\t\022\014\n\004size\030\003 \002(\003\022\014\n\004path\030\004 \001(\t\022\r\n\005a" + "vail\030\005 \001(\t\"f\n\003Dir\022\014\n\004name\030\001 \002(\t\022\014\n\004path\030" + "\002 \002(\t\022!\n\007subdirs\030\003 \003(\0132\020.rsctrl.core.Dir" + "\022 \n\005files\030\004 \003(\0132\021.rsctrl.core.File\"\372\001\n\014S" + "ystemStatus\0225\n\nnet_status\030\001 \002(\0162!.rsctrl" + ".core.SystemStatus.NetCode\022\013\n\003msg\030\002 \001(\t\"" + "\245\001\n\007NetCode\022\017\n\013BAD_UNKNOWN\020\000\022\017\n\013BAD_OFFL" + "INE\020\001\022\016\n\nBAD_NATSYM\020\002\022\021\n\rBAD_NODHT_NAT\020\003" + "\022\023\n\017WARNING_RESTART\020\004\022\022\n\016WARNING_NATTED\020" + "\005\022\021\n\rWARNING_NODHT\020\006\022\010\n\004GOOD\020\007\022\017\n\013ADV_FO" + "RWARD\020\010\"3\n\tBandwidth\022\n\n\002up\030\001 \002(\002\022\014\n\004down" + "\030\002 \002(\002\022\014\n\004name\030\003 \001(\t\":\n\014BandwidthSet\022*\n\n" + "bandwidths\030\001 \003(\0132\026.rsctrl.core.Bandwidth" + "*\027\n\013ExtensionId\022\010\n\004CORE\020\000*6\n\tPackageId\022\t" + "\n\005PEERS\020\001\022\n\n\006SYSTEM\020\002\022\010\n\004CHAT\020\003\022\010\n\003GXS\020\350" + "\007", 1281); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "core.proto", &protobuf_RegisterTypes); Status::default_instance_ = new Status(); @@ -366,8 +368,6 @@ bool PackageId_IsValid(int value) { case 1: case 2: case 3: - case 4: - case 5: case 1000: return true; default: @@ -389,7 +389,6 @@ bool Status_StatusCode_IsValid(int value) { case 2: case 3: case 4: - case 5: return true; default: return false; @@ -400,7 +399,6 @@ bool Status_StatusCode_IsValid(int value) { const Status_StatusCode Status::FAILED; const Status_StatusCode Status::NO_IMPL_YET; const Status_StatusCode Status::INVALID_QUERY; -const Status_StatusCode Status::PARTIAL_SUCCESS; const Status_StatusCode Status::SUCCESS; const Status_StatusCode Status::READMSG; const Status_StatusCode Status::StatusCode_MIN; @@ -1784,6 +1782,8 @@ void Person::Swap(Person* other) { const int File::kNameFieldNumber; const int File::kHashFieldNumber; const int File::kSizeFieldNumber; +const int File::kPathFieldNumber; +const int File::kAvailFieldNumber; #endif // !_MSC_VER File::File() @@ -1804,7 +1804,9 @@ void File::SharedCtor() { _cached_size_ = 0; name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); hash_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); - size_ = GOOGLE_ULONGLONG(0); + size_ = GOOGLE_LONGLONG(0); + path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + avail_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -1819,6 +1821,12 @@ void File::SharedDtor() { if (hash_ != &::google::protobuf::internal::kEmptyString) { delete hash_; } + if (path_ != &::google::protobuf::internal::kEmptyString) { + delete path_; + } + if (avail_ != &::google::protobuf::internal::kEmptyString) { + delete avail_; + } if (this != default_instance_) { } } @@ -1855,7 +1863,17 @@ void File::Clear() { hash_->clear(); } } - size_ = GOOGLE_ULONGLONG(0); + size_ = GOOGLE_LONGLONG(0); + if (has_path()) { + if (path_ != &::google::protobuf::internal::kEmptyString) { + path_->clear(); + } + } + if (has_avail()) { + if (avail_ != &::google::protobuf::internal::kEmptyString) { + avail_->clear(); + } + } } ::memset(_has_bits_, 0, sizeof(_has_bits_)); mutable_unknown_fields()->Clear(); @@ -1900,18 +1918,52 @@ bool File::MergePartialFromCodedStream( break; } - // required uint64 size = 3; + // required int64 size = 3; case 3: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { parse_size: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( input, &size_))); set_has_size(); } else { goto handle_uninterpreted; } + if (input->ExpectTag(34)) goto parse_path; + break; + } + + // optional string path = 4; + case 4: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_path: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_path())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(42)) goto parse_avail; + break; + } + + // optional string avail = 5; + case 5: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_avail: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_avail())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->avail().data(), this->avail().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } if (input->ExpectAtEnd()) return true; break; } @@ -1952,9 +2004,27 @@ void File::SerializeWithCachedSizes( 2, this->hash(), output); } - // required uint64 size = 3; + // required int64 size = 3; if (has_size()) { - ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->size(), output); + ::google::protobuf::internal::WireFormatLite::WriteInt64(3, this->size(), output); + } + + // optional string path = 4; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 4, this->path(), output); + } + + // optional string avail = 5; + if (has_avail()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->avail().data(), this->avail().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 5, this->avail(), output); } if (!unknown_fields().empty()) { @@ -1985,9 +2055,29 @@ void File::SerializeWithCachedSizes( 2, this->hash(), target); } - // required uint64 size = 3; + // required int64 size = 3; if (has_size()) { - target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->size(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(3, this->size(), target); + } + + // optional string path = 4; + if (has_path()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->path().data(), this->path().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 4, this->path(), target); + } + + // optional string avail = 5; + if (has_avail()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->avail().data(), this->avail().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 5, this->avail(), target); } if (!unknown_fields().empty()) { @@ -2015,13 +2105,27 @@ int File::ByteSize() const { this->hash()); } - // required uint64 size = 3; + // required int64 size = 3; if (has_size()) { total_size += 1 + - ::google::protobuf::internal::WireFormatLite::UInt64Size( + ::google::protobuf::internal::WireFormatLite::Int64Size( this->size()); } + // optional string path = 4; + if (has_path()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->path()); + } + + // optional string avail = 5; + if (has_avail()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->avail()); + } + } if (!unknown_fields().empty()) { total_size += @@ -2058,6 +2162,12 @@ void File::MergeFrom(const File& from) { if (from.has_size()) { set_size(from.size()); } + if (from.has_path()) { + set_path(from.path()); + } + if (from.has_avail()) { + set_avail(from.avail()); + } } mutable_unknown_fields()->MergeFrom(from.unknown_fields()); } @@ -2085,6 +2195,8 @@ void File::Swap(File* other) { std::swap(name_, other->name_); std::swap(hash_, other->hash_); std::swap(size_, other->size_); + std::swap(path_, other->path_); + std::swap(avail_, other->avail_); std::swap(_has_bits_[0], other->_has_bits_[0]); _unknown_fields_.Swap(&other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); diff --git a/retroshare-nogui/src/rpc/proto/gencc/system.pb.cc b/retroshare-nogui/src/rpc/proto/gencc/system.pb.cc index 915d6affd..ca729ce8f 100644 --- a/retroshare-nogui/src/rpc/proto/gencc/system.pb.cc +++ b/retroshare-nogui/src/rpc/proto/gencc/system.pb.cc @@ -25,13 +25,6 @@ const ::google::protobuf::Descriptor* ResponseSystemStatus_descriptor_ = NULL; const ::google::protobuf::internal::GeneratedMessageReflection* ResponseSystemStatus_reflection_ = NULL; const ::google::protobuf::EnumDescriptor* ResponseSystemStatus_NetCode_descriptor_ = NULL; -const ::google::protobuf::Descriptor* RequestSystemQuit_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - RequestSystemQuit_reflection_ = NULL; -const ::google::protobuf::EnumDescriptor* RequestSystemQuit_QuitCode_descriptor_ = NULL; -const ::google::protobuf::Descriptor* ResponseSystemQuit_descriptor_ = NULL; -const ::google::protobuf::internal::GeneratedMessageReflection* - ResponseSystemQuit_reflection_ = NULL; const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor_ = NULL; const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor_ = NULL; @@ -78,37 +71,6 @@ void protobuf_AssignDesc_system_2eproto() { ::google::protobuf::MessageFactory::generated_factory(), sizeof(ResponseSystemStatus)); ResponseSystemStatus_NetCode_descriptor_ = ResponseSystemStatus_descriptor_->enum_type(0); - RequestSystemQuit_descriptor_ = file->message_type(2); - static const int RequestSystemQuit_offsets_[1] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestSystemQuit, quit_code_), - }; - RequestSystemQuit_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - RequestSystemQuit_descriptor_, - RequestSystemQuit::default_instance_, - RequestSystemQuit_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestSystemQuit, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestSystemQuit, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(RequestSystemQuit)); - RequestSystemQuit_QuitCode_descriptor_ = RequestSystemQuit_descriptor_->enum_type(0); - ResponseSystemQuit_descriptor_ = file->message_type(3); - static const int ResponseSystemQuit_offsets_[1] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSystemQuit, status_), - }; - ResponseSystemQuit_reflection_ = - new ::google::protobuf::internal::GeneratedMessageReflection( - ResponseSystemQuit_descriptor_, - ResponseSystemQuit::default_instance_, - ResponseSystemQuit_offsets_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSystemQuit, _has_bits_[0]), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSystemQuit, _unknown_fields_), - -1, - ::google::protobuf::DescriptorPool::generated_pool(), - ::google::protobuf::MessageFactory::generated_factory(), - sizeof(ResponseSystemQuit)); RequestMsgIds_descriptor_ = file->enum_type(0); ResponseMsgIds_descriptor_ = file->enum_type(1); } @@ -127,10 +89,6 @@ void protobuf_RegisterTypes(const ::std::string&) { RequestSystemStatus_descriptor_, &RequestSystemStatus::default_instance()); ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( ResponseSystemStatus_descriptor_, &ResponseSystemStatus::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - RequestSystemQuit_descriptor_, &RequestSystemQuit::default_instance()); - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - ResponseSystemQuit_descriptor_, &ResponseSystemQuit::default_instance()); } } // namespace @@ -140,10 +98,6 @@ void protobuf_ShutdownFile_system_2eproto() { delete RequestSystemStatus_reflection_; delete ResponseSystemStatus::default_instance_; delete ResponseSystemStatus_reflection_; - delete RequestSystemQuit::default_instance_; - delete RequestSystemQuit_reflection_; - delete ResponseSystemQuit::default_instance_; - delete ResponseSystemQuit_reflection_; } void protobuf_AddDesc_system_2eproto() { @@ -165,25 +119,15 @@ void protobuf_AddDesc_system_2eproto() { "\016\n\nBAD_NATSYM\020\002\022\021\n\rBAD_NODHT_NAT\020\003\022\023\n\017WA" "RNING_RESTART\020\004\022\022\n\016WARNING_NATTED\020\005\022\021\n\rW" "ARNING_NODHT\020\006\022\010\n\004GOOD\020\007\022\017\n\013ADV_FORWARD\020" - "\010\"\201\001\n\021RequestSystemQuit\022<\n\tquit_code\030\001 \002" - "(\0162).rsctrl.system.RequestSystemQuit.Qui" - "tCode\".\n\010QuitCode\022\021\n\rCLOSE_CHANNEL\020\001\022\017\n\013" - "SHUTDOWN_RS\020\002\"9\n\022ResponseSystemQuit\022#\n\006s" - "tatus\030\001 \002(\0132\023.rsctrl.core.Status*K\n\rRequ" - "estMsgIds\022\035\n\031MsgId_RequestSystemStatus\020\001" - "\022\033\n\027MsgId_RequestSystemQuit\020\002*N\n\016Respons" - "eMsgIds\022\036\n\032MsgId_ResponseSystemStatus\020\001\022" - "\034\n\030MsgId_ResponseSystemQuit\020\002", 789); + "\010*.\n\rRequestMsgIds\022\035\n\031MsgId_RequestSyste" + "mStatus\020\001*0\n\016ResponseMsgIds\022\036\n\032MsgId_Res" + "ponseSystemStatus\020\001", 539); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "system.proto", &protobuf_RegisterTypes); RequestSystemStatus::default_instance_ = new RequestSystemStatus(); ResponseSystemStatus::default_instance_ = new ResponseSystemStatus(); - RequestSystemQuit::default_instance_ = new RequestSystemQuit(); - ResponseSystemQuit::default_instance_ = new ResponseSystemQuit(); RequestSystemStatus::default_instance_->InitAsDefaultInstance(); ResponseSystemStatus::default_instance_->InitAsDefaultInstance(); - RequestSystemQuit::default_instance_->InitAsDefaultInstance(); - ResponseSystemQuit::default_instance_->InitAsDefaultInstance(); ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_system_2eproto); } @@ -201,7 +145,6 @@ const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor() { bool RequestMsgIds_IsValid(int value) { switch(value) { case 1: - case 2: return true; default: return false; @@ -215,7 +158,6 @@ const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor() { bool ResponseMsgIds_IsValid(int value) { switch(value) { case 1: - case 2: return true; default: return false; @@ -803,457 +745,6 @@ void ResponseSystemStatus::Swap(ResponseSystemStatus* other) { } -// =================================================================== - -const ::google::protobuf::EnumDescriptor* RequestSystemQuit_QuitCode_descriptor() { - protobuf_AssignDescriptorsOnce(); - return RequestSystemQuit_QuitCode_descriptor_; -} -bool RequestSystemQuit_QuitCode_IsValid(int value) { - switch(value) { - case 1: - case 2: - return true; - default: - return false; - } -} - -#ifndef _MSC_VER -const RequestSystemQuit_QuitCode RequestSystemQuit::CLOSE_CHANNEL; -const RequestSystemQuit_QuitCode RequestSystemQuit::SHUTDOWN_RS; -const RequestSystemQuit_QuitCode RequestSystemQuit::QuitCode_MIN; -const RequestSystemQuit_QuitCode RequestSystemQuit::QuitCode_MAX; -const int RequestSystemQuit::QuitCode_ARRAYSIZE; -#endif // _MSC_VER -#ifndef _MSC_VER -const int RequestSystemQuit::kQuitCodeFieldNumber; -#endif // !_MSC_VER - -RequestSystemQuit::RequestSystemQuit() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void RequestSystemQuit::InitAsDefaultInstance() { -} - -RequestSystemQuit::RequestSystemQuit(const RequestSystemQuit& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void RequestSystemQuit::SharedCtor() { - _cached_size_ = 0; - quit_code_ = 1; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -RequestSystemQuit::~RequestSystemQuit() { - SharedDtor(); -} - -void RequestSystemQuit::SharedDtor() { - if (this != default_instance_) { - } -} - -void RequestSystemQuit::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* RequestSystemQuit::descriptor() { - protobuf_AssignDescriptorsOnce(); - return RequestSystemQuit_descriptor_; -} - -const RequestSystemQuit& RequestSystemQuit::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_system_2eproto(); return *default_instance_; -} - -RequestSystemQuit* RequestSystemQuit::default_instance_ = NULL; - -RequestSystemQuit* RequestSystemQuit::New() const { - return new RequestSystemQuit; -} - -void RequestSystemQuit::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - quit_code_ = 1; - } - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool RequestSystemQuit::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // required .rsctrl.system.RequestSystemQuit.QuitCode quit_code = 1; - case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { - int value; - DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( - input, &value))); - if (::rsctrl::system::RequestSystemQuit_QuitCode_IsValid(value)) { - set_quit_code(static_cast< ::rsctrl::system::RequestSystemQuit_QuitCode >(value)); - } else { - mutable_unknown_fields()->AddVarint(1, value); - } - } else { - goto handle_uninterpreted; - } - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void RequestSystemQuit::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // required .rsctrl.system.RequestSystemQuit.QuitCode quit_code = 1; - if (has_quit_code()) { - ::google::protobuf::internal::WireFormatLite::WriteEnum( - 1, this->quit_code(), output); - } - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* RequestSystemQuit::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // required .rsctrl.system.RequestSystemQuit.QuitCode quit_code = 1; - if (has_quit_code()) { - target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( - 1, this->quit_code(), target); - } - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int RequestSystemQuit::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // required .rsctrl.system.RequestSystemQuit.QuitCode quit_code = 1; - if (has_quit_code()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::EnumSize(this->quit_code()); - } - - } - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void RequestSystemQuit::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const RequestSystemQuit* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void RequestSystemQuit::MergeFrom(const RequestSystemQuit& from) { - GOOGLE_CHECK_NE(&from, this); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from.has_quit_code()) { - set_quit_code(from.quit_code()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void RequestSystemQuit::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void RequestSystemQuit::CopyFrom(const RequestSystemQuit& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool RequestSystemQuit::IsInitialized() const { - if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; - - return true; -} - -void RequestSystemQuit::Swap(RequestSystemQuit* other) { - if (other != this) { - std::swap(quit_code_, other->quit_code_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - } -} - -::google::protobuf::Metadata RequestSystemQuit::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = RequestSystemQuit_descriptor_; - metadata.reflection = RequestSystemQuit_reflection_; - return metadata; -} - - -// =================================================================== - -#ifndef _MSC_VER -const int ResponseSystemQuit::kStatusFieldNumber; -#endif // !_MSC_VER - -ResponseSystemQuit::ResponseSystemQuit() - : ::google::protobuf::Message() { - SharedCtor(); -} - -void ResponseSystemQuit::InitAsDefaultInstance() { - status_ = const_cast< ::rsctrl::core::Status*>(&::rsctrl::core::Status::default_instance()); -} - -ResponseSystemQuit::ResponseSystemQuit(const ResponseSystemQuit& from) - : ::google::protobuf::Message() { - SharedCtor(); - MergeFrom(from); -} - -void ResponseSystemQuit::SharedCtor() { - _cached_size_ = 0; - status_ = NULL; - ::memset(_has_bits_, 0, sizeof(_has_bits_)); -} - -ResponseSystemQuit::~ResponseSystemQuit() { - SharedDtor(); -} - -void ResponseSystemQuit::SharedDtor() { - if (this != default_instance_) { - delete status_; - } -} - -void ResponseSystemQuit::SetCachedSize(int size) const { - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); -} -const ::google::protobuf::Descriptor* ResponseSystemQuit::descriptor() { - protobuf_AssignDescriptorsOnce(); - return ResponseSystemQuit_descriptor_; -} - -const ResponseSystemQuit& ResponseSystemQuit::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_system_2eproto(); return *default_instance_; -} - -ResponseSystemQuit* ResponseSystemQuit::default_instance_ = NULL; - -ResponseSystemQuit* ResponseSystemQuit::New() const { - return new ResponseSystemQuit; -} - -void ResponseSystemQuit::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (has_status()) { - if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); - } - } - ::memset(_has_bits_, 0, sizeof(_has_bits_)); - mutable_unknown_fields()->Clear(); -} - -bool ResponseSystemQuit::MergePartialFromCodedStream( - ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false - ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { - switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { - // required .rsctrl.core.Status status = 1; - case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( - input, mutable_status())); - } else { - goto handle_uninterpreted; - } - if (input->ExpectAtEnd()) return true; - break; - } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; - } - DO_(::google::protobuf::internal::WireFormat::SkipField( - input, tag, mutable_unknown_fields())); - break; - } - } - } - return true; -#undef DO_ -} - -void ResponseSystemQuit::SerializeWithCachedSizes( - ::google::protobuf::io::CodedOutputStream* output) const { - // required .rsctrl.core.Status status = 1; - if (has_status()) { - ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 1, this->status(), output); - } - - if (!unknown_fields().empty()) { - ::google::protobuf::internal::WireFormat::SerializeUnknownFields( - unknown_fields(), output); - } -} - -::google::protobuf::uint8* ResponseSystemQuit::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { - // required .rsctrl.core.Status status = 1; - if (has_status()) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 1, this->status(), target); - } - - if (!unknown_fields().empty()) { - target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( - unknown_fields(), target); - } - return target; -} - -int ResponseSystemQuit::ByteSize() const { - int total_size = 0; - - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - // required .rsctrl.core.Status status = 1; - if (has_status()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->status()); - } - - } - if (!unknown_fields().empty()) { - total_size += - ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( - unknown_fields()); - } - GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); - _cached_size_ = total_size; - GOOGLE_SAFE_CONCURRENT_WRITES_END(); - return total_size; -} - -void ResponseSystemQuit::MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const ResponseSystemQuit* source = - ::google::protobuf::internal::dynamic_cast_if_available( - &from); - if (source == NULL) { - ::google::protobuf::internal::ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } -} - -void ResponseSystemQuit::MergeFrom(const ResponseSystemQuit& from) { - GOOGLE_CHECK_NE(&from, this); - if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from.has_status()) { - mutable_status()->::rsctrl::core::Status::MergeFrom(from.status()); - } - } - mutable_unknown_fields()->MergeFrom(from.unknown_fields()); -} - -void ResponseSystemQuit::CopyFrom(const ::google::protobuf::Message& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -void ResponseSystemQuit::CopyFrom(const ResponseSystemQuit& from) { - if (&from == this) return; - Clear(); - MergeFrom(from); -} - -bool ResponseSystemQuit::IsInitialized() const { - if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; - - if (has_status()) { - if (!this->status().IsInitialized()) return false; - } - return true; -} - -void ResponseSystemQuit::Swap(ResponseSystemQuit* other) { - if (other != this) { - std::swap(status_, other->status_); - std::swap(_has_bits_[0], other->_has_bits_[0]); - _unknown_fields_.Swap(&other->_unknown_fields_); - std::swap(_cached_size_, other->_cached_size_); - } -} - -::google::protobuf::Metadata ResponseSystemQuit::GetMetadata() const { - protobuf_AssignDescriptorsOnce(); - ::google::protobuf::Metadata metadata; - metadata.descriptor = ResponseSystemQuit_descriptor_; - metadata.reflection = ResponseSystemQuit_reflection_; - return metadata; -} - - // @@protoc_insertion_point(namespace_scope) } // namespace system diff --git a/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc b/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc index 7a0e1e52a..29c7c5cbc 100644 --- a/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc +++ b/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc @@ -86,11 +86,6 @@ int RpcProtoSystem::processMsg(uint32_t chan_id, uint32_t msg_id, uint32_t req_i case rsctrl::system::MsgId_RequestSystemStatus: processSystemStatus(chan_id, msg_id, req_id, msg); break; -#if 0 - case rsctrl::system::MsgId_RequestSystemQuit: - processSystemQuit(chan_id, msg_id, req_id, msg); - break; -#endif default: std::cerr << "RpcProtoSystem::processMsg() ERROR should never get here"; std::cerr << std::endl; @@ -216,71 +211,3 @@ int RpcProtoSystem::processSystemStatus(uint32_t chan_id, uint32_t msg_id, uint3 } - -int RpcProtoSystem::processSystemQuit(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg) -{ - std::cerr << "RpcProtoSystem::processSystemQuit()"; - std::cerr << std::endl; - - // parse msg. - rsctrl::system::RequestSystemQuit req; - if (!req.ParseFromString(msg)) - { - std::cerr << "RpcProtoSystem::processSystemQuit() ERROR ParseFromString()"; - std::cerr << std::endl; - return 0; - } - - // NO Options... so go straight to answer. - // response. - rsctrl::system::ResponseSystemQuit resp; - bool success = true; - - switch(req.quit_code()) - { - default: - case rsctrl::system::RequestSystemQuit::CLOSE_CHANNEL: - { - RpcServer *server = getRpcServer(); - server->error(chan_id, "CLOSE_CHANNEL"); - - break; - } - case rsctrl::system::RequestSystemQuit::SHUTDOWN_RS: - { - rsicontrol->rsGlobalShutDown(); - break; - } - } - - if (success) - { - rsctrl::core::Status *status = resp.mutable_status(); - status->set_code(rsctrl::core::Status::SUCCESS); - } - else - { - rsctrl::core::Status *status = resp.mutable_status(); - status->set_code(rsctrl::core::Status::FAILED); - status->set_msg("Unknown ERROR"); - } - - std::string outmsg; - if (!resp.SerializeToString(&outmsg)) - { - std::cerr << "RpcProtoSystem::processSystemQuit() ERROR SerialiseToString()"; - std::cerr << std::endl; - return 0; - } - - // Correctly Name Message. - uint32_t out_msg_id = constructMsgId(rsctrl::core::CORE, rsctrl::core::SYSTEM, - rsctrl::system::MsgId_ResponseSystemQuit, true); - - // queue it. - queueResponse(chan_id, out_msg_id, req_id, outmsg); - - return 1; -} - - diff --git a/retroshare-nogui/src/rpc/rpc.cc b/retroshare-nogui/src/rpc/rpc.cc index a1aa1683b..6fd5a0b74 100644 --- a/retroshare-nogui/src/rpc/rpc.cc +++ b/retroshare-nogui/src/rpc/rpc.cc @@ -43,11 +43,6 @@ void RpcMediator::reset(uint32_t chan_id) mServer->reset(chan_id); } -int RpcMediator::error(uint32_t chan_id, std::string msg) -{ - return mComms->error(chan_id, msg); -} - int RpcMediator::tick() { diff --git a/retroshare-nogui/src/rpc/rpcserver.cc b/retroshare-nogui/src/rpc/rpcserver.cc index a879e08df..484a7576e 100644 --- a/retroshare-nogui/src/rpc/rpcserver.cc +++ b/retroshare-nogui/src/rpc/rpcserver.cc @@ -63,16 +63,11 @@ void RpcServer::reset(uint32_t chan_id) return; } -int RpcServer::error(uint32_t chan_id, std::string msg) -{ - return mMediator->error(chan_id, msg); -} int RpcServer::addService(RpcService *service) { RsStackMutex stack(mRpcMtx); /********** LOCKED MUTEX ***************/ - service->setRpcServer(this); mAllServices.push_back(service); return 1; diff --git a/retroshare-nogui/src/rpc/rpcsetup.cc b/retroshare-nogui/src/rpc/rpcsetup.cc index 015d72142..528f5b425 100644 --- a/retroshare-nogui/src/rpc/rpcsetup.cc +++ b/retroshare-nogui/src/rpc/rpcsetup.cc @@ -27,12 +27,10 @@ #include "rpc/proto/rpcprotopeers.h" #include "rpc/proto/rpcprotosystem.h" #include "rpc/proto/rpcprotochat.h" -#include "rpc/proto/rpcprotosearch.h" -#include "rpc/proto/rpcprotofiles.h" #include "rpc/rpcecho.h" -RpcMediator *CreateRpcSystem(RpcComms *comms, NotifyTxt *notify) +RpcMediator *CreateRpcSystem(RpcComms *comms) { RpcMediator *med = new RpcMediator(comms); RpcServer *server = new RpcServer(med); @@ -47,12 +45,6 @@ RpcMediator *CreateRpcSystem(RpcComms *comms, NotifyTxt *notify) RpcProtoChat *chat = new RpcProtoChat(1); server->addService(chat); - RpcProtoSearch *search = new RpcProtoSearch(1, notify); - server->addService(search); - - RpcProtoFiles *files = new RpcProtoFiles(1); - server->addService(files); - /* Finally an Echo Service - which will echo back any unprocesses commands. */ RpcEcho *echo = new RpcEcho(1); server->addService(echo); From 33d001898f3c9402c41f51419c196a2b8bfea7dc Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Tue, 18 Sep 2012 21:19:29 +0000 Subject: [PATCH 065/222] fixed to allow compilation. but photodialog slightly less usable. issue with retroshare-nogui still needs fixing git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5567 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgxsnetservice.cc | 2 +- libretroshare/src/rsserver/rsinit.cc | 6 +- .../src/serialiser/rsphotov2items.cc | 40 ++++++-- .../src/services/p3photoserviceV2.cc | 92 ++++++++++++++++++- .../src/gui/PhotoShare/PhotoDialog.cpp | 5 + .../src/gui/PhotoShare/PhotoShare.cpp | 1 - retroshare-gui/src/util/TokenQueueV2.cpp | 4 +- retroshare-gui/src/util/TokenQueueV2.h | 3 +- 8 files changed, 137 insertions(+), 16 deletions(-) diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 875f42b48..19e22ca0f 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -98,7 +98,7 @@ void RsGxsNetService::syncWithPeers() { RsGxsGrpMetaData* meta = mit->second; - if(meta->mSubscribeFlags & GXS_SERV::RSGXS_GROUP_SUBSCRIBE_MASK) + if(meta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_MASK) grpIds.push_back(mit->first); } diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index c708eb0de..6c58ab54c 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1806,7 +1806,7 @@ RsTurtle *rsTurtle = NULL ; #include "services/p3blogs.h" #include "turtle/p3turtle.h" -#define ENABLE_GXS_SERVICES 1 +//#define ENABLE_GXS_SERVICES 1 #define ENABLE_GXS_CORE 1 #ifdef ENABLE_GXS_CORE @@ -2272,7 +2272,7 @@ int RsServer::StartupRetroShare() // first prep the core RsGeneralDataService* photo_ds = new RsDataService("./", "photoV2_db", - RS_SERVICE_TYPE_PHOTO, NULL); + RS_SERVICE_GXSV1_TYPE_PHOTO, NULL); photo_ds->resetDataStore(); @@ -2580,11 +2580,11 @@ int RsServer::StartupRetroShare() rsForums = mForums; rsChannels = mChannels; + rsPhotoV2 = mPhotoV2; #ifdef ENABLE_GXS_SERVICES // Testing of new cache system interfaces. rsIdentity = mIdentity; rsPhoto = mPhotos; - rsPhotoV2 = mPhotoV2; rsWiki = mWikis; rsWire = mWire; rsForumsV2 = mForumsV2; diff --git a/libretroshare/src/serialiser/rsphotov2items.cc b/libretroshare/src/serialiser/rsphotov2items.cc index ac153ecba..9320eaf8d 100644 --- a/libretroshare/src/serialiser/rsphotov2items.cc +++ b/libretroshare/src/serialiser/rsphotov2items.cc @@ -88,7 +88,7 @@ RsItem* RsGxsPhotoSerialiser::deserialise(void* data, uint32_t* size) uint32_t rstype = getRsItemId(data); if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_TYPE_PHOTO != getRsItemService(rstype))) + (RS_SERVICE_GXSV1_TYPE_PHOTO != getRsItemService(rstype))) { return NULL; /* wrong type */ } @@ -175,7 +175,7 @@ bool RsGxsPhotoSerialiser::serialiseGxsPhotoAlbumItem(RsGxsPhotoAlbumItem* item, ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mWhen); ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mWhere); ok &= SetTlvString(data, tlvsize, &offset, 1, item->album.mThumbnail.type); - RsTlvBinaryData b(RS_SERVICE_TYPE_PHOTO); // TODO, need something more persisitent + RsTlvBinaryData b(RS_SERVICE_GXSV1_TYPE_PHOTO); // TODO, need something more persisitent b.setBinData(item->album.mThumbnail.data, item->album.mThumbnail.size); ok &= b.SetTlv(data, tlvsize, &offset); @@ -213,7 +213,7 @@ RsGxsPhotoAlbumItem* RsGxsPhotoSerialiser::deserialiseGxsPhotoAlbumItem(void* da if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_TYPE_PHOTO != getRsItemService(rstype)) || + (RS_SERVICE_GXSV1_TYPE_PHOTO != getRsItemService(rstype)) || (RS_PKT_SUBTYPE_PHOTO_ITEM != getRsItemSubType(rstype))) { #ifdef GXS_PHOTO_SERIAL_DEBUG @@ -251,7 +251,7 @@ RsGxsPhotoAlbumItem* RsGxsPhotoSerialiser::deserialiseGxsPhotoAlbumItem(void* da ok &= GetTlvString(data, rssize, &offset, 1, item->album.mWhere); ok &= GetTlvString(data, rssize, &offset, 1, item->album.mThumbnail.type); - RsTlvBinaryData b(RS_SERVICE_TYPE_PHOTO); // TODO, need something more persisitent + RsTlvBinaryData b(RS_SERVICE_GXSV1_TYPE_PHOTO); // TODO, need something more persisitent ok &= b.GetTlv(data, rssize, &offset); item->album.mThumbnail.data = (uint8_t*)b.bin_data; item->album.mThumbnail.size = b.bin_len; @@ -341,7 +341,7 @@ bool RsGxsPhotoSerialiser::serialiseGxsPhotoPhotoItem(RsGxsPhotoPhotoItem* item, ok &= SetTlvString(data, tlvsize, &offset, 1, item->photo.mWhen); ok &= SetTlvString(data, tlvsize, &offset, 1, item->photo.mWhere); ok &= SetTlvString(data, tlvsize, &offset, 1, item->photo.mThumbnail.type); - RsTlvBinaryData b(RS_SERVICE_TYPE_PHOTO); // TODO, need something more persisitent + RsTlvBinaryData b(RS_SERVICE_GXSV1_TYPE_PHOTO); // TODO, need something more persisitent b.setBinData(item->photo.mThumbnail.data, item->photo.mThumbnail.size); ok &= b.SetTlv(data, tlvsize, &offset); @@ -379,7 +379,7 @@ RsGxsPhotoPhotoItem* RsGxsPhotoSerialiser::deserialiseGxsPhotoPhotoItem(void* da if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_TYPE_PHOTO != getRsItemService(rstype)) || + (RS_SERVICE_GXSV1_TYPE_PHOTO != getRsItemService(rstype)) || (RS_PKT_SUBTYPE_PHOTO_SHOW_ITEM != getRsItemSubType(rstype))) { #ifdef GXS_PHOTO_SERIAL_DEBUG @@ -415,7 +415,7 @@ RsGxsPhotoPhotoItem* RsGxsPhotoSerialiser::deserialiseGxsPhotoPhotoItem(void* da ok &= GetTlvString(data, rssize, &offset, 1, item->photo.mWhere); ok &= GetTlvString(data, rssize, &offset, 1, item->photo.mThumbnail.type); - RsTlvBinaryData b(RS_SERVICE_TYPE_PHOTO); // TODO, need something more persisitent + RsTlvBinaryData b(RS_SERVICE_GXSV1_TYPE_PHOTO); // TODO, need something more persisitent ok &= b.GetTlv(data, rssize, &offset); item->photo.mThumbnail.data = (uint8_t*)(b.bin_data); item->photo.mThumbnail.size = b.bin_len; @@ -443,6 +443,21 @@ RsGxsPhotoPhotoItem* RsGxsPhotoSerialiser::deserialiseGxsPhotoPhotoItem(void* da return item; } +uint32_t RsGxsPhotoSerialiser::sizeGxsPhotoCommentItem(RsGxsPhotoCommentItem *item) +{ + +} + +bool RsGxsPhotoSerialiser::serialiseGxsPhotoCommentItem (RsGxsPhotoCommentItem *item, void *data, uint32_t *size) +{ + return false; +} + +RsGxsPhotoCommentItem * RsGxsPhotoSerialiser::deserialiseGxsPhotoCommentItem(void *data, uint32_t *size) +{ + return NULL; +} + void RsGxsPhotoAlbumItem::clear() { album.mCaption.clear(); @@ -457,6 +472,17 @@ void RsGxsPhotoAlbumItem::clear() album.mThumbnail.deleteImage(); } +void RsGxsPhotoCommentItem::clear() +{ + + +} + +std::ostream& RsGxsPhotoCommentItem::print(std::ostream& out, uint16_t indent) +{ + return out; +} + std::ostream& RsGxsPhotoAlbumItem::print(std::ostream& out, uint16_t indent) { printRsItemBase(out, "RsGxsPhotoAlbumItem", indent); diff --git a/libretroshare/src/services/p3photoserviceV2.cc b/libretroshare/src/services/p3photoserviceV2.cc index a460ff3b7..82efc8579 100644 --- a/libretroshare/src/services/p3photoserviceV2.cc +++ b/libretroshare/src/services/p3photoserviceV2.cc @@ -1,10 +1,81 @@ #include "p3photoserviceV2.h" #include "serialiser/rsphotov2items.h" +#include "gxs/rsgxsflags.h" RsPhotoV2 *rsPhotoV2 = NULL; + + + +bool RsPhotoThumbnail::copyFrom(const RsPhotoThumbnail &nail) +{ + if (data) + { + deleteImage(); + } + + if ((!nail.data) || (nail.size == 0)) + { + return false; + } + + size = nail.size; + type = nail.type; + data = (uint8_t *) malloc(size); + memcpy(data, nail.data, size); + + return true; +} + +bool RsPhotoThumbnail::deleteImage() +{ + if (data) + { + free(data); + data = NULL; + size = 0; + type.clear(); + } + return true; +} + + +RsPhotoPhoto::RsPhotoPhoto() + :mSetFlags(0), mOrder(0), mMode(0), mModFlags(0) +{ + return; +} + +RsPhotoAlbum::RsPhotoAlbum() + :mMode(0), mSetFlags(0), mModFlags(0) +{ + return; +} + +RsPhotoComment::RsPhotoComment() + : mComment(""), mCommentFlag(0) { + +} + +std::ostream &operator<<(std::ostream &out, const RsPhotoPhoto &photo) +{ + out << "RsPhotoPhoto [ "; + out << "Title: " << photo.mMeta.mMsgName; + out << "]"; + return out; +} + + +std::ostream &operator<<(std::ostream &out, const RsPhotoAlbum &album) +{ + out << "RsPhotoAlbum [ "; + out << "Title: " << album.mMeta.mGroupName; + out << "]"; + return out; +} + p3PhotoServiceV2::p3PhotoServiceV2(RsGeneralDataService* gds, RsNetworkExchangeService* nes) - : RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_TYPE_PHOTO) + : RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_GXSV1_TYPE_PHOTO) { } @@ -182,6 +253,16 @@ bool p3PhotoServiceV2::submitPhoto(uint32_t& token, RsPhotoPhoto& photo) return true; } +bool p3PhotoServiceV2::submitComment(uint32_t &token, RsPhotoComment &comment) +{ + RsGxsPhotoCommentItem* commentItem = new RsGxsPhotoCommentItem(); + commentItem->comment = comment; + commentItem->meta = comment.mMeta; + + RsGenExchange::publishMsg(token, commentItem); + return true; +} + bool p3PhotoServiceV2::acknowledgeMsg(const uint32_t& token, std::pair& msgId) { @@ -195,5 +276,14 @@ bool p3PhotoServiceV2::acknowledgeGrp(const uint32_t& token, return RsGenExchange::acknowledgeTokenGrp(token, grpId); } +bool p3PhotoServiceV2::subscribeToAlbum(uint32_t &token, const RsGxsGroupId &grpId, bool subscribe) +{ + if(subscribe) + RsGenExchange::setGroupSubscribeFlag(token, grpId, GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED); + else + RsGenExchange::setGroupSubscribeFlag(token, grpId, ~GXS_SERV::GROUP_SUBSCRIBE_MASK); + + return true; +} diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index 8035fb525..a92d38db2 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -31,3 +31,8 @@ void PhotoDialog::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &r { } + +void PhotoDialog::addComment() +{ + +} diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp index d3cae9452..d46f40f67 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp @@ -95,7 +95,6 @@ PhotoShare::PhotoShare(QWidget *parent) timer->connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate())); timer->start(1000); - /* setup TokenQueue */ mPhotoQueue = new TokenQueueV2(rsPhotoV2->getTokenService(), this); requestAlbumData(); diff --git a/retroshare-gui/src/util/TokenQueueV2.cpp b/retroshare-gui/src/util/TokenQueueV2.cpp index 10c45c86d..c35d33400 100644 --- a/retroshare-gui/src/util/TokenQueueV2.cpp +++ b/retroshare-gui/src/util/TokenQueueV2.cpp @@ -66,11 +66,11 @@ bool TokenQueueV2::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTok return true; } -bool TokenQueueV2::requestMsgRelatedInfo(uint32_t &token, const RsTokReqOptionsV2 &opts, const std::list &grpIds, uint32_t usertype) +bool TokenQueueV2::requestMsgRelatedInfo(uint32_t &token, const RsTokReqOptionsV2 &opts, const GxsMsgReq& msgIds, uint32_t usertype) { uint32_t basictype = TOKENREQ_MSGINFO; uint32_t anstype = RS_TOKREQ_ANSTYPE_LIST; // always a list answer - mService->requestMsgRelatedInfo(token, anstype, opts, ids); + mService->requestMsgRelatedInfo(token, anstype, opts, msgIds); queueRequest(token, basictype, anstype, usertype); return true; diff --git a/retroshare-gui/src/util/TokenQueueV2.h b/retroshare-gui/src/util/TokenQueueV2.h index 2f37a10b9..0d7aa9b6b 100644 --- a/retroshare-gui/src/util/TokenQueueV2.h +++ b/retroshare-gui/src/util/TokenQueueV2.h @@ -85,6 +85,7 @@ public: bool requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, std::list& ids, uint32_t usertype); + bool requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, uint32_t usertype); bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, @@ -93,7 +94,7 @@ public: bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, const GxsMsgReq& grpIds, uint32_t usertype); - bool requestMsgRelatedInfo(uint32_t &token, const RsTokReqOptionsV2 &opts, const std::list& grpIds, uint32_t usertype); + bool requestMsgRelatedInfo(uint32_t &token, const RsTokReqOptionsV2 &opts, const GxsMsgReq& msgIds, uint32_t usertype); bool cancelRequest(const uint32_t token); From 2e3e5b4ee45495f4ac6e41083d841ae186015e8d Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Thu, 20 Sep 2012 17:18:26 +0000 Subject: [PATCH 066/222] added photo comment serialisation and addition reimplemented getmsgrelatedinfo and getmsginfo as previous was incorrectly done, rstokenservice for msgs buggy now updated test, commiting to transfer work to windows git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5576 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsdataservice.cc | 4 +- libretroshare/src/gxs/rsdataservice.h | 2 +- libretroshare/src/gxs/rsgds.h | 2 +- libretroshare/src/gxs/rsgxsdataaccess.cc | 453 ++++++++++++++---- libretroshare/src/gxs/rsgxsdataaccess.h | 11 +- libretroshare/src/gxs/rsgxsrequesttypes.h | 2 +- libretroshare/src/gxs/rstokenservice.h | 2 +- .../src/serialiser/rsphotov2items.cc | 181 ++++++- .../src/tests/gxs/genexchangetester.cpp | 12 +- .../src/tests/gxs/genexchangetester.h | 6 +- libretroshare/src/tests/gxs/nxs_tests.pro | 123 +++++ .../src/tests/gxs/rsgenexchange_test.cc | 20 +- 12 files changed, 689 insertions(+), 129 deletions(-) create mode 100644 libretroshare/src/tests/gxs/nxs_tests.pro diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index cc0ae6ff5..1fbfbaf15 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -807,9 +807,9 @@ void RsDataService::retrieveMessages(RetroCursor *c, std::vector &ms return; } -int RsDataService::retrieveGxsMsgMetaData(GxsMsgReq& reqIds, GxsMsgMetaResult &msgMeta) +int RsDataService::retrieveGxsMsgMetaData(const GxsMsgReq& reqIds, GxsMsgMetaResult &msgMeta) { - GxsMsgReq::iterator mit = reqIds.begin(); + GxsMsgReq::const_iterator mit = reqIds.begin(); for(; mit != reqIds.end(); mit++) { diff --git a/libretroshare/src/gxs/rsdataservice.h b/libretroshare/src/gxs/rsdataservice.h index 3ef293c95..bf2496488 100644 --- a/libretroshare/src/gxs/rsdataservice.h +++ b/libretroshare/src/gxs/rsdataservice.h @@ -70,7 +70,7 @@ public: * @param cache whether to store retrieval in mem for faster later retrieval * @return error code */ - int retrieveGxsMsgMetaData(GxsMsgReq& reqIds, GxsMsgMetaResult& msgMeta); + int retrieveGxsMsgMetaData(const GxsMsgReq& reqIds, GxsMsgMetaResult& msgMeta); /*! * remove msgs in data store diff --git a/libretroshare/src/gxs/rsgds.h b/libretroshare/src/gxs/rsgds.h index 2abf2c982..277473c8a 100644 --- a/libretroshare/src/gxs/rsgds.h +++ b/libretroshare/src/gxs/rsgds.h @@ -151,7 +151,7 @@ public: * @param cache whether to store retrieval in mem for faster later retrieval * @return error code */ - virtual int retrieveGxsMsgMetaData(GxsMsgReq& msgIds, GxsMsgMetaResult& msgMeta) = 0; + virtual int retrieveGxsMsgMetaData(const GxsMsgReq& msgIds, GxsMsgMetaResult& msgMeta) = 0; /*! * remove msgs in data store listed in msgIds param diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index 6166f23e5..7e6c89265 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -270,11 +270,11 @@ bool RsGxsDataAccess::requestMsgInfo(uint32_t &token, uint32_t ansType, } bool RsGxsDataAccess::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, - const GxsMsgReq& msgIds) + const RsGxsGrpMsgIdPair &msgIds) { MsgRelatedInfoReq* req = new MsgRelatedInfoReq(); - req->mMsgIds = msgIds; + req->mMsgId = msgIds; generateToken(token); @@ -723,7 +723,13 @@ bool RsGxsDataAccess::getGroupList(GroupIdReq* req) bool RsGxsDataAccess::getMsgData(MsgDataReq* req) { GxsMsgResult result; - mDataStore->retrieveNxsMsgs(req->mMsgIds, result, true, true); + + GxsMsgReq msgIdOut; + + // filter based on options + getMsgList(req->mMsgIds, req->Options, msgIdOut); + + mDataStore->retrieveNxsMsgs(msgIdOut, result, true, true); req->mMsgData = result; return true; @@ -733,22 +739,24 @@ bool RsGxsDataAccess::getMsgData(MsgDataReq* req) bool RsGxsDataAccess::getMsgSummary(MsgMetaReq* req) { GxsMsgMetaResult result; - mDataStore->retrieveGxsMsgMetaData(req->mMsgIds, result); + + GxsMsgReq msgIdOut; + + // filter based on options + getMsgList(req->mMsgIds, req->Options, msgIdOut); + + mDataStore->retrieveGxsMsgMetaData(msgIdOut, result); req->mMsgMetaData = result; return true; } -bool RsGxsDataAccess::getMsgRelatedInfo(MsgRelatedInfoReq* req) +bool RsGxsDataAccess::getMsgList(const GxsMsgReq& msgIds, const RsTokReqOptionsV2& opts, GxsMsgReq msgIdsOut) { GxsMsgMetaResult result; - const RsTokReqOptionsV2& opts = req->Options; - - mDataStore->retrieveGxsMsgMetaData(req->mMsgIds, result); - - + mDataStore->retrieveGxsMsgMetaData(msgIds, result); /* CASEs this handles. * Input is groupList + Flags. @@ -798,105 +806,104 @@ bool RsGxsDataAccess::getMsgRelatedInfo(MsgRelatedInfoReq* req) { std::vector::const_iterator vit = metaV.begin(); - // RUN THROUGH ALL MSGS... in map origId -> TS. std::map > origMsgTs; std::map >::iterator oit; for(; vit != metaV.end(); vit++) { - RsGxsMsgMetaData* msgMeta = *vit; + RsGxsMsgMetaData* msgMeta = *vit; - /* if we are grabbing thread Head... then parentId == empty. */ - if (onlyThreadHeadMsgs) + /* if we are grabbing thread Head... then parentId == empty. */ + if (onlyThreadHeadMsgs) + { + if (!(msgMeta->mParentId.empty())) { - if (!(msgMeta->mParentId.empty())) - { - continue; - } + continue; } + } - oit = origMsgTs.find(msgMeta->mOrigMsgId); - bool addMsg = false; - if (oit == origMsgTs.end()) - { - std::cerr << "RsGxsDataAccess::getMsgList() Found New OrigMsgId: "; - std::cerr << msgMeta->mOrigMsgId; - std::cerr << " MsgId: " << msgMeta->mMsgId; - std::cerr << " TS: " << msgMeta->mPublishTs; - std::cerr << std::endl; + oit = origMsgTs.find(msgMeta->mOrigMsgId); + bool addMsg = false; + if (oit == origMsgTs.end()) + { + std::cerr << "RsGxsDataAccess::getMsgList() Found New OrigMsgId: "; + std::cerr << msgMeta->mOrigMsgId; + std::cerr << " MsgId: " << msgMeta->mMsgId; + std::cerr << " TS: " << msgMeta->mPublishTs; + std::cerr << std::endl; - addMsg = true; - } - // check timestamps. - else if (oit->second.second < msgMeta->mPublishTs) - { - std::cerr << "RsGxsDataAccess::getMsgList() Found Later Msg. OrigMsgId: "; - std::cerr << msgMeta->mOrigMsgId; - std::cerr << " MsgId: " << msgMeta->mMsgId; - std::cerr << " TS: " << msgMeta->mPublishTs; + addMsg = true; + } + // check timestamps. + else if (oit->second.second < msgMeta->mPublishTs) + { + std::cerr << "RsGxsDataAccess::getMsgList() Found Later Msg. OrigMsgId: "; + std::cerr << msgMeta->mOrigMsgId; + std::cerr << " MsgId: " << msgMeta->mMsgId; + std::cerr << " TS: " << msgMeta->mPublishTs; - addMsg = true; - } + addMsg = true; + } - if (addMsg) - { - // add as latest. (overwriting if necessary) - origMsgTs[msgMeta->mOrigMsgId] = std::make_pair(msgMeta->mMsgId, msgMeta->mPublishTs); - metaFilter[grpId].insert(std::make_pair(msgMeta->mMsgId, msgMeta)); - } + if (addMsg) + { + // add as latest. (overwriting if necessary) + origMsgTs[msgMeta->mOrigMsgId] = std::make_pair(msgMeta->mMsgId, msgMeta->mPublishTs); + metaFilter[grpId].insert(std::make_pair(msgMeta->mMsgId, msgMeta)); + } } // Add the discovered Latest Msgs. for(oit = origMsgTs.begin(); oit != origMsgTs.end(); oit++) { - req->mMsgIdResult[grpId].push_back(oit->second.first); + msgIdsOut[grpId].push_back(oit->second.first); } } else // ALL OTHER CASES. { - std::vector::const_iterator vit = metaV.begin(); + std::vector::const_iterator vit = metaV.begin(); - for(; vit != metaV.end(); vit++) + for(; vit != metaV.end(); vit++) + { + RsGxsMsgMetaData* msgMeta = *vit; + bool add = false; + + /* if we are grabbing thread Head... then parentId == empty. */ + if (onlyThreadHeadMsgs) { - RsGxsMsgMetaData* msgMeta = *vit; - bool add = false; - - /* if we are grabbing thread Head... then parentId == empty. */ - if (onlyThreadHeadMsgs) + if (!(msgMeta->mParentId.empty())) { - if (!(msgMeta->mParentId.empty())) - { - continue; - } + continue; } - - - if (onlyOrigMsgs) - { - if (msgMeta->mMsgId == msgMeta->mOrigMsgId) - { - add = true; - } - } - else - { - add = true; - } - - if (add) - { - req->mMsgIdResult[grpId].push_back(msgMeta->mMsgId); - metaFilter[grpId].insert(std::make_pair(msgMeta->mMsgId, msgMeta)); - } - } + + + if (onlyOrigMsgs) + { + if (msgMeta->mMsgId == msgMeta->mOrigMsgId) + { + add = true; + } + } + else + { + add = true; + } + + if (add) + { + msgIdsOut[grpId].push_back(msgMeta->mMsgId); + metaFilter[grpId].insert(std::make_pair(msgMeta->mMsgId, msgMeta)); + } + + } } } - filterMsgList(req->mMsgIdResult, opts, metaFilter); + filterMsgList(msgIdsOut, opts, metaFilter); metaFilter.clear(); @@ -906,12 +913,263 @@ bool RsGxsDataAccess::getMsgRelatedInfo(MsgRelatedInfoReq* req) return true; } +bool RsGxsDataAccess::getMsgRelatedInfo(MsgRelatedInfoReq *req) +{ + /* CASEs this handles. + * Input is msgList + Flags. + * 1) No Flags => return nothing + */ + + std::cerr << "RsGxsDataAccess::getMsgRelatedList()"; + std::cerr << std::endl; + + const RsTokReqOptionsV2& opts = req->Options; + + bool onlyLatestMsgs = false; + bool onlyAllVersions = false; + bool onlyChildMsgs = false; + bool onlyThreadMsgs = false; + + if (opts.mOptions & RS_TOKREQOPT_MSG_LATEST) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() MSG_LATEST"; + std::cerr << std::endl; + onlyLatestMsgs = true; + } + else if (opts.mOptions & RS_TOKREQOPT_MSG_VERSIONS) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() MSG_VERSIONS"; + std::cerr << std::endl; + onlyAllVersions = true; + } + + if (opts.mOptions & RS_TOKREQOPT_MSG_PARENT) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() MSG_PARENTS"; + std::cerr << std::endl; + onlyChildMsgs = true; + } + + if (opts.mOptions & RS_TOKREQOPT_MSG_THREAD) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() MSG_THREAD"; + std::cerr << std::endl; + onlyThreadMsgs = true; + } + + if (onlyAllVersions && onlyChildMsgs) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() ERROR Incompatible FLAGS (VERSIONS & PARENT)"; + std::cerr << std::endl; + + return false; + } + + if (onlyAllVersions && onlyThreadMsgs) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() ERROR Incompatible FLAGS (VERSIONS & THREAD)"; + std::cerr << std::endl; + + return false; + } + + if ((!onlyLatestMsgs) && onlyChildMsgs) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() ERROR Incompatible FLAGS (!LATEST & PARENT)"; + std::cerr << std::endl; + + return false; + } + + if ((!onlyLatestMsgs) && onlyThreadMsgs) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() ERROR Incompatible FLAGS (!LATEST & THREAD)"; + std::cerr << std::endl; + + return false; + } + + if (onlyChildMsgs && onlyThreadMsgs) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() ERROR Incompatible FLAGS (PARENT & THREAD)"; + std::cerr << std::endl; + + return false; + } + + + /* FALL BACK OPTION */ + if ((!onlyLatestMsgs) && (!onlyAllVersions) && (!onlyChildMsgs) && (!onlyThreadMsgs)) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() FALLBACK -> NO FLAGS -> SIMPLY RETURN nothing"; + std::cerr << std::endl; + + return true; + } + + MsgMetaFilter filterMap; + + RsStackMutex stack(mDataMutex); /***** LOCKED *****/ + + // get meta data for all in group + GxsMsgMetaResult result; + GxsMsgReq msgIds; + msgIds.insert(std::make_pair(req->mMsgId.first, std::vector())); + mDataStore->retrieveGxsMsgMetaData(msgIds, result); + std::vector& metaV = result[req->mMsgId.first]; + std::vector::iterator vit_meta; + + // msg id to relate to + const RsGxsMessageId& msgId = req->mMsgId.second; + const RsGxsGroupId& grpId = req->mMsgId.first; + + std::vector outMsgIds; + + + + RsGxsMsgMetaData* origMeta = NULL; + for(vit_meta = metaV.begin(); vit_meta != metaV.end(); vit_meta++) + { + RsGxsMsgMetaData* meta = *vit_meta; + + if(msgId == meta->mMsgId) + { + origMeta = meta; + break; + } + } + + if(!origMeta) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedInfo(): Cannot find meta of msgId (to relate to)!" + << std::endl; + cleanseMsgMetaMap(result); + return false; + } + + const RsGxsMessageId& origMsgId = origMeta->mOrigMsgId; + std::map& metaMap = filterMap[grpId]; + + if (onlyLatestMsgs) + { + if (onlyChildMsgs || onlyThreadMsgs) + { + // RUN THROUGH ALL MSGS... in map origId -> TS. + std::map > origMsgTs; + std::map >::iterator oit; + for(vit_meta = metaV.begin(); vit_meta != metaV.end(); vit_meta++) + { + + RsGxsMsgMetaData* meta = *vit_meta; + + // skip msgs that aren't children. + if (onlyChildMsgs) + { + if (meta->mParentId != origMsgId) + { + continue; + } + } + else /* onlyThreadMsgs */ + { + if (meta->mThreadId != msgId) + { + continue; + } + } + + + oit = origMsgTs.find(meta->mOrigMsgId); + + bool addMsg = false; + if (oit == origMsgTs.end()) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() Found New OrigMsgId: "; + std::cerr << meta->mOrigMsgId; + std::cerr << " MsgId: " << meta->mMsgId; + std::cerr << " TS: " << meta->mPublishTs; + std::cerr << std::endl; + + addMsg = true; + } + // check timestamps. + else if (oit->second.second < meta->mPublishTs) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() Found Later Msg. OrigMsgId: "; + std::cerr << meta->mOrigMsgId; + std::cerr << " MsgId: " << meta->mMsgId; + std::cerr << " TS: " << meta->mPublishTs; + + addMsg = true; + } + + if (addMsg) + { + // add as latest. (overwriting if necessary) + origMsgTs[meta->mOrigMsgId] = std::make_pair(meta->mMsgId, meta->mPublishTs); + metaMap.insert(std::make_pair(meta->mOrigMsgId, meta)); + } + } + + // Add the discovered Latest Msgs. + for(oit = origMsgTs.begin(); oit != origMsgTs.end(); oit++) + { + outMsgIds.push_back(oit->second.first); + } + } + else + { + + /* first guess is potentially better than Orig (can't be worse!) */ + time_t latestTs = 0; + RsGxsMessageId latestMsgId; + RsGxsMsgMetaData* latestMeta; + + for(vit_meta = metaV.begin(); vit_meta != metaV.end(); vit_meta++) + { + RsGxsMsgMetaData* meta = *vit_meta; + + if (meta->mOrigMsgId == origMsgId) + { + if (meta->mPublishTs > latestTs) + { + latestTs = meta->mPublishTs; + latestMsgId = meta->mMsgId; + latestMeta = meta; + } + } + } + outMsgIds.push_back(latestMsgId); + metaMap.insert(std::make_pair(latestMsgId, latestMeta)); + } + } + else if (onlyAllVersions) + { + for(vit_meta = metaV.begin(); vit_meta != metaV.end(); vit_meta++) + { + RsGxsMsgMetaData* meta = *vit_meta; + + if (meta->mOrigMsgId == origMsgId) + { + outMsgIds.push_back(meta->mMsgId); + metaMap.insert(std::make_pair(meta->mOrigMsgId, meta)); + } + } + } + + req->mMsgIdResult[grpId] = outMsgIds; + filterMsgList(req->mMsgIdResult, opts, filterMap); + + cleanseMsgMetaMap(result); + + return true; +} + bool RsGxsDataAccess::getMsgList(MsgIdReq* req) { GxsMsgMetaResult result; - mDataStore->retrieveGxsMsgMetaData(req->mMsgIds, result); @@ -931,6 +1189,13 @@ bool RsGxsDataAccess::getMsgList(MsgIdReq* req) delete meta; // discard meta data mem } } + + GxsMsgReq msgIdOut; + + // filter based on options + getMsgList(req->mMsgIdResult, req->Options, msgIdOut); + req->mMsgIdResult = msgIdOut; + return true; } @@ -1116,7 +1381,7 @@ bool RsGxsDataAccess::disposeOfPublicToken(const uint32_t& token) bool RsGxsDataAccess::checkMsgFilter(const RsTokReqOptionsV2& opts, const RsGxsMsgMetaData* meta) const { bool statusMatch = false; - if (opts.mStatusMask) + if (opts.mStatusMask) { // Exact Flags match required. if ((opts.mStatusMask & opts.mStatusFilter) == (opts.mStatusMask & meta->mMsgStatus)) @@ -1141,5 +1406,33 @@ bool RsGxsDataAccess::checkMsgFilter(const RsTokReqOptionsV2& opts, const RsGxsM // no status comparision, statusMatch = true; } - return statusMatch; + + bool flagMatch = false; + + if(opts.mMsgFlagMask) + { + // Exact Flags match required. + if ((opts.mMsgFlagMask & opts.mMsgFlagFilter) == (opts.mMsgFlagMask & meta->mMsgFlags)) + { + std::cerr << "checkMsgFilter() Accepting Msg as FlagMatches: "; + std::cerr << " Mask: " << opts.mMsgFlagMask << " FlagFilter: " << opts.mMsgFlagFilter; + std::cerr << " MsgFlag: " << meta->mMsgFlags << " MsgId: " << meta->mMsgId; + std::cerr << std::endl; + + flagMatch = true; + } + else + { + std::cerr << "checkMsgFilter() Dropping Msg due to !FlagMatch "; + std::cerr << " Mask: " << opts.mMsgFlagMask << " FlagFilter: " << opts.mMsgFlagFilter; + std::cerr << " MsgFlag: " << meta->mMsgFlags << " MsgId: " << meta->mMsgId; + std::cerr << std::endl; + + flagMatch = false; + } + }else{ + flagMatch = true; + } + + return statusMatch && flagMatch; } diff --git a/libretroshare/src/gxs/rsgxsdataaccess.h b/libretroshare/src/gxs/rsgxsdataaccess.h index c1261ff55..575fc3426 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.h +++ b/libretroshare/src/gxs/rsgxsdataaccess.h @@ -90,7 +90,7 @@ public: * @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs * @return true if request successful false otherwise */ - bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq& msgIds); + bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const RsGxsGrpMsgIdPair &msgIds); /* Poll */ uint32_t requestStatus(const uint32_t token); @@ -343,6 +343,15 @@ private: */ bool checkMsgFilter(const RsTokReqOptionsV2& opts, const RsGxsMsgMetaData* meta) const; + /*! + * This is a filter method which applies the request options to the list of ids + * requested + * @param msgIds the msg ids for filter to be applied to + * @param opts the options used to parameterise the id filter + * @param msgIdsOut the left overs ids after filter is applied to msgIds + */ + bool getMsgList(const GxsMsgReq& msgIds, const RsTokReqOptionsV2& opts, GxsMsgReq msgIdsOut); + private: RsGeneralDataService* mDataStore; diff --git a/libretroshare/src/gxs/rsgxsrequesttypes.h b/libretroshare/src/gxs/rsgxsrequesttypes.h index 5536a4d6d..b270e1ed5 100644 --- a/libretroshare/src/gxs/rsgxsrequesttypes.h +++ b/libretroshare/src/gxs/rsgxsrequesttypes.h @@ -99,7 +99,7 @@ class MsgRelatedInfoReq : public GxsRequest { public: - GxsMsgReq mMsgIds; + RsGxsGrpMsgIdPair mMsgId; GxsMsgIdResult mMsgIdResult; }; diff --git a/libretroshare/src/gxs/rstokenservice.h b/libretroshare/src/gxs/rstokenservice.h index 408c93dd0..ced417734 100644 --- a/libretroshare/src/gxs/rstokenservice.h +++ b/libretroshare/src/gxs/rstokenservice.h @@ -168,7 +168,7 @@ public: * @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs * @return true if request successful false otherwise */ - virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq& msgIds) = 0; + virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const RsGxsGrpMsgIdPair& msgIds) = 0; /* Poll */ diff --git a/libretroshare/src/serialiser/rsphotov2items.cc b/libretroshare/src/serialiser/rsphotov2items.cc index 9320eaf8d..559253e59 100644 --- a/libretroshare/src/serialiser/rsphotov2items.cc +++ b/libretroshare/src/serialiser/rsphotov2items.cc @@ -23,10 +23,11 @@ * */ +#include #include "rsphotov2items.h" #include "serialiser/rstlvbase.h" -#include +#include "serialiser/rsbaseserial.h" #define GXS_PHOTO_SERIAL_DEBUG @@ -35,6 +36,7 @@ uint32_t RsGxsPhotoSerialiser::size(RsItem* item) { RsGxsPhotoPhotoItem* ppItem = NULL; RsGxsPhotoAlbumItem* paItem = NULL; + RsGxsPhotoCommentItem* cItem = NULL; if((ppItem = dynamic_cast(item)) != NULL) { @@ -44,6 +46,10 @@ uint32_t RsGxsPhotoSerialiser::size(RsItem* item) { return sizeGxsPhotoAlbumItem(paItem); } + else if((cItem = dynamic_cast(item)) != NULL) + { + return sizeGxsPhotoCommentItem(cItem); + } else { #ifdef GXS_PHOTO_SERIAL_DEBUG @@ -57,24 +63,28 @@ uint32_t RsGxsPhotoSerialiser::size(RsItem* item) bool RsGxsPhotoSerialiser::serialise(RsItem* item, void* data, uint32_t* size) { - RsGxsPhotoPhotoItem* ppItem = NULL; - RsGxsPhotoAlbumItem* paItem = NULL; + RsGxsPhotoPhotoItem* ppItem = NULL; + RsGxsPhotoAlbumItem* paItem = NULL; + RsGxsPhotoCommentItem* cItem = NULL; - if((ppItem = dynamic_cast(item)) != NULL) - { - return serialiseGxsPhotoPhotoItem(ppItem, data, size); - } - else if((paItem = dynamic_cast(item)) != NULL) - { - return serialiseGxsPhotoAlbumItem(paItem, data, size); - } - else - { + if((ppItem = dynamic_cast(item)) != NULL) + { + return serialiseGxsPhotoPhotoItem(ppItem, data, size); + } + else if((paItem = dynamic_cast(item)) != NULL) + { + return serialiseGxsPhotoAlbumItem(paItem, data, size); + }else if((cItem = dynamic_cast(item)) != NULL) + { + return serialiseGxsPhotoCommentItem(cItem, data, size); + } + else + { #ifdef GXS_PHOTO_SERIAL_DEBUG #endif - return false; - } + return false; + } } @@ -100,11 +110,13 @@ RsItem* RsGxsPhotoSerialiser::deserialise(void* data, uint32_t* size) return deserialiseGxsPhotoPhotoItem(data, size); case RS_PKT_SUBTYPE_PHOTO_ITEM: return deserialiseGxsPhotoAlbumItem(data, size); + case RS_PKT_SUBTYPE_PHOTO_COMMENT_ITEM: + return deserialiseGxsPhotoCommentItem(data, size); default: { #ifdef GXS_PHOTO_SERIAL_DEBUG std::cerr << "RsGxsPhotoSerialiser::deserialise(): subtype could not be dealt with" - << std::endl; + << std::endl; #endif break; } @@ -136,6 +148,19 @@ uint32_t RsGxsPhotoSerialiser::sizeGxsPhotoAlbumItem(RsGxsPhotoAlbumItem* item) return s; } +uint32_t RsGxsPhotoSerialiser::sizeGxsPhotoCommentItem(RsGxsPhotoCommentItem *item) +{ + + const RsPhotoComment& comment = item->comment; + uint32_t s = 8; // header + + s += GetTlvStringSize(comment.mComment); + s += 4; // mflags + + return s; + +} + bool RsGxsPhotoSerialiser::serialiseGxsPhotoAlbumItem(RsGxsPhotoAlbumItem* item, void* data, uint32_t* size) { @@ -443,19 +468,123 @@ RsGxsPhotoPhotoItem* RsGxsPhotoSerialiser::deserialiseGxsPhotoPhotoItem(void* da return item; } -uint32_t RsGxsPhotoSerialiser::sizeGxsPhotoCommentItem(RsGxsPhotoCommentItem *item) -{ -} bool RsGxsPhotoSerialiser::serialiseGxsPhotoCommentItem (RsGxsPhotoCommentItem *item, void *data, uint32_t *size) { - return false; + + +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::serialiseGxsPhotoCommentItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsPhotoCommentItem(item); + uint32_t offset = 0; + + if(*size < tlvsize){ +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::serialiseGxsPhotoCommentItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsPhotoAlbumItem */ + + ok &= SetTlvString(data, tlvsize, &offset, 0, item->comment.mComment); + ok &= setRawUInt32(data, tlvsize, &offset, item->comment.mCommentFlag); + + if(offset != tlvsize) + { +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::serialiseGxsPhotoCommentItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef GXS_PHOTO_SERIAL_DEBUG + if (!ok) + { + std::cerr << "RsGxsPhotoSerialiser::serialiseGxsPhotoCommentItem() NOK" << std::endl; + } +#endif + + return ok; } RsGxsPhotoCommentItem * RsGxsPhotoSerialiser::deserialiseGxsPhotoCommentItem(void *data, uint32_t *size) { - return NULL; + + +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::deserialiseGxsPhotoPhotoItem()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_PHOTO != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_PHOTO_COMMENT_ITEM != getRsItemSubType(rstype))) + { +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::deserialiseGxsPhotoCommentItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::deserialiseGxsPhotoCommentItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsPhotoCommentItem* item = new RsGxsPhotoCommentItem(); + + /* skip the header */ + offset += 8; + + ok &= GetTlvString(data, rssize, &offset, 1, item->comment.mComment); + ok &= getRawUInt32(data, rssize, &offset, &(item->comment.mCommentFlag)); + + if (offset != rssize) + { +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::deserialiseGxsPhotoCommentItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef GXS_PHOTO_SERIAL_DEBUG + std::cerr << "RsGxsPhotoSerialiser::deserialiseGxsPhotoCommentItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; } void RsGxsPhotoAlbumItem::clear() @@ -474,12 +603,17 @@ void RsGxsPhotoAlbumItem::clear() void RsGxsPhotoCommentItem::clear() { - - + comment.mComment.clear(); + comment.mCommentFlag = 0; } std::ostream& RsGxsPhotoCommentItem::print(std::ostream& out, uint16_t indent) { + printRsItemBase(out, "RsGxsPhotoCommentItem", indent); + uint16_t int_Indent = indent + 2; + + + printRsItemEnd(out ,"RsGxsPhotoCommentItem", indent); return out; } @@ -488,6 +622,7 @@ std::ostream& RsGxsPhotoAlbumItem::print(std::ostream& out, uint16_t indent) printRsItemBase(out, "RsGxsPhotoAlbumItem", indent); uint16_t int_Indent = indent + 2; + out << album << std::endl; printRsItemEnd(out ,"RsGxsPhotoAlbumItem", indent); return out; diff --git a/libretroshare/src/tests/gxs/genexchangetester.cpp b/libretroshare/src/tests/gxs/genexchangetester.cpp index 5f41f2022..b63f1475b 100644 --- a/libretroshare/src/tests/gxs/genexchangetester.cpp +++ b/libretroshare/src/tests/gxs/genexchangetester.cpp @@ -827,7 +827,7 @@ bool GenExchangeTester::testSpecificMsgMetaRetrieval() return ok; } -bool GenExchangeTester::testRelatedMsgIdRetrieval_Parents() +bool GenExchangeTester::testMsgIdRetrieval_OptParents() { // start up setUp(); @@ -884,7 +884,7 @@ bool GenExchangeTester::testRelatedMsgIdRetrieval_Parents() opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; opts.mOptions = RS_TOKREQOPT_MSG_THREAD; - mTokenService->requestMsgRelatedInfo(token, 0, opts, req); + mTokenService->requestMsgInfo(token, 0, opts, req); pollForToken(token, opts); @@ -925,7 +925,7 @@ bool GenExchangeTester::testRelatedMsgIdRetrieval_Parents() } -bool GenExchangeTester::testRelatedMsgIdRetrieval_OrigMsgId() +bool GenExchangeTester::testMsgIdRetrieval_OptOrigMsgId() { // start up setUp(); @@ -981,7 +981,7 @@ bool GenExchangeTester::testRelatedMsgIdRetrieval_OrigMsgId() opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; opts.mOptions = RS_TOKREQOPT_MSG_ORIGMSG; - mTokenService->requestMsgRelatedInfo(token, 0, opts, req); + mTokenService->requestMsgInfo(token, 0, opts, req); pollForToken(token, opts); @@ -1022,7 +1022,7 @@ bool GenExchangeTester::testRelatedMsgIdRetrieval_OrigMsgId() } -bool GenExchangeTester::testRelatedMsgIdRetrieval_Latest() +bool GenExchangeTester::testMsgIdRetrieval_OptLatest() { // testing for latest, create msg which are origMsgIds then @@ -1189,7 +1189,7 @@ bool GenExchangeTester::testRelatedMsgIdRetrieval_Latest() opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - mTokenService->requestMsgRelatedInfo(token, 0, opts, req); + mTokenService->requestMsgInfo(token, 0, opts, req); pollForToken(token, opts); diff --git a/libretroshare/src/tests/gxs/genexchangetester.h b/libretroshare/src/tests/gxs/genexchangetester.h index 63619bc12..67be18ed3 100644 --- a/libretroshare/src/tests/gxs/genexchangetester.h +++ b/libretroshare/src/tests/gxs/genexchangetester.h @@ -27,9 +27,9 @@ public: bool testMsgSubmissionRetrieval(); bool testMsgIdRetrieval(); - bool testRelatedMsgIdRetrieval_Parents(); - bool testRelatedMsgIdRetrieval_OrigMsgId(); - bool testRelatedMsgIdRetrieval_Latest(); + bool testMsgIdRetrieval_OptParents(); + bool testMsgIdRetrieval_OptOrigMsgId(); + bool testMsgIdRetrieval_OptLatest(); bool testSpecificMsgMetaRetrieval(); bool testGrpSubmissionRetrieval(); diff --git a/libretroshare/src/tests/gxs/nxs_tests.pro b/libretroshare/src/tests/gxs/nxs_tests.pro new file mode 100644 index 000000000..8ceaba0f0 --- /dev/null +++ b/libretroshare/src/tests/gxs/nxs_tests.pro @@ -0,0 +1,123 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2012-05-06T09:19:26 +# +#------------------------------------------------- + + +# +QT += core network + +QT -= gui + +CONFIG += gen_exchange_target #dstore_target + +dstore_target { + +TARGET = rs_dstore_test + +} + +gen_exchange_target { + +TARGET = gen_exchange_test + +} + +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +CONFIG += debug + +debug { +# DEFINES *= DEBUG +# DEFINES *= OPENDHT_DEBUG DHT_DEBUG CONN_DEBUG DEBUG_UDP_SORTER P3DISC_DEBUG DEBUG_UDP_LAYER FT_DEBUG EXTADDRSEARCH_DEBUG +# DEFINES *= CONTROL_DEBUG FT_DEBUG DEBUG_FTCHUNK P3TURTLE_DEBUG +# DEFINES *= P3TURTLE_DEBUG +# DEFINES *= NET_DEBUG +# DEFINES *= DISTRIB_DEBUG +# DEFINES *= P3TURTLE_DEBUG FT_DEBUG DEBUG_FTCHUNK MPLEX_DEBUG +# DEFINES *= STATUS_DEBUG SERV_DEBUG RSSERIAL_DEBUG #CONN_DEBUG + + QMAKE_CXXFLAGS -= -O2 -fomit-frame-pointer + QMAKE_CXXFLAGS *= -g -fno-omit-frame-pointer +} +################################# Linux ########################################## +# Put lib dir in QMAKE_LFLAGS so it appears before -L/usr/lib +linux-* { + #CONFIG += version_detail_bash_script + QMAKE_CXXFLAGS *= -D_FILE_OFFSET_BITS=64 + + system(which gpgme-config >/dev/null 2>&1) { + INCLUDEPATH += $$system(gpgme-config --cflags | sed -e "s/-I//g") + } else { + message(Could not find gpgme-config on your system, assuming gpgme.h is in /usr/include) + } + + PRE_TARGETDEPS *= ../../lib/libretroshare.a + + LIBS += ../../lib/libretroshare.a + LIBS += ../../../../libbitdht/src/lib/libbitdht.a + LIBS += ../../../../openpgpsdk/src/lib/libops.a + LIBS += -lssl -lgpgme -lupnp -lixml -lgnome-keyring -lsqlite3 -lbz2 + LIBS *= -rdynamic -frtti + DEFINES *= HAVE_XSS # for idle time, libx screensaver extensions + DEFINES *= UBUNTU +} + +linux-g++ { + OBJECTS_DIR = temp/linux-g++/obj +} + +linux-g++-64 { + OBJECTS_DIR = temp/linux-g++-64/obj +} + +version_detail_bash_script { + DEFINES += ADD_LIBRETROSHARE_VERSION_INFO + QMAKE_EXTRA_TARGETS += write_version_detail + PRE_TARGETDEPS = write_version_detail + write_version_detail.commands = ./version_detail.sh +} + +install_rs { + INSTALLS += binary_rs + binary_rs.path = $$(PREFIX)/usr/bin + binary_rs.files = ./RetroShare +} + +dstore_target { + + SOURCES += \ + support.cc \ + rsdataservice_test.cc \ + data_support.cc + + HEADERS += support.h \ + rsdataservice_test.h \ + data_support.h + + +} + + +gen_exchange_target { + + SOURCES += \ + support.cc \ + genexchangetester.cpp \ + genexchangetestservice.cpp \ + rsdummyservices.cc \ + rsgenexchange_test.cc + + HEADERS += support.h \ + rsdataservice_test.h \ + rsdummyservices.h \ + data_support.h + + +} + +INCLUDEPATH += ../../ \ No newline at end of file diff --git a/libretroshare/src/tests/gxs/rsgenexchange_test.cc b/libretroshare/src/tests/gxs/rsgenexchange_test.cc index 4ae8adb3c..2a1bc4537 100644 --- a/libretroshare/src/tests/gxs/rsgenexchange_test.cc +++ b/libretroshare/src/tests/gxs/rsgenexchange_test.cc @@ -15,17 +15,17 @@ int main() GenExchangeTester tester; CHECK(tester.testMsgSubmissionRetrieval()); REPORT("testMsgSubmissionRetrieval()"); - CHECK(tester.testSpecificMsgMetaRetrieval()); REPORT("testSpecificMsgMetaRetrieval()"); - CHECK(tester.testMsgIdRetrieval()); REPORT("tester.testMsgIdRetrieval()"); - CHECK(tester.testRelatedMsgIdRetrieval_Parents()); REPORT("tester.testRelatedMsgIdRetrieval_Parents()"); - CHECK(tester.testRelatedMsgIdRetrieval_OrigMsgId()); REPORT("tester.testRelatedMsgIdRetrieval_OrigMsgId()"); - CHECK(tester.testRelatedMsgIdRetrieval_Latest()); REPORT("tester.testRelatedMsgIdRetrieval_Latest()"); - CHECK(tester.testMsgMetaModRequest()); REPORT("tester.testMsgMetaModRequest()"); +// CHECK(tester.testSpecificMsgMetaRetrieval()); REPORT("testSpecificMsgMetaRetrieval()"); +// CHECK(tester.testMsgIdRetrieval()); REPORT("tester.testMsgIdRetrieval()"); +// CHECK(tester.testMsgIdRetrieval_OptParents()); REPORT("tester.testRelatedMsgIdRetrieval_Parents()"); +// CHECK(tester.testMsgIdRetrieval_OptOrigMsgId()); REPORT("tester.testRelatedMsgIdRetrieval_OrigMsgId()"); +// CHECK(tester.testMsgIdRetrieval_OptLatest()); REPORT("tester.testRelatedMsgIdRetrieval_Latest()"); +// CHECK(tester.testMsgMetaModRequest()); REPORT("tester.testMsgMetaModRequest()"); - CHECK(tester.testGrpSubmissionRetrieval()); REPORT("tester.testGrpSubmissionRetrieval()"); - CHECK(tester.testGrpMetaRetrieval()); REPORT("tester.testGrpMetaRetrieval()"); - CHECK(tester.testGrpIdRetrieval()); REPORT("tester.testGrpIdRetrieval()"); - CHECK(tester.testGrpMetaModRequest()); REPORT("tester.testGrpMetaModRequest()"); +// CHECK(tester.testGrpSubmissionRetrieval()); REPORT("tester.testGrpSubmissionRetrieval()"); +// CHECK(tester.testGrpMetaRetrieval()); REPORT("tester.testGrpMetaRetrieval()"); +// CHECK(tester.testGrpIdRetrieval()); REPORT("tester.testGrpIdRetrieval()"); +// CHECK(tester.testGrpMetaModRequest()); REPORT("tester.testGrpMetaModRequest()"); FINALREPORT("RsGenExchangeTest"); From 1aeae0390ad55cd415f9e69963610332a611caa2 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Thu, 20 Sep 2012 21:09:23 +0000 Subject: [PATCH 067/222] Added test for child msg retrieval ui improvement for comments git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5577 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgxsdataaccess.cc | 4 +- libretroshare/src/gxs/rsgxsdataaccess.h | 2 +- .../src/tests/gxs/genexchangetester.cpp | 124 +++++++++++++++++- .../src/tests/gxs/genexchangetester.h | 3 + libretroshare/src/tests/gxs/nxs_tests.pro | 69 +++++++++- .../src/tests/gxs/rsgenexchange_test.cc | 9 +- .../src/gui/PhotoShare/PhotoCommentItem.ui | 67 +++++++++- 7 files changed, 257 insertions(+), 21 deletions(-) diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index 7e6c89265..552c961dc 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -752,7 +752,7 @@ bool RsGxsDataAccess::getMsgSummary(MsgMetaReq* req) } -bool RsGxsDataAccess::getMsgList(const GxsMsgReq& msgIds, const RsTokReqOptionsV2& opts, GxsMsgReq msgIdsOut) +bool RsGxsDataAccess::getMsgList(const GxsMsgReq& msgIds, const RsTokReqOptionsV2& opts, GxsMsgReq& msgIdsOut) { GxsMsgMetaResult result; @@ -1009,8 +1009,6 @@ bool RsGxsDataAccess::getMsgRelatedInfo(MsgRelatedInfoReq *req) MsgMetaFilter filterMap; - RsStackMutex stack(mDataMutex); /***** LOCKED *****/ - // get meta data for all in group GxsMsgMetaResult result; GxsMsgReq msgIds; diff --git a/libretroshare/src/gxs/rsgxsdataaccess.h b/libretroshare/src/gxs/rsgxsdataaccess.h index 575fc3426..04911bf65 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.h +++ b/libretroshare/src/gxs/rsgxsdataaccess.h @@ -350,7 +350,7 @@ private: * @param opts the options used to parameterise the id filter * @param msgIdsOut the left overs ids after filter is applied to msgIds */ - bool getMsgList(const GxsMsgReq& msgIds, const RsTokReqOptionsV2& opts, GxsMsgReq msgIdsOut); + bool getMsgList(const GxsMsgReq& msgIds, const RsTokReqOptionsV2& opts, GxsMsgReq& msgIdsOut); private: diff --git a/libretroshare/src/tests/gxs/genexchangetester.cpp b/libretroshare/src/tests/gxs/genexchangetester.cpp index b63f1475b..88bbf39ae 100644 --- a/libretroshare/src/tests/gxs/genexchangetester.cpp +++ b/libretroshare/src/tests/gxs/genexchangetester.cpp @@ -725,6 +725,118 @@ bool GenExchangeTester::testMsgIdRetrieval() return true; } +bool GenExchangeTester::testMsgChildRetrieval() +{ + // start up + setUp(); + setUpGrps(); + + /********************/ + + + // create msgs + // then make all requests immediately then poll afterwards for each and run outbound test + // we want only latest for now + int nMsgs = (rand()%50)+2; // test a large number of msgs + std::vector msgs; + createMsgs(msgs, nMsgs); + RsTokReqOptionsV2 opts; + opts.mReqType = 4000; + uint32_t token; + + bool first = true; + RsGxsGrpMsgIdPair firstMsgId; + + // everyone is parent of first msg + + for(int i=0; i < nMsgs; i++) + { + RsDummyMsg* msg = msgs[i]; + + int j = rand()%5; + + + if(first){ + msg->meta.mParentId = ""; + msg->meta.mOrigMsgId = ""; + } + else + { + msg->meta.mParentId = firstMsgId.second; + msg->meta.mGroupId = firstMsgId.first; + msg->meta.mOrigMsgId = ""; + } + + mTestService->publishDummyMsg(token, msg); + pollForToken(token, opts); + RsGxsGrpMsgIdPair msgId; + mTestService->acknowledgeTokenMsg(token, msgId); + + // less than half have no parents + if(first){ + firstMsgId.second = msgId.second; + firstMsgId.first = msgId.first; + + } + + if(msgId.first.empty() || msgId.second.empty()) + { + breakDown(); + std::cerr << "serious error: Acknowledgement failed! " << std::endl; + return false; + } + + if(!first) + { + mMsgIdsOut[msgId.first].push_back(msgId.second); + first = false; + } + + } + + + opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; + opts.mOptions = RS_TOKREQOPT_MSG_PARENT | RS_TOKREQOPT_MSG_LATEST; + mTokenService->requestMsgRelatedInfo(token, 0, opts, firstMsgId); + + pollForToken(token, opts); + + GxsMsgIdResult::iterator mit = mMsgIdsOut.begin(); + for(; mit != mMsgIdsOut.end(); mit++) + { + std::vector msgIdsOut, msgIdsIn; + msgIdsOut = mit->second; + + std::vector::iterator vit_out = msgIdsOut.begin(), vit_in; + + for(; vit_out != msgIdsOut.end(); vit_out++) + { + bool found = false; + msgIdsIn = mMsgIdsIn[mit->first]; + vit_in = msgIdsIn.begin(); + + for(; vit_in != msgIdsIn.end(); vit_in++) + { + if(*vit_in == *vit_out) + found = true; + } + + if(!found){ + breakDown(); + return false; + } + + } + } + + /********************/ + + // complete + breakDown(); + + return true; +} + bool GenExchangeTester::testSpecificMsgMetaRetrieval() { @@ -874,12 +986,12 @@ bool GenExchangeTester::testMsgIdRetrieval_OptParents() } - GxsMsgReq req; + std::list req; // use empty grp ids request types, non specific msgs ids for(int i=0; i < mRandGrpIds.size(); i++) { - req[mRandGrpIds[i]] = std::vector(); + req.push_back(mRandGrpIds[i]); } opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; @@ -971,12 +1083,12 @@ bool GenExchangeTester::testMsgIdRetrieval_OptOrigMsgId() } - GxsMsgReq req; + std::list req; // use empty grp ids request types, non specific msgs ids for(int i=0; i < mRandGrpIds.size(); i++) { - req[mRandGrpIds[i]] = std::vector(); + req.push_back(mRandGrpIds[i]); } opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; @@ -1181,10 +1293,10 @@ bool GenExchangeTester::testMsgIdRetrieval_OptLatest() // use empty grp ids request types, non specific msgs ids - GxsMsgReq req; + std::list req; for(int i=0; i < mRandGrpIds.size(); i++) { - req[mRandGrpIds[i]] = std::vector(); + req.push_back(mRandGrpIds[i]); } opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; diff --git a/libretroshare/src/tests/gxs/genexchangetester.h b/libretroshare/src/tests/gxs/genexchangetester.h index 67be18ed3..83f6150e6 100644 --- a/libretroshare/src/tests/gxs/genexchangetester.h +++ b/libretroshare/src/tests/gxs/genexchangetester.h @@ -32,6 +32,9 @@ public: bool testMsgIdRetrieval_OptLatest(); bool testSpecificMsgMetaRetrieval(); + bool testMsgChildRetrieval(); + + bool testGrpSubmissionRetrieval(); bool testSpecificGrpRetrieval(); bool testGrpIdRetrieval(); diff --git a/libretroshare/src/tests/gxs/nxs_tests.pro b/libretroshare/src/tests/gxs/nxs_tests.pro index 8ceaba0f0..977c90e2c 100644 --- a/libretroshare/src/tests/gxs/nxs_tests.pro +++ b/libretroshare/src/tests/gxs/nxs_tests.pro @@ -75,6 +75,73 @@ linux-g++-64 { OBJECTS_DIR = temp/linux-g++-64/obj } +#################################### Windows ##################################### + +win32 { + + DEFINES *= WINDOWS_SYS \ + WIN32 \ + STATICLIB \ + MINGW + # Switch on extra warnings + QMAKE_CFLAGS += -Wextra + QMAKE_CXXFLAGS += -Wextra + + # Switch off optimization for release version + QMAKE_CXXFLAGS_RELEASE -= -O2 + QMAKE_CXXFLAGS_RELEASE += -O0 + QMAKE_CFLAGS_RELEASE -= -O2 + QMAKE_CFLAGS_RELEASE += -O0 + + # Switch on optimization for debug version + #QMAKE_CXXFLAGS_DEBUG += -O2 + #QMAKE_CFLAGS_DEBUG += -O2 + +# PRE_TARGETDEPS += ../../libretroshare/src/lib/libretroshare.a + PRE_TARGETDEPS += ../../../../libretroshare/libretroshare-build-desktop/lib/libretroshare.a + + LIBS += ../../../../libretroshare/libretroshare-build-desktop/lib/libretroshare.a + LIBS += C:\Development\Rs\v0.5-gxs-b1\openpgpsdk\openpgpsdk-build-desktop\lib\libops.a + LIBS += C:\Development\Libraries\sqlite\sqlite-autoconf-3070900\lib\libsqlite3.a + LIBS += -L"../../../../../lib" + LIBS += -lssl -lcrypto -lgpgme -lpthreadGC2d -lminiupnpc -lz -lbz2 +# added after bitdht +# LIBS += -lws2_32 + LIBS += -luuid -lole32 -liphlpapi -lcrypt32-cygwin -lgdi32 + LIBS += -lole32 -lwinmm + + # export symbols for the plugins + #LIBS += -Wl,--export-all-symbols,--out-implib,lib/libretroshare-gui.a + + GPG_ERROR_DIR = ../../../../libgpg-error-1.7 + GPGME_DIR = ../../../../gpgme-1.1.8 + GPG_ERROR_DIR = ../../../../lib/libgpg-error-1.7 + GPGME_DIR = ../../../../lib/gpgme-1.1.8 + INCLUDEPATH += . $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src + + SQLITE_DIR = ../../../../../../Libraries/sqlite/sqlite-autoconf-3070900 + INCLUDEPATH += . \ + $${SQLITE_DIR} + + + + +} + +bitdht { + LIBS += C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a + PRE_TARGETDEPS *= C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a + + # Chris version. + #LIBS += ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a + #PRE_TARGETDEPS *= ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a +} + +win32 { +# must be added after bitdht + LIBS += -lws2_32 +} + version_detail_bash_script { DEFINES += ADD_LIBRETROSHARE_VERSION_INFO QMAKE_EXTRA_TARGETS += write_version_detail @@ -120,4 +187,4 @@ gen_exchange_target { } -INCLUDEPATH += ../../ \ No newline at end of file +INCLUDEPATH += ../../ diff --git a/libretroshare/src/tests/gxs/rsgenexchange_test.cc b/libretroshare/src/tests/gxs/rsgenexchange_test.cc index 2a1bc4537..c60c2eb96 100644 --- a/libretroshare/src/tests/gxs/rsgenexchange_test.cc +++ b/libretroshare/src/tests/gxs/rsgenexchange_test.cc @@ -14,13 +14,14 @@ int main() { GenExchangeTester tester; - CHECK(tester.testMsgSubmissionRetrieval()); REPORT("testMsgSubmissionRetrieval()"); +// CHECK(tester.testMsgSubmissionRetrieval()); REPORT("testMsgSubmissionRetrieval()"); // CHECK(tester.testSpecificMsgMetaRetrieval()); REPORT("testSpecificMsgMetaRetrieval()"); -// CHECK(tester.testMsgIdRetrieval()); REPORT("tester.testMsgIdRetrieval()"); -// CHECK(tester.testMsgIdRetrieval_OptParents()); REPORT("tester.testRelatedMsgIdRetrieval_Parents()"); +// CHECK(tester.testMsgIdRetrieval()); REPORT("tester.testMsgIdRetrieval()"); + //CHECK(tester.testMsgIdRetrieval_OptParents()); REPORT("tester.testRelatedMsgIdRetrieval_Parents()"); // CHECK(tester.testMsgIdRetrieval_OptOrigMsgId()); REPORT("tester.testRelatedMsgIdRetrieval_OrigMsgId()"); // CHECK(tester.testMsgIdRetrieval_OptLatest()); REPORT("tester.testRelatedMsgIdRetrieval_Latest()"); -// CHECK(tester.testMsgMetaModRequest()); REPORT("tester.testMsgMetaModRequest()"); + //CHECK(tester.testMsgMetaModRequest()); REPORT("tester.testMsgMetaModRequest()"); + CHECK(tester.testMsgChildRetrieval()); REPORT("tester.testMsgMetaModRequest()"); // CHECK(tester.testGrpSubmissionRetrieval()); REPORT("tester.testGrpSubmissionRetrieval()"); // CHECK(tester.testGrpMetaRetrieval()); REPORT("tester.testGrpMetaRetrieval()"); diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui index a0a27b3d1..78b7f8415 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui @@ -1,21 +1,76 @@ + - - - PhotoCommentItem 0 0 - 400 - 300 + 484 + 110 Form + + + + + QFrame#expandFrame{border: 2px solid #D3D3D3; +background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, +stop:0 #FFFFFF, stop:1 #F2F2F2);; +border-radius: 10px;} + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + QWidget#msgWidget{border: 2px solid #238; +border-radius: 10px;} + + + + 5 + + + + + + 0 + 0 + + + + + PreferAntialias + + + + true + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + - + From 51362f7baca4c6363d8318bbce0a10c5e9a850e1 Mon Sep 17 00:00:00 2001 From: drbob Date: Fri, 21 Sep 2012 23:15:26 +0000 Subject: [PATCH 068/222] restored back to svn 5549, before chris changed random stuff... how / why? git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5581 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/menu/menus.cc | 17 +- retroshare-nogui/src/notifytxt.cc | 40 +- retroshare-nogui/src/retroshare.cc | 2 +- .../src/rpc/proto/gencc/core.pb.cc | 206 ++----- .../src/rpc/proto/gencc/system.pb.cc | 515 +++++++++++++++++- .../src/rpc/proto/rpcprotosystem.cc | 73 +++ retroshare-nogui/src/rpc/rpc.cc | 5 + retroshare-nogui/src/rpc/rpcserver.cc | 5 + retroshare-nogui/src/rpc/rpcsetup.cc | 10 +- 9 files changed, 701 insertions(+), 172 deletions(-) diff --git a/retroshare-nogui/src/menu/menus.cc b/retroshare-nogui/src/menu/menus.cc index fc3b95105..46e044aa6 100644 --- a/retroshare-nogui/src/menu/menus.cc +++ b/retroshare-nogui/src/menu/menus.cc @@ -84,7 +84,7 @@ Menu *CreateMenuStructure(NotifyTxt *notify) MenuList *search = new MenuListSearch(notify); MenuList *searchlist = new MenuListSearchList(notify); - search->addMenuItem(MENU_SEARCH_KEY_ADD, new MenuOpSearchNew()); + search->addMenuItem(MENU_SEARCH_KEY_ADD, new MenuOpSearchNew(notify)); //search->addMenuItem(MENU_SEARCH_KEY_REMOVE, new MenuOpSearchDelete()); search->addMenuItem(MENU_SEARCH_KEY_VIEW, searchlist); searchlist->addMenuItem(MENU_SEARCH_KEY_DOWNLOAD, new MenuOpSearchListDownload()); @@ -362,11 +362,17 @@ int MenuListSearch::removeSearch(std::string strSearchId) it = mSearchIds.find(strSearchId); if (it != mSearchIds.end()) { - /* cleanup local maps */ /* cancel search */ + // CAN'T DO!!! /* clear results from Notify Collector */ + mNotify->clearSearchId(it->second); + + /* cleanup local maps */ + mSearchIds.erase(it); + + /* cleanup terms maps (TODO) */ } return 1; @@ -392,6 +398,7 @@ uint32_t MenuOpSearchNew::process_lines(std::string input) std::string search = input.substr(0, input.size() - 1); // remove \n. uint32_t searchId = (uint32_t) rsTurtle->turtleSearch(search); + mNotify->collectSearchResults(searchId); /* store request in parent */ MenuListSearch *ms = dynamic_cast(parent()); @@ -645,7 +652,7 @@ int MenuListShared::getEntryDesc(int idx, std::string &desc) rsFiles->getSharedDirectories(dirs); std::list::iterator it; std::string shareflag; - unsigned int i=0; + int i=0; for (it = dirs.begin(); (i < idx) && (it != dirs.end()); it++, i++); if (it != dirs.end()) { @@ -675,7 +682,7 @@ int MenuListShared::unshareSelected() std::list dirs; rsFiles->getSharedDirectories(dirs); std::list::iterator it; - unsigned int i=0; + int i=0; for (it = dirs.begin(); (i < mSelectIdx) && (it != dirs.end()); it++, i++); if (it != dirs.end()) { @@ -696,7 +703,7 @@ int MenuListShared::toggleFlagSelected(uint32_t shareflags) std::list dirs; rsFiles->getSharedDirectories(dirs); std::list::iterator it; - unsigned int i=0; + int i=0; for (it = dirs.begin(); (i < mSelectIdx) && (it != dirs.end()); it++, i++); if (it != dirs.end()) { diff --git a/retroshare-nogui/src/notifytxt.cc b/retroshare-nogui/src/notifytxt.cc index 9bc01d1a4..9995d3ba3 100644 --- a/retroshare-nogui/src/notifytxt.cc +++ b/retroshare-nogui/src/notifytxt.cc @@ -230,8 +230,15 @@ void NotifyTxt::notifyTurtleSearchResult(uint32_t search_id,const std::listsecond.size(); } - -int NotifyTxt::clearSearchId(uint32_t searchId) + // only collect results for selected searches. + // will drop others. +int NotifyTxt::collectSearchResults(uint32_t searchId) { + std::cerr << "NotifyTxt::collectSearchResult(" << searchId << ")"; + std::cerr << std::endl; + RsStackMutex stack(mNotifyMtx); /****** LOCKED *****/ std::map >::iterator it; it = mSearchResults.find(searchId); if (it == mSearchResults.end()) { + std::list emptyList; + mSearchResults[searchId] = emptyList; + return 1; + } + + std::cerr << "NotifyTxt::collectSearchResult() ERROR Id exists"; + std::cerr << std::endl; + return 1; +} + +int NotifyTxt::clearSearchId(uint32_t searchId) +{ + std::cerr << "NotifyTxt::clearSearchId(" << searchId << ")"; + std::cerr << std::endl; + + RsStackMutex stack(mNotifyMtx); /****** LOCKED *****/ + + std::map >::iterator it; + it = mSearchResults.find(searchId); + if (it == mSearchResults.end()) + { + std::cerr << "NotifyTxt::clearSearchId() ERROR Id not there"; + std::cerr << std::endl; return 0; } diff --git a/retroshare-nogui/src/retroshare.cc b/retroshare-nogui/src/retroshare.cc index 36fd0172e..d1b6a5abd 100644 --- a/retroshare-nogui/src/retroshare.cc +++ b/retroshare-nogui/src/retroshare.cc @@ -388,7 +388,7 @@ int main(int argc, char **argv) if (enableRpc) { /* Build RPC Server */ - RpcMediator *med = CreateRpcSystem(ssh); + RpcMediator *med = CreateRpcSystem(ssh, notify); ssh->setRpcSystem(med); ssh->setSleepPeriods(0.01, 0.1); } diff --git a/retroshare-nogui/src/rpc/proto/gencc/core.pb.cc b/retroshare-nogui/src/rpc/proto/gencc/core.pb.cc index e95575c67..cb1061f88 100644 --- a/retroshare-nogui/src/rpc/proto/gencc/core.pb.cc +++ b/retroshare-nogui/src/rpc/proto/gencc/core.pb.cc @@ -134,12 +134,10 @@ void protobuf_AssignDesc_core_2eproto() { sizeof(Person)); Person_Relationship_descriptor_ = Person_descriptor_->enum_type(0); File_descriptor_ = file->message_type(4); - static const int File_offsets_[5] = { + static const int File_offsets_[3] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, hash_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, size_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, path_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(File, avail_), }; File_reflection_ = new ::google::protobuf::internal::GeneratedMessageReflection( @@ -283,39 +281,39 @@ void protobuf_AddDesc_core_2eproto() { GOOGLE_PROTOBUF_VERIFY_VERSION; ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( - "\n\ncore.proto\022\013rsctrl.core\"\233\001\n\006Status\022,\n\004" + "\n\ncore.proto\022\013rsctrl.core\"\260\001\n\006Status\022,\n\004" "code\030\001 \002(\0162\036.rsctrl.core.Status.StatusCo" - "de\022\013\n\003msg\030\002 \001(\t\"V\n\nStatusCode\022\n\n\006FAILED\020" - "\000\022\017\n\013NO_IMPL_YET\020\001\022\021\n\rINVALID_QUERY\020\002\022\013\n" - "\007SUCCESS\020\003\022\013\n\007READMSG\020\004\")\n\006IpAddr\022\016\n\004add" - "r\030\001 \002(\t:\000\022\017\n\004port\030\002 \002(\r:\0010\"\303\001\n\010Location\022" - "\016\n\006ssl_id\030\001 \002(\t\022\020\n\010location\030\002 \002(\t\022&\n\tloc" - "aladdr\030\003 \002(\0132\023.rsctrl.core.IpAddr\022$\n\007ext" - "addr\030\004 \002(\0132\023.rsctrl.core.IpAddr\022\r\n\005state" - "\030\005 \002(\r\"8\n\nStateFlags\022\n\n\006ONLINE\020\001\022\r\n\tCONN" - "ECTED\020\002\022\017\n\013UNREACHABLE\020\004\"\340\001\n\006Person\022\016\n\006g" - "pg_id\030\001 \002(\t\022\014\n\004name\030\002 \002(\t\0222\n\010relation\030\003 " - "\002(\0162 .rsctrl.core.Person.Relationship\022(\n" - "\tlocations\030\004 \003(\0132\025.rsctrl.core.Location\"" - "Z\n\014Relationship\022\n\n\006FRIEND\020\001\022\032\n\026FRIEND_OF" - "_MANY_FRIENDS\020\002\022\025\n\021FRIEND_OF_FRIENDS\020\003\022\013" - "\n\007UNKNOWN\020\004\"M\n\004File\022\014\n\004name\030\001 \002(\t\022\014\n\004has" - "h\030\002 \002(\t\022\014\n\004size\030\003 \002(\003\022\014\n\004path\030\004 \001(\t\022\r\n\005a" - "vail\030\005 \001(\t\"f\n\003Dir\022\014\n\004name\030\001 \002(\t\022\014\n\004path\030" - "\002 \002(\t\022!\n\007subdirs\030\003 \003(\0132\020.rsctrl.core.Dir" - "\022 \n\005files\030\004 \003(\0132\021.rsctrl.core.File\"\372\001\n\014S" - "ystemStatus\0225\n\nnet_status\030\001 \002(\0162!.rsctrl" - ".core.SystemStatus.NetCode\022\013\n\003msg\030\002 \001(\t\"" - "\245\001\n\007NetCode\022\017\n\013BAD_UNKNOWN\020\000\022\017\n\013BAD_OFFL" - "INE\020\001\022\016\n\nBAD_NATSYM\020\002\022\021\n\rBAD_NODHT_NAT\020\003" - "\022\023\n\017WARNING_RESTART\020\004\022\022\n\016WARNING_NATTED\020" - "\005\022\021\n\rWARNING_NODHT\020\006\022\010\n\004GOOD\020\007\022\017\n\013ADV_FO" - "RWARD\020\010\"3\n\tBandwidth\022\n\n\002up\030\001 \002(\002\022\014\n\004down" - "\030\002 \002(\002\022\014\n\004name\030\003 \001(\t\":\n\014BandwidthSet\022*\n\n" - "bandwidths\030\001 \003(\0132\026.rsctrl.core.Bandwidth" - "*\027\n\013ExtensionId\022\010\n\004CORE\020\000*6\n\tPackageId\022\t" - "\n\005PEERS\020\001\022\n\n\006SYSTEM\020\002\022\010\n\004CHAT\020\003\022\010\n\003GXS\020\350" - "\007", 1281); + "de\022\013\n\003msg\030\002 \001(\t\"k\n\nStatusCode\022\n\n\006FAILED\020" + "\000\022\017\n\013NO_IMPL_YET\020\001\022\021\n\rINVALID_QUERY\020\002\022\023\n" + "\017PARTIAL_SUCCESS\020\003\022\013\n\007SUCCESS\020\004\022\013\n\007READM" + "SG\020\005\")\n\006IpAddr\022\016\n\004addr\030\001 \002(\t:\000\022\017\n\004port\030\002" + " \002(\r:\0010\"\303\001\n\010Location\022\016\n\006ssl_id\030\001 \002(\t\022\020\n\010" + "location\030\002 \002(\t\022&\n\tlocaladdr\030\003 \002(\0132\023.rsct" + "rl.core.IpAddr\022$\n\007extaddr\030\004 \002(\0132\023.rsctrl" + ".core.IpAddr\022\r\n\005state\030\005 \002(\r\"8\n\nStateFlag" + "s\022\n\n\006ONLINE\020\001\022\r\n\tCONNECTED\020\002\022\017\n\013UNREACHA" + "BLE\020\004\"\340\001\n\006Person\022\016\n\006gpg_id\030\001 \002(\t\022\014\n\004name" + "\030\002 \002(\t\0222\n\010relation\030\003 \002(\0162 .rsctrl.core.P" + "erson.Relationship\022(\n\tlocations\030\004 \003(\0132\025." + "rsctrl.core.Location\"Z\n\014Relationship\022\n\n\006" + "FRIEND\020\001\022\032\n\026FRIEND_OF_MANY_FRIENDS\020\002\022\025\n\021" + "FRIEND_OF_FRIENDS\020\003\022\013\n\007UNKNOWN\020\004\"0\n\004File" + "\022\014\n\004name\030\001 \002(\t\022\014\n\004hash\030\002 \002(\t\022\014\n\004size\030\003 \002" + "(\004\"f\n\003Dir\022\014\n\004name\030\001 \002(\t\022\014\n\004path\030\002 \002(\t\022!\n" + "\007subdirs\030\003 \003(\0132\020.rsctrl.core.Dir\022 \n\005file" + "s\030\004 \003(\0132\021.rsctrl.core.File\"\372\001\n\014SystemSta" + "tus\0225\n\nnet_status\030\001 \002(\0162!.rsctrl.core.Sy" + "stemStatus.NetCode\022\013\n\003msg\030\002 \001(\t\"\245\001\n\007NetC" + "ode\022\017\n\013BAD_UNKNOWN\020\000\022\017\n\013BAD_OFFLINE\020\001\022\016\n" + "\nBAD_NATSYM\020\002\022\021\n\rBAD_NODHT_NAT\020\003\022\023\n\017WARN" + "ING_RESTART\020\004\022\022\n\016WARNING_NATTED\020\005\022\021\n\rWAR" + "NING_NODHT\020\006\022\010\n\004GOOD\020\007\022\017\n\013ADV_FORWARD\020\010\"" + "3\n\tBandwidth\022\n\n\002up\030\001 \002(\002\022\014\n\004down\030\002 \002(\002\022\014" + "\n\004name\030\003 \001(\t\":\n\014BandwidthSet\022*\n\nbandwidt" + "hs\030\001 \003(\0132\026.rsctrl.core.Bandwidth*\027\n\013Exte" + "nsionId\022\010\n\004CORE\020\000*M\n\tPackageId\022\t\n\005PEERS\020" + "\001\022\n\n\006SYSTEM\020\002\022\010\n\004CHAT\020\003\022\n\n\006SEARCH\020\004\022\t\n\005F" + "ILES\020\005\022\010\n\003GXS\020\350\007", 1296); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "core.proto", &protobuf_RegisterTypes); Status::default_instance_ = new Status(); @@ -368,6 +366,8 @@ bool PackageId_IsValid(int value) { case 1: case 2: case 3: + case 4: + case 5: case 1000: return true; default: @@ -389,6 +389,7 @@ bool Status_StatusCode_IsValid(int value) { case 2: case 3: case 4: + case 5: return true; default: return false; @@ -399,6 +400,7 @@ bool Status_StatusCode_IsValid(int value) { const Status_StatusCode Status::FAILED; const Status_StatusCode Status::NO_IMPL_YET; const Status_StatusCode Status::INVALID_QUERY; +const Status_StatusCode Status::PARTIAL_SUCCESS; const Status_StatusCode Status::SUCCESS; const Status_StatusCode Status::READMSG; const Status_StatusCode Status::StatusCode_MIN; @@ -1782,8 +1784,6 @@ void Person::Swap(Person* other) { const int File::kNameFieldNumber; const int File::kHashFieldNumber; const int File::kSizeFieldNumber; -const int File::kPathFieldNumber; -const int File::kAvailFieldNumber; #endif // !_MSC_VER File::File() @@ -1804,9 +1804,7 @@ void File::SharedCtor() { _cached_size_ = 0; name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); hash_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); - size_ = GOOGLE_LONGLONG(0); - path_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); - avail_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + size_ = GOOGLE_ULONGLONG(0); ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -1821,12 +1819,6 @@ void File::SharedDtor() { if (hash_ != &::google::protobuf::internal::kEmptyString) { delete hash_; } - if (path_ != &::google::protobuf::internal::kEmptyString) { - delete path_; - } - if (avail_ != &::google::protobuf::internal::kEmptyString) { - delete avail_; - } if (this != default_instance_) { } } @@ -1863,17 +1855,7 @@ void File::Clear() { hash_->clear(); } } - size_ = GOOGLE_LONGLONG(0); - if (has_path()) { - if (path_ != &::google::protobuf::internal::kEmptyString) { - path_->clear(); - } - } - if (has_avail()) { - if (avail_ != &::google::protobuf::internal::kEmptyString) { - avail_->clear(); - } - } + size_ = GOOGLE_ULONGLONG(0); } ::memset(_has_bits_, 0, sizeof(_has_bits_)); mutable_unknown_fields()->Clear(); @@ -1918,52 +1900,18 @@ bool File::MergePartialFromCodedStream( break; } - // required int64 size = 3; + // required uint64 size = 3; case 3: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { parse_size: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< - ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( input, &size_))); set_has_size(); } else { goto handle_uninterpreted; } - if (input->ExpectTag(34)) goto parse_path; - break; - } - - // optional string path = 4; - case 4: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_path: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_path())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->path().data(), this->path().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } - if (input->ExpectTag(42)) goto parse_avail; - break; - } - - // optional string avail = 5; - case 5: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - parse_avail: - DO_(::google::protobuf::internal::WireFormatLite::ReadString( - input, this->mutable_avail())); - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->avail().data(), this->avail().length(), - ::google::protobuf::internal::WireFormat::PARSE); - } else { - goto handle_uninterpreted; - } if (input->ExpectAtEnd()) return true; break; } @@ -2004,27 +1952,9 @@ void File::SerializeWithCachedSizes( 2, this->hash(), output); } - // required int64 size = 3; + // required uint64 size = 3; if (has_size()) { - ::google::protobuf::internal::WireFormatLite::WriteInt64(3, this->size(), output); - } - - // optional string path = 4; - if (has_path()) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->path().data(), this->path().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 4, this->path(), output); - } - - // optional string avail = 5; - if (has_avail()) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->avail().data(), this->avail().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - ::google::protobuf::internal::WireFormatLite::WriteString( - 5, this->avail(), output); + ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->size(), output); } if (!unknown_fields().empty()) { @@ -2055,29 +1985,9 @@ void File::SerializeWithCachedSizes( 2, this->hash(), target); } - // required int64 size = 3; + // required uint64 size = 3; if (has_size()) { - target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(3, this->size(), target); - } - - // optional string path = 4; - if (has_path()) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->path().data(), this->path().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 4, this->path(), target); - } - - // optional string avail = 5; - if (has_avail()) { - ::google::protobuf::internal::WireFormat::VerifyUTF8String( - this->avail().data(), this->avail().length(), - ::google::protobuf::internal::WireFormat::SERIALIZE); - target = - ::google::protobuf::internal::WireFormatLite::WriteStringToArray( - 5, this->avail(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->size(), target); } if (!unknown_fields().empty()) { @@ -2105,27 +2015,13 @@ int File::ByteSize() const { this->hash()); } - // required int64 size = 3; + // required uint64 size = 3; if (has_size()) { total_size += 1 + - ::google::protobuf::internal::WireFormatLite::Int64Size( + ::google::protobuf::internal::WireFormatLite::UInt64Size( this->size()); } - // optional string path = 4; - if (has_path()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->path()); - } - - // optional string avail = 5; - if (has_avail()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::StringSize( - this->avail()); - } - } if (!unknown_fields().empty()) { total_size += @@ -2162,12 +2058,6 @@ void File::MergeFrom(const File& from) { if (from.has_size()) { set_size(from.size()); } - if (from.has_path()) { - set_path(from.path()); - } - if (from.has_avail()) { - set_avail(from.avail()); - } } mutable_unknown_fields()->MergeFrom(from.unknown_fields()); } @@ -2195,8 +2085,6 @@ void File::Swap(File* other) { std::swap(name_, other->name_); std::swap(hash_, other->hash_); std::swap(size_, other->size_); - std::swap(path_, other->path_); - std::swap(avail_, other->avail_); std::swap(_has_bits_[0], other->_has_bits_[0]); _unknown_fields_.Swap(&other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); diff --git a/retroshare-nogui/src/rpc/proto/gencc/system.pb.cc b/retroshare-nogui/src/rpc/proto/gencc/system.pb.cc index ca729ce8f..915d6affd 100644 --- a/retroshare-nogui/src/rpc/proto/gencc/system.pb.cc +++ b/retroshare-nogui/src/rpc/proto/gencc/system.pb.cc @@ -25,6 +25,13 @@ const ::google::protobuf::Descriptor* ResponseSystemStatus_descriptor_ = NULL; const ::google::protobuf::internal::GeneratedMessageReflection* ResponseSystemStatus_reflection_ = NULL; const ::google::protobuf::EnumDescriptor* ResponseSystemStatus_NetCode_descriptor_ = NULL; +const ::google::protobuf::Descriptor* RequestSystemQuit_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + RequestSystemQuit_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* RequestSystemQuit_QuitCode_descriptor_ = NULL; +const ::google::protobuf::Descriptor* ResponseSystemQuit_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ResponseSystemQuit_reflection_ = NULL; const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor_ = NULL; const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor_ = NULL; @@ -71,6 +78,37 @@ void protobuf_AssignDesc_system_2eproto() { ::google::protobuf::MessageFactory::generated_factory(), sizeof(ResponseSystemStatus)); ResponseSystemStatus_NetCode_descriptor_ = ResponseSystemStatus_descriptor_->enum_type(0); + RequestSystemQuit_descriptor_ = file->message_type(2); + static const int RequestSystemQuit_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestSystemQuit, quit_code_), + }; + RequestSystemQuit_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + RequestSystemQuit_descriptor_, + RequestSystemQuit::default_instance_, + RequestSystemQuit_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestSystemQuit, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RequestSystemQuit, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(RequestSystemQuit)); + RequestSystemQuit_QuitCode_descriptor_ = RequestSystemQuit_descriptor_->enum_type(0); + ResponseSystemQuit_descriptor_ = file->message_type(3); + static const int ResponseSystemQuit_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSystemQuit, status_), + }; + ResponseSystemQuit_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + ResponseSystemQuit_descriptor_, + ResponseSystemQuit::default_instance_, + ResponseSystemQuit_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSystemQuit, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ResponseSystemQuit, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(ResponseSystemQuit)); RequestMsgIds_descriptor_ = file->enum_type(0); ResponseMsgIds_descriptor_ = file->enum_type(1); } @@ -89,6 +127,10 @@ void protobuf_RegisterTypes(const ::std::string&) { RequestSystemStatus_descriptor_, &RequestSystemStatus::default_instance()); ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( ResponseSystemStatus_descriptor_, &ResponseSystemStatus::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + RequestSystemQuit_descriptor_, &RequestSystemQuit::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ResponseSystemQuit_descriptor_, &ResponseSystemQuit::default_instance()); } } // namespace @@ -98,6 +140,10 @@ void protobuf_ShutdownFile_system_2eproto() { delete RequestSystemStatus_reflection_; delete ResponseSystemStatus::default_instance_; delete ResponseSystemStatus_reflection_; + delete RequestSystemQuit::default_instance_; + delete RequestSystemQuit_reflection_; + delete ResponseSystemQuit::default_instance_; + delete ResponseSystemQuit_reflection_; } void protobuf_AddDesc_system_2eproto() { @@ -119,15 +165,25 @@ void protobuf_AddDesc_system_2eproto() { "\016\n\nBAD_NATSYM\020\002\022\021\n\rBAD_NODHT_NAT\020\003\022\023\n\017WA" "RNING_RESTART\020\004\022\022\n\016WARNING_NATTED\020\005\022\021\n\rW" "ARNING_NODHT\020\006\022\010\n\004GOOD\020\007\022\017\n\013ADV_FORWARD\020" - "\010*.\n\rRequestMsgIds\022\035\n\031MsgId_RequestSyste" - "mStatus\020\001*0\n\016ResponseMsgIds\022\036\n\032MsgId_Res" - "ponseSystemStatus\020\001", 539); + "\010\"\201\001\n\021RequestSystemQuit\022<\n\tquit_code\030\001 \002" + "(\0162).rsctrl.system.RequestSystemQuit.Qui" + "tCode\".\n\010QuitCode\022\021\n\rCLOSE_CHANNEL\020\001\022\017\n\013" + "SHUTDOWN_RS\020\002\"9\n\022ResponseSystemQuit\022#\n\006s" + "tatus\030\001 \002(\0132\023.rsctrl.core.Status*K\n\rRequ" + "estMsgIds\022\035\n\031MsgId_RequestSystemStatus\020\001" + "\022\033\n\027MsgId_RequestSystemQuit\020\002*N\n\016Respons" + "eMsgIds\022\036\n\032MsgId_ResponseSystemStatus\020\001\022" + "\034\n\030MsgId_ResponseSystemQuit\020\002", 789); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "system.proto", &protobuf_RegisterTypes); RequestSystemStatus::default_instance_ = new RequestSystemStatus(); ResponseSystemStatus::default_instance_ = new ResponseSystemStatus(); + RequestSystemQuit::default_instance_ = new RequestSystemQuit(); + ResponseSystemQuit::default_instance_ = new ResponseSystemQuit(); RequestSystemStatus::default_instance_->InitAsDefaultInstance(); ResponseSystemStatus::default_instance_->InitAsDefaultInstance(); + RequestSystemQuit::default_instance_->InitAsDefaultInstance(); + ResponseSystemQuit::default_instance_->InitAsDefaultInstance(); ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_system_2eproto); } @@ -145,6 +201,7 @@ const ::google::protobuf::EnumDescriptor* RequestMsgIds_descriptor() { bool RequestMsgIds_IsValid(int value) { switch(value) { case 1: + case 2: return true; default: return false; @@ -158,6 +215,7 @@ const ::google::protobuf::EnumDescriptor* ResponseMsgIds_descriptor() { bool ResponseMsgIds_IsValid(int value) { switch(value) { case 1: + case 2: return true; default: return false; @@ -745,6 +803,457 @@ void ResponseSystemStatus::Swap(ResponseSystemStatus* other) { } +// =================================================================== + +const ::google::protobuf::EnumDescriptor* RequestSystemQuit_QuitCode_descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestSystemQuit_QuitCode_descriptor_; +} +bool RequestSystemQuit_QuitCode_IsValid(int value) { + switch(value) { + case 1: + case 2: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const RequestSystemQuit_QuitCode RequestSystemQuit::CLOSE_CHANNEL; +const RequestSystemQuit_QuitCode RequestSystemQuit::SHUTDOWN_RS; +const RequestSystemQuit_QuitCode RequestSystemQuit::QuitCode_MIN; +const RequestSystemQuit_QuitCode RequestSystemQuit::QuitCode_MAX; +const int RequestSystemQuit::QuitCode_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int RequestSystemQuit::kQuitCodeFieldNumber; +#endif // !_MSC_VER + +RequestSystemQuit::RequestSystemQuit() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void RequestSystemQuit::InitAsDefaultInstance() { +} + +RequestSystemQuit::RequestSystemQuit(const RequestSystemQuit& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void RequestSystemQuit::SharedCtor() { + _cached_size_ = 0; + quit_code_ = 1; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +RequestSystemQuit::~RequestSystemQuit() { + SharedDtor(); +} + +void RequestSystemQuit::SharedDtor() { + if (this != default_instance_) { + } +} + +void RequestSystemQuit::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* RequestSystemQuit::descriptor() { + protobuf_AssignDescriptorsOnce(); + return RequestSystemQuit_descriptor_; +} + +const RequestSystemQuit& RequestSystemQuit::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_system_2eproto(); return *default_instance_; +} + +RequestSystemQuit* RequestSystemQuit::default_instance_ = NULL; + +RequestSystemQuit* RequestSystemQuit::New() const { + return new RequestSystemQuit; +} + +void RequestSystemQuit::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + quit_code_ = 1; + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool RequestSystemQuit::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.system.RequestSystemQuit.QuitCode quit_code = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::rsctrl::system::RequestSystemQuit_QuitCode_IsValid(value)) { + set_quit_code(static_cast< ::rsctrl::system::RequestSystemQuit_QuitCode >(value)); + } else { + mutable_unknown_fields()->AddVarint(1, value); + } + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void RequestSystemQuit::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.system.RequestSystemQuit.QuitCode quit_code = 1; + if (has_quit_code()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->quit_code(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* RequestSystemQuit::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.system.RequestSystemQuit.QuitCode quit_code = 1; + if (has_quit_code()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->quit_code(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int RequestSystemQuit::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.system.RequestSystemQuit.QuitCode quit_code = 1; + if (has_quit_code()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->quit_code()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void RequestSystemQuit::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const RequestSystemQuit* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void RequestSystemQuit::MergeFrom(const RequestSystemQuit& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_quit_code()) { + set_quit_code(from.quit_code()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void RequestSystemQuit::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void RequestSystemQuit::CopyFrom(const RequestSystemQuit& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool RequestSystemQuit::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void RequestSystemQuit::Swap(RequestSystemQuit* other) { + if (other != this) { + std::swap(quit_code_, other->quit_code_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata RequestSystemQuit::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = RequestSystemQuit_descriptor_; + metadata.reflection = RequestSystemQuit_reflection_; + return metadata; +} + + +// =================================================================== + +#ifndef _MSC_VER +const int ResponseSystemQuit::kStatusFieldNumber; +#endif // !_MSC_VER + +ResponseSystemQuit::ResponseSystemQuit() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void ResponseSystemQuit::InitAsDefaultInstance() { + status_ = const_cast< ::rsctrl::core::Status*>(&::rsctrl::core::Status::default_instance()); +} + +ResponseSystemQuit::ResponseSystemQuit(const ResponseSystemQuit& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void ResponseSystemQuit::SharedCtor() { + _cached_size_ = 0; + status_ = NULL; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +ResponseSystemQuit::~ResponseSystemQuit() { + SharedDtor(); +} + +void ResponseSystemQuit::SharedDtor() { + if (this != default_instance_) { + delete status_; + } +} + +void ResponseSystemQuit::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ResponseSystemQuit::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ResponseSystemQuit_descriptor_; +} + +const ResponseSystemQuit& ResponseSystemQuit::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_system_2eproto(); return *default_instance_; +} + +ResponseSystemQuit* ResponseSystemQuit::default_instance_ = NULL; + +ResponseSystemQuit* ResponseSystemQuit::New() const { + return new ResponseSystemQuit; +} + +void ResponseSystemQuit::Clear() { + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (has_status()) { + if (status_ != NULL) status_->::rsctrl::core::Status::Clear(); + } + } + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool ResponseSystemQuit::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required .rsctrl.core.Status status = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_status())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void ResponseSystemQuit::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->status(), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* ResponseSystemQuit::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->status(), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int ResponseSystemQuit::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required .rsctrl.core.Status status = 1; + if (has_status()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->status()); + } + + } + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ResponseSystemQuit::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const ResponseSystemQuit* source = + ::google::protobuf::internal::dynamic_cast_if_available( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ResponseSystemQuit::MergeFrom(const ResponseSystemQuit& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_status()) { + mutable_status()->::rsctrl::core::Status::MergeFrom(from.status()); + } + } + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void ResponseSystemQuit::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ResponseSystemQuit::CopyFrom(const ResponseSystemQuit& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ResponseSystemQuit::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + if (has_status()) { + if (!this->status().IsInitialized()) return false; + } + return true; +} + +void ResponseSystemQuit::Swap(ResponseSystemQuit* other) { + if (other != this) { + std::swap(status_, other->status_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata ResponseSystemQuit::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ResponseSystemQuit_descriptor_; + metadata.reflection = ResponseSystemQuit_reflection_; + return metadata; +} + + // @@protoc_insertion_point(namespace_scope) } // namespace system diff --git a/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc b/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc index 29c7c5cbc..7a0e1e52a 100644 --- a/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc +++ b/retroshare-nogui/src/rpc/proto/rpcprotosystem.cc @@ -86,6 +86,11 @@ int RpcProtoSystem::processMsg(uint32_t chan_id, uint32_t msg_id, uint32_t req_i case rsctrl::system::MsgId_RequestSystemStatus: processSystemStatus(chan_id, msg_id, req_id, msg); break; +#if 0 + case rsctrl::system::MsgId_RequestSystemQuit: + processSystemQuit(chan_id, msg_id, req_id, msg); + break; +#endif default: std::cerr << "RpcProtoSystem::processMsg() ERROR should never get here"; std::cerr << std::endl; @@ -211,3 +216,71 @@ int RpcProtoSystem::processSystemStatus(uint32_t chan_id, uint32_t msg_id, uint3 } + +int RpcProtoSystem::processSystemQuit(uint32_t chan_id, uint32_t msg_id, uint32_t req_id, const std::string &msg) +{ + std::cerr << "RpcProtoSystem::processSystemQuit()"; + std::cerr << std::endl; + + // parse msg. + rsctrl::system::RequestSystemQuit req; + if (!req.ParseFromString(msg)) + { + std::cerr << "RpcProtoSystem::processSystemQuit() ERROR ParseFromString()"; + std::cerr << std::endl; + return 0; + } + + // NO Options... so go straight to answer. + // response. + rsctrl::system::ResponseSystemQuit resp; + bool success = true; + + switch(req.quit_code()) + { + default: + case rsctrl::system::RequestSystemQuit::CLOSE_CHANNEL: + { + RpcServer *server = getRpcServer(); + server->error(chan_id, "CLOSE_CHANNEL"); + + break; + } + case rsctrl::system::RequestSystemQuit::SHUTDOWN_RS: + { + rsicontrol->rsGlobalShutDown(); + break; + } + } + + if (success) + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::SUCCESS); + } + else + { + rsctrl::core::Status *status = resp.mutable_status(); + status->set_code(rsctrl::core::Status::FAILED); + status->set_msg("Unknown ERROR"); + } + + std::string outmsg; + if (!resp.SerializeToString(&outmsg)) + { + std::cerr << "RpcProtoSystem::processSystemQuit() ERROR SerialiseToString()"; + std::cerr << std::endl; + return 0; + } + + // Correctly Name Message. + uint32_t out_msg_id = constructMsgId(rsctrl::core::CORE, rsctrl::core::SYSTEM, + rsctrl::system::MsgId_ResponseSystemQuit, true); + + // queue it. + queueResponse(chan_id, out_msg_id, req_id, outmsg); + + return 1; +} + + diff --git a/retroshare-nogui/src/rpc/rpc.cc b/retroshare-nogui/src/rpc/rpc.cc index 6fd5a0b74..a1aa1683b 100644 --- a/retroshare-nogui/src/rpc/rpc.cc +++ b/retroshare-nogui/src/rpc/rpc.cc @@ -43,6 +43,11 @@ void RpcMediator::reset(uint32_t chan_id) mServer->reset(chan_id); } +int RpcMediator::error(uint32_t chan_id, std::string msg) +{ + return mComms->error(chan_id, msg); +} + int RpcMediator::tick() { diff --git a/retroshare-nogui/src/rpc/rpcserver.cc b/retroshare-nogui/src/rpc/rpcserver.cc index 484a7576e..a879e08df 100644 --- a/retroshare-nogui/src/rpc/rpcserver.cc +++ b/retroshare-nogui/src/rpc/rpcserver.cc @@ -63,11 +63,16 @@ void RpcServer::reset(uint32_t chan_id) return; } +int RpcServer::error(uint32_t chan_id, std::string msg) +{ + return mMediator->error(chan_id, msg); +} int RpcServer::addService(RpcService *service) { RsStackMutex stack(mRpcMtx); /********** LOCKED MUTEX ***************/ + service->setRpcServer(this); mAllServices.push_back(service); return 1; diff --git a/retroshare-nogui/src/rpc/rpcsetup.cc b/retroshare-nogui/src/rpc/rpcsetup.cc index 528f5b425..015d72142 100644 --- a/retroshare-nogui/src/rpc/rpcsetup.cc +++ b/retroshare-nogui/src/rpc/rpcsetup.cc @@ -27,10 +27,12 @@ #include "rpc/proto/rpcprotopeers.h" #include "rpc/proto/rpcprotosystem.h" #include "rpc/proto/rpcprotochat.h" +#include "rpc/proto/rpcprotosearch.h" +#include "rpc/proto/rpcprotofiles.h" #include "rpc/rpcecho.h" -RpcMediator *CreateRpcSystem(RpcComms *comms) +RpcMediator *CreateRpcSystem(RpcComms *comms, NotifyTxt *notify) { RpcMediator *med = new RpcMediator(comms); RpcServer *server = new RpcServer(med); @@ -45,6 +47,12 @@ RpcMediator *CreateRpcSystem(RpcComms *comms) RpcProtoChat *chat = new RpcProtoChat(1); server->addService(chat); + RpcProtoSearch *search = new RpcProtoSearch(1, notify); + server->addService(search); + + RpcProtoFiles *files = new RpcProtoFiles(1); + server->addService(files); + /* Finally an Echo Service - which will echo back any unprocesses commands. */ RpcEcho *echo = new RpcEcho(1); server->addService(echo); From 0fc3a2704bc5c9913ac028a7b339dde28d599e57 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Tue, 25 Sep 2012 21:04:04 +0000 Subject: [PATCH 069/222] Fixed compile issues for VEG in librs (rs-gui VEG ui cannot be compiled as was the case prior to issues) removed VEG photoservice Enabled group synchronisation between retroshare peers! test synchro between two rs peers worked. Added crude commenting facility to photoshare, much tuning to be done git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5602 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgenexchange.cc | 93 ++- libretroshare/src/gxs/rsgxsdataaccess.cc | 60 +- libretroshare/src/gxs/rsgxsnetservice.cc | 39 +- libretroshare/src/gxs/rsgxsnetservice.h | 18 +- libretroshare/src/gxs/rstokenservice.h | 12 +- libretroshare/src/retroshare/rsidentityVEG.h | 7 +- libretroshare/src/retroshare/rsphotoV2.h | 9 + libretroshare/src/retroshare/rsphotoVEG.h | 85 --- libretroshare/src/rsserver/rsinit.cc | 57 +- .../src/serialiser/rsphotov2items.cc | 2 +- .../src/services/p3photoserviceV2.cc | 138 +++- libretroshare/src/services/p3photoserviceV2.h | 3 + .../src/services/p3photoserviceVEG.cc | 680 ------------------ .../src/services/p3photoserviceVEG.h | 138 ---- retroshare-gui/src/RetroShare.pro | 31 +- .../src/gui/PhotoShare/AddCommentDialog.cpp | 19 + .../src/gui/PhotoShare/AddCommentDialog.h | 23 + .../src/gui/PhotoShare/AddCommentDialog.ui | 67 ++ .../src/gui/PhotoShare/AlbumCreateDialog.cpp | 2 +- .../src/gui/PhotoShare/PhotoCommentItem.cpp | 15 +- .../src/gui/PhotoShare/PhotoCommentItem.h | 9 +- .../src/gui/PhotoShare/PhotoCommentItem.ui | 8 +- .../src/gui/PhotoShare/PhotoDialog.cpp | 155 +++- .../src/gui/PhotoShare/PhotoDialog.h | 21 + .../src/gui/PhotoShare/PhotoDialog.ui | 29 +- .../src/gui/PhotoShare/PhotoShare.cpp | 7 +- retroshare-gui/src/util/TokenQueueV2.cpp | 9 +- retroshare-gui/src/util/TokenQueueV2.h | 2 +- retroshare-gui/src/util/TokenQueueVEG.h | 2 +- 29 files changed, 653 insertions(+), 1087 deletions(-) delete mode 100644 libretroshare/src/retroshare/rsphotoVEG.h delete mode 100644 libretroshare/src/services/p3photoserviceVEG.cc delete mode 100644 libretroshare/src/services/p3photoserviceVEG.h create mode 100644 retroshare-gui/src/gui/PhotoShare/AddCommentDialog.cpp create mode 100644 retroshare-gui/src/gui/PhotoShare/AddCommentDialog.h create mode 100644 retroshare-gui/src/gui/PhotoShare/AddCommentDialog.ui diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index ff39da0ff..ea52c3f17 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -69,8 +69,13 @@ void RsGenExchange::tick() processMsgMetaChanges(); - notifyChanges(mNotifications); - mNotifications.clear(); + processRecvdData(); + + if(!mNotifications.empty()) + { + notifyChanges(mNotifications); + mNotifications.clear(); + } } @@ -493,10 +498,10 @@ void RsGenExchange::processMsgMetaChanges() if(ok) { - mDataAccess->updatePublicRequestStatus(token, RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE); + mDataAccess->updatePublicRequestStatus(token, RsTokenServiceV2::GXS_REQUEST_V2_STATUS_COMPLETE); }else { - mDataAccess->updatePublicRequestStatus(token, RsTokenServiceV2::GXS_REQUEST_STATUS_FAILED); + mDataAccess->updatePublicRequestStatus(token, RsTokenServiceV2::GXS_REQUEST_V2_STATUS_FAILED); } mMsgNotify.insert(std::make_pair(token, m.msgId)); } @@ -519,10 +524,10 @@ void RsGenExchange::processGrpMetaChanges() if(ok) { - mDataAccess->updatePublicRequestStatus(token, RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE); + mDataAccess->updatePublicRequestStatus(token, RsTokenServiceV2::GXS_REQUEST_V2_STATUS_COMPLETE); }else { - mDataAccess->updatePublicRequestStatus(token, RsTokenServiceV2::GXS_REQUEST_STATUS_FAILED); + mDataAccess->updatePublicRequestStatus(token, RsTokenServiceV2::GXS_REQUEST_V2_STATUS_FAILED); } mGrpNotify.insert(std::make_pair(token, g.grpId)); } @@ -582,7 +587,7 @@ void RsGenExchange::publishMsgs() // add to published to allow acknowledgement mMsgNotify.insert(std::make_pair(mit->first, std::make_pair(msg->grpId, msg->msgId))); - mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE); + mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_V2_STATUS_COMPLETE); } // if addition failed then delete nxs message @@ -628,6 +633,7 @@ void RsGenExchange::publishGrps() grp->metaData = new RsGxsGrpMetaData(); grpItem->meta.mPublishTs = time(NULL); *(grp->metaData) = grpItem->meta; + grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; createGroup(grp); size = grp->metaData->serial_size(); char mData[size]; @@ -639,7 +645,7 @@ void RsGenExchange::publishGrps() // add to published to allow acknowledgement mGrpNotify.insert(std::make_pair(mit->first, grp->grpId)); - mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE); + mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_V2_STATUS_COMPLETE); } if(!ok) @@ -652,7 +658,7 @@ void RsGenExchange::publishGrps() // add to published to allow acknowledgement, grpid is empty as grp creation failed mGrpNotify.insert(std::make_pair(mit->first, RsGxsGroupId(""))); - mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_STATUS_FAILED); + mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_V2_STATUS_FAILED); continue; } @@ -664,9 +670,50 @@ void RsGenExchange::publishGrps() mGrpsToPublish.clear(); } +void RsGenExchange::createDummyGroup(RsGxsGrpItem *grpItem) +{ + + RsStackMutex stack(mGenMtx); + + + RsNxsGrp* grp = new RsNxsGrp(mServType); + uint32_t size = mSerialiser->size(grpItem); + char gData[size]; + bool ok = mSerialiser->serialise(grpItem, gData, &size); + grp->grp.setBinData(gData, size); + + if(ok) + { + grp->metaData = new RsGxsGrpMetaData(); + grpItem->meta.mPublishTs = time(NULL); + *(grp->metaData) = grpItem->meta; + grp->metaData->mSubscribeFlags = ~GXS_SERV::GROUP_SUBSCRIBE_MASK; + createGroup(grp); + size = grp->metaData->serial_size(); + char mData[size]; + grp->metaData->mGroupId = grp->grpId; + ok = grp->metaData->serialise(mData, size); + grp->meta.setBinData(mData, size); + + ok = mDataAccess->addGroupData(grp); + } + + if(!ok) + { + +#ifdef GEN_EXCH_DEBUG + std::cerr << "RsGenExchange::createDummyGroup(); failed to publish grp " << std::endl; +#endif + delete grp; + } + + delete grpItem; +} + void RsGenExchange::processRecvdData() { + processRecvdGroups(); } @@ -677,5 +724,33 @@ void RsGenExchange::processRecvdMessages() void RsGenExchange::processRecvdGroups() { + RsStackMutex stack(mGenMtx); + + std::vector::iterator vit = mReceivedGrps.begin(); + std::map grps; + + std::list grpIds; + + for(; vit != mReceivedGrps.end(); vit++) + { + RsNxsGrp* grp = *vit; + RsGxsGrpMetaData* meta = new RsGxsGrpMetaData(); + meta->deserialise(grp->meta.bin_data, grp->meta.bin_len); + grps.insert(std::make_pair(grp, meta)); + + grpIds.push_back(grp->grpId); + + } + + if(!grpIds.empty()) + { + RsGxsGroupChange* c = new RsGxsGroupChange(); + c->grpIdList = grpIds; + mNotifications.push_back(c); + mDataStore->storeGroup(grps); + } + + mReceivedGrps.clear(); + } diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index 552c961dc..123edb55c 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -49,12 +49,12 @@ #define RS_TOKREQ_ANSTYPE_SUMMARY 0x0002 #define RS_TOKREQ_ANSTYPE_DATA 0x0003 - const uint8_t RsTokenServiceV2::GXS_REQUEST_STATUS_FAILED = 0; - const uint8_t RsTokenServiceV2::GXS_REQUEST_STATUS_PENDING = 1; - const uint8_t RsTokenServiceV2::GXS_REQUEST_STATUS_PARTIAL = 2; - const uint8_t RsTokenServiceV2::GXS_REQUEST_STATUS_FINISHED_INCOMPLETE = 3; - const uint8_t RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE = 4; - const uint8_t RsTokenServiceV2::GXS_REQUEST_STATUS_DONE = 5; // ONCE ALL DATA RETRIEVED. + const uint8_t RsTokenServiceV2::GXS_REQUEST_V2_STATUS_FAILED = 0; + const uint8_t RsTokenServiceV2::GXS_REQUEST_V2_STATUS_PENDING = 1; + const uint8_t RsTokenServiceV2::GXS_REQUEST_V2_STATUS_PARTIAL = 2; + const uint8_t RsTokenServiceV2::GXS_REQUEST_V2_STATUS_FINISHED_INCOMPLETE = 3; + const uint8_t RsTokenServiceV2::GXS_REQUEST_V2_STATUS_COMPLETE = 4; + const uint8_t RsTokenServiceV2::GXS_REQUEST_V2_STATUS_DONE = 5; // ONCE ALL DATA RETRIEVED. RsGxsDataAccess::RsGxsDataAccess(RsGeneralDataService* ds) : mDataStore(ds), mDataMutex("RsGxsDataAccess"), mNextToken(0) @@ -183,19 +183,19 @@ bool RsGxsDataAccess::requestMsgInfo(uint32_t &token, uint32_t ansType, for(; vit != toRemove.end(); vit++) filteredMsgIds.erase(*vit); - if(reqType & GXS_REQUEST_TYPE_MSG_META) + if(reqType & GXS_REQUEST_TYPE_MSG_META) { MsgMetaReq* mmr = new MsgMetaReq(); mmr->mMsgIds = filteredMsgIds; req = mmr; - }else if(reqType & GXS_REQUEST_TYPE_MSG_DATA) + }else if(reqType & GXS_REQUEST_TYPE_MSG_DATA) { MsgDataReq* mdr = new MsgDataReq(); mdr->mMsgIds = filteredMsgIds; req = mdr; - }else if(reqType & GXS_REQUEST_TYPE_MSG_IDS) + }else if(reqType & GXS_REQUEST_TYPE_MSG_IDS) { MsgIdReq* mir = new MsgIdReq(); mir->mMsgIds = filteredMsgIds; @@ -296,7 +296,7 @@ void RsGxsDataAccess::storeRequest(GxsRequest* req) { RsStackMutex stack(mDataMutex); /****** LOCKED *****/ - req->status = GXS_REQUEST_STATUS_PENDING; + req->status = GXS_REQUEST_V2_STATUS_PENDING; mRequests[req->token] = req; return; @@ -359,14 +359,14 @@ bool RsGxsDataAccess::getGroupSummary(const uint32_t& token, std::liststatus == GXS_REQUEST_STATUS_COMPLETE){ + }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ GroupMetaReq* gmreq = dynamic_cast(req); if(gmreq) { groupInfo = gmreq->mGroupMetaData; - locked_updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); }else{ std::cerr << "RsGxsDataAccess::getGroupSummary() Req found, failed caste" << std::endl; return false; @@ -389,14 +389,14 @@ bool RsGxsDataAccess::getGroupData(const uint32_t& token, std::list& std::cerr << "RsGxsDataAccess::getGroupData() Unable to retrieve group data" << std::endl; return false; - }else if(req->status == GXS_REQUEST_STATUS_COMPLETE){ + }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ GroupDataReq* gmreq = dynamic_cast(req); if(gmreq) { grpData = gmreq->mGroupData; - locked_updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); }else{ std::cerr << "RsGxsDataAccess::getGroupData() Req found, failed caste" << std::endl; return false; @@ -420,14 +420,14 @@ bool RsGxsDataAccess::getMsgData(const uint32_t& token, NxsMsgDataResult& msgDat std::cerr << "RsGxsDataAccess::getMsgData() Unable to retrieve group data" << std::endl; return false; - }else if(req->status == GXS_REQUEST_STATUS_COMPLETE){ + }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ MsgDataReq* mdreq = dynamic_cast(req); if(mdreq) { msgData = mdreq->mMsgData; - locked_updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); }else{ std::cerr << "RsGxsDataAccess::getMsgData() Req found, failed caste" << std::endl; return false; @@ -451,14 +451,14 @@ bool RsGxsDataAccess::getMsgSummary(const uint32_t& token, GxsMsgMetaResult& msg std::cerr << "RsGxsDataAccess::getMsgSummary() Unable to retrieve group data" << std::endl; return false; - }else if(req->status == GXS_REQUEST_STATUS_COMPLETE){ + }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ MsgMetaReq* mmreq = dynamic_cast(req); if(mmreq) { msgInfo = mmreq->mMsgMetaData; - locked_updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); }else{ std::cerr << "RsGxsDataAccess::getMsgSummary() Req found, failed caste" << std::endl; @@ -482,7 +482,7 @@ bool RsGxsDataAccess::getMsgList(const uint32_t& token, GxsMsgIdResult& msgIds) std::cerr << "RsGxsDataAccess::getMsgList() Unable to retrieve group data" << std::endl; return false; - }else if(req->status == GXS_REQUEST_STATUS_COMPLETE){ + }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ MsgIdReq* mireq = dynamic_cast(req); MsgRelatedInfoReq* mrireq = dynamic_cast(req); @@ -490,12 +490,12 @@ bool RsGxsDataAccess::getMsgList(const uint32_t& token, GxsMsgIdResult& msgIds) if(mireq) { msgIds = mireq->mMsgIdResult; - locked_updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); } else if(mrireq) { msgIds = mrireq->mMsgIdResult; - locked_updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); } else{ std::cerr << "RsGxsDataAccess::getMsgList() Req found, failed caste" << std::endl; @@ -520,14 +520,14 @@ bool RsGxsDataAccess::getGroupList(const uint32_t& token, std::liststatus == GXS_REQUEST_STATUS_COMPLETE){ + }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ GroupIdReq* gireq = dynamic_cast(req); if(gireq) { groupIds = gireq->mGroupIdResult; - locked_updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); + locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); }else{ std::cerr << "RsGxsDataAccess::getGroupList() Req found, failed caste" << std::endl; @@ -579,13 +579,13 @@ void RsGxsDataAccess::processRequests() { GxsRequest* req = it->second; - if (req->status == GXS_REQUEST_STATUS_PENDING) + if (req->status == GXS_REQUEST_V2_STATUS_PENDING) { std::cerr << "RsGxsDataAccess::processRequests() Processing Token: " << req->token << " Status: " << req->status << " ReqType: " << req->reqType << " Age: " << now - req->reqTime << std::endl; - req->status = GXS_REQUEST_STATUS_PARTIAL; + req->status = GXS_REQUEST_V2_STATUS_PARTIAL; /* PROCESS REQUEST! */ @@ -624,14 +624,14 @@ void RsGxsDataAccess::processRequests() << req->token << std::endl; #endif - req->status = GXS_REQUEST_STATUS_FAILED; + req->status = GXS_REQUEST_V2_STATUS_FAILED; } } - else if (req->status == GXS_REQUEST_STATUS_PARTIAL) + else if (req->status == GXS_REQUEST_V2_STATUS_PARTIAL) { - req->status = GXS_REQUEST_STATUS_COMPLETE; + req->status = GXS_REQUEST_V2_STATUS_COMPLETE; } - else if (req->status == GXS_REQUEST_STATUS_DONE) + else if (req->status == GXS_REQUEST_V2_STATUS_DONE) { std::cerr << "RsGxsDataAccess::processrequests() Clearing Done Request Token: " << req->token; @@ -1331,7 +1331,7 @@ uint32_t RsGxsDataAccess::generatePublicToken() { RsStackMutex stack(mDataMutex); - mPublicToken[token] = RsTokenServiceV2::GXS_REQUEST_STATUS_PENDING; + mPublicToken[token] = RsTokenServiceV2::GXS_REQUEST_V2_STATUS_PENDING; } return token; diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 19e22ca0f..884b1760d 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -98,7 +98,7 @@ void RsGxsNetService::syncWithPeers() { RsGxsGrpMetaData* meta = mit->second; - if(meta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_MASK) + if(meta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) grpIds.push_back(mit->first); } @@ -655,8 +655,6 @@ void RsGxsNetService::locked_processCompletedIncomingTrans(NxsTransaction* tr) } } - int nitems = msgs.size(); - // notify listener of msgs mObserver->notifyNewMessages(msgs); @@ -761,6 +759,8 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr) } } + if(msgItemL.empty()) + return; // get grp id for this transaction RsNxsSyncMsgItem* item = msgItemL.front(); @@ -1258,3 +1258,36 @@ NxsTransaction::~NxsTransaction(){ delete mTransaction; mTransaction = NULL; } + + +/* Net Manager */ + +RsNxsNetMgrImpl::RsNxsNetMgrImpl(p3LinkMgr *lMgr) + : mLinkMgr(lMgr) +{ + +} + + +std::string RsNxsNetMgrImpl::getOwnId() +{ + return mLinkMgr->getOwnId(); +} + +void RsNxsNetMgrImpl::getOnlineList(std::set &ssl_peers) +{ + ssl_peers.clear(); + + std::list pList; + mLinkMgr->getOnlineList(pList); + + std::list::const_iterator lit = pList.begin(); + + for(; lit != pList.end(); lit++) + ssl_peers.insert(*lit); +} + + + + + diff --git a/libretroshare/src/gxs/rsgxsnetservice.h b/libretroshare/src/gxs/rsgxsnetservice.h index fc1f9bf38..716420939 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.h +++ b/libretroshare/src/gxs/rsgxsnetservice.h @@ -90,17 +90,21 @@ public: }; -//class RsNxsNetMgrImpl : public RsNxsNetMgrImpl -//{ +class RsNxsNetMgrImpl : public RsNxsNetMgr +{ -//public: +public: -// RsNxsNetMgrImpl(p3LinkMgr* lMgr); + RsNxsNetMgrImpl(p3LinkMgr* lMgr); -// std::string getOwnId(); -// void getOnlineList(std::set& ssl_peers); + std::string getOwnId(); + void getOnlineList(std::set& ssl_peers); -//}; +private: + + p3LinkMgr* mLinkMgr; + +}; /// keep track of transaction number diff --git a/libretroshare/src/gxs/rstokenservice.h b/libretroshare/src/gxs/rstokenservice.h index ced417734..870e6db5f 100644 --- a/libretroshare/src/gxs/rstokenservice.h +++ b/libretroshare/src/gxs/rstokenservice.h @@ -107,12 +107,12 @@ class RsTokenServiceV2 public: - static const uint8_t GXS_REQUEST_STATUS_FAILED; - static const uint8_t GXS_REQUEST_STATUS_PENDING; - static const uint8_t GXS_REQUEST_STATUS_PARTIAL; - static const uint8_t GXS_REQUEST_STATUS_FINISHED_INCOMPLETE; - static const uint8_t GXS_REQUEST_STATUS_COMPLETE; - static const uint8_t GXS_REQUEST_STATUS_DONE; // ONCE ALL DATA RETRIEVED. + static const uint8_t GXS_REQUEST_V2_STATUS_FAILED; + static const uint8_t GXS_REQUEST_V2_STATUS_PENDING; + static const uint8_t GXS_REQUEST_V2_STATUS_PARTIAL; + static const uint8_t GXS_REQUEST_V2_STATUS_FINISHED_INCOMPLETE; + static const uint8_t GXS_REQUEST_V2_STATUS_COMPLETE; + static const uint8_t GXS_REQUEST_V2_STATUS_DONE; // ONCE ALL DATA RETRIEVED. public: diff --git a/libretroshare/src/retroshare/rsidentityVEG.h b/libretroshare/src/retroshare/rsidentityVEG.h index 9a58ab96d..d88943442 100644 --- a/libretroshare/src/retroshare/rsidentityVEG.h +++ b/libretroshare/src/retroshare/rsidentityVEG.h @@ -61,7 +61,8 @@ #define RS_TOKREQOPT_UNREAD 0x0002 #define RS_TOKREQ_ANSTYPE_LIST 0x0001 -#define RS_TOKREQ_ANSTYPE_SUMMARY 0x0002 +#define RS_TOKREQ_ANSTYPE_SUMMARY 0x0002 +#define RS_TOKREQ_ANSTYPE_DATA 0x0003 @@ -358,8 +359,8 @@ virtual bool groupShareKeys(const std::string &groupId, std::list& /* The Main Interface Class - for information about your Peers */ -class RsIdentity; -extern RsIdentity *rsIdentity; +class RsIdentityVEG; +extern RsIdentityVEG *rsIdentityVEG; #define RSID_TYPE_MASK 0xff00 #define RSID_RELATION_MASK 0x00ff diff --git a/libretroshare/src/retroshare/rsphotoV2.h b/libretroshare/src/retroshare/rsphotoV2.h index 838843134..f42bd1452 100644 --- a/libretroshare/src/retroshare/rsphotoV2.h +++ b/libretroshare/src/retroshare/rsphotoV2.h @@ -168,6 +168,7 @@ std::ostream &operator<<(std::ostream &out, const RsPhotoPhoto &photo); std::ostream &operator<<(std::ostream &out, const RsPhotoAlbum &album); typedef std::map > PhotoResult; +typedef std::map > PhotoCommentResult; typedef std::map > MsgMetaResult; class RsPhotoV2 @@ -266,6 +267,14 @@ public: /* details are updated in album - to choose Album ID, and storage path */ + /*! + * @param token token to be redeemed for photo request + * @param photo the photo returned for given request token + * @return false if request token is invalid, check token status for error report + */ + virtual bool getPhotoComment(const uint32_t &token, + PhotoCommentResult& comments) = 0; + /*! * submits album, which returns a token that needs * to be acknowledge to get album grp id diff --git a/libretroshare/src/retroshare/rsphotoVEG.h b/libretroshare/src/retroshare/rsphotoVEG.h deleted file mode 100644 index 13c7da7ac..000000000 --- a/libretroshare/src/retroshare/rsphotoVEG.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef RETROSHARE_PHOTO_GUI_INTERFACE_H -#define RETROSHARE_PHOTO_GUI_INTERFACE_H - -/* - * libretroshare/src/retroshare: rsphoto.h - * - * RetroShare C++ Interface. - * - * Copyright 2008-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include -#include -#include -#include -#include "rsphotoV2.h" - -/* The Main Interface Class - for information about your Peers */ -class RsPhotoVEG; -extern RsPhotoVEG *rsPhotoVEG; - -/******************* NEW STUFF FOR NEW CACHE SYSTEM *********/ - -#define RSPHOTO_MODE_NEW 1 -#define RSPHOTO_MODE_OWN 2 -#define RSPHOTO_MODE_REMOTE 3 - -/* If these flags are no set - the Photo inherits values from the Album - */ - -#define RSPHOTO_FLAGS_ATTRIB_TITLE 0x0001 -#define RSPHOTO_FLAGS_ATTRIB_CAPTION 0x0002 -#define RSPHOTO_FLAGS_ATTRIB_DESC 0x0004 -#define RSPHOTO_FLAGS_ATTRIB_PHOTOGRAPHER 0x0008 -#define RSPHOTO_FLAGS_ATTRIB_WHERE 0x0010 -#define RSPHOTO_FLAGS_ATTRIB_WHEN 0x0020 -#define RSPHOTO_FLAGS_ATTRIB_OTHER 0x0040 -#define RSPHOTO_FLAGS_ATTRIB_CATEGORY 0x0080 -#define RSPHOTO_FLAGS_ATTRIB_HASHTAGS 0x0100 -#define RSPHOTO_FLAGS_ATTRIB_ORDER 0x0200 -#define RSPHOTO_FLAGS_ATTRIB_THUMBNAIL 0x0400 -#define RSPHOTO_FLAGS_ATTRIB_MODE 0x0800 -#define RSPHOTO_FLAGS_ATTRIB_AUTHOR 0x1000 // PUSH UP ORDER -#define RSPHOTO_FLAGS_ATTRIB_PHOTO 0x2000 // PUSH UP ORDER. - - -std::ostream &operator<<(std::ostream &out, const RsPhotoPhoto &photo); -std::ostream &operator<<(std::ostream &out, const RsPhotoAlbum &album); - - -class RsPhotoVEG: public RsTokenServiceVEG -{ - public: - - RsPhotoVEG() { return; } -virtual ~RsPhotoVEG() { return; } - - /* Specific Service Data */ -virtual bool getAlbum(const uint32_t &token, RsPhotoAlbum &album) = 0; -virtual bool getPhoto(const uint32_t &token, RsPhotoPhoto &photo) = 0; - -virtual bool submitAlbumDetails(uint32_t &token, RsPhotoAlbum &album, bool isNew) = 0; -virtual bool submitPhoto(uint32_t &token, RsPhotoPhoto &photo, bool isNew) = 0; - -}; - - -#endif diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 6c58ab54c..0a1cce5e9 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1806,7 +1806,7 @@ RsTurtle *rsTurtle = NULL ; #include "services/p3blogs.h" #include "turtle/p3turtle.h" -//#define ENABLE_GXS_SERVICES 1 +#define ENABLE_GXS_SERVICES 1 #define ENABLE_GXS_CORE 1 #ifdef ENABLE_GXS_CORE @@ -1817,12 +1817,11 @@ RsTurtle *rsTurtle = NULL ; #endif #ifdef ENABLE_GXS_SERVICES -#include "services/p3photoservice.h" -#include "services/p3wikiservice.h" -#include "services/p3wire.h" -#include "services/p3idservice.h" -#include "services/p3forumsv2.h" -#include "services/p3posted.h" +#include "services/p3wikiserviceVEG.h" +#include "services/p3wireVEG.h" +#include "services/p3idserviceVEG.h".h" +#include "services/p3forumsVEG.h" +#include "services/p3postedVEG.h" #endif #ifndef PQI_DISABLE_TUNNEL @@ -2271,55 +2270,56 @@ int RsServer::StartupRetroShare() // first prep the core - RsGeneralDataService* photo_ds = new RsDataService("./", "photoV2_db", + + RsDirUtil::checkCreateDirectory(mLinkMgr->getOwnId()); + RsGeneralDataService* photo_ds = new RsDataService("./" + mLinkMgr->getOwnId() + "/", "photoV2_db", RS_SERVICE_GXSV1_TYPE_PHOTO, NULL); photo_ds->resetDataStore(); + // init gxs services + mPhotoV2 = new p3PhotoServiceV2(photo_ds, NULL); + // TODO need net manager - //RsGxsNetService* photo_ns = new RsGxsNetService( - // RS_SERVICE_TYPE_PHOTO, photo_ds, NULL, mPhotoV2); + RsGxsNetService* photo_ns = new RsGxsNetService( + RS_SERVICE_GXSV1_TYPE_PHOTO, photo_ds, new RsNxsNetMgrImpl(mLinkMgr), mPhotoV2); - // init gxs services - mPhotoV2 = new p3PhotoServiceV2(photo_ds, NULL); - GxsCoreServer* mGxsCore = new GxsCoreServer(); mGxsCore->addService(mPhotoV2); // cores read start up servers ! // start nxs core core server - //createThread(*photo_ns); + createThread(*photo_ns); // start up gxs core server createThread(*mGxsCore); + pqih->addService(photo_ns); + #endif #ifdef ENABLE_GXS_SERVICES + // Testing New Cache Services. - p3PhotoService *mPhotos = new p3PhotoService(RS_SERVICE_TYPE_PHOTO); - pqih -> addService(mPhotos); - - // Testing New Cache Services. - p3WikiService *mWikis = new p3WikiService(RS_SERVICE_TYPE_WIKI); + p3WikiServiceVEG *mWikis = new p3WikiServiceVEG(RS_SERVICE_GXSV1_TYPE_WIKI); pqih -> addService(mWikis); // Testing New Cache Services. - p3Wire *mWire = new p3Wire(RS_SERVICE_TYPE_WIRE); + p3WireVEG *mWire = new p3WireVEG(RS_SERVICE_GXSV1_TYPE_WIRE); pqih -> addService(mWire); // Testing New Cache Services. - p3IdService *mIdentity = new p3IdService(RS_SERVICE_TYPE_IDENTITY); + p3IdServiceVEG *mIdentity = new p3IdServiceVEG(RS_SERVICE_GXSV1_TYPE_IDENTITY); pqih -> addService(mIdentity); // Testing New Cache Services. - p3ForumsV2 *mForumsV2 = new p3ForumsV2(RS_SERVICE_TYPE_FORUMSV2); + p3ForumsVEG *mForumsV2 = new p3ForumsVEG(RS_SERVICE_GXSV1_TYPE_FORUMS); pqih -> addService(mForumsV2); // Testing New Cache Services. - p3PostedService *mPosted = new p3PostedService(RS_SERVICE_TYPE_POSTED); + p3PostedServiceVEG *mPosted = new p3PostedServiceVEG(RS_SERVICE_GXSV1_TYPE_POSTED); pqih -> addService(mPosted); #endif // ENABLE_GXS_SERVICES @@ -2583,12 +2583,11 @@ int RsServer::StartupRetroShare() rsPhotoV2 = mPhotoV2; #ifdef ENABLE_GXS_SERVICES // Testing of new cache system interfaces. - rsIdentity = mIdentity; - rsPhoto = mPhotos; - rsWiki = mWikis; - rsWire = mWire; - rsForumsV2 = mForumsV2; - rsPosted = mPosted; + rsIdentityVEG = mIdentity; + rsWikiVEG = mWikis; + rsWireVEG = mWire; + rsForumsVEG = mForumsV2; + rsPostedVEG = mPosted; #endif // ENABLE_GXS_SERVICES diff --git a/libretroshare/src/serialiser/rsphotov2items.cc b/libretroshare/src/serialiser/rsphotov2items.cc index 559253e59..ea09415ff 100644 --- a/libretroshare/src/serialiser/rsphotov2items.cc +++ b/libretroshare/src/serialiser/rsphotov2items.cc @@ -562,7 +562,7 @@ RsGxsPhotoCommentItem * RsGxsPhotoSerialiser::deserialiseGxsPhotoCommentItem( /* skip the header */ offset += 8; - ok &= GetTlvString(data, rssize, &offset, 1, item->comment.mComment); + ok &= GetTlvString(data, rssize, &offset, 0, item->comment.mComment); ok &= getRawUInt32(data, rssize, &offset, &(item->comment.mCommentFlag)); if (offset != rssize) diff --git a/libretroshare/src/services/p3photoserviceV2.cc b/libretroshare/src/services/p3photoserviceV2.cc index 82efc8579..cce6b3952 100644 --- a/libretroshare/src/services/p3photoserviceV2.cc +++ b/libretroshare/src/services/p3photoserviceV2.cc @@ -5,6 +5,11 @@ RsPhotoV2 *rsPhotoV2 = NULL; +const uint32_t RsPhotoV2::FLAG_MSG_TYPE_MASK = 0x000f; +const uint32_t RsPhotoV2::FLAG_MSG_TYPE_PHOTO_POST = 0x0001; +const uint32_t RsPhotoV2::FLAG_MSG_TYPE_PHOTO_COMMENT = 0x0002; + + bool RsPhotoThumbnail::copyFrom(const RsPhotoThumbnail &nail) @@ -75,33 +80,46 @@ std::ostream &operator<<(std::ostream &out, const RsPhotoAlbum &album) } p3PhotoServiceV2::p3PhotoServiceV2(RsGeneralDataService* gds, RsNetworkExchangeService* nes) - : RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_GXSV1_TYPE_PHOTO) + : RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_GXSV1_TYPE_PHOTO), mPhotoMutex(std::string("Photo Mutex")) { + // create dummy grps + + RsGxsPhotoAlbumItem* item1 = new RsGxsPhotoAlbumItem(), *item2 = new RsGxsPhotoAlbumItem(); + + item1->meta.mGroupName = "Dummy Album 1"; + item2->meta.mGroupName = "Dummy Album 2"; + + createDummyGroup(item1); + createDummyGroup(item2); } bool p3PhotoServiceV2::updated() { - bool changed = (!mGroupChange.empty() || !mMsgChange.empty()); + RsStackMutex stack(mPhotoMutex); - return changed; + bool changed = (!mGroupChange.empty() || !mMsgChange.empty()); + + return changed; } void p3PhotoServiceV2::groupsChanged(std::list& grpIds) { - while(!mGroupChange.empty()) - { - RsGxsGroupChange* gc = mGroupChange.back(); - std::list& gList = gc->grpIdList; - std::list::iterator lit = gList.begin(); - for(; lit != gList.end(); lit++) - grpIds.push_back(*lit); + RsStackMutex stack(mPhotoMutex); - mGroupChange.pop_back(); - delete gc; - } + while(!mGroupChange.empty()) + { + RsGxsGroupChange* gc = mGroupChange.back(); + std::list& gList = gc->grpIdList; + std::list::iterator lit = gList.begin(); + for(; lit != gList.end(); lit++) + grpIds.push_back(*lit); + + mGroupChange.pop_back(); + delete gc; + } } @@ -192,13 +210,14 @@ bool p3PhotoServiceV2::getPhoto(const uint32_t& token, PhotoResult& photos) if(item) { - RsPhotoPhoto photo = item->photo; + RsPhotoPhoto photo = item->photo; photo.mMeta = item->meta; photos[grpId].push_back(photo); delete item; }else { - delete *vit; + std::cerr << "Not a photo Item, deleting!" << std::endl; + delete *vit; } } } @@ -207,40 +226,79 @@ bool p3PhotoServiceV2::getPhoto(const uint32_t& token, PhotoResult& photos) return ok; } +bool p3PhotoServiceV2::getPhotoComment(const uint32_t &token, PhotoCommentResult &comments) +{ + GxsMsgDataMap msgData; + bool ok = RsGenExchange::getMsgData(token, msgData); + + if(ok) + { + GxsMsgDataMap::iterator mit = msgData.begin(); + + for(; mit != msgData.end(); mit++) + { + RsGxsGroupId grpId = mit->first; + std::vector& msgItems = mit->second; + std::vector::iterator vit = msgItems.begin(); + + for(; vit != msgItems.end(); vit++) + { + RsGxsPhotoCommentItem* item = dynamic_cast(*vit); + + if(item) + { + RsPhotoComment comment = item->comment; + comment.mMeta = item->meta; + comments[grpId].push_back(comment); + delete item; + }else + { + std::cerr << "Not a comment Item, deleting!" << std::endl; + delete *vit; + } + } + } + } + + return ok; +} bool p3PhotoServiceV2::submitAlbumDetails(uint32_t& token, RsPhotoAlbum& album) { - RsGxsPhotoAlbumItem* albumItem = new RsGxsPhotoAlbumItem(); - albumItem->album = album; - albumItem->meta = album.mMeta; - RsGenExchange::publishGroup(token, albumItem); - return true; + RsGxsPhotoAlbumItem* albumItem = new RsGxsPhotoAlbumItem(); + albumItem->album = album; + albumItem->meta = album.mMeta; + RsGenExchange::publishGroup(token, albumItem); + return true; } void p3PhotoServiceV2::notifyChanges(std::vector& changes) { - std::vector::iterator vit = changes.begin(); - for(; vit != changes.end(); vit++) - { - RsGxsNotify* n = *vit; - RsGxsGroupChange* gc; - RsGxsMsgChange* mc; - if((mc = dynamic_cast(n)) != NULL) - { - mMsgChange.push_back(mc); - } - else if((gc = dynamic_cast(n)) != NULL) - { - mGroupChange.push_back(gc); - } - else - { - delete n; - } - } + RsStackMutex stack(mPhotoMutex); + + std::vector::iterator vit = changes.begin(); + + for(; vit != changes.end(); vit++) + { + RsGxsNotify* n = *vit; + RsGxsGroupChange* gc; + RsGxsMsgChange* mc; + if((mc = dynamic_cast(n)) != NULL) + { + mMsgChange.push_back(mc); + } + else if((gc = dynamic_cast(n)) != NULL) + { + mGroupChange.push_back(gc); + } + else + { + delete n; + } + } } bool p3PhotoServiceV2::submitPhoto(uint32_t& token, RsPhotoPhoto& photo) @@ -248,6 +306,7 @@ bool p3PhotoServiceV2::submitPhoto(uint32_t& token, RsPhotoPhoto& photo) RsGxsPhotoPhotoItem* photoItem = new RsGxsPhotoPhotoItem(); photoItem->photo = photo; photoItem->meta = photo.mMeta; + photoItem->meta.mMsgFlags = FLAG_MSG_TYPE_PHOTO_POST; RsGenExchange::publishMsg(token, photoItem); return true; @@ -258,6 +317,7 @@ bool p3PhotoServiceV2::submitComment(uint32_t &token, RsPhotoComment &comment) RsGxsPhotoCommentItem* commentItem = new RsGxsPhotoCommentItem(); commentItem->comment = comment; commentItem->meta = comment.mMeta; + commentItem->meta.mMsgFlags = FLAG_MSG_TYPE_PHOTO_COMMENT; RsGenExchange::publishMsg(token, commentItem); return true; diff --git a/libretroshare/src/services/p3photoserviceV2.h b/libretroshare/src/services/p3photoserviceV2.h index fe58dab07..631de1c05 100644 --- a/libretroshare/src/services/p3photoserviceV2.h +++ b/libretroshare/src/services/p3photoserviceV2.h @@ -73,6 +73,7 @@ public: /* Specific Service Data */ bool getAlbum(const uint32_t &token, std::vector &albums); bool getPhoto(const uint32_t &token, PhotoResult &photos); + bool getPhotoComment(const uint32_t &token, PhotoCommentResult &comments); public: @@ -134,6 +135,8 @@ private: std::vector mGroupChange; std::vector mMsgChange; + + RsMutex mPhotoMutex; }; #endif // P3PHOTOSERVICEV2_H diff --git a/libretroshare/src/services/p3photoserviceVEG.cc b/libretroshare/src/services/p3photoserviceVEG.cc deleted file mode 100644 index ade88b459..000000000 --- a/libretroshare/src/services/p3photoserviceVEG.cc +++ /dev/null @@ -1,680 +0,0 @@ -/* - * libretroshare/src/services p3photoservice.cc - * - * Photo Service for RetroShare. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "services/p3photoserviceVEG.h" -#include "util/rsrandom.h" - -/**** - * #define PHOTO_DEBUG 1 - ****/ - -RsPhotoVEG *rsPhotoVEG = NULL; - - -/********************************************************************************/ -/******************* Startup / Tick ******************************************/ -/********************************************************************************/ - -p3PhotoServiceVEG::p3PhotoServiceVEG(uint16_t type) - :p3GxsDataServiceVEG(type, new PhotoDataProxy()), mPhotoMtx("p3PhotoService"), mUpdated(true) -{ - RsStackMutex stack(mPhotoMtx); /********** STACK LOCKED MTX ******/ - - mPhotoProxy = (PhotoDataProxy *) mProxy; - return; -} - - -int p3PhotoServiceVEG::tick() -{ - //std::cerr << "p3PhotoServiceVEG::tick()"; - //std::cerr << std::endl; - - fakeprocessrequests(); - - return 0; -} - -bool p3PhotoServiceVEG::updated() -{ - RsStackMutex stack(mPhotoMtx); /********** STACK LOCKED MTX ******/ - - if (mUpdated) - { - mUpdated = false; - return true; - } - return false; -} - - - /* Data Requests */ -bool p3PhotoServiceVEG::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) -{ - generateToken(token); - std::cerr << "p3PhotoServiceVEG::requestGroupInfo() gets Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); - - return true; -} - -bool p3PhotoServiceVEG::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) -{ - generateToken(token); - std::cerr << "p3PhotoServiceVEG::requestMsgInfo() gets Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds); - - return true; -} - -bool p3PhotoServiceVEG::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds) -{ - generateToken(token); - std::cerr << "p3PhotoServiceVEG::requestMsgRelatedInfo() gets Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); - - return true; -} - - /* Generic Lists */ -bool p3PhotoServiceVEG::getGroupList( const uint32_t &token, std::list &groupIds) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_LIST) - { - std::cerr << "p3PhotoServiceVEG::getGroupList() ERROR AnsType Wrong" << std::endl; - return false; - } - - if (reqtype != GXS_REQUEST_TYPE_GROUPS) - { - std::cerr << "p3PhotoServiceVEG::getGroupList() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3PhotoServiceVEG::getGroupList() ERROR Status Incomplete" << std::endl; - return false; - } - - bool ans = loadRequestOutList(token, groupIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - return ans; -} - - - - -bool p3PhotoServiceVEG::getMsgList( const uint32_t &token, std::list &msgIds) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_LIST) - { - std::cerr << "p3PhotoServiceVEG::getMsgList() ERROR AnsType Wrong" << std::endl; - return false; - } - - if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) - { - std::cerr << "p3PhotoServiceVEG::getMsgList() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3PhotoServiceVEG::getMsgList() ERROR Status Incomplete" << std::endl; - return false; - } - - bool ans = loadRequestOutList(token, msgIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - return ans; -} - - - /* Generic Summary */ -bool p3PhotoServiceVEG::getGroupSummary( const uint32_t &token, std::list &groupInfo) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY) - { - std::cerr << "p3PhotoServiceVEG::getGroupSummary() ERROR AnsType Wrong" << std::endl; - return false; - } - - if (reqtype != GXS_REQUEST_TYPE_GROUPS) - { - std::cerr << "p3PhotoServiceVEG::getGroupSummary() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3PhotoServiceVEG::getGroupSummary() ERROR Status Incomplete" << std::endl; - return false; - } - - std::list groupIds; - bool ans = loadRequestOutList(token, groupIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - /* convert to RsGroupMetaData */ - mProxy->getGroupSummary(groupIds, groupInfo); - - return ans; -} - -bool p3PhotoServiceVEG::getMsgSummary( const uint32_t &token, std::list &msgInfo) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY) - { - std::cerr << "p3PhotoServiceVEG::getMsgSummary() ERROR AnsType Wrong" << std::endl; - return false; - } - - if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) - { - std::cerr << "p3PhotoServiceVEG::getMsgSummary() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3PhotoServiceVEG::getMsgSummary() ERROR Status Incomplete" << std::endl; - return false; - } - - std::list msgIds; - bool ans = loadRequestOutList(token, msgIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - /* convert to RsMsgMetaData */ - mProxy->getMsgSummary(msgIds, msgInfo); - - return ans; -} - - - /* Specific Service Data */ -bool p3PhotoServiceVEG::getAlbum(const uint32_t &token, RsPhotoAlbum &album) -{ - std::cerr << "p3PhotoServiceVEG::getAlbum() Token: " << token; - std::cerr << std::endl; - - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - - if (anstype != RS_TOKREQ_ANSTYPE_DATA) - { - std::cerr << "p3PhotoServiceVEG::getAlbum() ERROR AnsType Wrong" << std::endl; - return false; - } - - if (reqtype != GXS_REQUEST_TYPE_GROUPS) - { - std::cerr << "p3PhotoServiceVEG::getAlbum() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3PhotoServiceVEG::getAlbum() ERROR Status Incomplete" << std::endl; - return false; - } - - std::string id; - if (!popRequestOutList(token, id)) - { - /* finished */ - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - return false; - } - - /* convert to RsPhotoAlbum */ - bool ans = mPhotoProxy->getAlbum(id, album); - return ans; -} - - -bool p3PhotoServiceVEG::getPhoto(const uint32_t &token, RsPhotoPhoto &photo) -{ - std::cerr << "p3PhotoServiceVEG::getPhoto() Token: " << token; - std::cerr << std::endl; - - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - - if (anstype != RS_TOKREQ_ANSTYPE_DATA) - { - std::cerr << "p3PhotoServiceVEG::getPhoto() ERROR AnsType Wrong" << std::endl; - return false; - } - - if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) - { - std::cerr << "p3PhotoServiceVEG::getPhoto() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3PhotoServiceVEG::getPhoto() ERROR Status Incomplete" << std::endl; - return false; - } - - std::string id; - if (!popRequestOutList(token, id)) - { - /* finished */ - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - return false; - } - - /* convert to RsPhotoAlbum */ - bool ans = mPhotoProxy->getPhoto(id, photo); - return ans; -} - - - - /* Poll */ -uint32_t p3PhotoServiceVEG::requestStatus(const uint32_t token) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - return status; -} - - - /* Cancel Request */ -bool p3PhotoServiceVEG::cancelRequest(const uint32_t &token) -{ - return clearRequest(token); -} - - -bool p3PhotoServiceVEG::setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask) -{ - return mPhotoProxy->setMessageStatus(msgId, status, statusMask); -} - -bool p3PhotoServiceVEG::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask) -{ - return mPhotoProxy->setGroupStatus(groupId, status, statusMask); -} - -bool p3PhotoServiceVEG::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) -{ - return mPhotoProxy->setGroupSubscribeFlags(groupId, subscribeFlags, subscribeMask); -} - -bool p3PhotoServiceVEG::setMessageServiceString(const std::string &msgId, const std::string &str) -{ - return mPhotoProxy->setMessageServiceString(msgId, str); -} - -bool p3PhotoServiceVEG::setGroupServiceString(const std::string &grpId, const std::string &str) -{ - return mPhotoProxy->setGroupServiceString(grpId, str); -} - - -bool p3PhotoServiceVEG::groupRestoreKeys(const std::string &groupId) -{ - return false; -} - -bool p3PhotoServiceVEG::groupShareKeys(const std::string &groupId, std::list& peers) -{ - return false; -} - - -/* details are updated in album - to choose Album ID, and storage path */ - -bool p3PhotoServiceVEG::submitAlbumDetails(uint32_t &token, RsPhotoAlbum &album, bool isNew) -{ - /* check if its a modification or a new album */ - - /* add to database */ - - /* check if its a mod or new photo */ - if (album.mMeta.mGroupId.empty()) - { - /* new photo */ - - /* generate a temp id */ - album.mMeta.mGroupId = genRandomId(); - // TODO. - //album.mMeta.mPublishTs = time(NULL); - - std::cerr << "p3PhotoServiceVEG::submitAlbumDetails() Generated New GroupID: " << album.mMeta.mGroupId; - std::cerr << std::endl; - } - - album.mModFlags = 0; // These are always cleared. - - { - RsStackMutex stack(mPhotoMtx); /********** STACK LOCKED MTX ******/ - - mUpdated = true; - - /* add / modify */ - mPhotoProxy->addAlbum(album); - } - - // Fake a request to return the GroupMetaData. - generateToken(token); - uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptionsVEG opts; // NULL is good. - std::list groupIds; - groupIds.push_back(album.mMeta.mGroupId); // It will just return this one. - - std::cerr << "p3PhotoServiceVEG::submitAlbumDetails() Generating Request Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); - - return true; -} - -bool p3PhotoServiceVEG::submitPhoto(uint32_t &token, RsPhotoPhoto &photo, bool isNew) -{ - if (photo.mMeta.mGroupId.empty()) - { - /* new photo */ - std::cerr << "p3PhotoServiceVEG::submitPhoto() Missing GroupID: ERROR"; - std::cerr << std::endl; - return false; - } - - /* generate a new id */ - photo.mMeta.mMsgId = genRandomId(); - photo.mMeta.mPublishTs = time(NULL); - - if (isNew) - { - /* new (Original Msg) photo */ - photo.mMeta.mOrigMsgId = photo.mMeta.mMsgId; - std::cerr << "p3PhotoServiceVEG::submitPhoto() New Msg"; - std::cerr << std::endl; - } - else - { - std::cerr << "p3PhotoServiceVEG::submitPhoto() Updated Msg"; - std::cerr << std::endl; - } - - photo.mModFlags = 0; // These are always cleared. - - std::cerr << "p3PhotoServiceVEG::submitPhoto() OrigMsgId: " << photo.mMeta.mOrigMsgId; - std::cerr << " MsgId: " << photo.mMeta.mMsgId; - std::cerr << std::endl; - - { - RsStackMutex stack(mPhotoMtx); /********** STACK LOCKED MTX ******/ - - mUpdated = true; - mPhotoProxy->addPhoto(photo); - } - - // Fake a request to return the MsgMetaData. - generateToken(token); - uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptionsVEG opts; // NULL is good. - std::list msgIds; - msgIds.push_back(photo.mMeta.mMsgId); // It will just return this one. - - std::cerr << "p3PhotoServiceVEG::submitPhoto() Generating Request Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); - - return true; -} - - - -/********************************************************************************************/ - -bool PhotoDataProxy::getAlbum(const std::string &id, RsPhotoAlbum &album) -{ - void *groupData = NULL; - RsGroupMetaData meta; - if (getGroupData(id, groupData) && getGroupSummary(id, meta)) - { - RsPhotoAlbum *pA = (RsPhotoAlbum *) groupData; - // Shallow copy of thumbnail. - album = *pA; - - // update definitive version of the metadata. - album.mMeta = meta; - - std::cerr << "PhotoDataProxy::getAlbum() Id: " << id; - std::cerr << " MetaData: " << meta << " DataPointer: " << groupData; - std::cerr << std::endl; - return true; - } - - std::cerr << "PhotoDataProxy::getAlbum() FAILED Id: " << id; - std::cerr << std::endl; - - return false; -} - -bool PhotoDataProxy::getPhoto(const std::string &id, RsPhotoPhoto &photo) -{ - void *msgData = NULL; - RsMsgMetaData meta; - if (getMsgData(id, msgData) && getMsgSummary(id, meta)) - { - RsPhotoPhoto *pP = (RsPhotoPhoto *) msgData; - // Shallow copy of thumbnail. - photo = *pP; - - // update definitive version of the metadata. - photo.mMeta = meta; - - std::cerr << "PhotoDataProxy::getPhoto() Id: " << id; - std::cerr << " MetaData: " << meta << " DataPointer: " << msgData; - std::cerr << std::endl; - return true; - } - - std::cerr << "PhotoDataProxy::getPhoto() FAILED Id: " << id; - std::cerr << std::endl; - - return false; -} - - - -bool PhotoDataProxy::addAlbum(const RsPhotoAlbum &album) -{ - // Make duplicate. - RsPhotoAlbum *pA = new RsPhotoAlbum(); - *pA = album; - - std::cerr << "PhotoDataProxy::addAlbum()"; - std::cerr << " MetaData: " << pA->mMeta << " DataPointer: " << pA; - std::cerr << std::endl; - - // deep copy thumbnail. - pA->mThumbnail.data = NULL; - pA->mThumbnail.copyFrom(album.mThumbnail); - - return createGroup(pA); -} - - -bool PhotoDataProxy::addPhoto(const RsPhotoPhoto &photo) -{ - // Make duplicate. - RsPhotoPhoto *pP = new RsPhotoPhoto(); - *pP = photo; - - std::cerr << "PhotoDataProxy::addPhoto()"; - std::cerr << " MetaData: " << pP->mMeta << " DataPointer: " << pP; - std::cerr << std::endl; - - // deep copy thumbnail. - pP->mThumbnail.data = NULL; - pP->mThumbnail.copyFrom(photo.mThumbnail); - - return createMsg(pP); -} - - - - /* These Functions must be overloaded to complete the service */ -bool PhotoDataProxy::convertGroupToMetaData(void *groupData, RsGroupMetaData &meta) -{ - RsPhotoAlbum *album = (RsPhotoAlbum *) groupData; - meta = album->mMeta; - - return true; -} - -bool PhotoDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta) -{ - RsPhotoPhoto *photo = (RsPhotoPhoto *) msgData; - meta = photo->mMeta; - - return true; -} - - -/********************************************************************************************/ - -std::string p3PhotoServiceVEG::genRandomId() -{ - std::string randomId; - for(int i = 0; i < 20; i++) - { - randomId += (char) ('a' + (RSRandom::random_u32() % 26)); - } - - return randomId; -} - - -bool RsPhotoThumbnail::copyFrom(const RsPhotoThumbnail &nail) -{ - if (data) - { - deleteImage(); - } - - if ((!nail.data) || (nail.size == 0)) - { - return false; - } - - size = nail.size; - type = nail.type; - data = (uint8_t *) malloc(size); - memcpy(data, nail.data, size); - - return true; -} - -bool RsPhotoThumbnail::deleteImage() -{ - if (data) - { - free(data); - data = NULL; - size = 0; - type.clear(); - } - return true; -} - - - -/********************************************************************************************/ - -RsPhotoPhoto::RsPhotoPhoto() - :mSetFlags(0), mOrder(0), mMode(0), mModFlags(0) -{ - return; -} - -RsPhotoAlbum::RsPhotoAlbum() - :mMode(0), mSetFlags(0), mModFlags(0) -{ - return; -} - -std::ostream &operator<<(std::ostream &out, const RsPhotoPhoto &photo) -{ - out << "RsPhotoPhoto [ "; - out << "Title: " << photo.mMeta.mMsgName; - out << "]"; - return out; -} - - -std::ostream &operator<<(std::ostream &out, const RsPhotoAlbum &album) -{ - out << "RsPhotoAlbum [ "; - out << "Title: " << album.mMeta.mGroupName; - out << "]"; - return out; -} - - diff --git a/libretroshare/src/services/p3photoserviceVEG.h b/libretroshare/src/services/p3photoserviceVEG.h deleted file mode 100644 index 87dbaa9f7..000000000 --- a/libretroshare/src/services/p3photoserviceVEG.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * libretroshare/src/services: p3photoservice.h - * - * 3P/PQI network interface for RetroShare. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#ifndef P3_PHOTO_SERVICE_VEG_HEADER -#define P3_PHOTO_SERVICE_VEG_HEADER - -#include "services/p3gxsserviceVEG.h" -#include "retroshare/rsphotoVEG.h" - -#include -#include - -/* - * Photo Service - * - * This is an example service for the new cache system. - * For the moment, it will only hold data passed to it from the GUI. - * and spew that back when asked.... - * - * We are doing it like this - so we can check the required interface functionality. - * - * Expect it won't take long before it'll be properly linked into the backend! - * - * This will be transformed into a Plugin Service, once the basics have been worked out. - * - */ - - -class PhotoDataProxy: public GxsDataProxyVEG -{ - public: - - bool addAlbum(const RsPhotoAlbum &album); - bool addPhoto(const RsPhotoPhoto &photo); - - bool getAlbum(const std::string &id, RsPhotoAlbum &album); - bool getPhoto(const std::string &id, RsPhotoPhoto &photo); - - /* These Functions must be overloaded to complete the service */ -virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta); -virtual bool convertMsgToMetaData(void *groupData, RsMsgMetaData &meta); - -}; - - - -class p3PhotoServiceVEG: public p3GxsDataServiceVEG, public RsPhotoVEG -{ - public: - - p3PhotoServiceVEG(uint16_t type); - -virtual int tick(); - - public: - -// NEW INTERFACE. -/************* Extern Interface *******/ - - /* changed? */ -virtual bool updated(); - - /* Data Requests */ -virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); -virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); -virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds); - - /* Generic Lists */ -virtual bool getGroupList( const uint32_t &token, std::list &groupIds); -virtual bool getMsgList( const uint32_t &token, std::list &msgIds); - - /* Generic Summary */ -virtual bool getGroupSummary( const uint32_t &token, std::list &groupInfo); -virtual bool getMsgSummary( const uint32_t &token, std::list &msgInfo); - - /* Actual Data -> specific to Interface */ - /* Specific Service Data */ -virtual bool getAlbum(const uint32_t &token, RsPhotoAlbum &album); -virtual bool getPhoto(const uint32_t &token, RsPhotoPhoto &photo); - - /* Poll */ -virtual uint32_t requestStatus(const uint32_t token); - - /* Cancel Request */ -virtual bool cancelRequest(const uint32_t &token); - - ////////////////////////////////////////////////////////////////////////////// -virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask); -virtual bool setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask); -virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask); -virtual bool setMessageServiceString(const std::string &msgId, const std::string &str); -virtual bool setGroupServiceString(const std::string &grpId, const std::string &str); - -virtual bool groupRestoreKeys(const std::string &groupId); -virtual bool groupShareKeys(const std::string &groupId, std::list& peers); - - -/* details are updated in album - to choose Album ID, and storage path */ -virtual bool submitAlbumDetails(uint32_t &token, RsPhotoAlbum &album, bool isNew); -virtual bool submitPhoto(uint32_t &token, RsPhotoPhoto &photo, bool isNew); - - - - private: - -std::string genRandomId(); - - PhotoDataProxy *mPhotoProxy; - - RsMutex mPhotoMtx; - bool mUpdated; - - -}; - -#endif diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index a67c0a0e5..9966bd7ef 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -2,12 +2,12 @@ CONFIG += qt gui uic qrc resources uitools idle bitdht # Below is for GXS services. CONFIG += photoshare -#CONFIG += wikipoos -#CONFIG += thewire +#CONFIG += wikipoos +#CONFIG += thewire #CONFIG += identities -#CONFIG += forumsv2 -#CONFIG += posted -CONFIG += unfinished +#CONFIG += forumsv2 +#CONFIG += posted +CONFIG += unfinished #CONFIG += gxsgui #CONFIG += pluginmgr @@ -417,7 +417,7 @@ HEADERS += rshare.h \ gui/dht/DhtWindow.h \ gui/bwctrl/BwCtrlWindow.h \ gui/GetStartedDialog.h \ - gui/PhotoShare/PhotoCommentItem.h + @@ -520,8 +520,7 @@ FORMS += gui/StartDialog.ui \ gui/style/StyleDialog.ui \ gui/dht/DhtWindow.ui \ gui/bwctrl/BwCtrlWindow.ui \ - gui/GetStartedDialog.ui \ - gui/PhotoShare/PhotoCommentItem.ui + gui/GetStartedDialog.ui SOURCES += main.cpp \ rshare.cpp \ gui/notifyqt.cpp \ @@ -700,8 +699,8 @@ SOURCES += main.cpp \ gui/groups/CreateGroup.cpp \ gui/dht/DhtWindow.cpp \ gui/bwctrl/BwCtrlWindow.cpp \ - gui/GetStartedDialog.cpp \ - gui/PhotoShare/PhotoCommentItem.cpp + gui/GetStartedDialog.cpp + RESOURCES += gui/images.qrc lang/lang.qrc gui/help/content/content.qrc @@ -873,7 +872,9 @@ photoshare { gui/PhotoShare/PhotoShareItemHolder.h \ gui/PhotoShare/PhotoShare.h \ gui/PhotoShare/PhotoSlideShow.h \ - gui/PhotoShare/PhotoDialog.h + gui/PhotoShare/PhotoDialog.h \ + gui/PhotoShare/PhotoCommentItem.h \ + gui/PhotoShare/AddCommentDialog.h FORMS += \ gui/PhotoShare/PhotoItem.ui \ @@ -882,7 +883,9 @@ photoshare { gui/PhotoShare/AlbumDialog.ui \ gui/PhotoShare/AlbumCreateDialog.ui \ gui/PhotoShare/PhotoShare.ui \ - gui/PhotoShare/PhotoSlideShow.ui + gui/PhotoShare/PhotoSlideShow.ui \ + gui/PhotoShare/PhotoCommentItem.ui \ + gui/PhotoShare/AddCommentDialog.ui SOURCES += \ gui/PhotoShare/PhotoItem.cpp \ @@ -894,7 +897,9 @@ photoshare { util/TokenQueueV2.cpp \ gui/PhotoShare/PhotoShareItemHolder.cpp \ gui/PhotoShare/PhotoShare.cpp \ - gui/PhotoShare/PhotoSlideShow.cpp + gui/PhotoShare/PhotoSlideShow.cpp \ + gui/PhotoShare/PhotoCommentItem.cpp \ + gui/PhotoShare/AddCommentDialog.cpp } diff --git a/retroshare-gui/src/gui/PhotoShare/AddCommentDialog.cpp b/retroshare-gui/src/gui/PhotoShare/AddCommentDialog.cpp new file mode 100644 index 000000000..d77cd20b6 --- /dev/null +++ b/retroshare-gui/src/gui/PhotoShare/AddCommentDialog.cpp @@ -0,0 +1,19 @@ +#include "AddCommentDialog.h" +#include "ui_AddCommentDialog.h" + +AddCommentDialog::AddCommentDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::AddCommentDialog) +{ + ui->setupUi(this); +} + +AddCommentDialog::~AddCommentDialog() +{ + delete ui; +} + +QString AddCommentDialog::getComment() const +{ + return ui->textEditAddComment->document()->toPlainText(); +} diff --git a/retroshare-gui/src/gui/PhotoShare/AddCommentDialog.h b/retroshare-gui/src/gui/PhotoShare/AddCommentDialog.h new file mode 100644 index 000000000..f08aa65ca --- /dev/null +++ b/retroshare-gui/src/gui/PhotoShare/AddCommentDialog.h @@ -0,0 +1,23 @@ +#ifndef ADDCOMMENTDIALOG_H +#define ADDCOMMENTDIALOG_H + +#include + +namespace Ui { + class AddCommentDialog; +} + +class AddCommentDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AddCommentDialog(QWidget *parent = 0); + ~AddCommentDialog(); + QString getComment() const; + +private: + Ui::AddCommentDialog *ui; +}; + +#endif // ADDCOMMENTDIALOG_H diff --git a/retroshare-gui/src/gui/PhotoShare/AddCommentDialog.ui b/retroshare-gui/src/gui/PhotoShare/AddCommentDialog.ui new file mode 100644 index 000000000..d07b9f6dd --- /dev/null +++ b/retroshare-gui/src/gui/PhotoShare/AddCommentDialog.ui @@ -0,0 +1,67 @@ + + + AddCommentDialog + + + + 0 + 0 + 370 + 118 + + + + Add Comment + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + AddCommentDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AddCommentDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp index e40a46020..04e185fd5 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp @@ -69,7 +69,7 @@ bool AlbumCreateDialog::getAlbumThumbnail(RsPhotoThumbnail &nail) void AlbumCreateDialog::addAlbumThumbnail() { - QPixmap img = misc::getOpenThumbnailedPicture(this, tr("Load Album Thumbnail"), 64, 64); + QPixmap img = misc::getOpenThumbnailedPicture(this, tr("Load Album Thumbnail"), 128, 128); if (img.isNull()) return; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.cpp index c85d55b65..bef0d0c14 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.cpp @@ -1,14 +1,25 @@ #include "PhotoCommentItem.h" #include "ui_PhotoCommentItem.h" -PhotoCommentItem::PhotoCommentItem(QWidget *parent) : +PhotoCommentItem::PhotoCommentItem(const RsPhotoComment& comment, QWidget *parent): QWidget(parent), - ui(new Ui::PhotoCommentItem) + ui(new Ui::PhotoCommentItem), mComment(comment) { ui->setupUi(this); + setUp(); } PhotoCommentItem::~PhotoCommentItem() { delete ui; } + +const RsPhotoComment& PhotoCommentItem::getComment() +{ + return mComment; +} + +void PhotoCommentItem::setUp() +{ + ui->labelComment->setText(QString::fromStdString(mComment.mComment)); +} diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.h b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.h index 5480c685e..4f414839c 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.h @@ -2,6 +2,7 @@ #define PHOTOCOMMENTITEM_H #include +#include "retroshare/rsphotoV2.h" namespace Ui { class PhotoCommentItem; @@ -12,11 +13,17 @@ class PhotoCommentItem : public QWidget Q_OBJECT public: - explicit PhotoCommentItem(QWidget *parent = 0); + explicit PhotoCommentItem(const RsPhotoComment& comment, QWidget *parent = 0); ~PhotoCommentItem(); + const RsPhotoComment& getComment(); + +private: + + void setUp(); private: Ui::PhotoCommentItem *ui; + RsPhotoComment mComment; }; #endif // PHOTOCOMMENTITEM_H diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui index 78b7f8415..3ba829473 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui @@ -6,8 +6,8 @@ 0 0 - 484 - 110 + 479 + 89 @@ -30,7 +30,7 @@ border-radius: 10px;} - + QWidget#msgWidget{border: 2px solid #238; border-radius: 10px;} @@ -40,7 +40,7 @@ border-radius: 10px;} 5 - + 0 diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index a92d38db2..d28197e00 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -1,15 +1,22 @@ +#include +#include #include "PhotoDialog.h" #include "ui_PhotoDialog.h" + + PhotoDialog::PhotoDialog(RsPhotoV2 *rs_photo, const RsPhotoPhoto &photo, QWidget *parent) : QDialog(parent), ui(new Ui::PhotoDialog), mRsPhoto(rs_photo), mPhotoQueue(new TokenQueueV2(mRsPhoto->getTokenService(), this)), - mPhotoDetails(photo) + mPhotoDetails(photo), mCommentDialog(NULL) { ui->setupUi(this); setAttribute ( Qt::WA_DeleteOnClose, true ); setUp(); + connect(ui->toolButton_AddComment, SIGNAL(clicked()), this, SLOT(addComment())); + + } PhotoDialog::~PhotoDialog() @@ -24,15 +31,155 @@ void PhotoDialog::setUp() qtn.loadFromData(mPhotoDetails.mThumbnail.data, mPhotoDetails.mThumbnail.size, mPhotoDetails.mThumbnail.type.c_str()); ui->label_Photo->setPixmap(qtn); ui->lineEdit_Title->setText(QString::fromStdString(mPhotoDetails.mMeta.mMsgName)); + + ui->scrollAreaWidgetContents->setLayout(new QVBoxLayout()); } -void PhotoDialog::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req) -{ -} void PhotoDialog::addComment() { + mCommentDialog = new AddCommentDialog(this); + connect(mCommentDialog, SIGNAL(accepted()), this, SLOT(createComment())); + connect(mCommentDialog, SIGNAL(rejected()), mCommentDialog, SLOT(deleteLater())); + mCommentDialog->exec(); +} + +void PhotoDialog::clearComments() +{ + QLayout* l = ui->scrollAreaWidgetContents->layout(); + QSetIterator sit(mComments); + while(sit.hasNext()) + { + PhotoCommentItem* item = sit.next(); + l->removeWidget(item); + item->setParent(NULL); + } +} + +void PhotoDialog::resetComments() +{ + clearComments(); + + QSetIterator sit(mComments); + QLayout* l = ui->scrollAreaWidgetContents->layout(); + while(sit.hasNext()) + { + PhotoCommentItem* item = sit.next(); + l->addWidget(item); + } +} + +void PhotoDialog::createComment() +{ + if(mCommentDialog) + { + RsPhotoComment comment; + QString commentString = mCommentDialog->getComment(); + + comment.mComment = commentString.toStdString(); + + uint32_t token; + comment.mMeta.mGroupId = mPhotoDetails.mMeta.mGroupId; + mRsPhoto->submitComment(token, comment); + mPhotoQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); + + mCommentDialog->close(); + delete mCommentDialog; + mCommentDialog = NULL; + } +} + + +/*************** message loading **********************/ + +void PhotoDialog::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req) +{ + std::cerr << "PhotoShare::loadRequest()"; + std::cerr << std::endl; + + if (queue == mPhotoQueue) + { + /* now switch on req */ + switch(req.mType) + { + case TOKENREQ_MSGINFO: + { + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_DATA: + loadComment(req.mToken); + break; + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgeComment(req.mToken); + break; + default: + std::cerr << "PhotoShare::loadRequest() ERROR: MSG INVALID TYPE"; + std::cerr << std::endl; + break; + } + break; + } + + default: + { + std::cerr << "PhotoShare::loadRequest() ERROR: INVALID TYPE"; + std::cerr << std::endl; + break; + } + } + } } + +void PhotoDialog::loadComment(uint32_t token) +{ + + PhotoCommentResult results; + mRsPhoto->getPhotoComment(token, results); + + PhotoCommentResult::iterator mit = results.begin(); + + for(; mit != results.end(); mit++) + { + const std::vector& commentV = mit->second; + std::vector::const_iterator vit = commentV.begin(); + + for(; vit != commentV.end(); vit++) + { + addComment(*vit); + } + } + + resetComments(); +} + +void PhotoDialog::addComment(const RsPhotoComment &comment) +{ + PhotoCommentItem* item = new PhotoCommentItem(comment); + mComments.insert(item); +} + +void PhotoDialog::acknowledgeComment(uint32_t token) +{ + RsGxsGrpMsgIdPair msgId; + mRsPhoto->acknowledgeMsg(token, msgId); + + if(msgId.first.empty() || msgId.second.empty()){ + + }else + { + uint32_t reqToken; + RsTokReqOptionsV2 opts; + opts.mMsgFlagMask = RsPhotoV2::FLAG_MSG_TYPE_MASK; + opts.mMsgFlagFilter = RsPhotoV2::FLAG_MSG_TYPE_PHOTO_COMMENT; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + GxsMsgReq req; + std::vector msgIdsV; + msgIdsV.push_back(msgId.second); + req.insert(std::make_pair(msgId.first, msgIdsV)); + mPhotoQueue->requestMsgInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, req, 0); + } +} + diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h index 4d3750ca9..151c054fc 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h @@ -2,8 +2,11 @@ #define PHOTODIALOG_H #include +#include #include "retroshare/rsphotoV2.h" #include "util/TokenQueueV2.h" +#include "PhotoCommentItem.h" +#include "AddCommentDialog.h" namespace Ui { class PhotoDialog; @@ -20,17 +23,35 @@ public: private slots: void addComment(); + void createComment(); public: void loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req); private: void setUp(); + + /*! + * clears comments + * and places them back in dialog + */ + void resetComments(); + + /*! + * Simply removes comments but doesn't place them back in dialog + */ + void clearComments(); + + void acknowledgeComment(uint32_t token); + void loadComment(uint32_t token); + void addComment(const RsPhotoComment& comment); private: Ui::PhotoDialog *ui; RsPhotoV2* mRsPhoto; TokenQueueV2* mPhotoQueue; RsPhotoPhoto mPhotoDetails; + QSet mComments; + AddCommentDialog* mCommentDialog; }; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui index 6b1ff2dba..6631999cc 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui @@ -7,7 +7,7 @@ 0 0 516 - 449 + 460 @@ -173,7 +173,7 @@ - + Add Comment @@ -195,14 +195,11 @@ - + true - - Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - - + 0 @@ -211,24 +208,6 @@ 69 - - QWidget#scrollAreaWidgetContents{border: none;} - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp index d46f40f67..7f9e89968 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp @@ -178,7 +178,12 @@ void PhotoShare::checkUpdate() std::list grpIds; rsPhotoV2->groupsChanged(grpIds); if(!grpIds.empty()) - requestAlbumList(grpIds); + { + RsTokReqOptionsV2 opts; + uint32_t token; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); + } GxsMsgIdResult res; rsPhotoV2->msgsChanged(res); diff --git a/retroshare-gui/src/util/TokenQueueV2.cpp b/retroshare-gui/src/util/TokenQueueV2.cpp index c35d33400..7b6fce9d1 100644 --- a/retroshare-gui/src/util/TokenQueueV2.cpp +++ b/retroshare-gui/src/util/TokenQueueV2.cpp @@ -66,11 +66,12 @@ bool TokenQueueV2::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTok return true; } -bool TokenQueueV2::requestMsgRelatedInfo(uint32_t &token, const RsTokReqOptionsV2 &opts, const GxsMsgReq& msgIds, uint32_t usertype) + +bool TokenQueueV2::requestMsgRelatedInfo(uint32_t &token, const RsTokReqOptionsV2 &opts, const RsGxsGrpMsgIdPair &msgId, uint32_t usertype) { uint32_t basictype = TOKENREQ_MSGINFO; uint32_t anstype = RS_TOKREQ_ANSTYPE_LIST; // always a list answer - mService->requestMsgRelatedInfo(token, anstype, opts, msgIds); + mService->requestMsgRelatedInfo(token, anstype, opts, msgId); queueRequest(token, basictype, anstype, usertype); return true; @@ -154,8 +155,8 @@ bool TokenQueueV2::checkForRequest(uint32_t token) { /* check token */ uint32_t status = mService->requestStatus(token); - return ( (RsTokenServiceV2::GXS_REQUEST_STATUS_FAILED == status) || - (RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE == status) ); + return ( (RsTokenServiceV2::GXS_REQUEST_V2_STATUS_FAILED == status) || + (RsTokenServiceV2::GXS_REQUEST_V2_STATUS_COMPLETE == status) ); } diff --git a/retroshare-gui/src/util/TokenQueueV2.h b/retroshare-gui/src/util/TokenQueueV2.h index 0d7aa9b6b..d2279ba47 100644 --- a/retroshare-gui/src/util/TokenQueueV2.h +++ b/retroshare-gui/src/util/TokenQueueV2.h @@ -94,7 +94,7 @@ public: bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, const GxsMsgReq& grpIds, uint32_t usertype); - bool requestMsgRelatedInfo(uint32_t &token, const RsTokReqOptionsV2 &opts, const GxsMsgReq& msgIds, uint32_t usertype); + bool requestMsgRelatedInfo(uint32_t &token, const RsTokReqOptionsV2 &opts, const RsGxsGrpMsgIdPair& msgId, uint32_t usertype); bool cancelRequest(const uint32_t token); diff --git a/retroshare-gui/src/util/TokenQueueVEG.h b/retroshare-gui/src/util/TokenQueueVEG.h index 4f6b5a667..eca5a431a 100644 --- a/retroshare-gui/src/util/TokenQueueVEG.h +++ b/retroshare-gui/src/util/TokenQueueVEG.h @@ -56,7 +56,7 @@ class TokenResponseVEG public: //virtual ~TokenResponse() { return; } // These Functions are overloaded to get results out. - virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req) = 0; + virtual void loadRequest(const TokenQueueVEG *queue, const TokenRequestVEG &req) = 0; }; From bdd6c6041b64cda166cda1780e87aaf13f6db325 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Thu, 27 Sep 2012 21:42:00 +0000 Subject: [PATCH 070/222] Updated GXS tests, lots of mem leak fixes from valgrind run. - mem leak caused by not deleting stored msgs and groups, rsdatastore now a group/msg sink - mem leak caused in rsgxsnetservice by not deleting meta information after retrieval - fixed mem leak in rstlvkeyset::getTlv due to tlvbindata making own data copy git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5616 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsdataservice.cc | 30 +++++++++++++++++-- libretroshare/src/gxs/rsgenexchange.cc | 20 +++++++------ libretroshare/src/gxs/rsgxsnetservice.cc | 3 ++ libretroshare/src/serialiser/rstlvkeys.cc | 2 +- .../src/tests/gxs/genexchangetester.cpp | 5 ++-- libretroshare/src/tests/gxs/nxs_tests.pro | 25 +++++++++++++++- .../src/tests/gxs/nxstestscenario.cc | 20 ------------- .../src/tests/gxs/rsdataservice_test.cc | 29 +++++++++++++++--- .../src/tests/gxs/rsgenexchange_test.cc | 14 ++++----- 9 files changed, 101 insertions(+), 47 deletions(-) diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index 1fbfbaf15..ec8e56997 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -508,7 +508,19 @@ int RsDataService::storeMessage(std::map &msg) } // finish transaction - return mDb->execSQL("COMMIT;"); + bool ret = mDb->execSQL("COMMIT;"); + + for(mit = msg.begin(); mit != msg.end(); mit++) + { + //TODO: API encourages aliasing, remove this abomination + if(mit->second != mit->first->metaData) + delete mit->second; + + delete mit->first; + ; + } + + return ret; } @@ -519,7 +531,8 @@ int RsDataService::storeGroup(std::map &grp) // begin transaction mDb->execSQL("BEGIN;"); - for(; sit != grp.end(); sit++){ + for(; sit != grp.end(); sit++) + { RsNxsGrp* grpPtr = sit->first; RsGxsGrpMetaData* grpMetaPtr = sit->second; @@ -589,7 +602,18 @@ int RsDataService::storeGroup(std::map &grp) mDb->sqlInsert(GRP_TABLE_NAME, "", cv); } // finish transaction - return mDb->execSQL("COMMIT;"); + bool ret = mDb->execSQL("COMMIT;"); + + for(sit = grp.begin(); sit != grp.end(); sit++) + { + //TODO: API encourages aliasing, remove this abomination + if(sit->second != sit->first->metaData) + delete sit->second; + delete sit->first; + + } + + return ret; } int RsDataService::retrieveNxsGrps(std::map &grp, bool withMeta, bool cache){ diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index ea52c3f17..15e5bf7dd 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -564,8 +564,9 @@ void RsGenExchange::publishMsgs() msg->metaData->serialise(metaDataBuff, &size); msg->meta.setBinData(metaDataBuff, size); - ok = createMessage(msg); - + ok = createMessage(msg); + RsGxsMessageId msgId; + RsGxsGroupId grpId; if(ok) { msg->metaData->mPublishTs = time(NULL); @@ -581,12 +582,13 @@ void RsGenExchange::publishMsgs() { msg->metaData->mOrigMsgId = msg->metaData->mMsgId; } - + msgId = msg->msgId; + grpId = msg->grpId; ok = mDataAccess->addMsgData(msg); } // add to published to allow acknowledgement - mMsgNotify.insert(std::make_pair(mit->first, std::make_pair(msg->grpId, msg->msgId))); + mMsgNotify.insert(std::make_pair(mit->first, std::make_pair(grpId, msgId))); mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_V2_STATUS_COMPLETE); } @@ -597,7 +599,7 @@ void RsGenExchange::publishMsgs() std::cerr << "RsGenExchange::publishMsgs() failed to publish msg " << std::endl; #endif mMsgNotify.insert(std::make_pair(mit->first, std::make_pair(RsGxsGroupId(""), RsGxsMessageId("")))); - delete msg; + continue; } @@ -640,11 +642,11 @@ void RsGenExchange::publishGrps() grp->metaData->mGroupId = grp->grpId; ok = grp->metaData->serialise(mData, size); grp->meta.setBinData(mData, size); - - ok = mDataAccess->addGroupData(grp); + RsGxsGroupId grpId = grp->grpId; + mDataAccess->addGroupData(grp); // add to published to allow acknowledgement - mGrpNotify.insert(std::make_pair(mit->first, grp->grpId)); + mGrpNotify.insert(std::make_pair(mit->first, grpId)); mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_V2_STATUS_COMPLETE); } @@ -695,7 +697,7 @@ void RsGenExchange::createDummyGroup(RsGxsGrpItem *grpItem) ok = grp->metaData->serialise(mData, size); grp->meta.setBinData(mData, size); - ok = mDataAccess->addGroupData(grp); + mDataAccess->addGroupData(grp); } if(!ok) diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 884b1760d..c5dae6263 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -100,6 +100,8 @@ void RsGxsNetService::syncWithPeers() if(meta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) grpIds.push_back(mit->first); + + delete meta; } sit = peers.begin(); @@ -1131,6 +1133,7 @@ void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrp* item) gItem->PeerId(peer); gItem->transactionNumber = transN; itemL.push_back(gItem); + delete mit->second; // release resource } tr->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM; diff --git a/libretroshare/src/serialiser/rstlvkeys.cc b/libretroshare/src/serialiser/rstlvkeys.cc index 1a6f2663f..089517f86 100644 --- a/libretroshare/src/serialiser/rstlvkeys.cc +++ b/libretroshare/src/serialiser/rstlvkeys.cc @@ -322,7 +322,7 @@ bool RsTlvSecurityKeySet::GetTlv(void *data, uint32_t size, uint32_t *offset) / if (ok) { keys[key.keyId] = key; - key.ShallowClear(); /* so that the Map can get control - should be ref counted*/ + key.TlvClear(); /* so that the Map can get control - should be ref counted*/ } } break; diff --git a/libretroshare/src/tests/gxs/genexchangetester.cpp b/libretroshare/src/tests/gxs/genexchangetester.cpp index 88bbf39ae..5826e1fcb 100644 --- a/libretroshare/src/tests/gxs/genexchangetester.cpp +++ b/libretroshare/src/tests/gxs/genexchangetester.cpp @@ -1,6 +1,7 @@ #include "genexchangetester.h" #include "support.h" #include "gxs/rsdataservice.h" +#include "gxs/rsgxsflags.h" GenExchangeTester::GenExchangeTester() @@ -1404,7 +1405,7 @@ void GenExchangeTester::init(RsGroupMetaData &grpMeta) const grpMeta.mPop = randNum(); grpMeta.mSignFlags = randNum(); grpMeta.mPublishTs = randNum(); - grpMeta.mSubscribeFlags = randNum(); + grpMeta.mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; } @@ -1510,7 +1511,7 @@ void GenExchangeTester::pollForToken(uint32_t token, const RsTokReqOptionsV2 &op Sleep((int) (timeDelta * 1000)); #endif - if(RsTokenServiceV2::GXS_REQUEST_STATUS_COMPLETE == + if(RsTokenServiceV2::GXS_REQUEST_V2_STATUS_COMPLETE == mTokenService->requestStatus(token)) { switch(opts.mReqType) diff --git a/libretroshare/src/tests/gxs/nxs_tests.pro b/libretroshare/src/tests/gxs/nxs_tests.pro index 977c90e2c..feda6172d 100644 --- a/libretroshare/src/tests/gxs/nxs_tests.pro +++ b/libretroshare/src/tests/gxs/nxs_tests.pro @@ -10,7 +10,7 @@ QT += core network QT -= gui -CONFIG += gen_exchange_target #dstore_target +CONFIG += dstore_target #gen_exchange_target # #nxs_net_test dstore_target { @@ -24,6 +24,12 @@ TARGET = gen_exchange_test } +nxs_net_test { + +TARGET = nxs_net_test + +} + CONFIG += console CONFIG -= app_bundle @@ -187,4 +193,21 @@ gen_exchange_target { } +nxs_net_test { + + SOURCES += \ + support.cc \ + nxstesthub.cc \ + rsgxsnetservice_test.cc \ + nxstestscenario.cc \ + data_support.cc + + + HEADERS += support.h \ + nxstesthub.h \ + rsgxsnetservice_test.h \ + nxstestscenario.h \ + data_support.h +} + INCLUDEPATH += ../../ diff --git a/libretroshare/src/tests/gxs/nxstestscenario.cc b/libretroshare/src/tests/gxs/nxstestscenario.cc index e5806a8a9..e6973cf0c 100644 --- a/libretroshare/src/tests/gxs/nxstestscenario.cc +++ b/libretroshare/src/tests/gxs/nxstestscenario.cc @@ -82,16 +82,6 @@ void NxsMessageTest::populateStore(RsGeneralDataService* dStore) dStore->storeGroup(grps); - - std::map::iterator grp_it - = grps.begin(); - for(; grp_it != grps.end(); grp_it++) - { - delete grp_it->first; - delete grp_it->second; - } - - int nMsgs = rand()%23; std::map msgs; RsNxsMsg* msg = NULL; @@ -119,16 +109,6 @@ void NxsMessageTest::populateStore(RsGeneralDataService* dStore) dStore->storeMessage(msgs); - // clean up - std::map::iterator msg_it - = msgs.begin(); - - for(; msg_it != msgs.end(); msg_it++) - { - delete msg_it->first; - delete msg_it->second; - } - return; } diff --git a/libretroshare/src/tests/gxs/rsdataservice_test.cc b/libretroshare/src/tests/gxs/rsdataservice_test.cc index af5155773..e1d0243fe 100644 --- a/libretroshare/src/tests/gxs/rsdataservice_test.cc +++ b/libretroshare/src/tests/gxs/rsdataservice_test.cc @@ -38,7 +38,7 @@ void test_groupStoreAndRetrieve(){ setUp(); int nGrp = rand()%32; - std::map grps; + std::map grps, grps_copy; RsNxsGrp* grp; RsGxsGrpMetaData* grpMeta; for(int i = 0; i < nGrp; i++){ @@ -51,13 +51,21 @@ void test_groupStoreAndRetrieve(){ init_item(grpMeta); grpMeta->mGroupId = grp->grpId; grps.insert(p); - + RsNxsGrp* grp_copy = new RsNxsGrp(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); + *grp_copy = *grp; + RsGxsGrpMetaData* grpMeta_copy = new RsGxsGrpMetaData(); + *grpMeta_copy = *grpMeta; + grps_copy.insert(std::make_pair(grp_copy, grpMeta_copy )); grpMeta = NULL; grp = NULL; } dStore->storeGroup(grps); + //use copy, a grps are deleted in store + grps.clear(); + grps = grps_copy; + std::map gR; std::map grpMetaR; dStore->retrieveNxsGrps(gR, false, false); @@ -141,6 +149,7 @@ void test_messageStoresAndRetrieve() grpV.push_back(grpId1); std::map msgs; + std::map msgs_copy; RsNxsMsg* msg = NULL; RsGxsMsgMetaData* msgMeta = NULL; int nMsgs = rand()%120; @@ -170,9 +179,15 @@ void test_messageStoresAndRetrieve() msgMeta->mMsgId = msg->msgId; msgMeta->mGroupId = msg->grpId = grpId; + RsNxsMsg* msg_copy = new RsNxsMsg(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); + RsGxsMsgMetaData* msgMeta_copy = new RsGxsMsgMetaData(); + + *msg_copy = *msg; + *msgMeta_copy = *msgMeta; + // store msgs in map to use for verification - std::pair vP(msg->msgId, msg); - std::pair vPmeta(msg->msgId, msgMeta); + std::pair vP(msg->msgId, msg_copy); + std::pair vPmeta(msg->msgId, msgMeta_copy); if(!chosen) { @@ -184,15 +199,21 @@ void test_messageStoresAndRetrieve() VergrpId1.insert(vP); VerMetagrpId0.insert(vPmeta); } + + + msg = NULL; msgMeta = NULL; msgs.insert(p); + msgs_copy.insert(std::make_pair(msg_copy, msgMeta_copy)); } req[grpV[0]] = std::vector(); // assign empty list for other dStore->storeMessage(msgs); + msgs.clear(); + msgs = msgs_copy; // now retrieve msgs for comparison // first selective retrieval diff --git a/libretroshare/src/tests/gxs/rsgenexchange_test.cc b/libretroshare/src/tests/gxs/rsgenexchange_test.cc index c60c2eb96..2a6769a37 100644 --- a/libretroshare/src/tests/gxs/rsgenexchange_test.cc +++ b/libretroshare/src/tests/gxs/rsgenexchange_test.cc @@ -17,16 +17,16 @@ int main() // CHECK(tester.testMsgSubmissionRetrieval()); REPORT("testMsgSubmissionRetrieval()"); // CHECK(tester.testSpecificMsgMetaRetrieval()); REPORT("testSpecificMsgMetaRetrieval()"); // CHECK(tester.testMsgIdRetrieval()); REPORT("tester.testMsgIdRetrieval()"); - //CHECK(tester.testMsgIdRetrieval_OptParents()); REPORT("tester.testRelatedMsgIdRetrieval_Parents()"); +// CHECK(tester.testMsgIdRetrieval_OptParents()); REPORT("tester.testRelatedMsgIdRetrieval_Parents()"); // CHECK(tester.testMsgIdRetrieval_OptOrigMsgId()); REPORT("tester.testRelatedMsgIdRetrieval_OrigMsgId()"); // CHECK(tester.testMsgIdRetrieval_OptLatest()); REPORT("tester.testRelatedMsgIdRetrieval_Latest()"); - //CHECK(tester.testMsgMetaModRequest()); REPORT("tester.testMsgMetaModRequest()"); - CHECK(tester.testMsgChildRetrieval()); REPORT("tester.testMsgMetaModRequest()"); +// CHECK(tester.testMsgMetaModRequest()); REPORT("tester.testMsgMetaModRequest()"); +// CHECK(tester.testMsgChildRetrieval()); REPORT("tester.testMsgMetaModRequest()"); -// CHECK(tester.testGrpSubmissionRetrieval()); REPORT("tester.testGrpSubmissionRetrieval()"); -// CHECK(tester.testGrpMetaRetrieval()); REPORT("tester.testGrpMetaRetrieval()"); -// CHECK(tester.testGrpIdRetrieval()); REPORT("tester.testGrpIdRetrieval()"); -// CHECK(tester.testGrpMetaModRequest()); REPORT("tester.testGrpMetaModRequest()"); + CHECK(tester.testGrpSubmissionRetrieval()); REPORT("tester.testGrpSubmissionRetrieval()"); + CHECK(tester.testGrpMetaRetrieval()); REPORT("tester.testGrpMetaRetrieval()"); + CHECK(tester.testGrpIdRetrieval()); REPORT("tester.testGrpIdRetrieval()"); + CHECK(tester.testGrpMetaModRequest()); REPORT("tester.testGrpMetaModRequest()"); FINALREPORT("RsGenExchangeTest"); From b06214b779f233645ddf0d8ab69005c770e8605d Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sun, 30 Sep 2012 14:21:17 +0000 Subject: [PATCH 071/222] Message Synchronisation now supported by photoshare (photo and comments sync) Photoshare UI now functional - subscribing to an album enables message sync - TokenQueue now operate with FIFO stack to prevent overlap in request completion - photos are now load on demand as with comments - fixed some noddy bugs (subscribe flag initialises incorrectly) git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5624 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgenexchange.cc | 71 ++++++++++-- libretroshare/src/gxs/rsgxsdata.cc | 2 +- libretroshare/src/gxs/rsgxsnetservice.cc | 25 +++-- .../src/services/p3photoserviceV2.cc | 8 ++ .../src/gui/PhotoShare/PhotoCommentItem.ui | 16 ++- .../src/gui/PhotoShare/PhotoDialog.cpp | 54 ++++++--- .../src/gui/PhotoShare/PhotoDialog.h | 6 + .../src/gui/PhotoShare/PhotoItem.cpp | 6 +- .../src/gui/PhotoShare/PhotoShare.cpp | 103 ++++++++++++------ .../src/gui/PhotoShare/PhotoShare.h | 7 +- retroshare-gui/src/util/TokenQueueV2.cpp | 37 +++---- retroshare-gui/src/util/TokenQueueV2.h | 7 +- 12 files changed, 240 insertions(+), 102 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 15e5bf7dd..6c5327341 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -558,11 +558,6 @@ void RsGenExchange::publishMsgs() msg->metaData = new RsGxsMsgMetaData(); msg->msg.setBinData(mData, size); *(msg->metaData) = msgItem->meta; - size = msg->metaData->serial_size(); - char metaDataBuff[size]; - - msg->metaData->serialise(metaDataBuff, &size); - msg->meta.setBinData(metaDataBuff, size); ok = createMessage(msg); RsGxsMessageId msgId; @@ -582,6 +577,14 @@ void RsGenExchange::publishMsgs() { msg->metaData->mOrigMsgId = msg->metaData->mMsgId; } + + // now serialise meta data + size = msg->metaData->serial_size(); + char metaDataBuff[size]; + msg->metaData->serialise(metaDataBuff, &size); + msg->meta.setBinData(metaDataBuff, size); + + msgId = msg->msgId; grpId = msg->grpId; ok = mDataAccess->addMsgData(msg); @@ -716,11 +719,50 @@ void RsGenExchange::createDummyGroup(RsGxsGrpItem *grpItem) void RsGenExchange::processRecvdData() { processRecvdGroups(); + + processRecvdMessages(); } void RsGenExchange::processRecvdMessages() { + RsStackMutex stack(mGenMtx); + + std::vector::iterator vit = mReceivedMsgs.begin(); + GxsMsgReq msgIds; + std::map msgs; + + for(; vit != mReceivedMsgs.end(); vit++) + { + RsNxsMsg* msg = *vit; + RsGxsMsgMetaData* meta = new RsGxsMsgMetaData(); + bool ok = meta->deserialise(msg->meta.bin_data, &(msg->meta.bin_len)); + + if(ok) + { + msgs.insert(std::make_pair(msg, meta)); + msgIds[msg->grpId].push_back(msg->msgId); + } + else + { +#ifdef GXS_GENX_DEBUG + std::cerr << "failed to deserialise incoming meta, grpId: " + << msg->grpId << ", msgId: " << msg->msgId << std::endl; +#endif + delete msg; + delete meta; + } + } + + if(!msgIds.empty()) + { + mDataStore->storeMessage(msgs); + RsGxsMsgChange* c = new RsGxsMsgChange(); + c->msgChangeMap = msgIds; + mNotifications.push_back(c); + } + + mReceivedMsgs.clear(); } @@ -737,11 +779,22 @@ void RsGenExchange::processRecvdGroups() { RsNxsGrp* grp = *vit; RsGxsGrpMetaData* meta = new RsGxsGrpMetaData(); - meta->deserialise(grp->meta.bin_data, grp->meta.bin_len); - grps.insert(std::make_pair(grp, meta)); - - grpIds.push_back(grp->grpId); + bool ok = meta->deserialise(grp->meta.bin_data, grp->meta.bin_len); + if(ok) + { + grps.insert(std::make_pair(grp, meta)); + grpIds.push_back(grp->grpId); + } + else + { +#ifdef GXS_GENX_DEBUG + std::cerr << "failed to deserialise incoming meta, grpId: " + << grp->grpId << std::endl; +#endif + delete grp; + delete meta; + } } if(!grpIds.empty()) diff --git a/libretroshare/src/gxs/rsgxsdata.cc b/libretroshare/src/gxs/rsgxsdata.cc index 7b3bc59e3..d148a762b 100644 --- a/libretroshare/src/gxs/rsgxsdata.cc +++ b/libretroshare/src/gxs/rsgxsdata.cc @@ -30,7 +30,7 @@ RsGxsGrpMetaData::RsGxsGrpMetaData() { - + clear(); } uint32_t RsGxsGrpMetaData::serial_size() diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index c5dae6263..073b9b12f 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -98,7 +98,8 @@ void RsGxsNetService::syncWithPeers() { RsGxsGrpMetaData* meta = mit->second; - if(meta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) + if(meta->mSubscribeFlags & (GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED | + GXS_SERV::GROUP_SUBSCRIBE_ADMIN) ) grpIds.push_back(mit->first); delete meta; @@ -106,21 +107,21 @@ void RsGxsNetService::syncWithPeers() sit = peers.begin(); - // TODO msgs + // synchronise group msg for groups which we're subscribed to for(; sit != peers.end(); sit++) { - RsStackMutex stack(mNxsMutex); + RsStackMutex stack(mNxsMutex); - std::vector::iterator vit = grpIds.begin(); + std::vector::iterator vit = grpIds.begin(); - for(; vit != grpIds.end(); vit++) - { - RsNxsSyncMsg* msg = new RsNxsSyncMsg(mServType); - msg->clear(); - msg->PeerId(*sit); - msg->grpId = *vit; - sendItem(msg); - } + for(; vit != grpIds.end(); vit++) + { + RsNxsSyncMsg* msg = new RsNxsSyncMsg(mServType); + msg->clear(); + msg->PeerId(*sit); + msg->grpId = *vit; + sendItem(msg); + } } } diff --git a/libretroshare/src/services/p3photoserviceV2.cc b/libretroshare/src/services/p3photoserviceV2.cc index cce6b3952..f9bbf01ff 100644 --- a/libretroshare/src/services/p3photoserviceV2.cc +++ b/libretroshare/src/services/p3photoserviceV2.cc @@ -126,7 +126,15 @@ void p3PhotoServiceV2::groupsChanged(std::list& grpIds) void p3PhotoServiceV2::msgsChanged( std::map >& msgs) { + RsStackMutex stack(mPhotoMutex); + while(!mMsgChange.empty()) + { + RsGxsMsgChange* mc = mMsgChange.back(); + msgs = mc->msgChangeMap; + mMsgChange.pop_back(); + delete mc; + } } diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui index 3ba829473..792a69107 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui @@ -6,8 +6,8 @@ 0 0 - 479 - 89 + 411 + 84 @@ -16,6 +16,18 @@ + + + 0 + 0 + + + + + 400 + 71 + + QFrame#expandFrame{border: 2px solid #D3D3D3; background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index d28197e00..a8469cace 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -13,9 +13,8 @@ PhotoDialog::PhotoDialog(RsPhotoV2 *rs_photo, const RsPhotoPhoto &photo, QWidget { ui->setupUi(this); setAttribute ( Qt::WA_DeleteOnClose, true ); - setUp(); connect(ui->toolButton_AddComment, SIGNAL(clicked()), this, SLOT(addComment())); - + setUp(); } @@ -33,6 +32,8 @@ void PhotoDialog::setUp() ui->lineEdit_Title->setText(QString::fromStdString(mPhotoDetails.mMeta.mMsgName)); ui->scrollAreaWidgetContents->setLayout(new QVBoxLayout()); + + requestComments(); } @@ -55,13 +56,14 @@ void PhotoDialog::clearComments() PhotoCommentItem* item = sit.next(); l->removeWidget(item); item->setParent(NULL); + delete item; } + + mComments.clear(); } void PhotoDialog::resetComments() { - clearComments(); - QSetIterator sit(mComments); QLayout* l = ui->scrollAreaWidgetContents->layout(); while(sit.hasNext()) @@ -71,6 +73,21 @@ void PhotoDialog::resetComments() } } +void PhotoDialog::requestComments() +{ + RsTokReqOptionsV2 opts; + opts.mMsgFlagMask = RsPhotoV2::FLAG_MSG_TYPE_MASK; + opts.mMsgFlagFilter = RsPhotoV2::FLAG_MSG_TYPE_PHOTO_COMMENT; + + opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; + opts.mOptions = RS_TOKREQOPT_MSG_PARENT | RS_TOKREQOPT_MSG_LATEST; + RsGxsGrpMsgIdPair msgId; + uint32_t token; + msgId.first = mPhotoDetails.mMeta.mGroupId; + msgId.second = mPhotoDetails.mMeta.mMsgId; + mPhotoQueue->requestMsgRelatedInfo(token, opts, msgId, 0); +} + void PhotoDialog::createComment() { if(mCommentDialog) @@ -82,6 +99,7 @@ void PhotoDialog::createComment() uint32_t token; comment.mMeta.mGroupId = mPhotoDetails.mMeta.mGroupId; + comment.mMeta.mParentId = mPhotoDetails.mMeta.mOrigMsgId; mRsPhoto->submitComment(token, comment); mPhotoQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); @@ -111,6 +129,9 @@ void PhotoDialog::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &r case RS_TOKREQ_ANSTYPE_DATA: loadComment(req.mToken); break; + case RS_TOKREQ_ANSTYPE_LIST: + loadList(req.mToken); + break; case RS_TOKREQ_ANSTYPE_ACK: acknowledgeComment(req.mToken); break; @@ -136,6 +157,8 @@ void PhotoDialog::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &r void PhotoDialog::loadComment(uint32_t token) { + clearComments(); + PhotoCommentResult results; mRsPhoto->getPhotoComment(token, results); @@ -155,6 +178,18 @@ void PhotoDialog::loadComment(uint32_t token) resetComments(); } +void PhotoDialog::loadList(uint32_t token) +{ + GxsMsgReq msgIds; + mRsPhoto->getMsgList(token, msgIds); + RsTokReqOptionsV2 opts; + + // just use data as no need to worry about getting comments + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + uint32_t reqToken; + mPhotoQueue->requestMsgInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, 0); +} + void PhotoDialog::addComment(const RsPhotoComment &comment) { PhotoCommentItem* item = new PhotoCommentItem(comment); @@ -170,16 +205,7 @@ void PhotoDialog::acknowledgeComment(uint32_t token) }else { - uint32_t reqToken; - RsTokReqOptionsV2 opts; - opts.mMsgFlagMask = RsPhotoV2::FLAG_MSG_TYPE_MASK; - opts.mMsgFlagFilter = RsPhotoV2::FLAG_MSG_TYPE_PHOTO_COMMENT; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - GxsMsgReq req; - std::vector msgIdsV; - msgIdsV.push_back(msgId.second); - req.insert(std::make_pair(msgId.first, msgIdsV)); - mPhotoQueue->requestMsgInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, req, 0); + requestComments(); } } diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h index 151c054fc..0eb9fa5ee 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h @@ -36,6 +36,11 @@ private: */ void resetComments(); + /*! + * Request comments + */ + void requestComments(); + /*! * Simply removes comments but doesn't place them back in dialog */ @@ -43,6 +48,7 @@ private: void acknowledgeComment(uint32_t token); void loadComment(uint32_t token); + void loadList(uint32_t token); void addComment(const RsPhotoComment& comment); private: Ui::PhotoDialog *ui; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp index 71b5dadc5..c3506d52b 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp @@ -32,12 +32,12 @@ PhotoItem::PhotoItem(PhotoShareItemHolder *holder, const QString& path, QWidget { ui->setupUi(this); - int width = 120; - int height = 120; + int width = 250; + int height = 250; QPixmap qtn = QPixmap(path).scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation); - ui->label_Thumbnail->setPixmap(qtn); mThumbNail = qtn; + ui->label_Thumbnail->setPixmap(mThumbNail.scaled(120, 120, Qt::KeepAspectRatio, Qt::SmoothTransformation)); setSelected(false); getPhotoThumbnail(mPhotoDetails.mThumbnail); diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp index 7f9e89968..ff42ac285 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp @@ -98,7 +98,6 @@ PhotoShare::PhotoShare(QWidget *parent) /* setup TokenQueue */ mPhotoQueue = new TokenQueueV2(rsPhotoV2->getTokenService(), this); requestAlbumData(); - updateAlbums(); } void PhotoShare::notifySelection(PhotoShareItem *selection) @@ -113,8 +112,6 @@ void PhotoShare::notifySelection(PhotoShareItem *selection) if(mPhotoSelected) mPhotoSelected->setSelected(false); - clearPhotos(); - if(mAlbumSelected == aItem) { mAlbumSelected->setSelected(true); @@ -133,9 +130,11 @@ void PhotoShare::notifySelection(PhotoShareItem *selection) mAlbumSelected->setSelected(true); + // get photo data + std::list grpIds; + grpIds.push_back(mAlbumSelected->getAlbum().mMeta.mGroupId); + requestPhotoData(grpIds); } - - updatePhotos(); } else if((pItem = dynamic_cast(selection)) != NULL) { @@ -283,6 +282,8 @@ void PhotoShare::SetPhotoDialogClosed() void PhotoShare::clearAlbums() { + clearPhotos(); + std::cerr << "PhotoShare::clearAlbums()" << std::endl; QLayout *alayout = ui.scrollAreaWidgetContents->layout(); @@ -295,8 +296,6 @@ void PhotoShare::clearAlbums() item->setParent(NULL); } - clearPhotos(); - // set no albums to be selected if(mAlbumSelected) { @@ -328,23 +327,23 @@ void PhotoShare::deleteAlbums() void PhotoShare::clearPhotos() { std::cerr << "PhotoShare::clearPhotos()" << std::endl; - mPhotoSelected = NULL; QLayout *layout = ui.scrollAreaWidgetContents_2->layout(); if(mAlbumSelected) { - const RsGxsGroupId& id = mAlbumSelected->getAlbum().mMeta.mGroupId; - - QSetIterator sit(mPhotoItems[id]); + QSetIterator sit(mPhotoItems); while(sit.hasNext()) { PhotoItem* item = sit.next(); layout->removeWidget(item); item->setParent(NULL); + delete item; // remove item } + mPhotoItems.clear(); } + mPhotoSelected = NULL; } void PhotoShare::updateAlbums() @@ -407,10 +406,38 @@ void PhotoShare::updateAlbums() } } +void PhotoShare::deleteAlbum(const RsGxsGroupId &grpId) +{ + + QSetIterator sit(mAlbumItems); + + while(sit.hasNext()) + { + AlbumItem* item = sit.next(); + + if(item->getAlbum().mMeta.mGroupId == grpId){ + + if(mAlbumSelected == item) + { + item->setSelected(false); + mAlbumSelected = NULL; + } + + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); + alayout->removeWidget(item); + mAlbumItems.remove(item); + item->setParent(NULL); + delete item; + return; + } + } +} + void PhotoShare::addAlbum(const RsPhotoAlbum &album) { std::cerr << " PhotoShare::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; + deleteAlbum(album.mMeta.mGroupId); // remove from ui AlbumItem *item = new AlbumItem(album, this, this); mAlbumItems.insert(item); } @@ -423,9 +450,7 @@ void PhotoShare::addPhoto(const RsPhotoPhoto &photo) std::cerr << std::endl; PhotoItem* item = new PhotoItem(this, photo, this); - const RsGxsGroupId id = photo.mMeta.mGroupId; - - mPhotoItems[id].insert(item); + mPhotoItems.insert(item); } void PhotoShare::subscribeToAlbum() @@ -450,13 +475,10 @@ void PhotoShare::subscribeToAlbum() void PhotoShare::updatePhotos() { - clearPhotos(); if(mAlbumSelected) { - const RsGxsGroupId& grpId = mAlbumSelected->getAlbum().mMeta.mGroupId; - - QSetIterator sit(mPhotoItems[grpId]); + QSetIterator sit(mPhotoItems); while(sit.hasNext()) { @@ -497,8 +519,6 @@ void PhotoShare::loadAlbumList(const uint32_t &token) requestAlbumData(albumIds); - clearPhotos(); - std::list::iterator it; for(it = albumIds.begin(); it != albumIds.end(); it++) { @@ -525,9 +545,6 @@ void PhotoShare::requestAlbumData() bool PhotoShare::loadAlbumData(const uint32_t &token) { - - deleteAlbums(); - std::cerr << "PhotoShare::loadAlbumData()"; std::cerr << std::endl; @@ -544,6 +561,7 @@ bool PhotoShare::loadAlbumData(const uint32_t &token) addAlbum(album); } + updateAlbums(); return true; } @@ -575,7 +593,7 @@ void PhotoShare::acknowledgeGroup(const uint32_t &token) RsTokReqOptionsV2 opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; uint32_t reqToken; - mPhotoQueue->requestGroupInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, 0); + mPhotoQueue->requestGroupInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); } } @@ -584,18 +602,21 @@ void PhotoShare::acknowledgeMessage(const uint32_t &token) std::pair p; rsPhotoV2->acknowledgeMsg(token, p); - if(!p.first.empty()) - { - GxsMsgReq req; - std::vector v; - v.push_back(p.second); - req[p.first] = v; - RsTokReqOptionsV2 opts; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - uint32_t reqToken; - mPhotoQueue->requestMsgInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, req, 0); - } + // just acknowledge don't load it + // loading is only instigated by clicking an album (i.e. requesting photo data) + // but load it if the album is selected +// if(!p.first.empty()) +// { +// if(mAlbumSelected) +// { +// if(mAlbumSelected->getAlbum().mMeta.mGroupId == p.first) +// { +// std::list grpIds; +// grpIds.push_back(p.first); +// requestPhotoData(grpIds); +// } +// } +// } } void PhotoShare::loadPhotoList(const uint32_t &token) @@ -618,12 +639,22 @@ void PhotoShare::requestPhotoData(GxsMsgReq &photoIds) mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, photoIds, 0); } +void PhotoShare::requestPhotoData(const std::list& grpIds) +{ + RsTokReqOptionsV2 opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + uint32_t token; + mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); +} + void PhotoShare::loadPhotoData(const uint32_t &token) { std::cerr << "PhotoShare::loadPhotoData()"; std::cerr << std::endl; + clearPhotos(); + PhotoResult res; rsPhotoV2->getPhoto(token, res); PhotoResult::iterator mit = res.begin(); diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.h b/retroshare-gui/src/gui/PhotoShare/PhotoShare.h index 8d20d05f1..a87125a6e 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.h @@ -43,6 +43,7 @@ private slots: void SetPhotoDialogClosed(); void updateAlbums(); void subscribeToAlbum(); + void deleteAlbum(const RsGxsGroupId&); private: /* Request Response Functions for loading data */ @@ -56,6 +57,7 @@ private: void requestPhotoList(GxsMsgReq &albumIds); void requestPhotoList(const std::string &albumId); void requestPhotoData(GxsMsgReq &photoIds); + void requestPhotoData(const std::list &grpIds); void loadAlbumList(const uint32_t &token); bool loadAlbumData(const uint32_t &token); @@ -75,6 +77,9 @@ private: void clearAlbums(); void clearPhotos(); void deleteAlbums(); + /*! + * Fills up photo ui with photos held in mPhotoItems (current groups photos) + */ void updatePhotos(); private: @@ -92,7 +97,7 @@ private: Ui::PhotoShare ui; QSet mAlbumItems; - QMap > mPhotoItems; + QSet mPhotoItems; // the current album selected }; diff --git a/retroshare-gui/src/util/TokenQueueV2.cpp b/retroshare-gui/src/util/TokenQueueV2.cpp index 7b6fce9d1..c87f6be40 100644 --- a/retroshare-gui/src/util/TokenQueueV2.cpp +++ b/retroshare-gui/src/util/TokenQueueV2.cpp @@ -104,7 +104,7 @@ void TokenQueueV2::queueRequest(uint32_t token, uint32_t basictype, uint32_t ans gettimeofday(&req.mRequestTs, NULL); req.mPollTs = req.mRequestTs; - mRequests.push_back(req); + mRequests.push_back(req); if (mRequests.size() == 1) { @@ -123,26 +123,23 @@ void TokenQueueV2::doPoll(float dt) void TokenQueueV2::pollRequests() { - std::list::iterator it; - double pollPeriod = 1.0; // max poll period. - for(it = mRequests.begin(); it != mRequests.end();) - { - if (checkForRequest(it->mToken)) - { - /* clean it up and handle */ - loadRequest(*it); - it = mRequests.erase(it); - } - else - { - /* calculate desired poll period */ - /* if less then current poll period, adjust */ - - it++; - } - } + TokenRequestV2 req; + + if(mRequests.size() > 0){ + req = mRequests.front(); + }else + { + return; + } + + if (checkForRequest(req.mToken)) + { + /* clean it up and handle */ + loadRequest(req); + mRequests.pop_front(); + } if (mRequests.size() > 0) { @@ -178,7 +175,7 @@ bool TokenQueueV2::cancelRequest(const uint32_t token) /* cancel at lower level first */ mService->cancelRequest(token); - std::list::iterator it; + std::list::iterator it; for(it = mRequests.begin(); it != mRequests.end(); it++) { diff --git a/retroshare-gui/src/util/TokenQueueV2.h b/retroshare-gui/src/util/TokenQueueV2.h index d2279ba47..8578fbc24 100644 --- a/retroshare-gui/src/util/TokenQueueV2.h +++ b/retroshare-gui/src/util/TokenQueueV2.h @@ -64,9 +64,8 @@ class TokenResponseV2 /*! - * - * - * + * An important thing to note is that all requests are stacked (so FIFO) + * This is to prevent overlapped loads on GXS UIs */ class TokenQueueV2: public QWidget { @@ -110,7 +109,7 @@ private slots: private: /* Info for Data Requests */ - std::list mRequests; + std::list mRequests; RsTokenServiceV2 *mService; TokenResponseV2 *mResponder; From 19e856c2a8eb56c5e43e977aac27a3dbc79ab2d0 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Mon, 1 Oct 2012 20:57:56 +0000 Subject: [PATCH 072/222] Added RsTlvKeySignatureSet to rstlvkeys - added test to test/serialiser - Updated all relevant gxs test (ran whole suite, added gxsdata_test, tests meta serilisation, to pro file) Updated flag in rsgxsflags to account for authentication and private types Changed msgId/grpId generation to sha1 hash removed photoservice VEG file from pro file git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5630 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/gxssecurity.cc | 2 +- libretroshare/src/gxs/gxssecurity.h | 2 +- libretroshare/src/gxs/rsdataservice.cc | 111 ++++-------- libretroshare/src/gxs/rsgenexchange.cc | 21 ++- libretroshare/src/gxs/rsgxsdata.cc | 33 ++-- libretroshare/src/gxs/rsgxsdata.h | 6 +- libretroshare/src/gxs/rsgxsflags.h | 53 +++--- libretroshare/src/libretroshare.pro | 11 +- libretroshare/src/serialiser/rstlvbase.h | 2 + libretroshare/src/serialiser/rstlvkeys.cc | 169 +++++++++++++++++- libretroshare/src/serialiser/rstlvkeys.h | 16 ++ .../src/services/p3photoserviceV2.cc | 2 + libretroshare/src/tests/gxs/data_support.cc | 6 +- libretroshare/src/tests/gxs/nxs_tests.pro | 104 ++++++----- .../src/tests/gxs/rsdataservice_test.cc | 6 +- .../src/tests/gxs/rsgenexchange_test.cc | 6 +- libretroshare/src/tests/gxs/rsgxsdata_test.cc | 6 +- libretroshare/src/tests/gxs/support.cc | 37 ++++ libretroshare/src/tests/gxs/support.h | 2 + libretroshare/src/tests/serialiser/support.cc | 36 ++++ libretroshare/src/tests/serialiser/support.h | 2 + .../src/tests/serialiser/tlvkey_test.cc | 36 ++++ 22 files changed, 467 insertions(+), 202 deletions(-) create mode 100644 libretroshare/src/tests/serialiser/tlvkey_test.cc diff --git a/libretroshare/src/gxs/gxssecurity.cc b/libretroshare/src/gxs/gxssecurity.cc index 3ba7d6164..507b2a2e3 100644 --- a/libretroshare/src/gxs/gxssecurity.cc +++ b/libretroshare/src/gxs/gxssecurity.cc @@ -48,7 +48,7 @@ RSA *GxsSecurity::extractPublicKey(RsTlvSecurityKey& key) } -bool GxsSecurity::validateNxsMsg(RsNxsMsg *msg) +bool GxsSecurity::validateNxsMsg(RsNxsMsg *msg, RsGxsGrpMetaData *grpMeta) { return false; diff --git a/libretroshare/src/gxs/gxssecurity.h b/libretroshare/src/gxs/gxssecurity.h index 600561262..23ceca40d 100644 --- a/libretroshare/src/gxs/gxssecurity.h +++ b/libretroshare/src/gxs/gxssecurity.h @@ -126,7 +126,7 @@ public: * @param msg * @return false if verfication of signature is not passed */ - static bool validateNxsMsg(RsNxsMsg *msg); + static bool validateNxsMsg(RsNxsMsg *msg, RsGxsGrpMetaData* grpMeta); }; #endif // GXSSECURITY_H diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index ec8e56997..1afb0bb5a 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -40,7 +40,7 @@ #define KEY_NXS_IDENTITY std::string("identity") #define KEY_GRP_ID std::string("grpId") #define KEY_ORIG_GRP_ID std::string("origGrpId") -#define KEY_IDENTITY_SIGN std::string("idSign") +#define KEY_SIGN_SET std::string("signSet") #define KEY_TIME_STAMP std::string("timeStamp") #define KEY_NXS_FLAGS std::string("flags") #define KEY_NXS_META std::string("meta") @@ -48,7 +48,6 @@ // grp table columns -#define KEY_ADMIN_SIGN std::string("adminSign") #define KEY_KEY_SET std::string("keySet") #define KEY_GRP_NAME std::string("grpName") #define KEY_GRP_SIGN_FLAGS std::string("signFlags") @@ -62,7 +61,6 @@ // msg table columns -#define KEY_PUBLISH_SIGN std::string("publishSign") #define KEY_MSG_ID std::string("msgId") #define KEY_ORIG_MSG_ID std::string("origMsgId") #define KEY_MSG_PARENT_ID std::string("parentId") @@ -90,34 +88,32 @@ // grp col numbers -#define COL_ADMIN_SIGN 5 -#define COL_KEY_SET 6 -#define COL_GRP_SUBCR_FLAG 7 -#define COL_GRP_POP 8 -#define COL_MSG_COUNT 9 -#define COL_GRP_STATUS 10 -#define COL_GRP_NAME 11 -#define COL_GRP_LAST_POST 12 -#define COL_ORIG_GRP_ID 13 -#define COL_GRP_SERV_STRING 14 -#define COL_GRP_SIGN_FLAGS 15 +#define COL_KEY_SET 5 +#define COL_GRP_SUBCR_FLAG 6 +#define COL_GRP_POP 7 +#define COL_MSG_COUNT 8 +#define COL_GRP_STATUS 9 +#define COL_GRP_NAME 10 +#define COL_GRP_LAST_POST 11 +#define COL_ORIG_GRP_ID 12 +#define COL_GRP_SERV_STRING 13 +#define COL_GRP_SIGN_FLAGS 14 // msg col numbers -#define COL_PUBLISH_SIGN 5 -#define COL_MSG_ID 6 -#define COL_ORIG_MSG_ID 7 -#define COL_MSG_STATUS 8 -#define COL_CHILD_TS 9 -#define COL_PARENT_ID 10 -#define COL_THREAD_ID 11 -#define COL_MSG_NAME 12 -#define COL_MSG_SERV_STRING 13 +#define COL_MSG_ID 5 +#define COL_ORIG_MSG_ID 6 +#define COL_MSG_STATUS 7 +#define COL_CHILD_TS 8 +#define COL_PARENT_ID 9 +#define COL_THREAD_ID 10 +#define COL_MSG_NAME 11 +#define COL_MSG_SERV_STRING 12 // generic meta shared col numbers #define COL_GRP_ID 0 #define COL_TIME_STAMP 1 #define COL_NXS_FLAGS 2 -#define COL_IDENTITY_SIGN 3 +#define COL_SIGN_SET 3 #define COL_IDENTITY 4 #define RS_DATA_SERVICE_DEBUG @@ -138,7 +134,7 @@ RsDataService::RsDataService(const std::string &serviceDir, const std::string &d // for retrieving msg meta msgMetaColumns.push_back(KEY_GRP_ID); msgMetaColumns.push_back(KEY_TIME_STAMP); msgMetaColumns.push_back(KEY_NXS_FLAGS); - msgMetaColumns.push_back(KEY_IDENTITY_SIGN); msgMetaColumns.push_back(KEY_NXS_IDENTITY); msgMetaColumns.push_back(KEY_PUBLISH_SIGN); + msgMetaColumns.push_back(KEY_SIGN_SET); msgMetaColumns.push_back(KEY_NXS_IDENTITY); msgMetaColumns.push_back(KEY_MSG_ID); msgMetaColumns.push_back(KEY_ORIG_MSG_ID); msgMetaColumns.push_back(KEY_MSG_STATUS); msgMetaColumns.push_back(KEY_CHILD_TS); msgMetaColumns.push_back(KEY_MSG_PARENT_ID); msgMetaColumns.push_back(KEY_MSG_THREAD_ID); msgMetaColumns.push_back(KEY_MSG_NAME); msgMetaColumns.push_back(KEY_NXS_SERV_STRING); @@ -149,7 +145,7 @@ RsDataService::RsDataService(const std::string &serviceDir, const std::string &d // for retrieving grp meta data grpMetaColumns.push_back(KEY_GRP_ID); grpMetaColumns.push_back(KEY_TIME_STAMP); grpMetaColumns.push_back(KEY_NXS_FLAGS); - grpMetaColumns.push_back(KEY_IDENTITY_SIGN); grpMetaColumns.push_back(KEY_NXS_IDENTITY); grpMetaColumns.push_back(KEY_ADMIN_SIGN); + grpMetaColumns.push_back(KEY_SIGN_SET); grpMetaColumns.push_back(KEY_NXS_IDENTITY); grpMetaColumns.push_back(KEY_KEY_SET); grpMetaColumns.push_back(KEY_GRP_SUBCR_FLAG); grpMetaColumns.push_back(KEY_GRP_POP); grpMetaColumns.push_back(KEY_MSG_COUNT); grpMetaColumns.push_back(KEY_GRP_STATUS); grpMetaColumns.push_back(KEY_GRP_NAME); grpMetaColumns.push_back(KEY_GRP_LAST_POST); grpMetaColumns.push_back(KEY_ORIG_GRP_ID); grpMetaColumns.push_back(KEY_NXS_SERV_STRING); @@ -177,9 +173,8 @@ void RsDataService::initialise(){ KEY_NXS_FLAGS + " INT," + KEY_ORIG_MSG_ID + " TEXT," + KEY_TIME_STAMP + " INT," + - KEY_PUBLISH_SIGN + " BLOB," + KEY_NXS_IDENTITY + " TEXT," + - KEY_IDENTITY_SIGN + " BLOB," + + KEY_SIGN_SET + " BLOB," + KEY_NXS_FILE + " TEXT,"+ KEY_NXS_FILE_OFFSET + " INT," + KEY_MSG_STATUS + " INT," + @@ -195,7 +190,6 @@ void RsDataService::initialise(){ mDb->execSQL("CREATE TABLE " + GRP_TABLE_NAME + "(" + KEY_GRP_ID + " TEXT," + KEY_TIME_STAMP + " INT," + - KEY_ADMIN_SIGN + " BLOB," + " BLOB," + KEY_NXS_FILE + " TEXT," + KEY_NXS_FILE_OFFSET + " INT," + KEY_KEY_SET + " BLOB," + @@ -212,7 +206,7 @@ void RsDataService::initialise(){ KEY_NXS_SERV_STRING + " TEXT," + KEY_NXS_FLAGS + " INT," + KEY_GRP_SIGN_FLAGS + " INT," + - KEY_IDENTITY_SIGN + " BLOB);"); + KEY_SIGN_SET + " BLOB);"); } @@ -243,18 +237,7 @@ RsGxsGrpMetaData* RsDataService::getGrpMeta(RetroCursor &c) grpMeta->mPublishTs = c.getInt32(COL_TIME_STAMP); grpMeta->mGroupFlags = c.getInt32(COL_NXS_FLAGS); - // identity if any - if(!grpMeta->mAuthorId.empty() && ok){ - offset = 0; - data = (char*)c.getData(COL_IDENTITY_SIGN, data_len); - if(data) - grpMeta->idSign.GetTlv(data, data_len, &offset); - } - offset = 0; - data = (char*)c.getData(COL_ADMIN_SIGN, data_len); - if(data) - grpMeta->adminSign.GetTlv(data, data_len, &offset); offset = 0; data = NULL; data_len = 0; @@ -355,25 +338,16 @@ RsGxsMsgMetaData* RsDataService::getMsgMeta(RetroCursor &c) c.getString(COL_MSG_NAME, msgMeta->mMsgName); c.getString(COL_MSG_SERV_STRING, msgMeta->mServiceString); - if(!msgMeta->mAuthorId.empty()){ - offset = 0; - data = (char*)c.getData(COL_IDENTITY_SIGN, data_len); - msgMeta->idSign.GetTlv(data, data_len, &offset); - } + offset = 0; + data = (char*)c.getData(COL_SIGN_SET, data_len); + msgMeta->signSet.GetTlv(data, data_len, &offset); + msgMeta->mMsgFlags = c.getInt32(COL_NXS_FLAGS); msgMeta->mPublishTs = c.getInt32(COL_TIME_STAMP); offset = 0; data_len = 0; - if(ok){ - - data = (char*)c.getData(COL_PUBLISH_SIGN, data_len); - if(data) - msgMeta->pubSign.GetTlv(data, data_len, &offset); - - } - // thread and parent id c.getString(COL_THREAD_ID, msgMeta->mThreadId); c.getString(COL_PARENT_ID, msgMeta->mParentId); @@ -467,20 +441,15 @@ int RsDataService::storeMessage(std::map &msg) cv.put(KEY_MSG_ID, msgMetaPtr->mMsgId); cv.put(KEY_GRP_ID, msgMetaPtr->mGroupId); cv.put(KEY_NXS_SERV_STRING, msgMetaPtr->mServiceString); - char pubSignData[msgMetaPtr->pubSign.TlvSize()]; + + + char signSetData[msgMetaPtr->signSet.TlvSize()]; offset = 0; - msgMetaPtr->pubSign.SetTlv(pubSignData, msgMetaPtr->pubSign.TlvSize(), &offset); - cv.put(KEY_PUBLISH_SIGN, msgMetaPtr->pubSign.TlvSize(), pubSignData); + msgMetaPtr->signSet.SetTlv(signSetData, msgMetaPtr->signSet.TlvSize(), &offset); + cv.put(KEY_SIGN_SET, msgMetaPtr->signSet.TlvSize(), signSetData); + cv.put(KEY_NXS_IDENTITY, msgMetaPtr->mAuthorId); - if(! (msgMetaPtr->mAuthorId.empty()) ){ - char idSignData[msgMetaPtr->idSign.TlvSize()]; - offset = 0; - msgMetaPtr->idSign.SetTlv(idSignData, msgMetaPtr->idSign.TlvSize(), &offset); - cv.put(KEY_IDENTITY_SIGN, msgMetaPtr->idSign.TlvSize(), idSignData); - cv.put(KEY_NXS_IDENTITY, msgMetaPtr->mAuthorId); - } - cv.put(KEY_NXS_FLAGS, (int32_t) msgMetaPtr->mMsgFlags); cv.put(KEY_TIME_STAMP, (int32_t) msgMetaPtr->mPublishTs); @@ -562,20 +531,8 @@ int RsDataService::storeGroup(std::map &grp) if(! (grpMetaPtr->mAuthorId.empty()) ){ cv.put(KEY_NXS_IDENTITY, grpMetaPtr->mAuthorId); - - char idSignData[grpMetaPtr->idSign.TlvSize()]; - offset = 0; - grpMetaPtr->idSign.SetTlv(idSignData, grpMetaPtr->idSign.TlvSize(), &offset); - cv.put(KEY_IDENTITY_SIGN, grpMetaPtr->idSign.TlvSize(), idSignData); - std::string wat(idSignData, grpMetaPtr->idSign.TlvSize()); - std::cerr << wat << std::endl; } - char adminSignData[grpMetaPtr->adminSign.TlvSize()]; - offset = 0; - grpMetaPtr->adminSign.SetTlv(adminSignData, grpMetaPtr->adminSign.TlvSize(), &offset); - cv.put(KEY_ADMIN_SIGN, grpMetaPtr->adminSign.TlvSize(), adminSignData); - offset = 0; char keySetData[grpMetaPtr->keys.TlvSize()]; grpMetaPtr->keys.SetTlv(keySetData, grpMetaPtr->keys.TlvSize(), &offset); diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 6c5327341..6e4a4191f 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -29,6 +29,7 @@ #include #include +#include "pqi/pqihash.h" #include "rsgenexchange.h" #include "gxssecurity.h" #include "util/contentvalue.h" @@ -166,7 +167,11 @@ void RsGenExchange::createGroup(RsNxsGrp *grp) meta->keys.keys[pubKey.keyId] = pubKey; meta->keys.keys[privPubKey.keyId] = privPubKey; - meta->mGroupId = adminKey.keyId; + pqihash hash; + + // get hash of msg data to create msg id + hash.addData(grp->grp.bin_data, grp->grp.bin_len); + hash.Complete(meta->mGroupId); grp->grpId = meta->mGroupId; adminKey.TlvClear(); @@ -235,11 +240,19 @@ bool RsGenExchange::createMessage(RsNxsMsg* msg) unsigned char sigbuf[siglen]; ok = EVP_SignFinal(mdctx, sigbuf, &siglen, key_pub) == 1; + //place signature in msg meta RsGxsMsgMetaData &meta = *(msg->metaData); - meta.pubSign.signData.setBinData(sigbuf, siglen); - meta.pubSign.keyId = pubKey->keyId; + RsTlvKeySignatureSet& signSet = meta.signSet; + RsTlvKeySignature pubSign = signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH]; + pubSign.signData.setBinData(sigbuf, siglen); + pubSign.keyId = pubKey->keyId; - msg->metaData->mMsgId = msg->msgId = GxsSecurity::getBinDataSign(sigbuf, siglen); + // get hash of msg data to create msg id + pqihash hash; + hash.addData(msg->msg.bin_data, msg->msg.bin_len); + hash.Complete(msg->msgId); + + msg->metaData->mMsgId = msg->msgId; // clean up EVP_MD_CTX_destroy(mdctx); diff --git a/libretroshare/src/gxs/rsgxsdata.cc b/libretroshare/src/gxs/rsgxsdata.cc index d148a762b..d77ad1dbd 100644 --- a/libretroshare/src/gxs/rsgxsdata.cc +++ b/libretroshare/src/gxs/rsgxsdata.cc @@ -44,10 +44,9 @@ uint32_t RsGxsGrpMetaData::serial_size() s += 4; s += GetTlvStringSize(mAuthorId); s += GetTlvStringSize(mServiceString); - - s += adminSign.TlvSize(); + s += signSet.TlvSize(); s += keys.TlvSize(); - s += idSign.TlvSize(); + return s; } @@ -66,10 +65,9 @@ void RsGxsGrpMetaData::clear(){ mGroupStatus = 0; mLastPost = 0; mSubscribeFlags = 0; - - adminSign.TlvClear(); + signSet.TlvClear(); keys.TlvClear(); - idSign.TlvClear(); + } bool RsGxsGrpMetaData::serialise(void *data, uint32_t &pktsize) @@ -103,10 +101,9 @@ bool RsGxsGrpMetaData::serialise(void *data, uint32_t &pktsize) ok &= setRawUInt32(data, tlvsize, &offset, mPublishTs); ok &= SetTlvString(data, tlvsize, &offset, 0, mAuthorId); ok &= SetTlvString(data, tlvsize, &offset, 0, mServiceString); - - ok &= adminSign.SetTlv(data, tlvsize, &offset); + ok &= signSet.SetTlv(data, tlvsize, &offset); ok &= keys.SetTlv(data, tlvsize, &offset); - ok &= idSign.SetTlv(data, tlvsize, &offset); + return ok; } @@ -130,10 +127,9 @@ bool RsGxsGrpMetaData::deserialise(void *data, uint32_t &pktsize) ok &= getRawUInt32(data, pktsize, &offset, &mPublishTs); ok &= GetTlvString(data, pktsize, &offset, 0, mAuthorId); ok &= GetTlvString(data, pktsize, &offset, 0, mServiceString); - - ok &= adminSign.GetTlv(data, pktsize, &offset); + ok &= signSet.GetTlv(data, pktsize, &offset); ok &= keys.GetTlv(data, pktsize, &offset); - ok &= idSign.GetTlv(data, pktsize, &offset); + return ok; } @@ -155,8 +151,7 @@ uint32_t RsGxsMsgMetaData::serial_size() s += GetTlvStringSize(mAuthorId); s += GetTlvStringSize(mServiceString); - s += pubSign.TlvSize(); - s += idSign.TlvSize(); + s += signSet.TlvSize(); s += GetTlvStringSize(mMsgName); s += 4; s += 4; @@ -175,9 +170,7 @@ void RsGxsMsgMetaData::clear() mMsgName.clear(); mServiceString.clear(); - pubSign.TlvClear(); - idSign.TlvClear(); - + signSet.TlvClear(); mPublishTs = 0; mMsgFlags = 0; mMsgStatus = 0; @@ -215,8 +208,7 @@ bool RsGxsMsgMetaData::serialise(void *data, uint32_t *size) ok &= SetTlvString(data, *size, &offset, 0, mAuthorId); ok &= SetTlvString(data, *size, &offset, 0, mServiceString); - ok &= pubSign.SetTlv(data, *size, &offset); - ok &= idSign.SetTlv(data, *size, &offset); + ok &= signSet.SetTlv(data, *size, &offset); ok &= SetTlvString(data, *size, &offset, 0, mMsgName); ok &= setRawUInt32(data, *size, &offset, mPublishTs); ok &= setRawUInt32(data, *size, &offset, mMsgFlags); @@ -244,8 +236,7 @@ bool RsGxsMsgMetaData::deserialise(void *data, uint32_t *size) ok &= GetTlvString(data, *size, &offset, 0, mAuthorId); ok &= GetTlvString(data, *size, &offset, 0, mServiceString); - ok &= pubSign.GetTlv(data, *size, &offset); - ok &= idSign.GetTlv(data, *size, &offset); + ok &= signSet.GetTlv(data, *size, &offset); ok &= GetTlvString(data, *size, &offset, 0, mMsgName); uint32_t t; ok &= getRawUInt32(data, *size, &offset, &t); diff --git a/libretroshare/src/gxs/rsgxsdata.h b/libretroshare/src/gxs/rsgxsdata.h index 47fa29516..834ae187c 100644 --- a/libretroshare/src/gxs/rsgxsdata.h +++ b/libretroshare/src/gxs/rsgxsdata.h @@ -60,9 +60,8 @@ public: std::string mAuthorId; - RsTlvKeySignature adminSign; + RsTlvKeySignatureSet signSet; RsTlvSecurityKeySet keys; - RsTlvKeySignature idSign; std::string mServiceString; @@ -100,8 +99,7 @@ public: RsGxsMessageId mOrigMsgId; std::string mAuthorId; - RsTlvKeySignature pubSign; - RsTlvKeySignature idSign; + RsTlvKeySignatureSet signSet; std::string mServiceString; diff --git a/libretroshare/src/gxs/rsgxsflags.h b/libretroshare/src/gxs/rsgxsflags.h index a215a8809..cc23f8937 100644 --- a/libretroshare/src/gxs/rsgxsflags.h +++ b/libretroshare/src/gxs/rsgxsflags.h @@ -8,56 +8,51 @@ namespace GXS_SERV { - /*** GROUP FLAGS ***/ - /* type of group */ + /** privacy **/ - static const uint32_t FLAG_GRP_TYPE_MASK = 0; + static const uint32_t FLAG_PRIVACY_MASK = 0x0000000f; // pub key encrypted - static const uint32_t FLAG_GRP_TYPE_PRIVATE = 0; + static const uint32_t FLAG_PRIVACY_PRIVATE = 0x00000001; - // single publisher, read only - static const uint32_t FLAG_GRP_TYPE_RESTRICTED = 0; + // publish private key needed to publish + static const uint32_t FLAG_PRIVACY_RESTRICTED = 0x00000002; - // anyone can publish - static const uint32_t FLAG_GRP_TYPE_PUBLIC = 0; + // anyone can publish, publish key pair not needed + static const uint32_t FLAG_PRIVACY_PUBLIC = 0x00000004; + /** privacy **/ - /* type of msgs allowed */ + /** authentication **/ - static const uint32_t FLAG_MSG_TYPE_MASK = 0; + static const uint32_t FLAG_AUTHEN_MASK = 0x000000f0; - // only signee can edit, and sign required - static const uint32_t FLAG_MSG_TYPE_SIGNED = 0; + // identity + static const uint32_t FLAG_AUTHEN_IDENTITY = 0x000000010; - // no sign required, but signee can edit if signed - static const uint32_t FLAG_MSG_TYPE_ANON = 0; + // publish key + static const uint32_t FLAG_AUTHEN_PUBLISH = 0x000000020; - // anyone can mod but sign must be provided (needed for wikis) - static const uint32_t FLAG_MSG_TYPE_SIGNED_SHARED = 0; + // admin key + static const uint32_t FLAG_AUTHEN_ADMIN = 0x00000040; - /*** GROUP FLAGS ***/ + // pgp sign identity + static const uint32_t FLAG_AUTHEN_PGP_IDENTITY = 0x00000080; - - - /*** MESSAGE FLAGS ***/ - - // indicates message edits an existing message - static const uint32_t FLAG_MSG_EDIT = 0; - - // indicates msg is id signed - static const uint32_t FLAG_MSG_ID_SIGNED = 0; - - /*** MESSAGE FLAGS ***/ + /** authentication **/ // Subscription Flags. (LOCAL) static const uint32_t GROUP_SUBSCRIBE_ADMIN = 0x00000001; + static const uint32_t GROUP_SUBSCRIBE_PUBLISH = 0x00000002; + static const uint32_t GROUP_SUBSCRIBE_SUBSCRIBED = 0x00000004; - static const uint32_t GROUP_SUBSCRIBE_MONITOR = 0x00000008; + + static const uint32_t GROUP_SUBSCRIBE_NOT_SUBSCRIBED = 0x00000008; + static const uint32_t GROUP_SUBSCRIBE_MASK = 0x0000000f; } diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 515b19d72..063dc8aa7 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -10,7 +10,7 @@ CONFIG += test_voip # GXS Stuff. CONFIG += newcache -#CONFIG += newservices +CONFIG += newservices # Beware: All data of the stripped services are lost DEFINES *= PQI_DISABLE_TUNNEL @@ -588,7 +588,7 @@ HEADERS += retroshare/rsgame.h \ } newservices { - HEADERS += services/p3photoserviceVEG.h \ + HEADERS += services/p3photoserviceV2.h \ retroshare/rsphotoVEG.h \ services/p3gxsserviceVEG.h \ retroshare/rsidentityVEG.h \ @@ -600,15 +600,12 @@ HEADERS += retroshare/rsgame.h \ retroshare/rsforumsVEG.h \ services/p3forumsVEG.h \ retroshare/rspostedVEG.h \ - services/p3postedVEG.h \ - services/p3photoserviceV2VEG.h \ - retroshare/rsphotoVEG.h + services/p3postedVEG.h # Do I need this? #serialiser/rsphotoitemsVEG.h \ - SOURCES += services/p3photoserviceVEG.cc \ - services/p3gxsserviceVEG.cc \ + SOURCES += services/p3gxsserviceVEG.cc \ services/p3wikiserviceVEG.cc \ services/p3wireVEG.cc \ services/p3idserviceVEG.cc \ diff --git a/libretroshare/src/serialiser/rstlvbase.h b/libretroshare/src/serialiser/rstlvbase.h index 72e1b4a4b..70698df64 100644 --- a/libretroshare/src/serialiser/rstlvbase.h +++ b/libretroshare/src/serialiser/rstlvbase.h @@ -207,6 +207,8 @@ const uint16_t TLV_TYPE_SECURITYKEY = 0x1040; const uint16_t TLV_TYPE_SECURITYKEYSET= 0x1041; const uint16_t TLV_TYPE_KEYSIGNATURE = 0x1050; +const uint16_t TLV_TYPE_KEYSIGNATURESET = 0x1051; +const uint16_t TLV_TYPE_KEYSIGNATURETYPE = 0x1052; const uint16_t TLV_TYPE_IMAGE = 0x1060; diff --git a/libretroshare/src/serialiser/rstlvkeys.cc b/libretroshare/src/serialiser/rstlvkeys.cc index 089517f86..f2b39269b 100644 --- a/libretroshare/src/serialiser/rstlvkeys.cc +++ b/libretroshare/src/serialiser/rstlvkeys.cc @@ -34,7 +34,7 @@ #include #include -//#define TLV_DEBUG 1 +#define TLV_DEBUG 1 /************************************* RsTlvSecurityKey ************************************/ @@ -520,3 +520,170 @@ std::ostream &RsTlvKeySignature::print(std::ostream &out, uint16_t indent) return out; } + +/************************************* RsTlvKeySignatureSet ************************************/ + +RsTlvKeySignatureSet::RsTlvKeySignatureSet() +{ + +} + +std::ostream &RsTlvKeySignatureSet::print(std::ostream &out, uint16_t indent) +{ + printBase(out, "RsTlvKeySignatureSet", indent); + uint16_t int_Indent = indent + 2; + + printIndent(out, int_Indent); + + std::map::iterator mit = keySignSet.begin(); + + for(; mit != keySignSet.end(); mit++) + { + out << "SignType: " << mit->first << std::endl; + RsTlvKeySignature& sign = mit->second; + sign.print(out, indent); + } + + out << std::endl; + + printEnd(out, "RsTlvKeySignatureSet", indent); + return out; +} + +void RsTlvKeySignatureSet::TlvClear() +{ + keySignSet.clear(); +} + +bool RsTlvKeySignatureSet::SetTlv(void *data, uint32_t size, uint32_t *offset) +{ + + /* must check sizes */ + uint32_t tlvsize = TlvSize(); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) + { +#ifdef TLV_DEBUG + std::cerr << "RsTlvKeySignatureSet::SetTlv() Failed not enough space"; + std::cerr << std::endl; +#endif + return false; /* not enough space */ + } + + bool ok = true; + + /* start at data[offset] */ + ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_KEYSIGNATURESET , tlvsize); + + + if(!keySignSet.empty()) + { + std::map::iterator it; + + for(it = keySignSet.begin(); it != keySignSet.end() ; ++it) + { + ok &= SetTlvUInt32(data, size, offset, TLV_TYPE_KEYSIGNATURETYPE, it->first); + ok &= (it->second).SetTlv(data, size, offset); + } + } + + +return ok; +} + +bool RsTlvKeySignatureSet::GetTlv(void *data, uint32_t size, uint32_t *offset) +{ + if (size < *offset + TLV_HEADER_SIZE) + return false; + + uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); + uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); + uint32_t tlvend = *offset + tlvsize; + + if (size < tlvend) /* check size */ + return false; /* not enough space */ + + if (tlvtype != TLV_TYPE_KEYSIGNATURESET) /* check type */ + return false; + + bool ok = true; + + /* ready to load */ + TlvClear(); + + /* skip the header */ + (*offset) += TLV_HEADER_SIZE; + + SignType sign_type = 0; + + /* while there is TLV */ + while((*offset) + 2 < tlvend) + { + + /* get the next type */ + uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); + SignType currType; + + switch(tlvsubtype) + { + case TLV_TYPE_KEYSIGNATURE: + { + RsTlvKeySignature sign; + ok &= sign.GetTlv(data, size, offset); + if (ok) + { + keySignSet[currType] = sign; + } + } + break; + case TLV_TYPE_KEYSIGNATURETYPE: + { + ok = GetTlvUInt32(data, size, offset, TLV_TYPE_KEYSIGNATURETYPE, &sign_type); + + if(ok) + currType = sign_type; + } + break; + default: + ok &= SkipUnknownTlv(data, tlvend, offset); + break; + } + + if (!ok) + break; + } + + + + /*************************************************************************** + * NB: extra components could be added (for future expansion of the type). + * or be present (if this code is reading an extended version). + * + * We must chew up the extra characters to conform with TLV specifications + ***************************************************************************/ + if (*offset != tlvend) + { +#ifdef TLV_DEBUG + std::cerr << "RsTlvKeySignatureSet::GetTlv() Warning extra bytes at end of item"; + std::cerr << std::endl; +#endif + *offset = tlvend; + } + + return ok; +} + +uint32_t RsTlvKeySignatureSet::TlvSize() +{ + uint32_t s = TLV_HEADER_SIZE; // header size + std::map::iterator it; + + for(it = keySignSet.begin(); it != keySignSet.end() ; ++it) + { + s += GetTlvUInt32Size(); // sign type + s += it->second.TlvSize(); // signature + } + + return s; +} diff --git a/libretroshare/src/serialiser/rstlvkeys.h b/libretroshare/src/serialiser/rstlvkeys.h index 35caca20c..6f3f9b46c 100644 --- a/libretroshare/src/serialiser/rstlvkeys.h +++ b/libretroshare/src/serialiser/rstlvkeys.h @@ -41,6 +41,7 @@ const uint32_t RSTLV_KEY_TYPE_SHARED = 0x0004; const uint32_t RSTLV_KEY_DISTRIB_PUBLIC = 0x0010; const uint32_t RSTLV_KEY_DISTRIB_PRIVATE = 0x0020; const uint32_t RSTLV_KEY_DISTRIB_ADMIN = 0x0040; +const uint32_t RSTLV_KEY_DISTRIB_IDENTITY = 0x0080; class RsTlvSecurityKey: public RsTlvItem @@ -98,6 +99,21 @@ virtual std::ostream &print(std::ostream &out, uint16_t indent); // NO Certificates in Signatures... add as separate data type. }; +typedef uint32_t SignType; + +class RsTlvKeySignatureSet : public RsTlvItem +{ +public: + RsTlvKeySignatureSet(); + virtual ~RsTlvKeySignatureSet() { return; } + virtual uint32_t TlvSize(); + virtual void TlvClear(); + virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */ + virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */ + virtual std::ostream &print(std::ostream &out, uint16_t indent); + + std::map keySignSet; // mandatory +}; #endif diff --git a/libretroshare/src/services/p3photoserviceV2.cc b/libretroshare/src/services/p3photoserviceV2.cc index f9bbf01ff..58c3072a9 100644 --- a/libretroshare/src/services/p3photoserviceV2.cc +++ b/libretroshare/src/services/p3photoserviceV2.cc @@ -88,7 +88,9 @@ p3PhotoServiceV2::p3PhotoServiceV2(RsGeneralDataService* gds, RsNetworkExchangeS RsGxsPhotoAlbumItem* item1 = new RsGxsPhotoAlbumItem(), *item2 = new RsGxsPhotoAlbumItem(); item1->meta.mGroupName = "Dummy Album 1"; + item1->album.mCaption = "Dummy 1"; item2->meta.mGroupName = "Dummy Album 2"; + item2->album.mCaption = "Dummy 2"; createDummyGroup(item1); createDummyGroup(item2); diff --git a/libretroshare/src/tests/gxs/data_support.cc b/libretroshare/src/tests/gxs/data_support.cc index 272c9255e..8d286b28c 100644 --- a/libretroshare/src/tests/gxs/data_support.cc +++ b/libretroshare/src/tests/gxs/data_support.cc @@ -62,9 +62,8 @@ void init_item(RsGxsGrpMetaData* metaGrp) randString(SHORT_STR, metaGrp->mAuthorId); randString(SHORT_STR, metaGrp->mGroupName); - init_item(metaGrp->adminSign); + init_item(metaGrp->signSet); init_item(metaGrp->keys); - init_item(metaGrp->idSign); metaGrp->mPublishTs = rand()%3452; metaGrp->mGroupFlags = rand()%43; @@ -87,8 +86,7 @@ void init_item(RsGxsMsgMetaData* metaMsg) randString(SHORT_STR, metaMsg->mOrigMsgId); randString(SHORT_STR, metaMsg->mMsgName); - init_item(metaMsg->pubSign); - init_item(metaMsg->idSign); + init_item(metaMsg->signSet); metaMsg->mPublishTs = rand()%313; metaMsg->mMsgFlags = rand()%224; diff --git a/libretroshare/src/tests/gxs/nxs_tests.pro b/libretroshare/src/tests/gxs/nxs_tests.pro index feda6172d..7aabd0eb9 100644 --- a/libretroshare/src/tests/gxs/nxs_tests.pro +++ b/libretroshare/src/tests/gxs/nxs_tests.pro @@ -10,13 +10,14 @@ QT += core network QT -= gui -CONFIG += dstore_target #gen_exchange_target # #nxs_net_test +CONFIG += gen_exchange_target +#CONFIG += nxs_net_test +#CONFIG += dstore_target +#CONFIG += gxsdata_target + -dstore_target { -TARGET = rs_dstore_test -} gen_exchange_target { @@ -30,6 +31,12 @@ TARGET = nxs_net_test } +gxsdata_target { + +TARGET = gxsdata_test + +} + CONFIG += console CONFIG -= app_bundle @@ -161,53 +168,66 @@ install_rs { binary_rs.files = ./RetroShare } -dstore_target { - - SOURCES += \ - support.cc \ - rsdataservice_test.cc \ - data_support.cc - - HEADERS += support.h \ - rsdataservice_test.h \ - data_support.h - - -} - gen_exchange_target { - SOURCES += \ - support.cc \ - genexchangetester.cpp \ - genexchangetestservice.cpp \ - rsdummyservices.cc \ - rsgenexchange_test.cc - - HEADERS += support.h \ - rsdataservice_test.h \ - rsdummyservices.h \ - data_support.h + SOURCES += \ + support.cc \ + genexchangetester.cpp \ + genexchangetestservice.cpp \ + rsdummyservices.cc \ + rsgenexchange_test.cc + + HEADERS += support.h \ + rsdataservice_test.h \ + rsdummyservices.h \ + data_support.h } nxs_net_test { - SOURCES += \ - support.cc \ - nxstesthub.cc \ - rsgxsnetservice_test.cc \ - nxstestscenario.cc \ - data_support.cc - - - HEADERS += support.h \ - nxstesthub.h \ - rsgxsnetservice_test.h \ - nxstestscenario.h \ - data_support.h + SOURCES += \ + support.cc \ + nxstesthub.cc \ + rsgxsnetservice_test.cc \ + nxstestscenario.cc \ + data_support.cc + + + HEADERS += support.h \ + nxstesthub.h \ + rsgxsnetservice_test.h \ + nxstestscenario.h \ + data_support.h +} + + +dstore_target { + TARGET = rs_dstore_test + SOURCES += \ + support.cc \ + rsdataservice_test.cc \ + data_support.cc + + HEADERS += support.h \ + rsdataservice_test.h \ + data_support.h + + +} + +gxsdata_target { + + SOURCES += \ + support.cc \ + data_support.cc \ + rsgxsdata_test.cc + +HEADERS += \ + support.h \ + rsgxsdata_test.h } INCLUDEPATH += ../../ diff --git a/libretroshare/src/tests/gxs/rsdataservice_test.cc b/libretroshare/src/tests/gxs/rsdataservice_test.cc index e1d0243fe..90f800355 100644 --- a/libretroshare/src/tests/gxs/rsdataservice_test.cc +++ b/libretroshare/src/tests/gxs/rsdataservice_test.cc @@ -339,8 +339,7 @@ void tearDown(){ bool operator ==(const RsGxsGrpMetaData& l, const RsGxsGrpMetaData& r) { - if(!(l.adminSign == r.adminSign)) return false; - if(!(l.idSign == r.idSign)) return false; + if(!(l.signSet == r.signSet)) return false; if(!(l.keys == r.keys)) return false; if(l.mGroupFlags != r.mGroupFlags) return false; if(l.mPublishTs != r.mPublishTs) return false; @@ -358,8 +357,7 @@ bool operator ==(const RsGxsGrpMetaData& l, const RsGxsGrpMetaData& r) bool operator ==(const RsGxsMsgMetaData& l, const RsGxsMsgMetaData& r) { - if(!(l.idSign == r.idSign)) return false; - if(!(l.pubSign == r.pubSign)) return false; + if(!(l.signSet == r.signSet)) return false; if(l.mGroupId != r.mGroupId) return false; if(l.mAuthorId != r.mAuthorId) return false; if(l.mParentId != r.mParentId) return false; diff --git a/libretroshare/src/tests/gxs/rsgenexchange_test.cc b/libretroshare/src/tests/gxs/rsgenexchange_test.cc index 2a6769a37..7067e87f6 100644 --- a/libretroshare/src/tests/gxs/rsgenexchange_test.cc +++ b/libretroshare/src/tests/gxs/rsgenexchange_test.cc @@ -14,14 +14,14 @@ int main() { GenExchangeTester tester; -// CHECK(tester.testMsgSubmissionRetrieval()); REPORT("testMsgSubmissionRetrieval()"); + CHECK(tester.testMsgSubmissionRetrieval()); REPORT("testMsgSubmissionRetrieval()"); // CHECK(tester.testSpecificMsgMetaRetrieval()); REPORT("testSpecificMsgMetaRetrieval()"); // CHECK(tester.testMsgIdRetrieval()); REPORT("tester.testMsgIdRetrieval()"); // CHECK(tester.testMsgIdRetrieval_OptParents()); REPORT("tester.testRelatedMsgIdRetrieval_Parents()"); // CHECK(tester.testMsgIdRetrieval_OptOrigMsgId()); REPORT("tester.testRelatedMsgIdRetrieval_OrigMsgId()"); // CHECK(tester.testMsgIdRetrieval_OptLatest()); REPORT("tester.testRelatedMsgIdRetrieval_Latest()"); -// CHECK(tester.testMsgMetaModRequest()); REPORT("tester.testMsgMetaModRequest()"); -// CHECK(tester.testMsgChildRetrieval()); REPORT("tester.testMsgMetaModRequest()"); + CHECK(tester.testMsgMetaModRequest()); REPORT("tester.testMsgMetaModRequest()"); + CHECK(tester.testMsgChildRetrieval()); REPORT("tester.testMsgMetaModRequest()"); CHECK(tester.testGrpSubmissionRetrieval()); REPORT("tester.testGrpSubmissionRetrieval()"); CHECK(tester.testGrpMetaRetrieval()); REPORT("tester.testGrpMetaRetrieval()"); diff --git a/libretroshare/src/tests/gxs/rsgxsdata_test.cc b/libretroshare/src/tests/gxs/rsgxsdata_test.cc index 990240f8a..fa5dc3c6b 100644 --- a/libretroshare/src/tests/gxs/rsgxsdata_test.cc +++ b/libretroshare/src/tests/gxs/rsgxsdata_test.cc @@ -49,8 +49,7 @@ int main() bool operator ==(const RsGxsGrpMetaData& l, const RsGxsGrpMetaData& r) { - if(!(l.adminSign == r.adminSign)) return false; - if(!(l.idSign == r.idSign)) return false; + if(!(l.signSet == r.signSet)) return false; if(!(l.keys == r.keys)) return false; if(l.mGroupFlags != r.mGroupFlags) return false; if(l.mPublishTs != r.mPublishTs) return false; @@ -64,8 +63,7 @@ bool operator ==(const RsGxsGrpMetaData& l, const RsGxsGrpMetaData& r) bool operator ==(const RsGxsMsgMetaData& l, const RsGxsMsgMetaData& r) { - if(!(l.idSign == r.idSign)) return false; - if(!(l.pubSign == r.pubSign)) return false; + if(!(l.signSet == r.signSet)) return false; if(l.mGroupId != r.mGroupId) return false; if(l.mAuthorId != r.mAuthorId) return false; if(l.mParentId != r.mParentId) return false; diff --git a/libretroshare/src/tests/gxs/support.cc b/libretroshare/src/tests/gxs/support.cc index e726cef33..9003b6b60 100644 --- a/libretroshare/src/tests/gxs/support.cc +++ b/libretroshare/src/tests/gxs/support.cc @@ -103,6 +103,30 @@ bool operator==(const RsTlvSecurityKey& sk1, const RsTlvSecurityKey& sk2) return true; } +bool operator==(const RsTlvKeySignatureSet& kss1, const RsTlvKeySignatureSet& kss2) +{ + const std::map& set1 = kss1.keySignSet, + &set2 = kss2.keySignSet; + + if(set1.size() != set2.size()) return false; + + std::map::const_iterator it1 = set1.begin(), it2; + + for(; it1 != set1.end(); it1++) + { + SignType st1 = it1->first; + + if( (it2 =set2.find(st1)) == set2.end()) + return false; + + if(!(it1->second == it2->second)) + return false; + + } + + return true; +} + bool operator==(const RsTlvKeySignature& ks1, const RsTlvKeySignature& ks2) { @@ -138,6 +162,19 @@ void init_item(RsTlvImage& im) return; } +void init_item(RsTlvKeySignatureSet &kss) +{ + int numSign = rand()%21; + + for(int i=0; i < numSign; i++) + { + RsTlvKeySignature sign; + SignType sType = rand()%2452; + init_item(sign); + kss.keySignSet.insert(std::make_pair(sType, sign)); + } +} + bool operator==(const RsTlvBinaryData& bd1, const RsTlvBinaryData& bd2) { if(bd1.tlvtype != bd2.tlvtype) return false; diff --git a/libretroshare/src/tests/gxs/support.h b/libretroshare/src/tests/gxs/support.h index 901b2f4ef..bf33716af 100644 --- a/libretroshare/src/tests/gxs/support.h +++ b/libretroshare/src/tests/gxs/support.h @@ -56,6 +56,7 @@ void randString(const uint32_t, std::wstring&); void init_item(RsTlvSecurityKey&); void init_item(RsTlvKeySignature&); +void init_item(RsTlvKeySignatureSet&); void init_item(RsTlvBinaryData&); void init_item(RsTlvFileItem&); void init_item(RsTlvFileSet&); @@ -74,6 +75,7 @@ bool operator==(const RsTlvHashSet&, const RsTlvHashSet&); bool operator==(const RsTlvImage&, const RsTlvImage& ); bool operator==(const RsTlvPeerIdSet& , const RsTlvPeerIdSet& ); bool operator==(const RsTlvSecurityKeySet& , const RsTlvSecurityKeySet& ); +bool operator==(const RsTlvKeySignatureSet& , const RsTlvKeySignatureSet& ); diff --git a/libretroshare/src/tests/serialiser/support.cc b/libretroshare/src/tests/serialiser/support.cc index 9b4a22390..5207590b6 100644 --- a/libretroshare/src/tests/serialiser/support.cc +++ b/libretroshare/src/tests/serialiser/support.cc @@ -81,6 +81,30 @@ bool operator==(const RsTlvKeySignature& ks1, const RsTlvKeySignature& ks2) return true; } +bool operator==(const RsTlvKeySignatureSet& kss1, const RsTlvKeySignatureSet& kss2) +{ + const std::map& set1 = kss1.keySignSet, + &set2 = kss2.keySignSet; + + if(set1.size() != set2.size()) return false; + + std::map::const_iterator it1 = set1.begin(), it2; + + for(; it1 != set1.end(); it1++) + { + SignType st1 = it1->first; + + if( (it2 =set2.find(st1)) == set2.end()) + return false; + + if(!(it1->second == it2->second)) + return false; + + } + + return true; +} + bool operator==(const RsTlvPeerIdSet& pids1, const RsTlvPeerIdSet& pids2) { std::list::const_iterator it1 = pids1.ids.begin(), @@ -153,6 +177,18 @@ void init_item(RsTlvKeySignature& ks) return; } +void init_item(RsTlvKeySignatureSet &kss) +{ + int numSign = rand()%21; + + for(int i=0; i < numSign; i++) + { + RsTlvKeySignature sign; + SignType sType = rand()%2452; + init_item(sign); + kss.keySignSet.insert(std::make_pair(sType, sign)); + } +} bool operator==(const RsTlvImage& img1, const RsTlvImage& img2) diff --git a/libretroshare/src/tests/serialiser/support.h b/libretroshare/src/tests/serialiser/support.h index 9f2f8868d..3d1e23f6d 100644 --- a/libretroshare/src/tests/serialiser/support.h +++ b/libretroshare/src/tests/serialiser/support.h @@ -56,6 +56,7 @@ void randString(const uint32_t, std::wstring&); void init_item(RsTlvSecurityKey&); void init_item(RsTlvKeySignature&); +void init_item(RsTlvKeySignatureSet&); void init_item(RsTlvBinaryData&); void init_item(RsTlvFileItem&); void init_item(RsTlvFileSet&); @@ -72,6 +73,7 @@ bool operator==(const RsTlvFileSet&, const RsTlvFileSet& ); bool operator==(const RsTlvHashSet&, const RsTlvHashSet&); bool operator==(const RsTlvImage&, const RsTlvImage& ); bool operator==(const RsTlvPeerIdSet& , const RsTlvPeerIdSet& ); +bool operator==(const RsTlvKeySignatureSet& , const RsTlvKeySignatureSet& ); diff --git a/libretroshare/src/tests/serialiser/tlvkey_test.cc b/libretroshare/src/tests/serialiser/tlvkey_test.cc new file mode 100644 index 000000000..23c87a715 --- /dev/null +++ b/libretroshare/src/tests/serialiser/tlvkey_test.cc @@ -0,0 +1,36 @@ + + +#include "support.h" +#include "serialiser/rstlvkeys.h" + +INITTEST(); + +bool test_RsTlvKeySignatureSet(); + +int main() +{ + test_RsTlvKeySignatureSet(); REPORT("test_RsTlvKeySignatureSet()"); + + FINALREPORT("RsTlvKey Test"); +} + + + +bool test_RsTlvKeySignatureSet() +{ + RsTlvKeySignatureSet set; + + init_item(set); + + char data[set.TlvSize()]; + uint32_t offset = 0; + set.SetTlv(data, set.TlvSize(), &offset); + + RsTlvKeySignatureSet setConfirm; + + offset = 0; + setConfirm.GetTlv(data, set.TlvSize(), &offset); + + CHECK(setConfirm == set); + +} From dfa39c63a895bdc2ceb4808637662a5b526fc376 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 2 Oct 2012 19:00:17 +0000 Subject: [PATCH 073/222] fixed linux compilation. Added missing target in .pro git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5632 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/libretroshare.pro | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 063dc8aa7..ef479aa15 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -9,8 +9,8 @@ TARGET = retroshare CONFIG += test_voip # GXS Stuff. -CONFIG += newcache -CONFIG += newservices +#CONFIG += newcache +#CONFIG += newservices # Beware: All data of the stripped services are lost DEFINES *= PQI_DISABLE_TUNNEL @@ -149,7 +149,31 @@ HEADERS += retroshare/rsgame.h \ retroshare/rsphoto.h # ################################ Linux ########################################## + linux-* { + QMAKE_CC = g++ + OBJECTS_DIR = temp/obj + MOC_DIR = temp/moc + DESTDIR = lib + + # miniupnp implementation files + #HEADERS += upnp/upnputil.h + #SOURCES += upnp/upnputil.c + + # zeroconf disabled at the end of libretroshare.pro (but need the code) + #CONFIG += zeroconf + #CONFIG += zcnatassist + + OPENPGPSDK_DIR = ../../openpgpsdk/src + INCLUDEPATH += $${OPENPGPSDK_DIR} + INCLUDEPATH *= /usr/lib/x86_64-linux-gnu/glib-2.0/include/ + INCLUDEPATH *= /usr/lib/i386-linux-gnu/glib-2.0/include/ + INCLUDEPATH *= /usr/include/glib-2.0/ /usr/lib/glib-2.0/include + INCLUDEPATH *= /usr/local/include/glib-2.0 + + DEFINES *= UBUNTU + } + # ################### Cross compilation for windows under Linux #################### win32-x-g++ { OBJECTS_DIR = temp/win32xgcc/obj From 91bf67a7fed33099424d226f1b5053f054e55d8f Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Tue, 2 Oct 2012 19:15:24 +0000 Subject: [PATCH 074/222] fixed compilation issue for linux. needed to add inttypes header file (not needed for windows...) git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5633 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/pqi/pqihash.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libretroshare/src/pqi/pqihash.h b/libretroshare/src/pqi/pqihash.h index bf87f9d2f..7bf3cd506 100644 --- a/libretroshare/src/pqi/pqihash.h +++ b/libretroshare/src/pqi/pqihash.h @@ -27,6 +27,7 @@ #include #include #include "util/rsstring.h" +#include class pqihash { From a57d627074b5ca653384f7a941d42bd1fcc72bec Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 4 Oct 2012 19:11:21 +0000 Subject: [PATCH 075/222] added qt file to handle protobuf targets git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5636 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/protobuf.pri | 36 +++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 retroshare-nogui/src/protobuf.pri diff --git a/retroshare-nogui/src/protobuf.pri b/retroshare-nogui/src/protobuf.pri new file mode 100644 index 000000000..b4c545774 --- /dev/null +++ b/retroshare-nogui/src/protobuf.pri @@ -0,0 +1,36 @@ +# +# Qt qmake integration with Google Protocol Buffers compiler protoc +# +# To compile protocol buffers with qt qmake, specify PROTOS variable and +# include this file +# +# Example: +# LIBS += /usr/local/lib/libprotobuf.so +# PROTOS = a.proto b.proto +# include(protobuf.pri) +# +# By default protoc looks for .proto files (including the imported ones) in +# the current directory where protoc is run. If you need to include additional +# paths specify the PROTOPATH variable +# + +PROTOPATH += . +PROTOPATH += ../Protocol +PROTOPATHS = +for(p, PROTOPATH):PROTOPATHS += --proto_path=$${p} + +protobuf_decl.name = protobuf header +protobuf_decl.input = PROTOS +protobuf_decl.output = ${QMAKE_FILE_BASE}.pb.h +protobuf_decl.commands = protoc --cpp_out="." $${PROTOPATHS} ${QMAKE_FILE_NAME} +protobuf_decl.variable_out = GENERATED_FILES +QMAKE_EXTRA_COMPILERS += protobuf_decl + +protobuf_impl.name = protobuf implementation +protobuf_impl.input = PROTOS +protobuf_impl.output = ${QMAKE_FILE_BASE}.pb.cc +protobuf_impl.depends = ${QMAKE_FILE_BASE}.pb.h +protobuf_impl.commands = $$escape_expand(\n) +protobuf_impl.variable_out = GENERATED_SOURCES +QMAKE_EXTRA_COMPILERS += protobuf_impl + From 8f2d85ed52ee8d68a03b291c2aafeb9e9655c368 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Fri, 5 Oct 2012 18:12:52 +0000 Subject: [PATCH 076/222] laid groundwork for newcache posted re-enabled postedVEG added convenience base class for gxs services fixed posted and gxs gui removed tokenservicev2, now just tokenservice git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5641 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgenexchange.cc | 16 +- libretroshare/src/gxs/rsgenexchange.h | 2 +- libretroshare/src/gxs/rsgxs.h | 1 + libretroshare/src/gxs/rsgxsdataaccess.cc | 14 +- libretroshare/src/gxs/rsgxsdataaccess.h | 2 +- libretroshare/src/gxs/rsgxsifaceimpl.cc | 61 + libretroshare/src/gxs/rsgxsifaceimpl.h | 71 + libretroshare/src/gxs/rstokenservice.h | 6 +- libretroshare/src/libretroshare.pro | 1297 +++++++++-------- libretroshare/src/retroshare/rsphotoV2.h | 3 +- libretroshare/src/retroshare/rsposted.h | 155 ++ .../src/services/p3photoserviceV2.cc | 2 +- libretroshare/src/services/p3photoserviceV2.h | 2 +- libretroshare/src/services/p3posted.cc | 86 ++ libretroshare/src/services/p3posted.h | 52 + retroshare-gui/src/RetroShare.pro | 27 +- .../src/gui/Posted/PostedComments.cpp | 6 +- .../src/gui/Posted/PostedComments.h | 10 +- .../src/gui/Posted/PostedDialog.cpp | 2 +- retroshare-gui/src/gui/Posted/PostedDialog.h | 2 +- retroshare-gui/src/gui/Posted/PostedItem.cpp | 6 +- retroshare-gui/src/gui/Posted/PostedItem.h | 2 +- .../src/gui/Posted/PostedListDialog.cpp | 54 +- .../src/gui/Posted/PostedListDialog.h | 10 +- .../src/gui/gxs/GxsCommentTreeWidget.cpp | 12 +- .../src/gui/gxs/GxsCommentTreeWidget.h | 12 +- retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp | 8 +- retroshare-gui/src/gui/gxs/GxsGroupDialog.h | 12 +- .../src/gui/gxs/PostedGroupDialog.cpp | 10 +- .../src/gui/unfinished/ApplicationWindow.cpp | 10 +- retroshare-gui/src/util/TokenQueueV2.cpp | 6 +- retroshare-gui/src/util/TokenQueueV2.h | 4 +- 32 files changed, 1202 insertions(+), 761 deletions(-) create mode 100644 libretroshare/src/gxs/rsgxsifaceimpl.cc create mode 100644 libretroshare/src/gxs/rsgxsifaceimpl.h create mode 100644 libretroshare/src/retroshare/rsposted.h create mode 100644 libretroshare/src/services/p3posted.cc create mode 100644 libretroshare/src/services/p3posted.h diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 6e4a4191f..00b0eeb05 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -395,7 +395,7 @@ bool RsGenExchange::getMsgData(const uint32_t &token, } -RsTokenServiceV2* RsGenExchange::getTokenService() +RsTokenService* RsGenExchange::getTokenService() { return mDataAccess; } @@ -511,10 +511,10 @@ void RsGenExchange::processMsgMetaChanges() if(ok) { - mDataAccess->updatePublicRequestStatus(token, RsTokenServiceV2::GXS_REQUEST_V2_STATUS_COMPLETE); + mDataAccess->updatePublicRequestStatus(token, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE); }else { - mDataAccess->updatePublicRequestStatus(token, RsTokenServiceV2::GXS_REQUEST_V2_STATUS_FAILED); + mDataAccess->updatePublicRequestStatus(token, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED); } mMsgNotify.insert(std::make_pair(token, m.msgId)); } @@ -537,10 +537,10 @@ void RsGenExchange::processGrpMetaChanges() if(ok) { - mDataAccess->updatePublicRequestStatus(token, RsTokenServiceV2::GXS_REQUEST_V2_STATUS_COMPLETE); + mDataAccess->updatePublicRequestStatus(token, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE); }else { - mDataAccess->updatePublicRequestStatus(token, RsTokenServiceV2::GXS_REQUEST_V2_STATUS_FAILED); + mDataAccess->updatePublicRequestStatus(token, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED); } mGrpNotify.insert(std::make_pair(token, g.grpId)); } @@ -605,7 +605,7 @@ void RsGenExchange::publishMsgs() // add to published to allow acknowledgement mMsgNotify.insert(std::make_pair(mit->first, std::make_pair(grpId, msgId))); - mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_V2_STATUS_COMPLETE); + mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE); } // if addition failed then delete nxs message @@ -663,7 +663,7 @@ void RsGenExchange::publishGrps() // add to published to allow acknowledgement mGrpNotify.insert(std::make_pair(mit->first, grpId)); - mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_V2_STATUS_COMPLETE); + mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE); } if(!ok) @@ -676,7 +676,7 @@ void RsGenExchange::publishGrps() // add to published to allow acknowledgement, grpid is empty as grp creation failed mGrpNotify.insert(std::make_pair(mit->first, RsGxsGroupId(""))); - mDataAccess->updatePublicRequestStatus(mit->first, RsTokenServiceV2::GXS_REQUEST_V2_STATUS_FAILED); + mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED); continue; } diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index c2b20ea34..7af1c73ad 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -103,7 +103,7 @@ public: * @return handle to token service handle for making * request to this gxs service */ - RsTokenServiceV2* getTokenService(); + RsTokenService* getTokenService(); protected: diff --git a/libretroshare/src/gxs/rsgxs.h b/libretroshare/src/gxs/rsgxs.h index 4bb9a4cdf..5fef2a329 100644 --- a/libretroshare/src/gxs/rsgxs.h +++ b/libretroshare/src/gxs/rsgxs.h @@ -39,6 +39,7 @@ typedef std::map > GxsMsgReq; typedef std::map > GxsMsgIdResult; typedef std::map > GxsMsgMetaResult; +typedef std::map > MsgMetaResult; class RsGxsService { diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index 123edb55c..06dae853d 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -49,12 +49,12 @@ #define RS_TOKREQ_ANSTYPE_SUMMARY 0x0002 #define RS_TOKREQ_ANSTYPE_DATA 0x0003 - const uint8_t RsTokenServiceV2::GXS_REQUEST_V2_STATUS_FAILED = 0; - const uint8_t RsTokenServiceV2::GXS_REQUEST_V2_STATUS_PENDING = 1; - const uint8_t RsTokenServiceV2::GXS_REQUEST_V2_STATUS_PARTIAL = 2; - const uint8_t RsTokenServiceV2::GXS_REQUEST_V2_STATUS_FINISHED_INCOMPLETE = 3; - const uint8_t RsTokenServiceV2::GXS_REQUEST_V2_STATUS_COMPLETE = 4; - const uint8_t RsTokenServiceV2::GXS_REQUEST_V2_STATUS_DONE = 5; // ONCE ALL DATA RETRIEVED. + const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_FAILED = 0; + const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_PENDING = 1; + const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_PARTIAL = 2; + const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_FINISHED_INCOMPLETE = 3; + const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE = 4; + const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_DONE = 5; // ONCE ALL DATA RETRIEVED. RsGxsDataAccess::RsGxsDataAccess(RsGeneralDataService* ds) : mDataStore(ds), mDataMutex("RsGxsDataAccess"), mNextToken(0) @@ -1331,7 +1331,7 @@ uint32_t RsGxsDataAccess::generatePublicToken() { RsStackMutex stack(mDataMutex); - mPublicToken[token] = RsTokenServiceV2::GXS_REQUEST_V2_STATUS_PENDING; + mPublicToken[token] = RsTokenService::GXS_REQUEST_V2_STATUS_PENDING; } return token; diff --git a/libretroshare/src/gxs/rsgxsdataaccess.h b/libretroshare/src/gxs/rsgxsdataaccess.h index 04911bf65..6642ee6ce 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.h +++ b/libretroshare/src/gxs/rsgxsdataaccess.h @@ -33,7 +33,7 @@ typedef std::map< RsGxsGroupId, std::map > MsgMetaFilter; -class RsGxsDataAccess : public RsTokenServiceV2 +class RsGxsDataAccess : public RsTokenService { public: RsGxsDataAccess(RsGeneralDataService* ds); diff --git a/libretroshare/src/gxs/rsgxsifaceimpl.cc b/libretroshare/src/gxs/rsgxsifaceimpl.cc new file mode 100644 index 000000000..93af1bf3d --- /dev/null +++ b/libretroshare/src/gxs/rsgxsifaceimpl.cc @@ -0,0 +1,61 @@ +#include "rsgxsifaceimpl.h" +#include "gxs/rsgxs.h" + +RsGxsIfaceImpl::RsGxsIfaceImpl(RsGenExchange *gxs) + : mGxs(gxs) +{ +} + + + +void RsGxsIfaceImpl::groupsChanged(std::list& grpIds) +{ + +} + + +void RsGxsIfaceImpl::msgsChanged(std::map >& msgs) +{ + +} + +RsTokenService* RsGxsIfaceImpl::getTokenService() +{ + return mGxs->getTokenService(); +} + +bool RsGxsIfaceImpl::getGroupList(const uint32_t &token, + std::list &groupIds) +{ + +} + +bool RsGxsIfaceImpl::getMsgList(const uint32_t &token, + GxsMsgIdResult& msgIds) +{ + +} + +/* Generic Summary */ +bool RsGxsIfaceImpl::getGroupSummary(const uint32_t &token, + std::list &groupInfo) +{ + +} + +bool RsGxsIfaceImpl::getMsgSummary(const uint32_t &token, + GxsMsgMetaMap &msgInfo) +{ + +} + +bool RsGxsIfaceImpl::acknowledgeMsg(const uint32_t& token, std::pair& msgId) +{ + +} + +bool RsGxsIfaceImpl::acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId) +{ + +} diff --git a/libretroshare/src/gxs/rsgxsifaceimpl.h b/libretroshare/src/gxs/rsgxsifaceimpl.h new file mode 100644 index 000000000..16cc69a4e --- /dev/null +++ b/libretroshare/src/gxs/rsgxsifaceimpl.h @@ -0,0 +1,71 @@ +#ifndef RSGXSIFACEIMPL_H +#define RSGXSIFACEIMPL_H + +#include "gxs/rsgenexchange.h" + +/*! + * The simple idea of this class is to implement the simple interface functions + * of gen exchange + */ +class RsGxsIfaceImpl +{ +public: + + RsGxsIfaceImpl(RsGenExchange* gxs); + + + /*! + * @return true if a change has occured + */ + bool updated(); + +public: + + /** Requests **/ + + void groupsChanged(std::list& grpIds); + + + void msgsChanged(std::map >& msgs); + + RsTokenService* getTokenService(); + + bool getGroupList(const uint32_t &token, + std::list &groupIds); + bool getMsgList(const uint32_t &token, + GxsMsgIdResult& msgIds); + + /* Generic Summary */ + bool getGroupSummary(const uint32_t &token, + std::list &groupInfo); + + bool getMsgSummary(const uint32_t &token, + GxsMsgMetaMap &msgInfo); + + /*! + * This allows the client service to acknowledge that their msgs has + * been created/modified and retrieve the create/modified msg ids + * @param token the token related to modification/create request + * @param msgIds map of grpid->msgIds of message created/modified + * @return true if token exists false otherwise + */ + bool acknowledgeMsg(const uint32_t& token, std::pair& msgId); + + /*! + * This allows the client service to acknowledge that their grps has + * been created/modified and retrieve the create/modified grp ids + * @param token the token related to modification/create request + * @param msgIds vector of ids of groups created/modified + * @return true if token exists false otherwise + */ + bool acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId); + + + +private: + + RsGenExchange* mGxs; +}; + +#endif // RSGXSIFACEIMPL_H diff --git a/libretroshare/src/gxs/rstokenservice.h b/libretroshare/src/gxs/rstokenservice.h index 870e6db5f..316b6a454 100644 --- a/libretroshare/src/gxs/rstokenservice.h +++ b/libretroshare/src/gxs/rstokenservice.h @@ -102,7 +102,7 @@ time_t mAfter; * A proxy class for requesting generic service data for GXS * This seperates the request mechanism from the actual retrieval of data */ -class RsTokenServiceV2 +class RsTokenService { public: @@ -116,8 +116,8 @@ public: public: - RsTokenServiceV2() { return; } - virtual ~RsTokenServiceV2() { return; } + RsTokenService() { return; } + virtual ~RsTokenService() { return; } /* Data Requests */ diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index ef479aa15..fcb79000e 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -1,644 +1,653 @@ -TEMPLATE = lib - -# CONFIG += staticlib release -# CONFIG += staticlib testnetwork -CONFIG += staticlib \ - bitdht -CONFIG -= qt -TARGET = retroshare -CONFIG += test_voip - -# GXS Stuff. -#CONFIG += newcache -#CONFIG += newservices - -# Beware: All data of the stripped services are lost -DEFINES *= PQI_DISABLE_TUNNEL - -# ENABLE_CACHE_OPT -profiling { - QMAKE_CXXFLAGS -= -fomit-frame-pointer - QMAKE_CXXFLAGS *= -pg \ - -g \ - -fno-omit-frame-pointer -} -release: - -# UDP and TUNNEL dont work anymore. -# DEFINES *= PQI_DISABLE_UDP -# treat warnings as error for better removing -# QMAKE_CFLAGS += -Werror -# QMAKE_CXXFLAGS += -Werror -testnetwork { - # used in rsserver/rsinit.cc Enabled Port Restrictions, and makes Proxy Port next to Dht Port. - DEFINES *= LOCALNET_TESTING - - # used in tcponudp/udprelay.cc Debugging Info for Relays. - DEFINES *= DEBUG_UDP_RELAY - - # used in tcponudp/udpstunner.[h | cc] enables local stun (careful - modifies class variables). - DEFINES *= UDPSTUN_ALLOW_LOCALNET - - # used in pqi/p3linkmgr.cc prints out extra debug. - DEFINES *= LINKMGR_DEBUG_LINKTYPE - - # used in dht/connectstatebox to reduce connection times and display debug. - # DEFINES *= TESTING_PERIODS - # DEFINES *= DEBUG_CONNECTBOX - QMAKE_CXXFLAGS -= -fomit-frame-pointer - QMAKE_CXXFLAGS -= -O2 - QMAKE_CXXFLAGS *= -g \ - -fno-omit-frame-pointer -} -CONFIG += debug -debug { - # DEFINES *= DEBUG - # DEFINES *= OPENDHT_DEBUG DHT_DEBUG CONN_DEBUG DEBUG_UDP_SORTER P3DISC_DEBUG DEBUG_UDP_LAYER FT_DEBUG EXTADDRSEARCH_DEBUG - # DEFINES *= CONTROL_DEBUG FT_DEBUG DEBUG_FTCHUNK P3TURTLE_DEBUG - # DEFINES *= P3TURTLE_DEBUG - # DEFINES *= NET_DEBUG - # DEFINES *= DISTRIB_DEBUG - # DEFINES *= P3TURTLE_DEBUG FT_DEBUG DEBUG_FTCHUNK MPLEX_DEBUG - # DEFINES *= STATUS_DEBUG SERV_DEBUG RSSERIAL_DEBUG #CONN_DEBUG - QMAKE_CXXFLAGS -= -O2 \ - -fomit-frame-pointer - QMAKE_CXXFLAGS *= -g \ - -fno-omit-frame-pointer -} -bitdht { - HEADERS += dht/p3bitdht.h \ - dht/connectstatebox.h \ - dht/stunaddrassist.h - SOURCES += dht/p3bitdht.cc \ - dht/p3bitdht_interface.cc \ - dht/p3bitdht_peers.cc \ - dht/p3bitdht_peernet.cc \ - dht/p3bitdht_relay.cc \ - dht/connectstatebox.cc - HEADERS += tcponudp/udppeer.h \ - tcponudp/bio_tou.h \ - tcponudp/tcppacket.h \ - tcponudp/tcpstream.h \ - tcponudp/tou.h \ - tcponudp/udpstunner.h \ - tcponudp/udprelay.h - SOURCES += tcponudp/udppeer.cc \ - tcponudp/tcppacket.cc \ - tcponudp/tcpstream.cc \ - tcponudp/tou.cc \ - tcponudp/bss_tou.c \ - tcponudp/udpstunner.cc \ - tcponudp/udprelay.cc - - # These two aren't actually used (and don't compile) .... - # but could be useful later - # tcponudp/udpstunner.h \ - # tcponudp/udpstunner.cc \ - BITDHT_DIR = ../../libbitdht/src - INCLUDEPATH += . \ - $${BITDHT_DIR} - - # The next line if for compliance with debian packages. Keep it! - INCLUDEPATH += ../libbitdht - DEFINES *= RS_USE_BITDHT -} -test_bitdht { - # DISABLE TCP CONNECTIONS... - DEFINES *= P3CONNMGR_NO_TCP_CONNECTIONS - - # NO AUTO CONNECTIONS??? FOR TESTING DHT STATUS. - DEFINES *= P3CONNMGR_NO_AUTO_CONNECTION -} - -# ENABLED UDP NOW. -use_blogs { - HEADERS += services/p3blogs.h - SOURCES += services/p3blogs.cc - DEFINES *= RS_USE_BLOGS -} -PUBLIC_HEADERS = retroshare/rsblogs.h \ - retroshare/rschannels.h \ - retroshare/rsdisc.h \ - retroshare/rsdistrib.h \ - retroshare/rsexpr.h \ - retroshare/rsfiles.h \ - retroshare/rsforums.h \ - retroshare/rshistory.h \ - retroshare/rsiface.h \ - retroshare/rsinit.h \ - retroshare/rsplugin.h \ - retroshare/rsloginhandler.h \ - retroshare/rsmsgs.h \ - retroshare/rsnotify.h \ - retroshare/rspeers.h \ - retroshare/rsrank.h \ - retroshare/rsstatus.h \ - retroshare/rsturtle.h \ - retroshare/rstypes.h \ - retroshare/rsdht.h \ - retroshare/rsdsdv.h \ - retroshare/rsconfig.h \ - retroshare/rsphotoV2.h -HEADERS += plugins/pluginmanager.h \ - plugins/dlfcn_win32.h \ - serialiser/rspluginitems.h -HEADERS += $$PUBLIC_HEADERS - -# public headers to be... -HEADERS += retroshare/rsgame.h \ - retroshare/rsphoto.h - -# ################################ Linux ########################################## - linux-* { - QMAKE_CC = g++ - OBJECTS_DIR = temp/obj - MOC_DIR = temp/moc - DESTDIR = lib - - # miniupnp implementation files - #HEADERS += upnp/upnputil.h - #SOURCES += upnp/upnputil.c - - # zeroconf disabled at the end of libretroshare.pro (but need the code) - #CONFIG += zeroconf - #CONFIG += zcnatassist - - OPENPGPSDK_DIR = ../../openpgpsdk/src - INCLUDEPATH += $${OPENPGPSDK_DIR} - - INCLUDEPATH *= /usr/lib/x86_64-linux-gnu/glib-2.0/include/ - INCLUDEPATH *= /usr/lib/i386-linux-gnu/glib-2.0/include/ - INCLUDEPATH *= /usr/include/glib-2.0/ /usr/lib/glib-2.0/include - INCLUDEPATH *= /usr/local/include/glib-2.0 - - DEFINES *= UBUNTU - } - - # ################### Cross compilation for windows under Linux #################### - win32-x-g++ { - OBJECTS_DIR = temp/win32xgcc/obj - DESTDIR = lib.win32xgcc - DEFINES *= WINDOWS_SYS \ - WIN32 \ - WIN_CROSS_UBUNTU - QMAKE_CXXFLAGS *= -Wmissing-include-dirs - QMAKE_CC = i586-mingw32msvc-g++ - QMAKE_LIB = i586-mingw32msvc-ar - QMAKE_AR = i586-mingw32msvc-ar - DEFINES *= STATICLIB \ - WIN32 - - # miniupnp implementation files - HEADERS += upnp/upnputil.h - SOURCES += upnp/upnputil.c - SSL_DIR = ../../../../openssl - UPNPC_DIR = ../../../../miniupnpc-1.3 - GPG_ERROR_DIR = ../../../../libgpg-error-1.7 - GPGME_DIR = ../../../../gpgme-1.1.8 - INCLUDEPATH *= /usr/i586-mingw32msvc/include \ - ${HOME}/.wine/drive_c/pthreads/include/ - } - - # ################################ Windows ########################################## - win32 { - QMAKE_CC = g++ - OBJECTS_DIR = temp/obj - MOC_DIR = temp/moc - DEFINES *= WINDOWS_SYS \ - WIN32 \ - STATICLIB \ - MINGW - DEFINES *= MINIUPNPC_VERSION=13 - DESTDIR = lib - - # Switch on extra warnings - QMAKE_CFLAGS += -Wextra - QMAKE_CXXFLAGS += -Wextra - - # Switch off optimization for release version - QMAKE_CXXFLAGS_RELEASE -= -O2 - QMAKE_CXXFLAGS_RELEASE += -O0 - QMAKE_CFLAGS_RELEASE -= -O2 - QMAKE_CFLAGS_RELEASE += -O0 - - # Switch on optimization for debug version - # QMAKE_CXXFLAGS_DEBUG += -O2 - # QMAKE_CFLAGS_DEBUG += -O2 - DEFINES += USE_CMD_ARGS - - # miniupnp implementation files - HEADERS += upnp/upnputil.h - SOURCES += upnp/upnputil.c - UPNPC_DIR = ../../../lib/miniupnpc-1.3 - PTHREADS_DIR = ../../../lib/pthreads-w32-2-8-0-release - ZLIB_DIR = ../../../lib/zlib-1.2.3 - SSL_DIR = ../../../OpenSSL - OPENPGPSDK_DIR = ../../openpgpsdk/src - INCLUDEPATH += . \ - $${SSL_DIR}/include \ - $${UPNPC_DIR} \ - $${PTHREADS_DIR} \ - $${ZLIB_DIR} \ - $${OPENPGPSDK_DIR} - newcache { - SQLITE_DIR = ../../../../Libraries/sqlite/sqlite-autoconf-3070900 - INCLUDEPATH += . \ - $${SQLITE_DIR} - } - } - - # ################################ MacOSX ########################################## - mac { - QMAKE_CC = g++ - OBJECTS_DIR = temp/obj - MOC_DIR = temp/moc - - # DEFINES = WINDOWS_SYS WIN32 STATICLIB MINGW - # DEFINES *= MINIUPNPC_VERSION=13 - DESTDIR = lib - - # miniupnp implementation files - HEADERS += upnp/upnputil.h - SOURCES += upnp/upnputil.c - - # zeroconf disabled at the end of libretroshare.pro (but need the code) - CONFIG += zeroconf - CONFIG += zcnatassist - - # Beautiful Hack to fix 64bit file access. - QMAKE_CXXFLAGS *= -Dfseeko64=fseeko \ - -Dftello64=ftello \ - -Dfopen64=fopen \ - -Dvstatfs64=vstatfs - UPNPC_DIR = ../../../miniupnpc-1.0 - - # GPG_ERROR_DIR = ../../../../libgpg-error-1.7 - # GPGME_DIR = ../../../../gpgme-1.1.8 - OPENPGPSDK_DIR = ../../openpgpsdk/src - INCLUDEPATH += . \ - $${UPNPC_DIR} - INCLUDEPATH += $${OPENPGPSDK_DIR} - } - - # ../openpgpsdk - # INCLUDEPATH += . $${UPNPC_DIR} $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src - # ################################ FreeBSD ########################################## - freebsd-* { - INCLUDEPATH *= /usr/local/include/gpgme - INCLUDEPATH *= /usr/local/include/glib-2.0 - QMAKE_CXXFLAGS *= -Dfseeko64=fseeko \ - -Dftello64=ftello \ - -Dstat64=stat \ - -Dstatvfs64=statvfs \ - -Dfopen64=fopen - - # libupnp implementation files - HEADERS += upnp/UPnPBase.h - SOURCES += upnp/UPnPBase.cpp - DESTDIR = lib - } - - # ################################## COMMON stuff ################################## - HEADERS += dbase/cachestrapper.h \ - dbase/fimonitor.h \ - dbase/findex.h \ - dbase/fistore.h - - # HEADERS += dht/p3bitdht.h \ - HEADERS += ft/ftchunkmap.h \ - ft/ftcontroller.h \ - ft/ftdata.h \ - ft/ftdatamultiplex.h \ - ft/ftdbase.h \ - ft/ftextralist.h \ - ft/ftfilecreator.h \ - ft/ftfileprovider.h \ - ft/ftfilesearch.h \ - ft/ftsearch.h \ - ft/ftserver.h \ - ft/fttransfermodule.h - HEADERS += pqi/authssl.h \ - pqi/authgpg.h \ - pgp/pgphandler.h \ - pgp/pgpkeyutil.h \ - pqi/cleanupxpgp.h \ - pqi/p3cfgmgr.h \ - pqi/p3peermgr.h \ - pqi/p3linkmgr.h \ - pqi/p3netmgr.h \ - pqi/p3dhtmgr.h \ - pqi/p3notify.h \ - pqi/p3upnpmgr.h \ - pqi/pqiqos.h \ - pqi/pqi.h \ - pqi/pqi_base.h \ - pqi/pqiarchive.h \ - pqi/pqiassist.h \ - pqi/pqibin.h \ - pqi/pqihandler.h \ - pqi/pqihash.h \ - pqi/p3historymgr.h \ - pqi/pqiindic.h \ - pqi/pqiipset.h \ - pqi/pqilistener.h \ - pqi/pqiloopback.h \ - pqi/pqimonitor.h \ - pqi/pqinetwork.h \ - pqi/pqinotify.h \ - pqi/pqiperson.h \ - pqi/pqipersongrp.h \ - pqi/pqisecurity.h \ - pqi/pqiservice.h \ - pqi/pqissl.h \ - pqi/pqissllistener.h \ - pqi/pqisslpersongrp.h \ - pqi/pqissltunnel.h \ - pqi/pqissludp.h \ - pqi/pqistore.h \ - pqi/pqistreamer.h \ - pqi/pqiqosstreamer.h \ - pqi/sslfns.h \ - pqi/pqinetstatebox.h - HEADERS += rsserver/p3discovery.h \ - rsserver/p3face.h \ - rsserver/p3history.h \ - rsserver/p3msgs.h \ - rsserver/p3peers.h \ - rsserver/p3status.h \ - rsserver/p3serverconfig.h - HEADERS += serialiser/rsbaseitems.h \ - serialiser/rsbaseserial.h \ - serialiser/rsblogitems.h \ - serialiser/rschannelitems.h \ - serialiser/rsconfigitems.h \ - serialiser/rsdiscitems.h \ - serialiser/rsdistribitems.h \ - serialiser/rsforumitems.h \ - serialiser/rsgameitems.h \ - serialiser/rshistoryitems.h \ - serialiser/rsmsgitems.h \ - serialiser/rsserial.h \ - serialiser/rsserviceids.h \ - serialiser/rsserviceitems.h \ - serialiser/rsstatusitems.h \ - serialiser/rstlvaddrs.h \ - serialiser/rstlvbase.h \ - serialiser/rstlvkeys.h \ - serialiser/rstlvkvwide.h \ - serialiser/rstlvtypes.h \ - serialiser/rstlvutil.h \ - serialiser/rstlvdsdv.h \ - serialiser/rsdsdvitems.h \ - serialiser/rstlvbanlist.h \ - serialiser/rsbanlistitems.h \ - serialiser/rsbwctrlitems.h \ - serialiser/rstunnelitems.h - HEADERS += services/p3channels.h \ - services/p3chatservice.h \ - services/p3disc.h \ - services/p3forums.h \ - services/p3gamelauncher.h \ - services/p3gameservice.h \ - services/p3msgservice.h \ - services/p3service.h \ - services/p3statusservice.h \ - services/p3dsdv.h \ - services/p3banlist.h \ - services/p3bwctrl.h \ - services/p3tunnel.h - HEADERS += distrib/p3distrib.h \ - distrib/p3distribsecurity.h - - # services/p3blogs.h \ - HEADERS += turtle/p3turtle.h \ - turtle/rsturtleitem.h \ - turtle/turtletypes.h - HEADERS += upnp/upnphandler.h - HEADERS += util/folderiterator.h \ - util/rsdebug.h \ - util/smallobject.h \ - util/rsdir.h \ - util/rsdiscspace.h \ - util/rsnet.h \ - util/extaddrfinder.h \ - util/dnsresolver.h \ - util/rsprint.h \ - util/rsstring.h \ - util/rsthreads.h \ - util/rsversion.h \ - util/rswin.h \ - util/rsrandom.h \ - util/radix64.h \ - util/pugiconfig.h - SOURCES += dbase/cachestrapper.cc \ - dbase/fimonitor.cc \ - dbase/findex.cc \ - dbase/fistore.cc \ - dbase/rsexpr.cc - SOURCES += ft/ftchunkmap.cc \ - ft/ftcontroller.cc \ - ft/ftdata.cc \ - ft/ftdatamultiplex.cc \ - ft/ftdbase.cc \ - ft/ftextralist.cc \ - ft/ftfilecreator.cc \ - ft/ftfileprovider.cc \ - ft/ftfilesearch.cc \ - ft/ftserver.cc \ - ft/fttransfermodule.cc - SOURCES += pqi/authgpg.cc \ - pqi/authssl.cc \ - pgp/pgphandler.cc \ - pgp/pgpkeyutil.cc \ - pqi/cleanupxpgp.cc \ - pqi/p3cfgmgr.cc \ - pqi/p3peermgr.cc \ - pqi/p3linkmgr.cc \ - pqi/p3netmgr.cc \ - pqi/p3dhtmgr.cc \ - pqi/p3notify.cc \ - pqi/pqiqos.cc \ - pqi/pqiarchive.cc \ - pqi/pqibin.cc \ - pqi/pqihandler.cc \ - pqi/p3historymgr.cc \ - pqi/pqiipset.cc \ - pqi/pqiloopback.cc \ - pqi/pqimonitor.cc \ - pqi/pqinetwork.cc \ - pqi/pqiperson.cc \ - pqi/pqipersongrp.cc \ - pqi/pqisecurity.cc \ - pqi/pqiservice.cc \ - pqi/pqissl.cc \ - pqi/pqissllistener.cc \ - pqi/pqisslpersongrp.cc \ - pqi/pqissltunnel.cc \ - pqi/pqissludp.cc \ - pqi/pqistore.cc \ - pqi/pqistreamer.cc \ - pqi/pqiqosstreamer.cc \ - pqi/sslfns.cc \ - pqi/pqinetstatebox.cc - SOURCES += rsserver/p3discovery.cc \ - rsserver/p3face-config.cc \ - rsserver/p3face-msgs.cc \ - rsserver/p3face-server.cc \ - rsserver/p3history.cc \ - rsserver/p3msgs.cc \ - rsserver/p3peers.cc \ - rsserver/p3status.cc \ - rsserver/rsiface.cc \ - rsserver/rsinit.cc \ - rsserver/rsloginhandler.cc \ - rsserver/rstypes.cc \ - rsserver/p3serverconfig.cc - SOURCES += plugins/pluginmanager.cc \ - plugins/dlfcn_win32.cc \ - serialiser/rspluginitems.cc - SOURCES += serialiser/rsbaseitems.cc \ - serialiser/rsbaseserial.cc \ - serialiser/rsblogitems.cc \ - serialiser/rschannelitems.cc \ - serialiser/rsconfigitems.cc \ - serialiser/rsdiscitems.cc \ - serialiser/rsdistribitems.cc \ - serialiser/rsforumitems.cc \ - serialiser/rsgameitems.cc \ - serialiser/rshistoryitems.cc \ - serialiser/rsmsgitems.cc \ - serialiser/rsserial.cc \ - serialiser/rsstatusitems.cc \ - serialiser/rstlvaddrs.cc \ - serialiser/rstlvbase.cc \ - serialiser/rstlvfileitem.cc \ - serialiser/rstlvimage.cc \ - serialiser/rstlvkeys.cc \ - serialiser/rstlvkvwide.cc \ - serialiser/rstlvtypes.cc \ - serialiser/rstlvutil.cc \ - serialiser/rstlvdsdv.cc \ - serialiser/rsdsdvitems.cc \ - serialiser/rstlvbanlist.cc \ - serialiser/rsbanlistitems.cc \ - serialiser/rsbwctrlitems.cc \ - serialiser/rstunnelitems.cc - SOURCES += services/p3channels.cc \ - services/p3chatservice.cc \ - services/p3disc.cc \ - services/p3forums.cc \ - services/p3gamelauncher.cc \ - services/p3msgservice.cc \ - services/p3service.cc \ - services/p3statusservice.cc \ - services/p3dsdv.cc \ - services/p3banlist.cc \ - services/p3bwctrl.cc - - # removed because getPeer() doesn t exist services/p3tunnel.cc - SOURCES += distrib/p3distrib.cc \ - distrib/p3distribsecurity.cc - SOURCES += turtle/p3turtle.cc \ - turtle/rsturtleitem.cc - - # turtle/turtlerouting.cc \ - # turtle/turtlesearch.cc \ - # turtle/turtletunnels.cc - SOURCES += upnp/upnphandler.cc - SOURCES += util/folderiterator.cc \ - util/rsdebug.cc \ - util/smallobject.cc \ - util/rsdir.cc \ - util/rsdiscspace.cc \ - util/rsnet.cc \ - util/extaddrfinder.cc \ - util/dnsresolver.cc \ - util/rsprint.cc \ - util/rsstring.cc \ - util/rsthreads.cc \ - util/rsversion.cc \ - util/rswin.cc \ - util/rsrandom.cc - zeroconf { - HEADERS += zeroconf/p3zeroconf.h - SOURCES += zeroconf/p3zeroconf.cc - } - - # Disable Zeroconf (we still need the code for zcnatassist - # DEFINES *= RS_ENABLE_ZEROCONF - # This is seperated from the above for windows/linux platforms. - # It is acceptable to build in zeroconf and have it not work, - # but unacceptable to rely on Apple's libraries for Upnp when we have alternatives. ' - zcnatassist { - HEADERS += zeroconf/p3zcnatassist.h - SOURCES += zeroconf/p3zcnatassist.cc - DEFINES *= RS_ENABLE_ZCNATASSIST - } - - # new gxs cache system - newcache { - HEADERS += serialiser/rsnxsitems.h \ - gxs/rsgds.h \ - gxs/rsgxs.h \ - gxs/rsdataservice.h \ - gxs/rsgxsnetservice.h \ - gxs/rsgxsflags.h \ - gxs/rsgenexchange.h \ - gxs/rsnxsobserver.h \ - gxs/rsgxsdata.h \ - gxs/rstokenservice.h \ - gxs/rsgxsdataaccess.h \ - retroshare/rsgxsservice.h \ - serialiser/rsgxsitems.h \ - serialiser/rsphotov2items.h \ - util/retrodb.h \ - util/contentvalue.h \ - gxs/gxscoreserver.h \ - gxs/gxssecurity.h - - SOURCES += serialiser/rsnxsitems.cc \ - gxs/rsdataservice.cc \ - gxs/rsgenexchange.cc \ - gxs/rsgxsnetservice.cc \ - gxs/rsgxsdata.cc \ - serialiser/rsgxsitems.cc \ - services/p3photoserviceV2.cc \ - gxs/rsgxsdataaccess.cc \ - serialiser/rsphotov2items.cc \ - util/retrodb.cc \ - util/contentvalue.cc \ - gxs/gxscoreserver.cc \ - gxs/gxssecurity.cc - } - - newservices { - HEADERS += services/p3photoserviceV2.h \ - retroshare/rsphotoVEG.h \ - services/p3gxsserviceVEG.h \ - retroshare/rsidentityVEG.h \ - services/p3wikiserviceVEG.h \ - retroshare/rswikiVEG.h \ - retroshare/rswireVEG.h \ - services/p3wireVEG.h \ - services/p3idserviceVEG.h \ - retroshare/rsforumsVEG.h \ - services/p3forumsVEG.h \ - retroshare/rspostedVEG.h \ - services/p3postedVEG.h - - # Do I need this? - #serialiser/rsphotoitemsVEG.h \ - - SOURCES += services/p3gxsserviceVEG.cc \ - services/p3wikiserviceVEG.cc \ - services/p3wireVEG.cc \ - services/p3idserviceVEG.cc \ - services/p3forumsVEG.cc \ - services/p3postedVEG.cc - - # Do I need this? - # serialiser/rsphotoitemsVEG.cc \ - } - - - +TEMPLATE = lib + +# CONFIG += staticlib release +# CONFIG += staticlib testnetwork +CONFIG += staticlib \ + bitdht +CONFIG -= qt +TARGET = retroshare +CONFIG += test_voip + +# GXS Stuff. +CONFIG += newcache +CONFIG += newservices +#CONFIG += newcache +#CONFIG += newservices + +# Beware: All data of the stripped services are lost +DEFINES *= PQI_DISABLE_TUNNEL + +# ENABLE_CACHE_OPT +profiling { + QMAKE_CXXFLAGS -= -fomit-frame-pointer + QMAKE_CXXFLAGS *= -pg \ + -g \ + -fno-omit-frame-pointer +} +release: + +# UDP and TUNNEL dont work anymore. +# DEFINES *= PQI_DISABLE_UDP +# treat warnings as error for better removing +# QMAKE_CFLAGS += -Werror +# QMAKE_CXXFLAGS += -Werror +testnetwork { + # used in rsserver/rsinit.cc Enabled Port Restrictions, and makes Proxy Port next to Dht Port. + DEFINES *= LOCALNET_TESTING + + # used in tcponudp/udprelay.cc Debugging Info for Relays. + DEFINES *= DEBUG_UDP_RELAY + + # used in tcponudp/udpstunner.[h | cc] enables local stun (careful - modifies class variables). + DEFINES *= UDPSTUN_ALLOW_LOCALNET + + # used in pqi/p3linkmgr.cc prints out extra debug. + DEFINES *= LINKMGR_DEBUG_LINKTYPE + + # used in dht/connectstatebox to reduce connection times and display debug. + # DEFINES *= TESTING_PERIODS + # DEFINES *= DEBUG_CONNECTBOX + QMAKE_CXXFLAGS -= -fomit-frame-pointer + QMAKE_CXXFLAGS -= -O2 + QMAKE_CXXFLAGS *= -g \ + -fno-omit-frame-pointer +} +CONFIG += debug +debug { + # DEFINES *= DEBUG + # DEFINES *= OPENDHT_DEBUG DHT_DEBUG CONN_DEBUG DEBUG_UDP_SORTER P3DISC_DEBUG DEBUG_UDP_LAYER FT_DEBUG EXTADDRSEARCH_DEBUG + # DEFINES *= CONTROL_DEBUG FT_DEBUG DEBUG_FTCHUNK P3TURTLE_DEBUG + # DEFINES *= P3TURTLE_DEBUG + # DEFINES *= NET_DEBUG + # DEFINES *= DISTRIB_DEBUG + # DEFINES *= P3TURTLE_DEBUG FT_DEBUG DEBUG_FTCHUNK MPLEX_DEBUG + # DEFINES *= STATUS_DEBUG SERV_DEBUG RSSERIAL_DEBUG #CONN_DEBUG + QMAKE_CXXFLAGS -= -O2 \ + -fomit-frame-pointer + QMAKE_CXXFLAGS *= -g \ + -fno-omit-frame-pointer +} +bitdht { + HEADERS += dht/p3bitdht.h \ + dht/connectstatebox.h \ + dht/stunaddrassist.h + SOURCES += dht/p3bitdht.cc \ + dht/p3bitdht_interface.cc \ + dht/p3bitdht_peers.cc \ + dht/p3bitdht_peernet.cc \ + dht/p3bitdht_relay.cc \ + dht/connectstatebox.cc + HEADERS += tcponudp/udppeer.h \ + tcponudp/bio_tou.h \ + tcponudp/tcppacket.h \ + tcponudp/tcpstream.h \ + tcponudp/tou.h \ + tcponudp/udpstunner.h \ + tcponudp/udprelay.h + SOURCES += tcponudp/udppeer.cc \ + tcponudp/tcppacket.cc \ + tcponudp/tcpstream.cc \ + tcponudp/tou.cc \ + tcponudp/bss_tou.c \ + tcponudp/udpstunner.cc \ + tcponudp/udprelay.cc + + # These two aren't actually used (and don't compile) .... + # but could be useful later + # tcponudp/udpstunner.h \ + # tcponudp/udpstunner.cc \ + BITDHT_DIR = ../../libbitdht/src + INCLUDEPATH += . \ + $${BITDHT_DIR} + + # The next line if for compliance with debian packages. Keep it! + INCLUDEPATH += ../libbitdht + DEFINES *= RS_USE_BITDHT +} +test_bitdht { + # DISABLE TCP CONNECTIONS... + DEFINES *= P3CONNMGR_NO_TCP_CONNECTIONS + + # NO AUTO CONNECTIONS??? FOR TESTING DHT STATUS. + DEFINES *= P3CONNMGR_NO_AUTO_CONNECTION +} + +# ENABLED UDP NOW. +use_blogs { + HEADERS += services/p3blogs.h + SOURCES += services/p3blogs.cc + DEFINES *= RS_USE_BLOGS +} +PUBLIC_HEADERS = retroshare/rsblogs.h \ + retroshare/rschannels.h \ + retroshare/rsdisc.h \ + retroshare/rsdistrib.h \ + retroshare/rsexpr.h \ + retroshare/rsfiles.h \ + retroshare/rsforums.h \ + retroshare/rshistory.h \ + retroshare/rsiface.h \ + retroshare/rsinit.h \ + retroshare/rsplugin.h \ + retroshare/rsloginhandler.h \ + retroshare/rsmsgs.h \ + retroshare/rsnotify.h \ + retroshare/rspeers.h \ + retroshare/rsrank.h \ + retroshare/rsstatus.h \ + retroshare/rsturtle.h \ + retroshare/rstypes.h \ + retroshare/rsdht.h \ + retroshare/rsdsdv.h \ + retroshare/rsconfig.h \ + retroshare/rsphotoV2.h +HEADERS += plugins/pluginmanager.h \ + plugins/dlfcn_win32.h \ + serialiser/rspluginitems.h +HEADERS += $$PUBLIC_HEADERS + +# public headers to be... +HEADERS += retroshare/rsgame.h \ + retroshare/rsphoto.h + +# ################################ Linux ########################################## + linux-* { + QMAKE_CC = g++ + OBJECTS_DIR = temp/obj + MOC_DIR = temp/moc + DESTDIR = lib + + # miniupnp implementation files + #HEADERS += upnp/upnputil.h + #SOURCES += upnp/upnputil.c + + # zeroconf disabled at the end of libretroshare.pro (but need the code) + #CONFIG += zeroconf + #CONFIG += zcnatassist + + OPENPGPSDK_DIR = ../../openpgpsdk/src + INCLUDEPATH += $${OPENPGPSDK_DIR} + + INCLUDEPATH *= /usr/lib/x86_64-linux-gnu/glib-2.0/include/ + INCLUDEPATH *= /usr/lib/i386-linux-gnu/glib-2.0/include/ + INCLUDEPATH *= /usr/include/glib-2.0/ /usr/lib/glib-2.0/include + INCLUDEPATH *= /usr/local/include/glib-2.0 + + DEFINES *= UBUNTU + } + + # ################### Cross compilation for windows under Linux #################### + win32-x-g++ { + OBJECTS_DIR = temp/win32xgcc/obj + DESTDIR = lib.win32xgcc + DEFINES *= WINDOWS_SYS \ + WIN32 \ + WIN_CROSS_UBUNTU + QMAKE_CXXFLAGS *= -Wmissing-include-dirs + QMAKE_CC = i586-mingw32msvc-g++ + QMAKE_LIB = i586-mingw32msvc-ar + QMAKE_AR = i586-mingw32msvc-ar + DEFINES *= STATICLIB \ + WIN32 + + # miniupnp implementation files + HEADERS += upnp/upnputil.h + SOURCES += upnp/upnputil.c + SSL_DIR = ../../../../openssl + UPNPC_DIR = ../../../../miniupnpc-1.3 + GPG_ERROR_DIR = ../../../../libgpg-error-1.7 + GPGME_DIR = ../../../../gpgme-1.1.8 + INCLUDEPATH *= /usr/i586-mingw32msvc/include \ + ${HOME}/.wine/drive_c/pthreads/include/ + } + + # ################################ Windows ########################################## + win32 { + QMAKE_CC = g++ + OBJECTS_DIR = temp/obj + MOC_DIR = temp/moc + DEFINES *= WINDOWS_SYS \ + WIN32 \ + STATICLIB \ + MINGW + DEFINES *= MINIUPNPC_VERSION=13 + DESTDIR = lib + + # Switch on extra warnings + QMAKE_CFLAGS += -Wextra + QMAKE_CXXFLAGS += -Wextra + + # Switch off optimization for release version + QMAKE_CXXFLAGS_RELEASE -= -O2 + QMAKE_CXXFLAGS_RELEASE += -O0 + QMAKE_CFLAGS_RELEASE -= -O2 + QMAKE_CFLAGS_RELEASE += -O0 + + # Switch on optimization for debug version + # QMAKE_CXXFLAGS_DEBUG += -O2 + # QMAKE_CFLAGS_DEBUG += -O2 + DEFINES += USE_CMD_ARGS + + # miniupnp implementation files + HEADERS += upnp/upnputil.h + SOURCES += upnp/upnputil.c + UPNPC_DIR = ../../../lib/miniupnpc-1.3 + PTHREADS_DIR = ../../../lib/pthreads-w32-2-8-0-release + ZLIB_DIR = ../../../lib/zlib-1.2.3 + SSL_DIR = ../../../OpenSSL + OPENPGPSDK_DIR = ../../openpgpsdk/src + INCLUDEPATH += . \ + $${SSL_DIR}/include \ + $${UPNPC_DIR} \ + $${PTHREADS_DIR} \ + $${ZLIB_DIR} \ + $${OPENPGPSDK_DIR} + newcache { + SQLITE_DIR = ../../../../Libraries/sqlite/sqlite-autoconf-3070900 + INCLUDEPATH += . \ + $${SQLITE_DIR} + } + } + + # ################################ MacOSX ########################################## + mac { + QMAKE_CC = g++ + OBJECTS_DIR = temp/obj + MOC_DIR = temp/moc + + # DEFINES = WINDOWS_SYS WIN32 STATICLIB MINGW + # DEFINES *= MINIUPNPC_VERSION=13 + DESTDIR = lib + + # miniupnp implementation files + HEADERS += upnp/upnputil.h + SOURCES += upnp/upnputil.c + + # zeroconf disabled at the end of libretroshare.pro (but need the code) + CONFIG += zeroconf + CONFIG += zcnatassist + + # Beautiful Hack to fix 64bit file access. + QMAKE_CXXFLAGS *= -Dfseeko64=fseeko \ + -Dftello64=ftello \ + -Dfopen64=fopen \ + -Dvstatfs64=vstatfs + UPNPC_DIR = ../../../miniupnpc-1.0 + + # GPG_ERROR_DIR = ../../../../libgpg-error-1.7 + # GPGME_DIR = ../../../../gpgme-1.1.8 + OPENPGPSDK_DIR = ../../openpgpsdk/src + INCLUDEPATH += . \ + $${UPNPC_DIR} + INCLUDEPATH += $${OPENPGPSDK_DIR} + } + + # ../openpgpsdk + # INCLUDEPATH += . $${UPNPC_DIR} $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src + # ################################ FreeBSD ########################################## + freebsd-* { + INCLUDEPATH *= /usr/local/include/gpgme + INCLUDEPATH *= /usr/local/include/glib-2.0 + QMAKE_CXXFLAGS *= -Dfseeko64=fseeko \ + -Dftello64=ftello \ + -Dstat64=stat \ + -Dstatvfs64=statvfs \ + -Dfopen64=fopen + + # libupnp implementation files + HEADERS += upnp/UPnPBase.h + SOURCES += upnp/UPnPBase.cpp + DESTDIR = lib + } + + # ################################## COMMON stuff ################################## + HEADERS += dbase/cachestrapper.h \ + dbase/fimonitor.h \ + dbase/findex.h \ + dbase/fistore.h + + # HEADERS += dht/p3bitdht.h \ + HEADERS += ft/ftchunkmap.h \ + ft/ftcontroller.h \ + ft/ftdata.h \ + ft/ftdatamultiplex.h \ + ft/ftdbase.h \ + ft/ftextralist.h \ + ft/ftfilecreator.h \ + ft/ftfileprovider.h \ + ft/ftfilesearch.h \ + ft/ftsearch.h \ + ft/ftserver.h \ + ft/fttransfermodule.h + HEADERS += pqi/authssl.h \ + pqi/authgpg.h \ + pgp/pgphandler.h \ + pgp/pgpkeyutil.h \ + pqi/cleanupxpgp.h \ + pqi/p3cfgmgr.h \ + pqi/p3peermgr.h \ + pqi/p3linkmgr.h \ + pqi/p3netmgr.h \ + pqi/p3dhtmgr.h \ + pqi/p3notify.h \ + pqi/p3upnpmgr.h \ + pqi/pqiqos.h \ + pqi/pqi.h \ + pqi/pqi_base.h \ + pqi/pqiarchive.h \ + pqi/pqiassist.h \ + pqi/pqibin.h \ + pqi/pqihandler.h \ + pqi/pqihash.h \ + pqi/p3historymgr.h \ + pqi/pqiindic.h \ + pqi/pqiipset.h \ + pqi/pqilistener.h \ + pqi/pqiloopback.h \ + pqi/pqimonitor.h \ + pqi/pqinetwork.h \ + pqi/pqinotify.h \ + pqi/pqiperson.h \ + pqi/pqipersongrp.h \ + pqi/pqisecurity.h \ + pqi/pqiservice.h \ + pqi/pqissl.h \ + pqi/pqissllistener.h \ + pqi/pqisslpersongrp.h \ + pqi/pqissltunnel.h \ + pqi/pqissludp.h \ + pqi/pqistore.h \ + pqi/pqistreamer.h \ + pqi/pqiqosstreamer.h \ + pqi/sslfns.h \ + pqi/pqinetstatebox.h + HEADERS += rsserver/p3discovery.h \ + rsserver/p3face.h \ + rsserver/p3history.h \ + rsserver/p3msgs.h \ + rsserver/p3peers.h \ + rsserver/p3status.h \ + rsserver/p3serverconfig.h + HEADERS += serialiser/rsbaseitems.h \ + serialiser/rsbaseserial.h \ + serialiser/rsblogitems.h \ + serialiser/rschannelitems.h \ + serialiser/rsconfigitems.h \ + serialiser/rsdiscitems.h \ + serialiser/rsdistribitems.h \ + serialiser/rsforumitems.h \ + serialiser/rsgameitems.h \ + serialiser/rshistoryitems.h \ + serialiser/rsmsgitems.h \ + serialiser/rsserial.h \ + serialiser/rsserviceids.h \ + serialiser/rsserviceitems.h \ + serialiser/rsstatusitems.h \ + serialiser/rstlvaddrs.h \ + serialiser/rstlvbase.h \ + serialiser/rstlvkeys.h \ + serialiser/rstlvkvwide.h \ + serialiser/rstlvtypes.h \ + serialiser/rstlvutil.h \ + serialiser/rstlvdsdv.h \ + serialiser/rsdsdvitems.h \ + serialiser/rstlvbanlist.h \ + serialiser/rsbanlistitems.h \ + serialiser/rsbwctrlitems.h \ + serialiser/rstunnelitems.h + HEADERS += services/p3channels.h \ + services/p3chatservice.h \ + services/p3disc.h \ + services/p3forums.h \ + services/p3gamelauncher.h \ + services/p3gameservice.h \ + services/p3msgservice.h \ + services/p3service.h \ + services/p3statusservice.h \ + services/p3dsdv.h \ + services/p3banlist.h \ + services/p3bwctrl.h \ + services/p3tunnel.h + HEADERS += distrib/p3distrib.h \ + distrib/p3distribsecurity.h + + # services/p3blogs.h \ + HEADERS += turtle/p3turtle.h \ + turtle/rsturtleitem.h \ + turtle/turtletypes.h + HEADERS += upnp/upnphandler.h + HEADERS += util/folderiterator.h \ + util/rsdebug.h \ + util/smallobject.h \ + util/rsdir.h \ + util/rsdiscspace.h \ + util/rsnet.h \ + util/extaddrfinder.h \ + util/dnsresolver.h \ + util/rsprint.h \ + util/rsstring.h \ + util/rsthreads.h \ + util/rsversion.h \ + util/rswin.h \ + util/rsrandom.h \ + util/radix64.h \ + util/pugiconfig.h + SOURCES += dbase/cachestrapper.cc \ + dbase/fimonitor.cc \ + dbase/findex.cc \ + dbase/fistore.cc \ + dbase/rsexpr.cc + SOURCES += ft/ftchunkmap.cc \ + ft/ftcontroller.cc \ + ft/ftdata.cc \ + ft/ftdatamultiplex.cc \ + ft/ftdbase.cc \ + ft/ftextralist.cc \ + ft/ftfilecreator.cc \ + ft/ftfileprovider.cc \ + ft/ftfilesearch.cc \ + ft/ftserver.cc \ + ft/fttransfermodule.cc + SOURCES += pqi/authgpg.cc \ + pqi/authssl.cc \ + pgp/pgphandler.cc \ + pgp/pgpkeyutil.cc \ + pqi/cleanupxpgp.cc \ + pqi/p3cfgmgr.cc \ + pqi/p3peermgr.cc \ + pqi/p3linkmgr.cc \ + pqi/p3netmgr.cc \ + pqi/p3dhtmgr.cc \ + pqi/p3notify.cc \ + pqi/pqiqos.cc \ + pqi/pqiarchive.cc \ + pqi/pqibin.cc \ + pqi/pqihandler.cc \ + pqi/p3historymgr.cc \ + pqi/pqiipset.cc \ + pqi/pqiloopback.cc \ + pqi/pqimonitor.cc \ + pqi/pqinetwork.cc \ + pqi/pqiperson.cc \ + pqi/pqipersongrp.cc \ + pqi/pqisecurity.cc \ + pqi/pqiservice.cc \ + pqi/pqissl.cc \ + pqi/pqissllistener.cc \ + pqi/pqisslpersongrp.cc \ + pqi/pqissltunnel.cc \ + pqi/pqissludp.cc \ + pqi/pqistore.cc \ + pqi/pqistreamer.cc \ + pqi/pqiqosstreamer.cc \ + pqi/sslfns.cc \ + pqi/pqinetstatebox.cc + SOURCES += rsserver/p3discovery.cc \ + rsserver/p3face-config.cc \ + rsserver/p3face-msgs.cc \ + rsserver/p3face-server.cc \ + rsserver/p3history.cc \ + rsserver/p3msgs.cc \ + rsserver/p3peers.cc \ + rsserver/p3status.cc \ + rsserver/rsiface.cc \ + rsserver/rsinit.cc \ + rsserver/rsloginhandler.cc \ + rsserver/rstypes.cc \ + rsserver/p3serverconfig.cc + SOURCES += plugins/pluginmanager.cc \ + plugins/dlfcn_win32.cc \ + serialiser/rspluginitems.cc + SOURCES += serialiser/rsbaseitems.cc \ + serialiser/rsbaseserial.cc \ + serialiser/rsblogitems.cc \ + serialiser/rschannelitems.cc \ + serialiser/rsconfigitems.cc \ + serialiser/rsdiscitems.cc \ + serialiser/rsdistribitems.cc \ + serialiser/rsforumitems.cc \ + serialiser/rsgameitems.cc \ + serialiser/rshistoryitems.cc \ + serialiser/rsmsgitems.cc \ + serialiser/rsserial.cc \ + serialiser/rsstatusitems.cc \ + serialiser/rstlvaddrs.cc \ + serialiser/rstlvbase.cc \ + serialiser/rstlvfileitem.cc \ + serialiser/rstlvimage.cc \ + serialiser/rstlvkeys.cc \ + serialiser/rstlvkvwide.cc \ + serialiser/rstlvtypes.cc \ + serialiser/rstlvutil.cc \ + serialiser/rstlvdsdv.cc \ + serialiser/rsdsdvitems.cc \ + serialiser/rstlvbanlist.cc \ + serialiser/rsbanlistitems.cc \ + serialiser/rsbwctrlitems.cc \ + serialiser/rstunnelitems.cc + SOURCES += services/p3channels.cc \ + services/p3chatservice.cc \ + services/p3disc.cc \ + services/p3forums.cc \ + services/p3gamelauncher.cc \ + services/p3msgservice.cc \ + services/p3service.cc \ + services/p3statusservice.cc \ + services/p3dsdv.cc \ + services/p3banlist.cc \ + services/p3bwctrl.cc + + # removed because getPeer() doesn t exist services/p3tunnel.cc + SOURCES += distrib/p3distrib.cc \ + distrib/p3distribsecurity.cc + SOURCES += turtle/p3turtle.cc \ + turtle/rsturtleitem.cc + + # turtle/turtlerouting.cc \ + # turtle/turtlesearch.cc \ + # turtle/turtletunnels.cc + SOURCES += upnp/upnphandler.cc + SOURCES += util/folderiterator.cc \ + util/rsdebug.cc \ + util/smallobject.cc \ + util/rsdir.cc \ + util/rsdiscspace.cc \ + util/rsnet.cc \ + util/extaddrfinder.cc \ + util/dnsresolver.cc \ + util/rsprint.cc \ + util/rsstring.cc \ + util/rsthreads.cc \ + util/rsversion.cc \ + util/rswin.cc \ + util/rsrandom.cc + zeroconf { + HEADERS += zeroconf/p3zeroconf.h + SOURCES += zeroconf/p3zeroconf.cc + } + + # Disable Zeroconf (we still need the code for zcnatassist + # DEFINES *= RS_ENABLE_ZEROCONF + # This is seperated from the above for windows/linux platforms. + # It is acceptable to build in zeroconf and have it not work, + # but unacceptable to rely on Apple's libraries for Upnp when we have alternatives. ' + zcnatassist { + HEADERS += zeroconf/p3zcnatassist.h + SOURCES += zeroconf/p3zcnatassist.cc + DEFINES *= RS_ENABLE_ZCNATASSIST + } + + # new gxs cache system + newcache { + HEADERS += serialiser/rsnxsitems.h \ + gxs/rsgds.h \ + gxs/rsgxs.h \ + gxs/rsdataservice.h \ + gxs/rsgxsnetservice.h \ + gxs/rsgxsflags.h \ + gxs/rsgenexchange.h \ + gxs/rsnxsobserver.h \ + gxs/rsgxsdata.h \ + gxs/rstokenservice.h \ + gxs/rsgxsdataaccess.h \ + retroshare/rsgxsservice.h \ + serialiser/rsgxsitems.h \ + serialiser/rsphotov2items.h \ + util/retrodb.h \ + util/contentvalue.h \ + gxs/gxscoreserver.h \ + gxs/gxssecurity.h \ + gxs/gxssecurity.h \ + gxs/rsgxsifaceimpl.h \ + services/p3posted.h \ + retroshare/rsposted.h + + SOURCES += serialiser/rsnxsitems.cc \ + gxs/rsdataservice.cc \ + gxs/rsgenexchange.cc \ + gxs/rsgxsnetservice.cc \ + gxs/rsgxsdata.cc \ + serialiser/rsgxsitems.cc \ + services/p3photoserviceV2.cc \ + gxs/rsgxsdataaccess.cc \ + serialiser/rsphotov2items.cc \ + util/retrodb.cc \ + util/contentvalue.cc \ + gxs/gxscoreserver.cc \ + gxs/gxssecurity.cc \ + gxs/gxssecurity.cc \ + gxs/rsgxsifaceimpl.cc \ + services/p3posted.cc + } + + newservices { + HEADERS += services/p3photoserviceV2.h \ + retroshare/rsphotoVEG.h \ + services/p3gxsserviceVEG.h \ + retroshare/rsidentityVEG.h \ + services/p3wikiserviceVEG.h \ + retroshare/rswikiVEG.h \ + retroshare/rswireVEG.h \ + services/p3wireVEG.h \ + services/p3idserviceVEG.h \ + retroshare/rsforumsVEG.h \ + services/p3forumsVEG.h \ + retroshare/rspostedVEG.h \ + services/p3postedVEG.h + + # Do I need this? + #serialiser/rsphotoitemsVEG.h \ + + SOURCES += services/p3gxsserviceVEG.cc \ + services/p3wikiserviceVEG.cc \ + services/p3wireVEG.cc \ + services/p3idserviceVEG.cc \ + services/p3forumsVEG.cc \ + services/p3postedVEG.cc + + # Do I need this? + # serialiser/rsphotoitemsVEG.cc \ + } + + + diff --git a/libretroshare/src/retroshare/rsphotoV2.h b/libretroshare/src/retroshare/rsphotoV2.h index f42bd1452..f678105d1 100644 --- a/libretroshare/src/retroshare/rsphotoV2.h +++ b/libretroshare/src/retroshare/rsphotoV2.h @@ -169,7 +169,6 @@ std::ostream &operator<<(std::ostream &out, const RsPhotoAlbum &album); typedef std::map > PhotoResult; typedef std::map > PhotoCommentResult; -typedef std::map > MsgMetaResult; class RsPhotoV2 { @@ -209,7 +208,7 @@ public: * needed to make requests to the service * @return handle to token service for this gxs service */ - virtual RsTokenServiceV2* getTokenService() = 0; + virtual RsTokenService* getTokenService() = 0; /* Generic Lists */ diff --git a/libretroshare/src/retroshare/rsposted.h b/libretroshare/src/retroshare/rsposted.h new file mode 100644 index 000000000..c2ea5091e --- /dev/null +++ b/libretroshare/src/retroshare/rsposted.h @@ -0,0 +1,155 @@ +#ifndef RSPOSTED_H +#define RSPOSTED_H + + +/* + * libretroshare/src/retroshare: rsposted.h + * + * RetroShare C++ Interface. + * + * Copyright 2008-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include +#include +#include +#include "gxs/rstokenservice.h" +#include "gxs/rsgxsifaceimpl.h" + +/* The Main Interface Class - for information about your Peers */ +class RsPostedVEG; +extern RsPostedVEG *rsPostedVEG; + + +class RsPostedGroup +{ + public: + RsGroupMetaData mMeta; + RsPostedGroup() { return; } +}; + +class RsPostedMsg +{ + public: + RsPostedMsg(uint32_t t) + :postedType(t) { return; } + + RsMsgMetaData mMeta; + uint32_t postedType; +}; + +#define RSPOSTED_MSGTYPE_POST 0x0001 +#define RSPOSTED_MSGTYPE_VOTE 0x0002 +#define RSPOSTED_MSGTYPE_COMMENT 0x0004 + +#define RSPOSTED_PERIOD_YEAR 1 +#define RSPOSTED_PERIOD_MONTH 2 +#define RSPOSTED_PERIOD_WEEK 3 +#define RSPOSTED_PERIOD_DAY 4 +#define RSPOSTED_PERIOD_HOUR 5 + +#define RSPOSTED_VIEWMODE_LATEST 1 +#define RSPOSTED_VIEWMODE_TOP 2 +#define RSPOSTED_VIEWMODE_HOT 3 +#define RSPOSTED_VIEWMODE_COMMENTS 4 + + +class RsPostedPost: public RsPostedMsg +{ + public: + RsPostedPost(): RsPostedMsg(RSPOSTED_MSGTYPE_POST) + { + mMeta.mMsgFlags = RSPOSTED_MSGTYPE_POST; + return; + } + + std::string mLink; + std::string mNotes; +}; + + +class RsPostedVote: public RsPostedMsg +{ + public: + RsPostedVote(): RsPostedMsg(RSPOSTED_MSGTYPE_VOTE) + { + mMeta.mMsgFlags = RSPOSTED_MSGTYPE_VOTE; + return; + } +}; + + +class RsPostedComment: public RsPostedMsg +{ + public: + RsPostedComment(): RsPostedMsg(RSPOSTED_MSGTYPE_COMMENT) + { + mMeta.mMsgFlags = RSPOSTED_MSGTYPE_COMMENT; + return; + } + + std::string mComment; +}; + + +std::ostream &operator<<(std::ostream &out, const RsPostedGroup &group); +std::ostream &operator<<(std::ostream &out, const RsPostedPost &post); +std::ostream &operator<<(std::ostream &out, const RsPostedVote &vote); +std::ostream &operator<<(std::ostream &out, const RsPostedComment &comment); + + +class RsPosted : public RsGxsIfaceImpl +{ + public: + + RsPosted(RsGenExchange* gxs) : RsGxsIfaceImpl(gxs) { return; } +virtual ~RsPosted() { return; } + + /* Specific Service Data */ + +virtual RsTokenService* getToken() = 0; +virtual bool getGroup(const uint32_t &token, RsPostedGroup &group) = 0; +virtual bool getPost(const uint32_t &token, RsPostedPost &post) = 0; +virtual bool getComment(const uint32_t &token, RsPostedComment &comment) = 0; + +virtual bool submitGroup(uint32_t &token, RsPostedGroup &group) = 0; +virtual bool submitPost(uint32_t &token, RsPostedPost &post) = 0; +virtual bool submitVote(uint32_t &token, RsPostedVote &vote) = 0; +virtual bool submitComment(uint32_t &token, RsPostedComment &comment) = 0; + + // Special Ranking Request. +virtual bool requestRanking(uint32_t &token, RsGxsGroupId groupId) = 0; +virtual bool getRankedPost(const uint32_t &token, RsPostedPost &post) = 0; + +virtual bool extractPostedCache() = 0; + + + // Control Ranking Calculations. +virtual bool setViewMode(uint32_t mode) = 0; +virtual bool setViewPeriod(uint32_t period) = 0; +virtual bool setViewRange(uint32_t first, uint32_t count) = 0; + + // exposed for testing... +virtual float calcPostScore(uint32_t& token, const RsGxsMessageId) = 0; + +}; + + +#endif // RSPOSTED_H diff --git a/libretroshare/src/services/p3photoserviceV2.cc b/libretroshare/src/services/p3photoserviceV2.cc index 58c3072a9..92d7fa2a1 100644 --- a/libretroshare/src/services/p3photoserviceV2.cc +++ b/libretroshare/src/services/p3photoserviceV2.cc @@ -140,7 +140,7 @@ void p3PhotoServiceV2::msgsChanged( } -RsTokenServiceV2* p3PhotoServiceV2::getTokenService() { +RsTokenService* p3PhotoServiceV2::getTokenService() { return RsGenExchange::getTokenService(); } diff --git a/libretroshare/src/services/p3photoserviceV2.h b/libretroshare/src/services/p3photoserviceV2.h index 631de1c05..a4083a714 100644 --- a/libretroshare/src/services/p3photoserviceV2.h +++ b/libretroshare/src/services/p3photoserviceV2.h @@ -56,7 +56,7 @@ public: void msgsChanged(std::map >& msgs); - RsTokenServiceV2* getTokenService(); + RsTokenService* getTokenService(); bool getGroupList(const uint32_t &token, std::list &groupIds); diff --git a/libretroshare/src/services/p3posted.cc b/libretroshare/src/services/p3posted.cc new file mode 100644 index 000000000..45e13f5fc --- /dev/null +++ b/libretroshare/src/services/p3posted.cc @@ -0,0 +1,86 @@ +#include "p3posted.h" + +p3Posted::p3Posted(RsGeneralDataService *gds, RsNetworkExchangeService *nes) + : RsGenExchange(gds, nes, NULL, RS_SERVICE_GXSV1_TYPE_POSTED), RsPosted(this) +{ +} + +void p3Posted::notifyChanges(std::vector &changes) +{ + + +} + +bool p3Posted::getGroup(const uint32_t &token, RsPostedGroup &group) +{ + +} + +bool p3Posted::getPost(const uint32_t &token, RsPostedPost &post) +{ + +} + +bool p3Posted::getComment(const uint32_t &token, RsPostedComment &comment) +{ + +} + +bool p3Posted::submitGroup(uint32_t &token, RsPostedGroup &group) +{ + +} + +bool p3Posted::submitPost(uint32_t &token, RsPostedPost &post) +{ + +} + +bool p3Posted::submitVote(uint32_t &token, RsPostedVote &vote) +{ + +} + +bool p3Posted::submitComment(uint32_t &token, RsPostedComment &comment) +{ + +} + + // Special Ranking Request. +bool p3Posted::requestRanking(uint32_t &token, RsGxsGroupId groupId) +{ + +} + +bool p3Posted::getRankedPost(const uint32_t &token, RsPostedPost &post) +{ + +} + +bool p3Posted::extractPostedCache() +{ + +} + + + // Control Ranking Calculations. +bool p3Posted::setViewMode(uint32_t mode) +{ + +} + +bool p3Posted::setViewPeriod(uint32_t period) +{ + +} + +bool p3Posted::setViewRange(uint32_t first, uint32_t count) +{ + +} + + // exposed for testing... +float p3Posted::calcPostScore(uint32_t& token, const RsGxsMessageId) +{ + +} diff --git a/libretroshare/src/services/p3posted.h b/libretroshare/src/services/p3posted.h new file mode 100644 index 000000000..6dae736db --- /dev/null +++ b/libretroshare/src/services/p3posted.h @@ -0,0 +1,52 @@ +#ifndef P3POSTED_H +#define P3POSTED_H + +#include "retroshare/rsposted.h" +#include "gxs/rsgenexchange.h" + +class p3Posted : public RsGenExchange, public RsPosted +{ +public: + p3Posted(RsGeneralDataService* gds, RsNetworkExchangeService* nes); + +protected: + + /*! + * This confirms this class as an abstract one that \n + * should not be instantiated \n + * The deriving class should implement this function \n + * as it is called by the backend GXS system to \n + * update client of changes which should \n + * instigate client to retrieve new content from the system + * @param changes the changes that have occured to data held by this service + */ + void notifyChanges(std::vector& changes) ; + +public: + + bool getGroup(const uint32_t &token, RsPostedGroup &group); + bool getPost(const uint32_t &token, RsPostedPost &post) ; + bool getComment(const uint32_t &token, RsPostedComment &comment) ; + + bool submitGroup(uint32_t &token, RsPostedGroup &group); + bool submitPost(uint32_t &token, RsPostedPost &post); + bool submitVote(uint32_t &token, RsPostedVote &vote); + bool submitComment(uint32_t &token, RsPostedComment &comment) ; + + // Special Ranking Request. + bool requestRanking(uint32_t &token, RsGxsGroupId groupId) ; + bool getRankedPost(const uint32_t &token, RsPostedPost &post) ; + + bool extractPostedCache() ; + + + // Control Ranking Calculations. + bool setViewMode(uint32_t mode); + bool setViewPeriod(uint32_t period); + bool setViewRange(uint32_t first, uint32_t count); + + // exposed for testing... + float calcPostScore(uint32_t& token, const RsGxsMessageId); +}; + +#endif // P3POSTED_H diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index 9966bd7ef..eafe0c3d0 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -6,9 +6,9 @@ CONFIG += photoshare #CONFIG += thewire #CONFIG += identities #CONFIG += forumsv2 -#CONFIG += posted +CONFIG += posted CONFIG += unfinished -#CONFIG += gxsgui +CONFIG += gxsgui #CONFIG += pluginmgr @@ -940,14 +940,14 @@ thewire { identities { - HEADERS += util/TokenQueueVEG.h \ + HEADERS += \ gui/Identity/IdDialog.h \ gui/Identity/IdEditDialog.h \ FORMS += gui/Identity/IdDialog.ui \ gui/Identity/IdEditDialog.ui \ - SOURCES += util/TokenQueueVEG.cpp \ + SOURCES += \ gui/Identity/IdDialog.cpp \ gui/Identity/IdEditDialog.cpp \ @@ -983,6 +983,7 @@ posted { gui/Posted/PostedListDialog.h \ gui/Posted/PostedItem.h \ gui/Posted/PostedComments.h \ + util/TokenQueueVEG.h FORMS += gui/Posted/PostedDialog.ui \ gui/Posted/PostedListDialog.ui \ @@ -993,27 +994,31 @@ posted { gui/Posted/PostedListDialog.cpp \ gui/Posted/PostedItem.cpp \ gui/Posted/PostedComments.cpp \ + util/TokenQueueVEG.cpp } gxsgui { HEADERS += gui/gxs/GxsGroupDialog.h \ - gui/gxs/ForumV2GroupDialog.h \ - gui/gxs/WikiGroupDialog.h \ gui/gxs/PostedGroupDialog.h \ - gui/gxs/GxsCommentTreeWidget.h \ + gui/gxs/GxsCommentTreeWidget.h + # gui/gxs/ForumV2GroupDialog.h \ + # gui/gxs/WikiGroupDialog.h \ + # gui/gxs/GxsMsgDialog.h \ FORMS += gui/gxs/GxsGroupDialog.ui \ # gui/gxs/GxsMsgDialog.ui \ # gui/gxs/GxsCommentTreeWidget.ui \ - SOURCES += gui/gxs/GxsGroupDialog.cpp \ - gui/gxs/ForumV2GroupDialog.cpp \ - gui/gxs/WikiGroupDialog.cpp \ + SOURCES += gui/gxs/GxsGroupDialog.cpp \ gui/gxs/PostedGroupDialog.cpp \ - gui/gxs/GxsCommentTreeWidget.cpp \ + gui/gxs/GxsCommentTreeWidget.cpp + #gui/gxs/ForumV2GroupDialog.cpp \ +# gui/gxs/WikiGroupDialog.cpp \ +# + # gui/gxs/GxsMsgDialog.cpp \ diff --git a/retroshare-gui/src/gui/Posted/PostedComments.cpp b/retroshare-gui/src/gui/Posted/PostedComments.cpp index 00328335a..cbdd91fed 100644 --- a/retroshare-gui/src/gui/Posted/PostedComments.cpp +++ b/retroshare-gui/src/gui/Posted/PostedComments.cpp @@ -24,7 +24,7 @@ #include "PostedComments.h" //#include -#include +#include #include #include @@ -83,7 +83,7 @@ PostedComments::PostedComments(QWidget *parent) /* setup TokenQueue */ //mPhotoQueue = new TokenQueue(rsPhoto, this); - ui.treeWidget->setup(rsPosted); + ui.treeWidget->setup(rsPostedVEG); } @@ -573,7 +573,7 @@ void PhotoDialog::loadPhotoData(const uint32_t &token) /********************************/ -void PhotoDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) +void PhotoDialog::loadRequest(const TokenQueue *queue, const TokenRequestVEG &req) { std::cerr << "PhotoDialog::loadRequest()"; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/Posted/PostedComments.h b/retroshare-gui/src/gui/Posted/PostedComments.h index 9da5a8447..29569cc28 100644 --- a/retroshare-gui/src/gui/Posted/PostedComments.h +++ b/retroshare-gui/src/gui/Posted/PostedComments.h @@ -27,16 +27,16 @@ //#include "gui/mainpage.h" #include "ui_PostedComments.h" -#include +#include #include //#include "gui/Posted/PostedItem.h" //#include "gui/PhotoShare/PhotoAddDialog.h" //#include "gui/PhotoShare/PhotoSlideShow.h" -#include "util/TokenQueue.h" +#include "util/TokenQueueVEG.h" -class PostedComments: public QWidget, public TokenResponse +class PostedComments: public QWidget, public TokenResponseVEG { Q_OBJECT @@ -47,7 +47,7 @@ public slots: void loadComments( std::string ); private: - void loadRequest(const TokenQueue *queue, const TokenRequest &req) { return; } + void loadRequest(const TokenQueueVEG *queue, const TokenRequestVEG &req) { return; } #if 0 virtual void deletePhotoItem(PhotoItem *, uint32_t type); @@ -112,7 +112,7 @@ private: #endif - TokenQueue *mPhotoQueue; + TokenQueueVEG *mPhotoQueue; /* UI - from Designer */ Ui::PostedComments ui; diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.cpp b/retroshare-gui/src/gui/Posted/PostedDialog.cpp index 38d92a186..fcf93a908 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedDialog.cpp @@ -26,7 +26,7 @@ #include "PostedListDialog.h" #include "PostedComments.h" -#include +#include #include #include diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.h b/retroshare-gui/src/gui/Posted/PostedDialog.h index 823d44850..954d3ae0a 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedDialog.h @@ -27,7 +27,7 @@ #include "retroshare-gui/mainpage.h" #include "ui_PostedDialog.h" -#include +#include #include diff --git a/retroshare-gui/src/gui/Posted/PostedItem.cpp b/retroshare-gui/src/gui/Posted/PostedItem.cpp index 92c7717dc..80955432c 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.cpp +++ b/retroshare-gui/src/gui/Posted/PostedItem.cpp @@ -30,7 +30,7 @@ #include "PostedItem.h" -#include +#include #include #include @@ -53,7 +53,7 @@ PostedItem::PostedItem(PostedHolder *parent, const RsPostedPost &post) //scoreLabel->setText(QString("1140")); // exposed for testing... - float score = rsPosted->calcPostScore(post.mMeta); + float score = rsPostedVEG->calcPostScore(post.mMeta); time_t now = time(NULL); QString fromLabelTxt = QString(" Age: ") + QString::number(now - post.mMeta.mPublishTs); @@ -62,7 +62,7 @@ PostedItem::PostedItem(PostedHolder *parent, const RsPostedPost &post) uint32_t votes = 0; uint32_t comments = 0; - rsPosted->extractPostedCache(post.mMeta.mServiceString, votes, comments); + rsPostedVEG->extractPostedCache(post.mMeta.mServiceString, votes, comments); scoreLabel->setText(QString::number(votes)); QString commentLabel = QString("Comments: ") + QString::number(comments); commentLabel += QString(" Votes: ") + QString::number(votes); diff --git a/retroshare-gui/src/gui/Posted/PostedItem.h b/retroshare-gui/src/gui/Posted/PostedItem.h index b13925802..79690548a 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.h +++ b/retroshare-gui/src/gui/Posted/PostedItem.h @@ -26,7 +26,7 @@ #include "ui_PostedItem.h" -#include +#include class RsPostedPost; class PostedItem; diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp index 0c926be1e..b174f7e64 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp @@ -26,7 +26,7 @@ #include "gui/gxs/PostedGroupDialog.h" //#include -#include +#include #include #include @@ -69,7 +69,7 @@ PostedListDialog::PostedListDialog(QWidget *parent) ui.setupUi(this); /* Setup Queue */ - mPostedQueue = new TokenQueue(rsPosted, this); + mPostedQueue = new TokenQueueVEG(rsPostedVEG, this); connect( ui.groupTreeWidget, SIGNAL( treeCustomContextMenuRequested( QPoint ) ), this, SLOT( groupListCustomPopupMenu( QPoint ) ) ); @@ -157,12 +157,12 @@ void PostedListDialog::updateDisplay() { std::list groupIds; std::list::iterator it; - if (!rsPosted) + if (!rsPostedVEG) return; // TODO groupsChanged... HACK XXX. #if 0 - if ((rsPosted->groupsChanged(groupIds)) || (rsPosted->updated())) + if ((rsPostedVEG->groupsChanged(groupIds)) || (rsPostedVEG->updated())) { /* update Forums List */ insertGroups(); @@ -176,7 +176,7 @@ void PostedListDialog::updateDisplay() } #endif - if (rsPosted->updated()) + if (rsPostedVEG->updated()) { /* update Forums List */ insertGroups(); @@ -235,47 +235,47 @@ void PostedListDialog::sortButtonClicked( QAbstractButton *button ) std::cerr << "PostedListDialog::sortButtonClicked( From Button Group! )"; std::cerr << std::endl; - uint32_t sortMode = RSPOSTED_VIEWMODE_HOT; + uint32_t sortMode = RSPOSTED_VIEWMODE_HOT; if (button == ui.hotSortButton) { - sortMode = RSPOSTED_VIEWMODE_HOT; + sortMode = RSPOSTED_VIEWMODE_HOT; } else if (button == ui.newSortButton) { - sortMode = RSPOSTED_VIEWMODE_LATEST; + sortMode = RSPOSTED_VIEWMODE_LATEST; } else if (button == ui.topSortButton) { - sortMode = RSPOSTED_VIEWMODE_TOP; + sortMode = RSPOSTED_VIEWMODE_TOP; } - rsPosted->setViewMode(sortMode); + rsPostedVEG->setViewMode(sortMode); } void PostedListDialog::periodChanged( int index ) { - uint32_t periodMode = RSPOSTED_PERIOD_HOUR; + uint32_t periodMode = RSPOSTED_PERIOD_HOUR; switch (index) { case 0: - periodMode = RSPOSTED_PERIOD_HOUR; + periodMode = RSPOSTED_PERIOD_HOUR; break; case 1: - periodMode = RSPOSTED_PERIOD_DAY; + periodMode = RSPOSTED_PERIOD_DAY; break; default: case 2: - periodMode = RSPOSTED_PERIOD_WEEK; + periodMode = RSPOSTED_PERIOD_WEEK; break; case 3: - periodMode = RSPOSTED_PERIOD_MONTH; + periodMode = RSPOSTED_PERIOD_MONTH; break; case 4: - periodMode = RSPOSTED_PERIOD_YEAR; + periodMode = RSPOSTED_PERIOD_YEAR; break; } - rsPosted->setViewPeriod(periodMode); + rsPostedVEG->setViewPeriod(periodMode); } @@ -342,7 +342,7 @@ void PostedListDialog::requestGroupSummary() std::cerr << std::endl; std::list ids; - RsTokReqOptions opts; + RsTokReqOptionsVEG opts; uint32_t token; mPostedQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, ids, POSTEDDIALOG_LISTING); } @@ -353,7 +353,7 @@ void PostedListDialog::loadGroupSummary(const uint32_t &token) std::cerr << std::endl; std::list groupInfo; - rsPosted->getGroupSummary(token, groupInfo); + rsPostedVEG->getGroupSummary(token, groupInfo); if (groupInfo.size() > 0) { @@ -373,7 +373,7 @@ void PostedListDialog::loadGroupSummary(const uint32_t &token) void PostedListDialog::requestGroupSummary_CurrentForum(const std::string &forumId) { - RsTokReqOptions opts; + RsTokReqOptionsVEG opts; std::list grpIds; grpIds.push_back(forumId); @@ -391,7 +391,7 @@ void PostedListDialog::loadGroupSummary_CurrentForum(const uint32_t &token) std::cerr << std::endl; std::list groupInfo; - rsPosted->getGroupSummary(token, groupInfo); + rsPostedVEG->getGroupSummary(token, groupInfo); if (groupInfo.size() == 1) { @@ -452,7 +452,7 @@ void PostedListDialog::loadCurrentForumThreads(const std::string &forumId) void PostedListDialog::requestGroupThreadData_InsertThreads(const std::string &groupId) { - RsTokReqOptions opts; + RsTokReqOptionsVEG opts; opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; @@ -466,7 +466,7 @@ void PostedListDialog::requestGroupThreadData_InsertThreads(const std::string &g //mPostedQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, POSTEDDIALOG_INSERTTHREADS); // Do specific Posted Request.... - if (rsPosted->requestRanking(token, groupId)) + if (rsPostedVEG->requestRanking(token, groupId)) { // get the Queue to handle response. mPostedQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_DATA, POSTEDDIALOG_INSERTTHREADS); @@ -482,11 +482,11 @@ void PostedListDialog::loadGroupThreadData_InsertThreads(const uint32_t &token) bool moreData = true; while(moreData) { - RsPostedPost post; + RsPostedPost post; // Old Format. - //if (rsPosted->getPost(token, post)) + //if (rsPostedVEG->getPost(token, post)) - if (rsPosted->getRankedPost(token, post)) + if (rsPostedVEG->getRankedPost(token, post)) { std::cerr << "PostedListDialog::loadGroupThreadData_InsertThreads() MsgId: " << post.mMeta.mMsgId; std::cerr << std::endl; @@ -559,7 +559,7 @@ void PostedListDialog::clearPosts() /*********************** **** **** **** ***********************/ /*********************** **** **** **** ***********************/ -void PostedListDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) +void PostedListDialog::loadRequest(const TokenQueueVEG *queue, const TokenRequestVEG &req) { std::cerr << "PostedListDialog::loadRequest() UserType: " << req.mUserType; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.h b/retroshare-gui/src/gui/Posted/PostedListDialog.h index 14dd7c2ca..ab8b6183e 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.h @@ -27,18 +27,18 @@ #include "retroshare-gui/mainpage.h" #include "ui_PostedListDialog.h" -#include +#include #include #include "gui/Posted/PostedItem.h" #include "gui/common/GroupTreeWidget.h" -#include "util/TokenQueue.h" +#include "util/TokenQueueVEG.h" #include "retroshare-gui/RsAutoUpdatePage.h" -class PostedListDialog : public RsAutoUpdatePage, public PostedHolder, public TokenResponse +class PostedListDialog : public RsAutoUpdatePage, public PostedHolder, public TokenResponseVEG { Q_OBJECT @@ -90,7 +90,7 @@ void loadGroupThreadData_InsertThreads(const uint32_t &token); void insertGroupData(const std::list &groupList); void groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo &groupItemInfo); - void loadRequest(const TokenQueue *queue, const TokenRequest &req); + void loadRequest(const TokenQueueVEG *queue, const TokenRequestVEG &req); QTreeWidgetItem *yourTopics; @@ -103,7 +103,7 @@ void groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo & bool mThreadLoading; std::string mCurrTopicId; - TokenQueue *mPostedQueue; + TokenQueueVEG *mPostedQueue; /* UI - from Designer */ Ui::PostedListDialog ui; diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp index e1ea83ec4..792af91d9 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp @@ -36,7 +36,7 @@ #define GXSCOMMENTS_LOADTHREAD 1 // Temporarily make this specific. -#include "retroshare/rsposted.h" +#include "retroshare/rspostedVEG.h" GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent) @@ -46,10 +46,10 @@ GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent) return; } -void GxsCommentTreeWidget::setup(RsTokenService *service) +void GxsCommentTreeWidget::setup(RsTokenServiceVEG *service) { mRsService = service; - mTokenQueue = new TokenQueue(service, this); + mTokenQueue = new TokenQueueVEG(service, this); return; } @@ -72,7 +72,7 @@ void GxsCommentTreeWidget::service_requestComments(std::string threadId) std::cerr << "GxsCommentTreeWidget::service_requestComments(" << threadId << ")"; std::cerr << std::endl; - RsTokReqOptions opts; + RsTokReqOptionsVEG opts; opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; opts.mFlagsFilter = RSPOSTED_MSGTYPE_COMMENT; @@ -212,7 +212,7 @@ void GxsCommentTreeWidget::service_loadThread(const uint32_t &token) std::cerr << std::endl; RsPostedComment comment; - while(rsPosted->getComment(token, comment)) + while(rsPostedVEG->getComment(token, comment)) { /* convert to a QTreeWidgetItem */ std::cerr << "GxsCommentTreeWidget::service_loadThread() Got Comment: " << comment; @@ -286,7 +286,7 @@ QTreeWidgetItem *GxsCommentTreeWidget::service_createMissingItem(std::string par } -void GxsCommentTreeWidget::loadRequest(const TokenQueue *queue, const TokenRequest &req) +void GxsCommentTreeWidget::loadRequest(const TokenQueueVEG *queue, const TokenRequestVEG &req) { std::cerr << "GxsCommentTreeWidget::loadRequest() UserType: " << req.mUserType; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h index 41850b9ba..76b49b4e8 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h @@ -24,7 +24,7 @@ #include -#include "util/TokenQueue.h" +#include "util/TokenQueueVEG.h" /* indicies for search results item columns SR_ = Search Result */ #define SR_NAME_COL 0 @@ -39,17 +39,17 @@ #define SR_ROLE_LOCAL Qt::UserRole -class GxsCommentTreeWidget : public QTreeWidget, public TokenResponse +class GxsCommentTreeWidget : public QTreeWidget, public TokenResponseVEG { Q_OBJECT public: GxsCommentTreeWidget(QWidget *parent = 0); - void setup(RsTokenService *service); + void setup(RsTokenServiceVEG *service); void requestComments(std::string threadId); - void loadRequest(const TokenQueue *queue, const TokenRequest &req); + void loadRequest(const TokenQueueVEG *queue, const TokenRequestVEG &req); protected: @@ -73,8 +73,8 @@ protected: std::map mLoadingMap; std::multimap mPendingInsertMap; - TokenQueue *mTokenQueue; - RsTokenService *mRsService; + TokenQueueVEG *mTokenQueue; + RsTokenServiceVEG *mRsService; protected: //virtual QMimeData * mimeData ( const QList items ) const; diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index 3e9118cfc..ed1ef9659 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -35,13 +35,13 @@ #define GXSGROUP_LOADGROUP 2 /** Constructor */ -GxsGroupDialog::GxsGroupDialog(RsTokenService *service, QWidget *parent) +GxsGroupDialog::GxsGroupDialog(RsTokenServiceVEG *service, QWidget *parent) : QDialog(parent), mRsService(service) { /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); - mTokenQueue = new TokenQueue(service, this); + mTokenQueue = new TokenQueueVEG(service, this); // connect up the buttons. connect( ui.cancelButton, SIGNAL( clicked ( bool ) ), this, SLOT( cancelDialog( ) ) ); @@ -289,7 +289,7 @@ void GxsGroupDialog::existingGroup(std::string groupId, uint32_t mode) /* request data */ { - RsTokReqOptions opts; + RsTokReqOptionsVEG opts; std::list grpIds; grpIds.push_back(groupId); @@ -605,7 +605,7 @@ void GxsGroupDialog::service_loadExistingGroup(const uint32_t &token) } -void GxsGroupDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) +void GxsGroupDialog::loadRequest(const TokenQueueVEG *queue, const TokenRequestVEG &req) { std::cerr << "GxsGroupDialog::loadRequest() UserType: " << req.mUserType; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h index 165b1dc23..27e8162e5 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h @@ -25,7 +25,7 @@ #include "ui_GxsGroupDialog.h" -#include "util/TokenQueue.h" +#include "util/TokenQueueVEG.h" /******** @@ -90,12 +90,12 @@ public: #define GXS_GROUP_DIALOG_SHOW_MODE 2 #define GXS_GROUP_DIALOG_EDIT_MODE 3 -class GxsGroupDialog : public QDialog, public TokenResponse +class GxsGroupDialog : public QDialog, public TokenResponseVEG { Q_OBJECT public: - GxsGroupDialog(RsTokenService *service, QWidget *parent = 0); + GxsGroupDialog(RsTokenServiceVEG *service, QWidget *parent = 0); void setFlags(uint32_t enabledFlags, uint32_t readonlyFlags, uint32_t defaultFlags); void setMode(uint32_t mode); @@ -105,7 +105,7 @@ public: void existingGroup(std::string groupId, uint32_t mode); // Callback for all Loads. -virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); +virtual void loadRequest(const TokenQueueVEG *queue, const TokenRequestVEG &req); // Functions that can be overloaded for specific stuff. @@ -159,8 +159,8 @@ private: QPixmap picture; - RsTokenService *mRsService; - TokenQueue *mTokenQueue; + RsTokenServiceVEG *mRsService; + TokenQueueVEG *mTokenQueue; uint32_t mMode; diff --git a/retroshare-gui/src/gui/gxs/PostedGroupDialog.cpp b/retroshare-gui/src/gui/gxs/PostedGroupDialog.cpp index f357d9d50..7605c60da 100644 --- a/retroshare-gui/src/gui/gxs/PostedGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/PostedGroupDialog.cpp @@ -21,11 +21,11 @@ #include "PostedGroupDialog.h" -#include +#include #include PostedGroupDialog::PostedGroupDialog(QWidget *parent) - :GxsGroupDialog(rsPosted, parent) + :GxsGroupDialog(rsPostedVEG, parent) { // To start with we only have open forums - with distribution controls. @@ -66,11 +66,11 @@ PostedGroupDialog::PostedGroupDialog(QWidget *parent) bool PostedGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) { // Specific Function. - RsPostedGroup grp; + RsPostedGroup grp; grp.mMeta = meta; //grp.mDescription = std::string(desc.toUtf8()); - rsPosted->submitGroup(token, grp, true); + rsPostedVEG->submitGroup(token, grp, true); return true; } @@ -80,7 +80,7 @@ void PostedGroupDialog::service_loadExistingGroup(const uint32_t &token) std::cerr << std::endl; RsPostedGroup group; - if (!rsPosted->getGroup(token, group)) + if (!rsPostedVEG->getGroup(token, group)) { std::cerr << "PostedGroupDialog::service_loadExistingGroup() ERROR Getting Group"; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp index dd1cc2c60..903068a7d 100644 --- a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp +++ b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp @@ -33,6 +33,7 @@ #include #include "gui/PhotoShare/PhotoShare.h" +#include "gui/Posted/PostedDialog.h" // THESE HAVE TO BE CONVERTED TO VEG FORMAT #if USE_VEG_SERVICE @@ -40,7 +41,7 @@ #include "gui/TheWire/WireDialog.h" #include "gui/Identity/IdDialog.h" #include "gui/ForumsV2Dialog.h" -#include "gui/Posted/PostedDialog.h" + #endif //#include "GamesDialog.h" @@ -108,6 +109,9 @@ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) ui.stackPages->add(photoShare = new PhotoShare(ui.stackPages), createPageAction(QIcon(IMAGE_PHOTO), tr("Photo Share"), grp)); + PostedDialog *postedDialog = NULL; + ui.stackPages->add(postedDialog = new PostedDialog(ui.stackPages), + createPageAction(QIcon(IMAGE_LIBRARY), tr("Posted Links"), grp)); // THESE HAVE TO BE CONVERTED TO VEG FORMAT #if USE_VEG_SERVICE WikiDialog *wikiDialog = NULL; @@ -122,9 +126,7 @@ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) ui.stackPages->add(forumsV2Dialog = new ForumsV2Dialog(ui.stackPages), createPageAction(QIcon(IMAGE_FORUMSV2), tr("ForumsV2"), grp)); - PostedDialog *postedDialog = NULL; - ui.stackPages->add(postedDialog = new PostedDialog(ui.stackPages), - createPageAction(QIcon(IMAGE_LIBRARY), tr("Posted Links"), grp)); + #endif diff --git a/retroshare-gui/src/util/TokenQueueV2.cpp b/retroshare-gui/src/util/TokenQueueV2.cpp index c87f6be40..29b650f1c 100644 --- a/retroshare-gui/src/util/TokenQueueV2.cpp +++ b/retroshare-gui/src/util/TokenQueueV2.cpp @@ -32,7 +32,7 @@ *****/ /** Constructor */ -TokenQueueV2::TokenQueueV2(RsTokenServiceV2 *service, TokenResponseV2 *resp) +TokenQueueV2::TokenQueueV2(RsTokenService *service, TokenResponseV2 *resp) :QWidget(NULL), mService(service), mResponder(resp) { return; @@ -152,8 +152,8 @@ bool TokenQueueV2::checkForRequest(uint32_t token) { /* check token */ uint32_t status = mService->requestStatus(token); - return ( (RsTokenServiceV2::GXS_REQUEST_V2_STATUS_FAILED == status) || - (RsTokenServiceV2::GXS_REQUEST_V2_STATUS_COMPLETE == status) ); + return ( (RsTokenService::GXS_REQUEST_V2_STATUS_FAILED == status) || + (RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE == status) ); } diff --git a/retroshare-gui/src/util/TokenQueueV2.h b/retroshare-gui/src/util/TokenQueueV2.h index 8578fbc24..65418d0b6 100644 --- a/retroshare-gui/src/util/TokenQueueV2.h +++ b/retroshare-gui/src/util/TokenQueueV2.h @@ -72,7 +72,7 @@ class TokenQueueV2: public QWidget Q_OBJECT public: - TokenQueueV2(RsTokenServiceV2 *service, TokenResponseV2 *resp); + TokenQueueV2(RsTokenService *service, TokenResponseV2 *resp); /* generic handling of token / response update behaviour */ @@ -111,7 +111,7 @@ private: /* Info for Data Requests */ std::list mRequests; - RsTokenServiceV2 *mService; + RsTokenService *mService; TokenResponseV2 *mResponder; QTimer *mTrigger; From 92454adbe79e206ecaa2d2382d75eaa05f28ee78 Mon Sep 17 00:00:00 2001 From: defnax Date: Mon, 8 Oct 2012 15:59:22 +0000 Subject: [PATCH 077/222] added the required include dirs for win git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5647 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/retroshare-nogui.pro | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/retroshare-nogui/src/retroshare-nogui.pro b/retroshare-nogui/src/retroshare-nogui.pro index 2b9a0a4be..5767a735a 100644 --- a/retroshare-nogui/src/retroshare-nogui.pro +++ b/retroshare-nogui/src/retroshare-nogui.pro @@ -74,6 +74,13 @@ win32 { RC_FILE = resources/retroshare_win.rc DEFINES *= WINDOWS_SYS + + SSH_DIR = ../../../libssh-0.5.2 + SSL_DIR = ../../../openssl-1.0.1c + + INCLUDEPATH += . $${SSH_DIR}/include $${SSL_DIR}/include + + } ##################################### MacOS ###################################### From 6b6e7335afda447da6bf66307e1a98639fe6ef55 Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 8 Oct 2012 18:28:34 +0000 Subject: [PATCH 078/222] added missing UPNP files back in. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5648 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/libretroshare.pro | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index fcb79000e..03259d453 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -160,6 +160,10 @@ HEADERS += retroshare/rsgame.h \ # miniupnp implementation files #HEADERS += upnp/upnputil.h #SOURCES += upnp/upnputil.c + + # libupnp implementation files + HEADERS += upnp/UPnPBase.h + SOURCES += upnp/UPnPBase.cpp # zeroconf disabled at the end of libretroshare.pro (but need the code) #CONFIG += zeroconf From edde01c878a7d258817e7e3d01a38d5c501aa215 Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 8 Oct 2012 18:31:29 +0000 Subject: [PATCH 079/222] Fixed libbitdht linking for linux.... This needs to be setup properly, like the trunk! git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5649 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/RetroShare.pro | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index eafe0c3d0..c944c137f 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -193,8 +193,11 @@ freebsd-* { # ########################################### bitdht { - LIBS += C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a - PRE_TARGETDEPS *= C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a + LIBS += ../../libbitdht/src/lib/libbitdht.a + PRE_TARGETDEPS *= ../../libbitdht/src/lib/libbitdht.a + + #LIBS += C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a + #PRE_TARGETDEPS *= C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a # Chris version. #LIBS += ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a From 9ff0d70997d97d4f65f8245bb7dfde7fc994404f Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 9 Oct 2012 07:27:54 +0000 Subject: [PATCH 080/222] updated README file for this branch git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5651 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- README.txt | 60 +++++++++++++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/README.txt b/README.txt index 1b95ef7c5..2dff121e9 100644 --- a/README.txt +++ b/README.txt @@ -1,42 +1,38 @@ To use this branch: - chekcout the last version of openpgp SDK: - # svn co svn://openpgp.nominet.org.uk/openpgpsdk/tags/openpgpsdk-0.9 openpgpsdk - # cd openpgpsdk - # ./configure --without-idea - # make + - get source code for libssh-0.5.2, unzip it, and create build directory (if needed) - For the moment, the compilation is not workign on ubuntu + # wget http://www.libssh.org/files/0.5/libssh-0.5.2.tar.gz + # tar zxvf libssh-0.5.2.tar.gz + # cd libssh-0.5.2 + # mkdir build + # cd build + # cmake -DWITH_STATIC_LIB=ON .. + # make + # cd ../.. + + - build the google proto files -Work to do -========== -Put a 'x' when done. 1,2,3 means started/ongoing/almost finished. + # cd rsctrl/src + # make -Compilation - 00 [1] make sure the library compiles on linux - 01 [ ] make sure the library compiles on windows + Don't bother about python related errors. -Project - 02 [1] determine what's missing in OpenPGP-SDK - 03 [3] make a separate layer in RS to handle PGP. AuthPGP is too close to libretroshare. - 04 [1] write the new AuthGPG class - 05 [ ] consider removing thread behaviour of AuthGPG - 06 [ ] remove callback system and services from AuthGPG, since it's not useful anymore - 07 [ ] make all RS use GPGIdType isntead of std::string. + - go to retroshare-nogui, and compile it -Notes -===== - Questions to answer: - - do we rely on updates from openPGP-sdk ? Probably not. This code seems frozen. - - do we need an abstract layer for PGP handling in RS ? - - what new functionalities do we need in RS ? - * pgp keyring sharing/import/export - * identity import/export + # cd ../../retroshare-nogui + # qmake + # make - Code struture - - replace current AuthGPG (virtual class) by a class named GPGHandler, - that is responsible for signing, checking signatures, encrypting etc. - - add a specific 8-bytes type for GPG Ids. Could be a uint64_t, or a - uchar[8] + - to use the SSH RS server: + + # ssh-keygen -t rsa -f rs_ssh_host_rsa_key # this makes a RSA + # ./retroshare-nogui -G # generates a login+passwd hash for the RSA key used. + # ./retroshare-nogui -S 7022 -U[SSLid] -P [Passwd hash] + - to connect from a remote place to the server by SSH: + + # ssh -T -p 7022 [user]@[host] + + and use the command line interface to control your RS instance. From 78edc7687e47364d5594772d5aae9aeb152baaf6 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Tue, 9 Oct 2012 23:07:51 +0000 Subject: [PATCH 081/222] Fixed compile of libretroshare on Windows. The corrected pro files are not included. Moved the includes of rswin.h from the header files to the c files. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5655 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/dbase/fimonitor.cc | 1 + libretroshare/src/ft/ftfileprovider.cc | 8 ++++---- libretroshare/src/pgp/pgphandler.cc | 1 + libretroshare/src/pqi/authgpg.h | 1 - libretroshare/src/pqi/authssl.cc | 4 ++++ libretroshare/src/pqi/authssl.h | 2 -- libretroshare/src/pqi/pqinetwork.cc | 6 ++++-- libretroshare/src/pqi/pqinetwork.h | 2 -- libretroshare/src/pqi/pqissl.h | 2 -- libretroshare/src/pqi/pqissludp.h | 2 -- libretroshare/src/pqi/sslfns.h | 2 -- libretroshare/src/rsserver/rsinit.cc | 4 +++- libretroshare/src/tcponudp/tou.h | 2 -- libretroshare/src/tcponudp/udpstunner.h | 4 ---- libretroshare/src/util/folderiterator.h | 1 - libretroshare/src/util/rsnet.h | 2 -- libretroshare/src/util/rsthreads.h | 4 ---- 17 files changed, 17 insertions(+), 31 deletions(-) diff --git a/libretroshare/src/dbase/fimonitor.cc b/libretroshare/src/dbase/fimonitor.cc index 9b81c9652..84f101f13 100644 --- a/libretroshare/src/dbase/fimonitor.cc +++ b/libretroshare/src/dbase/fimonitor.cc @@ -23,6 +23,7 @@ #ifdef WINDOWS_SYS #include "util/rsstring.h" +#include "util/rswin.h" #endif #include "dbase/fimonitor.h" diff --git a/libretroshare/src/ft/ftfileprovider.cc b/libretroshare/src/ft/ftfileprovider.cc index 05907d7dd..b64153055 100644 --- a/libretroshare/src/ft/ftfileprovider.cc +++ b/libretroshare/src/ft/ftfileprovider.cc @@ -1,3 +1,7 @@ +#ifdef WINDOWS_SYS +#include "util/rswin.h" +#endif // WINDOWS_SYS + #include "ftfileprovider.h" #include "ftchunkmap.h" @@ -5,10 +9,6 @@ #include #include -#ifdef WINDOWS_SYS -#include "util/rswin.h" -#endif // WINDOWS_SYS - /******** * #define DEBUG_FT_FILE_PROVIDER 1 * #define DEBUG_TRANSFERS 1 // TO GET TIMESTAMPS of DATA READING diff --git a/libretroshare/src/pgp/pgphandler.cc b/libretroshare/src/pgp/pgphandler.cc index 327f794ec..6160d7fba 100644 --- a/libretroshare/src/pgp/pgphandler.cc +++ b/libretroshare/src/pgp/pgphandler.cc @@ -8,6 +8,7 @@ #ifdef WINDOWS_SYS #include "util/rsstring.h" +#include "util/rswin.h" #endif extern "C" { diff --git a/libretroshare/src/pqi/authgpg.h b/libretroshare/src/pqi/authgpg.h index e4576cb4b..6b32a8991 100644 --- a/libretroshare/src/pqi/authgpg.h +++ b/libretroshare/src/pqi/authgpg.h @@ -39,7 +39,6 @@ #ifndef RS_GPG_AUTH_HEADER #define RS_GPG_AUTH_HEADER -#include "util/rswin.h" #include #include #include "util/rsthreads.h" diff --git a/libretroshare/src/pqi/authssl.cc b/libretroshare/src/pqi/authssl.cc index d610c5068..1098a44d4 100644 --- a/libretroshare/src/pqi/authssl.cc +++ b/libretroshare/src/pqi/authssl.cc @@ -28,6 +28,10 @@ * */ +#ifdef WINDOWS_SYS +#include "util/rswin.h" +#endif // WINDOWS_SYS + #include "authssl.h" #include "sslfns.h" #include "cleanupxpgp.h" diff --git a/libretroshare/src/pqi/authssl.h b/libretroshare/src/pqi/authssl.h index 5f1c27e85..c975b5a1c 100644 --- a/libretroshare/src/pqi/authssl.h +++ b/libretroshare/src/pqi/authssl.h @@ -39,8 +39,6 @@ * */ -#include "util/rswin.h" - #include #include diff --git a/libretroshare/src/pqi/pqinetwork.cc b/libretroshare/src/pqi/pqinetwork.cc index 080b6fd35..3a59a2351 100644 --- a/libretroshare/src/pqi/pqinetwork.cc +++ b/libretroshare/src/pqi/pqinetwork.cc @@ -23,8 +23,10 @@ * */ - - +#ifdef WINDOWS_SYS +#include "util/rswin.h" +#include +#endif // WINDOWS_SYS #include "pqi/pqinetwork.h" #include "util/rsnet.h" diff --git a/libretroshare/src/pqi/pqinetwork.h b/libretroshare/src/pqi/pqinetwork.h index 52cb4f6d5..10bdcdb7e 100644 --- a/libretroshare/src/pqi/pqinetwork.h +++ b/libretroshare/src/pqi/pqinetwork.h @@ -45,12 +45,10 @@ #else -#include "util/rswin.h" #include "util/rsnet.h" /* more generic networking header */ #include -#include typedef int socklen_t; //typedef unsigned long in_addr_t; diff --git a/libretroshare/src/pqi/pqissl.h b/libretroshare/src/pqi/pqissl.h index b32eec8c9..988ae1e0d 100644 --- a/libretroshare/src/pqi/pqissl.h +++ b/libretroshare/src/pqi/pqissl.h @@ -28,8 +28,6 @@ #ifndef MRK_PQI_SSL_HEADER #define MRK_PQI_SSL_HEADER -#include "util/rswin.h" - #include // operating system specific network header. diff --git a/libretroshare/src/pqi/pqissludp.h b/libretroshare/src/pqi/pqissludp.h index f5044fbd4..f07632dd4 100644 --- a/libretroshare/src/pqi/pqissludp.h +++ b/libretroshare/src/pqi/pqissludp.h @@ -28,8 +28,6 @@ #ifndef MRK_PQI_SSL_UDP_HEADER #define MRK_PQI_SSL_UDP_HEADER -#include "util/rswin.h" - #include // operating system specific network header. diff --git a/libretroshare/src/pqi/sslfns.h b/libretroshare/src/pqi/sslfns.h index f4c693f7e..98e3b2c0e 100644 --- a/libretroshare/src/pqi/sslfns.h +++ b/libretroshare/src/pqi/sslfns.h @@ -33,8 +33,6 @@ /******************** notify of new Cert **************************/ -#include "util/rswin.h" - #include #include #include diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 0a1cce5e9..ce7091ef5 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -28,9 +28,11 @@ #include -// for locking instances #ifndef WINDOWS_SYS +// for locking instances #include +#else +#include "util/rswin.h" #endif #include "util/rsdebug.h" diff --git a/libretroshare/src/tcponudp/tou.h b/libretroshare/src/tcponudp/tou.h index 0c2522764..da72bb85d 100644 --- a/libretroshare/src/tcponudp/tou.h +++ b/libretroshare/src/tcponudp/tou.h @@ -40,10 +40,8 @@ #include #else - #include "util/rswin.h" #include #include - #include #include // #include typedef int socklen_t; diff --git a/libretroshare/src/tcponudp/udpstunner.h b/libretroshare/src/tcponudp/udpstunner.h index 74b07b517..1f55f241b 100644 --- a/libretroshare/src/tcponudp/udpstunner.h +++ b/libretroshare/src/tcponudp/udpstunner.h @@ -25,10 +25,6 @@ * */ -#ifdef WINDOWS_SYS -#include "util/rswin.h" -#endif - #ifndef WINDOWS_SYS #include #endif diff --git a/libretroshare/src/util/folderiterator.h b/libretroshare/src/util/folderiterator.h index bfddc6b74..8007db1a1 100644 --- a/libretroshare/src/util/folderiterator.h +++ b/libretroshare/src/util/folderiterator.h @@ -6,7 +6,6 @@ #include #ifdef WINDOWS_SYS - #include "util/rswin.h" #include #include #include diff --git a/libretroshare/src/util/rsnet.h b/libretroshare/src/util/rsnet.h index c8442f1c6..15bf5749a 100644 --- a/libretroshare/src/util/rsnet.h +++ b/libretroshare/src/util/rsnet.h @@ -44,10 +44,8 @@ #else -#include "util/rswin.h" #include -#include #include /* for ssize_t */ //typedef uint32_t socklen_t; diff --git a/libretroshare/src/util/rsthreads.h b/libretroshare/src/util/rsthreads.h index 7cd81a294..204fdd630 100644 --- a/libretroshare/src/util/rsthreads.h +++ b/libretroshare/src/util/rsthreads.h @@ -27,10 +27,6 @@ */ -#ifdef WINDOWS_SYS -#include "util/rswin.h" -#endif - #include #include #include From b5cadf357b9e0899d215574bd2b37e4545d1451a Mon Sep 17 00:00:00 2001 From: defnax Date: Wed, 10 Oct 2012 11:25:23 +0000 Subject: [PATCH 082/222] fixed project file for windows, to get compile gui again git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5658 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/RetroShare.pro | 35 ++++++++++++++++--------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index c944c137f..40255f727 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -123,30 +123,31 @@ win32 { #QMAKE_CXXFLAGS_DEBUG += -O2 #QMAKE_CFLAGS_DEBUG += -O2 -# PRE_TARGETDEPS += ../../libretroshare/src/lib/libretroshare.a - PRE_TARGETDEPS += ../../libretroshare/libretroshare-build-desktop/lib/libretroshare.a + OBJECTS_DIR = temp/obj - LIBS += ../../libretroshare/libretroshare-build-desktop/lib/libretroshare.a - LIBS += C:\Development\Rs\v0.5-gxs-b1\openpgpsdk\openpgpsdk-build-desktop\lib\libops.a - LIBS += C:\Development\Libraries\sqlite\sqlite-autoconf-3070900\lib\libsqlite3.a - LIBS += -L"../../../lib" - LIBS += -lssl -lcrypto -lgpgme -lpthreadGC2d -lminiupnpc -lz -lbz2 + PRE_TARGETDEPS += ../../libretroshare/src/lib/libretroshare.a + #PRE_TARGETDEPS += ../../libretroshare/libretroshare-build-desktop/lib/libretroshare.a + + LIBS += ../../libretroshare/src/lib/libretroshare.a + LIBS += ../../openpgpsdk/src/lib/libops.a + LIBS += ../../../sqlite-autoconf-3070900/.libs/libsqlite3.a + LIBS += -L"../../../lib" + LIBS += -lssl -lcrypto -lpthreadGC2d -lminiupnpc -lz -lbz2 # added after bitdht # LIBS += -lws2_32 - LIBS += -luuid -lole32 -liphlpapi -lcrypt32-cygwin -lgdi32 - LIBS += -lole32 -lwinmm - RC_FILE = gui/images/retroshare_win.rc + LIBS += -luuid -lole32 -liphlpapi -lcrypt32-cygwin -lgdi32 + LIBS += -lole32 -lwinmm + RC_FILE = gui/images/retroshare_win.rc - # export symbols for the plugins - #LIBS += -Wl,--export-all-symbols,--out-implib,lib/libretroshare-gui.a + # export symbols for the plugins + LIBS += -Wl,--export-all-symbols,--out-implib,lib/libretroshare-gui.a - GPG_ERROR_DIR = ../../../../libgpg-error-1.7 - GPGME_DIR = ../../../../gpgme-1.1.8 - GPG_ERROR_DIR = ../../../../lib/libgpg-error-1.7 - GPGME_DIR = ../../../../lib/gpgme-1.1.8 - INCLUDEPATH += . $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src + # create lib directory + QMAKE_PRE_LINK = $(CHK_DIR_EXISTS) lib $(MKDIR) lib + DEFINES += WINDOWS_SYS + INCLUDEPATH += . } From 87856b2c9eeee3f5c649dc942f087da3b77aefd8 Mon Sep 17 00:00:00 2001 From: defnax Date: Wed, 10 Oct 2012 15:53:59 +0000 Subject: [PATCH 083/222] little layout changes, to not stretch the labels display the comments on right side of the PhotoDialog git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5661 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/gui/PhotoShare/AlbumItem.ui | 13 + .../src/gui/PhotoShare/PhotoCommentItem.ui | 7 +- .../src/gui/PhotoShare/PhotoDialog.cpp | 23 +- .../src/gui/PhotoShare/PhotoDialog.ui | 348 ++++++++---------- .../src/gui/PhotoShare/PhotoItem.ui | 18 +- 5 files changed, 205 insertions(+), 204 deletions(-) diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumItem.ui b/retroshare-gui/src/gui/PhotoShare/AlbumItem.ui index 0ab51b8d4..88ef3770d 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumItem.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumItem.ui @@ -91,6 +91,19 @@ p, li { white-space: pre-wrap; }
+ + + + Qt::Vertical + + + + 20 + 40 + + + +
diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui index 792a69107..a11bcd470 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui @@ -6,14 +6,17 @@ 0 0 - 411 - 84 + 392 + 63 Form + + 0 + diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index a8469cace..9c7d69986 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -13,7 +13,7 @@ PhotoDialog::PhotoDialog(RsPhotoV2 *rs_photo, const RsPhotoPhoto &photo, QWidget { ui->setupUi(this); setAttribute ( Qt::WA_DeleteOnClose, true ); - connect(ui->toolButton_AddComment, SIGNAL(clicked()), this, SLOT(addComment())); + connect(ui->toolButton_AddComment, SIGNAL(clicked()), this, SLOT(createComment())); setUp(); } @@ -31,7 +31,7 @@ void PhotoDialog::setUp() ui->label_Photo->setPixmap(qtn); ui->lineEdit_Title->setText(QString::fromStdString(mPhotoDetails.mMeta.mMsgName)); - ui->scrollAreaWidgetContents->setLayout(new QVBoxLayout()); + //ui->scrollAreaWidgetContents->setLayout(new QVBoxLayout()); requestComments(); } @@ -49,12 +49,12 @@ void PhotoDialog::addComment() void PhotoDialog::clearComments() { - QLayout* l = ui->scrollAreaWidgetContents->layout(); + //QLayout* l = ui->scrollAreaWidgetContents->layout(); QSetIterator sit(mComments); while(sit.hasNext()) { PhotoCommentItem* item = sit.next(); - l->removeWidget(item); + ui->verticalLayout->removeWidget(item); item->setParent(NULL); delete item; } @@ -65,11 +65,11 @@ void PhotoDialog::clearComments() void PhotoDialog::resetComments() { QSetIterator sit(mComments); - QLayout* l = ui->scrollAreaWidgetContents->layout(); + //QLayout* l = ui->scrollAreaWidgetContents->layout(); while(sit.hasNext()) { PhotoCommentItem* item = sit.next(); - l->addWidget(item); + ui->verticalLayout->insertWidget(0,item); } } @@ -90,10 +90,8 @@ void PhotoDialog::requestComments() void PhotoDialog::createComment() { - if(mCommentDialog) - { RsPhotoComment comment; - QString commentString = mCommentDialog->getComment(); + QString commentString = ui->lineEdit->text(); comment.mComment = commentString.toStdString(); @@ -102,11 +100,8 @@ void PhotoDialog::createComment() comment.mMeta.mParentId = mPhotoDetails.mMeta.mOrigMsgId; mRsPhoto->submitComment(token, comment); mPhotoQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); - - mCommentDialog->close(); - delete mCommentDialog; - mCommentDialog = NULL; - } + + ui->lineEdit->clear(); } diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui index 6631999cc..3171923b9 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui @@ -6,196 +6,56 @@ 0 0 - 516 - 460 + 615 + 566 Dialog - - - - - - - - - - 0 - 1 - - - - Photo - - - - - - - 0 - 0 - - - - - 200 - 300 - - - - TextLabel - - - - - - - - - - - 0 - 0 - - - - - 50 - 200 - - - - Summary - - - - - - false - - - - 0 - 0 - - - - - - - - Caption - - - - - - - false - - - - 0 - 0 - - - - - - - - Where: - - - - - - - false - - - - 0 - 0 - - - - - - - - false - - - - 0 - 0 - - - - - - - - Photo Title: - - - - - - - When - - - - - - - - - + + + + + + 0 + 1 + + + + Photo + + + + + + + 0 + 0 + + + + + 200 + 300 + + + + TextLabel + + + + + - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Add Comment - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - + + + + 0 + 0 + + true @@ -204,13 +64,131 @@ 0 0 - 496 - 69 + 325 + 18 + + + 0 + 0 + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + Summary + + + + + + false + + + + 0 + 0 + + + + + + + + Caption + + + + + + + false + + + + 0 + 0 + + + + + + + + Where: + + + + + + + false + + + + 0 + 0 + + + + + + + + false + + + + 0 + 0 + + + + + + + + Photo Title: + + + + + + + When + + + + + + + + + + + + + Comment + + + diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoItem.ui b/retroshare-gui/src/gui/PhotoShare/PhotoItem.ui index b49b45ff3..7162fd137 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoItem.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoItem.ui @@ -7,7 +7,7 @@ 0 0 253 - 222 + 233 @@ -79,8 +79,7 @@ p, li { white-space: pre-wrap; } - - +
@@ -88,6 +87,19 @@ p, li { white-space: pre-wrap; } + + + + Qt::Vertical + + + + 20 + 40 + + + + From b166fe0c990dcc97235fd2ce1eea2629abb74186 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sat, 13 Oct 2012 21:10:42 +0000 Subject: [PATCH 084/222] Added photo slide show added time stamps on comments photo items now store real image fixed bug in rsdataservice due to stack overflow (large photo!) git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5672 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsdataservice.cc | 3 +- .../src/gui/PhotoShare/PhotoCommentItem.cpp | 7 ++ .../src/gui/PhotoShare/PhotoCommentItem.ui | 37 ++++++++- .../src/gui/PhotoShare/PhotoDialog.ui | 14 +++- .../src/gui/PhotoShare/PhotoItem.cpp | 6 +- .../src/gui/PhotoShare/PhotoShare.cpp | 5 +- .../src/gui/PhotoShare/PhotoSlideShow.cpp | 80 +++++-------------- .../src/gui/PhotoShare/PhotoSlideShow.h | 14 ++-- 8 files changed, 90 insertions(+), 76 deletions(-) diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index 1afb0bb5a..e6178e6ec 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -468,10 +468,11 @@ int RsDataService::storeMessage(std::map &msg) cv.put(KEY_CHILD_TS, (int32_t)msgMetaPtr->mChildTs); offset = 0; - char msgData[msgPtr->msg.TlvSize()]; + char* msgData = new char[msgPtr->msg.TlvSize()]; msgPtr->msg.SetTlv(msgData, msgPtr->msg.TlvSize(), &offset); ostrm.write(msgData, msgPtr->msg.TlvSize()); ostrm.close(); + delete[] msgData; mDb->sqlInsert(MSG_TABLE_NAME, "", cv); } diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.cpp index bef0d0c14..6cfb2236a 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.cpp @@ -1,6 +1,9 @@ +#include + #include "PhotoCommentItem.h" #include "ui_PhotoCommentItem.h" + PhotoCommentItem::PhotoCommentItem(const RsPhotoComment& comment, QWidget *parent): QWidget(parent), ui(new Ui::PhotoCommentItem), mComment(comment) @@ -22,4 +25,8 @@ const RsPhotoComment& PhotoCommentItem::getComment() void PhotoCommentItem::setUp() { ui->labelComment->setText(QString::fromStdString(mComment.mComment)); + QDateTime qtime; + qtime.setTime_t(mComment.mMeta.mPublishTs); + QString timestamp = qtime.toString("dd.MMMM yyyy hh:mm"); + ui->datetimelabel->setText(timestamp); } diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui index a11bcd470..609c69f43 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui @@ -43,7 +43,42 @@ border-radius: 10px;} QFrame::Raised - + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 75 + true + PreferAntialias + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:600; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; color:#666666;">DateTime</span></p></body></html> + + + + + diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui index 3171923b9..3436b84a0 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui @@ -10,8 +10,14 @@ 566 + + + 0 + 0 + + - Dialog + PhotoShare @@ -56,6 +62,12 @@ 0 + + + 327 + 0 + + true diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp index c3506d52b..c17034aad 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoItem.cpp @@ -32,10 +32,8 @@ PhotoItem::PhotoItem(PhotoShareItemHolder *holder, const QString& path, QWidget { ui->setupUi(this); - int width = 250; - int height = 250; - QPixmap qtn = QPixmap(path).scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation); + QPixmap qtn = QPixmap(path); mThumbNail = qtn; ui->label_Thumbnail->setPixmap(mThumbNail.scaled(120, 120, Qt::KeepAspectRatio, Qt::SmoothTransformation)); setSelected(false); @@ -133,7 +131,7 @@ void PhotoItem::updateImage(const RsPhotoThumbnail &thumbnail) { QPixmap qtn; qtn.loadFromData(thumbnail.data, thumbnail.size, thumbnail.type.c_str()); - ui->label_Thumbnail->setPixmap(qtn); + ui->label_Thumbnail->setPixmap(qtn.scaled(120, 120, Qt::KeepAspectRatio, Qt::SmoothTransformation)); mThumbNail = qtn; } } diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp index ff42ac285..07e230697 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp @@ -210,18 +210,15 @@ void PhotoShare::OpenSlideShow() return; } - std::string albumId = mAlbumSelected->getAlbum().mMeta.mGroupId; - if (mSlideShow) { mSlideShow->show(); } else { - mSlideShow = new PhotoSlideShow(NULL); + mSlideShow = new PhotoSlideShow(mAlbumSelected->getAlbum(), NULL); mSlideShow->show(); } - mSlideShow->loadAlbum(albumId); } diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp index 7330796e3..6b83e4b55 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp @@ -27,8 +27,8 @@ #include /** Constructor */ -PhotoSlideShow::PhotoSlideShow(QWidget *parent) -: QWidget(parent) +PhotoSlideShow::PhotoSlideShow(const RsPhotoAlbum& album, QWidget *parent) +: QWidget(parent), mAlbum(album) { ui.setupUi(this); @@ -45,12 +45,19 @@ PhotoSlideShow::PhotoSlideShow(QWidget *parent) mImageIdx = 0; - //loadImage(); + requestPhotos(); + loadImage(); //QTimer::singleShot(5000, this, SLOT(timerEvent())); } PhotoSlideShow::~PhotoSlideShow(){ + std::map::iterator mit = mPhotos.begin(); + + for(; mit != mPhotos.end(); mit++) + { + delete mit->second; + } } void PhotoSlideShow::showPhotoDetails() @@ -174,9 +181,7 @@ void PhotoSlideShow::loadImage() qtn.loadFromData(tn.data, tn.size, tn.type.c_str()); tn.data = 0; - //ui.imgLabel->setPixmap(qtn); - - QPixmap sqtn = qtn.scaled(ui.albumLabel->width(), ui.imgLabel->height(), Qt::KeepAspectRatio, Qt::SmoothTransformation); + QPixmap sqtn = qtn.scaled(800, 600, Qt::KeepAspectRatio, Qt::SmoothTransformation); ui.imgLabel->setPixmap(sqtn); } @@ -238,24 +243,16 @@ void PhotoSlideShow::clearDialog() #endif } - -void PhotoSlideShow::loadAlbum(const std::string &albumId) +void PhotoSlideShow::requestPhotos() { - /* much like main load fns */ - clearDialog(); - - RsTokReqOptionsV2 opts; - uint32_t token; - std::list albumIds; - albumIds.push_back(albumId); - - // We need both Album and Photo Data. - - mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, albumIds, 0); - + RsTokReqOptionsV2 opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + uint32_t token; + std::list grpIds; + grpIds.push_back(mAlbum.mMeta.mGroupId); + mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); } - bool PhotoSlideShow::loadPhotoData(const uint32_t &token) { std::cerr << "PhotoSlideShow::loadPhotoData()"; @@ -270,7 +267,7 @@ bool PhotoSlideShow::loadPhotoData(const uint32_t &token) { std::vector& photoV = mit->second; std::vector::iterator vit = photoV.begin(); - + int i = 0; for(; vit != photoV.end(); vit++) { RsPhotoPhoto& photo = *vit; @@ -278,7 +275,7 @@ bool PhotoSlideShow::loadPhotoData(const uint32_t &token) *ptr = photo; ptr->mThumbnail.data = 0; ptr->mThumbnail.copyFrom(photo.mThumbnail); - + ptr->mOrder = i++; mPhotos[photo.mMeta.mMsgId] = ptr; mPhotoOrder[ptr->mOrder] = photo.mMeta.mMsgId; @@ -297,38 +294,6 @@ bool PhotoSlideShow::loadPhotoData(const uint32_t &token) return true; } -bool PhotoSlideShow::loadAlbumData(const uint32_t &token) -{ - std::cerr << "PhotoSlideShow::loadAlbumData()"; - std::cerr << std::endl; - - std::vector albums; - rsPhotoV2->getAlbum(token, albums); - - std::vector::iterator vit = albums.begin(); - - GxsMsgReq req; - - for(; vit != albums.end(); vit++) - { - RsPhotoAlbum& album = *vit; - - std::cerr << " PhotoSlideShow::loadAlbumData() AlbumId: " << album.mMeta.mGroupId << std::endl; - //updateAlbumDetails(album); - uint32_t token; - std::list albumIds; - albumIds.push_back(album.mMeta.mGroupId); - req[album.mMeta.mGroupId] = std::vector(); - - } - - RsTokReqOptionsV2 opts; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - uint32_t t; - mPhotoQueue->requestMsgInfo(t, RS_TOKREQ_ANSTYPE_DATA, opts, req, 0); - return true; -} - void PhotoSlideShow::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req) { std::cerr << "PhotoSlideShow::loadRequest()"; @@ -339,14 +304,11 @@ void PhotoSlideShow::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 /* now switch on req */ switch(req.mType) { - case TOKENREQ_GROUPINFO: - loadAlbumData(req.mToken); - break; case TOKENREQ_MSGINFO: loadPhotoData(req.mToken); break; default: - std::cerr << "PhotoSlideShow::loadRequest() ERROR: GROUP: INVALID ANS TYPE"; + std::cerr << "PhotoSlideShow::loadRequest() ERROR: REQ: INVALID REQ TYPE"; std::cerr << std::endl; break; } diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.h b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.h index 0b5930691..70fc7340c 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.h @@ -28,17 +28,17 @@ #include #include "util/TokenQueueV2.h" +#include "AlbumItem.h" class PhotoSlideShow : public QWidget, public TokenResponseV2 { Q_OBJECT public: - PhotoSlideShow(QWidget *parent = 0); + PhotoSlideShow(const RsPhotoAlbum& mAlbum, QWidget *parent = 0); virtual ~PhotoSlideShow(); - void loadAlbum(const std::string &albumId); -virtual void loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req); + void loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req); void clearDialog(); @@ -53,13 +53,13 @@ private slots: private: + void requestPhotos(); void loadImage(); void updateMoveButtons(uint32_t status); - bool loadPhotoData(const uint32_t &token); - bool loadAlbumData(const uint32_t &token); + bool loadPhotoData(const uint32_t &token); -//protected: +private: std::map mPhotos; std::map mPhotoOrder; @@ -68,6 +68,8 @@ private: int mImageIdx; bool mShotActive; + RsPhotoAlbum mAlbum; + TokenQueueV2 *mPhotoQueue; Ui::PhotoSlideShow ui; From b35645a0ea2f952966261811b1dad215c51242c6 Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 14 Oct 2012 12:08:15 +0000 Subject: [PATCH 085/222] fix bad include - amazed it compiles with this error. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5674 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/rsserver/rsinit.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index ce7091ef5..366ce9786 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1821,7 +1821,7 @@ RsTurtle *rsTurtle = NULL ; #ifdef ENABLE_GXS_SERVICES #include "services/p3wikiserviceVEG.h" #include "services/p3wireVEG.h" -#include "services/p3idserviceVEG.h".h" +#include "services/p3idserviceVEG.h" #include "services/p3forumsVEG.h" #include "services/p3postedVEG.h" #endif From 1ec5c7fe6927674fcf6809a32456d47f8933d853 Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 14 Oct 2012 18:32:33 +0000 Subject: [PATCH 086/222] Added first pass at new RsIdentity service. * Updated rgixs with new interfaces. (tentative) * Switched rsIdentity to GXS basis. * Added Subscribe Function to rsGxsIfaceImpl + return false to functions. This code needs to be reviewed by chris ASAP, to see how it fits into the whole structure. This code is currently not compiled, or compilable. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5677 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgixs.h | 127 +++++++ libretroshare/src/gxs/rsgxsifaceimpl.cc | 15 +- libretroshare/src/gxs/rsgxsifaceimpl.h | 42 ++- libretroshare/src/libretroshare.pro | 2 - libretroshare/src/retroshare/rsidentity.h | 441 +++++----------------- libretroshare/src/services/p3idservice.h | 114 +++--- 6 files changed, 321 insertions(+), 420 deletions(-) diff --git a/libretroshare/src/gxs/rsgixs.h b/libretroshare/src/gxs/rsgixs.h index baeb4b138..386ab6379 100644 --- a/libretroshare/src/gxs/rsgixs.h +++ b/libretroshare/src/gxs/rsgixs.h @@ -60,6 +60,131 @@ */ +/****** + * More notes. The ideas above have been crystalised somewhat. + * + * The Identity service will now serve two roles: + * 1) validating msgs. + * 2) reputation of identity. + * + * The identity will be equivalent to a Group Definition. + * and the reputation contained in the group's messages. + * + * + * Group + * MetaData: + * Public Key + * Signatures. (Admin & optional GPG). + * RealData: + * Nickname. + * GPGHash + * + * The GPGHash will allow people to identify the real gpg user behind the identity. + * We must make sure that the Hash input has enough entropy that it cannot be brute-forced (e.g. like password hashes). + * + * The Identity service only has to provide hooks to access the Keys for each group. + * All the key definitions are exactly the same as for GroupMetaData. + * + * The Interface is split into three parts. + * 1) Internal interface used by GXS to verify signatures. + * 2) Internal interface used by GXS to help decide if we get a message or not. + * 3) External interface to access nicknames, generate new identities etc. + * + * The actual implementation will cache frequently used keys and nicknames, + * as these will be used very frequently. + *****/ + +typedef std::string GxsId; +typedef std::string PeerId; + +// External Interface - +class RsIdentityService +{ + enum IdentityType { Pseudonym, Signed, Anonymous }; + + virtual bool loadId(const GxsId &id) = 0; + + virtual bool getNickname(const GxsId &id, std::string &nickname) = 0; + + virtual bool createKey(RsGixsProfile& profile, uint32_t type) = 0; /* fills in mKeyId, and signature */ + + virtual RsGixsProfile* getProfile(const KeyRef& keyref) = 0; + + // modify reputation. + +}; + + +/* Identity Interface for GXS Message Verification. + */ + +class RsGixs +{ +public: + // Key related interface - used for validating msgs and groups. + /*! + * Use to query a whether given key is available by its key reference + * @param keyref the keyref of key that is being checked for + * @return true if available, false otherwise + */ + virtual bool haveKey(const GxsId &id) = 0; + + /*! + * Use to query whether private key member of the given key reference is available + * @param keyref the KeyRef of the key being checked for + * @return true if private key is held here, false otherwise + */ + virtual bool havePrivateKey(const GxsId &id) = 0; + + // The fetchKey has an optional peerList.. this is people that had the msg with the signature. + // These same people should have the identity - so we ask them first. + /*! + * Use to request a given key reference + * @param keyref the KeyRef of the key being requested + * @return will + */ + virtual bool requestKey(const GxsId &id, const std::list &peers) = 0; + + /*! + * Retrieves a key identity + * @param keyref + * @return a pointer to a valid profile if successful, otherwise NULL + * + */ + virtual int getKey(const GxsId &id, TlvSecurityKey &key) = 0; + virtual int getPrivateKey(const GxsId &id, TlvSecurityKey &key) = 0; // For signing outgoing messages. + + +}; + + +class RsGixsReputation +{ +public: + // get Reputation. + virtual bool getReputation(const GxsId &id, const GixsReputation &rep) = 0; +}; + + +/*** This Class pulls all the GXS Interfaces together ****/ + +class RsGxsIdExchange: public RsGenExchange, public RsGixsReputation, public RsGixs +{ +public: + RsGxsIdExchange() { return; } +virtual ~RsGxsIdExchange() { return; } + +}; + + + + + +// BELOW IS OLD - WILL DELETE SHORTLY + +#if 0 + + /*! * Storage class for private and public publish keys * @@ -227,5 +352,7 @@ public: }; +#endif // END OF #if 0 + #endif // RSGIXS_H diff --git a/libretroshare/src/gxs/rsgxsifaceimpl.cc b/libretroshare/src/gxs/rsgxsifaceimpl.cc index 93af1bf3d..b9f26dbf8 100644 --- a/libretroshare/src/gxs/rsgxsifaceimpl.cc +++ b/libretroshare/src/gxs/rsgxsifaceimpl.cc @@ -29,12 +29,14 @@ bool RsGxsIfaceImpl::getGroupList(const uint32_t &token, std::list &groupIds) { + return false; } bool RsGxsIfaceImpl::getMsgList(const uint32_t &token, GxsMsgIdResult& msgIds) { + return false; } /* Generic Summary */ @@ -42,20 +44,31 @@ bool RsGxsIfaceImpl::getGroupSummary(const uint32_t &token, std::list &groupInfo) { + return false; } bool RsGxsIfaceImpl::getMsgSummary(const uint32_t &token, GxsMsgMetaMap &msgInfo) { + return false; } +bool RsGxsIfaceImpl::subscribeToAlbum(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe) +{ + + return false; + +} + + bool RsGxsIfaceImpl::acknowledgeMsg(const uint32_t& token, std::pair& msgId) { + return false; } bool RsGxsIfaceImpl::acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId) { - + return false; } diff --git a/libretroshare/src/gxs/rsgxsifaceimpl.h b/libretroshare/src/gxs/rsgxsifaceimpl.h index 16cc69a4e..d39060b8f 100644 --- a/libretroshare/src/gxs/rsgxsifaceimpl.h +++ b/libretroshare/src/gxs/rsgxsifaceimpl.h @@ -23,26 +23,66 @@ public: /** Requests **/ + /*! + * + * @param grpIds + */ void groupsChanged(std::list& grpIds); - + /*! + * + * @param msgs + */ void msgsChanged(std::map >& msgs); RsTokenService* getTokenService(); + /* Generic Lists */ + + /*! + * + * @param token token to be redeemed for this request + * @param groupIds the ids return for given request token + * @return false if request token is invalid, check token status for error report + */ bool getGroupList(const uint32_t &token, std::list &groupIds); + + /*! + * @param token token to be redeemed for this request + * @param msgIds the ids return for given request token + * @return false if request token is invalid, check token status for error report + */ bool getMsgList(const uint32_t &token, GxsMsgIdResult& msgIds); /* Generic Summary */ + + /*! + * @param token token to be redeemed for group summary request + * @param groupInfo the ids returned for given request token + * @return false if request token is invalid, check token status for error report + */ bool getGroupSummary(const uint32_t &token, std::list &groupInfo); + /*! + * @param token token to be redeemed for message summary request + * @param msgInfo the message metadata returned for given request token + * @return false if request token is invalid, check token status for error report + */ bool getMsgSummary(const uint32_t &token, GxsMsgMetaMap &msgInfo); + /*! + * subscribes to group, and returns token which can be used + * to be acknowledged to get group Id + * @param token token to redeem for acknowledgement + * @param grpId the id of the group to subscribe to + */ + virtual bool subscribeToAlbum(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe); + /*! * This allows the client service to acknowledge that their msgs has * been created/modified and retrieve the create/modified msg ids diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 03259d453..127875236 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -11,8 +11,6 @@ CONFIG += test_voip # GXS Stuff. CONFIG += newcache CONFIG += newservices -#CONFIG += newcache -#CONFIG += newservices # Beware: All data of the stripped services are lost DEFINES *= PQI_DISABLE_TUNNEL diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index 8fb6df089..c30e551a2 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -10,7 +10,7 @@ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. + * License Version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -29,336 +29,7 @@ #include #include #include - -// FLAGS WILL BE REUSED FROM RSDISTRIB -> FOR NOW. -#include - -/********** Generic Token Request Interface *********************** - * This is packaged here, as most TokenServices will require ID Services too. - * The requests can be generic, but the reponses are service specific (dependent on data types). - */ - -// This bit will be filled out over time. -#define RS_TOKREQOPT_MSG_VERSIONS 0x0001 // MSGRELATED: Returns All MsgIds with OrigMsgId = MsgId. -#define RS_TOKREQOPT_MSG_ORIGMSG 0x0002 // MSGLIST: All Unique OrigMsgIds in a Group. -#define RS_TOKREQOPT_MSG_LATEST 0x0004 // MSGLIST: All Latest MsgIds in Group. MSGRELATED: Latest MsgIds for Input Msgs. - -#define RS_TOKREQOPT_MSG_THREAD 0x0010 // MSGRELATED: All Msgs in Thread. MSGLIST: All Unique Thread Ids in Group. -#define RS_TOKREQOPT_MSG_PARENT 0x0020 // MSGRELATED: All Children Msgs. - -#define RS_TOKREQOPT_MSG_AUTHOR 0x0040 // MSGLIST: Messages from this AuthorId - - -// Status Filtering... should it be a different Option Field. -#define RS_TOKREQOPT_GROUP_UPDATED 0x0100 // GROUPLIST: Groups that have been updated. -#define RS_TOKREQOPT_MSG_UPDATED 0x0200 // MSGLIST: Msg that have been updated from specified groups. -#define RS_TOKREQOPT_MSG_UPDATED 0x0200 // MSGLIST: Msg that have been updated from specified groups. - - - -// Read Status. -#define RS_TOKREQOPT_READ 0x0001 -#define RS_TOKREQOPT_UNREAD 0x0002 - -#define RS_TOKREQ_ANSTYPE_LIST 0x0001 -#define RS_TOKREQ_ANSTYPE_SUMMARY 0x0002 -#define RS_TOKREQ_ANSTYPE_DATA 0x0003 -#define RS_TOKREQ_ANSTYPE_ACK 0x0004 - - - - -class RsTokReqOptions -{ - public: - RsTokReqOptions() - { - mOptions = 0; - mStatusFilter = 0; mStatusMask = 0; - mFlagsFilter = 0; mFlagsMask = 0; - mSubscribeFilter = 0; - mBefore = 0; mAfter = 0; - } - - uint32_t mOptions; - - // Request specific matches with Group / Message Status. - // Should be usable with any Options... applied afterwards. - uint32_t mStatusFilter; - uint32_t mStatusMask; - - // MsgFlags or GroupsFlags, depends on Request. - uint32_t mFlagsFilter; - uint32_t mFlagsMask; - - uint32_t mSubscribeFilter; // Only for Groups. - - // Time range... again applied after Options. - time_t mBefore; - time_t mAfter; -}; - - -/********************************************************* - * Documentation for Groups Definitions. - * - * A Group is defined by: - * - TWO RSA Keys. (Admin Key & Publish Key) - * - Publish TS: Used to select the latest definition. - * - * - Operating Mode: - * - Circle (Public, External, Private). - * - Publish Mode: Encrypted / All-Signed / Only ThreadHead / None Required. - * - AuthorId: GPG Required / Any Required / Only if no Publish Signature. - * - * - Description: - * - Name & Description. - * - Optional AuthorId. - * - * Most of this information is contained inside the GroupMetaData. - * except for Actual Admin / Publish Keys, which are maintained internally. - * - ******* - * - Group Definition must be signed by Admin Key, otherwise invalid. - * - Circle Definition controls distribution of Group and Messages, see section on this for more details. - * - Public parts of Keys are distributed with Definition. - * - Private parts can be distributed to select people via alternative channels. - * - A Message Requires at least one signature: publish or Author. This signature will be used as MsgId. - * - * Groups will operate in the following modes: - * 1) Public Forum: PublishMode = None Required, AuthorId: Required. - * 2) Closed Forum: PublishMode = All-Signed, AuthorId: Required. - * 3) Private Forum: PublishMode = Encrypted, AuthorId: Required. - * - * 4) Anon Channel: PublishMode = All-Signed, AuthorId: None. - * 5) Anon Channel with Comments: PublishMode = Only ThreadHead, AuthorId: If No Publish Signature. - * 6) Private Channel: PublishMode = Encrypted. - * - * 7) Personal Photos - with comments: PublishMode = Only ThreadHead, AuthorId: Required. - * 8) Personal Photos - no comments: PublishMode = All-Signed, AuthorId: Required. - * - * 9 ) Public Wiki: PublishMode = None Required, AuthorId: Required. - * 10) Closed Wiki: PublishMode = All-Signed, AuthorId: Required. - * 11) Private Wiki: PublishMode = Encrypted, AuthorId: Required. - * - * 12) Twitter: PublishMode = Only ThreadHead, AuthorId: Required. - * - * 13) Posted: PublishMode = None Required, AuthorId: Required. - * - * - ****** - * - * Additionally to this information. The MetaData also contains several fields which can - * be used to store local information for the benefit of the service. - * - * In Particular: MsgStatus & GroupStatus inform the service if the user has read the message or if anything has changed. - * - ***/ - - -// Control of Publish Signatures. -#define RSGXS_GROUP_SIGN_PUBLISH_MASK 0x000000ff -#define RSGXS_GROUP_SIGN_PUBLISH_ENCRYPTED 0x00000001 -#define RSGXS_GROUP_SIGN_PUBLISH_ALLSIGNED 0x00000002 -#define RSGXS_GROUP_SIGN_PUBLISH_THREADHEAD 0x00000004 -#define RSGXS_GROUP_SIGN_PUBLISH_NONEREQ 0x00000008 - -// Author Signature. -#define RSGXS_GROUP_SIGN_AUTHOR_MASK 0x0000ff00 -#define RSGXS_GROUP_SIGN_AUTHOR_GPG 0x00000100 -#define RSGXS_GROUP_SIGN_AUTHOR_REQUIRED 0x00000200 -#define RSGXS_GROUP_SIGN_AUTHOR_IFNOPUBSIGN 0x00000400 -#define RSGXS_GROUP_SIGN_AUTHOR_NONE 0x00000800 - -// NB: That one signature is required... -// so some combinations are not possible. e.g. -// SIGN_PUBLISH_NONEREQ && SIGN_AUTHOR_NONE is not allowed. -// SIGN_PUBLISH_THREADHEAD && SIGN_AUTHOR_NONE is also invalid. - -#define RSGXS_GROUP_SIGN_RESERVED_MASK 0xffff0000 - - -// STATUS FLAGS: There is space here for Service specific flags - if they so desire. -// -// Msgs: UNREAD_BY_USER & PROCESSED are useful. -// Groups: NEW_MESSAGES & GROUP_UPDATED. - -#define RSGXS_MSG_STATUS_MASK 0x0000000f -#define RSGXS_MSG_STATUS_READ 0x00000001 // New or Not New -#define RSGXS_MSG_STATUS_UNREAD_BY_USER 0x00000002 -#define RSGXS_MSG_STATUS_UNPROCESSED 0x00000004 // By the Service. - -#define RSGXS_MSG_STATUS_SERVICE_MASK 0xffff0000 - -#define RSGXS_GROUP_STATUS_MASK 0x0000000f -#define RSGXS_GROUP_STATUS_UPDATED 0x00000001 -#define RSGXS_GROUP_STATUS_NEWGROUP 0x00000002 -#define RSGXS_GROUP_STATUS_NEWMSG 0x00000004 - -#define RSGXS_GROUP_STATUS_SERVICE_MASK 0xffff0000 - - - -// Subscription Flags. (LOCAL) -#define RSGXS_GROUP_SUBSCRIBE_MASK 0x0000000f -#define RSGXS_GROUP_SUBSCRIBE_ADMIN 0x00000001 -#define RSGXS_GROUP_SUBSCRIBE_PUBLISH 0x00000002 -#define RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED 0x00000004 -#define RSGXS_GROUP_SUBSCRIBE_MONITOR 0x00000008 - - -// Some MACROS for EASE OF USE. (USED BY FORUMSV2 At the moment. -#define IS_MSG_UNREAD(status) ((status & RSGXS_MSG_STATUS_READ) == 0 || (status & RSGXS_MSG_STATUS_UNREAD_BY_USER)) -#define IS_GROUP_ADMIN(subscribeFlags) (subscribeFlags & RSGXS_GROUP_SUBSCRIBE_ADMIN) -#define IS_GROUP_SUBSCRIBED(subscribeFlags) (subscribeFlags & (RSGXS_GROUP_SUBSCRIBE_ADMIN | RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED)) - - - -#define RSGXS_MAX_SERVICE_STRING 200 // Sensible limit for dbase usage. - -#include "serialiser/rsgxsitems.h" - -//class RsGroupMetaData -//{ -// public: -// -// RsGroupMetaData() -// { -// mGroupFlags = 0; -// mSignFlags = 0; -// mSubscribeFlags = 0; -// -// mPop = 0; -// mMsgCount = 0; -// mLastPost = 0; -// mGroupStatus = 0; -// -// //mPublishTs = 0; -// } -// -// std::string mGroupId; -// std::string mGroupName; -// uint32_t mGroupFlags; // Service Specific Options ???? -// uint32_t mSignFlags; // Combination of RSGXS_GROUP_SIGN_PUBLISH_MASK & RSGXS_GROUP_SIGN_AUTHOR_MASK. -// -// time_t mPublishTs; // Mandatory. -// std::string mAuthorId; // Optional. -// -// // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. -// -// uint32_t mSubscribeFlags; -// -// uint32_t mPop; // HOW DO WE DO THIS NOW. -// uint32_t mMsgCount; // ??? -// time_t mLastPost; // ??? -// -// uint32_t mGroupStatus; -// -// std::string mServiceString; // Service Specific Free-Form extra storage. -//}; -// -// -// -// -//class RsMsgMetaData -//{ -// public: -// -// RsMsgMetaData() -// { -// mPublishTs = 0; -// mMsgFlags = 0; -// mMsgStatus = 0; -// mChildTs = 0; -// } -// -// std::string mGroupId; -// std::string mMsgId; -// -// std::string mThreadId; -// std::string mParentId; -// std::string mOrigMsgId; -// -// std::string mAuthorId; -// -// std::string mMsgName; -// time_t mPublishTs; -// -// uint32_t mMsgFlags; // Whats this for? (Optional Service Specific - e.g. flag MsgType) -// -// // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. -// // normally READ / UNREAD flags. LOCAL Data. -// uint32_t mMsgStatus; -// time_t mChildTs; -// -// std::string mServiceString; // Service Specific Free-Form extra storage. -// -//}; - -std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta); -std::ostream &operator<<(std::ostream &out, const RsMsgMetaData &meta); - -class RsTokenService -{ - public: - - RsTokenService() { return; } -virtual ~RsTokenService() { return; } - - /* changed? */ -virtual bool updated() = 0; - - /* Data Requests */ -virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) = 0; -virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) = 0; -virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds) = 0; - - /* Generic Lists */ -virtual bool getGroupList( const uint32_t &token, std::list &groupIds) = 0; -virtual bool getMsgList( const uint32_t &token, std::list &msgIds) = 0; - - /* Generic Summary */ -virtual bool getGroupSummary( const uint32_t &token, std::list &groupInfo) = 0; -virtual bool getMsgSummary( const uint32_t &token, std::list &msgInfo) = 0; - - /* Actual Data -> specific to Interface */ - - - - /* Poll */ -virtual uint32_t requestStatus(const uint32_t token) = 0; - - /* Cancel Request */ -virtual bool cancelRequest(const uint32_t &token) = 0; - - - ////////////////////////////////////////////////////////////////////////////// - /* Functions from Forums -> need to be implemented generically */ - // Groups Changed is now part of requestGroupInfo request. -//virtual bool groupsChanged(std::list &groupIds) = 0; - - // Message/Group Status - is retrived via requests... - // These operations could have a token, but for the moment we are going to assume - // they are async and always succeed - (or fail silently). -virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask) = 0; -virtual bool setGroupStatus(const std::string &grpId, const uint32_t status, const uint32_t statusMask) = 0; - -virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) = 0; - -virtual bool setMessageServiceString(const std::string &msgId, const std::string &str) = 0; -virtual bool setGroupServiceString(const std::string &grpId, const std::string &str) = 0; - - // (FUTURE WORK). -virtual bool groupRestoreKeys(const std::string &groupId) = 0; -virtual bool groupShareKeys(const std::string &groupId, std::list& peers) = 0; - - - - -}; - - - +#include "rsgxsservice.h" /* The Main Interface Class - for information about your Peers */ class RsIdentity; @@ -391,7 +62,13 @@ class RsIdGroup uint32_t mIdType; - std::string mGpgIdHash; // SHA(KeyId + Gpg Fingerprint) -> can only be IDed if GPG known. + // SHA(KeyId + Gpg Fingerprint) -> can only be IDed if GPG known. + // The length of the input must be long enough to make brute force search implausible. + + // Easy to do 1e9 SHA-1 hash computations per second on a GPU. + // We will need a minimum of 256 bits, ideally 1024 bits or 2048 bits. + + std::string mGpgIdHash; // NOTE: These cannot be transmitted as part of underlying messages.... // Must use ServiceString. @@ -425,6 +102,7 @@ class RsIdMsg std::ostream &operator<<(std::ostream &out, const RsIdGroup &meta); std::ostream &operator<<(std::ostream &out, const RsIdMsg &meta); +typedef std::map > IdMsgResult; #if 0 @@ -456,24 +134,97 @@ class RsIdOpinion #endif -class RsIdentity: public RsTokenService +class RsIdentity: public RsGxsIfaceImpl { - public: - RsIdentity() { return; } -virtual ~RsIdentity() { return; } +public: + + RsIdentity(RsGenExchange *gxs): RsGxsIfaceImpl(gxs) { return; } + virtual ~RsIdentity() { return; } + + /* Specific Service Data */ + + /*! + * @param token token to be redeemed for album request + * @param album the album returned for given request token + * @return false if request token is invalid, check token status for error report + */ +// virtual bool getAlbum(const uint32_t &token, std::vector &album) = 0; + + /*! + * @param token token to be redeemed for photo request + * @param photo the photo returned for given request token + * @return false if request token is invalid, check token status for error report + */ +// virtual bool getPhoto(const uint32_t &token, +// PhotoResult &photo) = 0; + + /* details are updated in album - to choose Album ID, and storage path */ + + /*! + * @param token token to be redeemed for photo request + * @param photo the photo returned for given request token + * @return false if request token is invalid, check token status for error report + */ +// virtual bool getPhotoComment(const uint32_t &token, +// PhotoCommentResult& comments) = 0; + + /*! + * submits album, which returns a token that needs + * to be acknowledge to get album grp id + * @param token token to redeem for acknowledgement + * @param album album to be submitted + */ +// virtual bool submitAlbumDetails(uint32_t& token, RsPhotoAlbum &album) = 0; + + /*! + * submits photo, which returns a token that needs + * to be acknowledged to get photo msg-grp id pair + * @param token token to redeem for acknowledgement + * @param photo photo to be submitted + */ +// virtual bool submitPhoto(uint32_t& token, RsPhotoPhoto &photo) = 0; + + /*! + * submits photo comment, which returns a token that needs + * to be acknowledged to get photo msg-grp id pair + * The mParentId needs to be set to an existing msg for which + * commenting is enabled + * @param token token to redeem for acknowledgement + * @param comment comment to be submitted + */ +// virtual bool submitComment(uint32_t& token, RsPhotoComment &photo) = 0; + +/********************************************************************************************/ +/********************************************************************************************/ +/********************************************************************************************/ +/********************************************************************************************/ +/********************************************************************************************/ + + // For Other Services.... + // It should be impossible for them to get a message which we don't have the identity. + // Its a major error if we don't have the identity. + + // We cache all identities, and provide alternative (instantaneous) + // functions to extract info, rather than the standard Token system. + +virtual bool getNickname(const RsId &id, std::string &nickname) = 0; +virtual bool getIdDetails(const RsId &id, RsIdentityDetails &details) = 0; +virtual bool getOwnIds(std::list &ownIds) = 0; + + // +virtual bool submitOpinion(uint32_t& token, RsIdOpinion &opinion) = 0; +virtual bool createIdentity(uint32_t& token, RsIdentityParameters ¶ms) = 0; - /* INCLUDES INTERFACE FROM RS TOKEN SERVICE */ - ////////////////////////////////////////////////////////////////////////////// - + // Specific RsIdentity Functions.... /* Specific Service Data */ -virtual bool getGroupData(const uint32_t &token, RsIdGroup &group) = 0; -virtual bool getMsgData(const uint32_t &token, RsIdMsg &msg) = 0; +//virtual bool getGroupData(const uint32_t &token, RsIdGroup &group) = 0; +//virtual bool getMsgData(const uint32_t &token, RsIdMsg &msg) = 0; -virtual bool createGroup(uint32_t &token, RsIdGroup &group, bool isNew) = 0; -virtual bool createMsg(uint32_t &token, RsIdMsg &msg, bool isNew) = 0; +//virtual bool createGroup(uint32_t &token, RsIdGroup &group, bool isNew) = 0; +//virtual bool createMsg(uint32_t &token, RsIdMsg &msg, bool isNew) = 0; /* In the Identity System - You don't access the Messages Directly. * as they represent idividuals opinions.... @@ -530,6 +281,4 @@ virtual bool updateOpinion(RsIdOpinion &opinion) = 0; }; - - -#endif +#endif // RETROSHARE_IDENTITY_GUI_INTERFACE_H diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index c995c844b..63e4c7094 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -7,7 +7,7 @@ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. + * License Version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -39,24 +39,7 @@ * */ -class IdDataProxy: public GxsDataProxy -{ - public: - - bool getGroup(const std::string &id, RsIdGroup &group); - bool getMsg(const std::string &id, RsIdMsg &msg); - - bool addGroup(const RsIdGroup &group); - bool addMsg(const RsIdMsg &msg); - - /* These Functions must be overloaded to complete the service */ -virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta); -virtual bool convertMsgToMetaData(void *msgData, RsMsgMetaData &meta); -}; - - - -// INTERNAL DATA TYPES... +// INTERNAL DATA TYPES. // Describes data stored in GroupServiceString. class IdRepCumulScore { @@ -86,60 +69,53 @@ public: #define ID_LOCAL_STATUS_FULL_CALC_FLAG 0x00010000 #define ID_LOCAL_STATUS_INC_CALC_FLAG 0x00020000 -class p3IdService: public p3GxsDataService, public RsIdentity + + +// Not sure exactly what should be inherited here? +// Chris - please correct as necessary. + +class p3IdService: public RsIdentity, public RsGxsIdExchange { public: + p3IdService(RsGeneralDataService* gds, RsNetworkExchangeService* nes); - p3IdService(uint16_t type); - -virtual int tick(); - - public: + virtual int internal_tick(); // needed for background processing. - /* changed? */ -virtual bool updated(); + /* General Interface is provided by RsIdentity / RsGxsIfaceImpl. */ - /* From RsTokenService */ - /* Data Requests */ -virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds); -virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds); -virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds); + /* Data Specific Interface */ - /* Generic Lists */ -virtual bool getGroupList( const uint32_t &token, std::list &groupIds); -virtual bool getMsgList( const uint32_t &token, std::list &msgIds); + /* TODO */ - /* Generic Summary */ -virtual bool getGroupSummary( const uint32_t &token, std::list &groupInfo); -virtual bool getMsgSummary( const uint32_t &token, std::list &msgInfo); - /* Actual Data -> specific to Interface */ -virtual bool getGroupData(const uint32_t &token, RsIdGroup &group); -virtual bool getMsgData(const uint32_t &token, RsIdMsg &msg); + /**************** RsGixs Implementation + * Notes: + * Interface is only suggestion at the moment, will be changed as necessary. + * Results should be cached / preloaded for maximum speed. + * + */ +virtual bool haveKey(const GxsId &id); +virtual bool havePrivateKey(const GxsId &id); +virtual bool requestKey(const GxsId &id, const std::list &peers); +virtual int getKey(const GxsId &id, TlvSecurityKey &key); +virtual int getPrivateKey(const GxsId &id, TlvSecurityKey &key); - /* Poll */ -virtual uint32_t requestStatus(const uint32_t token); - - /* Cancel Request */ -virtual bool cancelRequest(const uint32_t &token); - - ////////////////////////////////////////////////////////////////////////////// -virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask); -virtual bool setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask); -virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask); -virtual bool setMessageServiceString(const std::string &msgId, const std::string &str); -virtual bool setGroupServiceString(const std::string &grpId, const std::string &str); - -virtual bool groupRestoreKeys(const std::string &groupId); -virtual bool groupShareKeys(const std::string &groupId, std::list& peers); - -virtual bool createGroup(uint32_t &token, RsIdGroup &group, bool isNew); -virtual bool createMsg(uint32_t &token, RsIdMsg &msg, bool isNew); + /**************** RsGixsReputation Implementation + * Notes: + * Again should be cached if possible. + */ + // get Reputation. +virtual bool getReputation(const GxsId &id, const GixsReputation &rep); private: +/************************************************************************ + * Below is the background task for processing opinions => reputations + * + */ + virtual void generateDummyData(); std::string genRandomId(); @@ -157,8 +133,6 @@ std::string genRandomId(); bool encodeIdGroupCache(std::string &str, const IdGroupServiceStrData &data); bool extractIdGroupCache(std::string &str, IdGroupServiceStrData &data); - IdDataProxy *mIdProxy; - RsMutex mIdMtx; /***** below here is locked *****/ @@ -170,17 +144,17 @@ std::string genRandomId(); std::map mBgGroupMap; std::list mBgFullCalcGroups; - - - bool mUpdated; -#if 0 - std::map mIds; - std::map > mOpinions; +/************************************************************************ + * Other Data that is protected by the Mutex. + */ - std::map mReputations; // this is created locally. -#endif + std::vector mGroupChange; + std::vector mMsgChange; }; -#endif +#endif // P3_IDENTITY_SERVICE_HEADER + + + From 57407fb8ae091e1d3bf485cda9db8ce6a692c3cc Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Mon, 15 Oct 2012 18:52:47 +0000 Subject: [PATCH 087/222] Added helper function to GXS services to access token management and data store git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5680 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsdataservice.cc | 144 ++++++++++-------- libretroshare/src/gxs/rsdataservice.h | 2 + libretroshare/src/gxs/rsgenexchange.cc | 22 +++ libretroshare/src/gxs/rsgenexchange.h | 42 +++++ libretroshare/src/gxs/rsgxsdataaccess.h | 2 +- libretroshare/src/rsserver/rsinit.cc | 10 +- .../src/services/p3photoserviceV2.cc | 5 + libretroshare/src/services/p3photoserviceV2.h | 5 + 8 files changed, 164 insertions(+), 68 deletions(-) diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index e6178e6ec..46cb3848d 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -128,7 +128,8 @@ const std::string RsGeneralDataService::MSG_META_STATUS = KEY_MSG_STATUS; RsDataService::RsDataService(const std::string &serviceDir, const std::string &dbName, uint16_t serviceType, RsGxsSearchModule *mod) - : RsGeneralDataService(), mServiceDir(serviceDir), mDbName(mServiceDir + "/" + dbName), mServType(serviceType){ + : RsGeneralDataService(), mServiceDir(serviceDir), mDbName(mServiceDir + "/" + dbName), mServType(serviceType), + mDbMutex("RsDataService"){ initialise(); @@ -163,6 +164,8 @@ RsDataService::~RsDataService(){ void RsDataService::initialise(){ + RsStackMutex stack(mDbMutex); + // initialise database mDb = new RetroDb(mDbName, RetroDb::OPEN_READWRITE_CREATE); @@ -417,6 +420,9 @@ RsNxsMsg* RsDataService::getMessage(RetroCursor &c) int RsDataService::storeMessage(std::map &msg) { + + RsStackMutex stack(mDbMutex); + std::map::iterator mit = msg.begin(); // start a transaction @@ -496,6 +502,9 @@ int RsDataService::storeMessage(std::map &msg) int RsDataService::storeGroup(std::map &grp) { + + RsStackMutex stack(mDbMutex); + std::map::iterator sit = grp.begin(); // begin transaction @@ -576,70 +585,72 @@ int RsDataService::storeGroup(std::map &grp) int RsDataService::retrieveNxsGrps(std::map &grp, bool withMeta, bool cache){ - if(grp.empty()){ + if(grp.empty()){ - RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, grpColumns, "", ""); + RsStackMutex stack(mDbMutex); + RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, grpColumns, "", ""); - if(c) - { - std::vector grps; - - retrieveGroups(c, grps); - std::vector::iterator vit = grps.begin(); - - for(; vit != grps.end(); vit++) - { - grp[(*vit)->grpId] = *vit; - } - - delete c; - } - - }else{ - - std::map::iterator mit = grp.begin(); - - for(; mit != grp.end(); mit++) - { - const std::string& grpId = mit->first; - RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, grpColumns, "grpId='" + grpId + "'", ""); - - if(c) - { - std::vector grps; - retrieveGroups(c, grps); - - if(!grps.empty()) - { - RsNxsGrp* ng = grps.front(); - grp[ng->grpId] = ng; - }else{ - grp.erase(grpId); - } - - delete c; - } - } - } - - if(withMeta) + if(c) { - std::map metaMap; - std::map::iterator mit = grp.begin(); - for(; mit != grp.end(); mit++) - metaMap.insert(std::make_pair(mit->first, (RsGxsGrpMetaData*)(NULL))); + std::vector grps; - retrieveGxsGrpMetaData(metaMap); + retrieveGroups(c, grps); + std::vector::iterator vit = grps.begin(); - mit = grp.begin(); - for(; mit != grp.end(); mit++) - { - RsNxsGrp* grpPtr = grp[mit->first]; - grpPtr->metaData = metaMap[mit->first]; - } + for(; vit != grps.end(); vit++) + { + grp[(*vit)->grpId] = *vit; + } + + delete c; } - return 1; + }else{ + + RsStackMutex stack(mDbMutex); + std::map::iterator mit = grp.begin(); + + for(; mit != grp.end(); mit++) + { + const std::string& grpId = mit->first; + RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, grpColumns, "grpId='" + grpId + "'", ""); + + if(c) + { + std::vector grps; + retrieveGroups(c, grps); + + if(!grps.empty()) + { + RsNxsGrp* ng = grps.front(); + grp[ng->grpId] = ng; + }else{ + grp.erase(grpId); + } + + delete c; + } + } + } + + if(withMeta) + { + std::map metaMap; + std::map::iterator mit = grp.begin(); + for(; mit != grp.end(); mit++) + metaMap.insert(std::make_pair(mit->first, (RsGxsGrpMetaData*)(NULL))); + + retrieveGxsGrpMetaData(metaMap); + + mit = grp.begin(); + for(; mit != grp.end(); mit++) + { + RsNxsGrp* grpPtr = grp[mit->first]; + grpPtr->metaData = metaMap[mit->first]; + } + } + + return 1; } void RsDataService::retrieveGroups(RetroCursor* c, std::vector& grps){ @@ -677,6 +688,9 @@ int RsDataService::retrieveNxsMsgs(const GxsMsgReq &reqIds, GxsMsgResult &msg, b std::vector msgSet; if(msgIdV.empty()){ + + RsStackMutex stack(mDbMutex); + RetroCursor* c = mDb->sqlQuery(MSG_TABLE_NAME, msgColumns, KEY_GRP_ID+ "='" + grpId + "'", ""); if(c) @@ -690,6 +704,9 @@ int RsDataService::retrieveNxsMsgs(const GxsMsgReq &reqIds, GxsMsgResult &msg, b for(; sit!=msgIdV.end();sit++){ const std::string& msgId = *sit; + + RsStackMutex stack(mDbMutex); + RetroCursor* c = mDb->sqlQuery(MSG_TABLE_NAME, msgColumns, KEY_GRP_ID+ "='" + grpId + "' AND " + KEY_MSG_ID + "='" + msgId + "'", ""); @@ -721,7 +738,6 @@ int RsDataService::retrieveNxsMsgs(const GxsMsgReq &reqIds, GxsMsgResult &msg, b if(withMeta) { - GxsMsgMetaResult metaResult; // request with meta ids so there is no chance of @@ -791,6 +807,9 @@ void RsDataService::retrieveMessages(RetroCursor *c, std::vector &ms int RsDataService::retrieveGxsMsgMetaData(const GxsMsgReq& reqIds, GxsMsgMetaResult &msgMeta) { + + RsStackMutex stack(mDbMutex); + GxsMsgReq::const_iterator mit = reqIds.begin(); for(; mit != reqIds.end(); mit++) @@ -848,6 +867,7 @@ void RsDataService::retrieveMsgMeta(RetroCursor *c, std::vector& grp) { + RsStackMutex stack(mDbMutex); if(grp.empty()){ @@ -918,6 +938,7 @@ int RsDataService::resetDataStore() std::map::iterator mit = grps.begin(); + // remove all grp msgs files from service dir for(; mit != grps.end(); mit++){ std::string file = mServiceDir + "/" + mit->first; @@ -925,8 +946,11 @@ int RsDataService::resetDataStore() remove(file.c_str()); // remove group file remove(msgFile.c_str()); // and remove messages file } + { + RsStackMutex stack(mDbMutex); + mDb->closeDb(); + } - mDb->closeDb(); remove(mDbName.c_str()); // remove db file // recreate database diff --git a/libretroshare/src/gxs/rsdataservice.h b/libretroshare/src/gxs/rsdataservice.h index bf2496488..4daa24111 100644 --- a/libretroshare/src/gxs/rsdataservice.h +++ b/libretroshare/src/gxs/rsdataservice.h @@ -190,6 +190,8 @@ private: RetroDb* mDb; + RsMutex mDbMutex; + std::list msgColumns; std::list msgMetaColumns; diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 00b0eeb05..f84b2af42 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -688,6 +688,28 @@ void RsGenExchange::publishGrps() mGrpsToPublish.clear(); } + + +uint32_t RsGenExchange::generatePublicToken() +{ + return mDataAccess->generatePublicToken(); +} + +bool RsGenExchange::updatePublicRequestStatus(const uint32_t &token, const uint32_t &status) +{ + return mDataAccess->updatePublicRequestStatus(token, status); +} + +bool RsGenExchange::disposeOfPublicToken(const uint32_t &token) +{ + return mDataAccess->disposeOfPublicToken(token); +} + +RsGeneralDataService* RsGenExchange::getDataStore() +{ + return mDataStore; +} + void RsGenExchange::createDummyGroup(RsGxsGrpItem *grpItem) { diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 7af1c73ad..dc66499d4 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -36,6 +36,7 @@ #include "rsnxsobserver.h" #include "retroshare/rsgxsservice.h" #include "serialiser/rsnxsitems.h" +//#include "rsgixs.h" typedef std::map > GxsMsgDataMap; typedef std::map GxsGroupDataMap; @@ -98,6 +99,12 @@ public: */ void tick(); + /*! + * Any backgroup processing needed by + */ + virtual void service_tick() = 0; + + /*! * * @return handle to token service handle for making @@ -160,6 +167,41 @@ protected: */ void createDummyGroup(RsGxsGrpItem* grpItem); +protected: + + /*! + * Assigns a token value to passed integer + * The status of the token can still be queried from request status feature + * @warning the token space is shared with RsGenExchange backend, so do not + * modify tokens except does you have created by calling generatePublicToken() + * @return token + */ + uint32_t generatePublicToken(); + + /*! + * Updates the status of associate token + * @warning the token space is shared with RsGenExchange backend, so do not + * modify tokens except does you have created by calling generatePublicToken() + * @param token + * @param status + * @return false if token could not be found, true if token disposed of + */ + bool updatePublicRequestStatus(const uint32_t &token, const uint32_t &status); + + /*! + * This gets rid of a publicly issued token + * @param token + * @return false if token could not found, true if token is disposed of + */ + bool disposeOfPublicToken(const uint32_t &token); + + /*! + * This gives access to the data store which hold msgs and groups + * for the service + * @return Data store for retrieving msgs and groups + */ + RsGeneralDataService* getDataStore(); + public: /*! diff --git a/libretroshare/src/gxs/rsgxsdataaccess.h b/libretroshare/src/gxs/rsgxsdataaccess.h index 6642ee6ce..7dca5ac60 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.h +++ b/libretroshare/src/gxs/rsgxsdataaccess.h @@ -254,7 +254,7 @@ public: uint32_t generatePublicToken(); /*! - * Update + * Updates the status of associate token * @param token * @param status * @return false if token could not be found, true if token disposed of diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 366ce9786..a0b0ebcb2 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -2311,11 +2311,7 @@ int RsServer::StartupRetroShare() // Testing New Cache Services. p3WireVEG *mWire = new p3WireVEG(RS_SERVICE_GXSV1_TYPE_WIRE); pqih -> addService(mWire); - - // Testing New Cache Services. - p3IdServiceVEG *mIdentity = new p3IdServiceVEG(RS_SERVICE_GXSV1_TYPE_IDENTITY); - pqih -> addService(mIdentity); - + // Testing New Cache Services. p3ForumsVEG *mForumsV2 = new p3ForumsVEG(RS_SERVICE_GXSV1_TYPE_FORUMS); pqih -> addService(mForumsV2); @@ -2584,8 +2580,8 @@ int RsServer::StartupRetroShare() rsPhotoV2 = mPhotoV2; #ifdef ENABLE_GXS_SERVICES - // Testing of new cache system interfaces. - rsIdentityVEG = mIdentity; + // Testing of new cache system interfaces. + rsWikiVEG = mWikis; rsWireVEG = mWire; rsForumsVEG = mForumsV2; diff --git a/libretroshare/src/services/p3photoserviceV2.cc b/libretroshare/src/services/p3photoserviceV2.cc index 92d7fa2a1..d208d2a2f 100644 --- a/libretroshare/src/services/p3photoserviceV2.cc +++ b/libretroshare/src/services/p3photoserviceV2.cc @@ -105,6 +105,11 @@ bool p3PhotoServiceV2::updated() return changed; } +void p3PhotoServiceV2::service_tick() +{ + +} + void p3PhotoServiceV2::groupsChanged(std::list& grpIds) diff --git a/libretroshare/src/services/p3photoserviceV2.h b/libretroshare/src/services/p3photoserviceV2.h index a4083a714..0401ad4d7 100644 --- a/libretroshare/src/services/p3photoserviceV2.h +++ b/libretroshare/src/services/p3photoserviceV2.h @@ -43,6 +43,11 @@ public: */ bool updated(); + /*! + * + */ + void service_tick(); + protected: void notifyChanges(std::vector& changes); From fed65073208cbee8d72667386ea0749223259015 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Mon, 15 Oct 2012 20:31:56 +0000 Subject: [PATCH 088/222] Implemented helper class RsGxsIfaceImpl Added calling of service_tick in RsGenExchange git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5681 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgenexchange.cc | 2 + libretroshare/src/gxs/rsgenexchange.h | 24 ++++--- libretroshare/src/gxs/rsgxsifaceimpl.cc | 84 +++++++++++++++++++++---- libretroshare/src/gxs/rsgxsifaceimpl.h | 56 ++++++++++++----- 4 files changed, 129 insertions(+), 37 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index f84b2af42..58f9973d1 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -78,6 +78,8 @@ void RsGenExchange::tick() mNotifications.clear(); } + // implemented service tick function + service_tick(); } bool RsGenExchange::acknowledgeTokenMsg(const uint32_t& token, diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index dc66499d4..71a356b5a 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -112,7 +112,7 @@ public: */ RsTokenService* getTokenService(); -protected: +public: /** data access functions **/ @@ -146,6 +146,17 @@ protected: */ bool getMsgMeta(const uint32_t &token, GxsMsgMetaMap &msgInfo); + + + +protected: + + /*! + * @param grpItem + * @deprecated only here to temporarily to testing + */ + void createDummyGroup(RsGxsGrpItem* grpItem); + /*! * retrieves group data associated to a request token * @param token token to be redeemed for grpitem retrieval @@ -160,15 +171,6 @@ protected: */ bool getMsgData(const uint32_t &token, GxsMsgDataMap& msgItems); - - /*! - * @param grpItem - * @deprecated only here to temporarily to testing - */ - void createDummyGroup(RsGxsGrpItem* grpItem); - -protected: - /*! * Assigns a token value to passed integer * The status of the token can still be queried from request status feature @@ -248,6 +250,8 @@ protected: */ void publishMsg(uint32_t& token, RsGxsMsgItem* msgItem); +public: + /*! * sets the group subscribe flag * @param token this is set to token value associated to this request diff --git a/libretroshare/src/gxs/rsgxsifaceimpl.cc b/libretroshare/src/gxs/rsgxsifaceimpl.cc index b9f26dbf8..bfae83f85 100644 --- a/libretroshare/src/gxs/rsgxsifaceimpl.cc +++ b/libretroshare/src/gxs/rsgxsifaceimpl.cc @@ -1,23 +1,78 @@ #include "rsgxsifaceimpl.h" #include "gxs/rsgxs.h" +#include "gxs/rsgxsflags.h" RsGxsIfaceImpl::RsGxsIfaceImpl(RsGenExchange *gxs) - : mGxs(gxs) + : mGxsIfaceMutex("RsGxsIfaceImpl"), mGxs(gxs) { } -void RsGxsIfaceImpl::groupsChanged(std::list& grpIds) +void RsGxsIfaceImpl::groupsChanged(std::list &grpIds) { + RsStackMutex stack(mGxsIfaceMutex); + while(!mGroupChange.empty()) + { + RsGxsGroupChange* gc = mGroupChange.back(); + std::list& gList = gc->grpIdList; + std::list::iterator lit = gList.begin(); + for(; lit != gList.end(); lit++) + grpIds.push_back(*lit); + + mGroupChange.pop_back(); + delete gc; + } } +bool RsGxsIfaceImpl::updated() +{ + RsStackMutex stack(mGxsIfaceMutex); -void RsGxsIfaceImpl::msgsChanged(std::map >& msgs) + bool changed = (!mGroupChange.empty() || !mMsgChange.empty()); + + return changed; +} + +void RsGxsIfaceImpl::msgsChanged(std::map > &msgs) +{ + RsStackMutex stack(mGxsIfaceMutex); + + while(!mMsgChange.empty()) + { + RsGxsMsgChange* mc = mMsgChange.back(); + msgs = mc->msgChangeMap; + mMsgChange.pop_back(); + delete mc; + } +} + +void RsGxsIfaceImpl::receiveChanges(std::vector &changes) { + RsStackMutex stack(mGxsIfaceMutex); + + std::vector::iterator vit = changes.begin(); + + for(; vit != changes.end(); vit++) + { + RsGxsNotify* n = *vit; + RsGxsGroupChange* gc; + RsGxsMsgChange* mc; + if((mc = dynamic_cast(n)) != NULL) + { + mMsgChange.push_back(mc); + } + else if((gc = dynamic_cast(n)) != NULL) + { + mGroupChange.push_back(gc); + } + else + { + delete n; + } + } } RsTokenService* RsGxsIfaceImpl::getTokenService() @@ -29,14 +84,14 @@ bool RsGxsIfaceImpl::getGroupList(const uint32_t &token, std::list &groupIds) { - return false; + return mGxs->getGroupList(token, groupIds); } bool RsGxsIfaceImpl::getMsgList(const uint32_t &token, GxsMsgIdResult& msgIds) { - return false; + return mGxs->getMsgList(token, msgIds); } /* Generic Summary */ @@ -44,31 +99,34 @@ bool RsGxsIfaceImpl::getGroupSummary(const uint32_t &token, std::list &groupInfo) { - return false; + return mGxs->getGroupMeta(token, groupInfo); } bool RsGxsIfaceImpl::getMsgSummary(const uint32_t &token, GxsMsgMetaMap &msgInfo) { - return false; + return mGxs->getMsgMeta(token, msgInfo); } -bool RsGxsIfaceImpl::subscribeToAlbum(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe) +bool RsGxsIfaceImpl::subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe) { + if(subscribe) + mGxs->setGroupSubscribeFlag(token, grpId, GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED); + else + mGxs->setGroupSubscribeFlag(token, grpId, ~GXS_SERV::GROUP_SUBSCRIBE_MASK); - return false; - + return true; } bool RsGxsIfaceImpl::acknowledgeMsg(const uint32_t& token, std::pair& msgId) { - return false; + return mGxs->acknowledgeTokenMsg(token, msgId); } bool RsGxsIfaceImpl::acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId) { - return false; + return mGxs->acknowledgeTokenGrp(token, grpId); } diff --git a/libretroshare/src/gxs/rsgxsifaceimpl.h b/libretroshare/src/gxs/rsgxsifaceimpl.h index d39060b8f..a1236421b 100644 --- a/libretroshare/src/gxs/rsgxsifaceimpl.h +++ b/libretroshare/src/gxs/rsgxsifaceimpl.h @@ -5,43 +5,68 @@ /*! * The simple idea of this class is to implement the simple interface functions - * of gen exchange + * of gen exchange. + * This class provides convenience implementations of: + * - Handle msg and group changes (client class must pass changes sent by RsGenExchange to it) + * - subscription to groups + * - retrieval of msgs and group ids and meta info */ class RsGxsIfaceImpl { public: + /*! + * + * @param gxs handle to RsGenExchange instance of service (Usually the service class itself) + */ RsGxsIfaceImpl(RsGenExchange* gxs); + /*! + * Gxs services should call this for automatic handling of + * changes, send + * @param changes + */ + void receiveChanges(std::vector& changes); /*! - * @return true if a change has occured + * Checks to see if a change has been received for + * for a message or group + * @return true if a change has occured for msg or group */ - bool updated(); + virtual bool updated(); public: - /** Requests **/ - /*! - * + * The groups changed. \n + * class can reimplement to use to tailor + * the group actually set for ui notification. + * If receivedChanges is not passed RsGxsNotify changes + * this function does nothing * @param grpIds */ - void groupsChanged(std::list& grpIds); + virtual void groupsChanged(std::list& grpIds); /*! - * + * The msg changed. \n + * class can reimplement to use to tailor + * the msg actually set for ui notification. + * If receivedChanges is not passed RsGxsNotify changes + * this function does nothing * @param msgs */ - void msgsChanged(std::map >& msgs); + /*! + * @return handle to token service for this GXS service + */ RsTokenService* getTokenService(); /* Generic Lists */ /*! - * + * Retrieve list of group ids associated to a request token * @param token token to be redeemed for this request * @param groupIds the ids return for given request token * @return false if request token is invalid, check token status for error report @@ -50,6 +75,7 @@ public: std::list &groupIds); /*! + * Retrieves list of msg ids associated to a request token * @param token token to be redeemed for this request * @param msgIds the ids return for given request token * @return false if request token is invalid, check token status for error report @@ -57,8 +83,6 @@ public: bool getMsgList(const uint32_t &token, GxsMsgIdResult& msgIds); - /* Generic Summary */ - /*! * @param token token to be redeemed for group summary request * @param groupInfo the ids returned for given request token @@ -81,7 +105,7 @@ public: * @param token token to redeem for acknowledgement * @param grpId the id of the group to subscribe to */ - virtual bool subscribeToAlbum(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe); + virtual bool subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe); /*! * This allows the client service to acknowledge that their msgs has @@ -102,10 +126,14 @@ public: bool acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId); - private: RsGenExchange* mGxs; + + std::vector mGroupChange; + std::vector mMsgChange; + + RsMutex mGxsIfaceMutex; }; #endif // RSGXSIFACEIMPL_H From 35bff312a7e3c5c8244b2a0d2e9e99c2df128663 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Wed, 17 Oct 2012 21:20:57 +0000 Subject: [PATCH 089/222] added rsposteditem serialiser and serialisable items for posted data types git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5688 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgxsifaceimpl.cc | 26 + libretroshare/src/gxs/rsgxsifaceimpl.h | 25 + libretroshare/src/serialiser/rsphotov2items.h | 1 - libretroshare/src/serialiser/rsposteditems.cc | 653 ++++++++++++++++++ libretroshare/src/serialiser/rsposteditems.h | 101 +++ libretroshare/src/services/p3posted.cc | 3 +- 6 files changed, 806 insertions(+), 3 deletions(-) create mode 100644 libretroshare/src/serialiser/rsposteditems.cc create mode 100644 libretroshare/src/serialiser/rsposteditems.h diff --git a/libretroshare/src/gxs/rsgxsifaceimpl.cc b/libretroshare/src/gxs/rsgxsifaceimpl.cc index bfae83f85..3a488cbef 100644 --- a/libretroshare/src/gxs/rsgxsifaceimpl.cc +++ b/libretroshare/src/gxs/rsgxsifaceimpl.cc @@ -1,3 +1,29 @@ + +/* + * libretroshare/src/gxs/rsgxsifaceimpl.cc: rsgxsifaceimpl.cc + * + * RetroShare GXS. + * + * Copyright 2012 by Christopher Evi-Parker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + #include "rsgxsifaceimpl.h" #include "gxs/rsgxs.h" #include "gxs/rsgxsflags.h" diff --git a/libretroshare/src/gxs/rsgxsifaceimpl.h b/libretroshare/src/gxs/rsgxsifaceimpl.h index a1236421b..df105cd91 100644 --- a/libretroshare/src/gxs/rsgxsifaceimpl.h +++ b/libretroshare/src/gxs/rsgxsifaceimpl.h @@ -1,6 +1,31 @@ #ifndef RSGXSIFACEIMPL_H #define RSGXSIFACEIMPL_H +/* + * libretroshare/src/gxs/: rsgxsifaceimpl.h + * + * RetroShare GXS. Convenience interface implementation + * + * Copyright 2012 by Christopher Evi-Parker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + #include "gxs/rsgenexchange.h" /*! diff --git a/libretroshare/src/serialiser/rsphotov2items.h b/libretroshare/src/serialiser/rsphotov2items.h index c636ab5bc..54cb76a07 100644 --- a/libretroshare/src/serialiser/rsphotov2items.h +++ b/libretroshare/src/serialiser/rsphotov2items.h @@ -33,7 +33,6 @@ #include "serialiser/rstlvtypes.h" #include "rsgxsitems.h" -//#include "rsphotoitems.h" #include "retroshare/rsphotoV2.h" const uint8_t RS_PKT_SUBTYPE_PHOTO_ITEM = 0x02; diff --git a/libretroshare/src/serialiser/rsposteditems.cc b/libretroshare/src/serialiser/rsposteditems.cc new file mode 100644 index 000000000..ce0f71bab --- /dev/null +++ b/libretroshare/src/serialiser/rsposteditems.cc @@ -0,0 +1,653 @@ + +/* + * libretroshare/src/gxs: rsopsteditems.cc + * + * RetroShare Serialiser. + * + * Copyright 2012 by Christopher Evi-Parker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "serialiser/rsposteditems.h" + + +uint32_t RsGxsPostedSerialiser::size(RsItem *item) +{ + RsGxsPostedPostItem* ppItem = NULL; + RsGxsPostedCommentItem* pcItem = NULL; + RsGxsPostedVoteItem* pvItem = NULL; + RsGxsPostedGroupItem* pgItem = NULL; + + if((ppItem = dynamic_cast(item)) != NULL) + { + return sizeGxsPostedPostItem(ppItem); + } + else if((pcItem = dynamic_cast(item)) != NULL) + { + return sizeGxsPostedCommentItem(pcItem); + }else if((pvItem = dynamic_cast(item)) != NULL) + { + return sizeGxsPostedVoteItem(pvItem); + }else if((pgItem = dynamic_cast(item)) != NULL) + { + return sizeGxsPostedGroupItem(pgItem); + } + else + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::size() Failed" << std::endl; +#endif + return NULL; + } +} + +bool RsGxsPostedSerialiser::serialise(RsItem *item, void *data, uint32_t *size) +{ + + RsGxsPostedPostItem* ppItem = NULL; + RsGxsPostedCommentItem* pcItem = NULL; + RsGxsPostedVoteItem* pvItem = NULL; + RsGxsPostedGroupItem* pgItem = NULL; + + if((ppItem = dynamic_cast(item)) != NULL) + { + return serialiseGxsPostedPostItem(ppItem, data, size); + } + else if((pcItem = dynamic_cast(item)) != NULL) + { + return serialiseGxsPostedCommentItem(pcItem, data, size); + }else if((pvItem = dynamic_cast(item)) != NULL) + { + return serialiseGxsPostedVoteItem(pvItem, data, size); + }else if((pgItem = dynamic_cast(item)) != NULL) + { + return serialiseGxsPostedGroupItem(pgItem, data, size); + } + else + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::serialise() FAILED" << std::endl; +#endif + return false; + } +} + +RsItem* RsGxsPostedSerialiser::deserialise(void *data, uint32_t *size) +{ +#ifdef RSSERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialise()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_POSTED != getRsItemService(rstype))) + { + return NULL; /* wrong type */ + } + + switch(getRsItemSubType(rstype)) + { + + case RS_PKT_SUBTYPE_POSTED_COMMENT_ITEM: + return deserialiseGxsPostedCommentItem(data, size); + case RS_PKT_SUBTYPE_POSTED_GRP_ITEM: + return deserialiseGxsPostedGroupItem(data, size); + case RS_PKT_SUBTYPE_POSTED_POST_ITEM: + return deserialiseGxsPostedPostItem(data, size); + case RS_PKT_SUBTYPE_POSTED_VOTE_ITEM: + return deserialiseGxsPostedVoteItem(data, size); + default: + { +#ifdef RS_SSERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialise(): subtype could not be dealt with" + << std::endl; +#endif + break; + } + } + return NULL; +} + + +uint32_t RsGxsPostedSerialiser::sizeGxsPostedPostItem(RsGxsPostedPostItem* item) +{ + RsPostedPost& p = item->mPost; + + uint32_t s = 8; + + s += GetTlvStringSize(p.mLink); + s += GetTlvStringSize(p.mNotes); + + return s; +} + +uint32_t RsGxsPostedSerialiser::sizeGxsPostedCommentItem(RsGxsPostedCommentItem* item) +{ + RsPostedComment& c = item->mComment; + + uint32_t s = 8; + + s += GetTlvStringSize(c.mComment); + + return s; +} + +uint32_t RsGxsPostedSerialiser::sizeGxsPostedVoteItem(RsGxsPostedVoteItem* item) +{ + RsPostedVote& v = item->mVote; + + uint32_t s = 8; + + return s; +} + +uint32_t RsGxsPostedSerialiser::sizeGxsPostedGroupItem(RsGxsPostedGroupItem* item) +{ + RsPostedGroup& g = item->mGroup; + + uint32_t s = 8; + return s; +} + +bool RsGxsPostedSerialiser::serialiseGxsPostedPostItem(RsGxsPostedPostItem* item, void* data, uint32_t *size) +{ + +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedPostItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsPostedPostItem(item); + uint32_t offset = 0; + + if(*size < tlvsize){ +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedPostItem()()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsPhotoAlbumItem */ + + ok &= SetTlvString(data, tlvsize, &offset, 1, item->mPost.mNotes); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->mPost.mLink); + + + if(offset != tlvsize) + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedPostItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef GXS_POSTED_SERIAL_DEBUG + if (!ok) + { + std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedPostItem() NOK" << std::endl; + } +#endif + + return ok; +} + +bool RsGxsPostedSerialiser::serialiseGxsPostedCommentItem(RsGxsPostedCommentItem* item, void* data, uint32_t *size) +{ +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedCommentItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsPostedCommentItem(item); + uint32_t offset = 0; + + if(*size < tlvsize){ +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedCommentItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsPhotoAlbumItem */ + + ok &= SetTlvString(data, tlvsize, &offset, 1, item->mComment.mComment); + + + if(offset != tlvsize) + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedCommentItem()() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef GXS_POSTED_SERIAL_DEBUG + if (!ok) + { + std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedCommentItem()() NOK" << std::endl; + } +#endif + + return ok; +} + +bool RsGxsPostedSerialiser::serialiseGxsPostedVoteItem(RsGxsPostedVoteItem* item, void* data, uint32_t *size) +{ + +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedVoteItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsPostedVoteItem(item); + uint32_t offset = 0; + + if(*size < tlvsize){ +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedVoteItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsPhotoAlbumItem */ + + if(offset != tlvsize) + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedVoteItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef GXS_POSTED_SERIAL_DEBUG + if (!ok) + { + std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedVoteItem() NOK" << std::endl; + } +#endif + + return ok; +} + +bool RsGxsPostedSerialiser::serialiseGxsPostedGroupItem(RsGxsPostedGroupItem* item, void* data, uint32_t *size) +{ + +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedGroupItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsPostedGroupItem(item); + uint32_t offset = 0; + + if(*size < tlvsize){ +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedGroupItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsPhotoAlbumItem */ + + if(offset != tlvsize) + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedGroupItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef GXS_POSTED_SERIAL_DEBUG + if (!ok) + { + std::cerr << "RsGxsPostedSerialiser::serialiseGxsPostedGroupItem() NOK" << std::endl; + } +#endif + + return ok; +} + +RsGxsPostedPostItem* RsGxsPostedSerialiser::deserialiseGxsPostedPostItem(void *data, uint32_t *size) +{ + +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedPostItem()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_POSTED != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_POSTED_POST_ITEM != getRsItemSubType(rstype))) + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedPostItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedPostItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsPostedPostItem* item = new RsGxsPostedPostItem(); + /* skip the header */ + offset += 8; + + + ok &= GetTlvString(data, rssize, &offset, 1, item->mPost.mLink); + ok &= GetTlvString(data, rssize, &offset, 1, item->mPost.mNotes); + + if (offset != rssize) + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedPostItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedPostItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + +RsGxsPostedCommentItem* RsGxsPostedSerialiser::deserialiseGxsPostedCommentItem(void *data, uint32_t *size) +{ +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedCommentItem()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_POSTED != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_POSTED_POST_ITEM != getRsItemSubType(rstype))) + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedCommentItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedCommentItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsPostedCommentItem* item = new RsGxsPostedCommentItem(); + /* skip the header */ + offset += 8; + + + ok &= GetTlvString(data, rssize, &offset, 1, item->mComment.mComment); + + if (offset != rssize) + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedCommentItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedCommentItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + +RsGxsPostedVoteItem* RsGxsPostedSerialiser::deserialiseGxsPostedVoteItem(void *data, uint32_t *size) +{ + +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedVoteItem()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_POSTED != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_POSTED_VOTE_ITEM != getRsItemSubType(rstype))) + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedVoteItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedVoteItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsPostedVoteItem* item = new RsGxsPostedVoteItem(); + /* skip the header */ + offset += 8; + + if (offset != rssize) + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedVoteItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedVoteItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + +RsGxsPostedGroupItem* RsGxsPostedSerialiser::deserialiseGxsPostedGroupItem(void *data, uint32_t *size) +{ + +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedGroupItem()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_POSTED != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_POSTED_VOTE_ITEM != getRsItemSubType(rstype))) + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedGroupItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedGroupItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsPostedGroupItem* item = new RsGxsPostedGroupItem(); + /* skip the header */ + offset += 8; + + if (offset != rssize) + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedGroupItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef GXS_POSTED_SERIAL_DEBUG + std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedGroupItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + + +void RsGxsPostedPostItem::clear() +{ + +} + +std::ostream & RsGxsPostedPostItem::print(std::ostream &out, uint16_t indent) +{ + return out; +} + +void RsGxsPostedVoteItem::clear() +{ + return; +} + +std::ostream & RsGxsPostedVoteItem::print(std::ostream &out, uint16_t indent) +{ + return out; +} + +void RsGxsPostedCommentItem::clear() +{ + return; +} + +std::ostream & RsGxsPostedCommentItem::print(std::ostream &out, uint16_t indent) +{ + return out; +} + +void RsGxsPostedGroupItem::clear() +{ + return; +} + +std::ostream & RsGxsPostedGroupItem::print(std::ostream &out, uint16_t indent) +{ + return out; + +} diff --git a/libretroshare/src/serialiser/rsposteditems.h b/libretroshare/src/serialiser/rsposteditems.h new file mode 100644 index 000000000..7ff748c44 --- /dev/null +++ b/libretroshare/src/serialiser/rsposteditems.h @@ -0,0 +1,101 @@ +#ifndef RSPOSTEDITEMS_H +#define RSPOSTEDITEMS_H + +#include "serialiser/rsserviceids.h" +#include "serialiser/rsserial.h" +#include "serialiser/rstlvtypes.h" + +#include "rsgxsitems.h" +#include "retroshare/rsposted.h" + +const uint8_t RS_PKT_SUBTYPE_POSTED_GRP_ITEM = 0x02; +const uint8_t RS_PKT_SUBTYPE_POSTED_POST_ITEM = 0x03; +const uint8_t RS_PKT_SUBTYPE_POSTED_VOTE_ITEM = 0x04; +const uint8_t RS_PKT_SUBTYPE_POSTED_COMMENT_ITEM = 0x05; + +class RsGxsPostedPostItem : public RsGxsMsgItem +{ +public: + RsGxsPostedPostItem() : RsGxsMsgItem(RS_SERVICE_GXSV1_TYPE_POSTED, + RS_PKT_SUBTYPE_POSTED_POST_ITEM) + {return ; } + + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + RsPostedPost mPost; +}; + +class RsGxsPostedVoteItem : public RsGxsMsgItem +{ +public: + RsGxsPostedVoteItem() : RsGxsMsgItem(RS_SERVICE_GXSV1_TYPE_POSTED, + RS_PKT_SUBTYPE_POSTED_VOTE_ITEM) + {return ;} + + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + RsPostedVote mVote; +}; + +class RsGxsPostedCommentItem : public RsGxsMsgItem +{ +public: + RsGxsPostedCommentItem() : RsGxsMsgItem(RS_SERVICE_GXSV1_TYPE_POSTED, + RS_PKT_SUBTYPE_POSTED_COMMENT_ITEM) + { return; } + + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + RsPostedComment mComment; +}; + +class RsGxsPostedGroupItem : public RsGxsGrpItem +{ +public: + RsGxsPostedGroupItem() : RsGxsGrpItem(RS_SERVICE_GXSV1_TYPE_POSTED, + RS_PKT_SUBTYPE_POSTED_GRP_ITEM) + { return; } + + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + RsPostedGroup mGroup; +}; + +class RsGxsPostedSerialiser : public RsSerialType +{ + + RsGxsPostedSerialiser() + : RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXSV1_TYPE_PHOTO) + { return; } + + virtual ~RsGxsPostedSerialiser() { return; } + + uint32_t size(RsItem *item); + bool serialise(RsItem *item, void *data, uint32_t *size); + RsItem* deserialise(void *data, uint32_t *size); + +private: + + uint32_t sizeGxsPostedPostItem(RsGxsPostedPostItem* item); + bool serialiseGxsPostedPostItem(RsGxsPostedPostItem* item, void* data, uint32_t *size); + RsGxsPostedPostItem* deserialiseGxsPostedPostItem(void *data, uint32_t *size); + + uint32_t sizeGxsPostedCommentItem(RsGxsPostedCommentItem* item); + bool serialiseGxsPostedCommentItem(RsGxsPostedCommentItem* item, void* data, uint32_t *size); + RsGxsPostedCommentItem* deserialiseGxsPostedCommentItem(void *data, uint32_t *size); + + uint32_t sizeGxsPostedVoteItem(RsGxsPostedVoteItem* item); + bool serialiseGxsPostedVoteItem(RsGxsPostedVoteItem* item, void* data, uint32_t *size); + RsGxsPostedVoteItem* deserialiseGxsPostedVoteItem(void *data, uint32_t *size); + + uint32_t sizeGxsPostedGroupItem(RsGxsPostedGroupItem* item); + bool serialiseGxsPostedGroupItem(RsGxsPostedGroupItem* item, void* data, uint32_t *size); + RsGxsPostedGroupItem* deserialiseGxsPostedGroupItem(void *data, uint32_t *size); +}; + + +#endif // RSPOSTEDITEMS_H diff --git a/libretroshare/src/services/p3posted.cc b/libretroshare/src/services/p3posted.cc index 45e13f5fc..a0fc2e91f 100644 --- a/libretroshare/src/services/p3posted.cc +++ b/libretroshare/src/services/p3posted.cc @@ -7,8 +7,7 @@ p3Posted::p3Posted(RsGeneralDataService *gds, RsNetworkExchangeService *nes) void p3Posted::notifyChanges(std::vector &changes) { - - + receiveChanges(changes); } bool p3Posted::getGroup(const uint32_t &token, RsPostedGroup &group) From c5d750c0eac99b789f631450e88739c3bfab1fe3 Mon Sep 17 00:00:00 2001 From: drbob Date: Thu, 18 Oct 2012 00:28:54 +0000 Subject: [PATCH 090/222] Basic code change over from VEG => Real GXS service. Still doesn't compile yet, mainly headers and the like to fix. NB: Interface Mismatch between RsGenExchange (vector) and individual result for getGroupData() / getMsgData() git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5689 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/services/p3idservice.cc | 720 +++++----------------- libretroshare/src/services/p3idservice.h | 14 + 2 files changed, 154 insertions(+), 580 deletions(-) diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 1dc8bc3c0..db64f3294 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -46,6 +46,13 @@ RsIdentity *rsIdentity = NULL; /******************* Startup / Tick ******************************************/ /********************************************************************************/ +p3IdService::p3IdService(RsGeneralDataService *gds, RsNetworkExchangeService *nes) + : RsIdentity(this), RsGenExchange(gds, nes, NULL, RS_SERVICE_GXSV1_TYPE_IDENTITY), + mIdMtx("p3IdService") +{ + +} + p3IdService::p3IdService(uint16_t type) :p3GxsDataService(type, new IdDataProxy()), mIdMtx("p3IdService"), mUpdated(true) { @@ -55,348 +62,191 @@ p3IdService::p3IdService(uint16_t type) return; } - -int p3IdService::tick() +int p3IdService::internal_tick() { - std::cerr << "p3IdService::tick()"; + std::cerr << "p3IdService::internal_tick()"; std::cerr << std::endl; - fakeprocessrequests(); // Disable for now. // background_tick(); return 0; } -bool p3IdService::updated() -{ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - if (mUpdated) - { - mUpdated = false; - return true; - } +/********************************************************************************/ +/******************* RsIdentity Interface ***************************************/ +/********************************************************************************/ + +bool p3IdService:: getNickname(const RsId &id, std::string &nickname) +{ + return false; +} + +bool p3IdService:: getIdDetails(const RsId &id, RsIdentityDetails &details) +{ + return false; +} + +bool p3IdService:: getOwnIds(std::list &ownIds) +{ return false; } - - /* Data Requests */ -bool p3IdService::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) +// +bool p3IdService::submitOpinion(uint32_t& token, RsIdOpinion &opinion) { - generateToken(token); - std::cerr << "p3IdService::requestGroupInfo() gets Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); - - return true; + return false; } -bool p3IdService::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) +bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) { - generateToken(token); - std::cerr << "p3IdService::requestMsgInfo() gets Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds); - - return true; -} - -bool p3IdService::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &msgIds) -{ - generateToken(token); - std::cerr << "p3IdService::requestMsgRelatedInfo() gets Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); - - return true; -} - - /* Generic Lists */ -bool p3IdService::getGroupList( const uint32_t &token, std::list &groupIds) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_LIST) - { - std::cerr << "p3IdService::getGroupList() ERROR AnsType Wrong" << std::endl; - return false; - } - - if (reqtype != GXS_REQUEST_TYPE_GROUPS) - { - std::cerr << "p3IdService::getGroupList() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3IdService::getGroupList() ERROR Status Incomplete" << std::endl; - return false; - } - - bool ans = loadRequestOutList(token, groupIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - return ans; + return false; } +/********************************************************************************/ +/******************* RsGixs Interface ***************************************/ +/********************************************************************************/ - -bool p3IdService::getMsgList( const uint32_t &token, std::list &msgIds) +bool p3IdService::haveKey(const GxsId &id) { - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); + return false; +} - if (anstype != RS_TOKREQ_ANSTYPE_LIST) - { - std::cerr << "p3IdService::getMsgList() ERROR AnsType Wrong" << std::endl; - return false; - } - - if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) - { - std::cerr << "p3IdService::getMsgList() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3IdService::getMsgList() ERROR Status Incomplete" << std::endl; - return false; - } +bool p3IdService::havePrivateKey(const GxsId &id) +{ + return false; +} - bool ans = loadRequestOutList(token, msgIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); +bool p3IdService::requestKey(const GxsId &id, const std::list &peers) +{ + return false; +} - return ans; +int p3IdService::getKey(const GxsId &id, TlvSecurityKey &key) +{ + return -1; +} + +int p3IdService::getPrivateKey(const GxsId &id, TlvSecurityKey &key) +{ + return -1; } - /* Generic Summary */ -bool p3IdService::getGroupSummary( const uint32_t &token, std::list &groupInfo) +/********************************************************************************/ +/******************* RsGixsReputation ***************************************/ +/********************************************************************************/ + +bool p3IdService::getReputation(const GxsId &id, const GixsReputation &rep) { - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY) - { - std::cerr << "p3IdService::getGroupSummary() ERROR AnsType Wrong" << std::endl; - return false; - } - - if (reqtype != GXS_REQUEST_TYPE_GROUPS) - { - std::cerr << "p3IdService::getGroupSummary() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3IdService::getGroupSummary() ERROR Status Incomplete" << std::endl; - return false; - } - - std::list groupIds; - bool ans = loadRequestOutList(token, groupIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - /* convert to RsGroupMetaData */ - mProxy->getGroupSummary(groupIds, groupInfo); - - return ans; -} - -bool p3IdService::getMsgSummary( const uint32_t &token, std::list &msgInfo) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY) - { - std::cerr << "p3IdService::getMsgSummary() ERROR AnsType Wrong" << std::endl; - return false; - } - - if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) - { - std::cerr << "p3IdService::getMsgSummary() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3IdService::getMsgSummary() ERROR Status Incomplete" << std::endl; - return false; - } - - std::list msgIds; - bool ans = loadRequestOutList(token, msgIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - /* convert to RsMsgMetaData */ - mProxy->getMsgSummary(msgIds, msgInfo); - - return ans; + return false; } - /* Specific Service Data */ +/********************************************************************************/ +/******************* Get/Set Data ******************************************/ +/********************************************************************************/ + bool p3IdService::getGroupData(const uint32_t &token, RsIdGroup &group) { - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_DATA) - { - std::cerr << "p3IdService::getGroupData() ERROR AnsType Wrong" << std::endl; - return false; - } - - if (reqtype != GXS_REQUEST_TYPE_GROUPS) - { - std::cerr << "p3IdService::getGroupData() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3IdService::getGroupData() ERROR Status Incomplete" << std::endl; - return false; - } - - std::string id; - if (!popRequestOutList(token, id)) - { - /* finished */ - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - return false; - } - - /* convert to RsIdGroup */ - bool ans = mIdProxy->getGroup(id, group); - return ans; +// MISMATCH BETWEEN RsGenExchange (vector) and individual result here. +#if 0 + std::vector grpData; + bool ok = RsGenExchange::getGroupData(token, grpData); + + if(ok) + { + std::vector::iterator vit = grpData.begin(); + + for(; vit != grpData.end(); vit++) + { + RsGxsIdGroupItem* item = dynamic_cast(*vit); + RsIdGroup group = item->group; + group.mMeta = item->meta + groups.push_back(group); + } + } + + return ok; +#endif + return false; } bool p3IdService::getMsgData(const uint32_t &token, RsIdMsg &msg) { - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_DATA) +// MISMATCH BETWEEN RsGenExchange (vector) and individual result here. +#if 0 + GxsMsgDataMap msgData; + bool ok = RsGenExchange::getMsgData(token, msgData); + + if(ok) { - std::cerr << "p3IdService::getMsgData() ERROR AnsType Wrong" << std::endl; - return false; + GxsMsgDataMap::iterator mit = msgData.begin(); + + for(; mit != msgData.end(); mit++) + { + RsGxsGroupId grpId = mit->first; + std::vector& msgItems = mit->second; + std::vector::iterator vit = msgItems.begin(); + + for(; vit != msgItems.end(); vit++) + { + RsGxsIdMsgItem* item = dynamic_cast(*vit); + + if(item) + { + RsIdMsg msg = item->msg; + msg.mMeta = item->meta; + msgs[grpId].push_back(msg); + delete item; + } + else + { + std::cerr << "Not a IdMsg Item, deleting!" << std::endl; + delete *vit; + } + } + } } - - if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) - { - std::cerr << "p3IdService::getMsgData() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3IdService::getMsgData() ERROR Status Incomplete" << std::endl; - return false; - } - - std::string id; - if (!popRequestOutList(token, id)) - { - /* finished */ - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - return false; - } - - /* convert to RsIdMsg */ - bool ans = mIdProxy->getMsg(id, msg); - return ans; -} - - - - /* Poll */ -uint32_t p3IdService::requestStatus(const uint32_t token) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - return status; -} - - - /* Cancel Request */ -bool p3IdService::cancelRequest(const uint32_t &token) -{ - return clearRequest(token); -} - - ////////////////////////////////////////////////////////////////////////////// -bool p3IdService::setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask) -{ - return mIdProxy->setMessageStatus(msgId, status, statusMask); -} - -bool p3IdService::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask) -{ - return mIdProxy->setGroupStatus(groupId, status, statusMask); -} - -bool p3IdService::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) -{ - return mIdProxy->setGroupSubscribeFlags(groupId, subscribeFlags, subscribeMask); -} - -bool p3IdService::setMessageServiceString(const std::string &msgId, const std::string &str) -{ - return mIdProxy->setMessageServiceString(msgId, str); -} - -bool p3IdService::setGroupServiceString(const std::string &grpId, const std::string &str) -{ - return mIdProxy->setGroupServiceString(grpId, str); -} - - -bool p3IdService::groupRestoreKeys(const std::string &groupId) -{ + return ok; +#endif return false; } -bool p3IdService::groupShareKeys(const std::string &groupId, std::list& peers) +/********************************************************************************/ +/********************************************************************************/ +/********************************************************************************/ + +bool p3IdService::createGroup(uint32_t& token, RsIdGroup &group) { - return false; + RsGxsIdGroupItem* item = new RsGxsIdGroupItem(); + item->group = group; + item->meta = group.mMeta; + RsGenExchange::publishGroup(token, item); + return true; } +bool p3IdService::createMsg(uint32_t& token, RsIdMsg &msg) +{ + RsGxsIdMsgItem* item = new RsGxsIdMsgItem(); + item->msg = msg; + item->meta = msg.mMeta; + RsGenExchange::publishMsg(token, item); + return true; +} -/********************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ - std::string p3IdService::genRandomId() { std::string randomId; @@ -408,296 +258,6 @@ std::string p3IdService::genRandomId() return randomId; } -bool p3IdService::createGroup(uint32_t &token, RsIdGroup &group, bool isNew) -{ - if (group.mMeta.mGroupId.empty()) - { - /* new photo */ - - /* generate a temp id */ - group.mMeta.mGroupId = genRandomId(); - } - else - { - std::cerr << "p3IdService::createGroup() Group with existing Id... dropping"; - std::cerr << std::endl; - return false; - } - - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - mUpdated = true; - mIdProxy->addGroup(group); - } - - // Fake a request to return the GroupMetaData. - generateToken(token); - uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptions opts; // NULL is good. - std::list groupIds; - groupIds.push_back(group.mMeta.mGroupId); // It will just return this one. - - std::cerr << "p3IdService::createGroup() Generating Request Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); - - - return true; -} - - - - -bool p3IdService::createMsg(uint32_t &token, RsIdMsg &msg, bool isNew) -{ - if (msg.mMeta.mGroupId.empty()) - { - /* new photo */ - std::cerr << "p3IdService::createMsg() Missing MsgID"; - std::cerr << std::endl; - return false; - } - - /* check if its a mod or new msg */ - if (msg.mMeta.mOrigMsgId.empty()) - { - std::cerr << "p3IdService::createMsg() New Msg"; - std::cerr << std::endl; - - /* new msg, generate a new OrigMsgId */ - msg.mMeta.mOrigMsgId = genRandomId(); - msg.mMeta.mMsgId = msg.mMeta.mOrigMsgId; - } - else - { - std::cerr << "p3IdService::createMsg() Modified Msg"; - std::cerr << std::endl; - - /* mod msg, keep orig msg id, generate a new MsgId */ - msg.mMeta.mMsgId = genRandomId(); - } - - std::cerr << "p3IdService::createMsg() GroupId: " << msg.mMeta.mGroupId; - std::cerr << std::endl; - std::cerr << "p3IdService::createMsg() MsgId: " << msg.mMeta.mMsgId; - std::cerr << std::endl; - std::cerr << "p3IdService::createMsg() OrigMsgId: " << msg.mMeta.mOrigMsgId; - std::cerr << std::endl; - - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - mUpdated = true; - mIdProxy->addMsg(msg); - } - - // Fake a request to return the MsgMetaData. - generateToken(token); - uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptions opts; // NULL is good. - std::list msgIds; - msgIds.push_back(msg.mMeta.mMsgId); // It will just return this one. - - std::cerr << "p3IdService::createMsg() Generating Request Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); - - return true; -} - - - -/********************************************************************************************/ - - - -bool IdDataProxy::getGroup(const std::string &id, RsIdGroup &group) -{ - void *groupData = NULL; - RsGroupMetaData meta; - if (getGroupData(id, groupData) && getGroupSummary(id, meta)) - { - RsIdGroup *pG = (RsIdGroup *) groupData; - group = *pG; - - // update definitive version of the metadata. - group.mMeta = meta; - - std::cerr << "IdDataProxy::getGroup() Id: " << id; - std::cerr << " MetaData: " << meta << " DataPointer: " << groupData; - std::cerr << std::endl; - return true; - } - - std::cerr << "IdDataProxy::getGroup() FAILED Id: " << id; - std::cerr << std::endl; - - return false; -} - -bool IdDataProxy::getMsg(const std::string &id, RsIdMsg &msg) -{ - void *msgData = NULL; - RsMsgMetaData meta; - if (getMsgData(id, msgData) && getMsgSummary(id, meta)) - { - RsIdMsg *pM = (RsIdMsg *) msgData; - // Shallow copy of thumbnail. - msg = *pM; - - // update definitive version of the metadata. - msg.mMeta = meta; - - std::cerr << "IdDataProxy::getMsg() Id: " << id; - std::cerr << " MetaData: " << meta << " DataPointer: " << msgData; - std::cerr << std::endl; - return true; - } - - std::cerr << "IdDataProxy::getMsg() FAILED Id: " << id; - std::cerr << std::endl; - - return false; -} - -bool IdDataProxy::addGroup(const RsIdGroup &group) -{ - // Make duplicate. - RsIdGroup *pG = new RsIdGroup(); - *pG = group; - - std::cerr << "IdDataProxy::addGroup()"; - std::cerr << " MetaData: " << pG->mMeta << " DataPointer: " << pG; - std::cerr << std::endl; - - return createGroup(pG); -} - - -bool IdDataProxy::addMsg(const RsIdMsg &msg) -{ - // Make duplicate. - RsIdMsg *pM = new RsIdMsg(); - *pM = msg; - - std::cerr << "IdDataProxy::addMsg()"; - std::cerr << " MetaData: " << pM->mMeta << " DataPointer: " << pM; - std::cerr << std::endl; - - return createMsg(pM); -} - - - - /* These Functions must be overloaded to complete the service */ -bool IdDataProxy::convertGroupToMetaData(void *groupData, RsGroupMetaData &meta) -{ - RsIdGroup *group = (RsIdGroup *) groupData; - meta = group->mMeta; - - return true; -} - -bool IdDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta) -{ - RsIdMsg *page = (RsIdMsg *) msgData; - meta = page->mMeta; - - return true; -} - - - - -/************************************************************************************/ -/************************************************************************************/ -/************************************************************************************/ -/************************************************************************************/ -/************************************************************************************/ - -#if 0 - -/* details are updated */ -bool p3IdService::updateIdentity(RsIdData &data) -{ - if (data.mKeyId.empty()) - { - /* new photo */ - - /* generate a temp id */ - data.mKeyId = genRandomId(); - - if (data.mIdType & RSID_TYPE_REALID) - { - data.mGpgIdHash = genRandomId(); - } - else - { - data.mGpgIdHash = ""; - } - - } - - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - mUpdated = true; - - /* add / modify */ - mIds[data.mKeyId] = data; - - return true; -} - - - - -bool p3IdService::updateOpinion(RsIdOpinion &opinion) -{ - if (opinion.mKeyId.empty()) - { - /* new photo */ - std::cerr << "p3IdService::updateOpinion() Missing KeyId"; - std::cerr << std::endl; - return false; - } - - /* check if its a mod or new page */ - if (opinion.mPeerId.empty()) - { - std::cerr << "p3IdService::updateOpinion() Missing PeerId"; - std::cerr << std::endl; - return false; - } - - std::cerr << "p3IdService::updateOpinion() KeyId: " << opinion.mKeyId; - std::cerr << std::endl; - std::cerr << "p3IdService::updateOpinion() PeerId: " << opinion.mPeerId; - std::cerr << std::endl; - - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - mUpdated = true; - - std::map >::iterator it; - std::map::iterator oit; - - it = mOpinions.find(opinion.mKeyId); - if (it == mOpinions.end()) - { - std::map emptyMap; - mOpinions[opinion.mKeyId] = emptyMap; - - it = mOpinions.find(opinion.mKeyId); - } - - (it->second)[opinion.mPeerId] = opinion; - return true; -} - - -#endif - - - void p3IdService::generateDummyData() { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index 63e4c7094..ba9e05575 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -89,6 +89,20 @@ class p3IdService: public RsIdentity, public RsGxsIdExchange /* TODO */ + /**************** RsIdentity External Interface. + * Notes: + */ + + +virtual bool getNickname(const RsId &id, std::string &nickname); +virtual bool getIdDetails(const RsId &id, RsIdentityDetails &details); +virtual bool getOwnIds(std::list &ownIds); + + // +virtual bool submitOpinion(uint32_t& token, RsIdOpinion &opinion); +virtual bool createIdentity(uint32_t& token, RsIdentityParameters ¶ms); + + /**************** RsGixs Implementation * Notes: * Interface is only suggestion at the moment, will be changed as necessary. From d4bf742268f31599e2d3eb9e51587ba62cbaa91f Mon Sep 17 00:00:00 2001 From: drbob Date: Fri, 19 Oct 2012 00:16:35 +0000 Subject: [PATCH 091/222] Added basic GXS Wiki Service. * Filled in p3wiki and rswiki * tweaked VEG files to prevent clashes. * added serialiser header. Still to do: * complete design of Wiki Links, and the like. * Finish serialiser git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5692 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/libretroshare.pro | 23 ++- libretroshare/src/retroshare/rswiki.h | 131 +++++++++++++ libretroshare/src/retroshare/rswikiVEG.h | 4 +- libretroshare/src/serialiser/rswikiitems.h | 112 +++++++++++ libretroshare/src/services/p3wiki.cc | 184 ++++++++++++++++++ libretroshare/src/services/p3wiki.h | 69 +++++++ libretroshare/src/services/p3wikiserviceVEG.h | 4 +- 7 files changed, 521 insertions(+), 6 deletions(-) create mode 100644 libretroshare/src/retroshare/rswiki.h create mode 100644 libretroshare/src/serialiser/rswikiitems.h create mode 100644 libretroshare/src/services/p3wiki.cc create mode 100644 libretroshare/src/services/p3wiki.h diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 127875236..3e211f0ea 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -602,7 +602,8 @@ HEADERS += retroshare/rsgame.h \ gxs/gxssecurity.h \ gxs/rsgxsifaceimpl.h \ services/p3posted.h \ - retroshare/rsposted.h + retroshare/rsposted.h \ + SOURCES += serialiser/rsnxsitems.cc \ gxs/rsdataservice.cc \ @@ -619,7 +620,25 @@ HEADERS += retroshare/rsgame.h \ gxs/gxssecurity.cc \ gxs/gxssecurity.cc \ gxs/rsgxsifaceimpl.cc \ - services/p3posted.cc + services/p3posted.cc \ + + # Identity Service + #HEADERS += retroshare/rsidentity.h \ + # gxs/rsgixs.h \ + # services/p3idservice.h \ + # serialiser/rsiditems.h \ + + #SOURCES += services/p3idservice.cc \ + # serialiser/rsiditems.cc \ + + # Wiki Service + HEADERS += retroshare/rswiki.h \ + services/p3wiki.h \ + serialiser/rswikiitems.h \ + + SOURCES += services/p3wiki.cc \ + # serialiser/rswikiitems.cc \ + } newservices { diff --git a/libretroshare/src/retroshare/rswiki.h b/libretroshare/src/retroshare/rswiki.h new file mode 100644 index 000000000..07e527791 --- /dev/null +++ b/libretroshare/src/retroshare/rswiki.h @@ -0,0 +1,131 @@ +#ifndef RETROSHARE_WIKI_GUI_INTERFACE_H +#define RETROSHARE_WIKI_GUI_INTERFACE_H + +/* + * libretroshare/src/retroshare: rswiki.h + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include +#include +#include + +#include "gxs/rstokenservice.h" +#include "gxs/rsgxsifaceimpl.h" + +/* The Main Interface Class - for information about your Peers */ +class RsWiki; +extern RsWiki *rsWiki; + + +/* so the basic idea of Wiki is a set of Collections about subjects. + * + * Collection: RS + * - page: DHT + * - edit + * - edit + * - official revision. (new version of thread head). + * + * A collection will be moderated by it creator - important to prevent stupid changes. + * We need a way to swap out / replace / fork collections if moderator is rubbish. + * + * This should probably be done that the collection level. + * and enable all the references to be modified. + * + * Collection1 (RS DHT) + * : Turtle Link: Collection 0x54e4dafc34 + * - Page 1 + * - Page 2 + * - Link to Self:Page 1 + * - Link to Turtle:Page 1 + * + * + */ + +#define FLAG_MSG_TYPE_WIKI_SNAPSHOT 0x0001 +#define FLAG_MSG_TYPE_WIKI_COMMENT 0x0002 + +class CollectionRef +{ + public: + + std::string KeyWord; + std::string CollectionId; +}; + + +class RsWikiCollection +{ + public: + + RsGroupMetaData mMeta; + + std::string mDescription; + std::string mCategory; + + std::string mHashTags; + + //std::map linkReferences; +}; + + +class RsWikiSnapshot +{ + public: + + RsMsgMetaData mMeta; + + std::string mPage; // all the text is stored here. + std::string mHashTags; +}; + + +class RsWikiComment +{ + public: + + RsMsgMetaData mMeta; + std::string mComment; +}; + + +class RsWiki: public RsGxsIfaceImpl +{ + public: + + RsWiki(RsGenExchange *gxs): RsGxsIfaceImpl(gxs) { return; } +virtual ~RsWiki() { return; } + + /* Specific Service Data */ +virtual bool getCollections(const uint32_t &token, std::vector &collections) = 0; +virtual bool getSnapshots(const uint32_t &token, std::vector &snapshots) = 0; +virtual bool getComments(const uint32_t &token, std::vector &comments) = 0; + +virtual bool submitCollection(uint32_t &token, RsWikiCollection &collection) = 0; +virtual bool submitSnapshot(uint32_t &token, RsWikiSnapshot &snapshot) = 0; +virtual bool submitComment(uint32_t &token, RsWikiComment &comment) = 0; + + +}; + +#endif diff --git a/libretroshare/src/retroshare/rswikiVEG.h b/libretroshare/src/retroshare/rswikiVEG.h index 75616c8d4..8431ee3d8 100644 --- a/libretroshare/src/retroshare/rswikiVEG.h +++ b/libretroshare/src/retroshare/rswikiVEG.h @@ -1,5 +1,5 @@ -#ifndef RETROSHARE_WIKI_GUI_INTERFACE_H -#define RETROSHARE_WIKI_GUI_INTERFACE_H +#ifndef RETROSHARE_WIKI_VEG_GUI_INTERFACE_H +#define RETROSHARE_WIKI_VEG_GUI_INTERFACE_H /* * libretroshare/src/retroshare: rswiki.h diff --git a/libretroshare/src/serialiser/rswikiitems.h b/libretroshare/src/serialiser/rswikiitems.h new file mode 100644 index 000000000..2b356c400 --- /dev/null +++ b/libretroshare/src/serialiser/rswikiitems.h @@ -0,0 +1,112 @@ +/* + * libretroshare/src/serialiser: rswikiitems.h + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#ifndef RS_WIKI_ITEMS_H +#define RS_WIKI_ITEMS_H + +#include + +#include "serialiser/rsserviceids.h" +#include "serialiser/rsserial.h" +#include "serialiser/rstlvtypes.h" + +#include "rsgxsitems.h" +#include "retroshare/rswiki.h" + +const uint8_t RS_PKT_SUBTYPE_WIKI_COLLECTION_ITEM = 0x02; +const uint8_t RS_PKT_SUBTYPE_WIKI_SNAPSHOT_ITEM = 0x03; +const uint8_t RS_PKT_SUBTYPE_WIKI_COMMENT_ITEM = 0x04; + +class RsGxsWikiCollectionItem : public RsGxsGrpItem +{ + +public: + + RsGxsWikiCollectionItem(): RsGxsGrpItem(RS_SERVICE_GXSV1_TYPE_WIKI, + RS_PKT_SUBTYPE_WIKI_COLLECTION_ITEM) { return;} + virtual ~RsGxsWikiCollectionItem() { return;} + + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + + RsWikiCollection collection; +}; + +class RsGxsWikiSnapshotItem : public RsGxsMsgItem +{ +public: + + RsGxsWikiSnapshotItem(): RsGxsMsgItem(RS_SERVICE_GXSV1_TYPE_WIKI, + RS_PKT_SUBTYPE_WIKI_SNAPSHOT_ITEM) {return; } + virtual ~RsGxsWikiSnapshotItem() { return;} + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + RsWikiSnapshot snapshot; +}; + +class RsGxsWikiCommentItem : public RsGxsMsgItem +{ +public: + + RsGxsWikiCommentItem(): RsGxsMsgItem(RS_SERVICE_GXSV1_TYPE_WIKI, + RS_PKT_SUBTYPE_WIKI_COMMENT_ITEM) { return; } + virtual ~RsGxsWikiCommentItem() { return; } + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + RsWikiComment comment; + +}; + +class RsGxsWikiSerialiser : public RsSerialType +{ +public: + + RsGxsWikiSerialiser() + :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXSV1_TYPE_WIKI) + { return; } + virtual ~RsGxsWikiSerialiser() { return; } + + uint32_t size(RsItem *item); + bool serialise (RsItem *item, void *data, uint32_t *size); + RsItem * deserialise(void *data, uint32_t *size); + + private: + + uint32_t sizeGxsWikiCollectionItem(RsGxsWikiCollectionItem *item); + bool serialiseGxsWikiCollectionItem (RsGxsWikiCollectionItem *item, void *data, uint32_t *size); + RsGxsWikiCollectionItem * deserialiseGxsWikiCollectionItem(void *data, uint32_t *size); + + uint32_t sizeGxsWikiSnapshotItem(RsGxsWikiSnapshotItem *item); + bool serialiseGxsWikiSnapshotItem (RsGxsWikiSnapshotItem *item, void *data, uint32_t *size); + RsGxsWikiSnapshotItem * deserialiseGxsWikiSnapshotItem(void *data, uint32_t *size); + + uint32_t sizeGxsWikiCommentItem(RsGxsWikiCommentItem *item); + bool serialiseGxsWikiCommentItem (RsGxsWikiCommentItem *item, void *data, uint32_t *size); + RsGxsWikiCommentItem * deserialiseGxsWikiCommentItem(void *data, uint32_t *size); + +}; + +#endif /* RS_WIKI_ITEMS_H */ diff --git a/libretroshare/src/services/p3wiki.cc b/libretroshare/src/services/p3wiki.cc new file mode 100644 index 000000000..563b5b04f --- /dev/null +++ b/libretroshare/src/services/p3wiki.cc @@ -0,0 +1,184 @@ +/* + * libretroshare/src/services p3wiki.cc + * + * Wiki interface for RetroShare. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "services/p3wiki.h" +#include "serialiser/rswikiitems.h" + +/**** + * #define WIKI_DEBUG 1 + ****/ + +RsWiki *rsWiki = NULL; + + +p3Wiki::p3Wiki(RsGeneralDataService* gds, RsNetworkExchangeService* nes) + :RsGenExchange(gds, nes, NULL, RS_SERVICE_GXSV1_TYPE_WIKI), RsWiki(this) +{ + + +} + +void p3Wiki::notifyChanges(std::vector& changes) +{ + receiveChanges(changes); +} + + /* Specific Service Data */ +bool p3Wiki::getCollections(const uint32_t &token, std::vector &collections) +{ + std::vector grpData; + bool ok = RsGenExchange::getGroupData(token, grpData); + + if(ok) + { + std::vector::iterator vit = grpData.begin(); + + for(; vit != grpData.end(); vit++) + { + RsGxsWikiCollectionItem* item = dynamic_cast(*vit); + RsWikiCollection collection = item->collection; + collection.mMeta = item->collection.mMeta; + delete item; + collections.push_back(collection); + } + } + return ok; +} + + +bool p3Wiki::getSnapshots(const uint32_t &token, std::vector &snapshots) +{ + GxsMsgDataMap msgData; + bool ok = RsGenExchange::getMsgData(token, msgData); + + if(ok) + { + GxsMsgDataMap::iterator mit = msgData.begin(); + + for(; mit != msgData.end(); mit++) + { + RsGxsGroupId grpId = mit->first; + std::vector& msgItems = mit->second; + std::vector::iterator vit = msgItems.begin(); + + for(; vit != msgItems.end(); vit++) + { + RsGxsWikiSnapshotItem* item = dynamic_cast(*vit); + + if(item) + { + RsWikiSnapshot snapshot = item->snapshot; + snapshot.mMeta = item->meta; + snapshots.push_back(snapshot); + delete item; + } + else + { + std::cerr << "Not a WikiSnapshot Item, deleting!" << std::endl; + delete *vit; + } + } + } + } + + return ok; +} + + +bool p3Wiki::getComments(const uint32_t &token, std::vector &comments) +{ + GxsMsgDataMap msgData; + bool ok = RsGenExchange::getMsgData(token, msgData); + + if(ok) + { + GxsMsgDataMap::iterator mit = msgData.begin(); + + for(; mit != msgData.end(); mit++) + { + RsGxsGroupId grpId = mit->first; + std::vector& msgItems = mit->second; + std::vector::iterator vit = msgItems.begin(); + + for(; vit != msgItems.end(); vit++) + { + RsGxsWikiCommentItem* item = dynamic_cast(*vit); + + if(item) + { + RsWikiComment comment = item->comment; + comment.mMeta = item->meta; + comments.push_back(comment); + delete item; + } + else + { + std::cerr << "Not a WikiComment Item, deleting!" << std::endl; + delete *vit; + } + } + } + } + + return ok; + return false; +} + + + +bool p3Wiki::submitCollection(uint32_t &token, RsWikiCollection &collection) +{ + RsGxsWikiCollectionItem* collectionItem = new RsGxsWikiCollectionItem(); + collectionItem->collection = collection; + collectionItem->meta = collection.mMeta; + RsGenExchange::publishGroup(token, collectionItem); + return true; +} + + +bool p3Wiki::submitSnapshot(uint32_t &token, RsWikiSnapshot &snapshot) +{ + RsGxsWikiSnapshotItem* snapshotItem = new RsGxsWikiSnapshotItem(); + snapshotItem->snapshot = snapshot; + snapshotItem->meta = snapshot.mMeta; + snapshotItem->meta.mMsgFlags = FLAG_MSG_TYPE_WIKI_SNAPSHOT; + + RsGenExchange::publishMsg(token, snapshotItem); + return true; +} + + +bool p3Wiki::submitComment(uint32_t &token, RsWikiComment &comment) +{ + RsGxsWikiCommentItem* commentItem = new RsGxsWikiCommentItem(); + commentItem->comment = comment; + commentItem->meta = comment.mMeta; + commentItem->meta.mMsgFlags = FLAG_MSG_TYPE_WIKI_COMMENT; + + RsGenExchange::publishMsg(token, commentItem); + return true; +} + + diff --git a/libretroshare/src/services/p3wiki.h b/libretroshare/src/services/p3wiki.h new file mode 100644 index 000000000..10bd1edd3 --- /dev/null +++ b/libretroshare/src/services/p3wiki.h @@ -0,0 +1,69 @@ +/* + * libretroshare/src/services: p3wikiservice.h + * + * Wiki interface for RetroShare. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#ifndef P3_WIKI_SERVICE_HEADER +#define P3_WIKI_SERVICE_HEADER + +#include "retroshare/rswiki.h" +#include "gxs/rsgenexchange.h" + +#include +#include + +/* + * Wiki Service + * + * + */ + +class p3Wiki: public RsGenExchange, public RsWiki +{ +public: + p3Wiki(RsGeneralDataService* gds, RsNetworkExchangeService* nes); + +protected: + +virtual void notifyChanges(std::vector& changes) ; + +public: + + /* Specific Service Data */ +virtual bool getCollections(const uint32_t &token, std::vector &collections); +virtual bool getSnapshots(const uint32_t &token, std::vector &snapshots); +virtual bool getComments(const uint32_t &token, std::vector &comments); + +virtual bool submitCollection(uint32_t &token, RsWikiCollection &collection); +virtual bool submitSnapshot(uint32_t &token, RsWikiSnapshot &snapshot); +virtual bool submitComment(uint32_t &token, RsWikiComment &comment); + + private: + +//std::string genRandomId(); +// RsMutex mWikiMtx; + + +}; + +#endif diff --git a/libretroshare/src/services/p3wikiserviceVEG.h b/libretroshare/src/services/p3wikiserviceVEG.h index 4aba5345a..f172f4d3f 100644 --- a/libretroshare/src/services/p3wikiserviceVEG.h +++ b/libretroshare/src/services/p3wikiserviceVEG.h @@ -23,8 +23,8 @@ * */ -#ifndef P3_WIKI_SERVICE_HEADER -#define P3_WIKI_SERVICE_HEADER +#ifndef P3_WIKI_SERVICE_VEG_HEADER +#define P3_WIKI_SERVICE_VEG_HEADER #include "services/p3gxsserviceVEG.h" #include "retroshare/rswikiVEG.h" From 02f8d27b6e367938fa8a931fc35789eaa0734576 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Fri, 19 Oct 2012 13:22:51 +0000 Subject: [PATCH 092/222] Fixed crash with uninitialized pointer RsSshd::mSession. Fixed some compile errors on Windows. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5693 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/menu/menu.cc | 1 + retroshare-nogui/src/ssh/rssshd.cc | 14 ++++++++++---- retroshare-nogui/src/ssh/rssshd.h | 8 ++++---- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/retroshare-nogui/src/menu/menu.cc b/retroshare-nogui/src/menu/menu.cc index 46852a4f3..39cdc1e9e 100644 --- a/retroshare-nogui/src/menu/menu.cc +++ b/retroshare-nogui/src/menu/menu.cc @@ -27,6 +27,7 @@ #include #include +#include #include "util/rsstring.h" diff --git a/retroshare-nogui/src/ssh/rssshd.cc b/retroshare-nogui/src/ssh/rssshd.cc index ff1ca5294..895cc318b 100644 --- a/retroshare-nogui/src/ssh/rssshd.cc +++ b/retroshare-nogui/src/ssh/rssshd.cc @@ -32,7 +32,7 @@ clients must be made or how a client should react. RsSshd *rsSshd = NULL; // External Reference Variable. // NB: This must be called EARLY before all the threads are launched. -RsSshd *RsSshd::InitRsSshd(std::string portStr, std::string rsakeyfile) +RsSshd *RsSshd::InitRsSshd(const std::string &portStr, const std::string &rsakeyfile) { #if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,5,0) ssh_threads_set_callbacks(ssh_threads_get_pthread()); @@ -58,13 +58,15 @@ RsSshd::RsSshd(std::string portStr) mBindState = 0; mRpcSystem = NULL; + mSession = NULL; + setSleepPeriods(0.01, 0.1); return; } -int RsSshd::init(std::string pathrsakey) +int RsSshd::init(const std::string &pathrsakey) { mBind=ssh_bind_new(); @@ -117,7 +119,11 @@ void RsSshd::run() } } cleanupSession(); +#ifndef WINDOWS_SYS sleep(5); // have a break; +#else + Sleep(5000); // have a break; +#endif } } @@ -628,7 +634,7 @@ int RsSshd::setSleepPeriods(float busy, float idle) /* PASSWORDS */ /***********************************************************************************/ -int RsSshd::auth_password(char *name, char *pwd) +int RsSshd::auth_password(const char *name, const char *pwd) { #ifdef ALLOW_CLEARPWDS if (auth_password_basic(name, pwd)) @@ -726,7 +732,7 @@ int RsSshd::adduserpwdhash(std::string username, std::string hash) } -int RsSshd::auth_password_hashed(char *name, char *pwd) +int RsSshd::auth_password_hashed(const char *name, const char *pwd) { std::string username(name); std::string password(pwd); diff --git a/retroshare-nogui/src/ssh/rssshd.h b/retroshare-nogui/src/ssh/rssshd.h index 07f289d2a..4033907c3 100644 --- a/retroshare-nogui/src/ssh/rssshd.h +++ b/retroshare-nogui/src/ssh/rssshd.h @@ -71,7 +71,7 @@ class RsSshd: public RsThread, public RpcComms public: // NB: This must be called EARLY before all the threads are launched. -static RsSshd *InitRsSshd(std::string portstr, std::string rsakeyfile); +static RsSshd *InitRsSshd(const std::string &portstr, const std::string &rsakeyfile); // Interface. @@ -101,7 +101,7 @@ int adduserpwdhash(std::string username, std::string hash); private: RsSshd(std::string portStr); /* private constructor => so can only create with */ -int init(std::string pathrsakey); +int init(const std::string &pathrsakey); // High level operations. int listenConnect(); @@ -122,8 +122,8 @@ int cleanupSession(); int cleanupAll(); /* Password Checking */ -int auth_password(char *name, char *pwd); -int auth_password_hashed(char *name, char *pwd); +int auth_password(const char *name, const char *pwd); +int auth_password_hashed(const char *name, const char *pwd); #ifdef ALLOW_CLEARPWDS int auth_password_basic(char *name, char *pwd); #endif // ALLOW_CLEARPWDS From 57a99d1aa3750e48fd0e68057e93f665d917c3b2 Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 21 Oct 2012 15:48:18 +0000 Subject: [PATCH 093/222] Made p3identity compile. (but won't run yet!) - Lots of tweaks to rsidentity & rsgixs interfaces to make them match. - added "mask" to gxs flag set operations. - added dummy RsMsgMetaData print functions. - enable compilation of code in .pro. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5702 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgenexchange.cc | 9 +- libretroshare/src/gxs/rsgenexchange.h | 6 +- libretroshare/src/gxs/rsgixs.h | 65 ++-- libretroshare/src/gxs/rsgxsifaceimpl.cc | 4 +- libretroshare/src/libretroshare.pro | 12 +- libretroshare/src/retroshare/rsidentity.h | 69 +++- libretroshare/src/retroshare/rsidentityVEG.h | 4 +- libretroshare/src/serialiser/rsgxsitems.cc | 16 + libretroshare/src/serialiser/rsgxsitems.h | 3 + libretroshare/src/serialiser/rsserviceids.h | 4 +- libretroshare/src/services/p3idservice.cc | 345 ++++++++++-------- libretroshare/src/services/p3idservice.h | 34 +- .../src/services/p3photoserviceV2.cc | 4 +- 13 files changed, 341 insertions(+), 234 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 58f9973d1..ecdb61cdc 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -441,8 +441,9 @@ void RsGenExchange::publishMsg(uint32_t& token, RsGxsMsgItem *msgItem) mMsgsToPublish.insert(std::make_pair(token, msgItem)); } -void RsGenExchange::setGroupSubscribeFlag(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& flag) +void RsGenExchange::setGroupSubscribeFlags(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& flag, const uint32_t& mask) { + /* TODO APPLY MASK TO FLAGS */ RsStackMutex stack(mGenMtx); token = mDataAccess->generatePublicToken(); @@ -452,8 +453,9 @@ void RsGenExchange::setGroupSubscribeFlag(uint32_t& token, const RsGxsGroupId& g mGrpLocMetaMap.insert(std::make_pair(token, g)); } -void RsGenExchange::setGroupStatusFlag(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status) +void RsGenExchange::setGroupStatusFlags(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status, const uint32_t& mask) { + /* TODO APPLY MASK TO FLAGS */ RsStackMutex stack(mGenMtx); token = mDataAccess->generatePublicToken(); @@ -475,8 +477,9 @@ void RsGenExchange::setGroupServiceString(uint32_t& token, const RsGxsGroupId& g mGrpLocMetaMap.insert(std::make_pair(token, g)); } -void RsGenExchange::setMsgStatusFlag(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const uint32_t& status) +void RsGenExchange::setMsgStatusFlags(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const uint32_t& status, const uint32_t& mask) { + /* TODO APPLY MASK TO FLAGS */ RsStackMutex stack(mGenMtx); token = mDataAccess->generatePublicToken(); diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 71a356b5a..438251dd1 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -257,13 +257,13 @@ public: * @param token this is set to token value associated to this request * @param */ - void setGroupSubscribeFlag(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status); + void setGroupSubscribeFlags(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status, const uint32_t& mask); - void setGroupStatusFlag(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status); + void setGroupStatusFlags(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status, const uint32_t& mask); void setGroupServiceString(uint32_t& token, const RsGxsGroupId& grpId, const std::string& servString); - void setMsgStatusFlag(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const uint32_t& status); + void setMsgStatusFlags(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const uint32_t& status, const uint32_t& mask); void setMsgServiceString(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const std::string& servString ); diff --git a/libretroshare/src/gxs/rsgixs.h b/libretroshare/src/gxs/rsgixs.h index 386ab6379..dcafcb240 100644 --- a/libretroshare/src/gxs/rsgixs.h +++ b/libretroshare/src/gxs/rsgixs.h @@ -27,9 +27,12 @@ */ #include "gxs/rsgxs.h" +#include "gxs/rsgenexchange.h" -#include -#include +#include "serialiser/rstlvkeys.h" + +//#include +//#include /*! * GIXP: General Identity Exchange Service. @@ -94,25 +97,27 @@ * as these will be used very frequently. *****/ -typedef std::string GxsId; +//typedef std::string GxsId; + typedef std::string PeerId; -// External Interface - -class RsIdentityService -{ - enum IdentityType { Pseudonym, Signed, Anonymous }; - - virtual bool loadId(const GxsId &id) = 0; - - virtual bool getNickname(const GxsId &id, std::string &nickname) = 0; - - virtual bool createKey(RsGixsProfile& profile, uint32_t type) = 0; /* fills in mKeyId, and signature */ - - virtual RsGixsProfile* getProfile(const KeyRef& keyref) = 0; - - // modify reputation. - -}; +// +//// External Interface - +//class RsIdentityService +//{ +// enum IdentityType { Pseudonym, Signed, Anonymous }; +// +// virtual bool loadId(const GxsId &id) = 0; +// +// virtual bool getNickname(const GxsId &id, std::string &nickname) = 0; +// +// virtual bool createKey(RsGixsProfile& profile, uint32_t type) = 0; /* fills in mKeyId, and signature */ +// +// virtual RsGixsProfile* getProfile(const KeyRef& keyref) = 0; +// +// // modify reputation. +// +//}; /* Identity Interface for GXS Message Verification. @@ -127,14 +132,14 @@ public: * @param keyref the keyref of key that is being checked for * @return true if available, false otherwise */ - virtual bool haveKey(const GxsId &id) = 0; + virtual bool haveKey(const RsGxsId &id) = 0; /*! * Use to query whether private key member of the given key reference is available * @param keyref the KeyRef of the key being checked for * @return true if private key is held here, false otherwise */ - virtual bool havePrivateKey(const GxsId &id) = 0; + virtual bool havePrivateKey(const RsGxsId &id) = 0; // The fetchKey has an optional peerList.. this is people that had the msg with the signature. // These same people should have the identity - so we ask them first. @@ -143,7 +148,7 @@ public: * @param keyref the KeyRef of the key being requested * @return will */ - virtual bool requestKey(const GxsId &id, const std::list &peers) = 0; + virtual bool requestKey(const RsGxsId &id, const std::list &peers) = 0; /*! * Retrieves a key identity @@ -151,18 +156,25 @@ public: * @return a pointer to a valid profile if successful, otherwise NULL * */ - virtual int getKey(const GxsId &id, TlvSecurityKey &key) = 0; - virtual int getPrivateKey(const GxsId &id, TlvSecurityKey &key) = 0; // For signing outgoing messages. + virtual int getKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0; + virtual int getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key) = 0; // For signing outgoing messages. }; +class GixsReputation +{ + public: + RsGxsId id; + int score; +}; + class RsGixsReputation { public: // get Reputation. - virtual bool getReputation(const GxsId &id, const GixsReputation &rep) = 0; + virtual bool getReputation(const RsGxsId &id, const GixsReputation &rep) = 0; }; @@ -171,7 +183,8 @@ public: class RsGxsIdExchange: public RsGenExchange, public RsGixsReputation, public RsGixs { public: - RsGxsIdExchange() { return; } + RsGxsIdExchange(RsGeneralDataService* gds, RsNetworkExchangeService* ns, RsSerialType* serviceSerialiser, uint16_t mServType) + :RsGenExchange(gds,ns,serviceSerialiser,mServType) { return; } virtual ~RsGxsIdExchange() { return; } }; diff --git a/libretroshare/src/gxs/rsgxsifaceimpl.cc b/libretroshare/src/gxs/rsgxsifaceimpl.cc index 3a488cbef..1d79986d6 100644 --- a/libretroshare/src/gxs/rsgxsifaceimpl.cc +++ b/libretroshare/src/gxs/rsgxsifaceimpl.cc @@ -138,9 +138,9 @@ bool RsGxsIfaceImpl::getMsgSummary(const uint32_t &token, bool RsGxsIfaceImpl::subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe) { if(subscribe) - mGxs->setGroupSubscribeFlag(token, grpId, GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED); + mGxs->setGroupSubscribeFlags(token, grpId, GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED, GXS_SERV::GROUP_SUBSCRIBE_MASK); else - mGxs->setGroupSubscribeFlag(token, grpId, ~GXS_SERV::GROUP_SUBSCRIBE_MASK); + mGxs->setGroupSubscribeFlags(token, grpId, 0, GXS_SERV::GROUP_SUBSCRIBE_MASK); return true; } diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 3e211f0ea..a39ea250d 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -623,13 +623,13 @@ HEADERS += retroshare/rsgame.h \ services/p3posted.cc \ # Identity Service - #HEADERS += retroshare/rsidentity.h \ - # gxs/rsgixs.h \ - # services/p3idservice.h \ - # serialiser/rsiditems.h \ + HEADERS += retroshare/rsidentity.h \ + gxs/rsgixs.h \ + services/p3idservice.h \ + serialiser/rsgxsiditems.h \ - #SOURCES += services/p3idservice.cc \ - # serialiser/rsiditems.cc \ + SOURCES += services/p3idservice.cc \ + # serialiser/rsgxsiditems.cc \ # Wiki Service HEADERS += retroshare/rswiki.h \ diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index c30e551a2..1677dbd75 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -29,7 +29,9 @@ #include #include #include -#include "rsgxsservice.h" + +#include "gxs/rstokenservice.h" +#include "gxs/rsgxsifaceimpl.h" /* The Main Interface Class - for information about your Peers */ class RsIdentity; @@ -49,7 +51,7 @@ extern RsIdentity *rsIdentity; std::string rsIdTypeToString(uint32_t idtype); -class RsIdGroup +class RsGxsIdGroup { public: @@ -80,7 +82,7 @@ class RsIdGroup -class RsIdMsg +class RsGxsIdOpinion { public: @@ -98,12 +100,18 @@ class RsIdMsg }; +// This will probably be dropped. +class RsGxsIdComment +{ + public: -std::ostream &operator<<(std::ostream &out, const RsIdGroup &meta); -std::ostream &operator<<(std::ostream &out, const RsIdMsg &meta); + RsMsgMetaData mMeta; + std::string mComment; +}; -typedef std::map > IdMsgResult; +std::ostream &operator<<(std::ostream &out, const RsGxsIdGroup &group); +std::ostream &operator<<(std::ostream &out, const RsGxsIdOpinion &msg); #if 0 class RsIdReputation @@ -134,6 +142,39 @@ class RsIdOpinion #endif +// DATA TYPE FOR EXTERNAL INTERFACE. + +typedef std::string RsGxsId; // TMP. => + +class RsIdentityDetails +{ + public: + + RsGxsId id; + + // identity details. + + + // reputation details. +}; + + +class RsIdOpinion +{ + public: + RsGxsId id; + int rating; +}; + + +class RsIdentityParameters +{ + public: + + int IdType; +}; + + class RsIdentity: public RsGxsIfaceImpl { @@ -208,23 +249,19 @@ public: // We cache all identities, and provide alternative (instantaneous) // functions to extract info, rather than the standard Token system. -virtual bool getNickname(const RsId &id, std::string &nickname) = 0; -virtual bool getIdDetails(const RsId &id, RsIdentityDetails &details) = 0; -virtual bool getOwnIds(std::list &ownIds) = 0; +virtual bool getNickname(const RsGxsId &id, std::string &nickname) = 0; +virtual bool getIdDetails(const RsGxsId &id, RsIdentityDetails &details) = 0; +virtual bool getOwnIds(std::list &ownIds) = 0; // virtual bool submitOpinion(uint32_t& token, RsIdOpinion &opinion) = 0; virtual bool createIdentity(uint32_t& token, RsIdentityParameters ¶ms) = 0; - - // Specific RsIdentity Functions.... /* Specific Service Data */ -//virtual bool getGroupData(const uint32_t &token, RsIdGroup &group) = 0; -//virtual bool getMsgData(const uint32_t &token, RsIdMsg &msg) = 0; - -//virtual bool createGroup(uint32_t &token, RsIdGroup &group, bool isNew) = 0; -//virtual bool createMsg(uint32_t &token, RsIdMsg &msg, bool isNew) = 0; + /* We expose these initially for testing / GUI purposes. + */ +virtual bool getGroupData(const uint32_t &token, std::vector &groups) = 0; /* In the Identity System - You don't access the Messages Directly. * as they represent idividuals opinions.... diff --git a/libretroshare/src/retroshare/rsidentityVEG.h b/libretroshare/src/retroshare/rsidentityVEG.h index d88943442..98937a0f3 100644 --- a/libretroshare/src/retroshare/rsidentityVEG.h +++ b/libretroshare/src/retroshare/rsidentityVEG.h @@ -293,8 +293,8 @@ class RsTokReqOptionsVEG // //}; -std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta); -std::ostream &operator<<(std::ostream &out, const RsMsgMetaData &meta); +//std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta); +//std::ostream &operator<<(std::ostream &out, const RsMsgMetaData &meta); class RsTokenServiceVEG { diff --git a/libretroshare/src/serialiser/rsgxsitems.cc b/libretroshare/src/serialiser/rsgxsitems.cc index 2d8374fd0..a68f889f0 100644 --- a/libretroshare/src/serialiser/rsgxsitems.cc +++ b/libretroshare/src/serialiser/rsgxsitems.cc @@ -8,6 +8,7 @@ #include "rsgxsitems.h" #include "gxs/rsgxsdata.h" +#include void RsMsgMetaData::operator =(const RsGxsMsgMetaData& rGxsMeta) { @@ -42,3 +43,18 @@ this->mServiceString = rGxsMeta.mServiceString; this->mSignFlags = rGxsMeta.mSignFlags; } + + +std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta) +{ + out << "RsGroupMetaData(TODO PRINT)"; + return out; +} + +std::ostream &operator<<(std::ostream &out, const RsMsgMetaData &meta) +{ + out << "RsMsgMetaData(TODO PRINT)"; + return out; +} + + diff --git a/libretroshare/src/serialiser/rsgxsitems.h b/libretroshare/src/serialiser/rsgxsitems.h index 082468fc2..103b0ae71 100644 --- a/libretroshare/src/serialiser/rsgxsitems.h +++ b/libretroshare/src/serialiser/rsgxsitems.h @@ -114,6 +114,9 @@ class RsMsgMetaData }; +std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta); +std::ostream &operator<<(std::ostream &out, const RsMsgMetaData &meta); + class RsGxsGrpItem : public RsItem { diff --git a/libretroshare/src/serialiser/rsserviceids.h b/libretroshare/src/serialiser/rsserviceids.h index 800116654..24a3e3779 100644 --- a/libretroshare/src/serialiser/rsserviceids.h +++ b/libretroshare/src/serialiser/rsserviceids.h @@ -131,7 +131,7 @@ const uint16_t RS_SERVICE_TYPE_GAME_POKER = 0xf214; /* Rs Network Exchange Service */ const uint16_t RS_SERVICE_TYPE_NXS = 0xf300; -const uint16_t RS_SERVICE_GXSV1_TYPE_IDENTITY = 0xf301; +const uint16_t RS_SERVICE_GXSV1_TYPE_GXSID = 0xf301; const uint16_t RS_SERVICE_GXSV1_TYPE_PHOTO = 0xf302; const uint16_t RS_SERVICE_GXSV1_TYPE_WIKI = 0xf303; const uint16_t RS_SERVICE_GXSV1_TYPE_WIRE = 0xf304; @@ -139,7 +139,7 @@ const uint16_t RS_SERVICE_GXSV1_TYPE_FORUMS = 0xf305; const uint16_t RS_SERVICE_GXSV1_TYPE_POSTED = 0xf306; const uint16_t RS_SERVICE_GXSV1_TYPE_CHANNELS = 0xf307; -const uint16_t RS_SERVICE_GXSV2_TYPE_IDENTITY = 0xf311; +const uint16_t RS_SERVICE_GXSV2_TYPE_GXSID = 0xf311; const uint16_t RS_SERVICE_GXSV2_TYPE_PHOTO = 0xf312; const uint16_t RS_SERVICE_GXSV2_TYPE_WIKI = 0xf313; const uint16_t RS_SERVICE_GXSV2_TYPE_WIRE = 0xf314; diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index db64f3294..b96a09c44 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -24,9 +24,11 @@ */ #include "services/p3idservice.h" +#include "serialiser/rsgxsiditems.h" #include "util/rsrandom.h" #include + #include #include @@ -41,27 +43,19 @@ RsIdentity *rsIdentity = NULL; +#define RSGXSID_MAX_SERVICE_STRING 1024 /********************************************************************************/ /******************* Startup / Tick ******************************************/ /********************************************************************************/ p3IdService::p3IdService(RsGeneralDataService *gds, RsNetworkExchangeService *nes) - : RsIdentity(this), RsGenExchange(gds, nes, NULL, RS_SERVICE_GXSV1_TYPE_IDENTITY), + : RsGxsIdExchange(gds, nes, NULL, RS_SERVICE_GXSV1_TYPE_GXSID), RsIdentity(this), mIdMtx("p3IdService") { } -p3IdService::p3IdService(uint16_t type) - :p3GxsDataService(type, new IdDataProxy()), mIdMtx("p3IdService"), mUpdated(true) -{ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - mIdProxy = (IdDataProxy *) mProxy; - return; -} - int p3IdService::internal_tick() { std::cerr << "p3IdService::internal_tick()"; @@ -78,17 +72,17 @@ int p3IdService::internal_tick() /******************* RsIdentity Interface ***************************************/ /********************************************************************************/ -bool p3IdService:: getNickname(const RsId &id, std::string &nickname) +bool p3IdService:: getNickname(const RsGxsId &id, std::string &nickname) { return false; } -bool p3IdService:: getIdDetails(const RsId &id, RsIdentityDetails &details) +bool p3IdService:: getIdDetails(const RsGxsId &id, RsIdentityDetails &details) { return false; } -bool p3IdService:: getOwnIds(std::list &ownIds) +bool p3IdService:: getOwnIds(std::list &ownIds) { return false; } @@ -110,27 +104,27 @@ bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) /******************* RsGixs Interface ***************************************/ /********************************************************************************/ -bool p3IdService::haveKey(const GxsId &id) +bool p3IdService::haveKey(const RsGxsId &id) { return false; } -bool p3IdService::havePrivateKey(const GxsId &id) +bool p3IdService::havePrivateKey(const RsGxsId &id) { return false; } -bool p3IdService::requestKey(const GxsId &id, const std::list &peers) +bool p3IdService::requestKey(const RsGxsId &id, const std::list &peers) { return false; } -int p3IdService::getKey(const GxsId &id, TlvSecurityKey &key) +int p3IdService::getKey(const RsGxsId &id, RsTlvSecurityKey &key) { return -1; } -int p3IdService::getPrivateKey(const GxsId &id, TlvSecurityKey &key) +int p3IdService::getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key) { return -1; } @@ -140,7 +134,7 @@ int p3IdService::getPrivateKey(const GxsId &id, TlvSecurityKey &key) /******************* RsGixsReputation ***************************************/ /********************************************************************************/ -bool p3IdService::getReputation(const GxsId &id, const GixsReputation &rep) +bool p3IdService::getReputation(const RsGxsId &id, const GixsReputation &rep) { return false; } @@ -150,11 +144,9 @@ bool p3IdService::getReputation(const GxsId &id, const GixsReputation &rep) /******************* Get/Set Data ******************************************/ /********************************************************************************/ -bool p3IdService::getGroupData(const uint32_t &token, RsIdGroup &group) +bool p3IdService::getGroupData(const uint32_t &token, std::vector &groups) { -// MISMATCH BETWEEN RsGenExchange (vector) and individual result here. -#if 0 std::vector grpData; bool ok = RsGenExchange::getGroupData(token, grpData); @@ -165,23 +157,18 @@ bool p3IdService::getGroupData(const uint32_t &token, RsIdGroup &group) for(; vit != grpData.end(); vit++) { RsGxsIdGroupItem* item = dynamic_cast(*vit); - RsIdGroup group = item->group; - group.mMeta = item->meta + RsGxsIdGroup group = item->group; + group.mMeta = item->meta; groups.push_back(group); } } return ok; -#endif - return false; } -bool p3IdService::getMsgData(const uint32_t &token, RsIdMsg &msg) +bool p3IdService::getMsgData(const uint32_t &token, std::vector &opinions) { - -// MISMATCH BETWEEN RsGenExchange (vector) and individual result here. -#if 0 GxsMsgDataMap msgData; bool ok = RsGenExchange::getMsgData(token, msgData); @@ -197,33 +184,31 @@ bool p3IdService::getMsgData(const uint32_t &token, RsIdMsg &msg) for(; vit != msgItems.end(); vit++) { - RsGxsIdMsgItem* item = dynamic_cast(*vit); + RsGxsIdOpinionItem* item = dynamic_cast(*vit); - if(item) + if (item) { - RsIdMsg msg = item->msg; - msg.mMeta = item->meta; - msgs[grpId].push_back(msg); + RsGxsIdOpinion opinion = item->opinion; + opinion.mMeta = item->meta; + opinions.push_back(opinion); delete item; } else { - std::cerr << "Not a IdMsg Item, deleting!" << std::endl; + std::cerr << "Not a IdOpinion Item, deleting!" << std::endl; delete *vit; } } } } return ok; -#endif - return false; } /********************************************************************************/ /********************************************************************************/ /********************************************************************************/ -bool p3IdService::createGroup(uint32_t& token, RsIdGroup &group) +bool p3IdService::createGroup(uint32_t& token, RsGxsIdGroup &group) { RsGxsIdGroupItem* item = new RsGxsIdGroupItem(); item->group = group; @@ -232,11 +217,11 @@ bool p3IdService::createGroup(uint32_t& token, RsIdGroup &group) return true; } -bool p3IdService::createMsg(uint32_t& token, RsIdMsg &msg) +bool p3IdService::createMsg(uint32_t& token, RsGxsIdOpinion &opinion) { - RsGxsIdMsgItem* item = new RsGxsIdMsgItem(); - item->msg = msg; - item->meta = msg.mMeta; + RsGxsIdOpinionItem* item = new RsGxsIdOpinionItem(); + item->opinion = opinion; + item->meta = opinion.mMeta; RsGenExchange::publishMsg(token, item); return true; } @@ -279,7 +264,7 @@ void p3IdService::generateDummyData() int nIds = 1 + (RSRandom::random_u32() % 2); for(i = 0; i < nIds; i++) { - RsIdGroup id; + RsGxsIdGroup id; RsPeerDetails details; @@ -328,7 +313,10 @@ void p3IdService::generateDummyData() } //mIds[id.mKeyId] = id; - mIdProxy->addGroup(id); + //mIdProxy->addGroup(id); + // STORE + uint32_t dummyToken = 0; + createGroup(dummyToken, id); } } @@ -341,7 +329,7 @@ void p3IdService::generateDummyData() /* make some fake gpg ids */ for(i = 0; i < nFakeGPGs; i++) { - RsIdGroup id; + RsGxsIdGroup id; RsPeerDetails details; @@ -359,13 +347,16 @@ void p3IdService::generateDummyData() id.mGpgEmail = ""; //mIds[id.mKeyId] = id; - mIdProxy->addGroup(id); + //mIdProxy->addGroup(id); + // STORE + uint32_t dummyToken = 0; + createGroup(dummyToken, id); } /* make lots of pseudo ids */ for(i = 0; i < nFakePseudoIds; i++) { - RsIdGroup id; + RsGxsIdGroup id; RsPeerDetails details; @@ -382,10 +373,13 @@ void p3IdService::generateDummyData() id.mGpgEmail = ""; //mIds[id.mKeyId] = id; - mIdProxy->addGroup(id); + //mIdProxy->addGroup(id); + // STORE + uint32_t dummyToken = 0; + createGroup(dummyToken, id); } - mUpdated = true; + //mUpdated = true; return; } @@ -566,9 +560,12 @@ bool p3IdService::background_checkTokenRequest() uint32_t reqtype; uint32_t anstype; time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); + + + status = RsGenExchange::getTokenService()->requestStatus(token); + //checkRequestStatus(token, status, reqtype, anstype, ts); - if (status == GXS_REQUEST_STATUS_COMPLETE) + if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) { switch(phase) { @@ -613,13 +610,16 @@ bool p3IdService::background_requestGroups() } uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptions opts; + RsTokReqOptionsV2 opts; std::list groupIds; +/** + TODO opts.mStatusFilter = RSGXS_GROUP_STATUS_NEWMSG; opts.mStatusMask = RSGXS_GROUP_STATUS_NEWMSG; +**/ - requestGroupInfo(token, ansType, opts, groupIds); + RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts, groupIds); { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ mBgToken = token; @@ -662,7 +662,10 @@ bool p3IdService::background_requestNewMessages() /* now we process the modGroupList -> a map so we can use it easily later, and create id list too */ for(it = modGroupList.begin(); it != modGroupList.end(); it++) { - setGroupStatus(it->mGroupId, 0, RSGXS_GROUP_STATUS_NEWMSG); + /*** TODO + uint32_t dummyToken = 0; + setGroupStatusFlags(dummyToken, it->mGroupId, 0, RSGXS_GROUP_STATUS_NEWMSG); + ***/ mBgGroupMap[it->mGroupId] = *it; groupIds.push_back(it->mGroupId); @@ -670,13 +673,15 @@ bool p3IdService::background_requestNewMessages() } uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptions opts; + RsTokReqOptionsV2 opts; token = 0; + /* TODO opts.mStatusFilter = RSGXS_MSG_STATUS_UNPROCESSED; opts.mStatusMask = RSGXS_MSG_STATUS_UNPROCESSED; + */ - requestMsgInfo(token, ansType, opts, groupIds); + RsGenExchange::getTokenService()->requestMsgInfo(token, ansType, opts, groupIds); { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ @@ -691,8 +696,8 @@ bool p3IdService::background_processNewMessages() std::cerr << "p3IdService::background_processNewMessages()"; std::cerr << std::endl; - std::list newMsgList; - std::list::iterator it; + GxsMsgMetaMap newMsgMap; + GxsMsgMetaMap::iterator it; uint32_t token = 0; { @@ -700,7 +705,7 @@ bool p3IdService::background_processNewMessages() token = mBgToken; } - if (!getMsgSummary(token, newMsgList)) + if (!getMsgSummary(token, newMsgMap)) { std::cerr << "p3IdService::background_processNewMessages() ERROR No New Msgs"; std::cerr << std::endl; @@ -708,7 +713,6 @@ bool p3IdService::background_processNewMessages() return false; } - /* iterate through the msgs.. update the mBgGroupMap with new data, * and flag these items as modified - so we rewrite them to the db later. * @@ -716,84 +720,93 @@ bool p3IdService::background_processNewMessages() */ std::map::iterator mit; - for(it = newMsgList.begin(); it != newMsgList.end(); it++) + + for (it = newMsgMap.begin(); it != newMsgMap.end(); it++) { - std::cerr << "p3IdService::background_processNewMessages() new MsgId: " << it->mMsgId; - std::cerr << std::endl; - - /* flag each new vote as processed */ - setMessageStatus(it->mMsgId, 0, RSGXS_MSG_STATUS_UNPROCESSED); - - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - mit = mBgGroupMap.find(it->mGroupId); - if (mit == mBgGroupMap.end()) + std::vector::iterator vit; + for(vit = it->second.begin(); vit != it->second.end(); vit++) { - std::cerr << "p3IdService::background_processNewMessages() ERROR missing GroupId: "; - std::cerr << it->mGroupId; + std::cerr << "p3IdService::background_processNewMessages() new MsgId: " << vit->mMsgId; std::cerr << std::endl; - - /* error */ - continue; - } - - if (mit->second.mGroupStatus & ID_LOCAL_STATUS_FULL_CALC_FLAG) - { - std::cerr << "p3IdService::background_processNewMessages() Group Already marked FULL_CALC"; - std::cerr << std::endl; - - /* already marked */ - continue; - } - - if (it->mMsgId != it->mOrigMsgId) - { - /* - * not original -> hard, redo calc (alt: could substract previous score) - */ - - std::cerr << "p3IdService::background_processNewMessages() Update, mark for FULL_CALC"; - std::cerr << std::endl; - - mit->second.mGroupStatus |= ID_LOCAL_STATUS_FULL_CALC_FLAG; - } - else - { - /* - * Try incremental calculation. - * - extract parameters from group. - * - increment, & save back. - * - flag group as modified. - */ - - std::cerr << "p3IdService::background_processNewMessages() NewOpt, Try Inc Calc"; - std::cerr << std::endl; - - mit->second.mGroupStatus |= ID_LOCAL_STATUS_INC_CALC_FLAG; - - std::string serviceString; - IdGroupServiceStrData ssData; - - if (!extractIdGroupCache(serviceString, ssData)) + + /* flag each new vote as processed */ + /** + TODO + uint32_t dummyToken = 0; + setMsgStatusFlags(dummyToken, it->mMsgId, 0, RSGXS_MSG_STATUS_UNPROCESSED); + **/ + + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + mit = mBgGroupMap.find(it->first); + if (mit == mBgGroupMap.end()) { - /* error */ - std::cerr << "p3IdService::background_processNewMessages() ERROR Extracting"; + std::cerr << "p3IdService::background_processNewMessages() ERROR missing GroupId: "; + std::cerr << vit->mGroupId; std::cerr << std::endl; + + /* error */ + continue; } - - /* do calcs */ - std::cerr << "p3IdService::background_processNewMessages() Extracted: "; - std::cerr << std::endl; - - /* store it back in */ - std::cerr << "p3IdService::background_processNewMessages() Stored: "; - std::cerr << std::endl; - - if (!encodeIdGroupCache(serviceString, ssData)) + + if (mit->second.mGroupStatus & ID_LOCAL_STATUS_FULL_CALC_FLAG) { - /* error */ - std::cerr << "p3IdService::background_processNewMessages() ERROR Storing"; + std::cerr << "p3IdService::background_processNewMessages() Group Already marked FULL_CALC"; std::cerr << std::endl; + + /* already marked */ + continue; + } + + if (vit->mMsgId != vit->mOrigMsgId) + { + /* + * not original -> hard, redo calc (alt: could substract previous score) + */ + + std::cerr << "p3IdService::background_processNewMessages() Update, mark for FULL_CALC"; + std::cerr << std::endl; + + mit->second.mGroupStatus |= ID_LOCAL_STATUS_FULL_CALC_FLAG; + } + else + { + /* + * Try incremental calculation. + * - extract parameters from group. + * - increment, & save back. + * - flag group as modified. + */ + + std::cerr << "p3IdService::background_processNewMessages() NewOpt, Try Inc Calc"; + std::cerr << std::endl; + + mit->second.mGroupStatus |= ID_LOCAL_STATUS_INC_CALC_FLAG; + + std::string serviceString; + IdGroupServiceStrData ssData; + + if (!extractIdGroupCache(serviceString, ssData)) + { + /* error */ + std::cerr << "p3IdService::background_processNewMessages() ERROR Extracting"; + std::cerr << std::endl; + } + + /* do calcs */ + std::cerr << "p3IdService::background_processNewMessages() Extracted: "; + std::cerr << std::endl; + + /* store it back in */ + std::cerr << "p3IdService::background_processNewMessages() Stored: "; + std::cerr << std::endl; + + if (!encodeIdGroupCache(serviceString, ssData)) + { + /* error */ + std::cerr << "p3IdService::background_processNewMessages() ERROR Storing"; + std::cerr << std::endl; + } } } } @@ -827,7 +840,8 @@ bool p3IdService::background_processNewMessages() std::cerr << std::endl; /* set Cache */ - setGroupServiceString(mit->second.mGroupId, mit->second.mServiceString); + uint32_t dummyToken = 0; + setGroupServiceString(dummyToken, mit->second.mGroupId, mit->second.mServiceString); } else { @@ -845,9 +859,9 @@ bool p3IdService::background_processNewMessages() bool p3IdService::encodeIdGroupCache(std::string &str, const IdGroupServiceStrData &data) { - char line[RSGXS_MAX_SERVICE_STRING]; + char line[RSGXSID_MAX_SERVICE_STRING]; - snprintf(line, RSGXS_MAX_SERVICE_STRING, "v1 {%s} {Y:%d O:%d %d %f %f R:%d %d %f %f}", + snprintf(line, RSGXSID_MAX_SERVICE_STRING, "v1 {%s} {Y:%d O:%d %d %f %f R:%d %d %f %f}", data.pgpId.c_str(), data.ownScore, data.opinion.count, data.opinion.nullcount, data.opinion.sum, data.opinion.sumsq, data.reputation.count, data.reputation.nullcount, data.reputation.sum, data.reputation.sumsq); @@ -859,8 +873,8 @@ bool p3IdService::encodeIdGroupCache(std::string &str, const IdGroupServiceStrDa bool p3IdService::extractIdGroupCache(std::string &str, IdGroupServiceStrData &data) { - char pgpline[RSGXS_MAX_SERVICE_STRING]; - char scoreline[RSGXS_MAX_SERVICE_STRING]; + char pgpline[RSGXSID_MAX_SERVICE_STRING]; + char scoreline[RSGXSID_MAX_SERVICE_STRING]; uint32_t iOwnScore; IdRepCumulScore iOpin; @@ -944,10 +958,10 @@ bool p3IdService::background_FullCalcRequest() /* request the summary info from the parents */ uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; uint32_t token = 0; - RsTokReqOptions opts; + RsTokReqOptionsV2 opts; opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - requestMsgInfo(token, ansType, opts, groupIds); + RsGenExchange::getTokenService()->requestMsgInfo(token, ansType, opts, groupIds); { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ @@ -967,7 +981,6 @@ bool p3IdService::background_processFullCalc() std::list msgList; std::list::iterator it; - RsIdMsg msg; bool validmsgs = false; @@ -982,20 +995,40 @@ bool p3IdService::background_processFullCalc() double rep_sum = 0; double rep_sumsq = 0; - while(getMsgData(mBgToken, msg)) + std::vector opinions; + std::vector::iterator vit; + + if (!getMsgData(mBgToken, opinions)) { + std::cerr << "p3IdService::background_processFullCalc() ERROR Failed to get Opinions"; + std::cerr << std::endl; + + return false; + } + + std::string groupId; + for(vit = opinions.begin(); vit != opinions.end(); vit++) + { + RsGxsIdOpinion &opinion = *vit; + + /* These should all be same group - should check for sanity! */ + if (groupId == "") + { + groupId = opinion.mMeta.mGroupId; + } + std::cerr << "p3IdService::background_processFullCalc() Msg:"; - std::cerr << msg; + std::cerr << opinion; std::cerr << std::endl; validmsgs = true; - /* for each msg ... extract score, and reputation */ - if (msg.mOpinion != 0) + /* for each opinion.... extract score, and reputation */ + if (opinion.mOpinion != 0) { opinion_count++; - opinion_sum += msg.mOpinion; - opinion_sum += (msg.mOpinion * msg.mOpinion); + opinion_sum += opinion.mOpinion; + opinion_sum += (opinion.mOpinion * opinion.mOpinion); } else { @@ -1003,12 +1036,12 @@ bool p3IdService::background_processFullCalc() } - /* for each msg ... extract score, and reputation */ - if (msg.mReputation != 0) + /* for each opinion.... extract score, and reputation */ + if (opinion.mReputation != 0) { rep_nullcount++; - rep_sum += msg.mReputation; - rep_sum += (msg.mReputation * msg.mReputation); + rep_sum += opinion.mReputation; + rep_sum += (opinion.mReputation * opinion.mReputation); } else { @@ -1042,8 +1075,6 @@ bool p3IdService::background_processFullCalc() if (validmsgs) { - std::string groupId = msg.mMeta.mGroupId; - std::string serviceString; IdGroupServiceStrData ssData; @@ -1058,7 +1089,8 @@ bool p3IdService::background_processFullCalc() std::cerr << "p3IdService::background_updateVoteCounts() Encoded String: " << serviceString; std::cerr << std::endl; /* store new result */ - setGroupServiceString(it->mMsgId, serviceString); + uint32_t dummyToken = 0; + setGroupServiceString(dummyToken, groupId, serviceString); } } @@ -1090,9 +1122,9 @@ bool p3IdService::background_cleanup() } -std::ostream &operator<<(std::ostream &out, const RsIdGroup &grp) +std::ostream &operator<<(std::ostream &out, const RsGxsIdGroup &grp) { - out << "RsIdGroup: Meta: " << grp.mMeta; + out << "RsGxsIdGroup: Meta: " << grp.mMeta; out << " IdType: " << grp.mIdType << " GpgIdHash: " << grp.mGpgIdHash; out << "(((Unusable: ( GpgIdKnown: " << grp.mGpgIdKnown << " GpgId: " << grp.mGpgId; out << " GpgName: " << grp.mGpgName << " GpgEmail: " << grp.mGpgEmail << ") )))"; @@ -1101,10 +1133,9 @@ std::ostream &operator<<(std::ostream &out, const RsIdGroup &grp) return out; } -std::ostream &operator<<(std::ostream &out, const RsIdMsg &msg) +std::ostream &operator<<(std::ostream &out, const RsGxsIdOpinion &opinion) { - out << "RsIdMsg: Meta: " << msg.mMeta; - //out << " IdType: " << grp.mIdType << " GpgIdHash: " << grp.mGpgIdHash; + out << "RsGxsIdOpinion: Meta: " << opinion.mMeta; out << std::endl; return out; diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index ba9e05575..64d48a4dc 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -26,10 +26,10 @@ #ifndef P3_IDENTITY_SERVICE_HEADER #define P3_IDENTITY_SERVICE_HEADER -#include "services/p3service.h" -#include "services/p3gxsservice.h" -#include "retroshare/rsidentity.h" +#include "retroshare/rsidentity.h" // External Interfaces. +#include "gxs/rsgenexchange.h" // GXS service. +#include "gxs/rsgixs.h" // Internal Interfaces. #include #include @@ -74,7 +74,7 @@ public: // Not sure exactly what should be inherited here? // Chris - please correct as necessary. -class p3IdService: public RsIdentity, public RsGxsIdExchange +class p3IdService: public RsGxsIdExchange, public RsIdentity { public: p3IdService(RsGeneralDataService* gds, RsNetworkExchangeService* nes); @@ -86,17 +86,21 @@ class p3IdService: public RsIdentity, public RsGxsIdExchange /* Data Specific Interface */ - /* TODO */ + // These are exposed via RsIdentity. +virtual bool getGroupData(const uint32_t &token, std::vector &groups); + // These are local - and not exposed via RsIdentity. +virtual bool getMsgData(const uint32_t &token, std::vector &opinions); +virtual bool createGroup(uint32_t& token, RsGxsIdGroup &group); +virtual bool createMsg(uint32_t& token, RsGxsIdOpinion &opinion); /**************** RsIdentity External Interface. * Notes: */ - -virtual bool getNickname(const RsId &id, std::string &nickname); -virtual bool getIdDetails(const RsId &id, RsIdentityDetails &details); -virtual bool getOwnIds(std::list &ownIds); +virtual bool getNickname(const RsGxsId &id, std::string &nickname); +virtual bool getIdDetails(const RsGxsId &id, RsIdentityDetails &details); +virtual bool getOwnIds(std::list &ownIds); // virtual bool submitOpinion(uint32_t& token, RsIdOpinion &opinion); @@ -109,11 +113,11 @@ virtual bool createIdentity(uint32_t& token, RsIdentityParameters ¶ms); * Results should be cached / preloaded for maximum speed. * */ -virtual bool haveKey(const GxsId &id); -virtual bool havePrivateKey(const GxsId &id); -virtual bool requestKey(const GxsId &id, const std::list &peers); -virtual int getKey(const GxsId &id, TlvSecurityKey &key); -virtual int getPrivateKey(const GxsId &id, TlvSecurityKey &key); +virtual bool haveKey(const RsGxsId &id); +virtual bool havePrivateKey(const RsGxsId &id); +virtual bool requestKey(const RsGxsId &id, const std::list &peers); +virtual int getKey(const RsGxsId &id, RsTlvSecurityKey &key); +virtual int getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key); /**************** RsGixsReputation Implementation * Notes: @@ -121,7 +125,7 @@ virtual int getPrivateKey(const GxsId &id, TlvSecurityKey &key); */ // get Reputation. -virtual bool getReputation(const GxsId &id, const GixsReputation &rep); +virtual bool getReputation(const RsGxsId &id, const GixsReputation &rep); private: diff --git a/libretroshare/src/services/p3photoserviceV2.cc b/libretroshare/src/services/p3photoserviceV2.cc index d208d2a2f..f14691210 100644 --- a/libretroshare/src/services/p3photoserviceV2.cc +++ b/libretroshare/src/services/p3photoserviceV2.cc @@ -354,9 +354,9 @@ bool p3PhotoServiceV2::acknowledgeGrp(const uint32_t& token, bool p3PhotoServiceV2::subscribeToAlbum(uint32_t &token, const RsGxsGroupId &grpId, bool subscribe) { if(subscribe) - RsGenExchange::setGroupSubscribeFlag(token, grpId, GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED); + RsGenExchange::setGroupSubscribeFlags(token, grpId, GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED, GXS_SERV::GROUP_SUBSCRIBE_MASK); else - RsGenExchange::setGroupSubscribeFlag(token, grpId, ~GXS_SERV::GROUP_SUBSCRIBE_MASK); + RsGenExchange::setGroupSubscribeFlags(token, grpId, 0, GXS_SERV::GROUP_SUBSCRIBE_MASK); return true; } From c5eee865a67fc83be1448c5ccb38ed5134c85d80 Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 21 Oct 2012 16:18:21 +0000 Subject: [PATCH 094/222] added definitions for RsGxsId serialiser items. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5703 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/serialiser/rsgxsiditems.h | 112 ++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 libretroshare/src/serialiser/rsgxsiditems.h diff --git a/libretroshare/src/serialiser/rsgxsiditems.h b/libretroshare/src/serialiser/rsgxsiditems.h new file mode 100644 index 000000000..a07e52732 --- /dev/null +++ b/libretroshare/src/serialiser/rsgxsiditems.h @@ -0,0 +1,112 @@ +/* + * libretroshare/src/serialiser: rsgxsiditems.h + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#ifndef RS_GXS_IDENTITY_ITEMS_H +#define RS_GXS_IDENTITY_ITEMS_H + +#include + +#include "serialiser/rsserviceids.h" +#include "serialiser/rsserial.h" +#include "serialiser/rstlvtypes.h" + +#include "rsgxsitems.h" +#include "retroshare/rsidentity.h" + +const uint8_t RS_PKT_SUBTYPE_GXSID_GROUP_ITEM = 0x02; +const uint8_t RS_PKT_SUBTYPE_GXSID_OPINION_ITEM = 0x03; +const uint8_t RS_PKT_SUBTYPE_GXSID_COMMENT_ITEM = 0x04; + +class RsGxsIdGroupItem : public RsGxsGrpItem +{ + +public: + + RsGxsIdGroupItem(): RsGxsGrpItem(RS_SERVICE_GXSV1_TYPE_GXSID, + RS_PKT_SUBTYPE_GXSID_GROUP_ITEM) { return;} + virtual ~RsGxsIdGroupItem() { return;} + + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + + RsGxsIdGroup group; +}; + +class RsGxsIdOpinionItem : public RsGxsMsgItem +{ +public: + + RsGxsIdOpinionItem(): RsGxsMsgItem(RS_SERVICE_GXSV1_TYPE_GXSID, + RS_PKT_SUBTYPE_GXSID_OPINION_ITEM) {return; } + virtual ~RsGxsIdOpinionItem() { return;} + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + RsGxsIdOpinion opinion; +}; + +class RsGxsIdCommentItem : public RsGxsMsgItem +{ +public: + + RsGxsIdCommentItem(): RsGxsMsgItem(RS_SERVICE_GXSV1_TYPE_GXSID, + RS_PKT_SUBTYPE_GXSID_COMMENT_ITEM) { return; } + virtual ~RsGxsIdCommentItem() { return; } + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + RsGxsIdComment comment; + +}; + +class RsGxsIdSerialiser : public RsSerialType +{ +public: + + RsGxsIdSerialiser() + :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXSV1_TYPE_GXSID) + { return; } + virtual ~RsGxsIdSerialiser() { return; } + + uint32_t size(RsItem *item); + bool serialise (RsItem *item, void *data, uint32_t *size); + RsItem * deserialise(void *data, uint32_t *size); + + private: + + uint32_t sizeGxsIdGroupItem(RsGxsIdGroupItem *item); + bool serialiseGxsIdGroupItem (RsGxsIdGroupItem *item, void *data, uint32_t *size); + RsGxsIdGroupItem * deserialiseGxsIdGroupItem(void *data, uint32_t *size); + + uint32_t sizeGxsIdOpinionItem(RsGxsIdOpinionItem *item); + bool serialiseGxsIdOpinionItem (RsGxsIdOpinionItem *item, void *data, uint32_t *size); + RsGxsIdOpinionItem * deserialiseGxsIdOpinionItem(void *data, uint32_t *size); + + uint32_t sizeGxsIdCommentItem(RsGxsIdCommentItem *item); + bool serialiseGxsIdCommentItem (RsGxsIdCommentItem *item, void *data, uint32_t *size); + RsGxsIdCommentItem * deserialiseGxsIdCommentItem(void *data, uint32_t *size); + +}; + +#endif /* RS_GXS_IDENTITY_ITEMS_H */ From 85cd85fec6e4111d559e17136b2eaf96965bc7f5 Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 21 Oct 2012 17:21:15 +0000 Subject: [PATCH 095/222] disabled VEG services. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5704 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/libretroshare.pro | 2 +- libretroshare/src/rsserver/rsinit.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index a39ea250d..db92ccbee 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -10,7 +10,7 @@ CONFIG += test_voip # GXS Stuff. CONFIG += newcache -CONFIG += newservices +#CONFIG += newservices # Beware: All data of the stripped services are lost DEFINES *= PQI_DISABLE_TUNNEL diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index a0b0ebcb2..9932a7a0b 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1808,7 +1808,7 @@ RsTurtle *rsTurtle = NULL ; #include "services/p3blogs.h" #include "turtle/p3turtle.h" -#define ENABLE_GXS_SERVICES 1 +//#define ENABLE_GXS_SERVICES 1 #define ENABLE_GXS_CORE 1 #ifdef ENABLE_GXS_CORE From dcb64f6631af4ca163296e82cbfc404d0d49cb5a Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 21 Oct 2012 19:15:46 +0000 Subject: [PATCH 096/222] Added Identity caching to Identity Service. - various p3IdService::cache_... fns. - moved duplicated print functions to GXS code. - restored compilation of VEG services. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5705 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/libretroshare.pro | 2 +- libretroshare/src/rsserver/rsinit.cc | 2 +- libretroshare/src/serialiser/rsgxsitems.cc | 10 +- libretroshare/src/services/p3gxsserviceVEG.cc | 2 + libretroshare/src/services/p3idservice.cc | 361 ++++++++++++++++++ libretroshare/src/services/p3idservice.h | 58 +++ 6 files changed, 431 insertions(+), 4 deletions(-) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index db92ccbee..a39ea250d 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -10,7 +10,7 @@ CONFIG += test_voip # GXS Stuff. CONFIG += newcache -#CONFIG += newservices +CONFIG += newservices # Beware: All data of the stripped services are lost DEFINES *= PQI_DISABLE_TUNNEL diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 9932a7a0b..a0b0ebcb2 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1808,7 +1808,7 @@ RsTurtle *rsTurtle = NULL ; #include "services/p3blogs.h" #include "turtle/p3turtle.h" -//#define ENABLE_GXS_SERVICES 1 +#define ENABLE_GXS_SERVICES 1 #define ENABLE_GXS_CORE 1 #ifdef ENABLE_GXS_CORE diff --git a/libretroshare/src/serialiser/rsgxsitems.cc b/libretroshare/src/serialiser/rsgxsitems.cc index a68f889f0..9f62c6da1 100644 --- a/libretroshare/src/serialiser/rsgxsitems.cc +++ b/libretroshare/src/serialiser/rsgxsitems.cc @@ -47,13 +47,19 @@ std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta) { - out << "RsGroupMetaData(TODO PRINT)"; + out << "[ GroupId: " << meta.mGroupId << " Name: " << meta.mGroupName << " ]"; return out; } std::ostream &operator<<(std::ostream &out, const RsMsgMetaData &meta) { - out << "RsMsgMetaData(TODO PRINT)"; + out << "[ GroupId: " << meta.mGroupId << " MsgId: " << meta.mMsgId; + out << " Name: " << meta.mMsgName; + out << " OrigMsgId: " << meta.mOrigMsgId; + out << " ThreadId: " << meta.mThreadId; + out << " ParentId: " << meta.mParentId; + out << " AuthorId: " << meta.mAuthorId; + out << " Name: " << meta.mMsgName << " ]"; return out; } diff --git a/libretroshare/src/services/p3gxsserviceVEG.cc b/libretroshare/src/services/p3gxsserviceVEG.cc index 5cb5cffcf..09eb6444f 100644 --- a/libretroshare/src/services/p3gxsserviceVEG.cc +++ b/libretroshare/src/services/p3gxsserviceVEG.cc @@ -1443,6 +1443,7 @@ bool p3GxsDataServiceVEG::fakeprocessrequests() return true; } +#if 0 // DISABLED AND MOVED TO GXS CODE. std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta) { @@ -1462,4 +1463,5 @@ std::ostream &operator<<(std::ostream &out, const RsMsgMetaData &meta) return out; } +#endif diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index b96a09c44..2ee7370ef 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -64,6 +64,8 @@ int p3IdService::internal_tick() // Disable for now. // background_tick(); + cache_tick(); + return 0; } @@ -226,6 +228,365 @@ bool p3IdService::createMsg(uint32_t& token, RsGxsIdOpinion &opinion) return true; } +/************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ + +/* Cache of recently used keys + * + * It is expensive to fetch the keys, so we want to keep them around if possible. + * It only stores the immutable stuff. + * + * This is probably crude and crap to start with. + * Want Least Recently Used (LRU) discard policy, without having to search whole cache. + * Use two maps: + * - CacheMap[key] => data. + * - LRUMultiMap[AccessTS] => key + * + * NOTE: This could be moved to a seperate class and templated to make generic + * as it might be generally useful. + * + */ + +bool p3IdService::cache_is_loaded(const RsGxsId &id) +{ + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + std::map::iterator it; + it = mCacheDataMap.find(id); + if (it == mCacheDataMap.end()) + { + return false; + } + return true; + +} + +bool p3IdService::cache_fetch(const RsGxsId &id, RsGxsIdCache &data) +{ + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + std::map::iterator it; + it = mCacheDataMap.find(id); + if (it == mCacheDataMap.end()) + { + return false; + } + + data = it->second; + + /* update ts on data */ + time_t old_ts = it->second.lastUsedTs; + time_t new_ts = time(NULL); + it->second.lastUsedTs = new_ts; + + locked_cache_update_lrumap(id, old_ts, new_ts); + + return true; +} + +bool p3IdService::cache_store(const RsGxsIdGroup &group) +{ + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + // Create Cache Data. + RsGxsIdCache cache(group); + + // For consistency + std::map::iterator it; + it = mCacheDataMap.find(cache.id); + if (it != mCacheDataMap.end()) + { + // ERROR. + return false; + } + + mCacheDataMap[cache.id] = cache; + mCacheDataCount++; + + /* add new lrumap entry */ + time_t old_ts = 0; + time_t new_ts = time(NULL); + it->second.lastUsedTs = new_ts; + + locked_cache_update_lrumap(cache.id, old_ts, new_ts); + + return true; +} + + +bool p3IdService::locked_cache_update_lrumap(const RsGxsId &key, time_t old_ts, time_t new_ts) +{ + if (old_ts == 0) + { + LruData data; + data.key = key; + /* new insertion */ + mCacheLruMap.insert(std::make_pair(new_ts, data)); + return true; + } + + /* find old entry */ + std::multimap::iterator mit; + std::multimap::iterator sit = mCacheLruMap.lower_bound(old_ts); + std::multimap::iterator eit = mCacheLruMap.upper_bound(old_ts); + + for(mit = sit; mit != eit; mit++) + { + if (mit->second.key == key) + { + LruData data = mit->second; + mCacheLruMap.erase(mit); + + if (new_ts != 0) // == 0, means remove. + { + mCacheLruMap.insert(std::make_pair(new_ts, data)); + } + return true; + } + } + return false; +} + + +bool p3IdService::cache_resize() +{ + int count_to_clear = 0; + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + // consistency check. + if ((mCacheDataMap.size() != mCacheDataCount) || + (mCacheLruMap.size() != mCacheDataCount)) + { + // ERROR. + + } + + if (mCacheDataCount > MAX_CACHE_SIZE) + { + count_to_clear = mCacheDataCount - MAX_CACHE_SIZE; + } + } + + if (count_to_clear > 0) + { + cache_discard_LRU(count_to_clear); + } + return true; +} + + + +bool p3IdService::cache_discard_LRU(int count_to_clear) +{ + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + while(count_to_clear > 0) + { + std::multimap::iterator mit = mCacheLruMap.begin(); + if (mit != mCacheLruMap.end()) + { + LruData data = mit->second; + mCacheLruMap.erase(mit); + + /* now clear from real cache */ + std::map::iterator it; + it = mCacheDataMap.find(data.key); + if (it == mCacheDataMap.end()) + { + // ERROR + std::cerr << "p3IdService::cache_discard_LRU(): ERROR Missing key: " << data.key; + std::cerr << std::endl; + return false; + } + else + { + mCacheDataMap.erase(it); + mCacheDataCount--; + } + } + else + { + // No More Data, ERROR. + std::cerr << "p3IdService::cache_discard_LRU(): INFO more more cache data"; + std::cerr << std::endl; + return true; + } + count_to_clear--; + } + return true; +} + + + + +/***** BELOW LOADS THE CACHE FROM GXS DATASTORE *****/ + +#define MIN_CYCLE_GAP 2 + +int p3IdService::cache_tick() +{ + std::cerr << "p3IdService::cache_tick()"; + std::cerr << std::endl; + + // Run Background Stuff. + background_checkTokenRequest(); + + /* every minute - run a background check */ + time_t now = time(NULL); + bool doCycle = false; + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + if (now - mCacheLoad_LastCycle > MIN_CYCLE_GAP) + { + doCycle = true; + mCacheLoad_LastCycle = now; + } + } + + if (doCycle) + { + cache_start_load(); + } + + cache_check_loading(); + + + return 0; +} + +bool p3IdService::cache_request_load(const RsGxsId &id) +{ + bool start = false; + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + mCacheLoad_ToCache.push_back(id); + + if (time(NULL) - mCacheLoad_LastCycle > MIN_CYCLE_GAP) + { + start = true; + } + } + + if (start) + cache_start_load(); + + return true; +} + + +bool p3IdService::cache_start_load() +{ + /* trigger request to load missing ids into cache */ + std::list groupIds; + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + mCacheLoad_LastCycle = time(NULL); + + mCacheLoad_Status = 1; + + /* now we process the modGroupList -> a map so we can use it easily later, and create id list too */ + std::list::iterator it; + for(it = mCacheLoad_ToCache.begin(); it != mCacheLoad_ToCache.end(); it++) + { + groupIds.push_back(*it); // might need conversion? + } + + mCacheLoad_ToCache.clear(); + } + + uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; + RsTokReqOptionsV2 opts; + uint32_t token = 0; + + RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts, groupIds); + + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + mCacheLoad_Tokens.push_back(token); + } + return 1; +} + +bool p3IdService::cache_check_loading() +{ + /* check the status of all active tokens */ + std::list toload; + std::list::iterator it; + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + for(it = mCacheLoad_Tokens.begin(); it != mCacheLoad_Tokens.end();) + { + uint32_t token = *it; + uint32_t status = RsGenExchange::getTokenService()->requestStatus(token); + //checkRequestStatus(token, status, reqtype, anstype, ts); + + if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + { + it = mCacheLoad_Tokens.erase(it); + toload.push_back(token); + } + else + { + it++; + } + } + } + + for(it = toload.begin(); it != toload.end(); it++) + { + cache_load_for_token(*it); + } + return 1; + +} + +bool p3IdService::cache_load_for_token(uint32_t token) +{ + std::cerr << "p3IdService::cache_load_for_token() : " << token; + std::cerr << std::endl; + + std::vector groups; + std::vector::iterator vit; + + if (!getGroupData(token, groups)) + { + std::cerr << "p3IdService::cache_load_for_token() ERROR no data"; + std::cerr << std::endl; + + return false; + } + + for(vit = groups.begin(); vit != groups.end(); vit++) + { + RsGxsIdGroup &group = *vit; + + std::cerr << "p3IdService::cache_load_for_token() Loaded Id with Meta: "; + std::cerr << group.mMeta; + std::cerr << std::endl; + + /* cache the data */ + cache_store(group); + } + + /* drop old entries */ + cache_resize(); + + return true; +} + + + +bool p3IdService::cache_check_consistency() +{ + + return false; +} + + /************************************************************************************/ /************************************************************************************/ /************************************************************************************/ diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index 64d48a4dc..cb528b3e1 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -71,6 +71,32 @@ public: +#define MAX_CACHE_SIZE 100 // Small for testing.. +//#define MAX_CACHE_SIZE 10000 // More useful size + +class RsGxsIdCache +{ + public: + RsGxsIdCache(); + RsGxsIdCache(const RsGxsIdGroup &group); + + RsGxsId id; + std::string name; + RsTlvSecurityKey pubkey; + double reputation; + time_t lastUsedTs; + +}; + + +class LruData +{ + public: + RsGxsId key; +}; + + + // Not sure exactly what should be inherited here? // Chris - please correct as necessary. @@ -129,6 +155,38 @@ virtual bool getReputation(const RsGxsId &id, const GixsReputation &rep); private: +/************************************************************************ + * This is the Cache for minimising calls to the DataStore. + * + */ + int cache_tick(); + + bool cache_is_loaded(const RsGxsId &id); + bool cache_fetch(const RsGxsId &key, RsGxsIdCache &data); + bool cache_store(const RsGxsIdGroup &group); + bool cache_resize(); + bool cache_discard_LRU(int count_to_clear); + + bool cache_request_load(const RsGxsId &id); + bool cache_start_load(); + bool cache_check_loading(); + bool cache_load_for_token(uint32_t token); + bool cache_check_consistency(); + + /* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */ + + bool locked_cache_update_lrumap(const RsGxsId &key, time_t old_ts, time_t new_ts); + + std::map mCacheDataMap; + std::multimap mCacheLruMap; + uint32_t mCacheDataCount; + + time_t mCacheLoad_LastCycle; + int mCacheLoad_Status; + std::list mCacheLoad_ToCache; + std::list mCacheLoad_Tokens; + + /************************************************************************ * Below is the background task for processing opinions => reputations * From c518bd2f19ca30604b3ba021abb61f3f50138216 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sun, 21 Oct 2012 19:45:35 +0000 Subject: [PATCH 097/222] Removed references to postedVEG from GxsGroupDialog and associated classes and PostedDialog (GUI does not work now but does not crash) Removed V2 references: TokenQueueV2 and RsTokReqOptionsV2 are now TokenQueue and RsTokReqOptions and renamed file Added initialisation of Posted back end service successfully Added new msg status flags GXS_SERV::MSG_STATUS_UNPROCESSED and ::MSG_STATUS_UNREAD git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5707 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgds.h | 2 +- libretroshare/src/gxs/rsgxsdata.h | 1 + libretroshare/src/gxs/rsgxsdataaccess.cc | 2873 +++++++++-------- libretroshare/src/gxs/rsgxsdataaccess.h | 734 ++--- libretroshare/src/gxs/rsgxsflags.h | 33 +- libretroshare/src/gxs/rsgxsnetservice.cc | 8 +- libretroshare/src/gxs/rsgxsnetservice.h | 1 + libretroshare/src/gxs/rsgxsrequesttypes.h | 3 +- libretroshare/src/gxs/rstokenservice.h | 17 +- libretroshare/src/libretroshare.pro | 27 +- libretroshare/src/retroshare/rsposted.h | 131 +- libretroshare/src/rsserver/rsinit.cc | 109 +- libretroshare/src/serialiser/rsgxsitems.h | 101 +- libretroshare/src/services/p3gxsserviceVEG.cc | 32 +- libretroshare/src/services/p3idservice.cc | 8 +- libretroshare/src/services/p3posted.cc | 156 +- libretroshare/src/services/p3posted.h | 20 +- retroshare-gui/src/RetroShare.pro | 22 +- .../src/gui/PhotoShare/AlbumCreateDialog.cpp | 2 +- .../src/gui/PhotoShare/AlbumCreateDialog.h | 6 +- .../src/gui/PhotoShare/AlbumDialog.cpp | 2 +- .../src/gui/PhotoShare/AlbumDialog.h | 6 +- .../src/gui/PhotoShare/PhotoDialog.cpp | 8 +- .../src/gui/PhotoShare/PhotoDialog.h | 8 +- .../src/gui/PhotoShare/PhotoShare.cpp | 22 +- .../src/gui/PhotoShare/PhotoShare.h | 8 +- .../src/gui/PhotoShare/PhotoSlideShow.cpp | 34 +- .../src/gui/PhotoShare/PhotoSlideShow.h | 10 +- .../src/gui/Posted/PostedComments.cpp | 561 +--- .../src/gui/Posted/PostedComments.h | 2 +- .../src/gui/Posted/PostedDialog.cpp | 598 +--- retroshare-gui/src/gui/Posted/PostedDialog.h | 2 +- retroshare-gui/src/gui/Posted/PostedItem.cpp | 250 +- retroshare-gui/src/gui/Posted/PostedItem.h | 2 +- .../src/gui/Posted/PostedListDialog.cpp | 105 +- .../src/gui/Posted/PostedListDialog.h | 10 +- .../src/gui/gxs/GxsCommentTreeWidget.cpp | 82 +- .../src/gui/gxs/GxsCommentTreeWidget.h | 12 +- retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp | 40 +- retroshare-gui/src/gui/gxs/GxsGroupDialog.h | 12 +- .../src/gui/gxs/PostedGroupDialog.cpp | 8 +- .../src/gui/unfinished/ApplicationWindow.cpp | 4 - .../util/{TokenQueueV2.cpp => TokenQueue.cpp} | 40 +- .../src/util/{TokenQueueV2.h => TokenQueue.h} | 28 +- 44 files changed, 2379 insertions(+), 3761 deletions(-) rename retroshare-gui/src/util/{TokenQueueV2.cpp => TokenQueue.cpp} (71%) rename retroshare-gui/src/util/{TokenQueueV2.h => TokenQueue.h} (78%) diff --git a/libretroshare/src/gxs/rsgds.h b/libretroshare/src/gxs/rsgds.h index 277473c8a..e80af47bc 100644 --- a/libretroshare/src/gxs/rsgds.h +++ b/libretroshare/src/gxs/rsgds.h @@ -36,7 +36,7 @@ #include "serialiser/rsnxsitems.h" #include "gxs/rsgxsdata.h" #include "rsgxs.h" -#include "util/retrodb.h" +#include "util/contentvalue.h" class RsGxsSearchModule { diff --git a/libretroshare/src/gxs/rsgxsdata.h b/libretroshare/src/gxs/rsgxsdata.h index 834ae187c..78dd3c8e4 100644 --- a/libretroshare/src/gxs/rsgxsdata.h +++ b/libretroshare/src/gxs/rsgxsdata.h @@ -109,6 +109,7 @@ public: // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. // normally READ / UNREAD flags. LOCAL Data. + uint32_t mMsgStatus; time_t mChildTs; diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index 06dae853d..c3cf80619 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -1,1436 +1,1437 @@ -/* - * libretroshare/src/retroshare: rsgxsdataaccess.cc - * - * RetroShare C++ Interface. - * - * Copyright 2012-2012 by Robert Fernie, Christopher Evi-Parker - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "rsgxsdataaccess.h" - -// This bit will be filled out over time. -#define RS_TOKREQOPT_MSG_VERSIONS 0x0001 // MSGRELATED: Returns All MsgIds with OrigMsgId = MsgId. -#define RS_TOKREQOPT_MSG_ORIGMSG 0x0002 // MSGLIST: All Unique OrigMsgIds in a Group. -#define RS_TOKREQOPT_MSG_LATEST 0x0004 // MSGLIST: All Latest MsgIds in Group. MSGRELATED: Latest MsgIds for Input Msgs. - -#define RS_TOKREQOPT_MSG_THREAD 0x0010 // MSGRELATED: All Msgs in Thread. MSGLIST: All Unique Thread Ids in Group. -#define RS_TOKREQOPT_MSG_PARENT 0x0020 // MSGRELATED: All Children Msgs. - -#define RS_TOKREQOPT_MSG_AUTHOR 0x0040 // MSGLIST: Messages from this AuthorId - - -// Status Filtering... should it be a different Option Field. -#define RS_TOKREQOPT_GROUP_UPDATED 0x0100 // GROUPLIST: Groups that have been updated. -#define RS_TOKREQOPT_MSG_UPDATED 0x0200 // MSGLIST: Msg that have been updated from specified groups. -#define RS_TOKREQOPT_MSG_UPDATED 0x0200 // MSGLIST: Msg that have been updated from specified groups. - -// Read Status. -#define RS_TOKREQOPT_READ 0x0001 -#define RS_TOKREQOPT_UNREAD 0x0002 - -#define RS_TOKREQ_ANSTYPE_LIST 0x0001 -#define RS_TOKREQ_ANSTYPE_SUMMARY 0x0002 -#define RS_TOKREQ_ANSTYPE_DATA 0x0003 - - const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_FAILED = 0; - const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_PENDING = 1; - const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_PARTIAL = 2; - const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_FINISHED_INCOMPLETE = 3; - const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE = 4; - const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_DONE = 5; // ONCE ALL DATA RETRIEVED. - -RsGxsDataAccess::RsGxsDataAccess(RsGeneralDataService* ds) - : mDataStore(ds), mDataMutex("RsGxsDataAccess"), mNextToken(0) -{ -} - - -bool RsGxsDataAccess::requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, - const std::list &groupIds) -{ - if(groupIds.empty()) - { - std::cerr << "Group Id list is empty" << std::endl; - return false; - } - - GxsRequest* req = NULL; - uint32_t reqType = opts.mReqType; - - if(reqType & GXS_REQUEST_TYPE_GROUP_META) - { - GroupMetaReq* gmr = new GroupMetaReq(); - gmr->mGroupIds = groupIds; - req = gmr; - } - else if(reqType & GXS_REQUEST_TYPE_GROUP_DATA) - { - GroupDataReq* gdr = new GroupDataReq(); - gdr->mGroupIds = groupIds; - req = gdr; - } - else if(reqType & GXS_REQUEST_TYPE_GROUP_IDS) - { - GroupIdReq* gir = new GroupIdReq(); - gir->mGroupIds = groupIds; - req = gir; - } - - if(req == NULL) - { - std::cerr << "RsGxsDataAccess::requestMsgInfo() request type not recognised, type " - << reqType << std::endl; - return false; - }else - { - generateToken(token); - std::cerr << "RsGxsDataAccess::requestMsgInfo() gets Token: " << token << std::endl; - } - - setReq(req, token, ansType, opts); - storeRequest(req); - - return true; -} - -bool RsGxsDataAccess::requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts) -{ - - GxsRequest* req = NULL; - uint32_t reqType = opts.mReqType; - - if(reqType & GXS_REQUEST_TYPE_GROUP_META) - { - GroupMetaReq* gmr = new GroupMetaReq(); - req = gmr; - } - else if(reqType & GXS_REQUEST_TYPE_GROUP_DATA) - { - GroupDataReq* gdr = new GroupDataReq(); - req = gdr; - } - else if(reqType & GXS_REQUEST_TYPE_GROUP_IDS) - { - GroupIdReq* gir = new GroupIdReq(); - req = gir; - } - - if(req == NULL) - { - std::cerr << "RsGxsDataAccess::requestMsgInfo() request type not recognised, type " - << reqType << std::endl; - return false; - }else - { - generateToken(token); - std::cerr << "RsGxsDataAccess::requestMsgInfo() gets Token: " << token << std::endl; - } - - setReq(req, token, ansType, opts); - storeRequest(req); - - return true; -} - -void RsGxsDataAccess::generateToken(uint32_t &token) -{ - RsStackMutex stack(mDataMutex); /****** LOCKED *****/ - - token = mNextToken++; - - return; -} - - -bool RsGxsDataAccess::requestMsgInfo(uint32_t &token, uint32_t ansType, - const RsTokReqOptionsV2 &opts, const GxsMsgReq &msgIds) -{ - - GxsRequest* req = NULL; - uint32_t reqType = opts.mReqType; - - // remove all empty grpId entries - GxsMsgReq::const_iterator mit = msgIds.begin(); - std::vector toRemove; - - for(; mit != msgIds.end(); mit++) - { - if(mit->second.empty()) - toRemove.push_back(mit->first); - } - - std::vector::const_iterator vit = toRemove.begin(); - - GxsMsgReq filteredMsgIds = msgIds; - - for(; vit != toRemove.end(); vit++) - filteredMsgIds.erase(*vit); - - if(reqType & GXS_REQUEST_TYPE_MSG_META) - { - MsgMetaReq* mmr = new MsgMetaReq(); - mmr->mMsgIds = filteredMsgIds; - req = mmr; - - }else if(reqType & GXS_REQUEST_TYPE_MSG_DATA) - { - MsgDataReq* mdr = new MsgDataReq(); - mdr->mMsgIds = filteredMsgIds; - req = mdr; - - }else if(reqType & GXS_REQUEST_TYPE_MSG_IDS) - { - MsgIdReq* mir = new MsgIdReq(); - mir->mMsgIds = filteredMsgIds; - req = mir; - - } - - if(req == NULL) - { - std::cerr << "RsGxsDataAccess::requestMsgInfo() request type not recognised, type " - << reqType << std::endl; - return false; - }else - { - generateToken(token); - std::cerr << "RsGxsDataAccess::requestMsgInfo() gets Token: " << token << std::endl; - } - - setReq(req, token, ansType, opts); - storeRequest(req); - return true; -} - -bool RsGxsDataAccess::requestMsgInfo(uint32_t &token, uint32_t ansType, - const RsTokReqOptionsV2 &opts, const std::list& grpIds) -{ - GxsRequest* req = NULL; - uint32_t reqType = opts.mReqType; - - std::list::const_iterator lit = grpIds.begin(); - - if(reqType & GXS_REQUEST_TYPE_MSG_META) - { - MsgMetaReq* mmr = new MsgMetaReq(); - - for(; lit != grpIds.end(); lit++) - mmr->mMsgIds[*lit] = std::vector(); - - req = mmr; - }else if(reqType & GXS_REQUEST_TYPE_MSG_DATA) - { - MsgDataReq* mdr = new MsgDataReq(); - - for(; lit != grpIds.end(); lit++) - mdr->mMsgIds[*lit] = std::vector(); - - req = mdr; - }else if(reqType & GXS_REQUEST_TYPE_MSG_IDS) - { - MsgIdReq* mir = new MsgIdReq(); - - for(; lit != grpIds.end(); lit++) - mir->mMsgIds[*lit] = std::vector(); - - req = mir; - } - - if(req == NULL) - { - std::cerr << "RsGxsDataAccess::requestMsgInfo() request type not recognised, type " - << reqType << std::endl; - return false; - }else - { - generateToken(token); - std::cerr << "RsGxsDataAccess::requestMsgInfo() gets Token: " << token << std::endl; - } - - setReq(req, token, ansType, opts); - storeRequest(req); - return true; -} - -bool RsGxsDataAccess::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, - const RsGxsGrpMsgIdPair &msgIds) -{ - - MsgRelatedInfoReq* req = new MsgRelatedInfoReq(); - req->mMsgId = msgIds; - - generateToken(token); - - setReq(req, token, ansType, opts); - storeRequest(req); - - return true; -} - - -void RsGxsDataAccess::setReq(GxsRequest* req, const uint32_t& token, const uint32_t& ansType, const RsTokReqOptionsV2& opts) const -{ - req->token = token; - req->ansType = ansType; - req->Options = opts; - return; -} -void RsGxsDataAccess::storeRequest(GxsRequest* req) -{ - RsStackMutex stack(mDataMutex); /****** LOCKED *****/ - - req->status = GXS_REQUEST_V2_STATUS_PENDING; - mRequests[req->token] = req; - - return; -} - -uint32_t RsGxsDataAccess::requestStatus(uint32_t token) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - - { - RsStackMutex stack(mDataMutex); - - // first check public tokens - if(mPublicToken.find(token) != mPublicToken.end()) - return mPublicToken[token]; - } - checkRequestStatus(token, status, reqtype, anstype, ts); - - return status; -} - - - - - -bool RsGxsDataAccess::cancelRequest(const uint32_t& token) -{ - return clearRequest(token); -} - -bool RsGxsDataAccess::clearRequest(const uint32_t& token) -{ - RsStackMutex stack(mDataMutex); /****** LOCKED *****/ - - std::map::iterator it; - - it = mRequests.find(token); - if (it == mRequests.end()) - { - return false; - } - - delete it->second; - mRequests.erase(it->first); - - return true; -} - -bool RsGxsDataAccess::getGroupSummary(const uint32_t& token, std::list& groupInfo) -{ - - RsStackMutex stack(mDataMutex); - - GxsRequest* req = locked_retrieveRequest(token); - - if(req == NULL){ - - std::cerr << "RsGxsDataAccess::getGroupSummary() Unable to retrieve group summary" << std::endl; - return false; - }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ - - GroupMetaReq* gmreq = dynamic_cast(req); - - if(gmreq) - { - groupInfo = gmreq->mGroupMetaData; - locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); - }else{ - std::cerr << "RsGxsDataAccess::getGroupSummary() Req found, failed caste" << std::endl; - return false; - } - }else{ - std::cerr << "RsGxsDataAccess::getGroupSummary() Req not ready" << std::endl; - return false; - } - - return true; -} - -bool RsGxsDataAccess::getGroupData(const uint32_t& token, std::list& grpData) -{ - RsStackMutex stack(mDataMutex); - - GxsRequest* req = locked_retrieveRequest(token); - - if(req == NULL){ - - std::cerr << "RsGxsDataAccess::getGroupData() Unable to retrieve group data" << std::endl; - return false; - }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ - - GroupDataReq* gmreq = dynamic_cast(req); - - if(gmreq) - { - grpData = gmreq->mGroupData; - locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); - }else{ - std::cerr << "RsGxsDataAccess::getGroupData() Req found, failed caste" << std::endl; - return false; - } - }else{ - std::cerr << "RsGxsDataAccess::getGroupData() Req not ready" << std::endl; - return false; - } - - return true; -} - -bool RsGxsDataAccess::getMsgData(const uint32_t& token, NxsMsgDataResult& msgData) -{ - - RsStackMutex stack(mDataMutex); - - GxsRequest* req = locked_retrieveRequest(token); - - if(req == NULL){ - - std::cerr << "RsGxsDataAccess::getMsgData() Unable to retrieve group data" << std::endl; - return false; - }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ - - MsgDataReq* mdreq = dynamic_cast(req); - - if(mdreq) - { - msgData = mdreq->mMsgData; - locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); - }else{ - std::cerr << "RsGxsDataAccess::getMsgData() Req found, failed caste" << std::endl; - return false; - } - }else{ - std::cerr << "RsGxsDataAccess::getMsgData() Req not ready" << std::endl; - return false; - } - - return true; -} - -bool RsGxsDataAccess::getMsgSummary(const uint32_t& token, GxsMsgMetaResult& msgInfo) -{ - - RsStackMutex stack(mDataMutex); - - GxsRequest* req = locked_retrieveRequest(token); - - if(req == NULL){ - - std::cerr << "RsGxsDataAccess::getMsgSummary() Unable to retrieve group data" << std::endl; - return false; - }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ - - MsgMetaReq* mmreq = dynamic_cast(req); - - if(mmreq) - { - msgInfo = mmreq->mMsgMetaData; - locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); - - }else{ - std::cerr << "RsGxsDataAccess::getMsgSummary() Req found, failed caste" << std::endl; - return false; - } - }else{ - std::cerr << "RsGxsDataAccess::getMsgSummary() Req not ready" << std::endl; - return false; - } - - return true; -} - -bool RsGxsDataAccess::getMsgList(const uint32_t& token, GxsMsgIdResult& msgIds) -{ - RsStackMutex stack(mDataMutex); - - GxsRequest* req = locked_retrieveRequest(token); - - if(req == NULL){ - - std::cerr << "RsGxsDataAccess::getMsgList() Unable to retrieve group data" << std::endl; - return false; - }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ - - MsgIdReq* mireq = dynamic_cast(req); - MsgRelatedInfoReq* mrireq = dynamic_cast(req); - - if(mireq) - { - msgIds = mireq->mMsgIdResult; - locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); - } - else if(mrireq) - { - msgIds = mrireq->mMsgIdResult; - locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); - } - else{ - std::cerr << "RsGxsDataAccess::getMsgList() Req found, failed caste" << std::endl; - return false; - } - }else{ - std::cerr << "RsGxsDataAccess::getMsgList() Req not ready" << std::endl; - return false; - } - - return true; -} - -bool RsGxsDataAccess::getGroupList(const uint32_t& token, std::list& groupIds) -{ - RsStackMutex stack(mDataMutex); - - GxsRequest* req = locked_retrieveRequest(token); - - if(req == NULL){ - - std::cerr << "RsGxsDataAccess::getGroupList() Unable to retrieve group data," - "\nRequest does not exist" << std::endl; - return false; - }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ - - GroupIdReq* gireq = dynamic_cast(req); - - if(gireq) - { - groupIds = gireq->mGroupIdResult; - locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); - - }else{ - std::cerr << "RsGxsDataAccess::getGroupList() Req found, failed caste" << std::endl; - return false; - } - }else{ - std::cerr << "RsGxsDataAccess::getGroupList() Req not ready" << std::endl; - return false; - } - - return true; -} - - -GxsRequest* RsGxsDataAccess::locked_retrieveRequest(const uint32_t& token) -{ - - if(mRequests.find(token) == mRequests.end()) return NULL; - - GxsRequest* req = mRequests[token]; - - return req; -} - -#define MAX_REQUEST_AGE 10 - -void RsGxsDataAccess::processRequests() -{ - - std::list toClear; - std::list::iterator cit; - time_t now = time(NULL); - - { - RsStackMutex stack(mDataMutex); /******* LOCKED *******/ - - std::map::iterator it; - - GroupMetaReq* gmr; - GroupDataReq* gdr; - GroupIdReq* gir; - - MsgMetaReq* mmr; - MsgDataReq* mdr; - MsgIdReq* mir; - MsgRelatedInfoReq* mri; - - for(it = mRequests.begin(); it != mRequests.end(); it++) - { - - GxsRequest* req = it->second; - if (req->status == GXS_REQUEST_V2_STATUS_PENDING) - { - std::cerr << "RsGxsDataAccess::processRequests() Processing Token: " << req->token << " Status: " - << req->status << " ReqType: " << req->reqType << " Age: " - << now - req->reqTime << std::endl; - - req->status = GXS_REQUEST_V2_STATUS_PARTIAL; - - /* PROCESS REQUEST! */ - - if((gmr = dynamic_cast(req)) != NULL) - { - getGroupSummary(gmr); - } - else if((gdr = dynamic_cast(req)) != NULL) - { - getGroupData(gdr); - } - else if((gir = dynamic_cast(req)) != NULL) - { - getGroupList(gir); - } - else if((mmr = dynamic_cast(req)) != NULL) - { - getMsgSummary(mmr); - } - else if((mdr = dynamic_cast(req)) != NULL) - { - getMsgData(mdr); - } - else if((mir = dynamic_cast(req)) != NULL) - { - getMsgList(mir); - } - else if((mri = dynamic_cast(req)) != NULL) - { - getMsgRelatedInfo(mri); - } - else - { - #ifdef GXSDATA_SERVE_DEBUG - std::cerr << "RsGxsDataAccess::processRequests() Failed to process request, token: " - << req->token << std::endl; - #endif - - req->status = GXS_REQUEST_V2_STATUS_FAILED; - } - } - else if (req->status == GXS_REQUEST_V2_STATUS_PARTIAL) - { - req->status = GXS_REQUEST_V2_STATUS_COMPLETE; - } - else if (req->status == GXS_REQUEST_V2_STATUS_DONE) - { - std::cerr << "RsGxsDataAccess::processrequests() Clearing Done Request Token: " - << req->token; - std::cerr << std::endl; - toClear.push_back(req->token); - } - else if (false/*now - req->reqTime > MAX_REQUEST_AGE*/) - { - std::cerr << "RsGxsDataAccess::processrequests() Clearing Old Request Token: " << req->token; - std::cerr << std::endl; - toClear.push_back(req->token); - } - } - - } // END OF MUTEX. - - for(cit = toClear.begin(); cit != toClear.end(); cit++) - { - clearRequest(*cit); - } - - return; -} - - -bool RsGxsDataAccess::getGroupData(GroupDataReq* req) -{ - std::map grpData; - - std::list::iterator lit = req->mGroupIds.begin(), - lit_end = req->mGroupIds.end(); - - for(; lit != lit_end; lit++) - { - grpData[*lit] = NULL; - } - - bool ok = mDataStore->retrieveNxsGrps(grpData, true, true); - - std::map::iterator mit = grpData.begin(); - for(; mit != grpData.end(); mit++) - req->mGroupData.push_back(mit->second); - - return ok; -} - -bool RsGxsDataAccess::getGroupSummary(GroupMetaReq* req) -{ - - std::map grpMeta; - - std::list::const_iterator lit = req->mGroupIds.begin(); - - for(; lit != req->mGroupIds.end(); lit++) - grpMeta[*lit] = NULL; - - mDataStore->retrieveGxsGrpMetaData(grpMeta); - - std::map::iterator mit = grpMeta.begin(); - - for(; mit != grpMeta.end(); mit++) - req->mGroupMetaData.push_back(mit->second); - - return true; -} - -bool RsGxsDataAccess::getGroupList(GroupIdReq* req) -{ - std::map grpMeta; - - std::list::const_iterator lit = req->mGroupIds.begin(); - - for(; lit != req->mGroupIds.end(); lit++) - grpMeta[*lit] = NULL; - - mDataStore->retrieveGxsGrpMetaData(grpMeta); - - std::map::iterator mit = grpMeta.begin(); - - for(; mit != grpMeta.end(); mit++) - { - req->mGroupIdResult.push_back(mit->first); - delete mit->second; // so wasteful!! - } - - return true; -} - -bool RsGxsDataAccess::getMsgData(MsgDataReq* req) -{ - GxsMsgResult result; - - GxsMsgReq msgIdOut; - - // filter based on options - getMsgList(req->mMsgIds, req->Options, msgIdOut); - - mDataStore->retrieveNxsMsgs(msgIdOut, result, true, true); - - req->mMsgData = result; - return true; -} - - -bool RsGxsDataAccess::getMsgSummary(MsgMetaReq* req) -{ - GxsMsgMetaResult result; - - GxsMsgReq msgIdOut; - - // filter based on options - getMsgList(req->mMsgIds, req->Options, msgIdOut); - - mDataStore->retrieveGxsMsgMetaData(msgIdOut, result); - req->mMsgMetaData = result; - - return true; -} - - -bool RsGxsDataAccess::getMsgList(const GxsMsgReq& msgIds, const RsTokReqOptionsV2& opts, GxsMsgReq& msgIdsOut) -{ - GxsMsgMetaResult result; - - mDataStore->retrieveGxsMsgMetaData(msgIds, result); - - /* CASEs this handles. - * Input is groupList + Flags. - * 1) No Flags => All Messages in those Groups. - * - */ - std::cerr << "RsGxsDataAccess::getMsgList()"; - std::cerr << std::endl; - - - bool onlyOrigMsgs = false; - bool onlyLatestMsgs = false; - bool onlyThreadHeadMsgs = false; - - // Can only choose one of these two. - if (opts.mOptions & RS_TOKREQOPT_MSG_ORIGMSG) - { - std::cerr << "RsGxsDataAccess::getMsgList() MSG_ORIGMSG"; - std::cerr << std::endl; - onlyOrigMsgs = true; - } - else if (opts.mOptions & RS_TOKREQOPT_MSG_LATEST) - { - std::cerr << "RsGxsDataAccess::getMsgList() MSG_LATEST"; - std::cerr << std::endl; - onlyLatestMsgs = true; - } - - if (opts.mOptions & RS_TOKREQOPT_MSG_THREAD) - { - std::cerr << "RsGxsDataAccess::getMsgList() MSG_THREAD"; - std::cerr << std::endl; - onlyThreadHeadMsgs = true; - } - - GxsMsgMetaResult::iterator meta_it; - MsgMetaFilter metaFilter; - - for(meta_it = result.begin(); meta_it != result.end(); meta_it++) - { - const RsGxsGroupId& grpId = meta_it->first; - - metaFilter[grpId] = std::map(); - - const std::vector& metaV = meta_it->second; - if (onlyLatestMsgs) // THIS ONE IS HARD -> LOTS OF COMP. - { - std::vector::const_iterator vit = metaV.begin(); - - // RUN THROUGH ALL MSGS... in map origId -> TS. - std::map > origMsgTs; - std::map >::iterator oit; - - for(; vit != metaV.end(); vit++) - { - RsGxsMsgMetaData* msgMeta = *vit; - - /* if we are grabbing thread Head... then parentId == empty. */ - if (onlyThreadHeadMsgs) - { - if (!(msgMeta->mParentId.empty())) - { - continue; - } - } - - - oit = origMsgTs.find(msgMeta->mOrigMsgId); - bool addMsg = false; - if (oit == origMsgTs.end()) - { - std::cerr << "RsGxsDataAccess::getMsgList() Found New OrigMsgId: "; - std::cerr << msgMeta->mOrigMsgId; - std::cerr << " MsgId: " << msgMeta->mMsgId; - std::cerr << " TS: " << msgMeta->mPublishTs; - std::cerr << std::endl; - - addMsg = true; - } - // check timestamps. - else if (oit->second.second < msgMeta->mPublishTs) - { - std::cerr << "RsGxsDataAccess::getMsgList() Found Later Msg. OrigMsgId: "; - std::cerr << msgMeta->mOrigMsgId; - std::cerr << " MsgId: " << msgMeta->mMsgId; - std::cerr << " TS: " << msgMeta->mPublishTs; - - addMsg = true; - } - - if (addMsg) - { - // add as latest. (overwriting if necessary) - origMsgTs[msgMeta->mOrigMsgId] = std::make_pair(msgMeta->mMsgId, msgMeta->mPublishTs); - metaFilter[grpId].insert(std::make_pair(msgMeta->mMsgId, msgMeta)); - } - } - - // Add the discovered Latest Msgs. - for(oit = origMsgTs.begin(); oit != origMsgTs.end(); oit++) - { - msgIdsOut[grpId].push_back(oit->second.first); - } - - } - else // ALL OTHER CASES. - { - std::vector::const_iterator vit = metaV.begin(); - - for(; vit != metaV.end(); vit++) - { - RsGxsMsgMetaData* msgMeta = *vit; - bool add = false; - - /* if we are grabbing thread Head... then parentId == empty. */ - if (onlyThreadHeadMsgs) - { - if (!(msgMeta->mParentId.empty())) - { - continue; - } - } - - - if (onlyOrigMsgs) - { - if (msgMeta->mMsgId == msgMeta->mOrigMsgId) - { - add = true; - } - } - else - { - add = true; - } - - if (add) - { - msgIdsOut[grpId].push_back(msgMeta->mMsgId); - metaFilter[grpId].insert(std::make_pair(msgMeta->mMsgId, msgMeta)); - } - - } - } - } - - filterMsgList(msgIdsOut, opts, metaFilter); - - metaFilter.clear(); - - // delete meta data - cleanseMsgMetaMap(result); - - return true; -} - -bool RsGxsDataAccess::getMsgRelatedInfo(MsgRelatedInfoReq *req) -{ - /* CASEs this handles. - * Input is msgList + Flags. - * 1) No Flags => return nothing - */ - - std::cerr << "RsGxsDataAccess::getMsgRelatedList()"; - std::cerr << std::endl; - - const RsTokReqOptionsV2& opts = req->Options; - - bool onlyLatestMsgs = false; - bool onlyAllVersions = false; - bool onlyChildMsgs = false; - bool onlyThreadMsgs = false; - - if (opts.mOptions & RS_TOKREQOPT_MSG_LATEST) - { - std::cerr << "RsGxsDataAccess::getMsgRelatedList() MSG_LATEST"; - std::cerr << std::endl; - onlyLatestMsgs = true; - } - else if (opts.mOptions & RS_TOKREQOPT_MSG_VERSIONS) - { - std::cerr << "RsGxsDataAccess::getMsgRelatedList() MSG_VERSIONS"; - std::cerr << std::endl; - onlyAllVersions = true; - } - - if (opts.mOptions & RS_TOKREQOPT_MSG_PARENT) - { - std::cerr << "RsGxsDataAccess::getMsgRelatedList() MSG_PARENTS"; - std::cerr << std::endl; - onlyChildMsgs = true; - } - - if (opts.mOptions & RS_TOKREQOPT_MSG_THREAD) - { - std::cerr << "RsGxsDataAccess::getMsgRelatedList() MSG_THREAD"; - std::cerr << std::endl; - onlyThreadMsgs = true; - } - - if (onlyAllVersions && onlyChildMsgs) - { - std::cerr << "RsGxsDataAccess::getMsgRelatedList() ERROR Incompatible FLAGS (VERSIONS & PARENT)"; - std::cerr << std::endl; - - return false; - } - - if (onlyAllVersions && onlyThreadMsgs) - { - std::cerr << "RsGxsDataAccess::getMsgRelatedList() ERROR Incompatible FLAGS (VERSIONS & THREAD)"; - std::cerr << std::endl; - - return false; - } - - if ((!onlyLatestMsgs) && onlyChildMsgs) - { - std::cerr << "RsGxsDataAccess::getMsgRelatedList() ERROR Incompatible FLAGS (!LATEST & PARENT)"; - std::cerr << std::endl; - - return false; - } - - if ((!onlyLatestMsgs) && onlyThreadMsgs) - { - std::cerr << "RsGxsDataAccess::getMsgRelatedList() ERROR Incompatible FLAGS (!LATEST & THREAD)"; - std::cerr << std::endl; - - return false; - } - - if (onlyChildMsgs && onlyThreadMsgs) - { - std::cerr << "RsGxsDataAccess::getMsgRelatedList() ERROR Incompatible FLAGS (PARENT & THREAD)"; - std::cerr << std::endl; - - return false; - } - - - /* FALL BACK OPTION */ - if ((!onlyLatestMsgs) && (!onlyAllVersions) && (!onlyChildMsgs) && (!onlyThreadMsgs)) - { - std::cerr << "RsGxsDataAccess::getMsgRelatedList() FALLBACK -> NO FLAGS -> SIMPLY RETURN nothing"; - std::cerr << std::endl; - - return true; - } - - MsgMetaFilter filterMap; - - // get meta data for all in group - GxsMsgMetaResult result; - GxsMsgReq msgIds; - msgIds.insert(std::make_pair(req->mMsgId.first, std::vector())); - mDataStore->retrieveGxsMsgMetaData(msgIds, result); - std::vector& metaV = result[req->mMsgId.first]; - std::vector::iterator vit_meta; - - // msg id to relate to - const RsGxsMessageId& msgId = req->mMsgId.second; - const RsGxsGroupId& grpId = req->mMsgId.first; - - std::vector outMsgIds; - - - - RsGxsMsgMetaData* origMeta = NULL; - for(vit_meta = metaV.begin(); vit_meta != metaV.end(); vit_meta++) - { - RsGxsMsgMetaData* meta = *vit_meta; - - if(msgId == meta->mMsgId) - { - origMeta = meta; - break; - } - } - - if(!origMeta) - { - std::cerr << "RsGxsDataAccess::getMsgRelatedInfo(): Cannot find meta of msgId (to relate to)!" - << std::endl; - cleanseMsgMetaMap(result); - return false; - } - - const RsGxsMessageId& origMsgId = origMeta->mOrigMsgId; - std::map& metaMap = filterMap[grpId]; - - if (onlyLatestMsgs) - { - if (onlyChildMsgs || onlyThreadMsgs) - { - // RUN THROUGH ALL MSGS... in map origId -> TS. - std::map > origMsgTs; - std::map >::iterator oit; - for(vit_meta = metaV.begin(); vit_meta != metaV.end(); vit_meta++) - { - - RsGxsMsgMetaData* meta = *vit_meta; - - // skip msgs that aren't children. - if (onlyChildMsgs) - { - if (meta->mParentId != origMsgId) - { - continue; - } - } - else /* onlyThreadMsgs */ - { - if (meta->mThreadId != msgId) - { - continue; - } - } - - - oit = origMsgTs.find(meta->mOrigMsgId); - - bool addMsg = false; - if (oit == origMsgTs.end()) - { - std::cerr << "RsGxsDataAccess::getMsgRelatedList() Found New OrigMsgId: "; - std::cerr << meta->mOrigMsgId; - std::cerr << " MsgId: " << meta->mMsgId; - std::cerr << " TS: " << meta->mPublishTs; - std::cerr << std::endl; - - addMsg = true; - } - // check timestamps. - else if (oit->second.second < meta->mPublishTs) - { - std::cerr << "RsGxsDataAccess::getMsgRelatedList() Found Later Msg. OrigMsgId: "; - std::cerr << meta->mOrigMsgId; - std::cerr << " MsgId: " << meta->mMsgId; - std::cerr << " TS: " << meta->mPublishTs; - - addMsg = true; - } - - if (addMsg) - { - // add as latest. (overwriting if necessary) - origMsgTs[meta->mOrigMsgId] = std::make_pair(meta->mMsgId, meta->mPublishTs); - metaMap.insert(std::make_pair(meta->mOrigMsgId, meta)); - } - } - - // Add the discovered Latest Msgs. - for(oit = origMsgTs.begin(); oit != origMsgTs.end(); oit++) - { - outMsgIds.push_back(oit->second.first); - } - } - else - { - - /* first guess is potentially better than Orig (can't be worse!) */ - time_t latestTs = 0; - RsGxsMessageId latestMsgId; - RsGxsMsgMetaData* latestMeta; - - for(vit_meta = metaV.begin(); vit_meta != metaV.end(); vit_meta++) - { - RsGxsMsgMetaData* meta = *vit_meta; - - if (meta->mOrigMsgId == origMsgId) - { - if (meta->mPublishTs > latestTs) - { - latestTs = meta->mPublishTs; - latestMsgId = meta->mMsgId; - latestMeta = meta; - } - } - } - outMsgIds.push_back(latestMsgId); - metaMap.insert(std::make_pair(latestMsgId, latestMeta)); - } - } - else if (onlyAllVersions) - { - for(vit_meta = metaV.begin(); vit_meta != metaV.end(); vit_meta++) - { - RsGxsMsgMetaData* meta = *vit_meta; - - if (meta->mOrigMsgId == origMsgId) - { - outMsgIds.push_back(meta->mMsgId); - metaMap.insert(std::make_pair(meta->mOrigMsgId, meta)); - } - } - } - - req->mMsgIdResult[grpId] = outMsgIds; - filterMsgList(req->mMsgIdResult, opts, filterMap); - - cleanseMsgMetaMap(result); - - return true; -} - -bool RsGxsDataAccess::getMsgList(MsgIdReq* req) -{ - - GxsMsgMetaResult result; - - mDataStore->retrieveGxsMsgMetaData(req->mMsgIds, result); - - - GxsMsgMetaResult::iterator mit = result.begin(), mit_end = result.end(); - - for(; mit != mit_end; mit++) - { - const RsGxsGroupId grpId = mit->first; - std::vector& metaV = mit->second; - std::vector::iterator vit = metaV.begin(), - vit_end = metaV.end(); - - for(; vit != vit_end; vit++) - { - RsGxsMsgMetaData* meta = *vit; - req->mMsgIdResult[grpId].push_back(meta->mMsgId); - delete meta; // discard meta data mem - } - } - - GxsMsgReq msgIdOut; - - // filter based on options - getMsgList(req->mMsgIdResult, req->Options, msgIdOut); - req->mMsgIdResult = msgIdOut; - - return true; -} - -void RsGxsDataAccess::cleanseMsgMetaMap(GxsMsgMetaResult& result) -{ - GxsMsgMetaResult::iterator mit = result.begin(); - - for(; mit !=result.end(); mit++) - { - - std::vector& msgMetaV = mit->second; - std::vector::iterator vit = msgMetaV.begin(); - for(; vit != msgMetaV.end(); vit++) - { - delete *vit; - } - } - - result.clear(); - return; -} - -void RsGxsDataAccess::filterMsgList(GxsMsgIdResult& msgIds, const RsTokReqOptionsV2& opts, - const MsgMetaFilter& msgMetas) const -{ - - GxsMsgIdResult::iterator mit = msgIds.begin(); - for(;mit != msgIds.end(); mit++) - { - - MsgMetaFilter::const_iterator cit = msgMetas.find(mit->first); - - if(cit == msgMetas.end()) - continue; - - std::vector& msgs = mit->second; - std::vector::iterator vit = msgs.begin(); - const std::map& meta = cit->second; - std::map::const_iterator cit2; - - for(; vit != msgs.end();) - { - - bool keep = false; - if( (cit2 = meta.find(*vit)) != meta.end() ) - { - keep = checkMsgFilter(opts, cit2->second); - } - - if(keep) - { - vit++; - }else - { - vit = msgs.erase(vit); - } - } - } -} - - -bool RsGxsDataAccess::checkRequestStatus(const uint32_t& token, - uint32_t& status, uint32_t& reqtype, uint32_t& anstype, time_t& ts) -{ - - RsStackMutex stack(mDataMutex); - - GxsRequest* req = locked_retrieveRequest(token); - - if(req == NULL) - return false; - - anstype = req->ansType; - reqtype = req->reqType; - status = req->status; - ts = req->reqTime; - - return true; -} - -bool RsGxsDataAccess::addGroupData(RsNxsGrp* grp) { - - RsStackMutex stack(mDataMutex); - - std::map grpM; - grpM.insert(std::make_pair(grp, grp->metaData)); - return mDataStore->storeGroup(grpM); -} - - - -bool RsGxsDataAccess::addMsgData(RsNxsMsg* msg) { - - RsStackMutex stack(mDataMutex); - - std::map msgM; - msgM.insert(std::make_pair(msg, msg->metaData)); - return mDataStore->storeMessage(msgM); -} - - - -void RsGxsDataAccess::tokenList(std::list& tokens) -{ - - RsStackMutex stack(mDataMutex); - - std::map::iterator mit = mRequests.begin(); - - for(; mit != mRequests.end(); mit++) - { - tokens.push_back(mit->first); - } -} - -bool RsGxsDataAccess::locked_updateRequestStatus(const uint32_t& token, - const uint32_t& status) -{ - - GxsRequest* req = locked_retrieveRequest(token); - - if(req) - req->status = status; - else - return false; - - return true; -} - -uint32_t RsGxsDataAccess::generatePublicToken() -{ - - uint32_t token; - generateToken(token); - - { - RsStackMutex stack(mDataMutex); - mPublicToken[token] = RsTokenService::GXS_REQUEST_V2_STATUS_PENDING; - } - - return token; -} - - - -bool RsGxsDataAccess::updatePublicRequestStatus(const uint32_t& token, - const uint32_t& status) -{ - RsStackMutex stack(mDataMutex); - std::map::iterator mit = mPublicToken.find(token); - - if(mit != mPublicToken.end()) - { - mit->second = status; - } - else - { - return false; - } - - return true; -} - - - -bool RsGxsDataAccess::disposeOfPublicToken(const uint32_t& token) -{ - RsStackMutex stack(mDataMutex); - std::map::iterator mit = mPublicToken.find(token); - - if(mit != mPublicToken.end()) - { - mPublicToken.erase(mit); - } - else - { - return false; - } - - return true; -} - -bool RsGxsDataAccess::checkMsgFilter(const RsTokReqOptionsV2& opts, const RsGxsMsgMetaData* meta) const -{ - bool statusMatch = false; - if (opts.mStatusMask) - { - // Exact Flags match required. - if ((opts.mStatusMask & opts.mStatusFilter) == (opts.mStatusMask & meta->mMsgStatus)) - { - std::cerr << "checkMsgFilter() Accepting Msg as StatusMatches: "; - std::cerr << " Mask: " << opts.mStatusMask << " StatusFilter: " << opts.mStatusFilter; - std::cerr << " MsgStatus: " << meta->mMsgStatus << " MsgId: " << meta->mMsgId; - std::cerr << std::endl; - - statusMatch = true; - } - else - { - std::cerr << "checkMsgFilter() Dropping Msg due to !StatusMatch "; - std::cerr << " Mask: " << opts.mStatusMask << " StatusFilter: " << opts.mStatusFilter; - std::cerr << " MsgStatus: " << meta->mMsgStatus << " MsgId: " << meta->mMsgId; - std::cerr << std::endl; - } - } - else - { - // no status comparision, - statusMatch = true; - } - - bool flagMatch = false; - - if(opts.mMsgFlagMask) - { - // Exact Flags match required. - if ((opts.mMsgFlagMask & opts.mMsgFlagFilter) == (opts.mMsgFlagMask & meta->mMsgFlags)) - { - std::cerr << "checkMsgFilter() Accepting Msg as FlagMatches: "; - std::cerr << " Mask: " << opts.mMsgFlagMask << " FlagFilter: " << opts.mMsgFlagFilter; - std::cerr << " MsgFlag: " << meta->mMsgFlags << " MsgId: " << meta->mMsgId; - std::cerr << std::endl; - - flagMatch = true; - } - else - { - std::cerr << "checkMsgFilter() Dropping Msg due to !FlagMatch "; - std::cerr << " Mask: " << opts.mMsgFlagMask << " FlagFilter: " << opts.mMsgFlagFilter; - std::cerr << " MsgFlag: " << meta->mMsgFlags << " MsgId: " << meta->mMsgId; - std::cerr << std::endl; - - flagMatch = false; - } - }else{ - flagMatch = true; - } - - return statusMatch && flagMatch; -} +/* + * libretroshare/src/retroshare: rsgxsdataaccess.cc + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie, Christopher Evi-Parker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "rsgxsdataaccess.h" + +// This bit will be filled out over time. +#define RS_TOKREQOPT_MSG_VERSIONS 0x0001 // MSGRELATED: Returns All MsgIds with OrigMsgId = MsgId. +#define RS_TOKREQOPT_MSG_ORIGMSG 0x0002 // MSGLIST: All Unique OrigMsgIds in a Group. +#define RS_TOKREQOPT_MSG_LATEST 0x0004 // MSGLIST: All Latest MsgIds in Group. MSGRELATED: Latest MsgIds for Input Msgs. + +#define RS_TOKREQOPT_MSG_THREAD 0x0010 // MSGRELATED: All Msgs in Thread. MSGLIST: All Unique Thread Ids in Group. +#define RS_TOKREQOPT_MSG_PARENT 0x0020 // MSGRELATED: All Children Msgs. + +#define RS_TOKREQOPT_MSG_AUTHOR 0x0040 // MSGLIST: Messages from this AuthorId + + +// Status Filtering... should it be a different Option Field. +#define RS_TOKREQOPT_GROUP_UPDATED 0x0100 // GROUPLIST: Groups that have been updated. +#define RS_TOKREQOPT_MSG_UPDATED 0x0200 // MSGLIST: Msg that have been updated from specified groups. +#define RS_TOKREQOPT_MSG_UPDATED 0x0200 // MSGLIST: Msg that have been updated from specified groups. + +// Read Status. +#define RS_TOKREQOPT_READ 0x0001 +#define RS_TOKREQOPT_UNREAD 0x0002 + +#define RS_TOKREQ_ANSTYPE_LIST 0x0001 +#define RS_TOKREQ_ANSTYPE_SUMMARY 0x0002 +#define RS_TOKREQ_ANSTYPE_DATA 0x0003 + + const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_FAILED = 0; + const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_PENDING = 1; + const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_PARTIAL = 2; + const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_FINISHED_INCOMPLETE = 3; + const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE = 4; + const uint8_t RsTokenService::GXS_REQUEST_V2_STATUS_DONE = 5; // ONCE ALL DATA RETRIEVED. + +RsGxsDataAccess::RsGxsDataAccess(RsGeneralDataService* ds) + : mDataStore(ds), mDataMutex("RsGxsDataAccess"), mNextToken(0) +{ +} + + +bool RsGxsDataAccess::requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, + const std::list &groupIds) +{ + if(groupIds.empty()) + { + std::cerr << "Group Id list is empty" << std::endl; + return false; + } + + GxsRequest* req = NULL; + uint32_t reqType = opts.mReqType; + + if(reqType & GXS_REQUEST_TYPE_GROUP_META) + { + GroupMetaReq* gmr = new GroupMetaReq(); + gmr->mGroupIds = groupIds; + req = gmr; + } + else if(reqType & GXS_REQUEST_TYPE_GROUP_DATA) + { + GroupDataReq* gdr = new GroupDataReq(); + gdr->mGroupIds = groupIds; + req = gdr; + } + else if(reqType & GXS_REQUEST_TYPE_GROUP_IDS) + { + GroupIdReq* gir = new GroupIdReq(); + gir->mGroupIds = groupIds; + req = gir; + } + + if(req == NULL) + { + std::cerr << "RsGxsDataAccess::requestMsgInfo() request type not recognised, type " + << reqType << std::endl; + return false; + }else + { + generateToken(token); + std::cerr << "RsGxsDataAccess::requestMsgInfo() gets Token: " << token << std::endl; + } + + setReq(req, token, ansType, opts); + storeRequest(req); + + return true; +} + +bool RsGxsDataAccess::requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts) +{ + + GxsRequest* req = NULL; + uint32_t reqType = opts.mReqType; + + if(reqType & GXS_REQUEST_TYPE_GROUP_META) + { + GroupMetaReq* gmr = new GroupMetaReq(); + req = gmr; + } + else if(reqType & GXS_REQUEST_TYPE_GROUP_DATA) + { + GroupDataReq* gdr = new GroupDataReq(); + req = gdr; + } + else if(reqType & GXS_REQUEST_TYPE_GROUP_IDS) + { + GroupIdReq* gir = new GroupIdReq(); + req = gir; + } + + if(req == NULL) + { + std::cerr << "RsGxsDataAccess::requestMsgInfo() request type not recognised, type " + << reqType << std::endl; + return false; + }else + { + generateToken(token); + std::cerr << "RsGxsDataAccess::requestMsgInfo() gets Token: " << token << std::endl; + } + + setReq(req, token, ansType, opts); + storeRequest(req); + + return true; +} + +void RsGxsDataAccess::generateToken(uint32_t &token) +{ + RsStackMutex stack(mDataMutex); /****** LOCKED *****/ + + token = mNextToken++; + + return; +} + + +bool RsGxsDataAccess::requestMsgInfo(uint32_t &token, uint32_t ansType, + const RsTokReqOptions &opts, const GxsMsgReq &msgIds) +{ + + GxsRequest* req = NULL; + uint32_t reqType = opts.mReqType; + + // remove all empty grpId entries + GxsMsgReq::const_iterator mit = msgIds.begin(); + std::vector toRemove; + + for(; mit != msgIds.end(); mit++) + { + if(mit->second.empty()) + toRemove.push_back(mit->first); + } + + std::vector::const_iterator vit = toRemove.begin(); + + GxsMsgReq filteredMsgIds = msgIds; + + for(; vit != toRemove.end(); vit++) + filteredMsgIds.erase(*vit); + + if(reqType & GXS_REQUEST_TYPE_MSG_META) + { + MsgMetaReq* mmr = new MsgMetaReq(); + mmr->mMsgIds = filteredMsgIds; + req = mmr; + + }else if(reqType & GXS_REQUEST_TYPE_MSG_DATA) + { + MsgDataReq* mdr = new MsgDataReq(); + mdr->mMsgIds = filteredMsgIds; + req = mdr; + + }else if(reqType & GXS_REQUEST_TYPE_MSG_IDS) + { + MsgIdReq* mir = new MsgIdReq(); + mir->mMsgIds = filteredMsgIds; + req = mir; + + } + + if(req == NULL) + { + std::cerr << "RsGxsDataAccess::requestMsgInfo() request type not recognised, type " + << reqType << std::endl; + return false; + }else + { + generateToken(token); + std::cerr << "RsGxsDataAccess::requestMsgInfo() gets Token: " << token << std::endl; + } + + setReq(req, token, ansType, opts); + storeRequest(req); + return true; +} + +bool RsGxsDataAccess::requestMsgInfo(uint32_t &token, uint32_t ansType, + const RsTokReqOptions &opts, const std::list& grpIds) +{ + GxsRequest* req = NULL; + uint32_t reqType = opts.mReqType; + + std::list::const_iterator lit = grpIds.begin(); + + if(reqType & GXS_REQUEST_TYPE_MSG_META) + { + MsgMetaReq* mmr = new MsgMetaReq(); + + for(; lit != grpIds.end(); lit++) + mmr->mMsgIds[*lit] = std::vector(); + + req = mmr; + }else if(reqType & GXS_REQUEST_TYPE_MSG_DATA) + { + MsgDataReq* mdr = new MsgDataReq(); + + for(; lit != grpIds.end(); lit++) + mdr->mMsgIds[*lit] = std::vector(); + + req = mdr; + }else if(reqType & GXS_REQUEST_TYPE_MSG_IDS) + { + MsgIdReq* mir = new MsgIdReq(); + + for(; lit != grpIds.end(); lit++) + mir->mMsgIds[*lit] = std::vector(); + + req = mir; + } + + if(req == NULL) + { + std::cerr << "RsGxsDataAccess::requestMsgInfo() request type not recognised, type " + << reqType << std::endl; + return false; + }else + { + generateToken(token); + std::cerr << "RsGxsDataAccess::requestMsgInfo() gets Token: " << token << std::endl; + } + + setReq(req, token, ansType, opts); + storeRequest(req); + return true; +} + +bool RsGxsDataAccess::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, + const RsGxsGrpMsgIdPair &msgIds) +{ + + MsgRelatedInfoReq* req = new MsgRelatedInfoReq(); + req->mMsgId = msgIds; + + generateToken(token); + + setReq(req, token, ansType, opts); + storeRequest(req); + + return true; +} + + +void RsGxsDataAccess::setReq(GxsRequest* req, const uint32_t& token, const uint32_t& ansType, const RsTokReqOptions& opts) const +{ + req->token = token; + req->ansType = ansType; + req->Options = opts; + return; +} +void RsGxsDataAccess::storeRequest(GxsRequest* req) +{ + RsStackMutex stack(mDataMutex); /****** LOCKED *****/ + + req->status = GXS_REQUEST_V2_STATUS_PENDING; + mRequests[req->token] = req; + + return; +} + +uint32_t RsGxsDataAccess::requestStatus(uint32_t token) +{ + uint32_t status; + uint32_t reqtype; + uint32_t anstype; + time_t ts; + + { + RsStackMutex stack(mDataMutex); + + // first check public tokens + if(mPublicToken.find(token) != mPublicToken.end()) + return mPublicToken[token]; + } + checkRequestStatus(token, status, reqtype, anstype, ts); + + return status; +} + + + + + +bool RsGxsDataAccess::cancelRequest(const uint32_t& token) +{ + return clearRequest(token); +} + +bool RsGxsDataAccess::clearRequest(const uint32_t& token) +{ + RsStackMutex stack(mDataMutex); /****** LOCKED *****/ + + std::map::iterator it; + + it = mRequests.find(token); + if (it == mRequests.end()) + { + return false; + } + + delete it->second; + mRequests.erase(it->first); + + return true; +} + +bool RsGxsDataAccess::getGroupSummary(const uint32_t& token, std::list& groupInfo) +{ + + RsStackMutex stack(mDataMutex); + + GxsRequest* req = locked_retrieveRequest(token); + + if(req == NULL){ + + std::cerr << "RsGxsDataAccess::getGroupSummary() Unable to retrieve group summary" << std::endl; + return false; + }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ + + GroupMetaReq* gmreq = dynamic_cast(req); + + if(gmreq) + { + groupInfo = gmreq->mGroupMetaData; + locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); + }else{ + std::cerr << "RsGxsDataAccess::getGroupSummary() Req found, failed caste" << std::endl; + return false; + } + }else{ + std::cerr << "RsGxsDataAccess::getGroupSummary() Req not ready" << std::endl; + return false; + } + + return true; +} + +bool RsGxsDataAccess::getGroupData(const uint32_t& token, std::list& grpData) +{ + RsStackMutex stack(mDataMutex); + + GxsRequest* req = locked_retrieveRequest(token); + + if(req == NULL){ + + std::cerr << "RsGxsDataAccess::getGroupData() Unable to retrieve group data" << std::endl; + return false; + }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ + + GroupDataReq* gmreq = dynamic_cast(req); + + if(gmreq) + { + grpData = gmreq->mGroupData; + locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); + }else{ + std::cerr << "RsGxsDataAccess::getGroupData() Req found, failed caste" << std::endl; + return false; + } + }else{ + std::cerr << "RsGxsDataAccess::getGroupData() Req not ready" << std::endl; + return false; + } + + return true; +} + +bool RsGxsDataAccess::getMsgData(const uint32_t& token, NxsMsgDataResult& msgData) +{ + + RsStackMutex stack(mDataMutex); + + GxsRequest* req = locked_retrieveRequest(token); + + if(req == NULL){ + + std::cerr << "RsGxsDataAccess::getMsgData() Unable to retrieve group data" << std::endl; + return false; + }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ + + MsgDataReq* mdreq = dynamic_cast(req); + + if(mdreq) + { + msgData = mdreq->mMsgData; + locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); + }else{ + std::cerr << "RsGxsDataAccess::getMsgData() Req found, failed caste" << std::endl; + return false; + } + }else{ + std::cerr << "RsGxsDataAccess::getMsgData() Req not ready" << std::endl; + return false; + } + + return true; +} + +bool RsGxsDataAccess::getMsgSummary(const uint32_t& token, GxsMsgMetaResult& msgInfo) +{ + + RsStackMutex stack(mDataMutex); + + GxsRequest* req = locked_retrieveRequest(token); + + if(req == NULL){ + + std::cerr << "RsGxsDataAccess::getMsgSummary() Unable to retrieve group data" << std::endl; + return false; + }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ + + MsgMetaReq* mmreq = dynamic_cast(req); + + if(mmreq) + { + msgInfo = mmreq->mMsgMetaData; + locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); + + }else{ + std::cerr << "RsGxsDataAccess::getMsgSummary() Req found, failed caste" << std::endl; + return false; + } + }else{ + std::cerr << "RsGxsDataAccess::getMsgSummary() Req not ready" << std::endl; + return false; + } + + return true; +} + +bool RsGxsDataAccess::getMsgList(const uint32_t& token, GxsMsgIdResult& msgIds) +{ + RsStackMutex stack(mDataMutex); + + GxsRequest* req = locked_retrieveRequest(token); + + if(req == NULL){ + + std::cerr << "RsGxsDataAccess::getMsgList() Unable to retrieve group data" << std::endl; + return false; + }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ + + MsgIdReq* mireq = dynamic_cast(req); + MsgRelatedInfoReq* mrireq = dynamic_cast(req); + + if(mireq) + { + msgIds = mireq->mMsgIdResult; + locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); + } + else if(mrireq) + { + msgIds = mrireq->mMsgIdResult; + locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); + } + else{ + std::cerr << "RsGxsDataAccess::getMsgList() Req found, failed caste" << std::endl; + return false; + } + }else{ + std::cerr << "RsGxsDataAccess::getMsgList() Req not ready" << std::endl; + return false; + } + + return true; +} + +bool RsGxsDataAccess::getGroupList(const uint32_t& token, std::list& groupIds) +{ + RsStackMutex stack(mDataMutex); + + GxsRequest* req = locked_retrieveRequest(token); + + if(req == NULL){ + + std::cerr << "RsGxsDataAccess::getGroupList() Unable to retrieve group data," + "\nRequest does not exist" << std::endl; + return false; + }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ + + GroupIdReq* gireq = dynamic_cast(req); + + if(gireq) + { + groupIds = gireq->mGroupIdResult; + locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); + + }else{ + std::cerr << "RsGxsDataAccess::getGroupList() Req found, failed caste" << std::endl; + return false; + } + }else{ + std::cerr << "RsGxsDataAccess::getGroupList() Req not ready" << std::endl; + return false; + } + + return true; +} + + +GxsRequest* RsGxsDataAccess::locked_retrieveRequest(const uint32_t& token) +{ + + if(mRequests.find(token) == mRequests.end()) return NULL; + + GxsRequest* req = mRequests[token]; + + return req; +} + +#define MAX_REQUEST_AGE 10 + +void RsGxsDataAccess::processRequests() +{ + + std::list toClear; + std::list::iterator cit; + time_t now = time(NULL); + + { + RsStackMutex stack(mDataMutex); /******* LOCKED *******/ + + std::map::iterator it; + + GroupMetaReq* gmr; + GroupDataReq* gdr; + GroupIdReq* gir; + + MsgMetaReq* mmr; + MsgDataReq* mdr; + MsgIdReq* mir; + MsgRelatedInfoReq* mri; + + for(it = mRequests.begin(); it != mRequests.end(); it++) + { + + GxsRequest* req = it->second; + if (req->status == GXS_REQUEST_V2_STATUS_PENDING) + { + std::cerr << "RsGxsDataAccess::processRequests() Processing Token: " << req->token << " Status: " + << req->status << " ReqType: " << req->reqType << " Age: " + << now - req->reqTime << std::endl; + + req->status = GXS_REQUEST_V2_STATUS_PARTIAL; + + /* PROCESS REQUEST! */ + + if((gmr = dynamic_cast(req)) != NULL) + { + getGroupSummary(gmr); + } + else if((gdr = dynamic_cast(req)) != NULL) + { + getGroupData(gdr); + } + else if((gir = dynamic_cast(req)) != NULL) + { + getGroupList(gir); + } + else if((mmr = dynamic_cast(req)) != NULL) + { + getMsgSummary(mmr); + } + else if((mdr = dynamic_cast(req)) != NULL) + { + getMsgData(mdr); + } + else if((mir = dynamic_cast(req)) != NULL) + { + getMsgList(mir); + } + else if((mri = dynamic_cast(req)) != NULL) + { + getMsgRelatedInfo(mri); + } + else + { + #ifdef GXSDATA_SERVE_DEBUG + std::cerr << "RsGxsDataAccess::processRequests() Failed to process request, token: " + << req->token << std::endl; + #endif + + req->status = GXS_REQUEST_V2_STATUS_FAILED; + } + } + else if (req->status == GXS_REQUEST_V2_STATUS_PARTIAL) + { + req->status = GXS_REQUEST_V2_STATUS_COMPLETE; + } + else if (req->status == GXS_REQUEST_V2_STATUS_DONE) + { + std::cerr << "RsGxsDataAccess::processrequests() Clearing Done Request Token: " + << req->token; + std::cerr << std::endl; + toClear.push_back(req->token); + } + else if (false/*now - req->reqTime > MAX_REQUEST_AGE*/) + { + std::cerr << "RsGxsDataAccess::processrequests() Clearing Old Request Token: " << req->token; + std::cerr << std::endl; + toClear.push_back(req->token); + } + } + + } // END OF MUTEX. + + for(cit = toClear.begin(); cit != toClear.end(); cit++) + { + clearRequest(*cit); + } + + return; +} + + +bool RsGxsDataAccess::getGroupData(GroupDataReq* req) +{ + std::map grpData; + + std::list::iterator lit = req->mGroupIds.begin(), + lit_end = req->mGroupIds.end(); + + for(; lit != lit_end; lit++) + { + grpData[*lit] = NULL; + } + + bool ok = mDataStore->retrieveNxsGrps(grpData, true, true); + + std::map::iterator mit = grpData.begin(); + for(; mit != grpData.end(); mit++) + req->mGroupData.push_back(mit->second); + + return ok; +} + +bool RsGxsDataAccess::getGroupSummary(GroupMetaReq* req) +{ + + std::map grpMeta; + + std::list::const_iterator lit = req->mGroupIds.begin(); + + for(; lit != req->mGroupIds.end(); lit++) + grpMeta[*lit] = NULL; + + mDataStore->retrieveGxsGrpMetaData(grpMeta); + + std::map::iterator mit = grpMeta.begin(); + + for(; mit != grpMeta.end(); mit++) + req->mGroupMetaData.push_back(mit->second); + + return true; +} + +bool RsGxsDataAccess::getGroupList(GroupIdReq* req) +{ + std::map grpMeta; + + std::list::const_iterator lit = req->mGroupIds.begin(); + + for(; lit != req->mGroupIds.end(); lit++) + grpMeta[*lit] = NULL; + + mDataStore->retrieveGxsGrpMetaData(grpMeta); + + std::map::iterator mit = grpMeta.begin(); + + for(; mit != grpMeta.end(); mit++) + { + req->mGroupIdResult.push_back(mit->first); + delete mit->second; // so wasteful!! + } + + return true; +} + +bool RsGxsDataAccess::getMsgData(MsgDataReq* req) +{ + GxsMsgResult result; + + GxsMsgReq msgIdOut; + + // filter based on options + getMsgList(req->mMsgIds, req->Options, msgIdOut); + + mDataStore->retrieveNxsMsgs(msgIdOut, result, true, true); + + req->mMsgData = result; + return true; +} + + +bool RsGxsDataAccess::getMsgSummary(MsgMetaReq* req) +{ + GxsMsgMetaResult result; + + GxsMsgReq msgIdOut; + + // filter based on options + getMsgList(req->mMsgIds, req->Options, msgIdOut); + + mDataStore->retrieveGxsMsgMetaData(msgIdOut, result); + req->mMsgMetaData = result; + + return true; +} + + +bool RsGxsDataAccess::getMsgList(const GxsMsgReq& msgIds, const RsTokReqOptions& opts, GxsMsgReq& msgIdsOut) +{ + GxsMsgMetaResult result; + + mDataStore->retrieveGxsMsgMetaData(msgIds, result); + + /* CASEs this handles. + * Input is groupList + Flags. + * 1) No Flags => All Messages in those Groups. + * + */ + std::cerr << "RsGxsDataAccess::getMsgList()"; + std::cerr << std::endl; + + + bool onlyOrigMsgs = false; + bool onlyLatestMsgs = false; + bool onlyThreadHeadMsgs = false; + + // Can only choose one of these two. + if (opts.mOptions & RS_TOKREQOPT_MSG_ORIGMSG) + { + std::cerr << "RsGxsDataAccess::getMsgList() MSG_ORIGMSG"; + std::cerr << std::endl; + onlyOrigMsgs = true; + } + else if (opts.mOptions & RS_TOKREQOPT_MSG_LATEST) + { + std::cerr << "RsGxsDataAccess::getMsgList() MSG_LATEST"; + std::cerr << std::endl; + onlyLatestMsgs = true; + } + + if (opts.mOptions & RS_TOKREQOPT_MSG_THREAD) + { + std::cerr << "RsGxsDataAccess::getMsgList() MSG_THREAD"; + std::cerr << std::endl; + onlyThreadHeadMsgs = true; + } + + GxsMsgMetaResult::iterator meta_it; + MsgMetaFilter metaFilter; + + for(meta_it = result.begin(); meta_it != result.end(); meta_it++) + { + const RsGxsGroupId& grpId = meta_it->first; + + metaFilter[grpId] = std::map(); + + const std::vector& metaV = meta_it->second; + if (onlyLatestMsgs) // THIS ONE IS HARD -> LOTS OF COMP. + { + std::vector::const_iterator vit = metaV.begin(); + + // RUN THROUGH ALL MSGS... in map origId -> TS. + std::map > origMsgTs; + std::map >::iterator oit; + + for(; vit != metaV.end(); vit++) + { + RsGxsMsgMetaData* msgMeta = *vit; + + /* if we are grabbing thread Head... then parentId == empty. */ + if (onlyThreadHeadMsgs) + { + if (!(msgMeta->mParentId.empty())) + { + continue; + } + } + + + oit = origMsgTs.find(msgMeta->mOrigMsgId); + bool addMsg = false; + if (oit == origMsgTs.end()) + { + std::cerr << "RsGxsDataAccess::getMsgList() Found New OrigMsgId: "; + std::cerr << msgMeta->mOrigMsgId; + std::cerr << " MsgId: " << msgMeta->mMsgId; + std::cerr << " TS: " << msgMeta->mPublishTs; + std::cerr << std::endl; + + addMsg = true; + } + // check timestamps. + else if (oit->second.second < msgMeta->mPublishTs) + { + std::cerr << "RsGxsDataAccess::getMsgList() Found Later Msg. OrigMsgId: "; + std::cerr << msgMeta->mOrigMsgId; + std::cerr << " MsgId: " << msgMeta->mMsgId; + std::cerr << " TS: " << msgMeta->mPublishTs; + + addMsg = true; + } + + if (addMsg) + { + // add as latest. (overwriting if necessary) + origMsgTs[msgMeta->mOrigMsgId] = std::make_pair(msgMeta->mMsgId, msgMeta->mPublishTs); + metaFilter[grpId].insert(std::make_pair(msgMeta->mMsgId, msgMeta)); + } + } + + // Add the discovered Latest Msgs. + for(oit = origMsgTs.begin(); oit != origMsgTs.end(); oit++) + { + msgIdsOut[grpId].push_back(oit->second.first); + } + + } + else // ALL OTHER CASES. + { + std::vector::const_iterator vit = metaV.begin(); + + for(; vit != metaV.end(); vit++) + { + RsGxsMsgMetaData* msgMeta = *vit; + bool add = false; + + /* if we are grabbing thread Head... then parentId == empty. */ + if (onlyThreadHeadMsgs) + { + if (!(msgMeta->mParentId.empty())) + { + continue; + } + } + + + if (onlyOrigMsgs) + { + if (msgMeta->mMsgId == msgMeta->mOrigMsgId) + { + add = true; + } + } + else + { + add = true; + } + + if (add) + { + msgIdsOut[grpId].push_back(msgMeta->mMsgId); + metaFilter[grpId].insert(std::make_pair(msgMeta->mMsgId, msgMeta)); + } + + } + } + } + + filterMsgList(msgIdsOut, opts, metaFilter); + + metaFilter.clear(); + + // delete meta data + cleanseMsgMetaMap(result); + + return true; +} + +bool RsGxsDataAccess::getMsgRelatedInfo(MsgRelatedInfoReq *req) +{ + /* CASEs this handles. + * Input is msgList + Flags. + * 1) No Flags => return nothing + */ + + std::cerr << "RsGxsDataAccess::getMsgRelatedList()"; + std::cerr << std::endl; + + const RsTokReqOptions& opts = req->Options; + + bool onlyLatestMsgs = false; + bool onlyAllVersions = false; + bool onlyChildMsgs = false; + bool onlyThreadMsgs = false; + + if (opts.mOptions & RS_TOKREQOPT_MSG_LATEST) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() MSG_LATEST"; + std::cerr << std::endl; + onlyLatestMsgs = true; + } + else if (opts.mOptions & RS_TOKREQOPT_MSG_VERSIONS) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() MSG_VERSIONS"; + std::cerr << std::endl; + onlyAllVersions = true; + } + + if (opts.mOptions & RS_TOKREQOPT_MSG_PARENT) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() MSG_PARENTS"; + std::cerr << std::endl; + onlyChildMsgs = true; + } + + if (opts.mOptions & RS_TOKREQOPT_MSG_THREAD) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() MSG_THREAD"; + std::cerr << std::endl; + onlyThreadMsgs = true; + } + + if (onlyAllVersions && onlyChildMsgs) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() ERROR Incompatible FLAGS (VERSIONS & PARENT)"; + std::cerr << std::endl; + + return false; + } + + if (onlyAllVersions && onlyThreadMsgs) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() ERROR Incompatible FLAGS (VERSIONS & THREAD)"; + std::cerr << std::endl; + + return false; + } + + if ((!onlyLatestMsgs) && onlyChildMsgs) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() ERROR Incompatible FLAGS (!LATEST & PARENT)"; + std::cerr << std::endl; + + return false; + } + + if ((!onlyLatestMsgs) && onlyThreadMsgs) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() ERROR Incompatible FLAGS (!LATEST & THREAD)"; + std::cerr << std::endl; + + return false; + } + + if (onlyChildMsgs && onlyThreadMsgs) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() ERROR Incompatible FLAGS (PARENT & THREAD)"; + std::cerr << std::endl; + + return false; + } + + + /* FALL BACK OPTION */ + if ((!onlyLatestMsgs) && (!onlyAllVersions) && (!onlyChildMsgs) && (!onlyThreadMsgs)) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() FALLBACK -> NO FLAGS -> SIMPLY RETURN nothing"; + std::cerr << std::endl; + + return true; + } + + MsgMetaFilter filterMap; + + // get meta data for all in group + GxsMsgMetaResult result; + GxsMsgReq msgIds; + msgIds.insert(std::make_pair(req->mMsgId.first, std::vector())); + mDataStore->retrieveGxsMsgMetaData(msgIds, result); + std::vector& metaV = result[req->mMsgId.first]; + std::vector::iterator vit_meta; + + // msg id to relate to + const RsGxsMessageId& msgId = req->mMsgId.second; + const RsGxsGroupId& grpId = req->mMsgId.first; + + std::vector outMsgIds; + + + + RsGxsMsgMetaData* origMeta = NULL; + for(vit_meta = metaV.begin(); vit_meta != metaV.end(); vit_meta++) + { + RsGxsMsgMetaData* meta = *vit_meta; + + if(msgId == meta->mMsgId) + { + origMeta = meta; + break; + } + } + + if(!origMeta) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedInfo(): Cannot find meta of msgId (to relate to)!" + << std::endl; + cleanseMsgMetaMap(result); + return false; + } + + const RsGxsMessageId& origMsgId = origMeta->mOrigMsgId; + std::map& metaMap = filterMap[grpId]; + + if (onlyLatestMsgs) + { + if (onlyChildMsgs || onlyThreadMsgs) + { + // RUN THROUGH ALL MSGS... in map origId -> TS. + std::map > origMsgTs; + std::map >::iterator oit; + for(vit_meta = metaV.begin(); vit_meta != metaV.end(); vit_meta++) + { + + RsGxsMsgMetaData* meta = *vit_meta; + + // skip msgs that aren't children. + if (onlyChildMsgs) + { + if (meta->mParentId != origMsgId) + { + continue; + } + } + else /* onlyThreadMsgs */ + { + if (meta->mThreadId != msgId) + { + continue; + } + } + + + oit = origMsgTs.find(meta->mOrigMsgId); + + bool addMsg = false; + if (oit == origMsgTs.end()) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() Found New OrigMsgId: "; + std::cerr << meta->mOrigMsgId; + std::cerr << " MsgId: " << meta->mMsgId; + std::cerr << " TS: " << meta->mPublishTs; + std::cerr << std::endl; + + addMsg = true; + } + // check timestamps. + else if (oit->second.second < meta->mPublishTs) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() Found Later Msg. OrigMsgId: "; + std::cerr << meta->mOrigMsgId; + std::cerr << " MsgId: " << meta->mMsgId; + std::cerr << " TS: " << meta->mPublishTs; + + addMsg = true; + } + + if (addMsg) + { + // add as latest. (overwriting if necessary) + origMsgTs[meta->mOrigMsgId] = std::make_pair(meta->mMsgId, meta->mPublishTs); + metaMap.insert(std::make_pair(meta->mOrigMsgId, meta)); + } + } + + // Add the discovered Latest Msgs. + for(oit = origMsgTs.begin(); oit != origMsgTs.end(); oit++) + { + outMsgIds.push_back(oit->second.first); + } + } + else + { + + /* first guess is potentially better than Orig (can't be worse!) */ + time_t latestTs = 0; + RsGxsMessageId latestMsgId; + RsGxsMsgMetaData* latestMeta; + + for(vit_meta = metaV.begin(); vit_meta != metaV.end(); vit_meta++) + { + RsGxsMsgMetaData* meta = *vit_meta; + + if (meta->mOrigMsgId == origMsgId) + { + if (meta->mPublishTs > latestTs) + { + latestTs = meta->mPublishTs; + latestMsgId = meta->mMsgId; + latestMeta = meta; + } + } + } + outMsgIds.push_back(latestMsgId); + metaMap.insert(std::make_pair(latestMsgId, latestMeta)); + } + } + else if (onlyAllVersions) + { + for(vit_meta = metaV.begin(); vit_meta != metaV.end(); vit_meta++) + { + RsGxsMsgMetaData* meta = *vit_meta; + + if (meta->mOrigMsgId == origMsgId) + { + outMsgIds.push_back(meta->mMsgId); + metaMap.insert(std::make_pair(meta->mOrigMsgId, meta)); + } + } + } + + req->mMsgIdResult[grpId] = outMsgIds; + filterMsgList(req->mMsgIdResult, opts, filterMap); + + cleanseMsgMetaMap(result); + + return true; +} + +bool RsGxsDataAccess::getMsgList(MsgIdReq* req) +{ + + GxsMsgMetaResult result; + + mDataStore->retrieveGxsMsgMetaData(req->mMsgIds, result); + + + GxsMsgMetaResult::iterator mit = result.begin(), mit_end = result.end(); + + for(; mit != mit_end; mit++) + { + const RsGxsGroupId grpId = mit->first; + std::vector& metaV = mit->second; + std::vector::iterator vit = metaV.begin(), + vit_end = metaV.end(); + + for(; vit != vit_end; vit++) + { + RsGxsMsgMetaData* meta = *vit; + req->mMsgIdResult[grpId].push_back(meta->mMsgId); + delete meta; // discard meta data mem + } + } + + GxsMsgReq msgIdOut; + + // filter based on options + getMsgList(req->mMsgIdResult, req->Options, msgIdOut); + req->mMsgIdResult = msgIdOut; + + return true; +} + +void RsGxsDataAccess::cleanseMsgMetaMap(GxsMsgMetaResult& result) +{ + GxsMsgMetaResult::iterator mit = result.begin(); + + for(; mit !=result.end(); mit++) + { + + std::vector& msgMetaV = mit->second; + std::vector::iterator vit = msgMetaV.begin(); + for(; vit != msgMetaV.end(); vit++) + { + delete *vit; + } + } + + result.clear(); + return; +} + +void RsGxsDataAccess::filterMsgList(GxsMsgIdResult& msgIds, const RsTokReqOptions& opts, + const MsgMetaFilter& msgMetas) const +{ + + GxsMsgIdResult::iterator mit = msgIds.begin(); + for(;mit != msgIds.end(); mit++) + { + + MsgMetaFilter::const_iterator cit = msgMetas.find(mit->first); + + if(cit == msgMetas.end()) + continue; + + std::vector& msgs = mit->second; + std::vector::iterator vit = msgs.begin(); + const std::map& meta = cit->second; + std::map::const_iterator cit2; + + for(; vit != msgs.end();) + { + + bool keep = false; + if( (cit2 = meta.find(*vit)) != meta.end() ) + { + keep = checkMsgFilter(opts, cit2->second); + } + + if(keep) + { + vit++; + }else + { + vit = msgs.erase(vit); + } + } + } +} + + +bool RsGxsDataAccess::checkRequestStatus(const uint32_t& token, + uint32_t& status, uint32_t& reqtype, uint32_t& anstype, time_t& ts) +{ + + RsStackMutex stack(mDataMutex); + + GxsRequest* req = locked_retrieveRequest(token); + + if(req == NULL) + return false; + + anstype = req->ansType; + reqtype = req->reqType; + status = req->status; + ts = req->reqTime; + + return true; +} + +bool RsGxsDataAccess::addGroupData(RsNxsGrp* grp) { + + RsStackMutex stack(mDataMutex); + + std::map grpM; + grpM.insert(std::make_pair(grp, grp->metaData)); + return mDataStore->storeGroup(grpM); +} + + + +bool RsGxsDataAccess::addMsgData(RsNxsMsg* msg) { + + RsStackMutex stack(mDataMutex); + + std::map msgM; + msgM.insert(std::make_pair(msg, msg->metaData)); + return mDataStore->storeMessage(msgM); +} + + + +void RsGxsDataAccess::tokenList(std::list& tokens) +{ + + RsStackMutex stack(mDataMutex); + + std::map::iterator mit = mRequests.begin(); + + for(; mit != mRequests.end(); mit++) + { + tokens.push_back(mit->first); + } +} + +bool RsGxsDataAccess::locked_updateRequestStatus(const uint32_t& token, + const uint32_t& status) +{ + + GxsRequest* req = locked_retrieveRequest(token); + + if(req) + req->status = status; + else + return false; + + return true; +} + +uint32_t RsGxsDataAccess::generatePublicToken() +{ + + uint32_t token; + generateToken(token); + + { + RsStackMutex stack(mDataMutex); + mPublicToken[token] = RsTokenService::GXS_REQUEST_V2_STATUS_PENDING; + } + + return token; +} + + + +bool RsGxsDataAccess::updatePublicRequestStatus(const uint32_t& token, + const uint32_t& status) +{ + RsStackMutex stack(mDataMutex); + std::map::iterator mit = mPublicToken.find(token); + + if(mit != mPublicToken.end()) + { + mit->second = status; + } + else + { + return false; + } + + return true; +} + + + +bool RsGxsDataAccess::disposeOfPublicToken(const uint32_t& token) +{ + RsStackMutex stack(mDataMutex); + std::map::iterator mit = mPublicToken.find(token); + + if(mit != mPublicToken.end()) + { + mPublicToken.erase(mit); + } + else + { + return false; + } + + return true; +} + +bool RsGxsDataAccess::checkMsgFilter(const RsTokReqOptions& opts, const RsGxsMsgMetaData* meta) const +{ + bool statusMatch = false; + if (opts.mStatusMask) + { + // Exact Flags match required. + if ((opts.mStatusMask & opts.mStatusFilter) == (opts.mStatusMask & meta->mMsgStatus)) + { + std::cerr << "checkMsgFilter() Accepting Msg as StatusMatches: "; + std::cerr << " Mask: " << opts.mStatusMask << " StatusFilter: " << opts.mStatusFilter; + std::cerr << " MsgStatus: " << meta->mMsgStatus << " MsgId: " << meta->mMsgId; + std::cerr << std::endl; + + statusMatch = true; + } + else + { + std::cerr << "checkMsgFilter() Dropping Msg due to !StatusMatch "; + std::cerr << " Mask: " << opts.mStatusMask << " StatusFilter: " << opts.mStatusFilter; + std::cerr << " MsgStatus: " << meta->mMsgStatus << " MsgId: " << meta->mMsgId; + std::cerr << std::endl; + } + } + else + { + // no status comparision, + statusMatch = true; + } + + bool flagMatch = false; + + if(opts.mMsgFlagMask) + { + // Exact Flags match required. + if ((opts.mMsgFlagMask & opts.mMsgFlagFilter) == (opts.mMsgFlagMask & meta->mMsgFlags)) + { + std::cerr << "checkMsgFilter() Accepting Msg as FlagMatches: "; + std::cerr << " Mask: " << opts.mMsgFlagMask << " FlagFilter: " << opts.mMsgFlagFilter; + std::cerr << " MsgFlag: " << meta->mMsgFlags << " MsgId: " << meta->mMsgId; + std::cerr << std::endl; + + flagMatch = true; + } + else + { + std::cerr << "checkMsgFilter() Dropping Msg due to !FlagMatch "; + std::cerr << " Mask: " << opts.mMsgFlagMask << " FlagFilter: " << opts.mMsgFlagFilter; + std::cerr << " MsgFlag: " << meta->mMsgFlags << " MsgId: " << meta->mMsgId; + std::cerr << std::endl; + + flagMatch = false; + } + }else{ + flagMatch = true; + } + + return statusMatch && flagMatch; +} + diff --git a/libretroshare/src/gxs/rsgxsdataaccess.h b/libretroshare/src/gxs/rsgxsdataaccess.h index 7dca5ac60..c0c3ac90f 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.h +++ b/libretroshare/src/gxs/rsgxsdataaccess.h @@ -1,367 +1,367 @@ -#ifndef RSGXSDATAACCESS_H -#define RSGXSDATAACCESS_H - -/* - * libretroshare/src/retroshare: rsgxsdataaccess.cc - * - * RetroShare C++ Interface. - * - * Copyright 2012-2012 by Robert Fernie, Christopher Evi-Parker - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "rstokenservice.h" -#include "rsgxsrequesttypes.h" -#include "rsgds.h" - - -typedef std::map< RsGxsGroupId, std::map > MsgMetaFilter; - -class RsGxsDataAccess : public RsTokenService -{ -public: - RsGxsDataAccess(RsGeneralDataService* ds); - virtual ~RsGxsDataAccess() { return ;} - -public: - - /** S: RsTokenService **/ - - /*! - * Use this to request group related information - * @param token The token returned for the request, store this value to pool for request completion - * @param ansType The type of result (e.g. group data, meta, ids) - * @param opts Additional option that affect outcome of request. Please see specific services, for valid values - * @param groupIds group id to request info for - * @return - */ - bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const std::list &groupIds); - - /*! - * Use this to request all group related info - * @param token The token returned for the request, store this value to pool for request completion - * @param ansType The type of result (e.g. group data, meta, ids) - * @param opts Additional option that affect outcome of request. Please see specific services, for valid values - * @return - */ - bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts); - - /*! - * Use this to get msg related information, store this value to pole for request completion - * @param token The token returned for the request - * @param ansType The type of result wanted - * @param opts Additional option that affect outcome of request. Please see specific services, for valid values - * @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs - * @return true if request successful false otherwise - */ - bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq& msgIds); - - /*! - * Use this to get msg related information, store this value to pole for request completion - * @param token The token returned for the request - * @param ansType The type of result wanted - * @param opts Additional option that affect outcome of request. Please see specific services, for valid values - * @param groupIds The ids of the groups to get, this retrieve all the msgs info for each grpId in list - * @return true if request successful false otherwise - */ - bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const std::list& grpIds); - - /*! - * For requesting msgs related to a given msg id within a group - * @param token The token returned for the request - * @param ansType The type of result wanted - * @param opts Additional option that affect outcome of request. Please see specific services, for valid values - * @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs - * @return true if request successful false otherwise - */ - bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const RsGxsGrpMsgIdPair &msgIds); - - /* Poll */ - uint32_t requestStatus(const uint32_t token); - - /* Cancel Request */ - bool cancelRequest(const uint32_t &token); - - /** E: RsTokenService **/ - -public: - - /*! - * This adds a groups to the gxs data base, this is a blocking call - * Responsibility for grp still lies with callee \n - * If function returns successfully DataAccess can be queried for grp - * @param grp the group to add, responsibility grp passed lies with callee - * @return false if group cound not be added - */ - bool addGroupData(RsNxsGrp* grp); - - /*! - * This adds a group to the gxs data base, this is a blocking call \n - * Responsibility for msg still lies with callee \n - * If function returns successfully DataAccess can be queried for msg - * @param msg the msg to add - * @return false if msg could not be added, true otherwise - */ - bool addMsgData(RsNxsMsg* msg); - -public: - - /*! - * This must be called periodically to progress requests - */ - void processRequests(); - - /*! - * Retrieve group list for a given token - * @param token request token to be redeemed - * @param groupIds - * @param msgIds - * @return false if token cannot be redeemed, if false you may have tried to redeem when not ready - */ - bool getGroupList(const uint32_t &token, std::list &groupIds); - - /*! - * - * @param token request token to be redeemed - * @param msgIds - */ - bool getMsgList(const uint32_t &token, GxsMsgIdResult &msgIds); - - - /*! - * @param token request token to be redeemed - * @param groupInfo - */ - bool getGroupSummary(const uint32_t &token, std::list &groupInfo); - - /*! - * - * @param token request token to be redeemed - * @param msgInfo - */ - bool getMsgSummary(const uint32_t &token, GxsMsgMetaResult &msgInfo); - - /*! - * - * @param token request token to be redeemed - * @param grpData - */ - bool getGroupData(const uint32_t &token, std::list& grpData); - - /*! - * - * @param token request token to be redeemed - * @param msgData - * @return false if data cannot be found for token - */ - bool getMsgData(const uint32_t &token, NxsMsgDataResult& msgData); - -private: - - /** helper functions to implement token service **/ - - /*! - * Assigns a token value to passed integer - * @param token is assigned a unique token value - */ - void generateToken(uint32_t &token); - - /*! - * - * @param token the value of the token for the request object handle wanted - * @return the request associated to this token - */ - GxsRequest* locked_retrieveRequest(const uint32_t& token); - - /*! - * Add a gxs request to queue - * @param req gxs request to add - */ - void storeRequest(GxsRequest* req); - - /*! - * convenience function to setting members of request - * @param req - * @param token - * @param ansType - * @param opts - */ - void setReq(GxsRequest* req,const uint32_t &token, const uint32_t& ansType, const RsTokReqOptionsV2 &opts) const; - - /*! - * Remove request for request queue - * Request is deleted - * @param token the token associated to the request - * @return true if token successfully cleared, false if token does not exist - */ - bool clearRequest(const uint32_t &token); - - /*! - * Updates the status flag of a request - * @param token the token value of the request to set - * @param status the status to set - * @return - */ - bool locked_updateRequestStatus(const uint32_t &token, const uint32_t &status); - - /*! - * Use to query the status and other values of a given token - * @param token the toke of the request to check for - * @param status set to current status of request - * @param reqtype set to request type of request - * @param anstype set to to anstype of request - * @param ts time stamp - * @return false if token does not exist, true otherwise - */ - bool checkRequestStatus(const uint32_t &token, uint32_t &status, uint32_t &reqtype, uint32_t &anstype, time_t &ts); - - // special ones for testing (not in final design) - /*! - * Get list of active tokens of this token service - * @param tokens sets to list of token contained in this tokenservice - */ - void tokenList(std::list &tokens); - - /*! - * Convenience function to delete the ids - * @param filter the meta filter to clean - */ - void cleanseMsgMetaMap(GxsMsgMetaResult& result); - -public: - - /*! - * Assigns a token value to passed integer - * The status of the token can still be queried from request status feature - * @param token is assigned a unique token value - */ - uint32_t generatePublicToken(); - - /*! - * Updates the status of associate token - * @param token - * @param status - * @return false if token could not be found, true if token disposed of - */ - bool updatePublicRequestStatus(const uint32_t &token, const uint32_t &status); - - /*! - * This gets rid of a publicly issued token - * @param token - * @return false if token could not found, true if token disposed of - */ - bool disposeOfPublicToken(const uint32_t &token); - -private: - - /* These perform the actual blocking retrieval of data */ - - /*! - * Attempts to retrieve group id list from data store - * @param req - * @return false if unsuccessful, true otherwise - */ - bool getGroupList(GroupIdReq* req); - - /*! - * Attempts to retrieve msg id list from data store - * Computationally/CPU-Bandwidth expensive - * @param req - * @return false if unsuccessful, true otherwise - */ - bool getMsgList(MsgIdReq* req); - - - /*! - * Attempts to retrieve group meta data from data store - * @param req - * @return false if unsuccessful, true otherwise - */ - bool getGroupSummary(GroupMetaReq* req); - - /*! - * Attempts to retrieve msg meta data from data store - * @param req - * @return false if unsuccessful, true otherwise - */ - bool getMsgSummary(MsgMetaReq* req); - - /*! - * Attempts to retrieve group data from data store - * @param req The request specifying data to retrieve - * @return false if unsuccessful, true otherwise - */ - bool getGroupData(GroupDataReq* req); - - /*! - * Attempts to retrieve message data from data store - * @param req The request specifying data to retrieve - * @return false if unsuccessful, true otherwise - */ - bool getMsgData(MsgDataReq* req); - - - /*! - * Attempts to retrieve messages related to msgIds of associated equest - * @param token request token to be redeemed - * @param msgIds - * @return false if data cannot be found for token - */ - bool getMsgRelatedInfo(MsgRelatedInfoReq* req); - - /*! - * This filter msgs based of options supplied (at the moment just status masks) - * @param msgIds The msgsIds to filter - * @param opts the request options set by user - * @param meta The accompanying meta information for msg, ids - */ - void filterMsgList(GxsMsgIdResult& msgIds, const RsTokReqOptionsV2& opts, const MsgMetaFilter& meta) const; - - - /*! - * This applies the options to the meta to find out if the given message satisfies - * them - * @param opts options containing filters to check - * @param meta meta containing currently defined options for msg - * @return true if msg meta passes all options - */ - bool checkMsgFilter(const RsTokReqOptionsV2& opts, const RsGxsMsgMetaData* meta) const; - - /*! - * This is a filter method which applies the request options to the list of ids - * requested - * @param msgIds the msg ids for filter to be applied to - * @param opts the options used to parameterise the id filter - * @param msgIdsOut the left overs ids after filter is applied to msgIds - */ - bool getMsgList(const GxsMsgReq& msgIds, const RsTokReqOptionsV2& opts, GxsMsgReq& msgIdsOut); - -private: - - RsGeneralDataService* mDataStore; - uint32_t mNextToken; - std::map mPublicToken; - std::map mRequests; - - RsMutex mDataMutex; - - -}; - -#endif // RSGXSDATAACCESS_H +#ifndef RSGXSDATAACCESS_H +#define RSGXSDATAACCESS_H + +/* + * libretroshare/src/retroshare: rsgxsdataaccess.cc + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie, Christopher Evi-Parker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "rstokenservice.h" +#include "rsgxsrequesttypes.h" +#include "rsgds.h" + + +typedef std::map< RsGxsGroupId, std::map > MsgMetaFilter; + +class RsGxsDataAccess : public RsTokenService +{ +public: + RsGxsDataAccess(RsGeneralDataService* ds); + virtual ~RsGxsDataAccess() { return ;} + +public: + + /** S: RsTokenService **/ + + /*! + * Use this to request group related information + * @param token The token returned for the request, store this value to pool for request completion + * @param ansType The type of result (e.g. group data, meta, ids) + * @param opts Additional option that affect outcome of request. Please see specific services, for valid values + * @param groupIds group id to request info for + * @return + */ + bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds); + + /*! + * Use this to request all group related info + * @param token The token returned for the request, store this value to pool for request completion + * @param ansType The type of result (e.g. group data, meta, ids) + * @param opts Additional option that affect outcome of request. Please see specific services, for valid values + * @return + */ + bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts); + + /*! + * Use this to get msg related information, store this value to pole for request completion + * @param token The token returned for the request + * @param ansType The type of result wanted + * @param opts Additional option that affect outcome of request. Please see specific services, for valid values + * @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs + * @return true if request successful false otherwise + */ + bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const GxsMsgReq& msgIds); + + /*! + * Use this to get msg related information, store this value to pole for request completion + * @param token The token returned for the request + * @param ansType The type of result wanted + * @param opts Additional option that affect outcome of request. Please see specific services, for valid values + * @param groupIds The ids of the groups to get, this retrieve all the msgs info for each grpId in list + * @return true if request successful false otherwise + */ + bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list& grpIds); + + /*! + * For requesting msgs related to a given msg id within a group + * @param token The token returned for the request + * @param ansType The type of result wanted + * @param opts Additional option that affect outcome of request. Please see specific services, for valid values + * @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs + * @return true if request successful false otherwise + */ + bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const RsGxsGrpMsgIdPair &msgIds); + + /* Poll */ + uint32_t requestStatus(const uint32_t token); + + /* Cancel Request */ + bool cancelRequest(const uint32_t &token); + + /** E: RsTokenService **/ + +public: + + /*! + * This adds a groups to the gxs data base, this is a blocking call + * Responsibility for grp still lies with callee \n + * If function returns successfully DataAccess can be queried for grp + * @param grp the group to add, responsibility grp passed lies with callee + * @return false if group cound not be added + */ + bool addGroupData(RsNxsGrp* grp); + + /*! + * This adds a group to the gxs data base, this is a blocking call \n + * Responsibility for msg still lies with callee \n + * If function returns successfully DataAccess can be queried for msg + * @param msg the msg to add + * @return false if msg could not be added, true otherwise + */ + bool addMsgData(RsNxsMsg* msg); + +public: + + /*! + * This must be called periodically to progress requests + */ + void processRequests(); + + /*! + * Retrieve group list for a given token + * @param token request token to be redeemed + * @param groupIds + * @param msgIds + * @return false if token cannot be redeemed, if false you may have tried to redeem when not ready + */ + bool getGroupList(const uint32_t &token, std::list &groupIds); + + /*! + * + * @param token request token to be redeemed + * @param msgIds + */ + bool getMsgList(const uint32_t &token, GxsMsgIdResult &msgIds); + + + /*! + * @param token request token to be redeemed + * @param groupInfo + */ + bool getGroupSummary(const uint32_t &token, std::list &groupInfo); + + /*! + * + * @param token request token to be redeemed + * @param msgInfo + */ + bool getMsgSummary(const uint32_t &token, GxsMsgMetaResult &msgInfo); + + /*! + * + * @param token request token to be redeemed + * @param grpData + */ + bool getGroupData(const uint32_t &token, std::list& grpData); + + /*! + * + * @param token request token to be redeemed + * @param msgData + * @return false if data cannot be found for token + */ + bool getMsgData(const uint32_t &token, NxsMsgDataResult& msgData); + +private: + + /** helper functions to implement token service **/ + + /*! + * Assigns a token value to passed integer + * @param token is assigned a unique token value + */ + void generateToken(uint32_t &token); + + /*! + * + * @param token the value of the token for the request object handle wanted + * @return the request associated to this token + */ + GxsRequest* locked_retrieveRequest(const uint32_t& token); + + /*! + * Add a gxs request to queue + * @param req gxs request to add + */ + void storeRequest(GxsRequest* req); + + /*! + * convenience function to setting members of request + * @param req + * @param token + * @param ansType + * @param opts + */ + void setReq(GxsRequest* req,const uint32_t &token, const uint32_t& ansType, const RsTokReqOptions &opts) const; + + /*! + * Remove request for request queue + * Request is deleted + * @param token the token associated to the request + * @return true if token successfully cleared, false if token does not exist + */ + bool clearRequest(const uint32_t &token); + + /*! + * Updates the status flag of a request + * @param token the token value of the request to set + * @param status the status to set + * @return + */ + bool locked_updateRequestStatus(const uint32_t &token, const uint32_t &status); + + /*! + * Use to query the status and other values of a given token + * @param token the toke of the request to check for + * @param status set to current status of request + * @param reqtype set to request type of request + * @param anstype set to to anstype of request + * @param ts time stamp + * @return false if token does not exist, true otherwise + */ + bool checkRequestStatus(const uint32_t &token, uint32_t &status, uint32_t &reqtype, uint32_t &anstype, time_t &ts); + + // special ones for testing (not in final design) + /*! + * Get list of active tokens of this token service + * @param tokens sets to list of token contained in this tokenservice + */ + void tokenList(std::list &tokens); + + /*! + * Convenience function to delete the ids + * @param filter the meta filter to clean + */ + void cleanseMsgMetaMap(GxsMsgMetaResult& result); + +public: + + /*! + * Assigns a token value to passed integer + * The status of the token can still be queried from request status feature + * @param token is assigned a unique token value + */ + uint32_t generatePublicToken(); + + /*! + * Updates the status of associate token + * @param token + * @param status + * @return false if token could not be found, true if token disposed of + */ + bool updatePublicRequestStatus(const uint32_t &token, const uint32_t &status); + + /*! + * This gets rid of a publicly issued token + * @param token + * @return false if token could not found, true if token disposed of + */ + bool disposeOfPublicToken(const uint32_t &token); + +private: + + /* These perform the actual blocking retrieval of data */ + + /*! + * Attempts to retrieve group id list from data store + * @param req + * @return false if unsuccessful, true otherwise + */ + bool getGroupList(GroupIdReq* req); + + /*! + * Attempts to retrieve msg id list from data store + * Computationally/CPU-Bandwidth expensive + * @param req + * @return false if unsuccessful, true otherwise + */ + bool getMsgList(MsgIdReq* req); + + + /*! + * Attempts to retrieve group meta data from data store + * @param req + * @return false if unsuccessful, true otherwise + */ + bool getGroupSummary(GroupMetaReq* req); + + /*! + * Attempts to retrieve msg meta data from data store + * @param req + * @return false if unsuccessful, true otherwise + */ + bool getMsgSummary(MsgMetaReq* req); + + /*! + * Attempts to retrieve group data from data store + * @param req The request specifying data to retrieve + * @return false if unsuccessful, true otherwise + */ + bool getGroupData(GroupDataReq* req); + + /*! + * Attempts to retrieve message data from data store + * @param req The request specifying data to retrieve + * @return false if unsuccessful, true otherwise + */ + bool getMsgData(MsgDataReq* req); + + + /*! + * Attempts to retrieve messages related to msgIds of associated equest + * @param token request token to be redeemed + * @param msgIds + * @return false if data cannot be found for token + */ + bool getMsgRelatedInfo(MsgRelatedInfoReq* req); + + /*! + * This filter msgs based of options supplied (at the moment just status masks) + * @param msgIds The msgsIds to filter + * @param opts the request options set by user + * @param meta The accompanying meta information for msg, ids + */ + void filterMsgList(GxsMsgIdResult& msgIds, const RsTokReqOptions& opts, const MsgMetaFilter& meta) const; + + + /*! + * This applies the options to the meta to find out if the given message satisfies + * them + * @param opts options containing filters to check + * @param meta meta containing currently defined options for msg + * @return true if msg meta passes all options + */ + bool checkMsgFilter(const RsTokReqOptions& opts, const RsGxsMsgMetaData* meta) const; + + /*! + * This is a filter method which applies the request options to the list of ids + * requested + * @param msgIds the msg ids for filter to be applied to + * @param opts the options used to parameterise the id filter + * @param msgIdsOut the left overs ids after filter is applied to msgIds + */ + bool getMsgList(const GxsMsgReq& msgIds, const RsTokReqOptions& opts, GxsMsgReq& msgIdsOut); + +private: + + RsGeneralDataService* mDataStore; + uint32_t mNextToken; + std::map mPublicToken; + std::map mRequests; + + RsMutex mDataMutex; + + +}; + +#endif // RSGXSDATAACCESS_H diff --git a/libretroshare/src/gxs/rsgxsflags.h b/libretroshare/src/gxs/rsgxsflags.h index cc23f8937..c769b06cc 100644 --- a/libretroshare/src/gxs/rsgxsflags.h +++ b/libretroshare/src/gxs/rsgxsflags.h @@ -3,13 +3,22 @@ #include "inttypes.h" -// this serves a single point of call for definining grp and msg modes -// GXS. These modes say +/** + * The GXS_SERV namespace serves a single point of reference for definining grp and msg flags + * Declared and defined here are: + * - privacy flags which define the level of privacy that can be given \n + * to a group + * - authentication types which defined types of authentication needed for a given message to + * confirm its authenticity + * - subscription flags: This used only locally by the peer to subscription status to a \n + * a group + * - + */ namespace GXS_SERV { - /** privacy **/ + /** START privacy **/ static const uint32_t FLAG_PRIVACY_MASK = 0x0000000f; @@ -22,9 +31,9 @@ namespace GXS_SERV { // anyone can publish, publish key pair not needed static const uint32_t FLAG_PRIVACY_PUBLIC = 0x00000004; - /** privacy **/ + /** END privacy **/ - /** authentication **/ + /** START authentication **/ static const uint32_t FLAG_AUTHEN_MASK = 0x000000f0; @@ -40,10 +49,10 @@ namespace GXS_SERV { // pgp sign identity static const uint32_t FLAG_AUTHEN_PGP_IDENTITY = 0x00000080; - /** authentication **/ + /** END authentication **/ - // Subscription Flags. (LOCAL) + /** START Subscription Flags. (LOCAL) **/ static const uint32_t GROUP_SUBSCRIBE_ADMIN = 0x00000001; @@ -55,6 +64,16 @@ namespace GXS_SERV { static const uint32_t GROUP_SUBSCRIBE_MASK = 0x0000000f; + /** END Subscription Flags. (LOCAL) **/ + + /** START GXS Msg status flags **/ + + static const uint32_t GXS_MSG_STATUS_UNPROCESSED = 0x000000100; + + static const uint32_t GXS_MSG_STATUS_UNREAD = 0x00000200; + + /** END GXS Msg status flags **/ + } diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 073b9b12f..0723b7ed1 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -1267,7 +1267,7 @@ NxsTransaction::~NxsTransaction(){ /* Net Manager */ RsNxsNetMgrImpl::RsNxsNetMgrImpl(p3LinkMgr *lMgr) - : mLinkMgr(lMgr) + : mLinkMgr(lMgr), mNxsNetMgrMtx("RsNxsNetMgrImpl") { } @@ -1275,6 +1275,7 @@ RsNxsNetMgrImpl::RsNxsNetMgrImpl(p3LinkMgr *lMgr) std::string RsNxsNetMgrImpl::getOwnId() { + RsStackMutex stack(mNxsNetMgrMtx); return mLinkMgr->getOwnId(); } @@ -1283,7 +1284,10 @@ void RsNxsNetMgrImpl::getOnlineList(std::set &ssl_peers) ssl_peers.clear(); std::list pList; - mLinkMgr->getOnlineList(pList); + { + RsStackMutex stack(mNxsNetMgrMtx); + mLinkMgr->getOnlineList(pList); + } std::list::const_iterator lit = pList.begin(); diff --git a/libretroshare/src/gxs/rsgxsnetservice.h b/libretroshare/src/gxs/rsgxsnetservice.h index 716420939..f555dd5d4 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.h +++ b/libretroshare/src/gxs/rsgxsnetservice.h @@ -103,6 +103,7 @@ public: private: p3LinkMgr* mLinkMgr; + RsMutex mNxsNetMgrMtx; }; diff --git a/libretroshare/src/gxs/rsgxsrequesttypes.h b/libretroshare/src/gxs/rsgxsrequesttypes.h index b270e1ed5..bd2723de5 100644 --- a/libretroshare/src/gxs/rsgxsrequesttypes.h +++ b/libretroshare/src/gxs/rsgxsrequesttypes.h @@ -26,6 +26,7 @@ * */ +#include "gxs/rstokenservice.h" #include "gxs/rsgds.h" class GxsRequest @@ -40,7 +41,7 @@ public: uint32_t ansType; uint32_t reqType; - RsTokReqOptionsV2 Options; + RsTokReqOptions Options; uint32_t status; }; diff --git a/libretroshare/src/gxs/rstokenservice.h b/libretroshare/src/gxs/rstokenservice.h index 316b6a454..cb6fee0b9 100644 --- a/libretroshare/src/gxs/rstokenservice.h +++ b/libretroshare/src/gxs/rstokenservice.h @@ -68,10 +68,10 @@ * This class provides useful generic support for GXS style services. * I expect much of this will be incorporated into the base GXS. */ -class RsTokReqOptionsV2 +class RsTokReqOptions { public: -RsTokReqOptionsV2() +RsTokReqOptions() { mOptions = 0; mStatusFilter = 0; mStatusMask = 0; mSubscribeFilter = 0; @@ -86,6 +86,7 @@ uint32_t mOptions; uint32_t mStatusFilter; uint32_t mStatusMask; +// use uint32_t mMsgFlagMask, mMsgFlagFilter; uint32_t mReqType; @@ -97,6 +98,8 @@ time_t mBefore; time_t mAfter; }; +std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta); +std::ostream &operator<<(std::ostream &out, const RsMsgMetaData &meta); /*! * A proxy class for requesting generic service data for GXS @@ -129,7 +132,7 @@ public: * @param groupIds group id to request info for * @return */ - virtual bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const std::list &groupIds) = 0; + virtual bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) = 0; /*! * Use this to request all group related info @@ -138,7 +141,7 @@ public: * @param opts Additional option that affect outcome of request. Please see specific services, for valid values * @return */ - virtual bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts) = 0; + virtual bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts) = 0; /*! * Use this to get msg related information, store this value to pole for request completion @@ -148,7 +151,7 @@ public: * @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs * @return true if request successful false otherwise */ - virtual bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const GxsMsgReq& msgIds) = 0; + virtual bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const GxsMsgReq& msgIds) = 0; /*! * Use this to get msg related information, store this value to pole for request completion @@ -158,7 +161,7 @@ public: * @param groupIds The ids of the groups to get, this retrieve all the msgs info for each grpId in list * @return true if request successful false otherwise */ - virtual bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const std::list& msgIds) = 0; + virtual bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list& msgIds) = 0; /*! * For requesting msgs related to a given msg id within a group @@ -168,7 +171,7 @@ public: * @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs * @return true if request successful false otherwise */ - virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsV2 &opts, const RsGxsGrpMsgIdPair& msgIds) = 0; + virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const RsGxsGrpMsgIdPair& msgIds) = 0; /* Poll */ diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index a39ea250d..f7d08313e 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -527,6 +527,7 @@ HEADERS += retroshare/rsgame.h \ serialiser/rsbanlistitems.cc \ serialiser/rsbwctrlitems.cc \ serialiser/rstunnelitems.cc + SOURCES += services/p3channels.cc \ services/p3chatservice.cc \ services/p3disc.cc \ @@ -580,7 +581,7 @@ HEADERS += retroshare/rsgame.h \ } # new gxs cache system - newcache { + newcache { HEADERS += serialiser/rsnxsitems.h \ gxs/rsgds.h \ gxs/rsgxs.h \ @@ -603,6 +604,7 @@ HEADERS += retroshare/rsgame.h \ gxs/rsgxsifaceimpl.h \ services/p3posted.h \ retroshare/rsposted.h \ + serialiser/rsposteditems.h SOURCES += serialiser/rsnxsitems.cc \ @@ -621,22 +623,23 @@ HEADERS += retroshare/rsgame.h \ gxs/gxssecurity.cc \ gxs/rsgxsifaceimpl.cc \ services/p3posted.cc \ + serialiser/rsposteditems.cc # Identity Service HEADERS += retroshare/rsidentity.h \ gxs/rsgixs.h \ services/p3idservice.h \ - serialiser/rsgxsiditems.h \ + serialiser/rsgxsiditems.h - SOURCES += services/p3idservice.cc \ + SOURCES += services/p3idservice.cc # serialiser/rsgxsiditems.cc \ # Wiki Service HEADERS += retroshare/rswiki.h \ services/p3wiki.h \ - serialiser/rswikiitems.h \ + serialiser/rswikiitems.h - SOURCES += services/p3wiki.cc \ + SOURCES += services/p3wiki.cc # serialiser/rswikiitems.cc \ } @@ -645,30 +648,20 @@ HEADERS += retroshare/rsgame.h \ HEADERS += services/p3photoserviceV2.h \ retroshare/rsphotoVEG.h \ services/p3gxsserviceVEG.h \ - retroshare/rsidentityVEG.h \ services/p3wikiserviceVEG.h \ retroshare/rswikiVEG.h \ retroshare/rswireVEG.h \ services/p3wireVEG.h \ - services/p3idserviceVEG.h \ retroshare/rsforumsVEG.h \ - services/p3forumsVEG.h \ - retroshare/rspostedVEG.h \ - services/p3postedVEG.h - + services/p3forumsVEG.h # Do I need this? #serialiser/rsphotoitemsVEG.h \ SOURCES += services/p3gxsserviceVEG.cc \ services/p3wikiserviceVEG.cc \ services/p3wireVEG.cc \ - services/p3idserviceVEG.cc \ - services/p3forumsVEG.cc \ - services/p3postedVEG.cc - + services/p3forumsVEG.cc # Do I need this? # serialiser/rsphotoitemsVEG.cc \ } - - diff --git a/libretroshare/src/retroshare/rsposted.h b/libretroshare/src/retroshare/rsposted.h index c2ea5091e..a1324e468 100644 --- a/libretroshare/src/retroshare/rsposted.h +++ b/libretroshare/src/retroshare/rsposted.h @@ -7,7 +7,7 @@ * * RetroShare C++ Interface. * - * Copyright 2008-2012 by Robert Fernie. + * Copyright 2008-2012 by Robert Fernie, Christopher Evi-Parker * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -33,10 +33,10 @@ #include "gxs/rstokenservice.h" #include "gxs/rsgxsifaceimpl.h" -/* The Main Interface Class - for information about your Peers */ -class RsPostedVEG; -extern RsPostedVEG *rsPostedVEG; +class RsPosted; +extern RsPosted *rsPosted; +/* The Main Interface Class - for information about your Peers */ class RsPostedGroup { @@ -45,19 +45,9 @@ class RsPostedGroup RsPostedGroup() { return; } }; -class RsPostedMsg -{ - public: - RsPostedMsg(uint32_t t) - :postedType(t) { return; } - - RsMsgMetaData mMeta; - uint32_t postedType; -}; - -#define RSPOSTED_MSGTYPE_POST 0x0001 -#define RSPOSTED_MSGTYPE_VOTE 0x0002 -#define RSPOSTED_MSGTYPE_COMMENT 0x0004 +//#define RSPOSTED_MSGTYPE_POST 0x0001 +//#define RSPOSTED_MSGTYPE_VOTE 0x0002 +//#define RSPOSTED_MSGTYPE_COMMENT 0x0004 #define RSPOSTED_PERIOD_YEAR 1 #define RSPOSTED_PERIOD_MONTH 2 @@ -70,44 +60,13 @@ class RsPostedMsg #define RSPOSTED_VIEWMODE_HOT 3 #define RSPOSTED_VIEWMODE_COMMENTS 4 +class RsPostedPost; +class RsPostedComment; +class RsPostedVote; -class RsPostedPost: public RsPostedMsg -{ - public: - RsPostedPost(): RsPostedMsg(RSPOSTED_MSGTYPE_POST) - { - mMeta.mMsgFlags = RSPOSTED_MSGTYPE_POST; - return; - } - - std::string mLink; - std::string mNotes; -}; - - -class RsPostedVote: public RsPostedMsg -{ - public: - RsPostedVote(): RsPostedMsg(RSPOSTED_MSGTYPE_VOTE) - { - mMeta.mMsgFlags = RSPOSTED_MSGTYPE_VOTE; - return; - } -}; - - -class RsPostedComment: public RsPostedMsg -{ - public: - RsPostedComment(): RsPostedMsg(RSPOSTED_MSGTYPE_COMMENT) - { - mMeta.mMsgFlags = RSPOSTED_MSGTYPE_COMMENT; - return; - } - - std::string mComment; -}; - +typedef std::map > PostedPostResult; +typedef std::map > PostedCommentResult; +typedef std::map > PostedVoteResult; std::ostream &operator<<(std::ostream &out, const RsPostedGroup &group); std::ostream &operator<<(std::ostream &out, const RsPostedPost &post); @@ -119,15 +78,19 @@ class RsPosted : public RsGxsIfaceImpl { public: + static const uint32_t FLAG_MSGTYPE_POST; + static const uint32_t FLAG_MSGTYPE_VOTE; + static const uint32_t FLAG_MSGTYPE_COMMENT; + + RsPosted(RsGenExchange* gxs) : RsGxsIfaceImpl(gxs) { return; } virtual ~RsPosted() { return; } /* Specific Service Data */ -virtual RsTokenService* getToken() = 0; -virtual bool getGroup(const uint32_t &token, RsPostedGroup &group) = 0; -virtual bool getPost(const uint32_t &token, RsPostedPost &post) = 0; -virtual bool getComment(const uint32_t &token, RsPostedComment &comment) = 0; +virtual bool getGroup(const uint32_t &token, std::vector &group) = 0; +virtual bool getPost(const uint32_t &token, PostedPostResult &post) = 0; +virtual bool getComment(const uint32_t &token, PostedCommentResult &comment) = 0; virtual bool submitGroup(uint32_t &token, RsPostedGroup &group) = 0; virtual bool submitPost(uint32_t &token, RsPostedPost &post) = 0; @@ -136,20 +99,48 @@ virtual bool submitComment(uint32_t &token, RsPostedComment &comment) = 0; // Special Ranking Request. virtual bool requestRanking(uint32_t &token, RsGxsGroupId groupId) = 0; -virtual bool getRankedPost(const uint32_t &token, RsPostedPost &post) = 0; - -virtual bool extractPostedCache() = 0; - - - // Control Ranking Calculations. -virtual bool setViewMode(uint32_t mode) = 0; -virtual bool setViewPeriod(uint32_t period) = 0; -virtual bool setViewRange(uint32_t first, uint32_t count) = 0; - - // exposed for testing... -virtual float calcPostScore(uint32_t& token, const RsGxsMessageId) = 0; }; +class RsPostedPost +{ + public: + RsPostedPost() + { + mMeta.mMsgFlags = RsPosted::FLAG_MSGTYPE_POST; + return; + } + + RsMsgMetaData mMeta; + std::string mLink; + std::string mNotes; +}; + + +class RsPostedVote +{ + public: + RsPostedVote() + { + mMeta.mMsgFlags = RsPosted::FLAG_MSGTYPE_VOTE; + return; + } + + RsMsgMetaData mMeta; +}; + + +class RsPostedComment +{ + public: + RsPostedComment() + { + mMeta.mMsgFlags = RsPosted::FLAG_MSGTYPE_COMMENT; + return; + } + + std::string mComment; + RsMsgMetaData mMeta; +}; #endif // RSPOSTED_H diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index a0b0ebcb2..7510041c1 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1813,17 +1813,18 @@ RsTurtle *rsTurtle = NULL ; #ifdef ENABLE_GXS_CORE #include "gxs/gxscoreserver.h" -#include "services/p3photoserviceV2.h" + #include "gxs/rsdataservice.h" #include "gxs/rsgxsnetservice.h" #endif #ifdef ENABLE_GXS_SERVICES +#include "services/p3photoserviceV2.h" +#include "services/p3posted.h" #include "services/p3wikiserviceVEG.h" #include "services/p3wireVEG.h" #include "services/p3idserviceVEG.h" #include "services/p3forumsVEG.h" -#include "services/p3postedVEG.h" #endif #ifndef PQI_DISABLE_TUNNEL @@ -2266,41 +2267,7 @@ int RsServer::StartupRetroShare() mPluginsManager->registerClientServices(pqih) ; mPluginsManager->registerCacheServices() ; -#ifdef ENABLE_GXS_CORE - p3PhotoServiceV2 *mPhotoV2 = NULL; - - // first prep the core - - - RsDirUtil::checkCreateDirectory(mLinkMgr->getOwnId()); - RsGeneralDataService* photo_ds = new RsDataService("./" + mLinkMgr->getOwnId() + "/", "photoV2_db", - RS_SERVICE_GXSV1_TYPE_PHOTO, NULL); - - photo_ds->resetDataStore(); - - // init gxs services - mPhotoV2 = new p3PhotoServiceV2(photo_ds, NULL); - - // TODO need net manager - RsGxsNetService* photo_ns = new RsGxsNetService( - RS_SERVICE_GXSV1_TYPE_PHOTO, photo_ds, new RsNxsNetMgrImpl(mLinkMgr), mPhotoV2); - - - GxsCoreServer* mGxsCore = new GxsCoreServer(); - mGxsCore->addService(mPhotoV2); - - // cores read start up servers ! - - // start nxs core core server - createThread(*photo_ns); - - // start up gxs core server - createThread(*mGxsCore); - - pqih->addService(photo_ns); - -#endif #ifdef ENABLE_GXS_SERVICES @@ -2315,12 +2282,69 @@ int RsServer::StartupRetroShare() // Testing New Cache Services. p3ForumsVEG *mForumsV2 = new p3ForumsVEG(RS_SERVICE_GXSV1_TYPE_FORUMS); pqih -> addService(mForumsV2); - - // Testing New Cache Services. - p3PostedServiceVEG *mPosted = new p3PostedServiceVEG(RS_SERVICE_GXSV1_TYPE_POSTED); - pqih -> addService(mPosted); + + + // TODO: temporary to store GXS service data, remove + RsDirUtil::checkCreateDirectory(mLinkMgr->getOwnId()); + + RsNxsNetMgr* nxsMgr = new RsNxsNetMgrImpl(mLinkMgr); + + /**** Photo service ****/ + + p3PhotoServiceV2 *mPhotoV2 = NULL; + + + + RsGeneralDataService* photo_ds = new RsDataService("./" + mLinkMgr->getOwnId() + "/", "photoV2_db", + RS_SERVICE_GXSV1_TYPE_PHOTO, NULL); + + photo_ds->resetDataStore(); //TODO: remove, new service data per RS session, for testing + + // init gxs services + mPhotoV2 = new p3PhotoServiceV2(photo_ds, NULL); + + // create GXS photo service + RsGxsNetService* photo_ns = new RsGxsNetService( + RS_SERVICE_GXSV1_TYPE_PHOTO, photo_ds, nxsMgr, mPhotoV2); + + /**** Posted GXS service ****/ + + p3Posted *mPosted = NULL; + + RsGeneralDataService* posted_ds = new RsDataService("./" + mLinkMgr->getOwnId()+ "/", "posted_db", + RS_SERVICE_GXSV1_TYPE_POSTED); + + posted_ds->resetDataStore(); //TODO: remove, new service data per RS session, for testing + + mPosted = new p3Posted(posted_ds, NULL); + + // create GXS photo service + RsGxsNetService* posted_ns = new RsGxsNetService( + RS_SERVICE_GXSV1_TYPE_POSTED, posted_ds, nxsMgr, mPosted); + + #endif // ENABLE_GXS_SERVICES +#ifdef ENABLE_GXS_CORE + + /*** start up GXS core runner ***/ + + GxsCoreServer* mGxsCore = new GxsCoreServer(); + mGxsCore->addService(mPhotoV2); + mGxsCore->addService(mPosted); + + // cores ready start up GXS net servers + createThread(*photo_ns); + createThread(*posted_ns); + + // now add to p3service + pqih->addService(photo_ns); + pqih->addService(posted_ns); + + // start up gxs core server + createThread(*mGxsCore); +#endif + #ifndef RS_RELEASE p3GameLauncher *gameLauncher = new p3GameLauncher(mLinkMgr); @@ -2578,14 +2602,15 @@ int RsServer::StartupRetroShare() rsForums = mForums; rsChannels = mChannels; - rsPhotoV2 = mPhotoV2; #ifdef ENABLE_GXS_SERVICES // Testing of new cache system interfaces. rsWikiVEG = mWikis; rsWireVEG = mWire; rsForumsVEG = mForumsV2; - rsPostedVEG = mPosted; + rsPosted = mPosted; + rsPhotoV2 = mPhotoV2; + #endif // ENABLE_GXS_SERVICES diff --git a/libretroshare/src/serialiser/rsgxsitems.h b/libretroshare/src/serialiser/rsgxsitems.h index 103b0ae71..151219c2c 100644 --- a/libretroshare/src/serialiser/rsgxsitems.h +++ b/libretroshare/src/serialiser/rsgxsitems.h @@ -36,41 +36,41 @@ class RsGxsMsgMetaData; class RsGroupMetaData { - public: +public: - RsGroupMetaData() - { - mGroupFlags = 0; - mSubscribeFlags = 0; + RsGroupMetaData() + { + mGroupFlags = 0; + mSubscribeFlags = 0; - mPop = 0; - mMsgCount = 0; - mLastPost = 0; - mGroupStatus = 0; + mPop = 0; + mMsgCount = 0; + mLastPost = 0; + mGroupStatus = 0; - //mPublishTs = 0; - } + //mPublishTs = 0; + } - void operator =(const RsGxsGrpMetaData& rGxsMeta); + void operator =(const RsGxsGrpMetaData& rGxsMeta); - std::string mGroupId; - std::string mGroupName; - uint32_t mGroupFlags; - uint32_t mSignFlags; // Combination of RSGXS_GROUP_SIGN_PUBLISH_MASK & RSGXS_GROUP_SIGN_AUTHOR_MASK. + std::string mGroupId; + std::string mGroupName; + uint32_t mGroupFlags; + uint32_t mSignFlags; // Combination of RSGXS_GROUP_SIGN_PUBLISH_MASK & RSGXS_GROUP_SIGN_AUTHOR_MASK. - time_t mPublishTs; // Mandatory. - std::string mAuthorId; // Optional. + time_t mPublishTs; // Mandatory. + std::string mAuthorId; // Optional. - // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. + // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. - uint32_t mSubscribeFlags; + uint32_t mSubscribeFlags; - uint32_t mPop; // HOW DO WE DO THIS NOW. - uint32_t mMsgCount; // ??? - time_t mLastPost; // ??? + uint32_t mPop; // HOW DO WE DO THIS NOW. + uint32_t mMsgCount; // ??? + time_t mLastPost; // ??? - uint32_t mGroupStatus; - std::string mServiceString; // Service Specific Free-Form extra storage. + uint32_t mGroupStatus; + std::string mServiceString; // Service Specific Free-Form extra storage. }; @@ -79,38 +79,43 @@ class RsGroupMetaData class RsMsgMetaData { - public: - RsMsgMetaData() - { - mPublishTs = 0; - mMsgFlags = 0; - mMsgStatus = 0; - mChildTs = 0; - } +public: - void operator =(const RsGxsMsgMetaData& rGxsMeta); + RsMsgMetaData() + { + mPublishTs = 0; + mMsgFlags = 0; + mMsgStatus = 0; + mChildTs = 0; + } + + void operator =(const RsGxsMsgMetaData& rGxsMeta); - std::string mGroupId; - std::string mMsgId; + std::string mGroupId; + std::string mMsgId; - std::string mThreadId; - std::string mParentId; - std::string mOrigMsgId; + std::string mThreadId; + std::string mParentId; + std::string mOrigMsgId; - std::string mAuthorId; + std::string mAuthorId; - std::string mMsgName; - time_t mPublishTs; + std::string mMsgName; + time_t mPublishTs; - uint32_t mMsgFlags; // Whats this for? + /// the first 16 bits for service, last 16 for GXS + uint32_t mMsgFlags; - // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. - // normally READ / UNREAD flags. LOCAL Data. - uint32_t mMsgStatus; - time_t mChildTs; - std::string mServiceString; // Service Specific Free-Form extra storage. + // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. + // normally READ / UNREAD flags. LOCAL Data. + + /// the first 16 bits for service, last 16 for GXS + uint32_t mMsgStatus; + + time_t mChildTs; + std::string mServiceString; // Service Specific Free-Form extra storage. }; diff --git a/libretroshare/src/services/p3gxsserviceVEG.cc b/libretroshare/src/services/p3gxsserviceVEG.cc index 09eb6444f..11ab6e013 100644 --- a/libretroshare/src/services/p3gxsserviceVEG.cc +++ b/libretroshare/src/services/p3gxsserviceVEG.cc @@ -1445,23 +1445,23 @@ bool p3GxsDataServiceVEG::fakeprocessrequests() #if 0 // DISABLED AND MOVED TO GXS CODE. -std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta) -{ - out << "[ GroupId: " << meta.mGroupId << " Name: " << meta.mGroupName << " ]"; - return out; -} +//std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta) +//{ +// out << "[ GroupId: " << meta.mGroupId << " Name: " << meta.mGroupName << " ]"; +// return out; +//} -std::ostream &operator<<(std::ostream &out, const RsMsgMetaData &meta) -{ - out << "[ GroupId: " << meta.mGroupId << " MsgId: " << meta.mMsgId; - out << " Name: " << meta.mMsgName; - out << " OrigMsgId: " << meta.mOrigMsgId; - out << " ThreadId: " << meta.mThreadId; - out << " ParentId: " << meta.mParentId; - out << " AuthorId: " << meta.mAuthorId; - out << " Name: " << meta.mMsgName << " ]"; - return out; -} +//std::ostream &operator<<(std::ostream &out, const RsMsgMetaData &meta) +//{ +// out << "[ GroupId: " << meta.mGroupId << " MsgId: " << meta.mMsgId; +// out << " Name: " << meta.mMsgName; +// out << " OrigMsgId: " << meta.mOrigMsgId; +// out << " ThreadId: " << meta.mThreadId; +// out << " ParentId: " << meta.mParentId; +// out << " AuthorId: " << meta.mAuthorId; +// out << " Name: " << meta.mMsgName << " ]"; +// return out; +//} #endif diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 2ee7370ef..6bcf7839d 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -499,7 +499,7 @@ bool p3IdService::cache_start_load() } uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; uint32_t token = 0; RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts, groupIds); @@ -971,7 +971,7 @@ bool p3IdService::background_requestGroups() } uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; std::list groupIds; /** @@ -1034,7 +1034,7 @@ bool p3IdService::background_requestNewMessages() } uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; token = 0; /* TODO @@ -1319,7 +1319,7 @@ bool p3IdService::background_FullCalcRequest() /* request the summary info from the parents */ uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; uint32_t token = 0; - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mOptions = RS_TOKREQOPT_MSG_LATEST; RsGenExchange::getTokenService()->requestMsgInfo(token, ansType, opts, groupIds); diff --git a/libretroshare/src/services/p3posted.cc b/libretroshare/src/services/p3posted.cc index a0fc2e91f..fb03dce05 100644 --- a/libretroshare/src/services/p3posted.cc +++ b/libretroshare/src/services/p3posted.cc @@ -1,4 +1,11 @@ #include "p3posted.h" +#include "serialiser/rsposteditems.h" + +const uint32_t RsPosted::FLAG_MSGTYPE_COMMENT = 0x0001; +const uint32_t RsPosted::FLAG_MSGTYPE_POST = 0x0002; +const uint32_t RsPosted::FLAG_MSGTYPE_VOTE = 0x0004; + +RsPosted *rsPosted = NULL; p3Posted::p3Posted(RsGeneralDataService *gds, RsNetworkExchangeService *nes) : RsGenExchange(gds, nes, NULL, RS_SERVICE_GXSV1_TYPE_POSTED), RsPosted(this) @@ -10,39 +17,147 @@ void p3Posted::notifyChanges(std::vector &changes) receiveChanges(changes); } -bool p3Posted::getGroup(const uint32_t &token, RsPostedGroup &group) +void p3Posted::service_tick() { } -bool p3Posted::getPost(const uint32_t &token, RsPostedPost &post) +bool p3Posted::getGroup(const uint32_t &token, std::vector &groups) { + std::vector grpData; + bool ok = RsGenExchange::getGroupData(token, grpData); + if(ok) + { + std::vector::iterator vit = grpData.begin(); + + for(; vit != grpData.end(); vit++) + { + RsGxsPostedGroupItem* item = dynamic_cast(*vit); + RsPostedGroup grp = item->mGroup; + item->mGroup.mMeta = item->meta; + grp.mMeta = item->mGroup.mMeta; + delete item; + groups.push_back(grp); + } + } + return ok; } -bool p3Posted::getComment(const uint32_t &token, RsPostedComment &comment) +bool p3Posted::getPost(const uint32_t &token, PostedPostResult &posts) { + GxsMsgDataMap msgData; + bool ok = RsGenExchange::getMsgData(token, msgData); + if(ok) + { + GxsMsgDataMap::iterator mit = msgData.begin(); + + for(; mit != msgData.end(); mit++) + { + RsGxsGroupId grpId = mit->first; + std::vector& msgItems = mit->second; + std::vector::iterator vit = msgItems.begin(); + + for(; vit != msgItems.end(); vit++) + { + RsGxsPostedPostItem* item = dynamic_cast(*vit); + + if(item) + { + RsPostedPost post = item->mPost; + post.mMeta = item->meta; + posts[grpId].push_back(post); + delete item; + }else + { + std::cerr << "Not a post Item, deleting!" << std::endl; + delete *vit; + } + } + } + } + + return ok; +} + +bool p3Posted::getComment(const uint32_t &token, PostedCommentResult &comments) +{ + GxsMsgDataMap msgData; + bool ok = RsGenExchange::getMsgData(token, msgData); + + if(ok) + { + GxsMsgDataMap::iterator mit = msgData.begin(); + + for(; mit != msgData.end(); mit++) + { + RsGxsGroupId grpId = mit->first; + std::vector& msgItems = mit->second; + std::vector::iterator vit = msgItems.begin(); + + for(; vit != msgItems.end(); vit++) + { + RsGxsPostedCommentItem* item = dynamic_cast(*vit); + + if(item) + { + RsPostedComment comment = item->mComment; + comment.mMeta = item->meta; + comments[grpId].push_back(comment); + delete item; + }else + { + std::cerr << "Not a comment Item, deleting!" << std::endl; + delete *vit; + } + } + } + } + + return ok; } bool p3Posted::submitGroup(uint32_t &token, RsPostedGroup &group) { - + RsGxsPostedGroupItem* grpItem = new RsGxsPostedGroupItem(); + grpItem->mGroup = group; + grpItem->meta = group.mMeta; + RsGenExchange::publishGroup(token, grpItem); + return true; } bool p3Posted::submitPost(uint32_t &token, RsPostedPost &post) { + RsGxsPostedPostItem* postItem = new RsGxsPostedPostItem(); + postItem->mPost = post; + postItem->meta = post.mMeta; + postItem->meta.mMsgFlags |= FLAG_MSGTYPE_POST; + RsGenExchange::publishMsg(token, postItem); + return true; } bool p3Posted::submitVote(uint32_t &token, RsPostedVote &vote) { + RsGxsPostedVoteItem* voteItem = new RsGxsPostedVoteItem(); + voteItem->mVote = vote; + voteItem->meta = vote.mMeta; + voteItem->meta.mMsgFlags |= FLAG_MSGTYPE_POST; + RsGenExchange::publishMsg(token, voteItem); + return true; } bool p3Posted::submitComment(uint32_t &token, RsPostedComment &comment) { + RsGxsPostedCommentItem* commentItem = new RsGxsPostedCommentItem(); + commentItem->mComment = comment; + commentItem->meta = comment.mMeta; + commentItem->meta.mMsgFlags |= FLAG_MSGTYPE_COMMENT; + RsGenExchange::publishMsg(token, commentItem); + return true; } // Special Ranking Request. @@ -50,36 +165,3 @@ bool p3Posted::requestRanking(uint32_t &token, RsGxsGroupId groupId) { } - -bool p3Posted::getRankedPost(const uint32_t &token, RsPostedPost &post) -{ - -} - -bool p3Posted::extractPostedCache() -{ - -} - - - // Control Ranking Calculations. -bool p3Posted::setViewMode(uint32_t mode) -{ - -} - -bool p3Posted::setViewPeriod(uint32_t period) -{ - -} - -bool p3Posted::setViewRange(uint32_t first, uint32_t count) -{ - -} - - // exposed for testing... -float p3Posted::calcPostScore(uint32_t& token, const RsGxsMessageId) -{ - -} diff --git a/libretroshare/src/services/p3posted.h b/libretroshare/src/services/p3posted.h index 6dae736db..cd198db1c 100644 --- a/libretroshare/src/services/p3posted.h +++ b/libretroshare/src/services/p3posted.h @@ -22,11 +22,13 @@ protected: */ void notifyChanges(std::vector& changes) ; + void service_tick(); + public: - bool getGroup(const uint32_t &token, RsPostedGroup &group); - bool getPost(const uint32_t &token, RsPostedPost &post) ; - bool getComment(const uint32_t &token, RsPostedComment &comment) ; + bool getGroup(const uint32_t &token, std::vector &group); + bool getPost(const uint32_t &token, PostedPostResult& posts) ; + bool getComment(const uint32_t &token, PostedCommentResult& comments) ; bool submitGroup(uint32_t &token, RsPostedGroup &group); bool submitPost(uint32_t &token, RsPostedPost &post); @@ -35,18 +37,12 @@ public: // Special Ranking Request. bool requestRanking(uint32_t &token, RsGxsGroupId groupId) ; - bool getRankedPost(const uint32_t &token, RsPostedPost &post) ; - - bool extractPostedCache() ; - // Control Ranking Calculations. - bool setViewMode(uint32_t mode); - bool setViewPeriod(uint32_t period); - bool setViewRange(uint32_t first, uint32_t count); +// bool setViewMode(uint32_t mode); +// bool setViewPeriod(uint32_t period); +// bool setViewRange(uint32_t first, uint32_t count); - // exposed for testing... - float calcPostScore(uint32_t& token, const RsGxsMessageId); }; #endif // P3POSTED_H diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index 40255f727..0cee20122 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -125,12 +125,12 @@ win32 { OBJECTS_DIR = temp/obj - PRE_TARGETDEPS += ../../libretroshare/src/lib/libretroshare.a - #PRE_TARGETDEPS += ../../libretroshare/libretroshare-build-desktop/lib/libretroshare.a + #PRE_TARGETDEPS += ../../libretroshare/src/lib/libretroshare.a + PRE_TARGETDEPS += ../../libretroshare/libretroshare-build-desktop/lib/libretroshare.a + LIBS += ../../libretroshare/libretroshare-build-desktop/lib/libretroshare.a - LIBS += ../../libretroshare/src/lib/libretroshare.a - LIBS += ../../openpgpsdk/src/lib/libops.a - LIBS += ../../../sqlite-autoconf-3070900/.libs/libsqlite3.a + LIBS += C:\Development\Rs\v0.5-gxs-b1\openpgpsdk\openpgpsdk-build-desktop\lib\libops.a + LIBS += C:\Development\Libraries\sqlite\sqlite-autoconf-3070900\.libs\libsqlite3.a LIBS += -L"../../../lib" LIBS += -lssl -lcrypto -lpthreadGC2d -lminiupnpc -lz -lbz2 # added after bitdht @@ -194,15 +194,15 @@ freebsd-* { # ########################################### bitdht { - LIBS += ../../libbitdht/src/lib/libbitdht.a - PRE_TARGETDEPS *= ../../libbitdht/src/lib/libbitdht.a + #LIBS += ../../libbitdht/src/lib/libbitdht.a + #PRE_TARGETDEPS *= ../../libbitdht/src/lib/libbitdht.a #LIBS += C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a #PRE_TARGETDEPS *= C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a # Chris version. - #LIBS += ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a - #PRE_TARGETDEPS *= ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a + LIBS += ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a + PRE_TARGETDEPS *= ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a } win32 { @@ -871,7 +871,7 @@ photoshare { gui/PhotoShare/AlbumItem.h \ gui/PhotoShare/AlbumDialog.h \ gui/PhotoShare/AlbumCreateDialog.h \ - util/TokenQueueV2.h \ + util/TokenQueue.h \ gui/PhotoShare/PhotoItem.h \ gui/PhotoShare/PhotoShareItemHolder.h \ gui/PhotoShare/PhotoShare.h \ @@ -898,7 +898,7 @@ photoshare { gui/PhotoShare/AlbumItem.cpp \ gui/PhotoShare/AlbumDialog.cpp \ gui/PhotoShare/AlbumCreateDialog.cpp \ - util/TokenQueueV2.cpp \ + util/TokenQueue.cpp \ gui/PhotoShare/PhotoShareItemHolder.cpp \ gui/PhotoShare/PhotoShare.cpp \ gui/PhotoShare/PhotoSlideShow.cpp \ diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp index 04e185fd5..c76286d1c 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp @@ -5,7 +5,7 @@ #include "util/misc.h" -AlbumCreateDialog::AlbumCreateDialog(TokenQueueV2 *photoQueue, RsPhotoV2 *rs_photo, QWidget *parent): +AlbumCreateDialog::AlbumCreateDialog(TokenQueue *photoQueue, RsPhotoV2 *rs_photo, QWidget *parent): QDialog(parent), ui(new Ui::AlbumCreateDialog), mPhotoQueue(photoQueue), mRsPhoto(rs_photo) { diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.h b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.h index d1562db69..9303ce6f6 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.h @@ -2,7 +2,7 @@ #define ALBUMCREATEDIALOG_H #include -#include "util/TokenQueueV2.h" +#include "util/TokenQueue.h" #include "retroshare/rsphotoV2.h" namespace Ui { @@ -15,7 +15,7 @@ class AlbumCreateDialog : public QDialog Q_OBJECT public: - explicit AlbumCreateDialog(TokenQueueV2* photoQueue, RsPhotoV2* rs_photo, QWidget *parent = 0); + explicit AlbumCreateDialog(TokenQueue* photoQueue, RsPhotoV2* rs_photo, QWidget *parent = 0); ~AlbumCreateDialog(); private slots: @@ -28,7 +28,7 @@ private: private: Ui::AlbumCreateDialog *ui; - TokenQueueV2* mPhotoQueue; + TokenQueue* mPhotoQueue; RsPhotoV2* mRsPhoto; QPixmap mThumbNail; }; diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp index 301ac7671..c2500df2d 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp @@ -3,7 +3,7 @@ #include "AlbumDialog.h" #include "ui_AlbumDialog.h" -AlbumDialog::AlbumDialog(const RsPhotoAlbum& album, TokenQueueV2* photoQueue, RsPhotoV2* rs_Photo, QWidget *parent) : +AlbumDialog::AlbumDialog(const RsPhotoAlbum& album, TokenQueue* photoQueue, RsPhotoV2* rs_Photo, QWidget *parent) : QWidget(parent), ui(new Ui::AlbumDialog), mPhotoQueue(photoQueue), mRsPhoto(rs_Photo), mAlbum(album), mPhotoSelected(NULL) { diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h index 73c58a2b5..0827a787e 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h @@ -3,7 +3,7 @@ #include #include "retroshare/rsphotoV2.h" -#include "util/TokenQueueV2.h" +#include "util/TokenQueue.h" #include "PhotoShareItemHolder.h" #include "PhotoItem.h" #include "PhotoDrop.h" @@ -17,7 +17,7 @@ class AlbumDialog : public QWidget, public PhotoShareItemHolder Q_OBJECT public: - explicit AlbumDialog(const RsPhotoAlbum& album, TokenQueueV2* photoQueue, RsPhotoV2* rs_Photo, QWidget *parent = 0); + explicit AlbumDialog(const RsPhotoAlbum& album, TokenQueue* photoQueue, RsPhotoV2* rs_Photo, QWidget *parent = 0); ~AlbumDialog(); void notifySelection(PhotoShareItem* selection); @@ -34,7 +34,7 @@ private slots: private: Ui::AlbumDialog *ui; RsPhotoV2* mRsPhoto; - TokenQueueV2* mPhotoQueue; + TokenQueue* mPhotoQueue; RsPhotoAlbum mAlbum; PhotoDrop* mPhotoDrop; PhotoItem* mPhotoSelected; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index 9c7d69986..9379a7f63 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -7,7 +7,7 @@ PhotoDialog::PhotoDialog(RsPhotoV2 *rs_photo, const RsPhotoPhoto &photo, QWidget *parent) : QDialog(parent), - ui(new Ui::PhotoDialog), mRsPhoto(rs_photo), mPhotoQueue(new TokenQueueV2(mRsPhoto->getTokenService(), this)), + ui(new Ui::PhotoDialog), mRsPhoto(rs_photo), mPhotoQueue(new TokenQueue(mRsPhoto->getTokenService(), this)), mPhotoDetails(photo), mCommentDialog(NULL) { @@ -75,7 +75,7 @@ void PhotoDialog::resetComments() void PhotoDialog::requestComments() { - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mMsgFlagMask = RsPhotoV2::FLAG_MSG_TYPE_MASK; opts.mMsgFlagFilter = RsPhotoV2::FLAG_MSG_TYPE_PHOTO_COMMENT; @@ -107,7 +107,7 @@ void PhotoDialog::createComment() /*************** message loading **********************/ -void PhotoDialog::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req) +void PhotoDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) { std::cerr << "PhotoShare::loadRequest()"; std::cerr << std::endl; @@ -177,7 +177,7 @@ void PhotoDialog::loadList(uint32_t token) { GxsMsgReq msgIds; mRsPhoto->getMsgList(token, msgIds); - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; // just use data as no need to worry about getting comments opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h index 0eb9fa5ee..855e14f3f 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h @@ -4,7 +4,7 @@ #include #include #include "retroshare/rsphotoV2.h" -#include "util/TokenQueueV2.h" +#include "util/TokenQueue.h" #include "PhotoCommentItem.h" #include "AddCommentDialog.h" @@ -12,7 +12,7 @@ namespace Ui { class PhotoDialog; } -class PhotoDialog : public QDialog, public TokenResponseV2 +class PhotoDialog : public QDialog, public TokenResponse { Q_OBJECT @@ -26,7 +26,7 @@ private slots: void createComment(); public: - void loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req); + void loadRequest(const TokenQueue *queue, const TokenRequest &req); private: void setUp(); @@ -54,7 +54,7 @@ private: Ui::PhotoDialog *ui; RsPhotoV2* mRsPhoto; - TokenQueueV2* mPhotoQueue; + TokenQueue* mPhotoQueue; RsPhotoPhoto mPhotoDetails; QSet mComments; AddCommentDialog* mCommentDialog; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp index 07e230697..4f1fdf342 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp @@ -96,7 +96,7 @@ PhotoShare::PhotoShare(QWidget *parent) timer->start(1000); /* setup TokenQueue */ - mPhotoQueue = new TokenQueueV2(rsPhotoV2->getTokenService(), this); + mPhotoQueue = new TokenQueue(rsPhotoV2->getTokenService(), this); requestAlbumData(); } @@ -178,7 +178,7 @@ void PhotoShare::checkUpdate() rsPhotoV2->groupsChanged(grpIds); if(!grpIds.empty()) { - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; uint32_t token; opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); @@ -490,7 +490,7 @@ void PhotoShare::updatePhotos() void PhotoShare::requestAlbumList(std::list& ids) { - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; uint32_t token; mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, ids, 0); @@ -498,7 +498,7 @@ void PhotoShare::requestAlbumList(std::list& ids) void PhotoShare::requestPhotoList(GxsMsgReq& req) { - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; uint32_t token; mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, req, 0); @@ -526,7 +526,7 @@ void PhotoShare::loadAlbumList(const uint32_t &token) void PhotoShare::requestAlbumData(std::list &ids) { - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; uint32_t token; opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, 0); @@ -534,7 +534,7 @@ void PhotoShare::requestAlbumData(std::list &ids) void PhotoShare::requestAlbumData() { - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; uint32_t token; opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, 0); @@ -569,7 +569,7 @@ void PhotoShare::requestPhotoList(const std::string &albumId) std::list grpIds; grpIds.push_back(albumId); - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; opts.mOptions = RS_TOKREQOPT_MSG_LATEST; uint32_t token; @@ -587,7 +587,7 @@ void PhotoShare::acknowledgeGroup(const uint32_t &token) std::list grpIds; grpIds.push_back(grpId); - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; uint32_t reqToken; mPhotoQueue->requestGroupInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); @@ -630,7 +630,7 @@ void PhotoShare::loadPhotoList(const uint32_t &token) void PhotoShare::requestPhotoData(GxsMsgReq &photoIds) { - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; uint32_t token; mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, photoIds, 0); @@ -638,7 +638,7 @@ void PhotoShare::requestPhotoData(GxsMsgReq &photoIds) void PhotoShare::requestPhotoData(const std::list& grpIds) { - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; uint32_t token; mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); @@ -677,7 +677,7 @@ void PhotoShare::loadPhotoData(const uint32_t &token) /**************************** Request / Response Filling of Data ************************/ -void PhotoShare::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req) +void PhotoShare::loadRequest(const TokenQueue *queue, const TokenRequest &req) { std::cerr << "PhotoShare::loadRequest()"; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.h b/retroshare-gui/src/gui/PhotoShare/PhotoShare.h index a87125a6e..b936de318 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.h @@ -16,14 +16,14 @@ #include "PhotoItem.h" #include "PhotoSlideShow.h" -#include "util/TokenQueueV2.h" +#include "util/TokenQueue.h" #include "PhotoShareItemHolder.h" namespace Ui { class PhotoShare; } -class PhotoShare : public MainPage, public TokenResponseV2, public PhotoShareItemHolder +class PhotoShare : public MainPage, public TokenResponse, public PhotoShareItemHolder { Q_OBJECT @@ -64,7 +64,7 @@ private: void loadPhotoList(const uint32_t &token); void loadPhotoData(const uint32_t &token); - void loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req); + void loadRequest(const TokenQueue *queue, const TokenRequest &req); void acknowledgeGroup(const uint32_t &token); void acknowledgeMessage(const uint32_t &token); @@ -91,7 +91,7 @@ private: AlbumDialog* mAlbumDialog; PhotoDialog* mPhotoDialog; - TokenQueueV2 *mPhotoQueue; + TokenQueue *mPhotoQueue; /* UI - from Designer */ Ui::PhotoShare ui; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp index 6b83e4b55..5af627ea1 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp @@ -38,7 +38,7 @@ PhotoSlideShow::PhotoSlideShow(const RsPhotoAlbum& album, QWidget *parent) connect(ui.pushButton_StartStop, SIGNAL( clicked( void ) ), this, SLOT( StartStop( void ) ) ); connect(ui.pushButton_Close, SIGNAL( clicked( void ) ), this, SLOT( closeShow( void ) ) ); - mPhotoQueue = new TokenQueueV2(rsPhotoV2->getTokenService(), this); + mPhotoQueue = new TokenQueue(rsPhotoV2->getTokenService(), this); mRunning = true; mShotActive = true; @@ -215,37 +215,9 @@ void PhotoSlideShow::updateMoveButtons(uint32_t status) } } - - - -void PhotoSlideShow::clearDialog() -{ -#if 0 - ui.lineEdit_Title->setText(QString("title")); - ui.lineEdit_Caption->setText(QString("Caption")); - ui.lineEdit_Where->setText(QString("Where")); - ui.lineEdit_When->setText(QString("When")); - - ui.scrollAreaWidgetContents->clearPhotos(); - ui.AlbumDrop->clearPhotos(); - - /* clean up album image */ - mAlbumData.mThumbnail.deleteImage(); - - RsPhotoAlbum emptyAlbum; - mAlbumData = emptyAlbum; - - /* add empty image */ - PhotoItem *item = new PhotoItem(NULL, mAlbumData); - ui.AlbumDrop->addPhotoItem(item); - - mAlbumEdit = false; -#endif -} - void PhotoSlideShow::requestPhotos() { - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; uint32_t token; std::list grpIds; @@ -294,7 +266,7 @@ bool PhotoSlideShow::loadPhotoData(const uint32_t &token) return true; } -void PhotoSlideShow::loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req) +void PhotoSlideShow::loadRequest(const TokenQueue *queue, const TokenRequest &req) { std::cerr << "PhotoSlideShow::loadRequest()"; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.h b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.h index 70fc7340c..1fa57337b 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.h @@ -27,10 +27,10 @@ #include "ui_PhotoSlideShow.h" #include -#include "util/TokenQueueV2.h" +#include "util/TokenQueue.h" #include "AlbumItem.h" -class PhotoSlideShow : public QWidget, public TokenResponseV2 +class PhotoSlideShow : public QWidget, public TokenResponse { Q_OBJECT @@ -38,9 +38,7 @@ public: PhotoSlideShow(const RsPhotoAlbum& mAlbum, QWidget *parent = 0); virtual ~PhotoSlideShow(); - void loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req); - - void clearDialog(); + void loadRequest(const TokenQueue *queue, const TokenRequest &req); private slots: void showPhotoDetails(); @@ -70,7 +68,7 @@ private: RsPhotoAlbum mAlbum; - TokenQueueV2 *mPhotoQueue; + TokenQueue *mPhotoQueue; Ui::PhotoSlideShow ui; }; diff --git a/retroshare-gui/src/gui/Posted/PostedComments.cpp b/retroshare-gui/src/gui/Posted/PostedComments.cpp index cbdd91fed..90345adf8 100644 --- a/retroshare-gui/src/gui/Posted/PostedComments.cpp +++ b/retroshare-gui/src/gui/Posted/PostedComments.cpp @@ -23,8 +23,7 @@ #include "PostedComments.h" -//#include -#include +#include #include #include @@ -64,26 +63,10 @@ PostedComments::PostedComments(QWidget *parent) { ui.setupUi(this); -#if 0 - mAddDialog = NULL; - mAlbumSelected = NULL; - mPhotoSelected = NULL; - mSlideShow = NULL; - - connect( ui.toolButton_NewAlbum, SIGNAL(clicked()), this, SLOT(OpenOrShowPhotoAddDialog())); - connect( ui.toolButton_EditAlbum, SIGNAL(clicked()), this, SLOT(OpenPhotoEditDialog())); - connect( ui.toolButton_SlideShow, SIGNAL(clicked()), this, SLOT(OpenSlideShow())); - - QTimer *timer = new QTimer(this); - timer->connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate())); - timer->start(1000); - -#endif - /* setup TokenQueue */ //mPhotoQueue = new TokenQueue(rsPhoto, this); - ui.treeWidget->setup(rsPostedVEG); + ui.treeWidget->setup(rsPosted->getTokenService()); } @@ -96,543 +79,3 @@ void PostedComments::loadComments( std::string threadId ) } -#if 0 - -void PhotoDialog::notifySelection(PhotoItem *item, int ptype) -{ - std::cerr << "PhotoDialog::notifySelection() from : " << ptype << " " << item; - std::cerr << std::endl; - - switch(ptype) - { - default: - case PHOTO_ITEM_TYPE_ALBUM: - notifyAlbumSelection(item); - break; - case PHOTO_ITEM_TYPE_PHOTO: - notifyPhotoSelection(item); - break; - } -} - -void PhotoDialog::notifyAlbumSelection(PhotoItem *item) -{ - std::cerr << "PhotoDialog::notifyAlbumSelection() from : " << item; - std::cerr << std::endl; - - if (mAlbumSelected) - { - std::cerr << "PhotoDialog::notifyAlbumSelection() unselecting old one : " << mAlbumSelected; - std::cerr << std::endl; - - mAlbumSelected->setSelected(false); - } - - mAlbumSelected = item; - insertPhotosForSelectedAlbum(); -} - - -void PhotoDialog::notifyPhotoSelection(PhotoItem *item) -{ - std::cerr << "PhotoDialog::notifyPhotoSelection() from : " << item; - std::cerr << std::endl; - - if (mPhotoSelected) - { - std::cerr << "PhotoDialog::notifyPhotoSelection() unselecting old one : " << mPhotoSelected; - std::cerr << std::endl; - - mPhotoSelected->setSelected(false); - } - - mPhotoSelected = item; -} - - -void PhotoDialog::checkUpdate() -{ - /* update */ - if (!rsPhoto) - return; - - if (rsPhoto->updated()) - { - //insertAlbums(); - requestAlbumList(); - } - - return; -} - - -/*************** New Photo Dialog ***************/ - -void PhotoDialog::OpenSlideShow() -{ - - // TODO. - if (!mAlbumSelected) - { - // ALERT. - int ret = QMessageBox::information(this, tr("PhotoShare"), - tr("Please select an album before\n" - "requesting to edit it!"), - QMessageBox::Ok); - return; - } - - if (mAlbumSelected->mIsPhoto) - { - std::cerr << "PhotoDialog::OpenPhotoEditDialog() MAJOR ERROR!"; - std::cerr << std::endl; - return; - } - - std::string albumId = mAlbumSelected->mAlbumDetails.mMeta.mGroupId; - - if (mSlideShow) - { - mSlideShow->show(); - } - else - { - mSlideShow = new PhotoSlideShow(NULL); - mSlideShow->show(); - } - mSlideShow->loadAlbum(albumId); - -} - - -/*************** New Photo Dialog ***************/ - -void PhotoDialog::OpenOrShowPhotoAddDialog() -{ - if (mAddDialog) - { - mAddDialog->show(); - } - else - { - mAddDialog = new PhotoAddDialog(NULL); - mAddDialog->show(); - } - mAddDialog->clearDialog(); -} - - -/*************** Edit Photo Dialog ***************/ - -void PhotoDialog::OpenPhotoEditDialog() -{ - /* check if we have an album selected */ - // THE TWO MessageBoxes - should be handled by disabling the Button!. - // TODO. - if (!mAlbumSelected) - { - // ALERT. - int ret = QMessageBox::information(this, tr("PhotoShare"), - tr("Please select an album before\n" - "requesting to edit it!"), - QMessageBox::Ok); - return; - } - - if (mAlbumSelected->mIsPhoto) - { - std::cerr << "PhotoDialog::OpenPhotoEditDialog() MAJOR ERROR!"; - std::cerr << std::endl; - } - - std::string albumId = mAlbumSelected->mAlbumDetails.mMeta.mGroupId; -#if 0 - uint32_t flags = mAlbumSelected->mAlbumDetails.mMeta.mGroupFlags; - - if (!(flags & OWN)) - { - // ALERT. - int ret = QMessageBox::information(this, tr("PhotoShare"), - tr("Cannot Edit Someone Else's Album"), - QMessageBox::Ok); - return; - } -#endif - - OpenOrShowPhotoAddDialog(); - mAddDialog->loadAlbum(albumId); - -} - - -bool PhotoDialog::matchesAlbumFilter(const RsPhotoAlbum &album) -{ - - return true; -} - -double PhotoDialog::AlbumScore(const RsPhotoAlbum &album) -{ - return 1; -} - - -bool PhotoDialog::matchesPhotoFilter(const RsPhotoPhoto &photo) -{ - - return true; -} - -double PhotoDialog::PhotoScore(const RsPhotoPhoto &photo) -{ - return 1; -} - -void PhotoDialog::insertPhotosForSelectedAlbum() -{ - std::cerr << "PhotoDialog::insertPhotosForSelectedAlbum()"; - std::cerr << std::endl; - - clearPhotos(); - - //std::list albumIds; - if (mAlbumSelected) - { - if (mAlbumSelected->mIsPhoto) - { - std::cerr << "PhotoDialog::insertPhotosForSelectedAlbum() MAJOR ERROR!"; - std::cerr << std::endl; - } - - std::string albumId = mAlbumSelected->mAlbumDetails.mMeta.mGroupId; - //albumIds.push_back(albumId); - - std::cerr << "PhotoDialog::insertPhotosForSelectedAlbum() AlbumId: " << albumId; - std::cerr << std::endl; - requestPhotoList(albumId); - } - //requestPhotoList(albumIds); -} - - -void PhotoDialog::clearAlbums() -{ - std::cerr << "PhotoDialog::clearAlbums()" << std::endl; - - std::list photoItems; - std::list::iterator pit; - - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - int count = alayout->count(); - for(int i = 0; i < count; i++) - { - QLayoutItem *litem = alayout->itemAt(i); - if (!litem) - { - std::cerr << "PhotoDialog::clearAlbums() missing litem"; - std::cerr << std::endl; - continue; - } - - PhotoItem *item = dynamic_cast(litem->widget()); - if (item) - { - std::cerr << "PhotoDialog::clearAlbums() item: " << item; - std::cerr << std::endl; - - photoItems.push_back(item); - } - else - { - std::cerr << "PhotoDialog::clearAlbums() Found Child, which is not a PhotoItem???"; - std::cerr << std::endl; - } - } - - for(pit = photoItems.begin(); pit != photoItems.end(); pit++) - { - PhotoItem *item = *pit; - alayout->removeWidget(item); - delete item; - } - mAlbumSelected = NULL; - -} - -void PhotoDialog::clearPhotos() -{ - std::cerr << "PhotoDialog::clearPhotos()" << std::endl; - - std::list photoItems; - std::list::iterator pit; - - QLayout *alayout = ui.scrollAreaWidgetContents_2->layout(); - int count = alayout->count(); - for(int i = 0; i < count; i++) - { - QLayoutItem *litem = alayout->itemAt(i); - if (!litem) - { - std::cerr << "PhotoDialog::clearPhotos() missing litem"; - std::cerr << std::endl; - continue; - } - - PhotoItem *item = dynamic_cast(litem->widget()); - if (item) - { - std::cerr << "PhotoDialog::clearPhotos() item: " << item; - std::cerr << std::endl; - - photoItems.push_back(item); - } - else - { - std::cerr << "PhotoDialog::clearPhotos() Found Child, which is not a PhotoItem???"; - std::cerr << std::endl; - } - } - - for(pit = photoItems.begin(); pit != photoItems.end(); pit++) - { - PhotoItem *item = *pit; - alayout->removeWidget(item); - delete item; - } - - mPhotoSelected = NULL; - - -} - -void PhotoDialog::addAlbum(const RsPhotoAlbum &album) -{ - std::cerr << " PhotoDialog::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; - - PhotoItem *item = new PhotoItem(this, album); - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - alayout->addWidget(item); -} - - -void PhotoDialog::addPhoto(const RsPhotoPhoto &photo) -{ - std::cerr << "PhotoDialog::addPhoto() AlbumId: " << photo.mMeta.mGroupId; - std::cerr << " PhotoId: " << photo.mMeta.mMsgId; - std::cerr << std::endl; - - RsPhotoAlbum dummyAlbum; - dummyAlbum.mSetFlags = 0; - - PhotoItem *item = new PhotoItem(this, photo, dummyAlbum); - QLayout *alayout = ui.scrollAreaWidgetContents_2->layout(); - alayout->addWidget(item); - -} - -void PhotoDialog::deletePhotoItem(PhotoItem *item, uint32_t type) -{ - - - return; -} - - -/**************************** Request / Response Filling of Data ************************/ - - -void PhotoDialog::requestAlbumList() -{ - - std::list ids; - RsTokReqOptions opts; - uint32_t token; - mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, ids, 0); -} - - -void PhotoDialog::loadAlbumList(const uint32_t &token) -{ - std::cerr << "PhotoDialog::loadAlbumList()"; - std::cerr << std::endl; - - std::list albumIds; - rsPhoto->getGroupList(token, albumIds); - - requestAlbumData(albumIds); - - clearPhotos(); - - std::list::iterator it; - for(it = albumIds.begin(); it != albumIds.end(); it++) - { - requestPhotoList(*it); - } - -} - - -void PhotoDialog::requestAlbumData(const std::list &ids) -{ - RsTokReqOptions opts; - uint32_t token; - mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, 0); -} - - -bool PhotoDialog::loadAlbumData(const uint32_t &token) -{ - std::cerr << "PhotoDialog::loadAlbumData()"; - std::cerr << std::endl; - - clearAlbums(); - - bool moreData = true; - while(moreData) - { - RsPhotoAlbum album; - if (rsPhoto->getAlbum(token, album)) - { - std::cerr << " PhotoDialog::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; - - PhotoItem *item = new PhotoItem(this, album); - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - alayout->addWidget(item); - } - else - { - moreData = false; - } - } - - return true; -} - - -void PhotoDialog::requestPhotoList(const std::string &albumId) -{ - - std::list ids; - ids.push_back(albumId); - RsTokReqOptions opts; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - uint32_t token; - mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, ids, 0); -} - - - - -void PhotoDialog::loadPhotoList(const uint32_t &token) -{ - std::cerr << "PhotoDialog::loadPhotoList()"; - std::cerr << std::endl; - - - std::list photoIds; - - rsPhoto->getMsgList(token, photoIds); - requestPhotoData(photoIds); -} - - -void PhotoDialog::requestPhotoData(const std::list &photoIds) -{ - RsTokReqOptions opts; - uint32_t token; - mPhotoQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, photoIds, 0); -} - - -void PhotoDialog::loadPhotoData(const uint32_t &token) -{ - std::cerr << "PhotoDialog::loadPhotoData()"; - std::cerr << std::endl; - - bool moreData = true; - while(moreData) - { - RsPhotoPhoto photo; - - if (rsPhoto->getPhoto(token, photo)) - { - - std::cerr << "PhotoDialog::loadPhotoData() AlbumId: " << photo.mMeta.mGroupId; - std::cerr << " PhotoId: " << photo.mMeta.mMsgId; - std::cerr << std::endl; - - addPhoto(photo); - } - else - { - moreData = false; - } - } -} - - -/********************************/ - -void PhotoDialog::loadRequest(const TokenQueue *queue, const TokenRequestVEG &req) -{ - std::cerr << "PhotoDialog::loadRequest()"; - std::cerr << std::endl; - - if (queue == mPhotoQueue) - { - /* now switch on req */ - switch(req.mType) - { - case TOKENREQ_GROUPINFO: - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_LIST: - loadAlbumList(req.mToken); - break; - case RS_TOKREQ_ANSTYPE_DATA: - loadAlbumData(req.mToken); - break; - default: - std::cerr << "PhotoDialog::loadRequest() ERROR: GROUP: INVALID ANS TYPE"; - std::cerr << std::endl; - break; - } - break; - case TOKENREQ_MSGINFO: - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_LIST: - loadPhotoList(req.mToken); - break; - //case RS_TOKREQ_ANSTYPE_DATA: - // loadPhotoData(req.mToken); - // break; - default: - std::cerr << "PhotoDialog::loadRequest() ERROR: MSG: INVALID ANS TYPE"; - std::cerr << std::endl; - break; - } - break; - case TOKENREQ_MSGRELATEDINFO: - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_DATA: - loadPhotoData(req.mToken); - break; - default: - std::cerr << "PhotoDialog::loadRequest() ERROR: MSG: INVALID ANS TYPE"; - std::cerr << std::endl; - break; - } - break; - default: - std::cerr << "PhotoDialog::loadRequest() ERROR: INVALID TYPE"; - std::cerr << std::endl; - break; - } - } -} - - -#endif - diff --git a/retroshare-gui/src/gui/Posted/PostedComments.h b/retroshare-gui/src/gui/Posted/PostedComments.h index 29569cc28..8a1d78e57 100644 --- a/retroshare-gui/src/gui/Posted/PostedComments.h +++ b/retroshare-gui/src/gui/Posted/PostedComments.h @@ -27,7 +27,7 @@ //#include "gui/mainpage.h" #include "ui_PostedComments.h" -#include +#include #include diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.cpp b/retroshare-gui/src/gui/Posted/PostedDialog.cpp index fcf93a908..1f1ec1cdd 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedDialog.cpp @@ -26,7 +26,7 @@ #include "PostedListDialog.h" #include "PostedComments.h" -#include +#include #include #include @@ -40,21 +40,8 @@ /**************************************************************** - * New Photo Display Widget. + * Posted Dialog * - * This has two 'lists'. - * Top list shows Albums. - * Lower list is photos from the selected Album. - * - * Notes: - * Each Item will be an AlbumItem, which contains a thumbnail & random details. - * We will limit Items to < 100. With a 'Filter to see more message. - * - * Thumbnails will come from Service. - * Option to Share albums / pictures onward (if permissions allow). - * Option to Download the albums to a specified directory. (is this required if sharing an album?) - * - * Will introduce a FullScreen SlideShow later... first get basics happening. */ PostedDialog::PostedDialog(QWidget *parent) @@ -74,587 +61,6 @@ PostedDialog::PostedDialog(QWidget *parent) } -#if 0 - - - - -/** Constructor */ -PhotoDialog::PhotoDialog(QWidget *parent) -: MainPage(parent) -{ - ui.setupUi(this); - - mAddDialog = NULL; - mAlbumSelected = NULL; - mPhotoSelected = NULL; - mSlideShow = NULL; - - connect( ui.toolButton_NewAlbum, SIGNAL(clicked()), this, SLOT(OpenOrShowPhotoAddDialog())); - connect( ui.toolButton_EditAlbum, SIGNAL(clicked()), this, SLOT(OpenPhotoEditDialog())); - connect( ui.toolButton_SlideShow, SIGNAL(clicked()), this, SLOT(OpenSlideShow())); - - QTimer *timer = new QTimer(this); - timer->connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate())); - timer->start(1000); - - - /* setup TokenQueue */ - mPhotoQueue = new TokenQueue(rsPhoto, this); - -} - - -void PhotoDialog::notifySelection(PhotoItem *item, int ptype) -{ - std::cerr << "PhotoDialog::notifySelection() from : " << ptype << " " << item; - std::cerr << std::endl; - - switch(ptype) - { - default: - case PHOTO_ITEM_TYPE_ALBUM: - notifyAlbumSelection(item); - break; - case PHOTO_ITEM_TYPE_PHOTO: - notifyPhotoSelection(item); - break; - } -} - -void PhotoDialog::notifyAlbumSelection(PhotoItem *item) -{ - std::cerr << "PhotoDialog::notifyAlbumSelection() from : " << item; - std::cerr << std::endl; - - if (mAlbumSelected) - { - std::cerr << "PhotoDialog::notifyAlbumSelection() unselecting old one : " << mAlbumSelected; - std::cerr << std::endl; - - mAlbumSelected->setSelected(false); - } - - mAlbumSelected = item; - insertPhotosForSelectedAlbum(); -} - - -void PhotoDialog::notifyPhotoSelection(PhotoItem *item) -{ - std::cerr << "PhotoDialog::notifyPhotoSelection() from : " << item; - std::cerr << std::endl; - - if (mPhotoSelected) - { - std::cerr << "PhotoDialog::notifyPhotoSelection() unselecting old one : " << mPhotoSelected; - std::cerr << std::endl; - - mPhotoSelected->setSelected(false); - } - - mPhotoSelected = item; -} - - -void PhotoDialog::checkUpdate() -{ - /* update */ - if (!rsPhoto) - return; - - if (rsPhoto->updated()) - { - //insertAlbums(); - requestAlbumList(); - } - - return; -} - - -/*************** New Photo Dialog ***************/ - -void PhotoDialog::OpenSlideShow() -{ - - // TODO. - if (!mAlbumSelected) - { - // ALERT. - int ret = QMessageBox::information(this, tr("PhotoShare"), - tr("Please select an album before\n" - "requesting to edit it!"), - QMessageBox::Ok); - return; - } - - if (mAlbumSelected->mIsPhoto) - { - std::cerr << "PhotoDialog::OpenPhotoEditDialog() MAJOR ERROR!"; - std::cerr << std::endl; - return; - } - - std::string albumId = mAlbumSelected->mAlbumDetails.mMeta.mGroupId; - - if (mSlideShow) - { - mSlideShow->show(); - } - else - { - mSlideShow = new PhotoSlideShow(NULL); - mSlideShow->show(); - } - mSlideShow->loadAlbum(albumId); - -} - - -/*************** New Photo Dialog ***************/ - -void PhotoDialog::OpenOrShowPhotoAddDialog() -{ - if (mAddDialog) - { - mAddDialog->show(); - } - else - { - mAddDialog = new PhotoAddDialog(NULL); - mAddDialog->show(); - } - mAddDialog->clearDialog(); -} - - -/*************** Edit Photo Dialog ***************/ - -void PhotoDialog::OpenPhotoEditDialog() -{ - /* check if we have an album selected */ - // THE TWO MessageBoxes - should be handled by disabling the Button!. - // TODO. - if (!mAlbumSelected) - { - // ALERT. - int ret = QMessageBox::information(this, tr("PhotoShare"), - tr("Please select an album before\n" - "requesting to edit it!"), - QMessageBox::Ok); - return; - } - - if (mAlbumSelected->mIsPhoto) - { - std::cerr << "PhotoDialog::OpenPhotoEditDialog() MAJOR ERROR!"; - std::cerr << std::endl; - } - - std::string albumId = mAlbumSelected->mAlbumDetails.mMeta.mGroupId; -#if 0 - uint32_t flags = mAlbumSelected->mAlbumDetails.mMeta.mGroupFlags; - - if (!(flags & OWN)) - { - // ALERT. - int ret = QMessageBox::information(this, tr("PhotoShare"), - tr("Cannot Edit Someone Else's Album"), - QMessageBox::Ok); - return; - } -#endif - - OpenOrShowPhotoAddDialog(); - mAddDialog->loadAlbum(albumId); - -} - - -bool PhotoDialog::matchesAlbumFilter(const RsPhotoAlbum &album) -{ - - return true; -} - -double PhotoDialog::AlbumScore(const RsPhotoAlbum &album) -{ - return 1; -} - - -bool PhotoDialog::matchesPhotoFilter(const RsPhotoPhoto &photo) -{ - - return true; -} - -double PhotoDialog::PhotoScore(const RsPhotoPhoto &photo) -{ - return 1; -} - -void PhotoDialog::insertPhotosForSelectedAlbum() -{ - std::cerr << "PhotoDialog::insertPhotosForSelectedAlbum()"; - std::cerr << std::endl; - - clearPhotos(); - - //std::list albumIds; - if (mAlbumSelected) - { - if (mAlbumSelected->mIsPhoto) - { - std::cerr << "PhotoDialog::insertPhotosForSelectedAlbum() MAJOR ERROR!"; - std::cerr << std::endl; - } - - std::string albumId = mAlbumSelected->mAlbumDetails.mMeta.mGroupId; - //albumIds.push_back(albumId); - - std::cerr << "PhotoDialog::insertPhotosForSelectedAlbum() AlbumId: " << albumId; - std::cerr << std::endl; - requestPhotoList(albumId); - } - //requestPhotoList(albumIds); -} - - -void PhotoDialog::clearAlbums() -{ - std::cerr << "PhotoDialog::clearAlbums()" << std::endl; - - std::list photoItems; - std::list::iterator pit; - - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - int count = alayout->count(); - for(int i = 0; i < count; i++) - { - QLayoutItem *litem = alayout->itemAt(i); - if (!litem) - { - std::cerr << "PhotoDialog::clearAlbums() missing litem"; - std::cerr << std::endl; - continue; - } - - PhotoItem *item = dynamic_cast(litem->widget()); - if (item) - { - std::cerr << "PhotoDialog::clearAlbums() item: " << item; - std::cerr << std::endl; - - photoItems.push_back(item); - } - else - { - std::cerr << "PhotoDialog::clearAlbums() Found Child, which is not a PhotoItem???"; - std::cerr << std::endl; - } - } - - for(pit = photoItems.begin(); pit != photoItems.end(); pit++) - { - PhotoItem *item = *pit; - alayout->removeWidget(item); - delete item; - } - mAlbumSelected = NULL; - -} - -void PhotoDialog::clearPhotos() -{ - std::cerr << "PhotoDialog::clearPhotos()" << std::endl; - - std::list photoItems; - std::list::iterator pit; - - QLayout *alayout = ui.scrollAreaWidgetContents_2->layout(); - int count = alayout->count(); - for(int i = 0; i < count; i++) - { - QLayoutItem *litem = alayout->itemAt(i); - if (!litem) - { - std::cerr << "PhotoDialog::clearPhotos() missing litem"; - std::cerr << std::endl; - continue; - } - - PhotoItem *item = dynamic_cast(litem->widget()); - if (item) - { - std::cerr << "PhotoDialog::clearPhotos() item: " << item; - std::cerr << std::endl; - - photoItems.push_back(item); - } - else - { - std::cerr << "PhotoDialog::clearPhotos() Found Child, which is not a PhotoItem???"; - std::cerr << std::endl; - } - } - - for(pit = photoItems.begin(); pit != photoItems.end(); pit++) - { - PhotoItem *item = *pit; - alayout->removeWidget(item); - delete item; - } - - mPhotoSelected = NULL; - - -} - -void PhotoDialog::addAlbum(const RsPhotoAlbum &album) -{ - std::cerr << " PhotoDialog::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; - - PhotoItem *item = new PhotoItem(this, album); - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - alayout->addWidget(item); -} - - -void PhotoDialog::addPhoto(const RsPhotoPhoto &photo) -{ - std::cerr << "PhotoDialog::addPhoto() AlbumId: " << photo.mMeta.mGroupId; - std::cerr << " PhotoId: " << photo.mMeta.mMsgId; - std::cerr << std::endl; - - RsPhotoAlbum dummyAlbum; - dummyAlbum.mSetFlags = 0; - - PhotoItem *item = new PhotoItem(this, photo, dummyAlbum); - QLayout *alayout = ui.scrollAreaWidgetContents_2->layout(); - alayout->addWidget(item); - -} - -void PhotoDialog::deletePhotoItem(PhotoItem *item, uint32_t type) -{ - - - return; -} - - -/**************************** Request / Response Filling of Data ************************/ - - -void PhotoDialog::requestAlbumList() -{ - - std::list ids; - RsTokReqOptions opts; - uint32_t token; - mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, ids, 0); -} - - -void PhotoDialog::loadAlbumList(const uint32_t &token) -{ - std::cerr << "PhotoDialog::loadAlbumList()"; - std::cerr << std::endl; - - std::list albumIds; - rsPhoto->getGroupList(token, albumIds); - - requestAlbumData(albumIds); - - clearPhotos(); - - std::list::iterator it; - for(it = albumIds.begin(); it != albumIds.end(); it++) - { - requestPhotoList(*it); - } - -} - - -void PhotoDialog::requestAlbumData(const std::list &ids) -{ - RsTokReqOptions opts; - uint32_t token; - mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, 0); -} - - -bool PhotoDialog::loadAlbumData(const uint32_t &token) -{ - std::cerr << "PhotoDialog::loadAlbumData()"; - std::cerr << std::endl; - - clearAlbums(); - - bool moreData = true; - while(moreData) - { - RsPhotoAlbum album; - if (rsPhoto->getAlbum(token, album)) - { - std::cerr << " PhotoDialog::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; - - PhotoItem *item = new PhotoItem(this, album); - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - alayout->addWidget(item); - } - else - { - moreData = false; - } - } - - return true; -} - - -void PhotoDialog::requestPhotoList(const std::string &albumId) -{ - - std::list ids; - ids.push_back(albumId); - RsTokReqOptions opts; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - uint32_t token; - mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, ids, 0); -} - - - - -void PhotoDialog::loadPhotoList(const uint32_t &token) -{ - std::cerr << "PhotoDialog::loadPhotoList()"; - std::cerr << std::endl; - - - std::list photoIds; - - rsPhoto->getMsgList(token, photoIds); - requestPhotoData(photoIds); -} - - -void PhotoDialog::requestPhotoData(const std::list &photoIds) -{ - RsTokReqOptions opts; - uint32_t token; - mPhotoQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, photoIds, 0); -} - - -void PhotoDialog::loadPhotoData(const uint32_t &token) -{ - std::cerr << "PhotoDialog::loadPhotoData()"; - std::cerr << std::endl; - - bool moreData = true; - while(moreData) - { - RsPhotoPhoto photo; - - if (rsPhoto->getPhoto(token, photo)) - { - - std::cerr << "PhotoDialog::loadPhotoData() AlbumId: " << photo.mMeta.mGroupId; - std::cerr << " PhotoId: " << photo.mMeta.mMsgId; - std::cerr << std::endl; - - addPhoto(photo); - } - else - { - moreData = false; - } - } -} - - -/********************************/ - -void PhotoDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) -{ - std::cerr << "PhotoDialog::loadRequest()"; - std::cerr << std::endl; - - if (queue == mPhotoQueue) - { - /* now switch on req */ - switch(req.mType) - { - case TOKENREQ_GROUPINFO: - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_LIST: - loadAlbumList(req.mToken); - break; - case RS_TOKREQ_ANSTYPE_DATA: - loadAlbumData(req.mToken); - break; - default: - std::cerr << "PhotoDialog::loadRequest() ERROR: GROUP: INVALID ANS TYPE"; - std::cerr << std::endl; - break; - } - break; - case TOKENREQ_MSGINFO: - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_LIST: - loadPhotoList(req.mToken); - break; - //case RS_TOKREQ_ANSTYPE_DATA: - // loadPhotoData(req.mToken); - // break; - default: - std::cerr << "PhotoDialog::loadRequest() ERROR: MSG: INVALID ANS TYPE"; - std::cerr << std::endl; - break; - } - break; - case TOKENREQ_MSGRELATEDINFO: - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_DATA: - loadPhotoData(req.mToken); - break; - default: - std::cerr << "PhotoDialog::loadRequest() ERROR: MSG: INVALID ANS TYPE"; - std::cerr << std::endl; - break; - } - break; - default: - std::cerr << "PhotoDialog::loadRequest() ERROR: INVALID TYPE"; - std::cerr << std::endl; - break; - } - } -} - - -/**************************** Request / Response Filling of Data ************************/ - - -#endif - - - - - - - - - - diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.h b/retroshare-gui/src/gui/Posted/PostedDialog.h index 954d3ae0a..823d44850 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedDialog.h @@ -27,7 +27,7 @@ #include "retroshare-gui/mainpage.h" #include "ui_PostedDialog.h" -#include +#include #include diff --git a/retroshare-gui/src/gui/Posted/PostedItem.cpp b/retroshare-gui/src/gui/Posted/PostedItem.cpp index 80955432c..9a0f756c5 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.cpp +++ b/retroshare-gui/src/gui/Posted/PostedItem.cpp @@ -30,7 +30,7 @@ #include "PostedItem.h" -#include +#include #include #include @@ -53,7 +53,7 @@ PostedItem::PostedItem(PostedHolder *parent, const RsPostedPost &post) //scoreLabel->setText(QString("1140")); // exposed for testing... - float score = rsPostedVEG->calcPostScore(post.mMeta); + float score = 0; time_t now = time(NULL); QString fromLabelTxt = QString(" Age: ") + QString::number(now - post.mMeta.mPublishTs); @@ -62,7 +62,7 @@ PostedItem::PostedItem(PostedHolder *parent, const RsPostedPost &post) uint32_t votes = 0; uint32_t comments = 0; - rsPostedVEG->extractPostedCache(post.mMeta.mServiceString, votes, comments); + //rsPosted->extractPostedCache(post.mMeta.mServiceString, votes, comments); scoreLabel->setText(QString::number(votes)); QString commentLabel = QString("Comments: ") + QString::number(comments); commentLabel += QString(" Votes: ") + QString::number(votes); @@ -87,247 +87,3 @@ void PostedItem::loadComments() std::cerr << std::endl; mParent->requestComments(mThreadId); } - - -#if 0 - -PhotoItem::PhotoItem(PhotoHolder *parent, const RsPhotoAlbum &album) -:QWidget(NULL), mParent(parent), mType(PHOTO_ITEM_TYPE_ALBUM) -{ - setupUi(this); - setAttribute ( Qt::WA_DeleteOnClose, true ); - - mIsPhoto = false; - setDummyText(); - updateAlbumText(album); // saves: mAlbumDetails = album; - updateImage(album.mThumbnail); - - setSelected(false); -} - - -PhotoItem::PhotoItem(PhotoHolder *parent, const RsPhotoPhoto &photo, const RsPhotoAlbum &album) -:QWidget(NULL), mParent(parent), mType(PHOTO_ITEM_TYPE_PHOTO) -{ - setupUi(this); - - setAttribute ( Qt::WA_DeleteOnClose, true ); - - mIsPhoto = true; - - setDummyText(); - updatePhotoText(photo); // saves: mPhotoDetails = photo; - updateAlbumText(album); // saves: mAlbumDetails = album; - - updateImage(photo.mThumbnail); - - setSelected(false); -} - - -PhotoItem::PhotoItem(PhotoHolder *parent, std::string path) // for new photos. -:QWidget(NULL), mParent(parent), mType(PHOTO_ITEM_TYPE_NEW) -{ - setupUi(this); - - setAttribute ( Qt::WA_DeleteOnClose, true ); - - setDummyText(); - mIsPhoto = true; - - int width = 120; - int height = 120; - - //QPixmap qtn = QPixmap(QString::fromStdString(path)).scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - QPixmap qtn = QPixmap(QString::fromStdString(path)).scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation); - imgLabel->setPixmap(qtn); - setSelected(false); -} - -void PhotoItem::updateParent(PhotoHolder *parent) // for external construction. -{ - mParent = parent; -} - - -void PhotoItem::setDummyText() -{ - titleLabel->setText(QString("Unknown")); - fromBoldLabel->setText(QString("By:")); - fromLabel->setText(QString("Unknown")); - statusBoldLabel->setText(QString("Where:")); - statusLabel->setText(QString("Unknown")); - dateBoldLabel->setText(QString("When:")); - dateLabel->setText(QString("Unknown")); -} - - -void PhotoItem::updateAlbumText(const RsPhotoAlbum &album) -{ - mAlbumDetails = album; - mAlbumDetails.mThumbnail.data = 0; - updateText(); -} - -void PhotoItem::updatePhotoText(const RsPhotoPhoto &photo) -{ - // Save new Photo details. - mPhotoDetails = photo; - mPhotoDetails.mThumbnail.data = 0; - updateText(); -} - - - -void PhotoItem::updateText() -{ - // SET Album Values first -> then overwrite with Photo Values. - if (mAlbumDetails.mSetFlags & RSPHOTO_FLAGS_ATTRIB_TITLE) - { - titleLabel->setText(QString::fromUtf8(mAlbumDetails.mMeta.mGroupName.c_str())); - } - - // This needs to be fixed!! TODO - fromLabel->setText(QString::fromStdString(mAlbumDetails.mMeta.mGroupId)); - if (mAlbumDetails.mSetFlags & RSPHOTO_FLAGS_ATTRIB_AUTHOR) - { - // This needs to be fixed!! TODO - fromLabel->setText(QString::fromStdString(mAlbumDetails.mMeta.mGroupId)); - } - - if (mAlbumDetails.mSetFlags & RSPHOTO_FLAGS_ATTRIB_WHERE) - { - statusLabel->setText(QString::fromUtf8(mAlbumDetails.mWhere.c_str())); - } - - if (mAlbumDetails.mSetFlags & RSPHOTO_FLAGS_ATTRIB_WHEN) - { - dateLabel->setText(QString::fromUtf8(mAlbumDetails.mWhen.c_str())); - } - - // NOW Photo Bits. - if (mIsPhoto) - { - if (mPhotoDetails.mSetFlags & RSPHOTO_FLAGS_ATTRIB_TITLE) - { - titleLabel->setText(QString::fromUtf8(mPhotoDetails.mMeta.mMsgName.c_str())); - } - - if (mPhotoDetails.mSetFlags & RSPHOTO_FLAGS_ATTRIB_AUTHOR) - { - // This needs to be fixed!! TODO - fromLabel->setText(QString::fromStdString(mPhotoDetails.mMeta.mAuthorId)); - } - - if (mPhotoDetails.mSetFlags & RSPHOTO_FLAGS_ATTRIB_WHERE) - { - statusLabel->setText(QString::fromUtf8(mPhotoDetails.mWhere.c_str())); - } - - if (mPhotoDetails.mSetFlags & RSPHOTO_FLAGS_ATTRIB_WHEN) - { - dateLabel->setText(QString::fromUtf8(mPhotoDetails.mWhen.c_str())); - } - } - -} - -void PhotoItem::updateImage(const RsPhotoThumbnail &thumbnail) -{ - if (thumbnail.data != NULL) - { - QPixmap qtn; - qtn.loadFromData(thumbnail.data, thumbnail.size, thumbnail.type.c_str()); - imgLabel->setPixmap(qtn); - } -} - -bool PhotoItem::getPhotoThumbnail(RsPhotoThumbnail &nail) -{ - const QPixmap *tmppix = imgLabel->pixmap(); - - QByteArray ba; - QBuffer buffer(&ba); - - if(!tmppix->isNull()) - { - // send chan image - - buffer.open(QIODevice::WriteOnly); - tmppix->save(&buffer, "PNG"); // writes image into ba in PNG format - - RsPhotoThumbnail tmpnail; - tmpnail.data = (uint8_t *) ba.data(); - tmpnail.size = ba.size(); - - nail.copyFrom(tmpnail); - - return true; - } - - nail.data = NULL; - nail.size = 0; - return false; -} - - -void PhotoItem::removeItem() -{ -#ifdef DEBUG_ITEM - std::cerr << "PhotoItem::removeItem()"; - std::cerr << std::endl; -#endif - hide(); - if (mParent) - { - mParent->deletePhotoItem(this, mType); - } -} - - -void PhotoItem::setSelected(bool on) -{ - mSelected = on; - if (mSelected) - { - mParent->notifySelection(this, mType); - frame->setStyleSheet("QFrame#frame{border: 2px solid #55CC55;\nbackground: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #55EE55, stop: 1 #CCCCCC);\nborder-radius: 10px}"); - } - else - { - frame->setStyleSheet("QFrame#frame{border: 2px solid #CCCCCC;\nbackground: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #EEEEEE, stop: 1 #CCCCCC);\nborder-radius: 10px}"); - } - update(); -} - -bool PhotoItem::isSelected() -{ - return mSelected; -} - - -void PhotoItem::mousePressEvent(QMouseEvent *event) -{ - /* We can be very cunning here? - * grab out position. - * flag ourselves as selected. - * then pass the mousePressEvent up for handling by the parent - */ - - QPoint pos = event->pos(); - - std::cerr << "PhotoItem::mousePressEvent(" << pos.x() << ", " << pos.y() << ")"; - std::cerr << std::endl; - - setSelected(true); - - QWidget::mousePressEvent(event); -} - - -const QPixmap *PhotoItem::getPixmap() -{ - return imgLabel->pixmap(); -} - -#endif diff --git a/retroshare-gui/src/gui/Posted/PostedItem.h b/retroshare-gui/src/gui/Posted/PostedItem.h index 79690548a..b13925802 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.h +++ b/retroshare-gui/src/gui/Posted/PostedItem.h @@ -26,7 +26,7 @@ #include "ui_PostedItem.h" -#include +#include class RsPostedPost; class PostedItem; diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp index b174f7e64..87f1e31b5 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp @@ -25,8 +25,7 @@ #include "gui/gxs/PostedGroupDialog.h" -//#include -#include +#include #include #include @@ -69,7 +68,7 @@ PostedListDialog::PostedListDialog(QWidget *parent) ui.setupUi(this); /* Setup Queue */ - mPostedQueue = new TokenQueueVEG(rsPostedVEG, this); + mPostedQueue = new TokenQueue(rsPosted->getTokenService(), this); connect( ui.groupTreeWidget, SIGNAL( treeCustomContextMenuRequested( QPoint ) ), this, SLOT( groupListCustomPopupMenu( QPoint ) ) ); @@ -144,12 +143,6 @@ void PostedListDialog::groupListCustomPopupMenu( QPoint /*point*/ ) action = contextMnu.addAction(QIcon(":/images/message-mail.png"), tr("Mark all as unread"), this, SLOT(markMsgAsUnreadAll())); //action->setEnabled (!mCurrTopicId.empty () && IS_FORUM_SUBSCRIBED(subscribeFlags)); -#ifdef DEBUG_FORUMS - contextMnu.addSeparator(); - action = contextMnu.addAction("Generate mass data", this, SLOT(generateMassData())); - action->setEnabled (!mCurrTopicId.empty() && IS_FORUM_SUBSCRIBED(subscribeFlags)); -#endif - contextMnu.exec(QCursor::pos()); } @@ -157,12 +150,12 @@ void PostedListDialog::updateDisplay() { std::list groupIds; std::list::iterator it; - if (!rsPostedVEG) + if (!rsPosted) return; // TODO groupsChanged... HACK XXX. #if 0 - if ((rsPostedVEG->groupsChanged(groupIds)) || (rsPostedVEG->updated())) + if ((rsPosted->groupsChanged(groupIds)) || (rsPosted->updated())) { /* update Forums List */ insertGroups(); @@ -176,7 +169,7 @@ void PostedListDialog::updateDisplay() } #endif - if (rsPostedVEG->updated()) + if (rsPosted->updated()) { /* update Forums List */ insertGroups(); @@ -244,8 +237,6 @@ void PostedListDialog::sortButtonClicked( QAbstractButton *button ) } else if (button == ui.topSortButton) { sortMode = RSPOSTED_VIEWMODE_TOP; } - - rsPostedVEG->setViewMode(sortMode); } @@ -275,7 +266,6 @@ void PostedListDialog::periodChanged( int index ) periodMode = RSPOSTED_PERIOD_YEAR; break; } - rsPostedVEG->setViewPeriod(periodMode); } @@ -342,7 +332,7 @@ void PostedListDialog::requestGroupSummary() std::cerr << std::endl; std::list ids; - RsTokReqOptionsVEG opts; + RsTokReqOptions opts; uint32_t token; mPostedQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, ids, POSTEDDIALOG_LISTING); } @@ -353,7 +343,7 @@ void PostedListDialog::loadGroupSummary(const uint32_t &token) std::cerr << std::endl; std::list groupInfo; - rsPostedVEG->getGroupSummary(token, groupInfo); + rsPosted->getGroupSummary(token, groupInfo); if (groupInfo.size() > 0) { @@ -373,7 +363,7 @@ void PostedListDialog::loadGroupSummary(const uint32_t &token) void PostedListDialog::requestGroupSummary_CurrentForum(const std::string &forumId) { - RsTokReqOptionsVEG opts; + RsTokReqOptions opts; std::list grpIds; grpIds.push_back(forumId); @@ -391,7 +381,7 @@ void PostedListDialog::loadGroupSummary_CurrentForum(const uint32_t &token) std::cerr << std::endl; std::list groupInfo; - rsPostedVEG->getGroupSummary(token, groupInfo); + rsPosted->getGroupSummary(token, groupInfo); if (groupInfo.size() == 1) { @@ -452,7 +442,7 @@ void PostedListDialog::loadCurrentForumThreads(const std::string &forumId) void PostedListDialog::requestGroupThreadData_InsertThreads(const std::string &groupId) { - RsTokReqOptionsVEG opts; + RsTokReqOptions opts; opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; @@ -466,7 +456,7 @@ void PostedListDialog::requestGroupThreadData_InsertThreads(const std::string &g //mPostedQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, POSTEDDIALOG_INSERTTHREADS); // Do specific Posted Request.... - if (rsPostedVEG->requestRanking(token, groupId)) + if (rsPosted->requestRanking(token, groupId)) { // get the Queue to handle response. mPostedQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_DATA, POSTEDDIALOG_INSERTTHREADS); @@ -484,9 +474,9 @@ void PostedListDialog::loadGroupThreadData_InsertThreads(const uint32_t &token) { RsPostedPost post; // Old Format. - //if (rsPostedVEG->getPost(token, post)) + //if () - if (rsPostedVEG->getRankedPost(token, post)) + if (/*rsPosted->getPost(token, post)*/false) { std::cerr << "PostedListDialog::loadGroupThreadData_InsertThreads() MsgId: " << post.mMeta.mMsgId; std::cerr << std::endl; @@ -559,7 +549,7 @@ void PostedListDialog::clearPosts() /*********************** **** **** **** ***********************/ /*********************** **** **** **** ***********************/ -void PostedListDialog::loadRequest(const TokenQueueVEG *queue, const TokenRequestVEG &req) +void PostedListDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) { std::cerr << "PostedListDialog::loadRequest() UserType: " << req.mUserType; std::cerr << std::endl; @@ -600,78 +590,11 @@ void PostedListDialog::loadRequest(const TokenQueueVEG *queue, const TokenReques void PostedListDialog::groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo &groupItemInfo) { - groupItemInfo.id = QString::fromStdString(groupInfo.mGroupId); - groupItemInfo.name = QString::fromUtf8(groupInfo.mGroupName.c_str()); - //groupItemInfo.description = QString::fromUtf8(groupInfo.forumDesc); - groupItemInfo.popularity = groupInfo.mPop; - groupItemInfo.lastpost = QDateTime::fromTime_t(groupInfo.mLastPost); - - if (groupInfo.mGroupFlags & RS_DISTRIB_AUTHEN_REQ) { - groupItemInfo.name += " (" + tr("AUTHD") + ")"; - groupItemInfo.icon = QIcon(IMAGE_FORUMAUTHD); - } else { - groupItemInfo.icon = QIcon(IMAGE_FORUM); - } } void PostedListDialog::insertGroupData(const std::list &groupList) { - std::list::const_iterator it; - QList adminList; - QList subList; - QList popList; - QList otherList; - std::multimap popMap; - - for (it = groupList.begin(); it != groupList.end(); it++) { - /* sort it into Publish (Own), Subscribed, Popular and Other */ - uint32_t flags = it->mSubscribeFlags; - - GroupItemInfo groupItemInfo; - groupInfoToGroupItemInfo(*it, groupItemInfo); - - if (flags & RSGXS_GROUP_SUBSCRIBE_ADMIN) { - adminList.push_back(groupItemInfo); - } else if (flags & RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED) { - /* subscribed forum */ - subList.push_back(groupItemInfo); - } else { - /* rate the others by popularity */ - popMap.insert(std::make_pair(it->mPop, groupItemInfo)); - } - } - - /* iterate backwards through popMap - take the top 5 or 10% of list */ - uint32_t popCount = 5; - if (popCount < popMap.size() / 10) - { - popCount = popMap.size() / 10; - } - - uint32_t i = 0; - uint32_t popLimit = 0; - std::multimap::reverse_iterator rit; - for(rit = popMap.rbegin(); ((rit != popMap.rend()) && (i < popCount)); rit++, i++) ; - if (rit != popMap.rend()) { - popLimit = rit->first; - } - - for (rit = popMap.rbegin(); rit != popMap.rend(); rit++) { - if (rit->second.popularity < (int) popLimit) { - otherList.append(rit->second); - } else { - popList.append(rit->second); - } - } - - /* now we can add them in as a tree! */ - ui.groupTreeWidget->fillGroupItems(yourTopics, adminList); - ui.groupTreeWidget->fillGroupItems(subscribedTopics, subList); - ui.groupTreeWidget->fillGroupItems(popularTopics, popList); - ui.groupTreeWidget->fillGroupItems(otherTopics, otherList); - - // updateMessageSummaryList(""); } /**************************************************************************************/ diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.h b/retroshare-gui/src/gui/Posted/PostedListDialog.h index ab8b6183e..104ca6e20 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.h @@ -27,18 +27,18 @@ #include "retroshare-gui/mainpage.h" #include "ui_PostedListDialog.h" -#include +#include #include #include "gui/Posted/PostedItem.h" #include "gui/common/GroupTreeWidget.h" -#include "util/TokenQueueVEG.h" +#include "util/TokenQueue.h" #include "retroshare-gui/RsAutoUpdatePage.h" -class PostedListDialog : public RsAutoUpdatePage, public PostedHolder, public TokenResponseVEG +class PostedListDialog : public RsAutoUpdatePage, public PostedHolder, public TokenResponse { Q_OBJECT @@ -90,7 +90,7 @@ void loadGroupThreadData_InsertThreads(const uint32_t &token); void insertGroupData(const std::list &groupList); void groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo &groupItemInfo); - void loadRequest(const TokenQueueVEG *queue, const TokenRequestVEG &req); + void loadRequest(const TokenQueue *queue, const TokenRequest &req); QTreeWidgetItem *yourTopics; @@ -103,7 +103,7 @@ void groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo & bool mThreadLoading; std::string mCurrTopicId; - TokenQueueVEG *mPostedQueue; + TokenQueue *mPostedQueue; /* UI - from Designer */ Ui::PostedListDialog ui; diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp index 792af91d9..88248879c 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp @@ -36,7 +36,7 @@ #define GXSCOMMENTS_LOADTHREAD 1 // Temporarily make this specific. -#include "retroshare/rspostedVEG.h" +#include "retroshare/rsposted.h" GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent) @@ -46,10 +46,10 @@ GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent) return; } -void GxsCommentTreeWidget::setup(RsTokenServiceVEG *service) +void GxsCommentTreeWidget::setup(RsTokenService *service) { mRsService = service; - mTokenQueue = new TokenQueueVEG(service, this); + mTokenQueue = new TokenQueue(service, this); return; } @@ -72,11 +72,11 @@ void GxsCommentTreeWidget::service_requestComments(std::string threadId) std::cerr << "GxsCommentTreeWidget::service_requestComments(" << threadId << ")"; std::cerr << std::endl; - RsTokReqOptionsVEG opts; + RsTokReqOptions opts; opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; - opts.mFlagsFilter = RSPOSTED_MSGTYPE_COMMENT; - opts.mFlagsMask = RSPOSTED_MSGTYPE_COMMENT; +// opts.mFlagsFilter = RSPOSTED_MSGTYPE_COMMENT; +// opts.mFlagsMask = RSPOSTED_MSGTYPE_COMMENT; std::list msgIds; msgIds.push_back(threadId); @@ -84,7 +84,7 @@ void GxsCommentTreeWidget::service_requestComments(std::string threadId) mThreadId = threadId; uint32_t token; - mTokenQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, GXSCOMMENTS_LOADTHREAD); +// mTokenQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, GXSCOMMENTS_LOADTHREAD); } @@ -211,49 +211,49 @@ void GxsCommentTreeWidget::service_loadThread(const uint32_t &token) std::cerr << "GxsCommentTreeWidget::service_loadThread() ERROR must be overloaded!"; std::cerr << std::endl; - RsPostedComment comment; - while(rsPostedVEG->getComment(token, comment)) - { - /* convert to a QTreeWidgetItem */ - std::cerr << "GxsCommentTreeWidget::service_loadThread() Got Comment: " << comment; - std::cerr << std::endl; +// RsPostedComment comment; +// while(rsPosted->getComment(token, comment)) +// { +// /* convert to a QTreeWidgetItem */ +// std::cerr << "GxsCommentTreeWidget::service_loadThread() Got Comment: " << comment; +// std::cerr << std::endl; - QTreeWidgetItem *item = new QTreeWidgetItem(); - QString text; +// QTreeWidgetItem *item = new QTreeWidgetItem(); +// QString text; - { - QDateTime qtime; - qtime.setTime_t(comment.mMeta.mPublishTs); +// { +// QDateTime qtime; +// qtime.setTime_t(comment.mMeta.mPublishTs); - text = qtime.toString("yyyy-MM-dd hh:mm:ss"); - item->setText(PCITEM_COLUMN_DATE, text); - } +// text = qtime.toString("yyyy-MM-dd hh:mm:ss"); +// item->setText(PCITEM_COLUMN_DATE, text); +// } - text = QString::fromUtf8(comment.mComment.c_str()); - item->setText(PCITEM_COLUMN_COMMENT, text); +// text = QString::fromUtf8(comment.mComment.c_str()); +// item->setText(PCITEM_COLUMN_COMMENT, text); - text = QString::fromUtf8(comment.mMeta.mAuthorId.c_str()); - if (text.isEmpty()) - { - item->setText(PCITEM_COLUMN_AUTHOR, tr("Anonymous")); - } - else - { - item->setText(PCITEM_COLUMN_AUTHOR, text); - } +// text = QString::fromUtf8(comment.mMeta.mAuthorId.c_str()); +// if (text.isEmpty()) +// { +// item->setText(PCITEM_COLUMN_AUTHOR, tr("Anonymous")); +// } +// else +// { +// item->setText(PCITEM_COLUMN_AUTHOR, text); +// } - text = QString::fromUtf8(comment.mMeta.mMsgId.c_str()); - item->setText(PCITEM_COLUMN_MSGID, text); +// text = QString::fromUtf8(comment.mMeta.mMsgId.c_str()); +// item->setText(PCITEM_COLUMN_MSGID, text); - text = QString::fromUtf8(comment.mMeta.mParentId.c_str()); - item->setText(PCITEM_COLUMN_PARENTID, text); +// text = QString::fromUtf8(comment.mMeta.mParentId.c_str()); +// item->setText(PCITEM_COLUMN_PARENTID, text); - text = QString::fromUtf8(comment.mMeta.mServiceString.c_str()); - item->setText(PCITEM_COLUMN_SERVSTRING, text); +// text = QString::fromUtf8(comment.mMeta.mServiceString.c_str()); +// item->setText(PCITEM_COLUMN_SERVSTRING, text); - addItem(comment.mMeta.mMsgId, comment.mMeta.mParentId, item); - } +// addItem(comment.mMeta.mMsgId, comment.mMeta.mParentId, item); +// } return; } @@ -286,7 +286,7 @@ QTreeWidgetItem *GxsCommentTreeWidget::service_createMissingItem(std::string par } -void GxsCommentTreeWidget::loadRequest(const TokenQueueVEG *queue, const TokenRequestVEG &req) +void GxsCommentTreeWidget::loadRequest(const TokenQueue *queue, const TokenRequest &req) { std::cerr << "GxsCommentTreeWidget::loadRequest() UserType: " << req.mUserType; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h index 76b49b4e8..87859d8ba 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h @@ -24,7 +24,7 @@ #include -#include "util/TokenQueueVEG.h" +#include "util/TokenQueue.h" /* indicies for search results item columns SR_ = Search Result */ #define SR_NAME_COL 0 @@ -39,17 +39,17 @@ #define SR_ROLE_LOCAL Qt::UserRole -class GxsCommentTreeWidget : public QTreeWidget, public TokenResponseVEG +class GxsCommentTreeWidget : public QTreeWidget, public TokenResponse { Q_OBJECT public: GxsCommentTreeWidget(QWidget *parent = 0); - void setup(RsTokenServiceVEG *service); + void setup(RsTokenService *service); void requestComments(std::string threadId); - void loadRequest(const TokenQueueVEG *queue, const TokenRequestVEG &req); + void loadRequest(const TokenQueue *queue, const TokenRequest &req); protected: @@ -73,8 +73,8 @@ protected: std::map mLoadingMap; std::multimap mPendingInsertMap; - TokenQueueVEG *mTokenQueue; - RsTokenServiceVEG *mRsService; + TokenQueue *mTokenQueue; + RsTokenService *mRsService; protected: //virtual QMimeData * mimeData ( const QList items ) const; diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index ed1ef9659..230e6f5eb 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -24,6 +24,7 @@ #include "util/misc.h" #include "GxsGroupDialog.h" #include "gui/common/PeerDefs.h" +#include "gxs/rsgxsflags.h" #include @@ -31,17 +32,31 @@ #include +// Control of Publish Signatures. +#define RSGXS_GROUP_SIGN_PUBLISH_MASK 0x000000ff +#define RSGXS_GROUP_SIGN_PUBLISH_ENCRYPTED 0x00000001 +#define RSGXS_GROUP_SIGN_PUBLISH_ALLSIGNED 0x00000002 +#define RSGXS_GROUP_SIGN_PUBLISH_THREADHEAD 0x00000004 +#define RSGXS_GROUP_SIGN_PUBLISH_NONEREQ 0x00000008 + +// Author Signature. +#define RSGXS_GROUP_SIGN_AUTHOR_MASK 0x0000ff00 +#define RSGXS_GROUP_SIGN_AUTHOR_GPG 0x00000100 +#define RSGXS_GROUP_SIGN_AUTHOR_REQUIRED 0x00000200 +#define RSGXS_GROUP_SIGN_AUTHOR_IFNOPUBSIGN 0x00000400 +#define RSGXS_GROUP_SIGN_AUTHOR_NONE 0x00000800 + #define GXSGROUP_NEWGROUPID 1 #define GXSGROUP_LOADGROUP 2 /** Constructor */ -GxsGroupDialog::GxsGroupDialog(RsTokenServiceVEG *service, QWidget *parent) +GxsGroupDialog::GxsGroupDialog(RsTokenService *service, QWidget *parent) : QDialog(parent), mRsService(service) { /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); - mTokenQueue = new TokenQueueVEG(service, this); + mTokenQueue = new TokenQueue(service, this); // connect up the buttons. connect( ui.cancelButton, SIGNAL( clicked ( bool ) ), this, SLOT( cancelDialog( ) ) ); @@ -289,7 +304,7 @@ void GxsGroupDialog::existingGroup(std::string groupId, uint32_t mode) /* request data */ { - RsTokReqOptionsVEG opts; + RsTokReqOptions opts; std::list grpIds; grpIds.push_back(groupId); @@ -391,7 +406,7 @@ void GxsGroupDialog::createGroup() meta.mSignFlags = getGroupSignFlags(); // These ones shouldn't be needed here - but will be used, until we have fully functional backend. - meta.mSubscribeFlags = RSGXS_GROUP_SUBSCRIBE_ADMIN; + meta.mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; meta.mPublishTs = time(NULL); if (service_CreateGroup(token, meta)) @@ -528,19 +543,7 @@ void GxsGroupDialog::addGroupLogo() void GxsGroupDialog::sendShareList(std::string groupId) { - if (!mRsService) - { - std::cerr << "GxsGroupDialog::sendShareList() GXS Service not active"; - std::cerr << std::endl; - return; - } - - if (ui.pubKeyShare_cb->isChecked()) - { - std::list shareList; - ui.keyShareList->selectedSslIds(shareList, false); - mRsService->groupShareKeys(groupId, shareList); - } + close(); } @@ -566,7 +569,6 @@ void GxsGroupDialog::loadNewGroupId(const uint32_t &token) std::cerr << std::endl; std::list groupInfo; - mRsService->getGroupSummary(token, groupInfo); if (groupInfo.size() == 1) { @@ -605,7 +607,7 @@ void GxsGroupDialog::service_loadExistingGroup(const uint32_t &token) } -void GxsGroupDialog::loadRequest(const TokenQueueVEG *queue, const TokenRequestVEG &req) +void GxsGroupDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) { std::cerr << "GxsGroupDialog::loadRequest() UserType: " << req.mUserType; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h index 27e8162e5..746429358 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h @@ -25,7 +25,7 @@ #include "ui_GxsGroupDialog.h" -#include "util/TokenQueueVEG.h" +#include "util/TokenQueue.h" /******** @@ -90,12 +90,12 @@ public: #define GXS_GROUP_DIALOG_SHOW_MODE 2 #define GXS_GROUP_DIALOG_EDIT_MODE 3 -class GxsGroupDialog : public QDialog, public TokenResponseVEG +class GxsGroupDialog : public QDialog, public TokenResponse { Q_OBJECT public: - GxsGroupDialog(RsTokenServiceVEG *service, QWidget *parent = 0); + GxsGroupDialog(RsTokenService *service, QWidget *parent = 0); void setFlags(uint32_t enabledFlags, uint32_t readonlyFlags, uint32_t defaultFlags); void setMode(uint32_t mode); @@ -105,7 +105,7 @@ public: void existingGroup(std::string groupId, uint32_t mode); // Callback for all Loads. -virtual void loadRequest(const TokenQueueVEG *queue, const TokenRequestVEG &req); +virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); // Functions that can be overloaded for specific stuff. @@ -159,8 +159,8 @@ private: QPixmap picture; - RsTokenServiceVEG *mRsService; - TokenQueueVEG *mTokenQueue; + RsTokenService *mRsService; + TokenQueue *mTokenQueue; uint32_t mMode; diff --git a/retroshare-gui/src/gui/gxs/PostedGroupDialog.cpp b/retroshare-gui/src/gui/gxs/PostedGroupDialog.cpp index 7605c60da..e7600a997 100644 --- a/retroshare-gui/src/gui/gxs/PostedGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/PostedGroupDialog.cpp @@ -21,11 +21,11 @@ #include "PostedGroupDialog.h" -#include +#include #include PostedGroupDialog::PostedGroupDialog(QWidget *parent) - :GxsGroupDialog(rsPostedVEG, parent) + :GxsGroupDialog(rsPosted->getTokenService(), parent) { // To start with we only have open forums - with distribution controls. @@ -70,7 +70,7 @@ bool PostedGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaDa grp.mMeta = meta; //grp.mDescription = std::string(desc.toUtf8()); - rsPostedVEG->submitGroup(token, grp, true); + rsPosted->submitGroup(token, grp); return true; } @@ -80,7 +80,7 @@ void PostedGroupDialog::service_loadExistingGroup(const uint32_t &token) std::cerr << std::endl; RsPostedGroup group; - if (!rsPostedVEG->getGroup(token, group)) + if (!rsPosted->getGroup(token, group)) { std::cerr << "PostedGroupDialog::service_loadExistingGroup() ERROR Getting Group"; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp index 903068a7d..749f9c93e 100644 --- a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp +++ b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp @@ -86,10 +86,6 @@ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) //ui.stackPages->add(statisticDialog = new StatisticDialog(ui.stackPages), // createPageAction(QIcon(IMAGE_STATISTIC), tr("Statistics"), grp)); - //PhotoDialog *photoDialog = NULL; - //ui.stackPages->add(photoDialog = new PhotoDialog(ui.stackPages), - // createPageAction(QIcon(IMAGE_PHOTO), tr("Photo View"), grp)); - //GamesDialog *gamesDialog = NULL; //ui.stackPages->add(gamesDialog = new GamesDialog(ui.stackPages), // createPageAction(QIcon(IMAGE_GAMES), tr("Games Launcher"), grp)); diff --git a/retroshare-gui/src/util/TokenQueueV2.cpp b/retroshare-gui/src/util/TokenQueue.cpp similarity index 71% rename from retroshare-gui/src/util/TokenQueueV2.cpp rename to retroshare-gui/src/util/TokenQueue.cpp index 29b650f1c..75031dea1 100644 --- a/retroshare-gui/src/util/TokenQueueV2.cpp +++ b/retroshare-gui/src/util/TokenQueue.cpp @@ -21,7 +21,7 @@ * */ -#include "util/TokenQueueV2.h" +#include "util/TokenQueue.h" #include #include @@ -32,13 +32,13 @@ *****/ /** Constructor */ -TokenQueueV2::TokenQueueV2(RsTokenService *service, TokenResponseV2 *resp) +TokenQueue::TokenQueue(RsTokenService *service, TokenResponse *resp) :QWidget(NULL), mService(service), mResponder(resp) { return; } -bool TokenQueueV2::requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, std::list& ids, uint32_t usertype) +bool TokenQueue::requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, std::list& ids, uint32_t usertype) { uint32_t basictype = TOKENREQ_GROUPINFO; mService->requestGroupInfo(token, anstype, opts, ids); @@ -48,7 +48,7 @@ bool TokenQueueV2::requestGroupInfo(uint32_t &token, uint32_t anstype, const RsT } -bool TokenQueueV2::requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, uint32_t usertype) +bool TokenQueue::requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, uint32_t usertype) { uint32_t basictype = TOKENREQ_GROUPINFO; mService->requestGroupInfo(token, anstype, opts); @@ -57,7 +57,7 @@ bool TokenQueueV2::requestGroupInfo(uint32_t &token, uint32_t anstype, const RsT return true; } -bool TokenQueueV2::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, const GxsMsgReq& ids, uint32_t usertype) +bool TokenQueue::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, const GxsMsgReq& ids, uint32_t usertype) { uint32_t basictype = TOKENREQ_MSGINFO; mService->requestMsgInfo(token, anstype, opts, ids); @@ -67,7 +67,7 @@ bool TokenQueueV2::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTok } -bool TokenQueueV2::requestMsgRelatedInfo(uint32_t &token, const RsTokReqOptionsV2 &opts, const RsGxsGrpMsgIdPair &msgId, uint32_t usertype) +bool TokenQueue::requestMsgRelatedInfo(uint32_t &token, const RsTokReqOptions &opts, const RsGxsGrpMsgIdPair &msgId, uint32_t usertype) { uint32_t basictype = TOKENREQ_MSGINFO; uint32_t anstype = RS_TOKREQ_ANSTYPE_LIST; // always a list answer @@ -78,7 +78,7 @@ bool TokenQueueV2::requestMsgRelatedInfo(uint32_t &token, const RsTokReqOptionsV } -bool TokenQueueV2::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, +bool TokenQueue::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, const std::list &grpIds, uint32_t usertype) { uint32_t basictype = TOKENREQ_MSGINFO; @@ -89,13 +89,13 @@ bool TokenQueueV2::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTok } -void TokenQueueV2::queueRequest(uint32_t token, uint32_t basictype, uint32_t anstype, uint32_t usertype) +void TokenQueue::queueRequest(uint32_t token, uint32_t basictype, uint32_t anstype, uint32_t usertype) { - std::cerr << "TokenQueueV2::queueRequest() Token: " << token << " Type: " << basictype; + std::cerr << "TokenQueue::queueRequest() Token: " << token << " Type: " << basictype; std::cerr << " AnsType: " << anstype << " UserType: " << usertype; std::cerr << std::endl; - TokenRequestV2 req; + TokenRequest req; req.mToken = token; req.mType = basictype; req.mAnsType = anstype; @@ -113,7 +113,7 @@ void TokenQueueV2::queueRequest(uint32_t token, uint32_t basictype, uint32_t ans } } -void TokenQueueV2::doPoll(float dt) +void TokenQueue::doPoll(float dt) { /* single shot poll */ //mTrigger->singlesshot(dt * 1000); @@ -121,11 +121,11 @@ void TokenQueueV2::doPoll(float dt) } -void TokenQueueV2::pollRequests() +void TokenQueue::pollRequests() { double pollPeriod = 1.0; // max poll period. - TokenRequestV2 req; + TokenRequest req; if(mRequests.size() > 0){ req = mRequests.front(); @@ -148,7 +148,7 @@ void TokenQueueV2::pollRequests() } -bool TokenQueueV2::checkForRequest(uint32_t token) +bool TokenQueue::checkForRequest(uint32_t token) { /* check token */ uint32_t status = mService->requestStatus(token); @@ -157,9 +157,9 @@ bool TokenQueueV2::checkForRequest(uint32_t token) } -void TokenQueueV2::loadRequest(const TokenRequestV2 &req) +void TokenQueue::loadRequest(const TokenRequest &req) { - std::cerr << "TokenQueueV2::loadRequest(): "; + std::cerr << "TokenQueue::loadRequest(): "; std::cerr << "Token: " << req.mToken << " Type: " << req.mType; std::cerr << " AnsType: " << req.mAnsType << " UserType: " << req.mUserType; std::cerr << std::endl; @@ -170,12 +170,12 @@ void TokenQueueV2::loadRequest(const TokenRequestV2 &req) } -bool TokenQueueV2::cancelRequest(const uint32_t token) +bool TokenQueue::cancelRequest(const uint32_t token) { /* cancel at lower level first */ mService->cancelRequest(token); - std::list::iterator it; + std::list::iterator it; for(it = mRequests.begin(); it != mRequests.end(); it++) { @@ -183,14 +183,14 @@ bool TokenQueueV2::cancelRequest(const uint32_t token) { mRequests.erase(it); - std::cerr << "TokenQueueV2::cancelRequest() Cleared Request: " << token; + std::cerr << "TokenQueue::cancelRequest() Cleared Request: " << token; std::cerr << std::endl; return true; } } - std::cerr << "TokenQueueV2::cancelRequest() Failed to Find Request: " << token; + std::cerr << "TokenQueue::cancelRequest() Failed to Find Request: " << token; std::cerr << std::endl; return false; diff --git a/retroshare-gui/src/util/TokenQueueV2.h b/retroshare-gui/src/util/TokenQueue.h similarity index 78% rename from retroshare-gui/src/util/TokenQueueV2.h rename to retroshare-gui/src/util/TokenQueue.h index 65418d0b6..417266e06 100644 --- a/retroshare-gui/src/util/TokenQueueV2.h +++ b/retroshare-gui/src/util/TokenQueue.h @@ -41,9 +41,9 @@ #define TOKENREQ_MSGRELATEDINFO 3 -class TokenQueueV2; +class TokenQueue; -class TokenRequestV2 +class TokenRequest { public: uint32_t mToken; @@ -54,12 +54,12 @@ class TokenRequestV2 struct timeval mPollTs; }; -class TokenResponseV2 +class TokenResponse { public: //virtual ~TokenResponse() { return; } // These Functions are overloaded to get results out. - virtual void loadRequest(const TokenQueueV2 *queue, const TokenRequestV2 &req) = 0; + virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req) = 0; }; @@ -67,12 +67,12 @@ class TokenResponseV2 * An important thing to note is that all requests are stacked (so FIFO) * This is to prevent overlapped loads on GXS UIs */ -class TokenQueueV2: public QWidget +class TokenQueue: public QWidget { Q_OBJECT public: - TokenQueueV2(RsTokenService *service, TokenResponseV2 *resp); + TokenQueue(RsTokenService *service, TokenResponse *resp); /* generic handling of token / response update behaviour */ @@ -81,25 +81,25 @@ public: * @token the token to be redeem is assigned here * */ - bool requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, + bool requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, std::list& ids, uint32_t usertype); - bool requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, uint32_t usertype); + bool requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, uint32_t usertype); - bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, + bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, const std::list& grpIds, uint32_t usertype); - bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptionsV2 &opts, + bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, const GxsMsgReq& grpIds, uint32_t usertype); - bool requestMsgRelatedInfo(uint32_t &token, const RsTokReqOptionsV2 &opts, const RsGxsGrpMsgIdPair& msgId, uint32_t usertype); + bool requestMsgRelatedInfo(uint32_t &token, const RsTokReqOptions &opts, const RsGxsGrpMsgIdPair& msgId, uint32_t usertype); bool cancelRequest(const uint32_t token); void queueRequest(uint32_t token, uint32_t basictype, uint32_t anstype, uint32_t usertype); bool checkForRequest(uint32_t token); - void loadRequest(const TokenRequestV2 &req); + void loadRequest(const TokenRequest &req); protected: void doPoll(float dt); @@ -109,10 +109,10 @@ private slots: private: /* Info for Data Requests */ - std::list mRequests; + std::list mRequests; RsTokenService *mService; - TokenResponseV2 *mResponder; + TokenResponse *mResponder; QTimer *mTrigger; }; From 3d4869e226d5d4273d3f1a72b0dd5bd19d4789db Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 21 Oct 2012 19:59:53 +0000 Subject: [PATCH 098/222] forgot to commit this file last time git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5708 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/retroshare-nogui.pro | 32 ++++++++++++----------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/retroshare-nogui/src/retroshare-nogui.pro b/retroshare-nogui/src/retroshare-nogui.pro index 5767a735a..21efc2a79 100644 --- a/retroshare-nogui/src/retroshare-nogui.pro +++ b/retroshare-nogui/src/retroshare-nogui.pro @@ -133,6 +133,8 @@ introserver { sshserver { + LIBSSH_DIR = ../../libssh-0.5.2 + # This Requires libssh-0.5.* to compile. # Modify path below to point at it. # Probably will only work on Linux for the moment. @@ -149,9 +151,9 @@ sshserver { # ./retroshare-nogui -h provides some more instructions. # - INCLUDEPATH += ../../../lib/libssh-0.5.2/include/ - LIBS += ../../../lib/libssh-0.5.2/build/src/libssh.a - LIBS += ../../../lib/libssh-0.5.2/build/src/threads/libssh_threads.a + INCLUDEPATH += $$LIBSSH_DIR/include/ + LIBS += $$LIBSSH_DIR/build/src/libssh.a + LIBS += $$LIBSSH_DIR/build/src/threads/libssh_threads.a #LIBS += -lssh #LIBS += -lssh_threads HEADERS += ssh/rssshd.h @@ -204,19 +206,19 @@ protorpc { rpc/proto/rpcprotofiles.cc \ # Generated ProtoBuf Code the RPC System - HEADERS += rpc/proto/gencc/core.pb.h \ - rpc/proto/gencc/peers.pb.h \ - rpc/proto/gencc/system.pb.h \ - rpc/proto/gencc/chat.pb.h \ - rpc/proto/gencc/search.pb.h \ - rpc/proto/gencc/files.pb.h \ + HEADERS += ../../rsctrl/src/gencc/core.pb.h \ + ../../rsctrl/src/gencc/peers.pb.h \ + ../../rsctrl/src/gencc/system.pb.h \ + ../../rsctrl/src/gencc/chat.pb.h \ + ../../rsctrl/src/gencc/search.pb.h \ + ../../rsctrl/src/gencc/files.pb.h \ - SOURCES += rpc/proto/gencc/core.pb.cc \ - rpc/proto/gencc/peers.pb.cc \ - rpc/proto/gencc/system.pb.cc \ - rpc/proto/gencc/chat.pb.cc \ - rpc/proto/gencc/search.pb.cc \ - rpc/proto/gencc/files.pb.cc \ + SOURCES += ../../rsctrl/src/gencc/core.pb.cc \ + ../../rsctrl/src/gencc/peers.pb.cc \ + ../../rsctrl/src/gencc/system.pb.cc \ + ../../rsctrl/src/gencc/chat.pb.cc \ + ../../rsctrl/src/gencc/search.pb.cc \ + ../../rsctrl/src/gencc/files.pb.cc \ QMAKE_CFLAGS += -pthread QMAKE_CXXFLAGS += -pthread From e92ef1a1be15a1f01ded2679b294f61d713ca6d3 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Mon, 22 Oct 2012 13:48:57 +0000 Subject: [PATCH 099/222] Fixed compile error on Windows. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5710 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/menu/stdiocomms.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/retroshare-nogui/src/menu/stdiocomms.cc b/retroshare-nogui/src/menu/stdiocomms.cc index 99d982616..132b8e89d 100644 --- a/retroshare-nogui/src/menu/stdiocomms.cc +++ b/retroshare-nogui/src/menu/stdiocomms.cc @@ -33,6 +33,8 @@ StdioComms::StdioComms(int infd, int outfd) :mIn(infd), mOut(outfd) { +// fcntl not available on Windows, search alternative when needed +#ifndef WINDOWS_SYS #if 1 // THIS Code is strange... // It seems to mess up stderr. @@ -57,6 +59,7 @@ StdioComms::StdioComms(int infd, int outfd) std::cerr << "StdioComms() STDERR msg 1"; std::cerr << std::endl; #endif +#endif // WINDOWS_SYS } From 6c784c306244b7c070105b22168a4d23d142f432 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Mon, 22 Oct 2012 13:51:40 +0000 Subject: [PATCH 100/222] Cleaned ApplicationWindow (unfinished modules). git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5711 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/gui/unfinished/ApplicationWindow.cpp | 104 +- .../src/gui/unfinished/ApplicationWindow.h | 57 +- .../src/gui/unfinished/ApplicationWindow.ui | 1043 +---------------- 3 files changed, 40 insertions(+), 1164 deletions(-) diff --git a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp index 749f9c93e..8011e80e1 100644 --- a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp +++ b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp @@ -19,13 +19,7 @@ * Boston, MA 02110-1301, USA. ****************************************************************/ -#include -#include -#include -#include -#include -#include -#include +#include #include #include "ApplicationWindow.h" @@ -49,8 +43,6 @@ //#include "PhotoDialog.h" //#include "StatisticDialog.h" -#define FONT QFont("Arial", 9) - /* Images for toolbar icons */ #define IMAGE_RETROSHARE ":/images/RetroShare16.png" #define IMAGE_ABOUT ":/images/informations_24x24.png" @@ -77,7 +69,6 @@ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) // Setting icons this->setWindowIcon(QIcon(QString::fromUtf8(":/images/rstray3.png"))); - loadStyleSheet("Default"); /* Create the config pages and actions */ QActionGroup *grp = new QActionGroup(this); @@ -125,21 +116,23 @@ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) #endif - /* Create the toolbar */ ui.toolBar->addActions(grp->actions()); ui.toolBar->addSeparator(); connect(grp, SIGNAL(triggered(QAction *)), ui.stackPages, SLOT(showPage(QAction *))); - + ui.stackPages->setCurrentIndex(0); } /** Creates a new action associated with a config page. */ QAction* ApplicationWindow::createPageAction(QIcon img, QString text, QActionGroup *group) { + QFont font; QAction *action = new QAction(img, text, group); + font = action->font(); + font.setPointSize(9); action->setCheckable(true); - action->setFont(FONT); + action->setFont(font); return action; } @@ -147,36 +140,13 @@ QAction* ApplicationWindow::createPageAction(QIcon img, QString text, QActionGro * the specified slot (if given). */ void ApplicationWindow::addAction(QAction *action, const char *slot) { - action->setFont(FONT); + QFont font = action->font(); + font.setPointSize(9); + action->setFont(font); ui.toolBar->addAction(action); connect(action, SIGNAL(triggered()), this, slot); } -/** Overloads the default show so we can load settings */ -void ApplicationWindow::show() -{ - - if (!this->isVisible()) { - QMainWindow::show(); - } else { - QMainWindow::activateWindow(); - setWindowState(windowState() & (~Qt::WindowMinimized | Qt::WindowActive)); - QMainWindow::raise(); - } -} - - -/** Shows the config dialog with focus set to the given page. */ -void ApplicationWindow::show(Page page) -{ - /* Show the dialog. */ - show(); - - /* Set the focus to the specified page. */ - ui.stackPages->setCurrentIndex((int)page); -} - - /** Destructor. */ ApplicationWindow::~ApplicationWindow() { @@ -184,12 +154,6 @@ ApplicationWindow::~ApplicationWindow() // delete exampleDialog; } -/** Create and bind actions to events. Setup for initial - * tray menu configuration. */ -void ApplicationWindow::createActions() -{ -} - void ApplicationWindow::closeEvent(QCloseEvent *e) { //Settings->saveWidgetInformation(this); @@ -197,53 +161,3 @@ void ApplicationWindow::closeEvent(QCloseEvent *e) hide(); e->ignore(); } - - -void ApplicationWindow::updateMenu() -{ - toggleVisibilityAction->setText(isVisible() ? tr("Hide") : tr("Show")); -} - -void ApplicationWindow::toggleVisibility(QSystemTrayIcon::ActivationReason e) -{ - if(e == QSystemTrayIcon::Trigger || e == QSystemTrayIcon::DoubleClick){ - if(isHidden()){ - show(); - if(isMinimized()){ - if(isMaximized()){ - showMaximized(); - }else{ - showNormal(); - } - } - raise(); - activateWindow(); - }else{ - hide(); - } - } -} - -void ApplicationWindow::toggleVisibilitycontextmenu() -{ - if (isVisible()) - hide(); - else - show(); -} - - - -void ApplicationWindow::loadStyleSheet(const QString &sheetName) -{ - QFile file(":/qss/" + sheetName.toLower() + ".qss"); - file.open(QFile::ReadOnly); - QString styleSheet = QLatin1String(file.readAll()); - - - qApp->setStyleSheet(styleSheet); - -} - - - diff --git a/retroshare-gui/src/gui/unfinished/ApplicationWindow.h b/retroshare-gui/src/gui/unfinished/ApplicationWindow.h index 04c70b88c..e60cceff2 100644 --- a/retroshare-gui/src/gui/unfinished/ApplicationWindow.h +++ b/retroshare-gui/src/gui/unfinished/ApplicationWindow.h @@ -22,34 +22,16 @@ #ifndef _ApplicationWindow_H #define _ApplicationWindow_H -#include #include -#include - -#include "ExampleDialog.h" - +//#include "ExampleDialog.h" #include "ui_ApplicationWindow.h" - class ApplicationWindow : public QMainWindow { Q_OBJECT public: - /** Main dialog pages. */ - enum Page { - Graph = 0, /** Network Graph */ - Channels = 1, /** Channels page. */ - SharedDirectories = 2, /** Shared Directories page. */ - Search = 3, /** Search page. */ - Transfers = 4, /** Transfers page. */ - Chat = 5, /** Chat page. */ - Messages = 6, /** Messages page. */ - Statistics = 8 /** Statistic page. */ - - }; - /** Default Constructor */ ApplicationWindow(QWidget *parent = 0, Qt::WFlags flags = 0); @@ -60,54 +42,23 @@ public: * the dialogs, so we can add them to the * Notify Class... */ - - ExampleDialog *exampleDialog; + + //ExampleDialog *exampleDialog; //ChannelsDialog *channelsDialog; //GroupsDialog *groupsDialog; //StatisticDialog *statisticDialog; -public slots: - /** Called when this dialog is to be displayed */ - void show(); - /** Shows the config dialog with focus set to the given page. */ - void show(Page page); - - -private slots: - - void updateMenu(); - - void toggleVisibility(QSystemTrayIcon::ActivationReason e); - void toggleVisibilitycontextmenu(); - - protected: void closeEvent(QCloseEvent *); - -private slots: - - - private: - - /** Create the actions on the tray menu or menubar */ - void createActions(); - /** Creates a new action for a config page. */ QAction* createPageAction(QIcon img, QString text, QActionGroup *group); /** Adds a new action to the toolbar. */ void addAction(QAction *action, const char *slot = 0); - - void loadStyleSheet(const QString &sheetName); - - QSystemTrayIcon *trayIcon; - QAction *toggleVisibilityAction; - QMenu *menu; - + /** Qt Designer generated object */ Ui::ApplicationWindow ui; }; #endif - diff --git a/retroshare-gui/src/gui/unfinished/ApplicationWindow.ui b/retroshare-gui/src/gui/unfinished/ApplicationWindow.ui index fb8be2949..384af0024 100644 --- a/retroshare-gui/src/gui/unfinished/ApplicationWindow.ui +++ b/retroshare-gui/src/gui/unfinished/ApplicationWindow.ui @@ -1,7 +1,8 @@ - + + ApplicationWindow - - + + 0 0 @@ -9,1055 +10,67 @@ 542 - - - - - - - 0 - 0 - 0 - - - - - - - 208 - 208 - 208 - - - - - - - 255 - 255 - 255 - - - - - - - 247 - 247 - 247 - - - - - - - 120 - 120 - 120 - - - - - - - 139 - 139 - 139 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 240 - 240 - 240 - - - - - - - 0 - 0 - 0 - - - - - - - 10 - 36 - 106 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 255 - - - - - - - 255 - 0 - 255 - - - - - - - 247 - 247 - 247 - - - - - - - - - 0 - 0 - 0 - - - - - - - 208 - 208 - 208 - - - - - - - 255 - 255 - 255 - - - - - - - 247 - 247 - 247 - - - - - - - 120 - 120 - 120 - - - - - - - 139 - 139 - 139 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 240 - 240 - 240 - - - - - - - 0 - 0 - 0 - - - - - - - 212 - 208 - 200 - - - - - - - 0 - 0 - 0 - - - - - - - 0 - 0 - 255 - - - - - - - 255 - 0 - 255 - - - - - - - 247 - 247 - 247 - - - - - - - - - 120 - 120 - 120 - - - - - - - 208 - 208 - 208 - - - - - - - 255 - 255 - 255 - - - - - - - 247 - 247 - 247 - - - - - - - 120 - 120 - 120 - - - - - - - 139 - 139 - 139 - - - - - - - 120 - 120 - 120 - - - - - - - 255 - 255 - 255 - - - - - - - 120 - 120 - 120 - - - - - - - 240 - 240 - 240 - - - - - - - 240 - 240 - 240 - - - - - - - 0 - 0 - 0 - - - - - - - 10 - 36 - 106 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 255 - - - - - - - 255 - 0 - 255 - - - - - - - 247 - 247 - 247 - - - - - - - - Qt::CustomContextMenu - - + RetroShare - + 24 24 - + Qt::ToolButtonTextUnderIcon - - - - 0 - 12 - 679 - 509 - - - - + + + 6 - + 0 - + 6 - + 0 - + 0 - - - - - 120 - 0 - - - - - 120 - 0 - - - - - - - - - 0 - 0 - 0 - - - - - - - 208 - 208 - 208 - - - - - - - 255 - 255 - 255 - - - - - - - 247 - 247 - 247 - - - - - - - 120 - 120 - 120 - - - - - - - 160 - 160 - 160 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 240 - 240 - 240 - - - - - - - 0 - 0 - 0 - - - - - - - 10 - 36 - 106 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 255 - - - - - - - 255 - 0 - 255 - - - - - - - 247 - 247 - 247 - - - - - - - - - 0 - 0 - 0 - - - - - - - 208 - 208 - 208 - - - - - - - 255 - 255 - 255 - - - - - - - 247 - 247 - 247 - - - - - - - 120 - 120 - 120 - - - - - - - 160 - 160 - 160 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 240 - 240 - 240 - - - - - - - 0 - 0 - 0 - - - - - - - 212 - 208 - 200 - - - - - - - 0 - 0 - 0 - - - - - - - 0 - 0 - 255 - - - - - - - 255 - 0 - 255 - - - - - - - 247 - 247 - 247 - - - - - - - - - 120 - 120 - 120 - - - - - - - 208 - 208 - 208 - - - - - - - 255 - 255 - 255 - - - - - - - 247 - 247 - 247 - - - - - - - 120 - 120 - 120 - - - - - - - 160 - 160 - 160 - - - - - - - 120 - 120 - 120 - - - - - - - 255 - 255 - 255 - - - - - - - 120 - 120 - 120 - - - - - - - 240 - 240 - 240 - - - - - - - 240 - 240 - 240 - - - - - - - 0 - 0 - 0 - - - - - - - 10 - 36 - 106 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 255 - - - - - - - 255 - 0 - 255 - - - - - - - 247 - 247 - 247 - - - - - - - - - 50 - false - - - - Qt::NoContextMenu - - + + - - - - 0 - 521 - 679 - 21 - - - - - - - 0 - 0 - 679 - 12 - - - + + + Qt::NoContextMenu - + true - + Qt::TopToolBarArea - + Qt::Horizontal - + 24 24 - + Qt::ToolButtonTextUnderIcon - + TopToolBarArea - + false @@ -1069,8 +82,6 @@
gui/mainpagestack.h
- - - +
From fde1e8d66d9a218fec1be0480a07a12a1ab64eee Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 22 Oct 2012 18:42:54 +0000 Subject: [PATCH 101/222] tweaked cyrils mods to be compatible with old ssh location, and use pregenerated proto.cc files. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5712 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-nogui/src/retroshare-nogui.pro | 45 ++++++++++++++++------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/retroshare-nogui/src/retroshare-nogui.pro b/retroshare-nogui/src/retroshare-nogui.pro index 21efc2a79..7906e0069 100644 --- a/retroshare-nogui/src/retroshare-nogui.pro +++ b/retroshare-nogui/src/retroshare-nogui.pro @@ -133,7 +133,7 @@ introserver { sshserver { - LIBSSH_DIR = ../../libssh-0.5.2 + LIBSSH_DIR = ../../../lib/libssh-0.5.2 # This Requires libssh-0.5.* to compile. # Modify path below to point at it. @@ -205,20 +205,37 @@ protorpc { rpc/proto/rpcprotosearch.cc \ rpc/proto/rpcprotofiles.cc \ - # Generated ProtoBuf Code the RPC System - HEADERS += ../../rsctrl/src/gencc/core.pb.h \ - ../../rsctrl/src/gencc/peers.pb.h \ - ../../rsctrl/src/gencc/system.pb.h \ - ../../rsctrl/src/gencc/chat.pb.h \ - ../../rsctrl/src/gencc/search.pb.h \ - ../../rsctrl/src/gencc/files.pb.h \ + # Offical Generated Code (protobuf 2.4.1) + HEADERS += rpc/proto/gencc/core.pb.h \ + rpc/proto/gencc/peers.pb.h \ + rpc/proto/gencc/system.pb.h \ + rpc/proto/gencc/chat.pb.h \ + rpc/proto/gencc/search.pb.h \ + rpc/proto/gencc/files.pb.h \ - SOURCES += ../../rsctrl/src/gencc/core.pb.cc \ - ../../rsctrl/src/gencc/peers.pb.cc \ - ../../rsctrl/src/gencc/system.pb.cc \ - ../../rsctrl/src/gencc/chat.pb.cc \ - ../../rsctrl/src/gencc/search.pb.cc \ - ../../rsctrl/src/gencc/files.pb.cc \ + SOURCES += rpc/proto/gencc/core.pb.cc \ + rpc/proto/gencc/peers.pb.cc \ + rpc/proto/gencc/system.pb.cc \ + rpc/proto/gencc/chat.pb.cc \ + rpc/proto/gencc/search.pb.cc \ + rpc/proto/gencc/files.pb.cc \ + + # Generated ProtoBuf Code the RPC System + # If you are developing, or have a different version of protobuf + # you can use these ones (run make inside rsctrl/src/ to generate) + #HEADERS += ../../rsctrl/src/gencc/core.pb.h \ + # ../../rsctrl/src/gencc/peers.pb.h \ + # ../../rsctrl/src/gencc/system.pb.h \ + # ../../rsctrl/src/gencc/chat.pb.h \ + # ../../rsctrl/src/gencc/search.pb.h \ + # ../../rsctrl/src/gencc/files.pb.h \ + + #SOURCES += ../../rsctrl/src/gencc/core.pb.cc \ + # ../../rsctrl/src/gencc/peers.pb.cc \ + # ../../rsctrl/src/gencc/system.pb.cc \ + # ../../rsctrl/src/gencc/chat.pb.cc \ + # ../../rsctrl/src/gencc/search.pb.cc \ + # ../../rsctrl/src/gencc/files.pb.cc \ QMAKE_CFLAGS += -pthread QMAKE_CXXFLAGS += -pthread From e432a2a66125e5f1296016ebd3250565900cc7c0 Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 22 Oct 2012 19:07:54 +0000 Subject: [PATCH 102/222] tweaked Makefile - only builds C++ by default. - files are generated into rs-nogui src tree. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5713 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- rsctrl/src/Makefile | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/rsctrl/src/Makefile b/rsctrl/src/Makefile index e4353a659..b6305a374 100644 --- a/rsctrl/src/Makefile +++ b/rsctrl/src/Makefile @@ -6,8 +6,8 @@ PROTO = core.proto peers.proto system.proto chat.proto search.proto files.proto PROTOPATH = ./definition #CDESTPATH = ./gencc CDESTPATH = ../../retroshare-nogui/src/rpc/proto/gencc -#PYDESTPATH = ./genpy -PYDESTPATH = ../../../../github/pyrs/pyrs/proto +PYDESTPATH = ./genpy +#PYDESTPATH = ../../../../github/pyrs/pyrs/proto CLIST = $(PROTO:%.proto=%.cc) CCODE = $(patsubst %.proto,$(CDESTPATH)/%.pb.cc, $(PROTO)) @@ -16,10 +16,12 @@ PYCODE = $(patsubst %.proto,$(PYDESTPATH)/%_pb2.py, $(PROTO)) all: allc - echo $(CCODE) - echo $(PYCODE) -allc: $(CCODE) $(PYCODE) +allc: $(CCODE) + echo $(CCODE) + +python_proto: $(PYCODE) + echo $(PYCODE) $(CDESTPATH)/%.pb.cc : $(PROTOPATH)/%.proto $(EXEC) --proto_path=$(PROTOPATH) --cpp_out=$(CDESTPATH) $< From bb9a80e95b6d9d572906e9ed11ea6d4833e47bd4 Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 22 Oct 2012 20:36:28 +0000 Subject: [PATCH 103/222] tried to link cache with data... turns out I can't extract the keys - help! git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5714 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/services/p3idservice.cc | 102 ++++++++++++++++++---- libretroshare/src/services/p3idservice.h | 6 +- 2 files changed, 89 insertions(+), 19 deletions(-) diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 6bcf7839d..673973549 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -43,6 +43,7 @@ RsIdentity *rsIdentity = NULL; + #define RSGXSID_MAX_SERVICE_STRING 1024 /********************************************************************************/ @@ -108,26 +109,41 @@ bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) bool p3IdService::haveKey(const RsGxsId &id) { - return false; + /* is it in the cache? */ + return cache_is_loaded(id); } bool p3IdService::havePrivateKey(const RsGxsId &id) { + /* TODO */ return false; } bool p3IdService::requestKey(const RsGxsId &id, const std::list &peers) { - return false; + /* basic version first --- don't have to worry about network load + * request it for the cache + */ + if (cache_is_loaded(id)) + return true; + + return cache_request_load(id); } int p3IdService::getKey(const RsGxsId &id, RsTlvSecurityKey &key) { + RsGxsIdCache data; + if (cache_fetch(id, data)) + { + key = data.pubkey; + return 1; + } return -1; } int p3IdService::getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key) { + /* TODO */ return -1; } @@ -248,6 +264,50 @@ bool p3IdService::createMsg(uint32_t& token, RsGxsIdOpinion &opinion) * */ +RsGxsIdCache::RsGxsIdCache() + :reputation(0), lastUsedTs(0) +{ + return; +} + +RsGxsIdCache::RsGxsIdCache(const RsGxsIdGroupItem *item) +{ + id = item->meta.mGroupId; + name = item->meta.mGroupName; + + /* extract key from keys */ + bool key_ok = false; + + /**** OKAY, I can't do this ???? how do I access the keys? ****/ +#if 0 + std::map::iterator kit; + + for (kit = item->meta.keys.keys.begin(); kit != item->meta.keys.keys.end(); kit++) + { + if (kit->second.keyFlags == RSTLV_KEY_DISTRIB_PUBLIC | RSTLV_KEY_TYPE_PUBLIC_ONLY) + { + std::cerr << "RsGxsIdCache::load() Found Public Key"; + std::cerr << std::endl; + + pubkey = kit->second; + key_ok = true; + } + } +#endif + + if (!key_ok) + { + std::cerr << "RsGxsIdCache::load() ERROR No Public Key Found"; + std::cerr << std::endl; + } + + reputation = 0; /* TODO: extract from string - This will need to be refreshed!!! */ + lastUsedTs = 0; + +}; + + + bool p3IdService::cache_is_loaded(const RsGxsId &id) { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ @@ -285,12 +345,12 @@ bool p3IdService::cache_fetch(const RsGxsId &id, RsGxsIdCache &data) return true; } -bool p3IdService::cache_store(const RsGxsIdGroup &group) +bool p3IdService::cache_store(const RsGxsIdGroupItem *item) { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ // Create Cache Data. - RsGxsIdCache cache(group); + RsGxsIdCache cache(item); // For consistency std::map::iterator it; @@ -549,10 +609,27 @@ bool p3IdService::cache_load_for_token(uint32_t token) std::cerr << "p3IdService::cache_load_for_token() : " << token; std::cerr << std::endl; - std::vector groups; - std::vector::iterator vit; + std::vector grpData; + bool ok = RsGenExchange::getGroupData(token, grpData); - if (!getGroupData(token, groups)) + if(ok) + { + std::vector::iterator vit = grpData.begin(); + + for(; vit != grpData.end(); vit++) + { + RsGxsIdGroupItem* item = dynamic_cast(*vit); + + std::cerr << "p3IdService::cache_load_for_token() Loaded Id with Meta: "; + std::cerr << item->meta; + std::cerr << std::endl; + + /* cache the data */ + cache_store(item); + delete item; + } + } + else { std::cerr << "p3IdService::cache_load_for_token() ERROR no data"; std::cerr << std::endl; @@ -560,17 +637,6 @@ bool p3IdService::cache_load_for_token(uint32_t token) return false; } - for(vit = groups.begin(); vit != groups.end(); vit++) - { - RsGxsIdGroup &group = *vit; - - std::cerr << "p3IdService::cache_load_for_token() Loaded Id with Meta: "; - std::cerr << group.mMeta; - std::cerr << std::endl; - - /* cache the data */ - cache_store(group); - } /* drop old entries */ cache_resize(); diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index cb528b3e1..7089273d5 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -74,11 +74,13 @@ public: #define MAX_CACHE_SIZE 100 // Small for testing.. //#define MAX_CACHE_SIZE 10000 // More useful size +class RsGxsIdGroupItem; + class RsGxsIdCache { public: RsGxsIdCache(); - RsGxsIdCache(const RsGxsIdGroup &group); + RsGxsIdCache(const RsGxsIdGroupItem *item); RsGxsId id; std::string name; @@ -163,6 +165,8 @@ virtual bool getReputation(const RsGxsId &id, const GixsReputation &rep); bool cache_is_loaded(const RsGxsId &id); bool cache_fetch(const RsGxsId &key, RsGxsIdCache &data); + bool cache_store(const RsGxsIdGroupItem *item); + bool cache_store(const RsGxsIdGroup &group); bool cache_resize(); bool cache_discard_LRU(int count_to_clear); From 6e04229d395d3d08712648e79c7fe07951ce7365 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Tue, 23 Oct 2012 00:24:41 +0000 Subject: [PATCH 104/222] Fixed utf8 handling in photo comments. Some cosmetic changes. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5715 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/gui/PhotoShare/AlbumCreateDialog.ui | 7 +- .../src/gui/PhotoShare/AlbumDialog.cpp | 5 +- .../src/gui/PhotoShare/AlbumDialog.h | 4 +- .../src/gui/PhotoShare/AlbumDialog.ui | 17 ++++- .../src/gui/PhotoShare/PhotoCommentItem.cpp | 2 +- .../src/gui/PhotoShare/PhotoDialog.cpp | 49 ++++++------ .../src/gui/PhotoShare/PhotoDialog.h | 3 - .../src/gui/PhotoShare/PhotoDialog.ui | 30 +++++--- .../src/gui/PhotoShare/PhotoShare.cpp | 75 +++++-------------- .../src/gui/PhotoShare/PhotoShare.h | 11 +-- .../src/gui/PhotoShare/PhotoSlideShow.ui | 7 +- retroshare-gui/src/gui/Posted/PostedDialog.ui | 10 +-- .../src/gui/unfinished/ApplicationWindow.ui | 2 +- 13 files changed, 92 insertions(+), 130 deletions(-) diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui index 52e3c5d70..5c881bfb9 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui @@ -7,11 +7,14 @@ 0 0 465 - 347 + 356 - Dialog + Create Album + + + true diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp index c2500df2d..c39825bdf 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp @@ -4,11 +4,10 @@ #include "ui_AlbumDialog.h" AlbumDialog::AlbumDialog(const RsPhotoAlbum& album, TokenQueue* photoQueue, RsPhotoV2* rs_Photo, QWidget *parent) : - QWidget(parent), - ui(new Ui::AlbumDialog), mPhotoQueue(photoQueue), mRsPhoto(rs_Photo), mAlbum(album), mPhotoSelected(NULL) + QDialog(parent), + ui(new Ui::AlbumDialog), mRsPhoto(rs_Photo), mPhotoQueue(photoQueue), mAlbum(album), mPhotoSelected(NULL) { ui->setupUi(this); - setAttribute ( Qt::WA_DeleteOnClose, true ); connect(ui->pushButton_PublishPhotos, SIGNAL(clicked()), this, SLOT(updateAlbumPhotos())); connect(ui->pushButton_DeletePhoto, SIGNAL(clicked()), this, SLOT(deletePhoto())); diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h index 0827a787e..8ee8b0405 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h @@ -1,7 +1,7 @@ #ifndef ALBUMDIALOG_H #define ALBUMDIALOG_H -#include +#include #include "retroshare/rsphotoV2.h" #include "util/TokenQueue.h" #include "PhotoShareItemHolder.h" @@ -12,7 +12,7 @@ namespace Ui { class AlbumDialog; } -class AlbumDialog : public QWidget, public PhotoShareItemHolder +class AlbumDialog : public QDialog, public PhotoShareItemHolder { Q_OBJECT diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui index a7f38e867..b5568d690 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui @@ -1,7 +1,7 @@ AlbumDialog - + 0 @@ -11,7 +11,14 @@ - Form + Album + + + + :/images/rstray3.png:/images/rstray3.png + + + true @@ -278,7 +285,7 @@ p, li { white-space: pre-wrap; } 0 0 627 - 116 + 107 @@ -353,6 +360,8 @@ p, li { white-space: pre-wrap; } 1 - + + + diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.cpp index 6cfb2236a..8d757122e 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.cpp @@ -24,7 +24,7 @@ const RsPhotoComment& PhotoCommentItem::getComment() void PhotoCommentItem::setUp() { - ui->labelComment->setText(QString::fromStdString(mComment.mComment)); + ui->labelComment->setText(QString::fromUtf8(mComment.mComment.c_str())); QDateTime qtime; qtime.setTime_t(mComment.mMeta.mPublishTs); QString timestamp = qtime.toString("dd.MMMM yyyy hh:mm"); diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index 9379a7f63..80348d1d4 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -3,19 +3,20 @@ #include "PhotoDialog.h" #include "ui_PhotoDialog.h" - +#include "AddCommentDialog.h" PhotoDialog::PhotoDialog(RsPhotoV2 *rs_photo, const RsPhotoPhoto &photo, QWidget *parent) : QDialog(parent), ui(new Ui::PhotoDialog), mRsPhoto(rs_photo), mPhotoQueue(new TokenQueue(mRsPhoto->getTokenService(), this)), - mPhotoDetails(photo), mCommentDialog(NULL) - + mPhotoDetails(photo) { ui->setupUi(this); setAttribute ( Qt::WA_DeleteOnClose, true ); - connect(ui->toolButton_AddComment, SIGNAL(clicked()), this, SLOT(createComment())); - setUp(); + connect(ui->pushButton_AddComment, SIGNAL(clicked()), this, SLOT(createComment())); + connect(ui->pushButton_AddCommentDlg, SIGNAL(clicked()), this, SLOT(addComment())); + + setUp(); } PhotoDialog::~PhotoDialog() @@ -36,15 +37,19 @@ void PhotoDialog::setUp() requestComments(); } - - - void PhotoDialog::addComment() { - mCommentDialog = new AddCommentDialog(this); - connect(mCommentDialog, SIGNAL(accepted()), this, SLOT(createComment())); - connect(mCommentDialog, SIGNAL(rejected()), mCommentDialog, SLOT(deleteLater())); - mCommentDialog->exec(); + AddCommentDialog dlg(this); + if (dlg.exec() == QDialog::Accepted) { + RsPhotoComment comment; + comment.mComment = dlg.getComment().toUtf8().constData(); + + uint32_t token; + comment.mMeta.mGroupId = mPhotoDetails.mMeta.mGroupId; + comment.mMeta.mParentId = mPhotoDetails.mMeta.mOrigMsgId; + mRsPhoto->submitComment(token, comment); + mPhotoQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); + } } void PhotoDialog::clearComments() @@ -90,18 +95,18 @@ void PhotoDialog::requestComments() void PhotoDialog::createComment() { - RsPhotoComment comment; - QString commentString = ui->lineEdit->text(); + RsPhotoComment comment; + QString commentString = ui->lineEdit->text(); - comment.mComment = commentString.toStdString(); + comment.mComment = commentString.toUtf8().constData(); - uint32_t token; - comment.mMeta.mGroupId = mPhotoDetails.mMeta.mGroupId; - comment.mMeta.mParentId = mPhotoDetails.mMeta.mOrigMsgId; - mRsPhoto->submitComment(token, comment); - mPhotoQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); - - ui->lineEdit->clear(); + uint32_t token; + comment.mMeta.mGroupId = mPhotoDetails.mMeta.mGroupId; + comment.mMeta.mParentId = mPhotoDetails.mMeta.mOrigMsgId; + mRsPhoto->submitComment(token, comment); + mPhotoQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); + + ui->lineEdit->clear(); } diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h index 855e14f3f..867382fbc 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h @@ -6,7 +6,6 @@ #include "retroshare/rsphotoV2.h" #include "util/TokenQueue.h" #include "PhotoCommentItem.h" -#include "AddCommentDialog.h" namespace Ui { class PhotoDialog; @@ -57,8 +56,6 @@ private: TokenQueue* mPhotoQueue; RsPhotoPhoto mPhotoDetails; QSet mComments; - AddCommentDialog* mCommentDialog; - }; #endif // PHOTODIALOG_H diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui index 3436b84a0..5cf9d47a5 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui @@ -10,15 +10,16 @@ 566 - - - 0 - 0 - - PhotoShare + + + :/images/rstray3.png:/images/rstray3.png + + + true + @@ -54,7 +55,7 @@
- + @@ -76,7 +77,7 @@ 0 0 - 325 + 369 18 @@ -194,8 +195,15 @@ + + + + Add Comment + + + - + Comment @@ -203,6 +211,8 @@
- + + + diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp index 4f1fdf342..010990d4b 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp @@ -75,9 +75,6 @@ PhotoShare::PhotoShare(QWidget *parent) mAlbumSelected = NULL; mPhotoSelected = NULL; - mSlideShow = NULL; - mAlbumDialog = NULL; - mPhotoDialog = NULL; connect( ui.toolButton_NewAlbum, SIGNAL(clicked()), this, SLOT(createAlbum())); connect( ui.toolButton_ViewAlbum, SIGNAL(clicked()), this, SLOT(OpenAlbumDialog())); @@ -198,28 +195,18 @@ void PhotoShare::checkUpdate() void PhotoShare::OpenSlideShow() { + // TODO. + if (!mAlbumSelected) { + // ALERT. + int ret = QMessageBox::information(this, tr("PhotoShare"), + tr("Please select an album before\n" + "requesting to edit it!"), + QMessageBox::Ok); + return; + } - // TODO. - if (!mAlbumSelected) - { - // ALERT. - int ret = QMessageBox::information(this, tr("PhotoShare"), - tr("Please select an album before\n" - "requesting to edit it!"), - QMessageBox::Ok); - return; - } - - if (mSlideShow) - { - mSlideShow->show(); - } - else - { - mSlideShow = new PhotoSlideShow(mAlbumSelected->getAlbum(), NULL); - mSlideShow->show(); - } - + PhotoSlideShow *dlg = new PhotoSlideShow(mAlbumSelected->getAlbum(), NULL); + dlg->show(); } @@ -233,48 +220,20 @@ void PhotoShare::createAlbum() void PhotoShare::OpenAlbumDialog() { - if(mAlbumSelected){ - - if(mAlbumDialog == NULL) - { - mAlbumDialog = new AlbumDialog(mAlbumSelected->getAlbum(), mPhotoQueue, rsPhotoV2); - connect(mAlbumDialog, SIGNAL(destroyed()), this, SLOT(SetAlbumDialogClosed())); - mAlbumDialog->show(); - }else{ - // bring dialog to front - mAlbumDialog->raise(); - } + if (mAlbumSelected) { + AlbumDialog dlg(mAlbumSelected->getAlbum(), mPhotoQueue, rsPhotoV2); + dlg.exec(); } - return; } void PhotoShare::OpenPhotoDialog() { - if(mPhotoSelected) - { - if(mPhotoDialog == NULL) - { - mPhotoDialog = new PhotoDialog(rsPhotoV2, mPhotoSelected->getPhotoDetails()); - connect(mPhotoDialog, SIGNAL(destroyed()), this, SLOT(SetPhotoDialogClosed())); - mPhotoDialog->show(); - } - else - { - mPhotoDialog->raise(); - } + if (mPhotoSelected) { + PhotoDialog *dlg = new PhotoDialog(rsPhotoV2, mPhotoSelected->getPhotoDetails()); + dlg->show(); } } -void PhotoShare::SetAlbumDialogClosed() -{ - mAlbumDialog = NULL; -} - -void PhotoShare::SetPhotoDialogClosed() -{ - mPhotoDialog = NULL; -} - /*************** Edit Photo Dialog ***************/ void PhotoShare::clearAlbums() diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.h b/retroshare-gui/src/gui/PhotoShare/PhotoShare.h index b936de318..53b722bd1 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.h @@ -33,19 +33,16 @@ public: void notifySelection(PhotoShareItem* selection); private slots: - void checkUpdate(); void createAlbum(); void OpenAlbumDialog(); void OpenPhotoDialog(); void OpenSlideShow(); - void SetAlbumDialogClosed(); - void SetPhotoDialogClosed(); void updateAlbums(); void subscribeToAlbum(); void deleteAlbum(const RsGxsGroupId&); -private: +private: /* Request Response Functions for loading data */ void requestAlbumList(std::list& ids); void requestAlbumData(std::list &ids); @@ -83,13 +80,9 @@ private: void updatePhotos(); private: - - AlbumItem* mAlbumSelected; PhotoItem* mPhotoSelected; - PhotoSlideShow* mSlideShow; - AlbumDialog* mAlbumDialog; - PhotoDialog* mPhotoDialog; + TokenQueue *mPhotoQueue; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.ui b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.ui index 9bc91f506..a684f9a48 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.ui @@ -10,9 +10,6 @@ 671 - - - @@ -137,8 +134,6 @@ - - - + diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.ui b/retroshare-gui/src/gui/Posted/PostedDialog.ui index bf21aa5f6..fef6921dd 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.ui +++ b/retroshare-gui/src/gui/Posted/PostedDialog.ui @@ -10,24 +10,16 @@ 557 - - - -1 - - true - - - - + diff --git a/retroshare-gui/src/gui/unfinished/ApplicationWindow.ui b/retroshare-gui/src/gui/unfinished/ApplicationWindow.ui index 384af0024..21e91fe63 100644 --- a/retroshare-gui/src/gui/unfinished/ApplicationWindow.ui +++ b/retroshare-gui/src/gui/unfinished/ApplicationWindow.ui @@ -47,7 +47,7 @@ - Qt::NoContextMenu + Qt::CustomContextMenu true From 301e85c2fa5a48dc4a06af029055d4fff02925af Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Tue, 23 Oct 2012 21:52:51 +0000 Subject: [PATCH 105/222] Bug fix, did not add time stamp at msg signing stage (bug thunder found) Did not do check for msgs that already existed, msg is not checked if it exist this is deleted and error is sent to GUI for token need to do same for groups! Removed stack allocated msgs which cause crashes for large message items (bug defnax found) Added function to retrieve group keys from GXS to RsGenExchange First bits need for validation: Signing now consist of all msg data (msg + meta except msgId and signature) git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5718 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/gxssecurity.cc | 90 +++++++++- libretroshare/src/gxs/gxssecurity.h | 27 +-- libretroshare/src/gxs/rsdataservice.cc | 3 +- libretroshare/src/gxs/rsgenexchange.cc | 232 ++++++++++++++++--------- libretroshare/src/gxs/rsgenexchange.h | 41 +++-- libretroshare/src/gxs/rsgixs.h | 16 +- 6 files changed, 286 insertions(+), 123 deletions(-) diff --git a/libretroshare/src/gxs/gxssecurity.cc b/libretroshare/src/gxs/gxssecurity.cc index 507b2a2e3..0c3f0318b 100644 --- a/libretroshare/src/gxs/gxssecurity.cc +++ b/libretroshare/src/gxs/gxssecurity.cc @@ -28,6 +28,8 @@ #include "pqi/authgpg.h" #include "retroshare/rspeers.h" +#define GXS_SECURITY_DEBUG + GxsSecurity::GxsSecurity() { } @@ -48,10 +50,92 @@ RSA *GxsSecurity::extractPublicKey(RsTlvSecurityKey& key) } -bool GxsSecurity::validateNxsMsg(RsNxsMsg *msg, RsGxsGrpMetaData *grpMeta) +bool GxsSecurity::validateNxsMsg(RsNxsMsg *msg, RsTlvKeySignature& sign, RsTlvSecurityKeySet& key) { + //#ifdef GXS_SECURITY_DEBUG + // std::cerr << "GxsSecurity::validateNxsMsg()"; + // std::cerr << std::endl; + // std::cerr << "RsNxsMsg :"; + // std::cerr << std::endl; + // msg->print(std::cerr, 10); + // std::cerr << std::endl; + //#endif - return false; + + // /********************* check signature *******************/ + + // /* check signature timeperiod */ + // if ((newMsg->timestamp < kit->second.startTS) || + // (newMsg->timestamp > kit->second.endTS)) + // { + //#ifdef DISTRIB_DEBUG + // std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() TS out of range"; + // std::cerr << std::endl; + //#endif + // return false; + // } + + // /* decode key */ + // const unsigned char *keyptr = (const unsigned char *) kit->second.keyData.bin_data; + // long keylen = kit->second.keyData.bin_len; + // unsigned int siglen = newMsg->publishSignature.signData.bin_len; + // unsigned char *sigbuf = (unsigned char *) newMsg->publishSignature.signData.bin_data; + + //#ifdef DISTRIB_DEBUG + // std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Decode Key"; + // std::cerr << " keylen: " << keylen << " siglen: " << siglen; + // std::cerr << std::endl; + //#endif + + // /* extract admin key */ + // RSA *rsakey = d2i_RSAPublicKey(NULL, &(keyptr), keylen); + + // if (!rsakey) + // { + //#ifdef DISTRIB_DEBUG + // std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg()"; + // std::cerr << " Invalid RSA Key"; + // std::cerr << std::endl; + + // unsigned long err = ERR_get_error(); + // std::cerr << "RSA Load Failed .... CODE(" << err << ")" << std::endl; + // std::cerr << ERR_error_string(err, NULL) << std::endl; + + // kit->second.print(std::cerr, 10); + //#endif + // } + + + // EVP_PKEY *signKey = EVP_PKEY_new(); + // EVP_PKEY_assign_RSA(signKey, rsakey); + + // /* calc and check signature */ + // EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); + + // EVP_VerifyInit(mdctx, EVP_sha1()); + // EVP_VerifyUpdate(mdctx, newMsg->packet.bin_data, newMsg->packet.bin_len); + // int signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey); + + // /* clean up */ + // EVP_PKEY_free(signKey); + // EVP_MD_CTX_destroy(mdctx); + + + // if (signOk == 1) + // { + //#ifdef GXS_SECURITY_DEBUG + // std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Signature OK"; + // std::cerr << std::endl; + //#endif + // return true; + // } + + //#ifdef DISTRIB_DEBUG + // std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Signature invalid"; + // std::cerr << std::endl; + //#endif + + // return false; } @@ -235,7 +319,7 @@ std::string GxsSecurity::getRsaKeySign(RSA *pubkey) } -bool GxsSecurity::validateNxsGrp(RsNxsGrp *newGrp) +bool GxsSecurity::validateNxsGrp(RsNxsGrp *newGrp, RsTlvKeySignature& sign, RsTlvSecurityKey& key) { } diff --git a/libretroshare/src/gxs/gxssecurity.h b/libretroshare/src/gxs/gxssecurity.h index 23ceca40d..10329bf2c 100644 --- a/libretroshare/src/gxs/gxssecurity.h +++ b/libretroshare/src/gxs/gxssecurity.h @@ -2,12 +2,12 @@ #define GXSSECURITY_H /* - * libretroshare/src/gxs: gxssecurity + * libretroshare/src/gxs: gxssecurity.h * * Security functions for Gxs * * Copyright 2008-2010 by Robert Fernie - * 2012 Christopher Evi-Parker + * 2011-2012 Christopher Evi-Parker * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -82,11 +82,11 @@ public: static std::string getRsaKeySign(RSA *pubkey); /*! - * extracts the signature and stores it in a string + * extracts the first CERTSIGNLEN bytes of signature and stores it in a string * in hex format - * @param data - * @param len - * @return + * @param data signature + * @param len the length of the signature data + * @return returns the first CERTSIGNLEN of the signature as a string */ static std::string getBinDataSign(void *data, int len); @@ -115,18 +115,21 @@ public: /*! * uses grp signature to check if group has been * tampered with - * @param newGrp + * @param newGrp the Nxs group to be validated + * @param sign the signature to validdate against + * @param key the public key to use to check signature * @return true if group valid false otherwise */ - static bool validateNxsGrp(RsNxsGrp *newGrp); + static bool validateNxsGrp(RsNxsGrp *newGrp, RsTlvKeySignature& sign, RsTlvSecurityKey& key); /*! - * uses groupinfo public key to verify signature of signed message - * @param info groupinfo for which msg is meant for - * @param msg + * Validate a msg's signature using the given public key + * @param msg the Nxs message to be validated + * @param sign the signature to validdate against + * @param key the public key to use to check signature * @return false if verfication of signature is not passed */ - static bool validateNxsMsg(RsNxsMsg *msg, RsGxsGrpMetaData* grpMeta); + static bool validateNxsMsg(RsNxsMsg *msg, RsTlvKeySignature& sign, RsTlvSecurityKeySet& key); }; #endif // GXSSECURITY_H diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index 46cb3848d..7f2bb6242 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -400,7 +400,7 @@ RsNxsMsg* RsDataService::getMessage(RetroCursor &c) if(ok){ - char msg_data[data_len]; + char* msg_data = new char[data_len]; std::ifstream istrm(msgFile.c_str(), std::ios::binary); istrm.seekg(offset, std::ios::beg); istrm.read(msg_data, data_len); @@ -408,6 +408,7 @@ RsNxsMsg* RsDataService::getMessage(RetroCursor &c) istrm.close(); offset = 0; ok &= msg->msg.GetTlv(msg_data, data_len, &offset); + delete[] msg_data; } if(ok) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index ecdb61cdc..8d6cf42fa 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -36,8 +36,8 @@ #include "rsgxsflags.h" RsGenExchange::RsGenExchange(RsGeneralDataService *gds, - RsNetworkExchangeService *ns, RsSerialType *serviceSerialiser, uint16_t servType) -: mGenMtx("GenExchange"), mDataStore(gds), mNetService(ns), mSerialiser(serviceSerialiser), mServType(servType) + RsNetworkExchangeService *ns, RsSerialType *serviceSerialiser, uint16_t servType, RsGixs* gixs) +: mGenMtx("GenExchange"), mDataStore(gds), mNetService(ns), mSerialiser(serviceSerialiser), mServType(servType), mGixs(gixs) { mDataAccess = new RsGxsDataAccess(gds); @@ -206,12 +206,11 @@ bool RsGenExchange::createMessage(RsNxsMsg* msg) } else { - // get publish key - RsGxsGrpMetaData* meta = metaMap[id]; + RsGxsGrpMetaData* grpMeta = metaMap[id]; // public and shared is publish key - RsTlvSecurityKeySet& keys = meta->keys; + RsTlvSecurityKeySet& keys = grpMeta->keys; RsTlvSecurityKey* pubKey; std::map::iterator mit = @@ -235,15 +234,28 @@ bool RsGenExchange::createMessage(RsNxsMsg* msg) /* calc and check signature */ EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); + RsGxsMsgMetaData &meta = *(msg->metaData); + + uint32_t metaDataLen = meta.serial_size(); + uint32_t allMsgDataLen = metaDataLen + msg->msg.bin_len; + char* metaData = new char[metaDataLen]; + char* allMsgData = new char[allMsgDataLen]; // msgData + metaData + + meta.serialise(metaData, &metaDataLen); + + // copy msg data and meta in allmsgData buffer + memcpy(allMsgData, msg->msg.bin_data, msg->msg.bin_len); + memcpy(allMsgData+(msg->msg.bin_len), metaData, metaDataLen); + ok = EVP_SignInit(mdctx, EVP_sha1()) == 1; - ok = EVP_SignUpdate(mdctx, msg->msg.bin_data, msg->msg.bin_len) == 1; + ok = EVP_SignUpdate(mdctx, allMsgData, allMsgDataLen) == 1; unsigned int siglen = EVP_PKEY_size(key_pub); unsigned char sigbuf[siglen]; ok = EVP_SignFinal(mdctx, sigbuf, &siglen, key_pub) == 1; //place signature in msg meta - RsGxsMsgMetaData &meta = *(msg->metaData); + RsTlvKeySignatureSet& signSet = meta.signSet; RsTlvKeySignature pubSign = signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH]; pubSign.signData.setBinData(sigbuf, siglen); @@ -251,7 +263,7 @@ bool RsGenExchange::createMessage(RsNxsMsg* msg) // get hash of msg data to create msg id pqihash hash; - hash.addData(msg->msg.bin_data, msg->msg.bin_len); + hash.addData(allMsgData, allMsgDataLen); hash.Complete(msg->msgId); msg->metaData->mMsgId = msg->msgId; @@ -261,13 +273,16 @@ bool RsGenExchange::createMessage(RsNxsMsg* msg) //RSA_free(rsa_pub); EVP_PKEY_free(key_pub); // no need to free rsa key as evp key is considered parent key by SSL + + delete[] metaData; + delete[] allMsgData; } else { ok = false; } - delete meta; + delete grpMeta; } return ok; @@ -366,33 +381,35 @@ bool RsGenExchange::getGroupData(const uint32_t &token, std::vectorgetMsgData(token, msgResult); - NxsMsgDataResult::iterator mit = msgResult.begin(); - if(ok) - { - for(; mit != msgResult.end(); mit++) - { - std::vector gxsMsgItems; - const RsGxsGroupId& grpId = mit->first; - std::vector& nxsMsgsV = mit->second; - std::vector::iterator vit - = nxsMsgsV.begin(); - for(; vit != nxsMsgsV.end(); vit++) - { - RsNxsMsg*& msg = *vit; + RsStackMutex stack(mGenMtx); + NxsMsgDataResult msgResult; + bool ok = mDataAccess->getMsgData(token, msgResult); + NxsMsgDataResult::iterator mit = msgResult.begin(); - RsItem* item = mSerialiser->deserialise(msg->msg.bin_data, - &msg->msg.bin_len); - RsGxsMsgItem* mItem = dynamic_cast(item); - mItem->meta = *((*vit)->metaData); // get meta info from nxs msg - gxsMsgItems.push_back(mItem); - delete msg; - } - msgItems[grpId] = gxsMsgItems; - } - } + if(ok) + { + for(; mit != msgResult.end(); mit++) + { + std::vector gxsMsgItems; + const RsGxsGroupId& grpId = mit->first; + std::vector& nxsMsgsV = mit->second; + std::vector::iterator vit + = nxsMsgsV.begin(); + for(; vit != nxsMsgsV.end(); vit++) + { + RsNxsMsg*& msg = *vit; + + RsItem* item = mSerialiser->deserialise(msg->msg.bin_data, + &msg->msg.bin_len); + RsGxsMsgItem* mItem = dynamic_cast(item); + mItem->meta = *((*vit)->metaData); // get meta info from nxs msg + gxsMsgItems.push_back(mItem); + delete msg; + } + msgItems[grpId] = gxsMsgItems; + } + } return ok; } @@ -562,70 +579,90 @@ void RsGenExchange::publishMsgs() for(; mit != mMsgsToPublish.end(); mit++) { - RsNxsMsg* msg = new RsNxsMsg(mServType); - RsGxsMsgItem* msgItem = mit->second; + RsNxsMsg* msg = new RsNxsMsg(mServType); + RsGxsMsgItem* msgItem = mit->second; - msg->grpId = msgItem->meta.mGroupId; + msg->grpId = msgItem->meta.mGroupId; - uint32_t size = mSerialiser->size(msgItem); - char mData[size]; - bool ok = mSerialiser->serialise(msgItem, mData, &size); + uint32_t size = mSerialiser->size(msgItem); + char* mData = new char[size]; + bool serialOk = false; + bool createOk = false; + serialOk = mSerialiser->serialise(msgItem, mData, &size); - if(ok) - { - msg->metaData = new RsGxsMsgMetaData(); - msg->msg.setBinData(mData, size); - *(msg->metaData) = msgItem->meta; + if(serialOk) + { + msg->msg.setBinData(mData, size); - ok = createMessage(msg); - RsGxsMessageId msgId; - RsGxsGroupId grpId; - if(ok) - { - msg->metaData->mPublishTs = time(NULL); + // now create meta + msg->metaData = new RsGxsMsgMetaData(); + *(msg->metaData) = msgItem->meta; - // empty orig msg id means this is the original - // msg - // TODO: a non empty msgid means one should at least - // have the msg on disk, after which this msg is signed - // based on the security settings - // public grp (sign by grp public pub key, private/id: signed by - // id - if(msg->metaData->mOrigMsgId.empty()) - { - msg->metaData->mOrigMsgId = msg->metaData->mMsgId; - } + // assign time stamp + msg->metaData->mPublishTs = time(NULL); - // now serialise meta data - size = msg->metaData->serial_size(); - char metaDataBuff[size]; - msg->metaData->serialise(metaDataBuff, &size); - msg->meta.setBinData(metaDataBuff, size); + // now intialise msg (sign it) + createOk = createMessage(msg); + RsGxsMessageId msgId; + RsGxsGroupId grpId = msgItem->meta.mGroupId; + + bool msgDoesnExist = false; + + if(createOk) + { + + GxsMsgReq req; + std::vector msgV; + msgV.push_back(msg->msgId); + GxsMsgMetaResult res; + req.insert(std::make_pair(msg->grpId, msgV)); + mDataStore->retrieveGxsMsgMetaData(req, res); + msgDoesnExist = res[grpId].empty(); + } + + if(createOk && msgDoesnExist) + { + // empty orig msg id means this is the original + // msg + // TODO: a non empty msgid means one should at least + // have the msg on disk, after which this msg is signed + // based on the security settings + // public grp (sign by grp public pub key, private/id: signed by + // id + if(msg->metaData->mOrigMsgId.empty()) + { + msg->metaData->mOrigMsgId = msg->metaData->mMsgId; + } + + // now serialise meta data + size = msg->metaData->serial_size(); + char metaDataBuff[size]; + msg->metaData->serialise(metaDataBuff, &size); + msg->meta.setBinData(metaDataBuff, size); + + msgId = msg->msgId; + grpId = msg->grpId; + mDataAccess->addMsgData(msg); - msgId = msg->msgId; - grpId = msg->grpId; - ok = mDataAccess->addMsgData(msg); - } + // add to published to allow acknowledgement + mMsgNotify.insert(std::make_pair(mit->first, std::make_pair(grpId, msgId))); + mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE); + } + else + { + // delete msg if created wasn't ok + delete msg; + mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED); - // add to published to allow acknowledgement - mMsgNotify.insert(std::make_pair(mit->first, std::make_pair(grpId, msgId))); - mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE); - } - - // if addition failed then delete nxs message - if(!ok) - { #ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::publishMsgs() failed to publish msg " << std::endl; + std::cerr << "RsGenExchange::publishMsgs() failed to publish msg " << std::endl; #endif - mMsgNotify.insert(std::make_pair(mit->first, std::make_pair(RsGxsGroupId(""), RsGxsMessageId("")))); + } + } - continue; - - } - - delete msgItem; // delete msg item as we're done with it + delete[] mData; + delete msgItem; } // clear msg list as we're done publishing them and entries @@ -715,6 +752,29 @@ RsGeneralDataService* RsGenExchange::getDataStore() return mDataStore; } +bool RsGenExchange::getGroupKeys(const RsGxsGroupId &grpId, RsTlvSecurityKeySet &keySet) +{ + if(grpId.empty()) + return false; + + RsStackMutex stack(mGenMtx); + + std::map grpMeta; + grpMeta[grpId] = NULL; + mDataStore->retrieveGxsGrpMetaData(grpMeta); + + if(grpMeta.empty()) + return false; + + RsGxsGrpMetaData* meta = grpMeta[grpId]; + + if(meta == NULL) + return false; + + keySet = meta->keys; + return true; +} + void RsGenExchange::createDummyGroup(RsGxsGrpItem *grpItem) { diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 438251dd1..71f607ca1 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -32,6 +32,7 @@ #include "rsgxs.h" #include "rsgds.h" #include "rsnxs.h" +#include "rsgixs.h" #include "rsgxsdataaccess.h" #include "rsnxsobserver.h" #include "retroshare/rsgxsservice.h" @@ -49,17 +50,17 @@ typedef std::map > GxsMsgMetaMap; * management/publishing/sync features * * Features: \n - * a. Data Access: - * Provided by handle to RsTokenService. This ensure consistency - * of requests and hiearchy of groups -> then messages which are - * sectioned by group ids. - * The one caveat is that redemption of tokens are done through - * the backend of this class - * b. Publishing: - * Methods are provided to publish msg and group items and also make - * changes to meta information of both item types - * c. Sync/Notification: - * Also notifications are made here on receipt of new data from + * a. Data Access: \n + * Provided by handle to RsTokenService. This ensure consistency \n + * of requests and hiearchy of groups -> then messages which are \n + * sectioned by group ids. \n + * The one caveat is that redemption of tokens are done through \n + * the backend of this class \n + * b. Publishing: \n + * Methods are provided to publish msg and group items and also make \n + * changes to meta information of both item types \n + * c. Sync/Notification: \n + * Also notifications are made here on receipt of new data from \n * connected peers */ class RsGenExchange : public RsGxsService, public RsNxsObserver @@ -67,14 +68,17 @@ class RsGenExchange : public RsGxsService, public RsNxsObserver public: /*! - * Constructs a RsGenExchange object, the owner ship of gds, ns, and serviceserialiser passes + * Constructs a RsGenExchange object, the owner ship of gds, ns, and serviceserialiser passes \n * onto the constructed object * @param gds Data service needed to act as store of message * @param ns Network service needed to synchronise data with rs peers * @param serviceSerialiser The users service needs this \n * in order for gen exchange to deal with its data types + * @param mServType This should be service type used by the serialiser + * @param This is used for verification of msgs and groups received by Gen Exchange using identities, set to NULL if \n + * identity verification is not wanted */ - RsGenExchange(RsGeneralDataService* gds, RsNetworkExchangeService* ns, RsSerialType* serviceSerialiser, uint16_t mServType); + RsGenExchange(RsGeneralDataService* gds, RsNetworkExchangeService* ns, RsSerialType* serviceSerialiser, uint16_t mServType, RsGixs* gixs = NULL); virtual ~RsGenExchange(); @@ -204,6 +208,16 @@ protected: */ RsGeneralDataService* getDataStore(); + /*! + * Retrieve keys for a given group, \n + * call is blocking retrieval for underlying db + * @warning under normal circumstance a service should not need this + * @param grpId the id of the group to retrieve keys for + * @param keys this is set to the retrieved keys + * @return false if group does not exist or grpId is empty + */ + bool getGroupKeys(const RsGxsGroupId& grpId, RsTlvSecurityKeySet& keySet); + public: /*! @@ -326,6 +340,7 @@ private: RsGeneralDataService* mDataStore; RsNetworkExchangeService *mNetService; RsSerialType *mSerialiser; + RsGixs* mGixs; std::vector mReceivedMsgs; std::vector mReceivedGrps; diff --git a/libretroshare/src/gxs/rsgixs.h b/libretroshare/src/gxs/rsgixs.h index dcafcb240..316a5e82c 100644 --- a/libretroshare/src/gxs/rsgixs.h +++ b/libretroshare/src/gxs/rsgixs.h @@ -122,7 +122,7 @@ typedef std::string PeerId; /* Identity Interface for GXS Message Verification. */ - +typedef std::string RsGxsId; class RsGixs { public: @@ -180,14 +180,14 @@ public: /*** This Class pulls all the GXS Interfaces together ****/ -class RsGxsIdExchange: public RsGenExchange, public RsGixsReputation, public RsGixs -{ -public: - RsGxsIdExchange(RsGeneralDataService* gds, RsNetworkExchangeService* ns, RsSerialType* serviceSerialiser, uint16_t mServType) - :RsGenExchange(gds,ns,serviceSerialiser,mServType) { return; } -virtual ~RsGxsIdExchange() { return; } +//class RsGxsIdExchange: public RsGenExchange, public RsGixsReputation, public RsGixs +//{ +//public: +// RsGxsIdExchange(RsGeneralDataService* gds, RsNetworkExchangeService* ns, RsSerialType* serviceSerialiser, uint16_t mServType) +// :RsGenExchange(gds,ns,serviceSerialiser,mServType) { return; } +//virtual ~RsGxsIdExchange() { return; } -}; +//}; From 72d3c868e345f4dc6deeb8b24b49f73459e816fe Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 28 Oct 2012 14:10:56 +0000 Subject: [PATCH 106/222] Tweaks to bitdht library for standalone single search option. - Added flag to disable local Network search. - Fixed DHT Msg Rate bug (ported from trunk). git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5731 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libbitdht/src/bitdht/bdmanager.cc | 47 ++++++++++++++++++------------- libbitdht/src/bitdht/bdmanager.h | 2 ++ libbitdht/src/bitdht/bdnode.cc | 6 ++-- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/libbitdht/src/bitdht/bdmanager.cc b/libbitdht/src/bitdht/bdmanager.cc index 16874eb85..719ade599 100644 --- a/libbitdht/src/bitdht/bdmanager.cc +++ b/libbitdht/src/bitdht/bdmanager.cc @@ -87,6 +87,8 @@ bdNodeManager::bdNodeManager(bdNodeId *id, std::string dhtVersion, std::string b mFns->bdPrintNodeId(std::cerr, id); std::cerr << std::endl; #endif + + mLocalNetEnhancements = true; } int bdNodeManager::stopDht() @@ -400,34 +402,39 @@ void bdNodeManager::iteration() std::cerr << std::endl; #endif - /* run a random search for ourselves, from own App DHT peer */ - QueryRandomLocalNet(); + /* This stuff is only important for "LocalNet based Features */ + if (mLocalNetEnhancements) + { + /* run a random search for ourselves, from own App DHT peer */ + QueryRandomLocalNet(); + #define SEARCH_MAX_SIZE 10 - if (mBdNetworkSize < SEARCH_MAX_SIZE) - { -#ifdef DEBUG_MGR - std::cerr << "Local Netsize: " << mBdNetworkSize << " to small...searching"; - std::cerr << std::endl; -#endif - - /* if the network size is very small */ - SearchForLocalNet(); - mSearchingDone = false; - } - else - { - if (!mSearchingDone) + if (mBdNetworkSize < SEARCH_MAX_SIZE) { - mSearchingDone = true; - mSearchTS = now; #ifdef DEBUG_MGR - std::cerr << "Completed LocalNet Search in : " << mSearchTS-mStartTS; + std::cerr << "Local Netsize: " << mBdNetworkSize << " to small...searching"; std::cerr << std::endl; #endif + + /* if the network size is very small */ + SearchForLocalNet(); + mSearchingDone = false; + } + else + { + if (!mSearchingDone) + { + mSearchingDone = true; + mSearchTS = now; +#ifdef DEBUG_MGR + std::cerr << "Completed LocalNet Search in : " << mSearchTS-mStartTS; + std::cerr << std::endl; +#endif + } } } - + #ifdef DEBUG_MGR std::cerr << "bdNodeManager::iteration(): REFRESH "; std::cerr << std::endl; diff --git a/libbitdht/src/bitdht/bdmanager.h b/libbitdht/src/bitdht/bdmanager.h index 635a5eb3f..a43a88342 100644 --- a/libbitdht/src/bitdht/bdmanager.h +++ b/libbitdht/src/bitdht/bdmanager.h @@ -187,6 +187,8 @@ void SearchForLocalNet(); bdBloom mBloomFilter; + bool mLocalNetEnhancements; + /* future node functions */ //addPeerPing(foundId); //clearPing(it->first); diff --git a/libbitdht/src/bitdht/bdnode.cc b/libbitdht/src/bitdht/bdnode.cc index 9e024b03b..b16a28c2d 100644 --- a/libbitdht/src/bitdht/bdnode.cc +++ b/libbitdht/src/bitdht/bdnode.cc @@ -134,14 +134,14 @@ uint32_t bdNode::setNodeDhtMode(uint32_t dhtFlags) { default: case BITDHT_MODE_TRAFFIC_LOW: - mMaxAllowedMsgs = BDNODE_HIGH_MSG_RATE; - break; - case BITDHT_MODE_TRAFFIC_HIGH: mMaxAllowedMsgs = BDNODE_LOW_MSG_RATE; break; case BITDHT_MODE_TRAFFIC_MED: mMaxAllowedMsgs = BDNODE_MED_MSG_RATE; break; + case BITDHT_MODE_TRAFFIC_HIGH: + mMaxAllowedMsgs = BDNODE_HIGH_MSG_RATE; + break; case BITDHT_MODE_TRAFFIC_TRICKLE: mMaxAllowedMsgs = BDNODE_TRICKLE_MSG_RATE; break; From 1a1e453c7e73a96eb47a9bad857df246546ebd2d Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 28 Oct 2012 14:21:58 +0000 Subject: [PATCH 107/222] Modified previous example into a Single Shot Search for RPC support. Takes 2 - 3 minutes to run at the moment. Got to make it faster! git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5732 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libbitdht/src/example/Makefile | 12 +- libbitdht/src/example/bdboot.txt | 1000 ++++++++++++++-------------- libbitdht/src/example/bdexample.cc | 42 -- libbitdht/src/example/bdhandler.cc | 97 ++- libbitdht/src/example/bdhandler.h | 17 + libbitdht/src/example/bssdht.cc | 59 ++ 6 files changed, 674 insertions(+), 553 deletions(-) delete mode 100644 libbitdht/src/example/bdexample.cc create mode 100644 libbitdht/src/example/bssdht.cc diff --git a/libbitdht/src/example/Makefile b/libbitdht/src/example/Makefile index eeb1c8c0b..6b13f2ba4 100644 --- a/libbitdht/src/example/Makefile +++ b/libbitdht/src/example/Makefile @@ -1,16 +1,16 @@ CXXFLAGS = -Wall -g -I.. -CXXFLAGS += -arch i386 # OSX +#CXXFLAGS += -arch i386 # OSX -LIBS = -L../lib -lbitdht +LIBS = -L../lib -lbitdht -lpthread -EXEC : bdexample +EXEC : bssdht -EGOBJ = bdhandler.o bdexample.o +EGOBJ = bdhandler.o bssdht.o -bdexample: $(EGOBJ) - $(CXX) $(CXXFLAGS) -o bdexample $(EGOBJ) $(LIBS) +bssdht: $(EGOBJ) + $(CXX) $(CXXFLAGS) -o bssdht $(EGOBJ) $(LIBS) diff --git a/libbitdht/src/example/bdboot.txt b/libbitdht/src/example/bdboot.txt index 89f27a247..44cf7d127 100644 --- a/libbitdht/src/example/bdboot.txt +++ b/libbitdht/src/example/bdboot.txt @@ -1,500 +1,500 @@ -64.121.80.63 45642 -84.82.225.139 52002 -200.104.218.244 24447 -116.81.147.106 10014 -76.238.231.136 37770 -68.148.109.134 32815 -78.43.60.243 18973 -62.33.209.243 20600 -84.40.115.5 49669 -93.11.108.82 45078 -90.157.139.222 28487 -79.83.184.114 40139 -109.104.187.16 30000 -87.101.162.223 21364 -99.251.104.111 60382 -130.63.133.216 47451 -64.216.32.37 6881 -75.137.149.242 19860 -208.102.25.182 50675 -75.72.144.15 54485 -68.148.20.202 22025 -69.148.177.153 26961 -121.222.5.240 51932 -88.161.156.9 48251 -88.200.104.216 27784 -109.160.52.2 36630 -74.12.101.58 61864 -174.71.75.121 48749 -186.66.255.5 37580 -24.116.239.194 59147 -95.65.178.164 23715 -220.70.175.83 43726 -182.169.110.245 64684 -119.247.164.154 22132 -77.202.227.150 15621 -79.129.217.171 17248 -98.117.197.195 53478 -71.72.3.201 40665 -72.88.206.217 57170 -95.29.8.61 59559 -142.163.161.23 60957 -70.27.27.105 23047 -90.42.104.194 10595 -114.36.7.29 26051 -78.26.164.132 59437 -70.126.197.41 14207 -187.14.3.249 8753 -62.166.34.78 62133 -82.45.213.218 24740 -213.123.71.145 56050 -93.12.188.2 22070 -203.184.0.161 10295 -69.156.209.139 19165 -83.81.119.121 34439 -109.208.211.98 36278 -84.3.208.199 50001 -85.87.98.187 53911 -93.127.107.157 35691 -188.195.145.172 21827 -184.56.151.190 11951 -98.168.190.247 61279 -83.237.221.242 16613 -75.30.79.175 57107 -90.24.61.26 57262 -125.27.132.48 10018 -94.98.122.161 62266 -81.25.50.209 44962 -94.24.137.191 35691 -74.119.191.181 62498 -46.33.237.37 21135 -183.83.30.78 15822 -109.75.207.23 14085 -92.147.163.123 36706 -110.3.132.18 10149 -90.38.163.86 61080 -77.50.87.114 11399 -76.106.47.230 6881 -24.47.46.185 59822 -118.150.145.87 16553 -98.121.178.252 31353 -95.62.64.40 12174 -85.91.17.78 8644 -98.148.37.251 55774 -122.117.82.108 16293 -200.26.143.117 14013 -187.37.80.22 25095 -95.19.224.225 25446 -79.132.4.131 36094 -109.86.136.248 44281 -85.54.187.59 28890 -99.225.92.6 38080 -178.40.89.75 10018 -189.237.151.135 17643 -189.114.233.119 12308 -93.13.211.51 59788 -80.56.69.253 25685 -83.131.224.235 62622 -201.229.9.69 28159 -201.223.65.4 43804 -77.167.196.115 64788 -71.72.158.196 37961 -86.132.129.242 23071 -93.103.167.242 35298 -212.37.169.128 31631 -74.105.104.186 23922 -173.176.243.27 31393 -86.13.110.77 47020 -76.181.24.116 35553 -94.158.107.234 32516 -99.242.143.80 19034 -201.209.54.201 26726 -109.87.52.11 20186 -98.121.161.117 54068 -75.69.6.91 6881 -98.223.44.215 35998 -123.193.220.215 54157 -95.130.12.23 61546 -84.215.125.229 51413 -77.203.179.13 23145 -217.172.179.78 18692 -85.170.52.161 12310 -98.244.158.38 40311 -71.201.200.183 41435 -99.111.202.61 10341 -84.252.27.201 17253 -210.6.173.193 6887 -74.67.142.125 17874 -94.23.212.70 57174 -77.99.18.29 63852 -91.100.81.198 49999 -82.74.117.94 25000 -78.83.127.162 53345 -95.84.255.201 17122 -85.228.78.9 47500 -217.77.60.189 58847 -67.174.74.95 35000 -95.105.198.233 80 -85.238.105.154 40000 -70.114.173.8 26375 -71.100.182.81 21724 -24.9.187.250 29985 -72.204.16.239 50200 -78.94.104.125 63580 -67.83.132.220 51515 -96.52.145.135 12607 -85.187.24.45 14111 -91.148.128.36 24464 -24.186.53.139 61726 -109.110.3.135 57756 -78.159.108.124 63982 -82.244.72.113 10620 -24.16.216.224 45546 -24.60.118.120 60005 -89.135.149.47 52055 -88.191.117.198 46881 -79.108.19.172 52750 -84.24.37.138 15678 -213.93.83.121 51413 -87.50.207.134 60361 -77.120.182.144 30585 -80.109.42.12 29168 -188.230.38.94 32525 -109.86.246.11 11400 -93.72.108.237 39272 -109.160.201.32 27495 -90.214.93.249 25238 -2.106.159.182 28860 -24.49.43.222 26917 -67.215.242.139 6881 -83.83.52.92 10000 -89.161.85.250 27553 -76.20.230.30 58335 -60.62.38.145 22101 -62.148.159.55 52603 -69.123.52.81 64701 -67.215.242.138 6881 -99.225.194.114 45586 -79.124.27.117 26472 -86.10.209.139 12001 -95.181.30.110 37075 -65.5.225.206 6881 -66.110.140.217 6881 -99.112.96.188 35979 -87.120.113.236 18301 -67.162.118.20 9820 -173.51.87.191 37950 -58.69.218.34 38072 -87.120.78.253 25118 -69.137.192.214 6881 -81.57.50.221 11095 -89.212.93.62 32590 -93.152.176.62 6881 -96.250.206.111 20965 -93.72.132.238 47860 -96.20.161.32 44893 -24.235.41.231 11181 -88.80.49.238 35857 -89.215.103.145 16242 -142.162.65.171 30537 -178.162.184.203 6821 -93.182.0.249 32217 -217.208.59.201 46227 -79.132.182.136 30129 -77.70.96.3 11949 -174.59.144.37 5895 -24.206.168.152 22102 -24.64.233.94 17962 -109.168.162.23 32195 -71.53.119.62 23108 -60.241.156.191 24064 -18.242.7.242 65435 -216.113.97.150 29801 -89.133.173.35 37855 -78.82.124.105 20047 -78.128.57.15 22034 -99.54.50.211 64189 -174.118.36.27 60010 -189.120.102.167 63495 -187.1.109.123 20546 -123.193.205.49 22248 -87.48.15.175 52767 -195.145.124.15 33639 -189.34.175.133 1142 -188.16.249.8 10428 -78.96.153.123 10943 -209.188.19.242 61204 -94.208.99.166 13733 -77.70.32.188 9459 -69.134.71.56 10713 -74.213.69.68 17477 -175.137.140.31 18987 -219.79.191.108 35982 -86.129.7.137 21672 -78.225.25.249 10323 -216.195.251.137 41238 -201.6.19.10 64067 -76.101.164.51 20673 -196.221.130.175 18290 -80.192.63.126 59768 -80.177.109.9 34474 -77.243.211.17 40330 -99.179.5.68 55337 -206.63.116.47 47092 -2.83.53.144 14926 -188.25.174.202 26218 -86.28.149.67 39274 -92.133.136.242 41243 -95.28.8.196 39167 -213.231.136.129 13219 -98.237.145.195 46637 -58.165.71.127 25006 -111.252.45.153 25943 -89.29.15.90 56736 -86.171.44.134 57592 -94.59.26.121 36725 -81.191.88.223 54799 -75.81.195.23 22056 -81.109.38.132 31233 -109.121.220.16 10301 -212.92.246.213 22544 -95.158.10.130 13941 -112.118.166.151 45684 -202.154.59.140 43442 -93.181.215.55 46157 -76.217.106.151 62033 -61.227.125.97 13874 -78.58.201.174 28778 -81.231.229.41 19130 -186.10.23.230 37769 -83.254.77.75 17232 -84.110.59.219 62065 -81.98.22.127 47800 -85.17.5.132 51413 -83.55.120.23 42521 -195.18.28.147 35691 -61.202.78.247 22221 -93.80.153.76 48878 -95.29.196.251 61629 -94.75.148.194 24796 -109.194.167.19 47193 -207.216.26.166 36202 -76.186.158.107 56213 -79.118.112.122 26181 -93.115.48.2 16132 -84.32.80.26 6881 -72.198.44.72 31231 -70.162.57.125 48027 -216.162.201.192 17384 -77.49.95.176 45619 -77.47.185.248 15245 -80.185.186.95 10318 -82.200.130.249 58389 -67.162.140.62 29974 -118.168.172.177 27161 -114.51.38.178 23793 -125.175.146.71 17014 -80.66.213.182 64219 -77.50.234.5 25866 -78.90.218.100 49844 -46.118.135.250 58667 -92.80.58.143 14569 -99.253.186.136 43003 -71.60.40.75 41590 -151.11.145.100 18163 -123.237.49.221 17321 -201.130.198.7 56378 -64.219.119.229 53546 -121.118.219.211 6880 -114.32.171.238 6881 -110.33.112.22 7336 -85.58.8.57 59138 -77.70.70.8 19445 -178.140.72.96 33178 -78.166.69.33 40531 -211.24.149.162 39719 -62.16.162.73 50001 -95.84.244.177 33076 -46.118.71.243 57944 -91.139.194.92 24902 -77.248.205.101 58849 -83.152.236.85 46613 -41.236.189.5 11493 -94.26.63.5 29973 -189.100.145.169 45441 -84.202.146.45 32122 -183.179.108.42 15833 -78.247.112.51 48465 -95.102.42.122 6881 -89.185.199.69 49879 -74.129.254.238 21830 -99.181.161.222 27636 -96.235.14.144 40928 -189.71.180.71 18172 -96.54.129.2 26085 -222.141.53.49 16006 -121.184.217.130 21563 -84.3.111.252 51111 -79.103.174.69 40190 -89.139.35.26 45625 -62.215.144.191 33078 -75.27.19.0 42707 -83.192.127.87 10785 -99.174.215.236 51128 -78.36.180.6 33016 -92.101.222.111 42441 -85.91.17.59 14091 -24.14.120.77 11682 -188.26.55.161 13650 -77.37.133.138 63572 -117.199.5.229 28835 -66.231.126.16 53509 -151.68.147.67 38146 -86.28.168.196 52549 -95.208.206.96 24833 -99.36.177.82 57416 -82.19.43.141 50274 -88.243.226.34 31952 -89.117.4.177 9026 -92.62.81.2 11369 -124.103.179.186 15356 -62.182.72.252 56899 -195.174.137.55 10152 -220.77.252.33 64170 -84.28.164.197 38804 -92.247.230.190 56889 -77.255.188.154 50182 -188.52.90.206 62502 -58.99.68.183 16001 -81.166.131.74 49856 -84.72.160.67 21783 -61.58.164.40 61726 -121.3.76.229 24859 -119.188.12.17 16003 -109.194.148.235 35691 -89.152.22.150 54895 -79.169.181.30 15368 -71.229.7.56 63792 -85.152.185.205 37976 -72.179.54.146 62040 -188.168.19.251 33178 -62.42.136.67 14957 -95.104.224.245 55165 -68.148.68.46 61984 -122.3.9.39 62546 -121.222.50.109 33067 -212.7.27.71 59005 -41.233.123.170 57369 -85.69.170.120 44386 -83.209.26.106 57404 -79.114.213.111 41823 -72.139.120.43 64593 -220.235.102.85 40329 -189.114.35.172 9884 -213.89.205.22 51413 -206.45.53.201 6881 -95.93.140.179 58457 -86.212.236.62 41939 -64.120.217.48 6821 -24.192.141.196 43444 -98.111.205.18 38107 -72.70.248.25 50824 -93.80.95.102 6882 -78.161.215.48 1024 -92.46.27.57 32582 -109.185.14.134 10020 -76.10.184.99 48754 -59.129.24.10 12345 -79.167.72.16 24971 -76.69.58.83 33258 -212.75.11.116 18431 -91.111.73.116 60521 -188.177.32.124 25573 -70.119.124.175 32302 -93.141.74.98 25058 -24.113.236.144 28024 -76.22.33.148 47355 -84.38.176.176 59787 -90.3.48.40 52585 -89.72.89.197 19610 -204.191.41.127 23927 -221.217.45.24 47709 -74.137.200.28 6112 -84.1.255.253 39168 -90.230.207.166 64697 -109.195.179.25 49034 -213.7.173.150 27444 -113.190.35.133 26298 -219.71.14.70 20000 -188.26.238.55 12082 -188.126.90.189 42521 -92.152.222.207 60086 -94.41.126.183 35691 -92.124.18.175 7691 -121.84.53.235 36421 -114.181.232.144 14859 -87.126.166.37 23145 -79.136.38.51 61193 -79.136.29.76 64123 -91.203.188.89 31780 -173.70.56.200 34107 -69.112.65.152 26394 -122.168.6.130 36327 -124.24.226.162 8640 -178.164.171.162 38624 -92.241.245.68 47765 -99.99.66.212 23188 -211.38.161.183 41794 -95.153.168.28 8033 -114.77.55.185 14890 -114.41.140.117 11675 -66.41.250.122 26560 -66.131.96.98 9090 -95.42.148.127 21982 -217.172.183.163 6881 -78.56.249.219 11699 -82.209.126.232 49180 -74.129.176.196 18957 -119.246.185.40 25295 -87.207.245.56 14132 -86.205.109.156 9739 -92.239.247.56 39166 -24.9.173.223 61423 -80.54.16.78 14221 -173.58.23.148 56221 -174.93.222.175 58944 -83.188.251.214 37857 -96.242.15.74 31666 -71.56.126.209 50316 -178.46.224.6 61397 -203.121.129.35 48913 -78.107.255.16 6884 -178.30.150.171 49763 -97.118.36.234 28186 -58.179.125.192 62734 -92.28.78.203 14274 -80.219.210.106 56365 -89.38.197.172 27077 -201.226.156.70 16668 -183.191.171.160 4041 -95.233.192.118 52630 -94.253.81.217 52858 -189.98.226.168 54960 -93.103.210.87 35228 -109.86.255.184 6881 -200.120.232.126 42476 -80.56.123.123 15541 -81.234.102.107 18764 -89.253.109.172 31844 -122.166.49.234 16842 -188.27.102.215 33333 -212.233.236.87 1041 -79.165.176.206 39053 -109.171.12.85 51441 -178.94.111.98 59615 -94.112.39.248 7289 -125.134.85.142 21707 -46.33.245.141 45822 -217.23.176.216 58252 -154.5.172.67 23127 -126.12.49.142 23120 +213.200.49.94 49729 +78.106.255.53 33010 +176.52.10.54 6881 +178.89.155.147 6881 +125.14.197.62 14856 +218.77.193.68 16001 +86.149.90.0 63079 +24.132.253.237 16107 +85.54.115.28 30782 +79.136.30.100 63177 +89.136.253.72 32789 +109.254.115.106 46229 +89.120.65.238 63900 +79.164.94.231 8093 +109.195.107.54 6881 +109.60.234.178 60562 +182.218.241.146 32308 +188.16.212.171 6881 +213.85.86.61 6881 +117.220.183.198 48158 +125.137.92.58 45682 +122.80.243.249 16001 +123.165.178.125 9371 +85.64.42.90 46866 +91.241.136.195 48137 +178.217.52.84 20801 +46.233.208.225 14158 +37.79.136.74 35691 +109.252.88.7 61862 +119.166.13.162 57726 +95.25.120.195 6881 +109.88.60.207 37375 +77.66.244.147 6881 +176.77.24.252 35691 +78.25.175.94 39012 +109.194.253.133 19755 +195.169.226.124 51413 +90.151.219.90 6881 +93.124.15.169 22826 +90.39.156.179 21066 +89.222.164.65 28505 +91.146.55.126 15984 +46.0.142.177 65116 +188.186.105.35 6881 +212.21.3.78 6881 +94.190.76.151 61998 +90.150.121.152 6881 +188.234.162.195 6881 +212.87.184.183 18025 +95.105.53.122 10022 +109.110.233.223 63596 +46.149.234.13 6881 +92.112.33.50 17016 +188.244.159.76 6881 +109.226.65.214 30220 +89.204.37.237 6881 +81.182.61.244 62762 +31.23.11.165 23690 +92.112.227.98 16020 +188.173.249.241 10649 +65.28.74.168 16111 +108.252.61.27 30097 +67.164.44.138 1025 +112.136.180.195 28478 +61.31.128.123 11708 +203.202.219.105 26397 +85.180.71.212 28824 +85.17.30.203 51721 +194.44.93.49 41558 +79.115.140.239 6881 +212.57.143.230 64209 +213.57.220.71 54355 +188.25.152.209 38685 +24.215.90.104 50000 +85.173.79.113 43424 +69.254.137.136 59805 +95.21.157.21 38284 +91.66.234.126 45618 +69.81.91.160 36510 +37.11.69.120 21518 +82.251.167.100 27364 +178.95.174.115 27719 +71.95.96.165 30732 +109.222.228.8 31901 +24.192.64.18 48809 +50.72.178.188 44692 +69.76.203.21 60466 +82.234.232.63 22112 +199.21.113.184 64103 +89.80.119.247 57369 +88.72.174.111 9023 +86.29.84.7 56010 +79.47.210.148 15421 +92.144.216.198 61409 +81.64.209.233 6262 +86.70.194.6 8000 +178.83.6.65 6881 +83.246.219.62 12485 +95.73.12.140 56350 +188.190.58.2 27739 +92.252.210.194 10000 +94.23.49.143 8000 +199.127.250.15 29015 +78.119.199.7 55227 +82.242.173.60 48585 +108.207.210.177 17312 +81.101.178.26 36319 +86.126.203.68 10566 +178.223.153.97 23683 +218.111.12.128 59991 +74.132.175.138 63239 +24.239.251.33 55679 +77.9.88.33 8812 +86.105.83.234 64836 +78.26.200.70 53675 +109.126.218.243 49001 +178.120.24.237 23854 +5.164.220.86 46394 +83.165.232.251 11618 +176.14.184.224 47779 +37.229.58.159 25397 +89.112.45.232 51413 +71.227.228.178 59982 +94.8.63.12 21695 +178.83.119.5 6881 +213.109.4.140 35063 +174.66.162.145 19398 +189.4.72.127 43453 +112.203.4.67 15817 +178.216.101.214 54537 +79.134.52.11 52512 +192.162.43.69 45684 +85.240.205.157 18883 +188.232.238.194 59524 +123.110.8.223 15666 +61.19.218.36 50115 +83.215.168.25 64268 +80.2.83.216 16532 +188.124.72.59 32042 +89.46.178.134 39707 +202.177.248.237 51359 +88.174.176.173 56969 +50.98.183.171 47301 +85.59.136.223 43831 +188.190.69.190 40122 +82.155.56.186 20870 +109.9.102.56 16279 +220.245.18.37 7952 +24.53.148.27 20698 +88.156.186.185 51413 +68.101.70.42 48176 +108.38.11.220 57600 +99.102.20.107 34921 +112.186.84.12 30224 +89.3.61.74 63799 +46.72.18.191 38514 +85.142.195.67 6881 +201.24.196.143 21263 +88.72.174.111 14804 +141.84.252.30 6881 +93.218.175.120 47467 +83.134.21.238 39471 +81.229.168.10 32995 +88.170.61.126 7465 +83.254.77.158 22722 +78.94.71.48 51091 +94.45.103.205 23560 +46.119.32.172 40356 +37.204.127.80 34869 +78.53.125.16 1451 +91.219.249.72 6881 +2.60.134.63 42890 +188.195.233.196 7971 +109.209.82.52 1064 +80.217.87.125 47610 +92.151.189.10 41785 +71.237.6.246 41304 +176.15.199.156 35691 +37.14.117.203 24956 +188.165.245.29 62201 +31.192.204.87 36504 +217.73.165.50 65165 +78.126.57.136 29452 +95.16.39.183 51413 +68.229.157.53 20538 +24.15.208.182 19353 +178.72.76.27 10693 +49.204.188.72 15546 +74.172.229.212 9518 +126.11.175.228 46373 +60.181.173.66 16001 +71.245.169.177 43766 +96.55.113.202 17765 +77.31.69.213 16975 +14.192.149.235 14523 +116.114.184.23 16001 +46.73.180.200 57274 +109.167.205.91 17782 +109.248.165.232 29068 +37.112.101.205 12115 +67.193.153.219 61956 +84.109.194.47 46742 +188.24.75.81 63815 +223.98.124.220 16001 +90.56.104.115 11101 +81.190.219.203 14573 +89.99.220.211 6881 +78.129.47.89 25456 +72.89.174.47 49559 +66.169.55.105 10610 +178.129.164.236 6881 +99.164.69.36 44396 +121.182.147.191 62483 +46.214.22.165 20056 +90.196.26.145 62421 +109.110.147.6 51158 +93.152.154.146 63760 +111.253.207.38 16001 +125.27.214.216 44366 +77.243.107.6 8392 +83.128.123.13 22300 +62.80.235.202 39059 +178.120.2.179 18001 +204.11.130.66 6881 +178.122.94.160 10024 +142.167.185.66 51623 +72.84.241.61 23793 +95.29.249.76 6881 +77.41.8.139 6881 +109.165.86.68 6881 +109.111.3.95 42832 +89.222.164.39 17108 +86.198.46.107 64700 +46.0.195.115 6881 +217.123.236.239 59665 +88.206.83.163 6881 +2.217.94.215 62479 +85.27.36.125 3675 +94.23.55.33 33530 +89.222.164.74 8750 +213.111.210.47 44581 +75.158.101.190 59340 +80.184.122.10 15829 +81.235.246.100 57582 +5.187.78.80 50811 +93.74.114.37 33017 +24.30.83.45 54662 +121.187.196.166 61829 +87.97.70.95 59216 +92.101.49.41 15939 +177.132.219.232 52537 +217.15.129.218 15808 +116.14.132.15 56063 +76.177.90.141 36194 +88.90.45.47 58649 +77.57.165.254 6881 +80.98.76.72 43577 +78.30.207.121 16466 +109.89.22.180 30439 +68.190.74.32 22007 +36.236.16.67 16001 +114.163.214.158 11302 +2.97.93.187 57692 +94.253.39.133 6881 +79.139.88.71 10208 +59.126.161.235 42539 +81.234.255.202 56118 +117.200.86.161 53208 +31.46.125.31 18045 +82.243.71.203 65432 +78.224.185.52 56621 +76.204.112.132 6890 +93.223.130.30 32417 +87.223.168.225 26656 +173.73.46.92 52828 +178.202.38.237 40068 +109.14.228.2 6969 +95.157.142.198 64123 +220.245.1.193 64765 +62.227.10.103 19379 +192.228.212.170 21654 +66.197.135.74 9870 +37.221.132.150 22894 +94.21.58.12 38698 +188.176.186.181 18273 +188.190.155.210 4455 +108.252.160.139 42007 +94.23.204.135 30392 +63.245.169.145 33247 +93.96.38.245 6881 +31.45.22.161 35225 +77.222.31.52 59415 +96.42.167.80 52280 +190.196.105.132 14079 +117.201.208.178 10171 +187.104.231.26 33447 +68.42.14.214 23361 +67.167.214.225 63185 +24.138.59.223 55955 +111.242.33.86 23406 +125.30.116.231 18391 +123.23.70.154 10075 +78.229.90.129 32138 +69.112.56.177 44811 +31.16.41.107 7627 +92.141.209.132 15734 +79.118.37.244 40171 +66.49.128.103 51413 +178.90.62.99 10000 +178.157.237.100 6881 +91.178.167.101 30268 +206.248.183.2 51413 +93.86.246.79 12180 +109.193.181.26 17836 +90.224.116.7 33923 +37.144.199.41 32118 +89.123.71.101 10982 +112.204.163.100 13292 +125.24.197.213 11698 +46.63.180.70 54251 +217.210.112.89 20503 +213.64.227.205 18926 +123.203.151.250 56045 +114.37.64.184 25431 +86.8.232.198 47955 +213.181.202.91 51413 +37.229.225.109 24351 +2.33.68.167 45682 +88.222.217.56 46421 +90.208.116.214 55538 +2.124.113.120 51413 +211.228.97.32 11160 +85.67.228.231 33392 +93.116.242.153 33116 +94.51.121.80 59150 +113.171.86.250 10000 +5.159.110.99 26947 +58.7.253.60 38684 +91.229.20.68 6881 +91.179.116.59 17040 +117.195.47.150 49441 +42.98.29.129 22491 +85.167.147.174 34182 +82.242.149.9 25108 +85.108.197.61 29286 +95.56.72.49 14451 +83.150.118.223 7200 +83.246.191.21 6881 +82.49.66.69 26973 +50.53.84.14 47235 +88.212.37.175 40585 +84.55.102.97 49909 +82.168.130.135 56755 +46.173.90.211 6881 +109.169.54.139 51415 +114.34.93.180 20810 +99.231.123.139 47345 +125.212.120.5 21305 +109.128.196.245 51413 +176.215.30.14 28689 +98.30.187.130 21000 +75.73.136.19 62765 +212.19.133.88 13525 +108.202.164.27 51413 +2.49.208.236 46064 +116.51.131.3 47451 +78.155.189.90 22557 +2.3.154.124 43411 +46.251.69.224 11789 +85.138.161.222 28829 +94.181.133.210 35691 +41.69.137.231 13336 +49.48.231.206 64581 +82.7.153.234 39772 +94.113.125.164 27426 +75.48.224.72 51413 +176.103.81.177 52440 +37.218.152.141 24385 +221.149.52.79 11254 +213.114.77.51 61820 +178.22.225.30 11104 +92.84.81.34 57407 +93.146.94.221 19306 +171.116.86.165 16001 +101.63.130.19 48832 +85.84.221.4 19153 +79.126.54.102 37807 +74.77.92.19 51413 +46.108.138.39 25884 +92.247.220.203 25527 +89.20.124.41 6881 +99.189.14.81 43179 +211.193.20.248 25381 +223.228.164.49 18616 +95.140.222.179 55740 +78.149.21.10 46511 +87.89.35.111 41473 +46.2.98.125 26797 +71.201.85.238 63526 +83.143.127.228 51413 +89.142.117.227 60538 +109.198.205.30 49001 +92.126.225.35 10022 +62.57.253.96 49665 +106.160.49.230 58911 +89.92.176.225 51413 +81.202.66.247 27326 +85.165.20.74 37250 +95.220.228.216 57575 +94.211.208.25 16881 +211.28.147.189 30748 +46.50.162.228 6881 +122.116.89.184 59116 +110.93.91.8 38100 +84.248.75.232 63001 +79.165.148.92 61137 +88.132.54.10 62580 +180.224.43.232 63573 +79.82.223.182 29297 +78.7.87.150 28643 +67.235.141.60 19894 +27.190.132.73 4245 +93.123.197.174 58547 +89.216.145.187 1055 +68.46.237.222 34912 +69.181.68.72 60496 +107.193.240.30 51276 +89.148.6.32 54889 +92.112.84.248 10007 +194.44.21.96 58530 +93.116.77.214 10035 +37.79.42.73 32840 +64.218.114.247 60600 +95.178.198.186 28243 +99.137.237.26 49238 +112.134.68.224 10008 +89.41.56.250 15440 +86.205.207.176 56623 +60.220.85.253 13569 +109.174.114.124 3725 +89.23.163.173 19575 +79.119.183.29 52107 +59.66.110.93 27589 +78.105.105.87 42127 +95.69.207.44 35691 +72.200.187.124 48593 +178.123.203.73 6881 +77.35.153.182 16318 +201.22.70.49 12947 +80.236.120.181 14451 +222.212.42.236 6107 +85.25.110.34 62453 +86.24.133.104 42572 +82.126.184.158 31323 +95.154.177.131 19995 +1.22.41.112 37043 +74.190.24.27 11742 +70.123.139.33 45645 +67.78.205.194 5007 +208.101.109.128 53329 +184.99.81.210 65160 +24.30.119.63 46448 +84.10.80.103 512 +95.58.107.250 58280 +213.113.242.33 11761 +95.58.198.83 19786 +187.34.104.235 23609 +61.51.62.143 43220 +2.122.203.188 34936 +95.29.127.137 9000 +85.176.27.50 60583 +178.185.5.228 10048 +189.110.211.69 52748 +212.231.247.212 18744 +212.253.173.114 57417 +69.157.252.118 63494 +95.108.119.185 46830 +213.112.21.57 27077 +95.79.173.173 42349 +76.121.182.77 54059 +70.177.183.134 62354 +92.124.7.63 26804 +176.43.91.144 55976 +220.135.191.36 13894 +78.230.236.178 51528 +194.213.106.70 49001 +176.110.229.36 13664 +178.88.53.243 19564 +124.169.108.217 34547 +109.104.173.57 19454 +70.179.13.236 40021 +109.209.193.34 37721 +2.90.14.222 21661 +79.131.212.125 16844 +142.68.216.103 20804 +123.238.67.137 16515 +50.13.6.176 23275 +58.170.3.84 34130 +91.122.18.146 49001 +76.116.68.100 53034 diff --git a/libbitdht/src/example/bdexample.cc b/libbitdht/src/example/bdexample.cc deleted file mode 100644 index 0c965eabd..000000000 --- a/libbitdht/src/example/bdexample.cc +++ /dev/null @@ -1,42 +0,0 @@ - - -#include "bitdht/bdiface.h" -#include "bitdht/bdstddht.h" -#include "bdhandler.h" - -int main(int argc, char **argv) -{ - - /* startup dht : with a random id! */ - bdNodeId ownId; - bdStdRandomNodeId(&ownId); - - uint16_t port = 6775; - std::string appId = "exId"; - std::string bootstrapfile = "bdboot.txt"; - - BitDhtHandler dht(&ownId, port, appId, bootstrapfile); - - /* run your program */ - while(1) - { - bdNodeId searchId; - bdStdRandomNodeId(&searchId); - - dht.FindNode(&searchId); - - sleep(180); - - dht.DropNode(&searchId); - } - - return 1; -} - - - - - - - - diff --git a/libbitdht/src/example/bdhandler.cc b/libbitdht/src/example/bdhandler.cc index faa6afb88..d1b1288af 100644 --- a/libbitdht/src/example/bdhandler.cc +++ b/libbitdht/src/example/bdhandler.cc @@ -28,8 +28,24 @@ #include #include +#include + #include "bdhandler.h" + +/**** + * This example bitdht app is designed to perform a single shot DHT search. + * Ww want to minimise the dht work, and number of UDP packets sent. + * + * This means we need to add: + * - don't search for App network. (libbitdht option) + * - don't bother filling up Space. (libbitdht option) + * - Programmatically add bootstrap peers. (libbitdht option) + * + */ + + + /* This is a conversion callback class */ @@ -110,6 +126,11 @@ BitDhtHandler::BitDhtHandler(bdNodeId *ownId, uint16_t port, std::string appId, mUdpBitDht->start(); /* starts up the bitdht thread */ + /* setup best mode for quick search */ + uint32_t dhtFlags = BITDHT_MODE_TRAFFIC_MED | BITDHT_MODE_RELAYSERVERS_IGNORED; + mUdpBitDht->setDhtMode(dhtFlags); + mUdpBitDht->setAttachMode(false); + /* switch on the dht too */ mUdpBitDht->startDht(); } @@ -162,8 +183,19 @@ bool BitDhtHandler::FindNode(bdNodeId *peerId) bdStdPrintNodeId(std::cerr, peerId); std::cerr << ")" << std::endl; + + BssResult res; + res.id.id = *peerId; + res.mode = BSS_SINGLE_SHOT; + res.status = 0; + + { + bdStackMutex stack(resultsMtx); /********** MUTEX LOCKED *************/ + mSearchNodes[*peerId] = res; + } + /* add in peer */ - mUdpBitDht->addFindNode(peerId, BITDHT_QFLAGS_DO_IDLE); + mUdpBitDht->addFindNode(peerId, BITDHT_QFLAGS_DISGUISE); return true ; } @@ -178,10 +210,50 @@ bool BitDhtHandler::DropNode(bdNodeId *peerId) /* remove in peer */ mUdpBitDht->removeFindNode(peerId); + bdStackMutex stack(resultsMtx); /********** MUTEX LOCKED *************/ + + /* find the node from our list */ + std::map::iterator it; + it = mSearchNodes.find(*peerId); + if (it != mSearchNodes.end()) + { + std::cerr << "BitDhtHandler::DropNode() Found NodeId, removing"; + std::cerr << std::endl; + + mSearchNodes.erase(it); + } return true ; } +bool BitDhtHandler::SearchResult(bdId *id, uint32_t &status) +{ + bdStackMutex stack(resultsMtx); /********** MUTEX LOCKED *************/ + + /* find the node from our list */ + std::map::iterator it; + it = mSearchNodes.find(id->id); + if (it != mSearchNodes.end()) + { + if (it->second.status != 0) + { + std::cerr << "BitDhtHandler::SearchResults() Found Results"; + std::cerr << std::endl; + status = it->second.status; + *id = it->second.id; + return true; + } + + std::cerr << "BitDhtHandler::SearchResults() No Results Yet"; + std::cerr << std::endl; + return false; + } + + std::cerr << "BitDhtHandler::SearchResults() ERROR: No Search Entry"; + std::cerr << std::endl; + return false; +} + /********************** Callback Functions **************************/ @@ -203,6 +275,20 @@ int BitDhtHandler::PeerCallback(const bdId *id, uint32_t status) bdStdPrintId(std::cerr, id); std::cerr << std::endl; + bdStackMutex stack(resultsMtx); /********** MUTEX LOCKED *************/ + + /* find the node from our list */ + std::map::iterator it; + it = mSearchNodes.find(id->id); + if (it == mSearchNodes.end()) + { + std::cerr << "BitDhtHandler::PeerCallback() Unknown NodeId !!! "; + std::cerr << std::endl; + + return 1; + } + it->second.status = status; + bool connect = false; switch(status) { @@ -211,6 +297,7 @@ int BitDhtHandler::PeerCallback(const bdId *id, uint32_t status) std::cerr << "BitDhtHandler::PeerCallback() QUERY FAILURE ... do nothin "; std::cerr << std::endl; + break; case BITDHT_MGR_QUERY_PEER_OFFLINE: @@ -224,19 +311,19 @@ int BitDhtHandler::PeerCallback(const bdId *id, uint32_t status) case BITDHT_MGR_QUERY_PEER_UNREACHABLE: /* do nothing */ - std::cerr << "BitDhtHandler::PeerCallback() QUERY PEER UNREACHABLE ... flag? / do nothin "; + std::cerr << "BitDhtHandler::PeerCallback() QUERY PEER UNREACHABLE ... saving address "; std::cerr << std::endl; - + it->second.id = *id; break; case BITDHT_MGR_QUERY_PEER_ONLINE: /* do something */ - std::cerr << "BitDhtHandler::PeerCallback() QUERY PEER ONLINE ... try udp connection"; + std::cerr << "BitDhtHandler::PeerCallback() QUERY PEER ONLINE ... saving address"; std::cerr << std::endl; - connect = true; + it->second.id = *id; break; } return 1; diff --git a/libbitdht/src/example/bdhandler.h b/libbitdht/src/example/bdhandler.h index e2ad55dc8..c0c942db6 100644 --- a/libbitdht/src/example/bdhandler.h +++ b/libbitdht/src/example/bdhandler.h @@ -37,6 +37,18 @@ /*** This class can be overloaded to use the XXXXCallback() Functions *****/ class BitDhtIntCallback; + +class BssResult +{ + public: + bdId id; + uint32_t mode; // single shot + uint32_t status; // SEARCHING, FAILURE, FOUND, MULTIPLE HITS. +}; + +#define BSS_SINGLE_SHOT 0x0001 + + class BitDhtHandler { @@ -58,12 +70,17 @@ virtual int NodeCallback(const bdId *id, uint32_t peerflags); virtual int PeerCallback(const bdId *id, uint32_t status); virtual int ValueCallback(const bdNodeId *id, std::string key, uint32_t status); +bool SearchResult(bdId *id, uint32_t &status); + private: /* real DHT classes */ UdpStack *mStack; UdpBitDht *mUdpBitDht; + bdMutex resultsMtx; /* for all class data (below) */ + + std::map mSearchNodes; }; diff --git a/libbitdht/src/example/bssdht.cc b/libbitdht/src/example/bssdht.cc new file mode 100644 index 000000000..b1d1e7bb3 --- /dev/null +++ b/libbitdht/src/example/bssdht.cc @@ -0,0 +1,59 @@ + + +#include "bitdht/bdiface.h" +#include "bitdht/bdstddht.h" +#include "bdhandler.h" + +int main(int argc, char **argv) +{ + + /* startup dht : with a random id! */ + bdNodeId ownId; + bdStdRandomNodeId(&ownId); + + uint16_t port = 6775; + std::string appId = "bsId"; + std::string bootstrapfile = "bdboot.txt"; + + BitDhtHandler dht(&ownId, port, appId, bootstrapfile); + + /* install search node */ + bdNodeId searchId; + bdStdRandomNodeId(&searchId); + + std::cerr << "bssdht: searching for Id: "; + bdStdPrintNodeId(std::cerr, &searchId); + std::cerr << std::endl; + + dht.FindNode(&searchId); + + /* run your program */ + bdId resultId; + uint32_t status; + + resultId.id = searchId; + + while(false == dht.SearchResult(&resultId, status)) + { + sleep(10); + } + + std::cerr << "bssdht: Found Result:" << std::endl; + + std::cerr << "\tId: "; + bdStdPrintId(std::cerr, &resultId); + std::cerr << std::endl; + + std::cerr << "\tstatus: " << status; + std::cerr << std::endl; + + return 1; +} + + + + + + + + From d208b59d33af656dd845c72d7e4750c656d91b6c Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 28 Oct 2012 16:51:00 +0000 Subject: [PATCH 108/222] Split the upnp files into libupnp and miniupnp implementations. modified libretroshare.pro to allow either to be used. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5733 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/libretroshare.pro | 57 ++- libretroshare/src/rsserver/rsinit.cc | 6 +- libretroshare/src/upnp/upnphandler_linux.cc | 431 +++++++++++++++++ libretroshare/src/upnp/upnphandler_linux.h | 78 ++++ ...upnphandler.cc => upnphandler_miniupnp.cc} | 437 ------------------ .../{upnphandler.h => upnphandler_miniupnp.h} | 93 +--- 6 files changed, 547 insertions(+), 555 deletions(-) create mode 100644 libretroshare/src/upnp/upnphandler_linux.cc create mode 100644 libretroshare/src/upnp/upnphandler_linux.h rename libretroshare/src/upnp/{upnphandler.cc => upnphandler_miniupnp.cc} (53%) rename libretroshare/src/upnp/{upnphandler.h => upnphandler_miniupnp.h} (50%) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index f7d08313e..7b0bf9a71 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -154,15 +154,11 @@ HEADERS += retroshare/rsgame.h \ OBJECTS_DIR = temp/obj MOC_DIR = temp/moc DESTDIR = lib - - # miniupnp implementation files - #HEADERS += upnp/upnputil.h - #SOURCES += upnp/upnputil.c + + # linux/bsd can use either - libupnp is more complete and packaged. + #CONFIG += upnp_miniupnpc + CONFIG += upnp_libupnp - # libupnp implementation files - HEADERS += upnp/UPnPBase.h - SOURCES += upnp/UPnPBase.cpp - # zeroconf disabled at the end of libretroshare.pro (but need the code) #CONFIG += zeroconf #CONFIG += zcnatassist @@ -192,9 +188,8 @@ HEADERS += retroshare/rsgame.h \ DEFINES *= STATICLIB \ WIN32 - # miniupnp implementation files - HEADERS += upnp/upnputil.h - SOURCES += upnp/upnputil.c + CONFIG += upnp_miniupnpc + SSL_DIR = ../../../../openssl UPNPC_DIR = ../../../../miniupnpc-1.3 GPG_ERROR_DIR = ../../../../libgpg-error-1.7 @@ -230,9 +225,8 @@ HEADERS += retroshare/rsgame.h \ # QMAKE_CFLAGS_DEBUG += -O2 DEFINES += USE_CMD_ARGS - # miniupnp implementation files - HEADERS += upnp/upnputil.h - SOURCES += upnp/upnputil.c + CONFIG += upnp_libupnp + UPNPC_DIR = ../../../lib/miniupnpc-1.3 PTHREADS_DIR = ../../../lib/pthreads-w32-2-8-0-release ZLIB_DIR = ../../../lib/zlib-1.2.3 @@ -261,10 +255,8 @@ HEADERS += retroshare/rsgame.h \ # DEFINES *= MINIUPNPC_VERSION=13 DESTDIR = lib - # miniupnp implementation files - HEADERS += upnp/upnputil.h - SOURCES += upnp/upnputil.c - + CONFIG += upnp_miniupnpc + # zeroconf disabled at the end of libretroshare.pro (but need the code) CONFIG += zeroconf CONFIG += zcnatassist @@ -296,9 +288,13 @@ HEADERS += retroshare/rsgame.h \ -Dstatvfs64=statvfs \ -Dfopen64=fopen + # linux/bsd can use either - libupnp is more complete and packaged. + #CONFIG += upnp_miniupnpc + CONFIG += upnp_libupnp + # libupnp implementation files - HEADERS += upnp/UPnPBase.h - SOURCES += upnp/UPnPBase.cpp + HEADERS += upnp/UPnPBase.h upnp/upnphandler_linux.h + SOURCES += upnp/UPnPBase.cpp upnp/upnphandler_linux.cc DESTDIR = lib } @@ -417,7 +413,7 @@ HEADERS += retroshare/rsgame.h \ HEADERS += turtle/p3turtle.h \ turtle/rsturtleitem.h \ turtle/turtletypes.h - HEADERS += upnp/upnphandler.h + HEADERS += util/folderiterator.h \ util/rsdebug.h \ util/smallobject.h \ @@ -434,6 +430,7 @@ HEADERS += retroshare/rsgame.h \ util/rsrandom.h \ util/radix64.h \ util/pugiconfig.h + SOURCES += dbase/cachestrapper.cc \ dbase/fimonitor.cc \ dbase/findex.cc \ @@ -549,7 +546,7 @@ HEADERS += retroshare/rsgame.h \ # turtle/turtlerouting.cc \ # turtle/turtlesearch.cc \ # turtle/turtletunnels.cc - SOURCES += upnp/upnphandler.cc + SOURCES += util/folderiterator.cc \ util/rsdebug.cc \ util/smallobject.cc \ @@ -564,6 +561,18 @@ HEADERS += retroshare/rsgame.h \ util/rsversion.cc \ util/rswin.cc \ util/rsrandom.cc + + upnp_miniupnpc { + HEADERS += upnp/upnputil.h upnp/upnphandler_miniupnp.h + SOURCES += upnp/upnputil.c upnp/upnphandler_miniupnp.cc + } + + upnp_libupnp { + HEADERS += upnp/UPnPBase.h upnp/upnphandler_linux.h + SOURCES += upnp/UPnPBase.cpp upnp/upnphandler_linux.cc + DEFINES *= RS_USE_LIBUPNP + } + zeroconf { HEADERS += zeroconf/p3zeroconf.h SOURCES += zeroconf/p3zeroconf.cc @@ -600,7 +609,6 @@ HEADERS += retroshare/rsgame.h \ util/contentvalue.h \ gxs/gxscoreserver.h \ gxs/gxssecurity.h \ - gxs/gxssecurity.h \ gxs/rsgxsifaceimpl.h \ services/p3posted.h \ retroshare/rsposted.h \ @@ -620,7 +628,6 @@ HEADERS += retroshare/rsgame.h \ util/contentvalue.cc \ gxs/gxscoreserver.cc \ gxs/gxssecurity.cc \ - gxs/gxssecurity.cc \ gxs/rsgxsifaceimpl.cc \ services/p3posted.cc \ serialiser/rsposteditems.cc @@ -631,7 +638,7 @@ HEADERS += retroshare/rsgame.h \ services/p3idservice.h \ serialiser/rsgxsiditems.h - SOURCES += services/p3idservice.cc + #SOURCES += services/p3idservice.cc # serialiser/rsgxsiditems.cc \ # Wiki Service diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 7510041c1..09508e322 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1795,7 +1795,11 @@ RsTurtle *rsTurtle = NULL ; #ifdef RS_ENABLE_ZCNATASSIST #include "zeroconf/p3zcnatassist.h" #else - #include "upnp/upnphandler.h" + #ifdef RS_USE_LIBUPNP + #include "upnp/upnphandler_linux.h" + #else + #include "upnp/upnphandler_miniupnp.h" + #endif #endif #include "services/p3disc.h" diff --git a/libretroshare/src/upnp/upnphandler_linux.cc b/libretroshare/src/upnp/upnphandler_linux.cc new file mode 100644 index 000000000..5d54b5581 --- /dev/null +++ b/libretroshare/src/upnp/upnphandler_linux.cc @@ -0,0 +1,431 @@ +//Linux only +/* This stuff is actually C */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} /* extern C */ +#endif +/* This stuff is actually C */ + +#include "upnp/upnphandler_linux.h" + +#include "util/rsnet.h" + +bool upnphandler::initUPnPState() +{ + #ifdef UPNP_DEBUG + std::cerr << "upnphandler::initUPnPState" << std::endl; + #endif + cUPnPControlPoint = new CUPnPControlPoint(2000); + + bool IGWDetected = cUPnPControlPoint->GetIGWDeviceDetected(); + + if (IGWDetected) { + /* MODIFY STATE */ + dataMtx.lock(); /* LOCK MUTEX */ + upnpState = RS_UPNP_S_READY; + + #ifdef UPNP_DEBUG + std::cerr << "upnphandler::initUPnPState cUPnPControlPoint internal ip adress : "; + std::cerr << cUPnPControlPoint->getInternalIpAddress() << std::endl; + #endif + + //const char ipaddr = cUPnPControlPoint->getInternalIpAddress().c_str(); + inet_aton(cUPnPControlPoint->getInternalIpAddress(), &(upnp_iaddr.sin_addr)); + upnp_iaddr.sin_port = htons(iport); + + #ifdef UPNP_DEBUG + std::cerr << "upnphandler::initUPnPState READY" << std::endl; + #endif + dataMtx.unlock(); /* UNLOCK MUTEX */ + + } else { + upnpState = RS_UPNP_S_UNAVAILABLE; + #ifdef UPNP_DEBUG + std::cerr << "upnphandler::initUPnPState UNAVAILABLE" << std::endl; + #endif + } + + return 0; +} + +class upnpThreadData +{ + public: + upnphandler *handler; + bool start; + bool stop; +}; + + /* Thread routines */ +extern "C" void* doSetupUPnP(void* p) +{ + #ifdef UPNP_DEBUG + std::cerr << "doSetupUPnP Creating upnp thread." << std::endl; + #endif + upnpThreadData *data = (upnpThreadData *) p; + if ((!data) || (!data->handler)) + { + pthread_exit(NULL); + } + + /* publish it! */ + if (data -> stop) + { + data->handler->shutdown_upnp(); + } + + if (data -> start) + { + data->handler->initUPnPState(); + data->handler->start_upnp(); + } + + delete data; + pthread_exit(NULL); + + return NULL; +} + +bool upnphandler::background_setup_upnp(bool start, bool stop) +{ + pthread_t tid; + + /* launch thread */ + #ifdef UPNP_DEBUG + std::cerr << "background_setup_upnp Creating upnp thread." << std::endl; + #endif + upnpThreadData *data = new upnpThreadData(); + data->handler = this; + data->start = start; + data->stop = stop; + + pthread_create(&tid, 0, &doSetupUPnP, (void *) data); + pthread_detach(tid); /* so memory is reclaimed in linux */ + + return true; +} + +bool upnphandler::start_upnp() +{ + if (!(upnpState >= RS_UPNP_S_READY)) + { + #ifdef UPNP_DEBUG + std::cerr << "upnphandler::start_upnp() Not Ready" << std::endl; + #endif + return false; + } + + struct sockaddr_in localAddr; + { + RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */ + + /* if we're to load -> load */ + /* select external ports */ + eport_curr = eport; + if (!eport_curr) + { + /* use local port if eport is zero */ + eport_curr = iport; + #ifdef UPNP_DEBUG + std::cerr << "upnphandler::start_upnp() Using LocalPort for extPort." << std::endl; + #endif + } + + if (!eport_curr) + { + #ifdef UPNP_DEBUG + std::cerr << "upnphandler::start_upnp() Invalid eport ... " << std::endl; + #endif + return false; + } + + /* our port */ + char in_addr[256]; + char in_port1[256]; + + upnp_iaddr.sin_port = htons(iport); + localAddr = upnp_iaddr; + uint32_t linaddr = ntohl(localAddr.sin_addr.s_addr); + snprintf(in_port1, 256, "%d", ntohs(localAddr.sin_port)); + snprintf(in_addr, 256, "%d.%d.%d.%d", + ((linaddr >> 24) & 0xff), + ((linaddr >> 16) & 0xff), + ((linaddr >> 8) & 0xff), + ((linaddr >> 0) & 0xff)); + + #ifdef UPNP_DEBUG + std::cerr << "Attempting Redirection: InAddr: " << in_addr; + std::cerr << " InPort: " << in_port1; + std::cerr << " ePort: " << eport_curr; + std::cerr << " eProt: " << "TCP and UDP"; + std::cerr << std::endl; + #endif + } + + //first of all, build the mappings + std::vector upnpPortMapping1; + CUPnPPortMapping cUPnPPortMapping1 = CUPnPPortMapping(eport_curr, ntohs(localAddr.sin_port), "TCP", true, "tcp retroshare redirection"); + upnpPortMapping1.push_back(cUPnPPortMapping1); + std::vector upnpPortMapping2; + CUPnPPortMapping cUPnPPortMapping2 = CUPnPPortMapping(eport_curr, ntohs(localAddr.sin_port), "UDP", true, "udp retroshare redirection"); + upnpPortMapping2.push_back(cUPnPPortMapping2); + + //attempt to remove formal port redirection rules + cUPnPControlPoint->DeletePortMappings(upnpPortMapping1); + cUPnPControlPoint->DeletePortMappings(upnpPortMapping2); + + //add new rules + bool res = cUPnPControlPoint->AddPortMappings(upnpPortMapping1); + bool res2 = cUPnPControlPoint->AddPortMappings(upnpPortMapping2); + + struct sockaddr_in extAddr; + bool extAddrResult = getExternalAddress(extAddr); + + { + RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */ + + if (extAddrResult && (res || res2)) { + upnpState = RS_UPNP_S_ACTIVE; + } else { + upnpState = RS_UPNP_S_TCP_AND_FAILED; + } + + toStart = false; + } + + return (upnpState == RS_UPNP_S_ACTIVE); + +} + +bool upnphandler::shutdown_upnp() +{ + RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */ + + /* always attempt this (unless no port number) */ + if (eport_curr > 0 && eport > 0 && (upnpState >= RS_UPNP_S_ACTIVE)) + { + #ifdef UPNP_DEBUG + std::cerr << "upnphandler::shutdown_upnp() : Attempting To Remove Redirection: port: " << eport_curr; + std::cerr << " Prot: TCP"; + std::cerr << std::endl; + #endif + + std::vector upnpPortMapping1; + CUPnPPortMapping cUPnPPortMapping1 = CUPnPPortMapping(eport_curr, 0, "TCP", true, "tcp redirection"); + upnpPortMapping1.push_back(cUPnPPortMapping1); + cUPnPControlPoint->DeletePortMappings(upnpPortMapping1); + + #ifdef UPNP_DEBUG + std::cerr << "upnphandler::shutdown_upnp() : Attempting To Remove Redirection: port: " << eport_curr; + std::cerr << " Prot: UDP"; + std::cerr << std::endl; + #endif + + std::vector upnpPortMapping2; + CUPnPPortMapping cUPnPPortMapping2 = CUPnPPortMapping(eport_curr, 0, "UDP", true, "udp redirection"); + upnpPortMapping2.push_back(cUPnPPortMapping2); + cUPnPControlPoint->DeletePortMappings(upnpPortMapping2); + + //destroy the upnp object + cUPnPControlPoint->~CUPnPControlPoint(); + } else { + #ifdef UPNP_DEBUG + std::cerr << "upnphandler::shutdown_upnp() : avoid upnp connection for shutdonws because probably a net flag went down." << std::endl; + #endif + } + + //stopping os ok, set starting to true for next net reset + toStop = false; + toStart = true; + upnpState = RS_UPNP_S_UNINITIALISED; + + return true; + +} + +/************************ External Interface ***************************** + * + * + * + */ + +upnphandler::upnphandler() + : + upnpState(RS_UPNP_S_UNINITIALISED), dataMtx("upupState"), + cUPnPControlPoint(NULL), + toEnable(false), toStart(false), toStop(false), + iport(0),eport(0), eport_curr(0) +{ +} + +upnphandler::~upnphandler() +{ + return; +} + + /* RsIface */ +void upnphandler::enable(bool active) +{ + #ifdef UPNP_DEBUG + std::cerr << "upnphandler::enable called with argument active : " << active << std::endl; + std::cerr << "toEnable : " << toEnable << std::endl; + std::cerr << "toStart : " << toStart << std::endl; + #endif + + dataMtx.lock(); /*** LOCK MUTEX ***/ + if (active != toEnable) + { + if (active) + { + toStart = true; + } + else + { + toStop = true; + } + } + toEnable = active; + + bool start = toStart; + + dataMtx.unlock(); /*** UNLOCK MUTEX ***/ + + if (start) + { + /* make background thread to startup UPnP */ + background_setup_upnp(true, false); + } +} + + +void upnphandler::shutdown() +{ + /* blocking call to shutdown upnp */ + + #ifdef UPNP_DEBUG + std::cerr << "upnphandler::shutdown() called." << std::endl; + #endif + shutdown_upnp(); +} + + +void upnphandler::restart() +{ + /* non-blocking call to shutdown upnp, and startup again. */ + #ifdef UPNP_DEBUG + std::cerr << "upnphandler::restart() called." << std::endl; + #endif + background_setup_upnp(true, true); +} + + + +bool upnphandler::getEnabled() +{ + dataMtx.lock(); /*** LOCK MUTEX ***/ + + bool on = toEnable; + + dataMtx.unlock(); /*** UNLOCK MUTEX ***/ + + return on; +} + +bool upnphandler::getActive() +{ + dataMtx.lock(); /*** LOCK MUTEX ***/ + + #ifdef UPNP_DEBUG + std::cerr <<"upnphandler::getActive() result : " << (upnpState == RS_UPNP_S_ACTIVE) << std::endl; + #endif + + bool on = (upnpState == RS_UPNP_S_ACTIVE); + + dataMtx.unlock(); /*** UNLOCK MUTEX ***/ + + return on; +} + + /* the address that the listening port is on */ +void upnphandler::setInternalPort(unsigned short iport_in) +{ + dataMtx.lock(); /*** LOCK MUTEX ***/ + if (iport != iport_in) + { + iport = iport_in; + if ((toEnable) && + (upnpState == RS_UPNP_S_ACTIVE)) + { + toStop = true; + toStart = true; + } + } + dataMtx.unlock(); /*** UNLOCK MUTEX ***/ +} + +void upnphandler::setExternalPort(unsigned short eport_in) +{ + dataMtx.lock(); /*** LOCK MUTEX ***/ + /* flag both shutdown/start -> for restart */ + if (eport != eport_in) + { + eport = eport_in; + if ((toEnable) && + (upnpState == RS_UPNP_S_ACTIVE)) + { + toStop = true; + toStart = true; + } + } + + dataMtx.unlock(); /*** UNLOCK MUTEX ***/ +} + + /* as determined by uPnP */ +bool upnphandler::getInternalAddress(struct sockaddr_in &addr) +{ + dataMtx.lock(); /*** LOCK MUTEX ***/ + addr = upnp_iaddr; + bool valid = (upnpState >= RS_UPNP_S_ACTIVE); + + dataMtx.unlock(); /*** UNLOCK MUTEX ***/ + + return valid; +} + +bool upnphandler::getExternalAddress(struct sockaddr_in &addr) +{ + std::string externalAdress = cUPnPControlPoint->getExternalAddress(); + + if(!externalAdress.empty() && externalAdress != "") + { + const char* externalIPAddress = externalAdress.c_str(); + + #ifdef UPNP_DEBUG + std::cerr << " upnphandler::getExternalAddress() : " << externalIPAddress; + std::cerr << ":" << eport_curr; + std::cerr << std::endl; + #endif + + dataMtx.lock(); /*** LOCK MUTEX ***/ + sockaddr_clear(&upnp_eaddr); + inet_aton(externalIPAddress, &(upnp_eaddr.sin_addr)); + upnp_eaddr.sin_family = AF_INET; + upnp_eaddr.sin_port = htons(eport_curr); + dataMtx.unlock(); /*** UNLOCK MUTEX ***/ + + addr = upnp_eaddr; + return true; + } + else + { + return false; + } +} + + + diff --git a/libretroshare/src/upnp/upnphandler_linux.h b/libretroshare/src/upnp/upnphandler_linux.h new file mode 100644 index 000000000..44b6c073a --- /dev/null +++ b/libretroshare/src/upnp/upnphandler_linux.h @@ -0,0 +1,78 @@ +#ifndef _RS_UPNP_IFACE_H +#define _RS_UPNP_IFACE_H + +#include + +/* platform independent networking... */ +#include "pqi/pqinetwork.h" +#include "pqi/pqiassist.h" + +#include "util/rsthreads.h" + +#include +#include "upnp/UPnPBase.h" + +#define RS_UPNP_S_UNINITIALISED 0 +#define RS_UPNP_S_UNAVAILABLE 1 +#define RS_UPNP_S_READY 2 +#define RS_UPNP_S_TCP_AND_FAILED 3 +//#define RS_UPNP_S_UDP_FAILED 4 +#define RS_UPNP_S_ACTIVE 5 + +class upnphandler: public pqiNetAssistFirewall +{ + public: + + upnphandler(); + virtual ~upnphandler(); + + /* External Interface (pqiNetAssistFirewall) */ + virtual void enable(bool active); + virtual void shutdown(); + virtual void restart(); + + virtual bool getEnabled(); + virtual bool getActive(); + + virtual void setInternalPort(unsigned short iport_in); + virtual void setExternalPort(unsigned short eport_in); + virtual bool getInternalAddress(struct sockaddr_in &addr); + virtual bool getExternalAddress(struct sockaddr_in &addr); + + /* Public functions - for background thread operation, + * but effectively private from rest of RS, as in derived class + */ + unsigned int upnpState; + + bool start_upnp(); + bool shutdown_upnp(); + + bool initUPnPState(); + + /* Mutex for data below */ + RsMutex dataMtx; + + private: + + CUPnPControlPoint *cUPnPControlPoint; + + bool background_setup_upnp(bool, bool); + + + bool toEnable; /* overall on/off switch */ + bool toStart; /* if set start forwarding */ + bool toStop; /* if set stop forwarding */ + + unsigned short iport; + unsigned short eport; /* config */ + unsigned short eport_curr; /* current forwarded */ + + /* info from upnp */ + struct sockaddr_in upnp_iaddr; + struct sockaddr_in upnp_eaddr; +}; + +/* info from upnp */ +int CtrlPointCallbackEventHandler(Upnp_EventType ,void* , void*); + +#endif /* _RS_UPNP_IFACE_H */ diff --git a/libretroshare/src/upnp/upnphandler.cc b/libretroshare/src/upnp/upnphandler_miniupnp.cc similarity index 53% rename from libretroshare/src/upnp/upnphandler.cc rename to libretroshare/src/upnp/upnphandler_miniupnp.cc index d77aa90d1..5d3937ca1 100644 --- a/libretroshare/src/upnp/upnphandler.cc +++ b/libretroshare/src/upnp/upnphandler_miniupnp.cc @@ -1,440 +1,4 @@ -//Linux only -#if !defined(WINDOWS_SYS) && !defined(__APPLE__) - -/* This stuff is actually C */ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} /* extern C */ -#endif -/* This stuff is actually C */ - -#include "upnp/upnphandler.h" - -#include "util/rsnet.h" - -bool upnphandler::initUPnPState() -{ - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::initUPnPState" << std::endl; - #endif - cUPnPControlPoint = new CUPnPControlPoint(2000); - - bool IGWDetected = cUPnPControlPoint->GetIGWDeviceDetected(); - - if (IGWDetected) { - /* MODIFY STATE */ - dataMtx.lock(); /* LOCK MUTEX */ - upnpState = RS_UPNP_S_READY; - - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::initUPnPState cUPnPControlPoint internal ip adress : "; - std::cerr << cUPnPControlPoint->getInternalIpAddress() << std::endl; - #endif - - //const char ipaddr = cUPnPControlPoint->getInternalIpAddress().c_str(); - inet_aton(cUPnPControlPoint->getInternalIpAddress(), &(upnp_iaddr.sin_addr)); - upnp_iaddr.sin_port = htons(iport); - - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::initUPnPState READY" << std::endl; - #endif - dataMtx.unlock(); /* UNLOCK MUTEX */ - - } else { - upnpState = RS_UPNP_S_UNAVAILABLE; - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::initUPnPState UNAVAILABLE" << std::endl; - #endif - } - - return 0; -} - -class upnpThreadData -{ - public: - upnphandler *handler; - bool start; - bool stop; -}; - - /* Thread routines */ -extern "C" void* doSetupUPnP(void* p) -{ - #ifdef UPNP_DEBUG - std::cerr << "doSetupUPnP Creating upnp thread." << std::endl; - #endif - upnpThreadData *data = (upnpThreadData *) p; - if ((!data) || (!data->handler)) - { - pthread_exit(NULL); - } - - /* publish it! */ - if (data -> stop) - { - data->handler->shutdown_upnp(); - } - - if (data -> start) - { - data->handler->initUPnPState(); - data->handler->start_upnp(); - } - - delete data; - pthread_exit(NULL); - - return NULL; -} - -bool upnphandler::background_setup_upnp(bool start, bool stop) -{ - pthread_t tid; - - /* launch thread */ - #ifdef UPNP_DEBUG - std::cerr << "background_setup_upnp Creating upnp thread." << std::endl; - #endif - upnpThreadData *data = new upnpThreadData(); - data->handler = this; - data->start = start; - data->stop = stop; - - pthread_create(&tid, 0, &doSetupUPnP, (void *) data); - pthread_detach(tid); /* so memory is reclaimed in linux */ - - return true; -} - -bool upnphandler::start_upnp() -{ - if (!(upnpState >= RS_UPNP_S_READY)) - { - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::start_upnp() Not Ready" << std::endl; - #endif - return false; - } - - struct sockaddr_in localAddr; - { - RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */ - - /* if we're to load -> load */ - /* select external ports */ - eport_curr = eport; - if (!eport_curr) - { - /* use local port if eport is zero */ - eport_curr = iport; - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::start_upnp() Using LocalPort for extPort." << std::endl; - #endif - } - - if (!eport_curr) - { - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::start_upnp() Invalid eport ... " << std::endl; - #endif - return false; - } - - /* our port */ - char in_addr[256]; - char in_port1[256]; - - upnp_iaddr.sin_port = htons(iport); - localAddr = upnp_iaddr; - uint32_t linaddr = ntohl(localAddr.sin_addr.s_addr); - snprintf(in_port1, 256, "%d", ntohs(localAddr.sin_port)); - snprintf(in_addr, 256, "%d.%d.%d.%d", - ((linaddr >> 24) & 0xff), - ((linaddr >> 16) & 0xff), - ((linaddr >> 8) & 0xff), - ((linaddr >> 0) & 0xff)); - - #ifdef UPNP_DEBUG - std::cerr << "Attempting Redirection: InAddr: " << in_addr; - std::cerr << " InPort: " << in_port1; - std::cerr << " ePort: " << eport_curr; - std::cerr << " eProt: " << "TCP and UDP"; - std::cerr << std::endl; - #endif - } - - //first of all, build the mappings - std::vector upnpPortMapping1; - CUPnPPortMapping cUPnPPortMapping1 = CUPnPPortMapping(eport_curr, ntohs(localAddr.sin_port), "TCP", true, "tcp retroshare redirection"); - upnpPortMapping1.push_back(cUPnPPortMapping1); - std::vector upnpPortMapping2; - CUPnPPortMapping cUPnPPortMapping2 = CUPnPPortMapping(eport_curr, ntohs(localAddr.sin_port), "UDP", true, "udp retroshare redirection"); - upnpPortMapping2.push_back(cUPnPPortMapping2); - - //attempt to remove formal port redirection rules - cUPnPControlPoint->DeletePortMappings(upnpPortMapping1); - cUPnPControlPoint->DeletePortMappings(upnpPortMapping2); - - //add new rules - bool res = cUPnPControlPoint->AddPortMappings(upnpPortMapping1); - bool res2 = cUPnPControlPoint->AddPortMappings(upnpPortMapping2); - - struct sockaddr_in extAddr; - bool extAddrResult = getExternalAddress(extAddr); - - { - RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */ - - if (extAddrResult && (res || res2)) { - upnpState = RS_UPNP_S_ACTIVE; - } else { - upnpState = RS_UPNP_S_TCP_AND_FAILED; - } - - toStart = false; - } - - return (upnpState == RS_UPNP_S_ACTIVE); - -} - -bool upnphandler::shutdown_upnp() -{ - RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */ - - /* always attempt this (unless no port number) */ - if (eport_curr > 0 && eport > 0 && (upnpState >= RS_UPNP_S_ACTIVE)) - { - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::shutdown_upnp() : Attempting To Remove Redirection: port: " << eport_curr; - std::cerr << " Prot: TCP"; - std::cerr << std::endl; - #endif - - std::vector upnpPortMapping1; - CUPnPPortMapping cUPnPPortMapping1 = CUPnPPortMapping(eport_curr, 0, "TCP", true, "tcp redirection"); - upnpPortMapping1.push_back(cUPnPPortMapping1); - cUPnPControlPoint->DeletePortMappings(upnpPortMapping1); - - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::shutdown_upnp() : Attempting To Remove Redirection: port: " << eport_curr; - std::cerr << " Prot: UDP"; - std::cerr << std::endl; - #endif - - std::vector upnpPortMapping2; - CUPnPPortMapping cUPnPPortMapping2 = CUPnPPortMapping(eport_curr, 0, "UDP", true, "udp redirection"); - upnpPortMapping2.push_back(cUPnPPortMapping2); - cUPnPControlPoint->DeletePortMappings(upnpPortMapping2); - - //destroy the upnp object - cUPnPControlPoint->~CUPnPControlPoint(); - } else { - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::shutdown_upnp() : avoid upnp connection for shutdonws because probably a net flag went down." << std::endl; - #endif - } - - //stopping os ok, set starting to true for next net reset - toStop = false; - toStart = true; - upnpState = RS_UPNP_S_UNINITIALISED; - - return true; - -} - -/************************ External Interface ***************************** - * - * - * - */ - -upnphandler::upnphandler() - : - upnpState(RS_UPNP_S_UNINITIALISED), dataMtx("upupState"), - cUPnPControlPoint(NULL), - toEnable(false), toStart(false), toStop(false), - iport(0),eport(0), eport_curr(0) -{ -} - -upnphandler::~upnphandler() -{ - return; -} - - /* RsIface */ -void upnphandler::enable(bool active) -{ - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::enable called with argument active : " << active << std::endl; - std::cerr << "toEnable : " << toEnable << std::endl; - std::cerr << "toStart : " << toStart << std::endl; - #endif - - dataMtx.lock(); /*** LOCK MUTEX ***/ - if (active != toEnable) - { - if (active) - { - toStart = true; - } - else - { - toStop = true; - } - } - toEnable = active; - - bool start = toStart; - - dataMtx.unlock(); /*** UNLOCK MUTEX ***/ - - if (start) - { - /* make background thread to startup UPnP */ - background_setup_upnp(true, false); - } -} - - -void upnphandler::shutdown() -{ - /* blocking call to shutdown upnp */ - - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::shutdown() called." << std::endl; - #endif - shutdown_upnp(); -} - - -void upnphandler::restart() -{ - /* non-blocking call to shutdown upnp, and startup again. */ - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::restart() called." << std::endl; - #endif - background_setup_upnp(true, true); -} - - - -bool upnphandler::getEnabled() -{ - dataMtx.lock(); /*** LOCK MUTEX ***/ - - bool on = toEnable; - - dataMtx.unlock(); /*** UNLOCK MUTEX ***/ - - return on; -} - -bool upnphandler::getActive() -{ - dataMtx.lock(); /*** LOCK MUTEX ***/ - - #ifdef UPNP_DEBUG - std::cerr <<"upnphandler::getActive() result : " << (upnpState == RS_UPNP_S_ACTIVE) << std::endl; - #endif - - bool on = (upnpState == RS_UPNP_S_ACTIVE); - - dataMtx.unlock(); /*** UNLOCK MUTEX ***/ - - return on; -} - - /* the address that the listening port is on */ -void upnphandler::setInternalPort(unsigned short iport_in) -{ - dataMtx.lock(); /*** LOCK MUTEX ***/ - if (iport != iport_in) - { - iport = iport_in; - if ((toEnable) && - (upnpState == RS_UPNP_S_ACTIVE)) - { - toStop = true; - toStart = true; - } - } - dataMtx.unlock(); /*** UNLOCK MUTEX ***/ -} - -void upnphandler::setExternalPort(unsigned short eport_in) -{ - dataMtx.lock(); /*** LOCK MUTEX ***/ - /* flag both shutdown/start -> for restart */ - if (eport != eport_in) - { - eport = eport_in; - if ((toEnable) && - (upnpState == RS_UPNP_S_ACTIVE)) - { - toStop = true; - toStart = true; - } - } - - dataMtx.unlock(); /*** UNLOCK MUTEX ***/ -} - - /* as determined by uPnP */ -bool upnphandler::getInternalAddress(struct sockaddr_in &addr) -{ - dataMtx.lock(); /*** LOCK MUTEX ***/ - addr = upnp_iaddr; - bool valid = (upnpState >= RS_UPNP_S_ACTIVE); - - dataMtx.unlock(); /*** UNLOCK MUTEX ***/ - - return valid; -} - -bool upnphandler::getExternalAddress(struct sockaddr_in &addr) -{ - std::string externalAdress = cUPnPControlPoint->getExternalAddress(); - - if(!externalAdress.empty() && externalAdress != "") - { - const char* externalIPAddress = externalAdress.c_str(); - - #ifdef UPNP_DEBUG - std::cerr << " upnphandler::getExternalAddress() : " << externalIPAddress; - std::cerr << ":" << eport_curr; - std::cerr << std::endl; - #endif - - dataMtx.lock(); /*** LOCK MUTEX ***/ - sockaddr_clear(&upnp_eaddr); - inet_aton(externalIPAddress, &(upnp_eaddr.sin_addr)); - upnp_eaddr.sin_family = AF_INET; - upnp_eaddr.sin_port = htons(eport_curr); - dataMtx.unlock(); /*** UNLOCK MUTEX ***/ - - addr = upnp_eaddr; - return true; - } - else - { - return false; - } -} -#endif - - - // Windows / Mac version. -#if defined(WINDOWS_SYS) || defined(__APPLE__) - /* This stuff is actually C */ #ifdef __cplusplus @@ -1001,4 +565,3 @@ bool upnphandler::getExternalAddress(struct sockaddr_in &addr) return valid; } -#endif diff --git a/libretroshare/src/upnp/upnphandler.h b/libretroshare/src/upnp/upnphandler_miniupnp.h similarity index 50% rename from libretroshare/src/upnp/upnphandler.h rename to libretroshare/src/upnp/upnphandler_miniupnp.h index 80b8560de..6708e68a0 100644 --- a/libretroshare/src/upnp/upnphandler.h +++ b/libretroshare/src/upnp/upnphandler_miniupnp.h @@ -1,94 +1,4 @@ -//Linux only... -#if !defined(WINDOWS_SYS) && !defined(__APPLE__) - -#ifndef _RS_UPNP_IFACE_H -#define _RS_UPNP_IFACE_H - -#include - -/* platform independent networking... */ -#include "pqi/pqinetwork.h" -#include "pqi/pqiassist.h" - -#include "util/rsthreads.h" - -#include -#include "upnp/UPnPBase.h" - -#define RS_UPNP_S_UNINITIALISED 0 -#define RS_UPNP_S_UNAVAILABLE 1 -#define RS_UPNP_S_READY 2 -#define RS_UPNP_S_TCP_AND_FAILED 3 -//#define RS_UPNP_S_UDP_FAILED 4 -#define RS_UPNP_S_ACTIVE 5 - -class upnphandler: public pqiNetAssistFirewall -{ - public: - - upnphandler(); - virtual ~upnphandler(); - - /* External Interface (pqiNetAssistFirewall) */ - virtual void enable(bool active); - virtual void shutdown(); - virtual void restart(); - - virtual bool getEnabled(); - virtual bool getActive(); - - virtual void setInternalPort(unsigned short iport_in); - virtual void setExternalPort(unsigned short eport_in); - virtual bool getInternalAddress(struct sockaddr_in &addr); - virtual bool getExternalAddress(struct sockaddr_in &addr); - - /* Public functions - for background thread operation, - * but effectively private from rest of RS, as in derived class - */ - unsigned int upnpState; - - bool start_upnp(); - bool shutdown_upnp(); - - bool initUPnPState(); - - /* Mutex for data below */ - RsMutex dataMtx; - - private: - - CUPnPControlPoint *cUPnPControlPoint; - - bool background_setup_upnp(bool, bool); - - - bool toEnable; /* overall on/off switch */ - bool toStart; /* if set start forwarding */ - bool toStop; /* if set stop forwarding */ - - unsigned short iport; - unsigned short eport; /* config */ - unsigned short eport_curr; /* current forwarded */ - - /* info from upnp */ - struct sockaddr_in upnp_iaddr; - struct sockaddr_in upnp_eaddr; -}; - -/* info from upnp */ -int CtrlPointCallbackEventHandler(Upnp_EventType ,void* , void*); - -#endif /* _RS_UPNP_IFACE_H */ - -#endif - - - - - -#if defined(WINDOWS_SYS) || defined(__APPLE__) - -//windows implementation +//windows/osx (miniupnpc) implementation #ifndef _RS_UPNP_IFACE_H #define _RS_UPNP_IFACE_H @@ -194,4 +104,3 @@ bool checkUPnPActive(); }; #endif /* _RS_UPNP_IFACE_H */ -#endif From a5f52e85a1f351c83c855dd997346110ccabf24a Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 28 Oct 2012 18:17:06 +0000 Subject: [PATCH 109/222] Added new Upnp interface fn, and dummy implementations. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5734 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/pqi/pqiassist.h | 20 +++++++++++++++++++ libretroshare/src/upnp/upnphandler_linux.h | 4 ++++ libretroshare/src/upnp/upnphandler_miniupnp.h | 4 ++++ libretroshare/src/zeroconf/p3zcnatassist.h | 3 +++ 4 files changed, 31 insertions(+) diff --git a/libretroshare/src/pqi/pqiassist.h b/libretroshare/src/pqi/pqiassist.h index 06cb5d434..3bf984f8d 100644 --- a/libretroshare/src/pqi/pqiassist.h +++ b/libretroshare/src/pqi/pqiassist.h @@ -64,6 +64,20 @@ virtual int tick() { return 0; } /* for internal accounting */ }; + +#define PFP_TYPE_UDP 0x0001 +#define PFP_TYPE_TCP 0x0002 + +class PortForwardParams +{ + public: + uint32_t fwdId; + uint32_t status; + uint32_t typeFlags; + struct sockaddr_in intAddr; + struct sockaddr_in extaddr; +}; + class pqiNetAssistFirewall: public pqiNetAssist { public: @@ -78,6 +92,12 @@ virtual void setExternalPort(unsigned short eport_in) = 0; virtual bool getInternalAddress(struct sockaddr_in &addr) = 0; virtual bool getExternalAddress(struct sockaddr_in &addr) = 0; + + /* New Port Forward interface to support as many ports as necessary */ +virtual bool requestPortForward(const PortForwardParams ¶ms) = 0; +virtual bool statusPortForward(const uint32_t fwdId, PortForwardParams ¶ms) = 0; + + }; diff --git a/libretroshare/src/upnp/upnphandler_linux.h b/libretroshare/src/upnp/upnphandler_linux.h index 44b6c073a..e0b8588a2 100644 --- a/libretroshare/src/upnp/upnphandler_linux.h +++ b/libretroshare/src/upnp/upnphandler_linux.h @@ -39,6 +39,10 @@ class upnphandler: public pqiNetAssistFirewall virtual bool getInternalAddress(struct sockaddr_in &addr); virtual bool getExternalAddress(struct sockaddr_in &addr); + /* TO IMPLEMENT: New Port Forward interface to support as many ports as necessary */ + virtual bool requestPortForward(const PortForwardParams ¶ms) { return false; } + virtual bool statusPortForward(const uint32_t fwdId, PortForwardParams ¶ms) { return false; } + /* Public functions - for background thread operation, * but effectively private from rest of RS, as in derived class */ diff --git a/libretroshare/src/upnp/upnphandler_miniupnp.h b/libretroshare/src/upnp/upnphandler_miniupnp.h index 6708e68a0..e734f8413 100644 --- a/libretroshare/src/upnp/upnphandler_miniupnp.h +++ b/libretroshare/src/upnp/upnphandler_miniupnp.h @@ -65,6 +65,10 @@ virtual void setExternalPort(unsigned short eport_in); virtual bool getInternalAddress(struct sockaddr_in &addr); virtual bool getExternalAddress(struct sockaddr_in &addr); + /* TO IMPLEMENT: New Port Forward interface to support as many ports as necessary */ +virtual bool requestPortForward(const PortForwardParams ¶ms) { return false; } +virtual bool statusPortForward(const uint32_t fwdId, PortForwardParams ¶ms) { return false; } + /* Public functions - for background thread operation, * but effectively private from rest of RS, as in derived class */ diff --git a/libretroshare/src/zeroconf/p3zcnatassist.h b/libretroshare/src/zeroconf/p3zcnatassist.h index 5171107ee..72bde8dea 100644 --- a/libretroshare/src/zeroconf/p3zcnatassist.h +++ b/libretroshare/src/zeroconf/p3zcnatassist.h @@ -64,6 +64,9 @@ virtual void setExternalPort(unsigned short eport_in); virtual bool getInternalAddress(struct sockaddr_in &addr); virtual bool getExternalAddress(struct sockaddr_in &addr); + /* TO IMPLEMENT: New Port Forward interface to support as many ports as necessary */ +virtual bool requestPortForward(const PortForwardParams ¶ms) { return false; } +virtual bool statusPortForward(const uint32_t fwdId, PortForwardParams ¶ms) { return false; } /* pqiNetAssistConnect - external interface functions */ From df1a3297e081193062329737de3e730f85ad4803 Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 28 Oct 2012 18:40:01 +0000 Subject: [PATCH 110/222] Fixed up circular #include issue. Reenabled RsGxsIdExchange interface. Compile p3idservice again. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5735 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgenexchange.h | 5 +++-- libretroshare/src/gxs/rsgixs.h | 17 ++++++++++------- libretroshare/src/libretroshare.pro | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 71f607ca1..363711386 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -32,12 +32,10 @@ #include "rsgxs.h" #include "rsgds.h" #include "rsnxs.h" -#include "rsgixs.h" #include "rsgxsdataaccess.h" #include "rsnxsobserver.h" #include "retroshare/rsgxsservice.h" #include "serialiser/rsnxsitems.h" -//#include "rsgixs.h" typedef std::map > GxsMsgDataMap; typedef std::map GxsGroupDataMap; @@ -63,6 +61,9 @@ typedef std::map > GxsMsgMetaMap; * Also notifications are made here on receipt of new data from \n * connected peers */ + +class RsGixs; + class RsGenExchange : public RsGxsService, public RsNxsObserver { public: diff --git a/libretroshare/src/gxs/rsgixs.h b/libretroshare/src/gxs/rsgixs.h index 316a5e82c..25b1d7a25 100644 --- a/libretroshare/src/gxs/rsgixs.h +++ b/libretroshare/src/gxs/rsgixs.h @@ -180,14 +180,17 @@ public: /*** This Class pulls all the GXS Interfaces together ****/ -//class RsGxsIdExchange: public RsGenExchange, public RsGixsReputation, public RsGixs -//{ -//public: -// RsGxsIdExchange(RsGeneralDataService* gds, RsNetworkExchangeService* ns, RsSerialType* serviceSerialiser, uint16_t mServType) -// :RsGenExchange(gds,ns,serviceSerialiser,mServType) { return; } -//virtual ~RsGxsIdExchange() { return; } +class RsGxsIdExchange: + public RsGenExchange, + public RsGixsReputation, + public RsGixs +{ +public: + RsGxsIdExchange(RsGeneralDataService* gds, RsNetworkExchangeService* ns, RsSerialType* serviceSerialiser, uint16_t mServType) + :RsGenExchange(gds,ns,serviceSerialiser,mServType, this) { return; } +virtual ~RsGxsIdExchange() { return; } -//}; +}; diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 7b0bf9a71..b04ebcc32 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -638,7 +638,7 @@ HEADERS += retroshare/rsgame.h \ services/p3idservice.h \ serialiser/rsgxsiditems.h - #SOURCES += services/p3idservice.cc + SOURCES += services/p3idservice.cc # serialiser/rsgxsiditems.cc \ # Wiki Service From cddeaeea81ed675db016fa019563ab2a78dd164e Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 28 Oct 2012 23:13:15 +0000 Subject: [PATCH 111/222] Got GxsId service compiling and linking. - Added entries in rsinit.cc - Added serialiser functions. - Tweaked some datatypes. - Fixed up duplicate headers. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5736 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/libretroshare.pro | 4 +- libretroshare/src/retroshare/rsidentity.h | 6 +- libretroshare/src/retroshare/rsidentityVEG.h | 4 +- libretroshare/src/rsserver/rsinit.cc | 25 +- libretroshare/src/serialiser/rsgxsiditems.cc | 578 +++++++++++++++++++ libretroshare/src/services/p3idservice.cc | 12 +- libretroshare/src/services/p3idservice.h | 12 +- libretroshare/src/services/p3idserviceVEG.h | 4 +- 8 files changed, 630 insertions(+), 15 deletions(-) create mode 100644 libretroshare/src/serialiser/rsgxsiditems.cc diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index b04ebcc32..2a1178a2e 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -638,8 +638,8 @@ HEADERS += retroshare/rsgame.h \ services/p3idservice.h \ serialiser/rsgxsiditems.h - SOURCES += services/p3idservice.cc - # serialiser/rsgxsiditems.cc \ + SOURCES += services/p3idservice.cc \ + serialiser/rsgxsiditems.cc \ # Wiki Service HEADERS += retroshare/rswiki.h \ diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index 1677dbd75..13209655b 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -92,7 +92,11 @@ class RsGxsIdOpinion //std::string mKeyId; (mGroupId) //std::string mPeerId; (mAuthorId) ??? - int mOpinion; + uint32_t mOpinion; + + + // NOT SERIALISED YET! + double mReputation; //int mRating; //int mPeersRating; diff --git a/libretroshare/src/retroshare/rsidentityVEG.h b/libretroshare/src/retroshare/rsidentityVEG.h index 98937a0f3..7a759b782 100644 --- a/libretroshare/src/retroshare/rsidentityVEG.h +++ b/libretroshare/src/retroshare/rsidentityVEG.h @@ -1,5 +1,5 @@ -#ifndef RETROSHARE_IDENTITY_GUI_INTERFACE_H -#define RETROSHARE_IDENTITY_GUI_INTERFACE_H +#ifndef RETROSHARE_IDENTITY_GUI_VEG_INTERFACE_H +#define RETROSHARE_IDENTITY_GUI_VEG_INTERFACE_H /* * libretroshare/src/retroshare: rsidentity.h diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 09508e322..7099e2395 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1827,7 +1827,8 @@ RsTurtle *rsTurtle = NULL ; #include "services/p3posted.h" #include "services/p3wikiserviceVEG.h" #include "services/p3wireVEG.h" -#include "services/p3idserviceVEG.h" +//#include "services/p3idserviceVEG.h" +#include "services/p3idservice.h" #include "services/p3forumsVEG.h" #endif @@ -2293,12 +2294,29 @@ int RsServer::StartupRetroShare() RsNxsNetMgr* nxsMgr = new RsNxsNetMgrImpl(mLinkMgr); + /**** Identity service ****/ + + p3IdService *mGxsIdService = NULL; + + RsGeneralDataService* gxsid_ds = new RsDataService("./" + mLinkMgr->getOwnId() + "/", "gxsid_db", + RS_SERVICE_GXSV1_TYPE_GXSID, NULL); + + gxsid_ds->resetDataStore(); + + // init gxs services + mGxsIdService = new p3IdService(gxsid_ds, NULL); + + // create GXS photo service + RsGxsNetService* gxsid_ns = new RsGxsNetService( + RS_SERVICE_GXSV1_TYPE_GXSID, gxsid_ds, nxsMgr, mGxsIdService); + + + /**** Photo service ****/ p3PhotoServiceV2 *mPhotoV2 = NULL; - RsGeneralDataService* photo_ds = new RsDataService("./" + mLinkMgr->getOwnId() + "/", "photoV2_db", RS_SERVICE_GXSV1_TYPE_PHOTO, NULL); @@ -2334,15 +2352,18 @@ int RsServer::StartupRetroShare() /*** start up GXS core runner ***/ GxsCoreServer* mGxsCore = new GxsCoreServer(); + mGxsCore->addService(mGxsIdService); mGxsCore->addService(mPhotoV2); mGxsCore->addService(mPosted); // cores ready start up GXS net servers createThread(*photo_ns); createThread(*posted_ns); + createThread(*gxsid_ns); // now add to p3service pqih->addService(photo_ns); + pqih->addService(gxsid_ns); pqih->addService(posted_ns); // start up gxs core server diff --git a/libretroshare/src/serialiser/rsgxsiditems.cc b/libretroshare/src/serialiser/rsgxsiditems.cc new file mode 100644 index 000000000..350d616d5 --- /dev/null +++ b/libretroshare/src/serialiser/rsgxsiditems.cc @@ -0,0 +1,578 @@ +/* + * libretroshare/src/serialiser: rsgxsiditems.cc + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include + +#include "rsgxsiditems.h" +#include "serialiser/rstlvbase.h" +#include "serialiser/rsbaseserial.h" + +#define GXSID_DEBUG 1 + + +uint32_t RsGxsIdSerialiser::size(RsItem *item) +{ + RsGxsIdGroupItem* grp_item = NULL; + RsGxsIdOpinionItem* op_item = NULL; + RsGxsIdCommentItem* com_item = NULL; + + if((grp_item = dynamic_cast(item)) != NULL) + { + return sizeGxsIdGroupItem(grp_item); + } + else if((op_item = dynamic_cast(item)) != NULL) + { + return sizeGxsIdOpinionItem(op_item); + } + else if((com_item = dynamic_cast(item)) != NULL) + { + return sizeGxsIdCommentItem(com_item); + } + return NULL; +} + +bool RsGxsIdSerialiser::serialise(RsItem *item, void *data, uint32_t *size) +{ + RsGxsIdGroupItem* grp_item = NULL; + RsGxsIdOpinionItem* op_item = NULL; + RsGxsIdCommentItem* com_item = NULL; + + if((grp_item = dynamic_cast(item)) != NULL) + { + return serialiseGxsIdGroupItem(grp_item, data, size); + } + else if((op_item = dynamic_cast(item)) != NULL) + { + return serialiseGxsIdGroupItem(grp_item, data, size); + return sizeGxsIdOpinionItem(op_item); + } + else if((com_item = dynamic_cast(item)) != NULL) + { + return serialiseGxsIdCommentItem(com_item, data, size); + } + return false; +} + +RsItem* RsGxsIdSerialiser::deserialise(void* data, uint32_t* size) +{ + +#ifdef RSSERIAL_DEBUG + std::cerr << "RsGxsIdSerialiser::deserialise()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_GXSID != getRsItemService(rstype))) + { + return NULL; /* wrong type */ + } + + switch(getRsItemSubType(rstype)) + { + + case RS_PKT_SUBTYPE_GXSID_GROUP_ITEM: + return deserialiseGxsIdGroupItem(data, size); + break; + case RS_PKT_SUBTYPE_GXSID_OPINION_ITEM: + return deserialiseGxsIdOpinionItem(data, size); + break; + case RS_PKT_SUBTYPE_GXSID_COMMENT_ITEM: + return deserialiseGxsIdCommentItem(data, size); + break; + default: +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::deserialise(): unknown subtype"; + std::cerr << std::endl; +#endif + break; + } + return NULL; +} + + + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + + +void RsGxsIdGroupItem::clear() +{ + group.mGpgIdHash.clear(); + group.mIdType = 0; + + // Others that aren't serialised. - but should be cleared anyway + group.mGpgIdKnown = false; + group.mGpgId.clear(); + group.mGpgName.clear(); + group.mGpgEmail.clear(); +} + +std::ostream& RsGxsIdGroupItem::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsGxsIdGroupItem", indent); + uint16_t int_Indent = indent + 2; + + printIndent(out, int_Indent); + out << "IdType: " << group.mIdType << std::endl; + printIndent(out, int_Indent); + out << "GpgIdHash: " << group.mGpgIdHash << std::endl; + + printRsItemEnd(out ,"RsGxsIdGroupItem", indent); + return out; +} + + +uint32_t RsGxsIdSerialiser::sizeGxsIdGroupItem(RsGxsIdGroupItem *item) +{ + + const RsGxsIdGroup& group = item->group; + uint32_t s = 8; // header + + s += 4; // mIdType. + s += GetTlvStringSize(group.mGpgIdHash); + + return s; +} + +bool RsGxsIdSerialiser::serialiseGxsIdGroupItem(RsGxsIdGroupItem *item, void *data, uint32_t *size) +{ + +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::serialiseGxsIdGroupItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsIdGroupItem(item); + uint32_t offset = 0; + + if(*size < tlvsize) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::serialiseGxsIdGroupItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsIdGroupItem */ + ok &= setRawUInt32(data, tlvsize, &offset, item->group.mIdType); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->group.mGpgIdHash); + + if(offset != tlvsize) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::serialiseGxsIdGroupItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef GXSID_DEBUG + if (!ok) + { + std::cerr << "RsGxsIdSerialiser::serialiseGxsIdgroupItem() NOK" << std::endl; + } +#endif + + return ok; + } + +RsGxsIdGroupItem* RsGxsIdSerialiser::deserialiseGxsIdGroupItem(void *data, uint32_t *size) +{ + +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdGroupItem()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_GXSID != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_GXSID_GROUP_ITEM != getRsItemSubType(rstype))) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdGroupItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdGroupItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsIdGroupItem* item = new RsGxsIdGroupItem(); + /* skip the header */ + offset += 8; + + ok &= getRawUInt32(data, rssize, &offset, &(item->group.mIdType)); + ok &= GetTlvString(data, rssize, &offset, 1, item->group.mGpgIdHash); + + if (offset != rssize) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdGroupItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdGroupItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + + + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + + +void RsGxsIdOpinionItem::clear() +{ + opinion.mOpinion = 0; + + // Others that aren't serialised. - but should be cleared anyway + opinion.mReputation = 0; +} + +std::ostream& RsGxsIdOpinionItem::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsGxsIdOpinionItem", indent); + uint16_t int_Indent = indent + 2; + + printIndent(out, int_Indent); + out << "Opinion: " << opinion.mOpinion << std::endl; + + printRsItemEnd(out ,"RsGxsIdOpinionItem", indent); + return out; +} + + +uint32_t RsGxsIdSerialiser::sizeGxsIdOpinionItem(RsGxsIdOpinionItem *item) +{ + + const RsGxsIdOpinion& opinion = item->opinion; + uint32_t s = 8; // header + + s += 4; // mOpinion. + + return s; +} + +bool RsGxsIdSerialiser::serialiseGxsIdOpinionItem(RsGxsIdOpinionItem *item, void *data, uint32_t *size) +{ + +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::serialiseGxsIdOpinionItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsIdOpinionItem(item); + uint32_t offset = 0; + + if(*size < tlvsize) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::serialiseGxsIdOpinionItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsIdOpinionItem */ + ok &= setRawUInt32(data, tlvsize, &offset, item->opinion.mOpinion); + + if(offset != tlvsize) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::serialiseGxsIdOpinionItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef GXSID_DEBUG + if (!ok) + { + std::cerr << "RsGxsIdSerialiser::serialiseGxsIdgroupItem() NOK" << std::endl; + } +#endif + + return ok; + } + +RsGxsIdOpinionItem* RsGxsIdSerialiser::deserialiseGxsIdOpinionItem(void *data, uint32_t *size) +{ + +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdOpinionItem()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_GXSID != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_GXSID_OPINION_ITEM != getRsItemSubType(rstype))) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdOpinionItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdOpinionItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsIdOpinionItem* item = new RsGxsIdOpinionItem(); + /* skip the header */ + offset += 8; + + ok &= getRawUInt32(data, rssize, &offset, &(item->opinion.mOpinion)); + + if (offset != rssize) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdOpinionItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdOpinionItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + + +void RsGxsIdCommentItem::clear() +{ + comment.mComment.clear(); +} + +std::ostream& RsGxsIdCommentItem::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsGxsIdCommentItem", indent); + uint16_t int_Indent = indent + 2; + + printIndent(out, int_Indent); + out << "Comment: " << comment.mComment << std::endl; + + printRsItemEnd(out ,"RsGxsIdCommentItem", indent); + return out; +} + + +uint32_t RsGxsIdSerialiser::sizeGxsIdCommentItem(RsGxsIdCommentItem *item) +{ + + const RsGxsIdComment& comment = item->comment; + uint32_t s = 8; // header + + s += 4; // mIdType. + s += GetTlvStringSize(comment.mComment); + + return s; +} + +bool RsGxsIdSerialiser::serialiseGxsIdCommentItem(RsGxsIdCommentItem *item, void *data, uint32_t *size) +{ + +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::serialiseGxsIdCommentItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsIdCommentItem(item); + uint32_t offset = 0; + + if(*size < tlvsize) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::serialiseGxsIdCommentItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsIdCommentItem */ + ok &= SetTlvString(data, tlvsize, &offset, 1, item->comment.mComment); + + if(offset != tlvsize) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::serialiseGxsIdCommentItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef GXSID_DEBUG + if (!ok) + { + std::cerr << "RsGxsIdSerialiser::serialiseGxsIdgroupItem() NOK" << std::endl; + } +#endif + + return ok; + } + +RsGxsIdCommentItem* RsGxsIdSerialiser::deserialiseGxsIdCommentItem(void *data, uint32_t *size) +{ + +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdCommentItem()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_GXSID != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_GXSID_COMMENT_ITEM != getRsItemSubType(rstype))) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdCommentItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdCommentItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsIdCommentItem* item = new RsGxsIdCommentItem(); + /* skip the header */ + offset += 8; + + ok &= GetTlvString(data, rssize, &offset, 1, item->comment.mComment); + + if (offset != rssize) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdCommentItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsIdSerialiser::deserialiseGxsIdCommentItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 673973549..066d6ce0d 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -57,19 +57,23 @@ p3IdService::p3IdService(RsGeneralDataService *gds, RsNetworkExchangeService *ne } -int p3IdService::internal_tick() +void p3IdService::service_tick() { - std::cerr << "p3IdService::internal_tick()"; + std::cerr << "p3IdService::service_tick()"; std::cerr << std::endl; // Disable for now. // background_tick(); - cache_tick(); + //cache_tick(); - return 0; + return; } +void p3IdService::notifyChanges(std::vector &changes) +{ + receiveChanges(changes); +} /********************************************************************************/ /******************* RsIdentity Interface ***************************************/ diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index 7089273d5..7096ad3bc 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -102,12 +102,14 @@ class LruData // Not sure exactly what should be inherited here? // Chris - please correct as necessary. -class p3IdService: public RsGxsIdExchange, public RsIdentity +class p3IdService: + public RsGxsIdExchange, + public RsIdentity { public: p3IdService(RsGeneralDataService* gds, RsNetworkExchangeService* nes); - virtual int internal_tick(); // needed for background processing. + virtual void service_tick(); // needed for background processing. /* General Interface is provided by RsIdentity / RsGxsIfaceImpl. */ @@ -155,6 +157,12 @@ virtual int getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key); // get Reputation. virtual bool getReputation(const RsGxsId &id, const GixsReputation &rep); + + protected: + + /** Notifications **/ + virtual void notifyChanges(std::vector& changes); + private: /************************************************************************ diff --git a/libretroshare/src/services/p3idserviceVEG.h b/libretroshare/src/services/p3idserviceVEG.h index 3553612a4..d0618b1d4 100644 --- a/libretroshare/src/services/p3idserviceVEG.h +++ b/libretroshare/src/services/p3idserviceVEG.h @@ -23,8 +23,8 @@ * */ -#ifndef P3_IDENTITY_SERVICE_HEADER -#define P3_IDENTITY_SERVICE_HEADER +#ifndef P3_IDENTITY_SERVICE_VEG_HEADER +#define P3_IDENTITY_SERVICE_VEG_HEADER #include "services/p3service.h" #include "services/p3gxsserviceVEG.h" From da70036f0f4de1f7f4480e2346741addcd6943bf Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Mon, 29 Oct 2012 22:41:41 +0000 Subject: [PATCH 112/222] fixed window minupnpc source, header file incorrect got Topic creation working with Posted GUI/backend refactored Posted/PostedGroupDialog to posted folder git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5742 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/serialiser/rsposteditems.h | 2 + libretroshare/src/services/p3posted.cc | 2 +- .../src/upnp/upnphandler_miniupnp.cc | 3 +- retroshare-gui/src/RetroShare.pro | 8 +- .../gui/{gxs => Posted}/PostedGroupDialog.cpp | 80 +- .../gui/{gxs => Posted}/PostedGroupDialog.h | 42 +- .../src/gui/Posted/PostedListDialog.cpp | 144 ++-- .../src/gui/Posted/PostedListDialog.h | 13 + retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp | 728 +++++++----------- retroshare-gui/src/gui/gxs/GxsGroupDialog.h | 100 ++- 10 files changed, 541 insertions(+), 581 deletions(-) rename retroshare-gui/src/gui/{gxs => Posted}/PostedGroupDialog.cpp (50%) rename retroshare-gui/src/gui/{gxs => Posted}/PostedGroupDialog.h (54%) diff --git a/libretroshare/src/serialiser/rsposteditems.h b/libretroshare/src/serialiser/rsposteditems.h index 7ff748c44..d7212c3f8 100644 --- a/libretroshare/src/serialiser/rsposteditems.h +++ b/libretroshare/src/serialiser/rsposteditems.h @@ -68,6 +68,8 @@ public: class RsGxsPostedSerialiser : public RsSerialType { +public: + RsGxsPostedSerialiser() : RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXSV1_TYPE_PHOTO) { return; } diff --git a/libretroshare/src/services/p3posted.cc b/libretroshare/src/services/p3posted.cc index fb03dce05..ff16734f7 100644 --- a/libretroshare/src/services/p3posted.cc +++ b/libretroshare/src/services/p3posted.cc @@ -8,7 +8,7 @@ const uint32_t RsPosted::FLAG_MSGTYPE_VOTE = 0x0004; RsPosted *rsPosted = NULL; p3Posted::p3Posted(RsGeneralDataService *gds, RsNetworkExchangeService *nes) - : RsGenExchange(gds, nes, NULL, RS_SERVICE_GXSV1_TYPE_POSTED), RsPosted(this) + : RsGenExchange(gds, nes, new RsGxsPostedSerialiser(), RS_SERVICE_GXSV1_TYPE_POSTED), RsPosted(this) { } diff --git a/libretroshare/src/upnp/upnphandler_miniupnp.cc b/libretroshare/src/upnp/upnphandler_miniupnp.cc index 5d3937ca1..b4cb3c199 100644 --- a/libretroshare/src/upnp/upnphandler_miniupnp.cc +++ b/libretroshare/src/upnp/upnphandler_miniupnp.cc @@ -10,7 +10,7 @@ extern "C" { #endif /* This stuff is actually C */ -#include "upnp/upnphandler.h" +#include "upnp/upnphandler_miniupnp.h" #include "upnp/upnputil.h" class uPnPConfigData @@ -402,6 +402,7 @@ bool upnphandler::shutdown_upnp() * */ + upnphandler::upnphandler() : dataMtx("upnpState"), toEnable(false), toStart(false), toStop(false), eport(0), eport_curr(0), diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index 0cee20122..1e27b598e 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -987,7 +987,8 @@ posted { gui/Posted/PostedListDialog.h \ gui/Posted/PostedItem.h \ gui/Posted/PostedComments.h \ - util/TokenQueueVEG.h + util/TokenQueueVEG.h \ + gui/Posted/PostedGroupDialog.h \ FORMS += gui/Posted/PostedDialog.ui \ gui/Posted/PostedListDialog.ui \ @@ -998,14 +999,14 @@ posted { gui/Posted/PostedListDialog.cpp \ gui/Posted/PostedItem.cpp \ gui/Posted/PostedComments.cpp \ - util/TokenQueueVEG.cpp + util/TokenQueueVEG.cpp \ + gui/Posted/PostedGroupDialog.cpp } gxsgui { HEADERS += gui/gxs/GxsGroupDialog.h \ - gui/gxs/PostedGroupDialog.h \ gui/gxs/GxsCommentTreeWidget.h # gui/gxs/ForumV2GroupDialog.h \ # gui/gxs/WikiGroupDialog.h \ @@ -1017,7 +1018,6 @@ gxsgui { # gui/gxs/GxsCommentTreeWidget.ui \ SOURCES += gui/gxs/GxsGroupDialog.cpp \ - gui/gxs/PostedGroupDialog.cpp \ gui/gxs/GxsCommentTreeWidget.cpp #gui/gxs/ForumV2GroupDialog.cpp \ # gui/gxs/WikiGroupDialog.cpp \ diff --git a/retroshare-gui/src/gui/gxs/PostedGroupDialog.cpp b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp similarity index 50% rename from retroshare-gui/src/gui/gxs/PostedGroupDialog.cpp rename to retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp index e7600a997..93d0a5164 100644 --- a/retroshare-gui/src/gui/gxs/PostedGroupDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp @@ -20,12 +20,13 @@ ****************************************************************/ #include "PostedGroupDialog.h" +#include "util/TokenQueue.h" #include #include -PostedGroupDialog::PostedGroupDialog(QWidget *parent) - :GxsGroupDialog(rsPosted->getTokenService(), parent) +PostedGroupDialog::PostedGroupDialog(TokenQueue* tokenQueue, QWidget *parent) + :GxsGroupDialog(tokenQueue, parent, GXS_GROUP_DIALOG_CREATE_MODE) { // To start with we only have open forums - with distribution controls. @@ -41,24 +42,40 @@ PostedGroupDialog::PostedGroupDialog(QWidget *parent) uint32_t readonlyFlags = 0; - uint32_t defaultsFlags = ( //GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC | - //GXS_GROUP_DEFAULTS_DISTRIB_GROUP | - GXS_GROUP_DEFAULTS_DISTRIB_LOCAL | - - //GXS_GROUP_DEFAULTS_PUBLISH_OPEN | - //GXS_GROUP_DEFAULTS_PUBLISH_THREADS | - GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED | - //GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED | - - //GXS_GROUP_DEFAULTS_PERSONAL_GPG | - //GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED | - GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | - - //GXS_GROUP_DEFAULTS_COMMENTS_YES | - GXS_GROUP_DEFAULTS_COMMENTS_NO | + uint32_t defaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_LOCAL | + GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED | + GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | + GXS_GROUP_DEFAULTS_COMMENTS_NO | 0); - setFlags(enabledFlags, readonlyFlags, defaultsFlags); + setFlags(enabledFlags, defaultsFlags); + +} + +PostedGroupDialog::PostedGroupDialog(const RsPostedGroup &grp, QWidget *parent) + :GxsGroupDialog(NULL, parent, GXS_GROUP_DIALOG_SHOW_MODE), mGrp(grp) +{ + + // To start with we only have open forums - with distribution controls. + + uint32_t enabledFlags = ( GXS_GROUP_FLAGS_ICON | + GXS_GROUP_FLAGS_DESCRIPTION | + GXS_GROUP_FLAGS_DISTRIBUTION | + GXS_GROUP_FLAGS_PUBLISHSIGN | + GXS_GROUP_FLAGS_SHAREKEYS | + GXS_GROUP_FLAGS_PERSONALSIGN | + GXS_GROUP_FLAGS_COMMENTS | + 0); + + uint32_t readonlyFlags = 0; + + uint32_t defaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_LOCAL | + GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED | + GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | + GXS_GROUP_DEFAULTS_COMMENTS_NO | + 0); + + setFlags(enabledFlags, defaultsFlags); } @@ -68,31 +85,24 @@ bool PostedGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaDa // Specific Function. RsPostedGroup grp; grp.mMeta = meta; - //grp.mDescription = std::string(desc.toUtf8()); rsPosted->submitGroup(token, grp); return true; } -void PostedGroupDialog::service_loadExistingGroup(const uint32_t &token) +QPixmap PostedGroupDialog::service_getLogo() { - std::cerr << "PostedGroupDialog::service_loadExistingGroup()"; - std::cerr << std::endl; + return QPixmap(); // null pixmap +} - RsPostedGroup group; - if (!rsPosted->getGroup(token, group)) - { - std::cerr << "PostedGroupDialog::service_loadExistingGroup() ERROR Getting Group"; - std::cerr << std::endl; - - return; - } - - /* must call metadata loader */ - loadExistingGroupMetaData(group.mMeta); - - /* now load any extra data we feel like */ +QString PostedGroupDialog::service_getDescription() +{ + return QString(); +} +RsGroupMetaData PostedGroupDialog::service_getMeta() +{ + return mGrp.mMeta; } diff --git a/retroshare-gui/src/gui/gxs/PostedGroupDialog.h b/retroshare-gui/src/gui/Posted/PostedGroupDialog.h similarity index 54% rename from retroshare-gui/src/gui/gxs/PostedGroupDialog.h rename to retroshare-gui/src/gui/Posted/PostedGroupDialog.h index f9ef3d8cc..7d832fae1 100644 --- a/retroshare-gui/src/gui/gxs/PostedGroupDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedGroupDialog.h @@ -23,20 +23,52 @@ #ifndef _POSTED_GROUP_DIALOG_H #define _POSTED_GROUP_DIALOG_H -#include "GxsGroupDialog.h" +#include "gui/gxs/GxsGroupDialog.h" +#include "retroshare/rsposted.h" class PostedGroupDialog : public GxsGroupDialog { Q_OBJECT public: - PostedGroupDialog(QWidget *parent); + + /*! + * This constructs a create dialog + */ + PostedGroupDialog(TokenQueue* tokenQueue, QWidget *parent = NULL); + + /*! + * This constructs a show dialog which displays an already existing group + */ + PostedGroupDialog(const RsPostedGroup& grp, QWidget *parent = NULL); protected: - virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); -// virtual bool service_CompleteCreateGroup(const RsGroupMetaData &meta); - virtual void service_loadExistingGroup(const uint32_t &token); + bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); + + /*! + * This should return a group logo \n + * Will be called when GxsGroupDialog is initialised in show mode + * + */ + virtual QPixmap service_getLogo(); + + /*! + * This should return a group description string + * @return group description string + */ + virtual QString service_getDescription(); + + /*! + * Used in show mode, returns a meta type + * @return the meta of existing grpMeta + */ + virtual RsGroupMetaData service_getMeta(); + + +private: + + RsPostedGroup mGrp; }; diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp index 87f1e31b5..ba74ae4b6 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp @@ -23,9 +23,10 @@ #include "PostedListDialog.h" -#include "gui/gxs/PostedGroupDialog.h" +#include "gui/Posted/PostedGroupDialog.h" #include +#include #include #include @@ -276,9 +277,7 @@ void PostedListDialog::periodChanged( int index ) void PostedListDialog::newGroup() { - PostedGroupDialog cf (this); - cf.newGroup(); - + PostedGroupDialog cf (mPostedQueue, this); cf.exec (); } @@ -289,38 +288,16 @@ void PostedListDialog::showGroupDetails() return; } - PostedGroupDialog cf (this); - cf.existingGroup(mCurrTopicId, GXS_GROUP_DIALOG_SHOW_MODE); - + PostedGroupDialog cf(mGroups[mCurrTopicId], this); cf.exec (); } void PostedListDialog::editGroupDetails() { - if (mCurrTopicId.empty()) - { - return; - } - - PostedGroupDialog cf (this); - cf.existingGroup(mCurrTopicId, GXS_GROUP_DIALOG_EDIT_MODE); - - cf.exec (); + } -/*********************** **** **** **** ***********************/ -/** Request / Response of Data ********************************/ -/*********************** **** **** **** ***********************/ - -#define POSTEDDIALOG_LISTING 1 -#define POSTEDDIALOG_CURRENTFORUM 2 -#define POSTEDDIALOG_INSERTTHREADS 3 -#define POSTEDDIALOG_INSERTCHILD 4 -#define POSTEDDIALOG_INSERT_POST 5 -#define POSTEDDIALOG_REPLY_MESSAGE 6 - - void PostedListDialog::insertGroups() { requestGroupSummary(); @@ -337,6 +314,23 @@ void PostedListDialog::requestGroupSummary() mPostedQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, ids, POSTEDDIALOG_LISTING); } +void PostedListDialog::acknowledgeGroup(const uint32_t &token) +{ + RsGxsGroupId grpId; + rsPosted->acknowledgeGrp(token, grpId); + + if(!grpId.empty()) + { + std::list grpIds; + grpIds.push_back(grpId); + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; + uint32_t reqToken; + mPostedQueue->requestGroupInfo(reqToken, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, 0); + } +} + void PostedListDialog::loadGroupSummary(const uint32_t &token) { std::cerr << "PostedListDialog::loadGroupSummary()"; @@ -557,24 +551,26 @@ void PostedListDialog::loadRequest(const TokenQueue *queue, const TokenRequest & if (queue == mPostedQueue) { /* now switch on req */ - switch(req.mUserType) + switch(req.mType) { - case POSTEDDIALOG_LISTING: - loadGroupSummary(req.mToken); - break; + case TOKENREQ_GROUPINFO: + switch(req.mAnsType) + { - case POSTEDDIALOG_CURRENTFORUM: - loadGroupSummary_CurrentForum(req.mToken); - break; - - case POSTEDDIALOG_INSERTTHREADS: - loadGroupThreadData_InsertThreads(req.mToken); - break; - - default: - std::cerr << "PostedListDialog::loadRequest() ERROR: INVALID TYPE"; - std::cerr << std::endl; - break; + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgeGroup(req.mToken); + break; + case RS_TOKREQ_ANSTYPE_SUMMARY: + loadGroupSummary(req.mToken); + default: + std::cerr << "Error, unexpected anstype:" << req.mAnsType << std::endl; + break; + } + break; + default: + std::cerr << "PostedListDialog::loadRequest() ERROR: INVALID TYPE"; + std::cerr << std::endl; + break; } } } @@ -589,12 +585,72 @@ void PostedListDialog::loadRequest(const TokenQueue *queue, const TokenRequest & void PostedListDialog::groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo &groupItemInfo) { + groupItemInfo.id = QString::fromStdString(groupInfo.mGroupId); +groupItemInfo.name = QString::fromUtf8(groupInfo.mGroupName.c_str()); +//groupItemInfo.description = QString::fromUtf8(groupInfo.forumDesc); +groupItemInfo.popularity = groupInfo.mPop; +groupItemInfo.lastpost = QDateTime::fromTime_t(groupInfo.mLastPost); + } void PostedListDialog::insertGroupData(const std::list &groupList) { + std::list::const_iterator it; + + QList adminList; + QList subList; + QList popList; + QList otherList; + std::multimap popMap; + + for (it = groupList.begin(); it != groupList.end(); it++) { + /* sort it into Publish (Own), Subscribed, Popular and Other */ + uint32_t flags = it->mSubscribeFlags; + + GroupItemInfo groupItemInfo; + groupInfoToGroupItemInfo(*it, groupItemInfo); + + // if (flags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) { + adminList.push_back(groupItemInfo); + // } else if (flags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) { + /* subscribed forum */ + // subList.push_back(groupItemInfo); + // } else { + /* rate the others by popularity */ +// popMap.insert(std::make_pair(it->mPop, groupItemInfo)); + } +// } + + /* iterate backwards through popMap - take the top 5 or 10% of list */ + uint32_t popCount = 5; + if (popCount < popMap.size() / 10) + { + popCount = popMap.size() / 10; + } + + uint32_t i = 0; + uint32_t popLimit = 0; + std::multimap::reverse_iterator rit; + for(rit = popMap.rbegin(); ((rit != popMap.rend()) && (i < popCount)); rit++, i++) ; + if (rit != popMap.rend()) { + popLimit = rit->first; + } + + for (rit = popMap.rbegin(); rit != popMap.rend(); rit++) { + if (rit->second.popularity < (int) popLimit) { + otherList.append(rit->second); + } else { + popList.append(rit->second); + } + } + + /* now we can add them in as a tree! */ + ui.groupTreeWidget->fillGroupItems(yourTopics, adminList); + ui.groupTreeWidget->fillGroupItems(subscribedTopics, subList); + ui.groupTreeWidget->fillGroupItems(popularTopics, popList); + ui.groupTreeWidget->fillGroupItems(otherTopics, otherList); } /**************************************************************************************/ diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.h b/retroshare-gui/src/gui/Posted/PostedListDialog.h index 104ca6e20..52e2367d1 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.h @@ -38,6 +38,17 @@ #include "retroshare-gui/RsAutoUpdatePage.h" +/*********************** **** **** **** ***********************/ +/** Request / Response of Data ********************************/ +/*********************** **** **** **** ***********************/ + +#define POSTEDDIALOG_LISTING 1 +#define POSTEDDIALOG_CURRENTFORUM 2 +#define POSTEDDIALOG_INSERTTHREADS 3 +#define POSTEDDIALOG_INSERTCHILD 4 +#define POSTEDDIALOG_INSERT_POST 5 +#define POSTEDDIALOG_REPLY_MESSAGE 6 + class PostedListDialog : public RsAutoUpdatePage, public PostedHolder, public TokenResponse { Q_OBJECT @@ -75,6 +86,7 @@ void loadPost(const RsPostedPost &post); void insertGroups(); void requestGroupSummary(); +void acknowledgeGroup(const uint32_t &token); void loadGroupSummary(const uint32_t &token); void requestGroupSummary_CurrentForum(const std::string &forumId); @@ -103,6 +115,7 @@ void groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo & bool mThreadLoading; std::string mCurrTopicId; + QMap mGroups; TokenQueue *mPostedQueue; /* UI - from Designer */ diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index 230e6f5eb..d196e4e55 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -50,100 +50,83 @@ #define GXSGROUP_LOADGROUP 2 /** Constructor */ -GxsGroupDialog::GxsGroupDialog(RsTokenService *service, QWidget *parent) -: QDialog(parent), mRsService(service) +GxsGroupDialog::GxsGroupDialog(TokenQueue* tokenQueue, QWidget *parent, uint32_t mode) +: QDialog(parent), mTokenQueue(tokenQueue), mMode(mode) { - /* Invoke the Qt Designer generated object setup routine */ - ui.setupUi(this); + /* Invoke the Qt Designer generated object setup routine */ + ui.setupUi(this); - mTokenQueue = new TokenQueue(service, this); + // connect up the buttons. + connect( ui.cancelButton, SIGNAL( clicked ( bool ) ), this, SLOT( cancelDialog( ) ) ); + connect( ui.createButton, SIGNAL( clicked ( bool ) ), this, SLOT( submitGroup( ) ) ); + connect( ui.pubKeyShare_cb, SIGNAL( clicked() ), this, SLOT( setShareList( ) )); - // connect up the buttons. - connect( ui.cancelButton, SIGNAL( clicked ( bool ) ), this, SLOT( cancelDialog( ) ) ); - connect( ui.createButton, SIGNAL( clicked ( bool ) ), this, SLOT( submitGroup( ) ) ); - connect( ui.pubKeyShare_cb, SIGNAL( clicked() ), this, SLOT( setShareList( ) )); + connect( ui.groupLogo, SIGNAL(clicked() ), this , SLOT(addGroupLogo())); + connect( ui.addLogoButton, SIGNAL(clicked() ), this , SLOT(addGroupLogo())); - connect( ui.groupLogo, SIGNAL(clicked() ), this , SLOT(addGroupLogo())); - connect( ui.addLogoButton, SIGNAL(clicked() ), this , SLOT(addGroupLogo())); + if (!ui.pubKeyShare_cb->isChecked()) { + ui.contactsdockWidget->hide(); + this->resize(this->size().width() - ui.contactsdockWidget->size().width(), this->size().height()); + } - if (!ui.pubKeyShare_cb->isChecked()) { - ui.contactsdockWidget->hide(); - this->resize(this->size().width() - ui.contactsdockWidget->size().width(), this->size().height()); - } - - /* initialize key share list */ - ui.keyShareList->setHeaderText(tr("Contacts:")); - ui.keyShareList->setModus(FriendSelectionWidget::MODUS_CHECK); - ui.keyShareList->start(); + /* initialize key share list */ + ui.keyShareList->setHeaderText(tr("Contacts:")); + ui.keyShareList->setModus(FriendSelectionWidget::MODUS_CHECK); + ui.keyShareList->start(); - /* Setup Reasonable Defaults */ + /* Setup Reasonable Defaults */ - uint32_t enabledFlags = ( GXS_GROUP_FLAGS_ICON | - GXS_GROUP_FLAGS_DESCRIPTION | - GXS_GROUP_FLAGS_DISTRIBUTION | - GXS_GROUP_FLAGS_PUBLISHSIGN | - GXS_GROUP_FLAGS_SHAREKEYS | - GXS_GROUP_FLAGS_PERSONALSIGN | - GXS_GROUP_FLAGS_COMMENTS ); + uint32_t enabledFlags = ( GXS_GROUP_FLAGS_ICON | + GXS_GROUP_FLAGS_DESCRIPTION | + GXS_GROUP_FLAGS_DISTRIBUTION | + GXS_GROUP_FLAGS_PUBLISHSIGN | + GXS_GROUP_FLAGS_SHAREKEYS | + GXS_GROUP_FLAGS_PERSONALSIGN | + GXS_GROUP_FLAGS_COMMENTS ); - uint32_t readonlyFlags = 0; - uint32_t defaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC | - //GXS_GROUP_DEFAULTS_DISTRIB_GROUP | - //GXS_GROUP_DEFAULTS_DISTRIB_LOCAL | - - //GXS_GROUP_DEFAULTS_PUBLISH_OPEN | - GXS_GROUP_DEFAULTS_PUBLISH_THREADS | - //GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED | - //GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED | - - //GXS_GROUP_DEFAULTS_PERSONAL_GPG | - //GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED | - GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | - - GXS_GROUP_DEFAULTS_COMMENTS_YES | - //GXS_GROUP_DEFAULTS_COMMENTS_NO | - 0); - - setFlags(enabledFlags, readonlyFlags, defaultsFlags); + uint32_t defaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC | + GXS_GROUP_DEFAULTS_PUBLISH_THREADS | + GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | + GXS_GROUP_DEFAULTS_COMMENTS_YES | + 0); + setFlags(enabledFlags, defaultsFlags); + setMode(mode); } -void GxsGroupDialog::setFlags(uint32_t enabledFlags, uint32_t readonlyFlags, uint32_t defaultsFlags) +void GxsGroupDialog::setFlags(uint32_t enabledFlags, uint32_t defaultsFlags) { - mEnabledFlags = enabledFlags; - mReadonlyFlags = readonlyFlags; - mDefaultsFlags = defaultsFlags; + mEnabledFlags = enabledFlags; + mDefaultsFlags = defaultsFlags; } void GxsGroupDialog::setMode(uint32_t mode) { - mMode = mode; + switch(mMode) + { + case GXS_GROUP_DIALOG_CREATE_MODE: + { + ui.createButton->setText(tr("Create Group")); + newGroup(); + } + break; - /* switch depending on mode */ - switch(mMode) - { - case GXS_GROUP_DIALOG_CREATE_MODE: - { - ui.createButton->setText(tr("Create Group")); - } - break; + default: + case GXS_GROUP_DIALOG_SHOW_MODE: + { + ui.cancelButton->setVisible(false); + ui.createButton->setText(tr("Close")); + } + break; - default: - case GXS_GROUP_DIALOG_SHOW_MODE: - { - ui.cancelButton->setVisible(false); - ui.createButton->setText(tr("Close")); - } - break; - - case GXS_GROUP_DIALOG_EDIT_MODE: - { - ui.createButton->setText(tr("Submit Changes")); - } - break; - } +// case GXS_GROUP_DIALOG_EDIT_MODE: +// { +// ui.createButton->setText(tr("Submit Changes")); +// } +// break; + } } @@ -151,7 +134,6 @@ void GxsGroupDialog::clearForm() { ui.groupName->clear(); ui.groupDesc->clear(); - ui.groupName->setFocus(); } @@ -160,359 +142,270 @@ void GxsGroupDialog::setupDefaults() { /* Enable / Show Parts based on Flags */ - if (mDefaultsFlags & GXS_GROUP_DEFAULTS_DISTRIB_MASK) - { - if (mDefaultsFlags & GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC) - { - ui.typePublic->setChecked(true); - } - else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_DISTRIB_GROUP) - { - ui.typeGroup->setChecked(true); - } - else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_DISTRIB_LOCAL) - { - ui.typeLocal->setChecked(true); - } - else - { - // default - ui.typePublic->setChecked(true); - } - } + if (mDefaultsFlags & GXS_GROUP_DEFAULTS_DISTRIB_MASK) + { + if (mDefaultsFlags & GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC) + { + ui.typePublic->setChecked(true); + } + else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_DISTRIB_GROUP) + { + ui.typeGroup->setChecked(true); + } + else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_DISTRIB_LOCAL) + { + ui.typeLocal->setChecked(true); + } + else + { + // default + ui.typePublic->setChecked(true); + } + } - if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PUBLISH_MASK) - { - if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED) - { - ui.publish_encrypt->setChecked(true); - } - else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED) - { - ui.publish_required->setChecked(true); - } - else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PUBLISH_THREADS) - { - ui.publish_threads->setChecked(true); - } - else - { - // default - ui.publish_open->setChecked(true); - } - } + if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PUBLISH_MASK) + { + if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED) + { + ui.publish_encrypt->setChecked(true); + } + else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED) + { + ui.publish_required->setChecked(true); + } + else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PUBLISH_THREADS) + { + ui.publish_threads->setChecked(true); + } + else + { + // default + ui.publish_open->setChecked(true); + } + } - if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PERSONAL_MASK) - { - if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PERSONAL_PGP) - { - ui.personal_pgp->setChecked(true); - } - else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED) - { - ui.personal_required->setChecked(true); - } - else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB) - { - ui.personal_ifnopub->setChecked(true); - } - else - { - // default - ui.personal_ifnopub->setChecked(true); - } - } + if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PERSONAL_MASK) + { + if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PERSONAL_PGP) + { + ui.personal_pgp->setChecked(true); + } + else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED) + { + ui.personal_required->setChecked(true); + } + else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB) + { + ui.personal_ifnopub->setChecked(true); + } + else + { + // default + ui.personal_ifnopub->setChecked(true); + } + } - if (mDefaultsFlags & GXS_GROUP_DEFAULTS_COMMENTS_MASK) - { - if (mDefaultsFlags & GXS_GROUP_DEFAULTS_COMMENTS_YES) - { - ui.comments_allowed->setChecked(true); - } - else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_COMMENTS_NO) - { - ui.comments_no->setChecked(true); - } - else - { - // default - ui.comments_no->setChecked(true); - } - - } + if (mDefaultsFlags & GXS_GROUP_DEFAULTS_COMMENTS_MASK) + { + if (mDefaultsFlags & GXS_GROUP_DEFAULTS_COMMENTS_YES) + { + ui.comments_allowed->setChecked(true); + } + else if (mDefaultsFlags & GXS_GROUP_DEFAULTS_COMMENTS_NO) + { + ui.comments_no->setChecked(true); + } + else + { + // default + ui.comments_no->setChecked(true); + } + } } void GxsGroupDialog::setupVisibility() { - { - ui.groupLogo->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ICON); - ui.addLogoButton->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ICON); - } + { + ui.groupLogo->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ICON); + ui.addLogoButton->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ICON); + } - { - ui.groupDesc->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DESCRIPTION); - ui.groupDescLabel->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DESCRIPTION); - } + { + ui.groupDesc->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DESCRIPTION); + ui.groupDescLabel->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DESCRIPTION); + } - { - ui.distribGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DISTRIBUTION); - } + { + ui.distribGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DISTRIBUTION); + } - { - ui.publishGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_PUBLISHSIGN); - } + { + ui.publishGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_PUBLISHSIGN); + } - { - ui.pubKeyShare_cb->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_SHAREKEYS); - } + { + ui.pubKeyShare_cb->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_SHAREKEYS); + } - { - ui.personalGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_PERSONALSIGN); - } + { + ui.personalGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_PERSONALSIGN); + } - { - ui.commentGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_COMMENTS); - } + { + ui.commentGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_COMMENTS); + } - { - ui.extraFrame->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_EXTRA); - } + { + ui.extraFrame->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_EXTRA); + } } void GxsGroupDialog::newGroup() { - setupDefaults(); - setupVisibility(); - clearForm(); + setupDefaults(); + setupVisibility(); + clearForm(); - setMode(GXS_GROUP_DIALOG_CREATE_MODE); - - service_NewGroup(); } -void GxsGroupDialog::existingGroup(std::string groupId, uint32_t mode) +void GxsGroupDialog::loadExistingGroupMetaData(const RsGroupMetaData &meta) { - setupDefaults(); - setupVisibility(); - clearForm(); + /* should set stuff - according to parameters */ + setGroupSignFlags(meta.mSignFlags); + ui.groupName->setText(QString::fromUtf8(meta.mGroupName.c_str())); - setMode(mode); - - service_ExistingGroup(); - - /* request data */ - { - RsTokReqOptions opts; - - std::list grpIds; - grpIds.push_back(groupId); - - std::cerr << "GxsGroupDialog::existingGroup() Requesting Data."; - std::cerr << std::endl; - - uint32_t token; - mTokenQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, GXSGROUP_LOADGROUP); - } -} - -bool GxsGroupDialog::loadExistingGroupMetaData(const RsGroupMetaData &meta) -{ - /* should set stuff - according to parameters */ - setGroupSignFlags(meta.mSignFlags); - ui.groupName->setText(QString::fromUtf8(meta.mGroupName.c_str())); - - return true; -} - - - -bool GxsGroupDialog::service_NewGroup() -{ - /* setup any extra bits */ - return true; -} - - -bool GxsGroupDialog::service_ExistingGroup() -{ - /* setup any extra bits */ - return true; + return; } void GxsGroupDialog::submitGroup() { - std::cerr << "GxsGroupDialog::submitGroup()"; - std::cerr << std::endl; + std::cerr << "GxsGroupDialog::submitGroup()"; + std::cerr << std::endl; - /* switch depending on mode */ - switch(mMode) - { - case GXS_GROUP_DIALOG_CREATE_MODE: - { - /* just close if down */ - createGroup(); - } - break; + /* switch depending on mode */ + switch(mMode) + { + case GXS_GROUP_DIALOG_CREATE_MODE: + { + /* just close if down */ + createGroup(); + } + break; - default: - case GXS_GROUP_DIALOG_SHOW_MODE: - { - /* just close if down */ - cancelDialog(); - } - break; + default: + case GXS_GROUP_DIALOG_SHOW_MODE: + { + /* just close if down */ + cancelDialog(); + } + break; - case GXS_GROUP_DIALOG_EDIT_MODE: - { - /* TEMP: just close if down */ - cancelDialog(); - } - break; - } + case GXS_GROUP_DIALOG_EDIT_MODE: + { + /* TEMP: just close if down */ + cancelDialog(); + } + break; + } } - - - - - void GxsGroupDialog::createGroup() { - QString name = misc::removeNewLine(ui.groupName->text()); - QString desc = ui.groupDesc->toPlainText(); //toHtml(); - uint32_t flags = 0; + QString name = misc::removeNewLine(ui.groupName->text()); + uint32_t flags = 0; - if(name.isEmpty()) - { - /* error message */ - QMessageBox::warning(this, "RetroShare", tr("Please add a Name"), QMessageBox::Ok, QMessageBox::Ok); - return; //Don't add a empty name!! - } + if(name.isEmpty()) + { + /* error message */ + QMessageBox::warning(this, "RetroShare", tr("Please add a Name"), QMessageBox::Ok, QMessageBox::Ok); + return; //Don't add a empty name!! + } - if (mRsService) - { - - uint32_t token; - RsGroupMetaData meta; + uint32_t token; + RsGroupMetaData meta; - // Fill in the MetaData as best we can. - meta.mGroupName = std::string(name.toUtf8()); - //meta.mDesc = std::string(desc.toUtf8()); + // Fill in the MetaData as best we can. + meta.mGroupName = std::string(name.toUtf8()); - meta.mGroupFlags = flags; - meta.mSignFlags = getGroupSignFlags(); + meta.mGroupFlags = flags; + meta.mSignFlags = getGroupSignFlags(); - // These ones shouldn't be needed here - but will be used, until we have fully functional backend. - meta.mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; - meta.mPublishTs = time(NULL); - - if (service_CreateGroup(token, meta)) - { - // get the Queue to handle response. - mTokenQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_SUMMARY, GXSGROUP_NEWGROUPID); - } - } + if (service_CreateGroup(token, meta)) + { + // get the Queue to handle response. + if(mTokenQueue != NULL) + mTokenQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, GXSGROUP_NEWGROUPID); + } + close(); } uint32_t GxsGroupDialog::getGroupSignFlags() { - /* grab from the ui options -> */ - uint32_t signFlags = 0; - if (ui.publish_encrypt->isChecked()) { - signFlags |= RSGXS_GROUP_SIGN_PUBLISH_ENCRYPTED; - } else if (ui.publish_required->isChecked()) { - signFlags |= RSGXS_GROUP_SIGN_PUBLISH_ALLSIGNED; - } else if (ui.publish_threads->isChecked()) { - signFlags |= RSGXS_GROUP_SIGN_PUBLISH_THREADHEAD; - } else { // publish_open (default). - signFlags |= RSGXS_GROUP_SIGN_PUBLISH_NONEREQ; - } + /* grab from the ui options -> */ + uint32_t signFlags = 0; + if (ui.publish_encrypt->isChecked()) { + signFlags |= RSGXS_GROUP_SIGN_PUBLISH_ENCRYPTED; + } else if (ui.publish_required->isChecked()) { + signFlags |= RSGXS_GROUP_SIGN_PUBLISH_ALLSIGNED; + } else if (ui.publish_threads->isChecked()) { + signFlags |= RSGXS_GROUP_SIGN_PUBLISH_THREADHEAD; + } else { // publish_open (default). + signFlags |= RSGXS_GROUP_SIGN_PUBLISH_NONEREQ; + } // Author Signature. - if (ui.personal_pgp->isChecked()) { - signFlags |= RSGXS_GROUP_SIGN_AUTHOR_GPG; - } else if (ui.personal_required->isChecked()) { - signFlags |= RSGXS_GROUP_SIGN_AUTHOR_REQUIRED; - } else if (ui.personal_ifnopub->isChecked()) { - signFlags |= RSGXS_GROUP_SIGN_AUTHOR_IFNOPUBSIGN; - } else { // shouldn't allow this one. - signFlags |= RSGXS_GROUP_SIGN_AUTHOR_NONE; - } - return signFlags; + if (ui.personal_pgp->isChecked()) { + signFlags |= RSGXS_GROUP_SIGN_AUTHOR_GPG; + } else if (ui.personal_required->isChecked()) { + signFlags |= RSGXS_GROUP_SIGN_AUTHOR_REQUIRED; + } else if (ui.personal_ifnopub->isChecked()) { + signFlags |= RSGXS_GROUP_SIGN_AUTHOR_IFNOPUBSIGN; + } else { // shouldn't allow this one. + signFlags |= RSGXS_GROUP_SIGN_AUTHOR_NONE; + } + return signFlags; } void GxsGroupDialog::setGroupSignFlags(uint32_t signFlags) { - if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_ENCRYPTED) { - ui.publish_encrypt->setChecked(true); - } else if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_ALLSIGNED) { - ui.publish_required->setChecked(true); - } else if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_THREADHEAD) { - ui.publish_threads->setChecked(true); - } else if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_NONEREQ) { - ui.publish_open->setChecked(true); - } - - if (signFlags & RSGXS_GROUP_SIGN_AUTHOR_GPG) { - ui.personal_pgp->setChecked(true); - } else if (signFlags & RSGXS_GROUP_SIGN_AUTHOR_REQUIRED) { - ui.personal_required->setChecked(true); - } else if (signFlags & RSGXS_GROUP_SIGN_AUTHOR_IFNOPUBSIGN) { - ui.personal_ifnopub->setChecked(true); - } else if (signFlags & RSGXS_GROUP_SIGN_AUTHOR_NONE) { - // Its the same... but not quite. - //ui.personal_noifpub->setChecked(); - } - - /* guess at comments */ - if ((signFlags & RSGXS_GROUP_SIGN_PUBLISH_THREADHEAD) - && (signFlags & RSGXS_GROUP_SIGN_AUTHOR_IFNOPUBSIGN)) - { - ui.comments_allowed->setChecked(true); - } - else - { - ui.comments_no->setChecked(true); - } + if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_ENCRYPTED) { + ui.publish_encrypt->setChecked(true); + } else if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_ALLSIGNED) { + ui.publish_required->setChecked(true); + } else if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_THREADHEAD) { + ui.publish_threads->setChecked(true); + } else if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_NONEREQ) { + ui.publish_open->setChecked(true); + } + if (signFlags & RSGXS_GROUP_SIGN_AUTHOR_GPG) { + ui.personal_pgp->setChecked(true); + } else if (signFlags & RSGXS_GROUP_SIGN_AUTHOR_REQUIRED) { + ui.personal_required->setChecked(true); + } else if (signFlags & RSGXS_GROUP_SIGN_AUTHOR_IFNOPUBSIGN) { + ui.personal_ifnopub->setChecked(true); + } else if (signFlags & RSGXS_GROUP_SIGN_AUTHOR_NONE) { + // Its the same... but not quite. + //ui.personal_noifpub->setChecked(); + } + /* guess at comments */ + if ((signFlags & RSGXS_GROUP_SIGN_PUBLISH_THREADHEAD) + && (signFlags & RSGXS_GROUP_SIGN_AUTHOR_IFNOPUBSIGN)) + { + ui.comments_allowed->setChecked(true); + } + else + { + ui.comments_no->setChecked(true); + } } - -bool GxsGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) -{ - token = 0; - return false; -} - -bool GxsGroupDialog::service_CompleteCreateGroup(const RsGroupMetaData &meta) -{ - /* dummy function - for overloading */ - return true; -} - -void GxsGroupDialog::completeCreateGroup(const RsGroupMetaData &newMeta) -{ - std::cerr << "GxsGroupDialog::completeCreateGroup() Created Group with MetaData: "; - std::cerr << std::endl; - std::cerr << newMeta; - std::cerr << std::endl; - - sendShareList(newMeta.mGroupId); - - service_CompleteCreateGroup(newMeta); - - std::cerr << "GxsGroupDialog::completeCreateGroup() Should Close!"; - std::cerr << std::endl; - - close(); -} - void GxsGroupDialog::cancelDialog() { std::cerr << "GxsGroupDialog::cancelDialog() Should Close!"; @@ -543,98 +436,17 @@ void GxsGroupDialog::addGroupLogo() void GxsGroupDialog::sendShareList(std::string groupId) { - close(); } void GxsGroupDialog::setShareList() { - if (ui.pubKeyShare_cb->isChecked()){ - this->resize(this->size().width() + ui.contactsdockWidget->size().width(), this->size().height()); - ui.contactsdockWidget->show(); - } else { // hide share widget - ui.contactsdockWidget->hide(); - this->resize(this->size().width() - ui.contactsdockWidget->size().width(), this->size().height()); - } + if (ui.pubKeyShare_cb->isChecked()){ + this->resize(this->size().width() + ui.contactsdockWidget->size().width(), this->size().height()); + ui.contactsdockWidget->show(); + } else { // hide share widget + ui.contactsdockWidget->hide(); + this->resize(this->size().width() - ui.contactsdockWidget->size().width(), this->size().height()); + } } - - -/*********************************************************************************** - Handle Callbacks for Load / Create. - ***********************************************************************************/ - -void GxsGroupDialog::loadNewGroupId(const uint32_t &token) -{ - std::cerr << "GxsGroupDialog::loadNewGroupId()"; - std::cerr << std::endl; - - std::list groupInfo; - - if (groupInfo.size() == 1) - { - RsGroupMetaData fi = groupInfo.front(); - completeCreateGroup(fi); - } - else - { - std::cerr << "GxsGroupDialog::loadNewGroupId() ERROR INVALID Number of Forums Created"; - std::cerr << std::endl; - } -} - - -void GxsGroupDialog::service_loadExistingGroup(const uint32_t &token) -{ - std::cerr << "GxsGroupDialog::service_loadExistingGroup() ERROR Must be Overloaded"; - std::cerr << std::endl; - -#if 0 - std::list groupInfo; - mRsService->getGroupSummary(token, groupInfo); - - if (groupInfo.size() == 1) - { - RsGroupMetaData fi = groupInfo.front(); - completeCreateGroup(fi); - } - else - { - std::cerr << "GxsGroupDialog::loadNewGroupId() ERROR INVALID Number of Forums Created"; - std::cerr << std::endl; - } -#endif - -} - - -void GxsGroupDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) -{ - std::cerr << "GxsGroupDialog::loadRequest() UserType: " << req.mUserType; - std::cerr << std::endl; - - if (queue != mTokenQueue) - { - std::cerr << "GxsGroupDialog::loadRequest() Queue ERROR"; - std::cerr << std::endl; - return; - } - - /* now switch on req */ - switch(req.mUserType) - { - - case GXSGROUP_NEWGROUPID: - loadNewGroupId(req.mToken); - break; - case GXSGROUP_LOADGROUP: - service_loadExistingGroup(req.mToken); - break; - default: - std::cerr << "GxsGroupDialog::loadRequest() UNKNOWN UserType "; - std::cerr << std::endl; - - } -} - - diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h index 746429358..bf62723c4 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h @@ -90,47 +90,91 @@ public: #define GXS_GROUP_DIALOG_SHOW_MODE 2 #define GXS_GROUP_DIALOG_EDIT_MODE 3 -class GxsGroupDialog : public QDialog, public TokenResponse +/*! + * The aim of this dialog is to be convenient to encapsulate group + * creation code for several GXS services such forums, channels + * and posted + * The functionality provided are for group creation are: + * - Specifying the authentication type of the group + * - Specifying group image + * - + * The main limitation is that it will not deal with the actual service GXS Group + * data structure, but the meta structure which is the same across GXS services + * The long term plan is perhap logic structure (i.e. code) will be moved into each GXS \n + * service for better customisation of group creation, or perhaps not! + */ +class GxsGroupDialog : public QDialog { Q_OBJECT public: - GxsGroupDialog(RsTokenService *service, QWidget *parent = 0); - void setFlags(uint32_t enabledFlags, uint32_t readonlyFlags, uint32_t defaultFlags); - void setMode(uint32_t mode); + /*! + * + * @param tokenQueue This should be the token service of the services Dialog \n + * in order to receive acknowledgement of group creation, if set to NULL with create mode \n + * creation will not happen + * @param parent The parent dialog + * @param mode + */ + GxsGroupDialog(TokenQueue* tokenQueue, QWidget *parent = NULL, uint32_t mode = GXS_GROUP_DIALOG_SHOW_MODE); - /*** Open Window -> in Correct Mode */ - void newGroup(); - void existingGroup(std::string groupId, uint32_t mode); + /*! + * + * @param enabledFlags This determines what options are enabled + * @param readonlyFlags This determines what is modifiable is particularly relevant to what mode the + * @param defaultFlags + */ + void setFlags(uint32_t enabledFlags, uint32_t defaultFlags); - // Callback for all Loads. -virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); +private: + void newGroup(); + void setMode(uint32_t mode); - - // Functions that can be overloaded for specific stuff. + // Functions that can be overloaded for specific stuff. protected slots: - void submitGroup(); - void addGroupLogo(); + void submitGroup(); + void addGroupLogo(); protected: - // Functions to be overloaded. + /*! + * Main purpose is to help tansfer meta data to service + * and also + * @param token This should be set to the token retrieved + * @param meta The deriving GXS service should set their grp meta to this value + */ + virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) = 0; - // Group Creation. - virtual bool service_NewGroup(); - virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); - virtual bool service_CompleteCreateGroup(const RsGroupMetaData &meta); + /*! + * This should return a group logo \n + * Will be called when GxsGroupDialog is initialised in show mode + * + */ + virtual QPixmap service_getLogo() = 0; - // Group Edit / Display. - virtual bool service_ExistingGroup(); // Initial Setup. - virtual void service_loadExistingGroup(const uint32_t &token); + /*! + * This should return a group description string + * @return group description string + */ + virtual QString service_getDescription() = 0; - bool loadExistingGroupMetaData(const RsGroupMetaData &meta); + /*! + * Used in show mode, returns a meta type + * @return the meta of existing grpMeta + */ + virtual RsGroupMetaData service_getMeta() = 0; + + /*! + * Loads meta data for group to GUI dialog + * @param meta the meta loaded fir group + */ + void loadExistingGroupMetaData(const RsGroupMetaData &meta); private slots: + /* actions to take.... */ void cancelDialog(); @@ -141,29 +185,19 @@ private: void setGroupSignFlags(uint32_t signFlags); uint32_t getGroupSignFlags(); - void setupDefaults(); void setupVisibility(); void clearForm(); - void createGroup(); - - virtual void completeCreateGroup(const RsGroupMetaData &newForumMeta); - - void sendShareList(std::string forumId); - void loadNewGroupId(const uint32_t &token); + std::list mShareList; - QPixmap picture; - - RsTokenService *mRsService; TokenQueue *mTokenQueue; uint32_t mMode; - uint32_t mEnabledFlags; uint32_t mReadonlyFlags; uint32_t mDefaultsFlags; From 5ea912b00c4c026387124b97a9e796b74a0b8482 Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 29 Oct 2012 23:25:09 +0000 Subject: [PATCH 113/222] Preliminary notes on Circles. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5743 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/services/p3circles.h | 208 +++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 libretroshare/src/services/p3circles.h diff --git a/libretroshare/src/services/p3circles.h b/libretroshare/src/services/p3circles.h new file mode 100644 index 000000000..2eceea528 --- /dev/null +++ b/libretroshare/src/services/p3circles.h @@ -0,0 +1,208 @@ +/* + * libretroshare/src/services: p3circles.h + * + * Identity interface for RetroShare. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#ifndef P3_CIRCLES_SERVICE_HEADER +#define P3_CIRCLES_SERVICE_HEADER + + +#include "retroshare/rscircles.h" // External Interfaces. +#include "gxs/rsgenexchange.h" // GXS service. +#include "gxs/rsgixs.h" // Internal Interfaces. + +#include +#include + +/* + * Circles Identity Service + * + * A collection of notes: + * + * We want to be able to express the following types of Circles. + * + * - Public + * - Groups & Messages can be passed onto anyone. ( No Restrictions. ) + * - GXS Notes: + * - This is what we have currently. + * + * - External Circle + * - List of Identities that can receive the Group / Messages. + * - This list will be defined via a set of RsIdentities - which have PGPHashes set. + * - We need the PGPHashes to be able to identify which peers can receive msgs. + * - Messages are passed to the Intersection of (Identified PGPHashes & Friends) + * - Distribution of Circle Definitions can be also be restricted via circles. + * - You can have Public External Groups, or Groups that only the Members know about. + * - Control of these External Groups is determined by Admin / Publish Keys. + * - The Danger with External Groups, is your ID wll be associated with other people... + * - Leaking information!!! + * - GXS Notes: + * - p3Circles will provide a distrib list for a given Circle Group. + * + * - Personal Circle or "Your Eyes Only". + * - Same as an Internal Circle Definition. (What will be used for File Sharing initially) + * - Each peer will have a bunch of these, Friends, Family, etc. + * + * - The list is not publically shared, only the originator of the message will distribute. + * - You can communicate back to the originator, who will share with the other members. + * but you mustn't discuss / share content with anyone else. + * - This is quite a Weak / Fragile Group, as there is only one distributor. + * - GXS NOTES: + * - TO make this work, we need GXS or RsCircles to maintain extra info: + * - GXS stores the original source, so communications can go back there. + * - If Originator, GXS store a REFERENCE, Circles turn this into a distrib list of peers. + * + * + * + * Like RsIdentities are used to validation messages, + * RsCircles will be used to determine if a peer can receive a group / messages. + * + * bool RsCircles::canSend(RsCircleId, RsPeerId) + * bool RsCircles::canSend(RsCircleInternalId, RsPeerId) + * + * or maybe just: + * + * bool RsCircles::recipients(GxsPermission &perms, std::list friendlist); + * + */ + + +/* Permissions is part of GroupMetaData + */ + +#define GXS_PERM_TYPE_PUBLIC 0x0001 +#define GXS_PERM_TYPE_EXTERNAL 0x0002 +#define GXS_PERM_TYPE_YOUREYESONLY 0x0003 + +class GxsPermissions +{ +public: + uint32_t mType; // PUBLIC, EXTERNAL or YOUREYESONLY, Mutually exclusive. + RsCircleId mCircleId; // If EXTERNAL, otherwise Blank. + + // BELOW IS NOT SERIALISED - BUT MUST BE STORED LOCALLY BY GXS. (If YOUREYESONLY) + RsPeerId mOriginator; + RsCircleInternalId mInternalCircle; // if Originator == ownId, otherwise blank. +}; + + +class RsGxsCircleGroup +{ + public: + GroupMetaData mMeta; // includes GxsPermissions, for control of group distribution. + + std::list mMembers; + std::list mCircleMembers; + + + // Not Serialised. + // Internally inside rsCircles, this will be turned into: + // std::list mAllowedFriends; +}; + + + + + +class rsCircle +{ +public: + + /* GXS Interface - for working out who can receive */ + + bool canSend(RsCircleId, RsPeerId) + bool canSend(RsCircleInternalId, RsPeerId) + bool recipients(GxsPermission &perms, std::list friendlist); + + /* Functions to handle Local / Internal Circles == Same as for file permissions. */ + createLocalCircle() + addToLocalCircle() + removeFromLocalCircle() + getLocalCirclePeers() + getListOfLocalCircles() + + /* similar functions for External Groups */ + virtual bool createGroup(uint32_t& token, RsGxsCircleGroup &group); + virtual bool getGroupData(const uint32_t &token, std::vector &groups); + + + +} + + + + + + +/*** IGNORE BELOW HERE *****/ + +class p3Circles: public RsGxsCircleExchange, public RsCircles +{ + public: + p3Circles(RsGeneralDataService* gds, RsNetworkExchangeService* nes); + + virtual void service_tick(); // needed for background processing. + + + /* General Interface is provided by RsIdentity / RsGxsIfaceImpl. */ + + /* Data Specific Interface */ + + // These are exposed via RsIdentity. +virtual bool getGroupData(const uint32_t &token, std::vector &groups); + + // These are local - and not exposed via RsIdentity. +virtual bool getMsgData(const uint32_t &token, std::vector &opinions); +virtual bool createGroup(uint32_t& token, RsGxsIdGroup &group); +virtual bool createMsg(uint32_t& token, RsGxsIdOpinion &opinion); + + /**************** RsIdentity External Interface. + * Notes: + */ + + /**************** RsGixs Implementation + * Notes: + * Interface is only suggestion at the moment, will be changed as necessary. + * Results should be cached / preloaded for maximum speed. + * + */ + + /**************** RsGixsReputation Implementation + * Notes: + * Again should be cached if possible. + */ + + + protected: + + /** Notifications **/ + virtual void notifyChanges(std::vector& changes); + + private: + +}; + +#endif // P3_IDENTITY_SERVICE_HEADER + + + From 216683f747e9f86801fd952585fbd75e9345ba33 Mon Sep 17 00:00:00 2001 From: drbob Date: Tue, 30 Oct 2012 00:15:57 +0000 Subject: [PATCH 114/222] got the wrong upnp library for windows. fixed. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5744 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/libretroshare.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 2a1178a2e..d41d7294a 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -225,7 +225,7 @@ HEADERS += retroshare/rsgame.h \ # QMAKE_CFLAGS_DEBUG += -O2 DEFINES += USE_CMD_ARGS - CONFIG += upnp_libupnp + CONFIG += upnp_miniupnpc UPNPC_DIR = ../../../lib/miniupnpc-1.3 PTHREADS_DIR = ../../../lib/pthreads-w32-2-8-0-release From f4448692717746bb731d4e411cb561f5891baf2b Mon Sep 17 00:00:00 2001 From: defnax Date: Tue, 30 Oct 2012 17:10:19 +0000 Subject: [PATCH 115/222] Added Fullscreen Button/functionality for PhotoDialog and PhotoSlideShow little design changes for the Comment Item, needs more improvements git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5747 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/gui/PhotoShare/PhotoCommentItem.ui | 232 ++++++++++++------ .../src/gui/PhotoShare/PhotoDialog.cpp | 25 ++ .../src/gui/PhotoShare/PhotoDialog.h | 1 + .../src/gui/PhotoShare/PhotoDialog.ui | 196 ++++++++++++--- .../src/gui/PhotoShare/PhotoSlideShow.cpp | 22 +- .../src/gui/PhotoShare/PhotoSlideShow.h | 2 +- .../src/gui/PhotoShare/PhotoSlideShow.ui | 19 +- 7 files changed, 381 insertions(+), 116 deletions(-) diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui index 609c69f43..e43693241 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.ui @@ -6,18 +6,18 @@ 0 0 - 392 - 63 + 338 + 60 Form - + 0 - + @@ -31,11 +31,75 @@ 71 + + + + + + + 255 + 255 + 255 + + + + + + + 237 + 239 + 244 + + + + + + + + + 255 + 255 + 255 + + + + + + + 237 + 239 + 244 + + + + + + + + + 237 + 239 + 244 + + + + + + + 237 + 239 + 244 + + + + + + + + true + - QFrame#expandFrame{border: 2px solid #D3D3D3; -background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, -stop:0 #FFFFFF, stop:1 #F2F2F2);; -border-radius: 10px;} + QFrame::StyledPanel @@ -43,77 +107,91 @@ border-radius: 10px;} QFrame::Raised - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 75 - true - PreferAntialias - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + + + 2 + + + 2 + + + + + + 32 + 32 + + + + + 32 + 32 + + + + + + + :/images/no_avatar_70.png + + + true + + + + + + + + 0 + 0 + + + + + PreferAntialias + + + + true + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Qt::Vertical + + + + 29 + 13 + + + + + + + + + 75 + true + PreferAntialias + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:600; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; color:#666666;">DateTime</span></p></body></html> - - - - - - - - - QWidget#msgWidget{border: 2px solid #238; -border-radius: 10px;} - - - 5 - - - - - - 0 - 0 - - - - - PreferAntialias - - - - true - - - true - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - @@ -121,6 +199,10 @@ border-radius: 10px;} - + + + + + diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index 80348d1d4..9ff64cb06 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -15,6 +15,11 @@ PhotoDialog::PhotoDialog(RsPhotoV2 *rs_photo, const RsPhotoPhoto &photo, QWidget connect(ui->pushButton_AddComment, SIGNAL(clicked()), this, SLOT(createComment())); connect(ui->pushButton_AddCommentDlg, SIGNAL(clicked()), this, SLOT(addComment())); + connect(ui->fullscreenButton, SIGNAL(clicked()),this, SLOT(setFullScreen())); + +#if QT_VERSION >= 0x040700 + ui.lineEdit->setPlaceholderText(tr("Write a comment...")) ; +#endif setUp(); } @@ -209,3 +214,23 @@ void PhotoDialog::acknowledgeComment(uint32_t token) } } +void PhotoDialog::setFullScreen() +{ + if (!isFullScreen()) { + // hide menu & toolbars + +#ifdef Q_WS_X11 + show(); + raise(); + setWindowState( windowState() | Qt::WindowFullScreen ); +#else + setWindowState( windowState() | Qt::WindowFullScreen ); + show(); + raise(); +#endif + } else { + + setWindowState( windowState() ^ Qt::WindowFullScreen ); + show(); + } +} diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h index 867382fbc..dae81cdb0 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h @@ -23,6 +23,7 @@ private slots: void addComment(); void createComment(); + void setFullScreen(); public: void loadRequest(const TokenQueue *queue, const TokenRequest &req); diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui index 5cf9d47a5..d61266bf0 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui @@ -6,8 +6,8 @@ 0 0 - 615 - 566 + 594 + 572 @@ -21,7 +21,7 @@ true - + @@ -55,43 +55,146 @@ - - + + 0 0 - - - 327 - 0 - + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + - + true - - - - 0 - 0 - 369 - 18 - - - - - 0 - 0 - - - - + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 0 + 0 + + + + + 300 + 0 + + + + true + + + + + 0 + 0 + 328 + 20 + + + + + 0 + 0 + + + + + + + 1 + + + + + + + + + + + + + + Comment + + + + - + @@ -192,8 +295,32 @@
- - + + + + ... + + + + :/images/window_fullscreen.png:/images/window_fullscreen.png + + + true + + + + + + + Qt::Horizontal + + + + 238 + 20 + + + @@ -202,13 +329,6 @@ - - - - Comment - - - diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp index 5af627ea1..2e9f925bb 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp @@ -37,6 +37,7 @@ PhotoSlideShow::PhotoSlideShow(const RsPhotoAlbum& album, QWidget *parent) connect(ui.pushButton_ShowDetails, SIGNAL( clicked( void ) ), this, SLOT( showPhotoDetails( void ) ) ); connect(ui.pushButton_StartStop, SIGNAL( clicked( void ) ), this, SLOT( StartStop( void ) ) ); connect(ui.pushButton_Close, SIGNAL( clicked( void ) ), this, SLOT( closeShow( void ) ) ); + connect(ui.fullscreenButton, SIGNAL(clicked()),this, SLOT(setFullScreen())); mPhotoQueue = new TokenQueue(rsPhotoV2->getTokenService(), this); @@ -287,6 +288,25 @@ void PhotoSlideShow::loadRequest(const TokenQueue *queue, const TokenRequest &re } } - +void PhotoSlideShow::setFullScreen() +{ + if (!isFullScreen()) { + // hide menu & toolbars + +#ifdef Q_WS_X11 + show(); + raise(); + setWindowState( windowState() | Qt::WindowFullScreen ); +#else + setWindowState( windowState() | Qt::WindowFullScreen ); + show(); + raise(); +#endif + } else { + + setWindowState( windowState() ^ Qt::WindowFullScreen ); + show(); + } +} diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.h b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.h index 1fa57337b..6da052c1d 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.h @@ -47,7 +47,7 @@ private slots: void StartStop(); void timerEvent(); void closeShow(); - + void setFullScreen(); private: diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.ui b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.ui index a684f9a48..be5148197 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.ui @@ -89,6 +89,20 @@ + + + + + + + + :/images/window_fullscreen.png:/images/window_fullscreen.png + + + true + + + @@ -134,6 +148,9 @@ - + + + + From 92969c2f58e4aec4786c5cda2c7761461b8e66ea Mon Sep 17 00:00:00 2001 From: drbob Date: Wed, 31 Oct 2012 22:43:23 +0000 Subject: [PATCH 116/222] Improvements to GXS services. * Added serialiser for wiki items (actual data to be finalised). * Added wiki and fixed id services to be run properly. * Disabled dummyData for ids. * Fixed some bugs in Id serialiser. * Added missing fns in p3wiki git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5748 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/libretroshare.pro | 4 +- libretroshare/src/rsserver/rsinit.cc | 44 +- libretroshare/src/serialiser/rsgxsiditems.cc | 4 +- libretroshare/src/serialiser/rswikiitems.cc | 580 +++++++++++++++++++ libretroshare/src/services/p3idservice.cc | 3 + libretroshare/src/services/p3wiki.cc | 6 + libretroshare/src/services/p3wiki.h | 2 + 7 files changed, 628 insertions(+), 15 deletions(-) create mode 100644 libretroshare/src/serialiser/rswikiitems.cc diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index d41d7294a..86abb1c0d 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -646,8 +646,8 @@ HEADERS += retroshare/rsgame.h \ services/p3wiki.h \ serialiser/rswikiitems.h - SOURCES += services/p3wiki.cc - # serialiser/rswikiitems.cc \ + SOURCES += services/p3wiki.cc \ + serialiser/rswikiitems.cc \ } diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 7099e2395..a8c437fbd 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1823,12 +1823,15 @@ RsTurtle *rsTurtle = NULL ; #endif #ifdef ENABLE_GXS_SERVICES -#include "services/p3photoserviceV2.h" +#include "services/p3idservice.h" +#include "services/p3wiki.h" #include "services/p3posted.h" -#include "services/p3wikiserviceVEG.h" +#include "services/p3photoserviceV2.h" + +// Not too many to convert now! +//#include "services/p3wikiserviceVEG.h" #include "services/p3wireVEG.h" //#include "services/p3idserviceVEG.h" -#include "services/p3idservice.h" #include "services/p3forumsVEG.h" #endif @@ -2277,8 +2280,8 @@ int RsServer::StartupRetroShare() #ifdef ENABLE_GXS_SERVICES // Testing New Cache Services. - p3WikiServiceVEG *mWikis = new p3WikiServiceVEG(RS_SERVICE_GXSV1_TYPE_WIKI); - pqih -> addService(mWikis); + //p3WikiServiceVEG *mWikis = new p3WikiServiceVEG(RS_SERVICE_GXSV1_TYPE_WIKI); + //pqih -> addService(mWikis); // Testing New Cache Services. p3WireVEG *mWire = new p3WireVEG(RS_SERVICE_GXSV1_TYPE_WIRE); @@ -2345,6 +2348,22 @@ int RsServer::StartupRetroShare() RS_SERVICE_GXSV1_TYPE_POSTED, posted_ds, nxsMgr, mPosted); + /**** Wiki GXS service ****/ + + p3Wiki *mWiki = NULL; + + RsGeneralDataService* wiki_ds = new RsDataService("./" + mLinkMgr->getOwnId()+ "/", "wiki_db", + RS_SERVICE_GXSV1_TYPE_WIKI); + + wiki_ds->resetDataStore(); //TODO: remove, new service data per RS session, for testing + + mWiki = new p3Wiki(posted_ds, NULL); + + // create GXS photo service + RsGxsNetService* wiki_ns = new RsGxsNetService( + RS_SERVICE_GXSV1_TYPE_WIKI, wiki_ds, nxsMgr, mWiki); + + #endif // ENABLE_GXS_SERVICES #ifdef ENABLE_GXS_CORE @@ -2355,16 +2374,19 @@ int RsServer::StartupRetroShare() mGxsCore->addService(mGxsIdService); mGxsCore->addService(mPhotoV2); mGxsCore->addService(mPosted); + mGxsCore->addService(mWiki); // cores ready start up GXS net servers + createThread(*gxsid_ns); createThread(*photo_ns); createThread(*posted_ns); - createThread(*gxsid_ns); + createThread(*wiki_ns); // now add to p3service - pqih->addService(photo_ns); pqih->addService(gxsid_ns); + pqih->addService(photo_ns); pqih->addService(posted_ns); + pqih->addService(wiki_ns); // start up gxs core server createThread(*mGxsCore); @@ -2630,12 +2652,14 @@ int RsServer::StartupRetroShare() #ifdef ENABLE_GXS_SERVICES // Testing of new cache system interfaces. - rsWikiVEG = mWikis; - rsWireVEG = mWire; - rsForumsVEG = mForumsV2; + rsIdentity = mGxsIdService; + rsWiki = mWiki; rsPosted = mPosted; rsPhotoV2 = mPhotoV2; + rsWireVEG = mWire; + rsForumsVEG = mForumsV2; + #endif // ENABLE_GXS_SERVICES diff --git a/libretroshare/src/serialiser/rsgxsiditems.cc b/libretroshare/src/serialiser/rsgxsiditems.cc index 350d616d5..ebacdc7a1 100644 --- a/libretroshare/src/serialiser/rsgxsiditems.cc +++ b/libretroshare/src/serialiser/rsgxsiditems.cc @@ -65,8 +65,7 @@ bool RsGxsIdSerialiser::serialise(RsItem *item, void *data, uint32_t *size) } else if((op_item = dynamic_cast(item)) != NULL) { - return serialiseGxsIdGroupItem(grp_item, data, size); - return sizeGxsIdOpinionItem(op_item); + return serialiseGxsIdOpinionItem(op_item, data, size); } else if((com_item = dynamic_cast(item)) != NULL) { @@ -453,7 +452,6 @@ uint32_t RsGxsIdSerialiser::sizeGxsIdCommentItem(RsGxsIdCommentItem *item) const RsGxsIdComment& comment = item->comment; uint32_t s = 8; // header - s += 4; // mIdType. s += GetTlvStringSize(comment.mComment); return s; diff --git a/libretroshare/src/serialiser/rswikiitems.cc b/libretroshare/src/serialiser/rswikiitems.cc new file mode 100644 index 000000000..2d1bcb272 --- /dev/null +++ b/libretroshare/src/serialiser/rswikiitems.cc @@ -0,0 +1,580 @@ +/* + * libretroshare/src/serialiser: rswikiitems.cc + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include + +#include "rswikiitems.h" +#include "serialiser/rstlvbase.h" +#include "serialiser/rsbaseserial.h" + +#define GXSID_DEBUG 1 + + +uint32_t RsGxsWikiSerialiser::size(RsItem *item) +{ + RsGxsWikiCollectionItem* grp_item = NULL; + RsGxsWikiSnapshotItem* snap_item = NULL; + RsGxsWikiCommentItem* com_item = NULL; + + if((grp_item = dynamic_cast(item)) != NULL) + { + return sizeGxsWikiCollectionItem(grp_item); + } + else if((snap_item = dynamic_cast(item)) != NULL) + { + return sizeGxsWikiSnapshotItem(snap_item); + } + else if((com_item = dynamic_cast(item)) != NULL) + { + return sizeGxsWikiCommentItem(com_item); + } + return NULL; +} + +bool RsGxsWikiSerialiser::serialise(RsItem *item, void *data, uint32_t *size) +{ + RsGxsWikiCollectionItem* grp_item = NULL; + RsGxsWikiSnapshotItem* snap_item = NULL; + RsGxsWikiCommentItem* com_item = NULL; + + if((grp_item = dynamic_cast(item)) != NULL) + { + return serialiseGxsWikiCollectionItem(grp_item, data, size); + } + else if((snap_item = dynamic_cast(item)) != NULL) + { + return serialiseGxsWikiSnapshotItem(snap_item, data, size); + } + else if((com_item = dynamic_cast(item)) != NULL) + { + return serialiseGxsWikiCommentItem(com_item, data, size); + } + return false; +} + +RsItem* RsGxsWikiSerialiser::deserialise(void* data, uint32_t* size) +{ + +#ifdef RSSERIAL_DEBUG + std::cerr << "RsGxsWikiSerialiser::deserialise()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_WIKI != getRsItemService(rstype))) + { + return NULL; /* wrong type */ + } + + switch(getRsItemSubType(rstype)) + { + + case RS_PKT_SUBTYPE_WIKI_COLLECTION_ITEM: + return deserialiseGxsWikiCollectionItem(data, size); + break; + case RS_PKT_SUBTYPE_WIKI_SNAPSHOT_ITEM: + return deserialiseGxsWikiSnapshotItem(data, size); + break; + case RS_PKT_SUBTYPE_WIKI_COMMENT_ITEM: + return deserialiseGxsWikiCommentItem(data, size); + break; + default: +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::deserialise(): unknown subtype"; + std::cerr << std::endl; +#endif + break; + } + return NULL; +} + + + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + + +void RsGxsWikiCollectionItem::clear() +{ + collection.mDescription.clear(); + collection.mCategory.clear(); + collection.mHashTags.clear(); +} + +std::ostream& RsGxsWikiCollectionItem::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsGxsWikiCollectionItem", indent); + uint16_t int_Indent = indent + 2; + + printIndent(out, int_Indent); + out << "Description: " << collection.mDescription << std::endl; + printIndent(out, int_Indent); + out << "Category: " << collection.mCategory << std::endl; + printIndent(out, int_Indent); + out << "HashTags: " << collection.mHashTags << std::endl; + + printRsItemEnd(out ,"RsGxsWikiCollectionItem", indent); + return out; +} + + +uint32_t RsGxsWikiSerialiser::sizeGxsWikiCollectionItem(RsGxsWikiCollectionItem *item) +{ + + const RsWikiCollection& collection = item->collection; + uint32_t s = 8; // header + + s += GetTlvStringSize(collection.mDescription); + s += GetTlvStringSize(collection.mCategory); + s += GetTlvStringSize(collection.mHashTags); + + return s; +} + +bool RsGxsWikiSerialiser::serialiseGxsWikiCollectionItem(RsGxsWikiCollectionItem *item, void *data, uint32_t *size) +{ + +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::serialiseGxsWikiCollectionItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsWikiCollectionItem(item); + uint32_t offset = 0; + + if(*size < tlvsize) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::serialiseGxsWikiCollectionItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsWikiCollectionItem */ + ok &= SetTlvString(data, tlvsize, &offset, 1, item->collection.mDescription); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->collection.mCategory); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->collection.mHashTags); + + if(offset != tlvsize) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::serialiseGxsWikiCollectionItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef GXSID_DEBUG + if (!ok) + { + std::cerr << "RsGxsWikiSerialiser::serialiseGxsIdcollectionItem() NOK" << std::endl; + } +#endif + + return ok; + } + +RsGxsWikiCollectionItem* RsGxsWikiSerialiser::deserialiseGxsWikiCollectionItem(void *data, uint32_t *size) +{ + +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::deserialiseGxsWikiCollectionItem()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_WIKI != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_WIKI_COLLECTION_ITEM != getRsItemSubType(rstype))) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::deserialiseGxsWikiCollectionItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::deserialiseGxsWikiCollectionItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsWikiCollectionItem* item = new RsGxsWikiCollectionItem(); + /* skip the header */ + offset += 8; + + ok &= GetTlvString(data, rssize, &offset, 1, item->collection.mDescription); + ok &= GetTlvString(data, rssize, &offset, 1, item->collection.mCategory); + ok &= GetTlvString(data, rssize, &offset, 1, item->collection.mHashTags); + + if (offset != rssize) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::deserialiseGxsWikiCollectionItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::deserialiseGxsWikiCollectionItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + + + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + + +void RsGxsWikiSnapshotItem::clear() +{ + snapshot.mPage.clear(); + snapshot.mHashTags.clear(); +} + +std::ostream& RsGxsWikiSnapshotItem::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsGxsWikiSnapshotItem", indent); + uint16_t int_Indent = indent + 2; + + printIndent(out, int_Indent); + out << "Page: " << snapshot.mPage << std::endl; + + printIndent(out, int_Indent); + out << "HashTags: " << snapshot.mHashTags << std::endl; + + printRsItemEnd(out ,"RsGxsWikiSnapshotItem", indent); + return out; +} + + +uint32_t RsGxsWikiSerialiser::sizeGxsWikiSnapshotItem(RsGxsWikiSnapshotItem *item) +{ + + const RsWikiSnapshot& snapshot = item->snapshot; + uint32_t s = 8; // header + + s += GetTlvStringSize(snapshot.mPage); + s += GetTlvStringSize(snapshot.mHashTags); + + return s; +} + +bool RsGxsWikiSerialiser::serialiseGxsWikiSnapshotItem(RsGxsWikiSnapshotItem *item, void *data, uint32_t *size) +{ + +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::serialiseGxsWikiSnapshotItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsWikiSnapshotItem(item); + uint32_t offset = 0; + + if(*size < tlvsize) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::serialiseGxsWikiSnapshotItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsWikiSnapshotItem */ + ok &= SetTlvString(data, tlvsize, &offset, 1, item->snapshot.mPage); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->snapshot.mHashTags); + + if(offset != tlvsize) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::serialiseGxsWikiSnapshotItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef GXSID_DEBUG + if (!ok) + { + std::cerr << "RsGxsWikiSerialiser::serialiseGxsIdgroupItem() NOK" << std::endl; + } +#endif + + return ok; + } + +RsGxsWikiSnapshotItem* RsGxsWikiSerialiser::deserialiseGxsWikiSnapshotItem(void *data, uint32_t *size) +{ + +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::deserialiseGxsWikiSnapshotItem()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_WIKI != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_WIKI_SNAPSHOT_ITEM != getRsItemSubType(rstype))) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::deserialiseGxsWikiSnapshotItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::deserialiseGxsWikiSnapshotItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsWikiSnapshotItem* item = new RsGxsWikiSnapshotItem(); + /* skip the header */ + offset += 8; + + ok &= GetTlvString(data, rssize, &offset, 1, item->snapshot.mPage); + ok &= GetTlvString(data, rssize, &offset, 1, item->snapshot.mHashTags); + + if (offset != rssize) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::deserialiseGxsWikiSnapshotItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::deserialiseGxsWikiSnapshotItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + + +void RsGxsWikiCommentItem::clear() +{ + comment.mComment.clear(); +} + +std::ostream& RsGxsWikiCommentItem::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsGxsWikiCommentItem", indent); + uint16_t int_Indent = indent + 2; + + printIndent(out, int_Indent); + out << "Comment: " << comment.mComment << std::endl; + + printRsItemEnd(out ,"RsGxsWikiCommentItem", indent); + return out; +} + + +uint32_t RsGxsWikiSerialiser::sizeGxsWikiCommentItem(RsGxsWikiCommentItem *item) +{ + + const RsWikiComment& comment = item->comment; + uint32_t s = 8; // header + + s += GetTlvStringSize(comment.mComment); + + return s; +} + +bool RsGxsWikiSerialiser::serialiseGxsWikiCommentItem(RsGxsWikiCommentItem *item, void *data, uint32_t *size) +{ + +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::serialiseGxsWikiCommentItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsWikiCommentItem(item); + uint32_t offset = 0; + + if(*size < tlvsize) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::serialiseGxsWikiCommentItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsWikiCommentItem */ + ok &= SetTlvString(data, tlvsize, &offset, 1, item->comment.mComment); + + if(offset != tlvsize) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::serialiseGxsWikiCommentItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef GXSID_DEBUG + if (!ok) + { + std::cerr << "RsGxsWikiSerialiser::serialiseGxsIdgroupItem() NOK" << std::endl; + } +#endif + + return ok; + } + +RsGxsWikiCommentItem* RsGxsWikiSerialiser::deserialiseGxsWikiCommentItem(void *data, uint32_t *size) +{ + +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::deserialiseGxsWikiCommentItem()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_WIKI != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_WIKI_COMMENT_ITEM != getRsItemSubType(rstype))) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::deserialiseGxsWikiCommentItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::deserialiseGxsWikiCommentItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsWikiCommentItem* item = new RsGxsWikiCommentItem(); + /* skip the header */ + offset += 8; + + ok &= GetTlvString(data, rssize, &offset, 1, item->comment.mComment); + + if (offset != rssize) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::deserialiseGxsWikiCommentItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef GXSID_DEBUG + std::cerr << "RsGxsWikiSerialiser::deserialiseGxsWikiCommentItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 066d6ce0d..c016aa263 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -678,6 +678,9 @@ void p3IdService::generateDummyData() { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + // Temporarily disable - until system is properly tested. + return; + /* grab all the gpg ids... and make some ids */ std::list gpgids; diff --git a/libretroshare/src/services/p3wiki.cc b/libretroshare/src/services/p3wiki.cc index 563b5b04f..ab1195aa2 100644 --- a/libretroshare/src/services/p3wiki.cc +++ b/libretroshare/src/services/p3wiki.cc @@ -40,6 +40,12 @@ p3Wiki::p3Wiki(RsGeneralDataService* gds, RsNetworkExchangeService* nes) } +void p3Wiki::service_tick() +{ + return; +} + + void p3Wiki::notifyChanges(std::vector& changes) { receiveChanges(changes); diff --git a/libretroshare/src/services/p3wiki.h b/libretroshare/src/services/p3wiki.h index 10bd1edd3..7a8f74b2a 100644 --- a/libretroshare/src/services/p3wiki.h +++ b/libretroshare/src/services/p3wiki.h @@ -49,6 +49,8 @@ virtual void notifyChanges(std::vector& changes) ; public: +virtual void service_tick(); + /* Specific Service Data */ virtual bool getCollections(const uint32_t &token, std::vector &collections); virtual bool getSnapshots(const uint32_t &token, std::vector &snapshots); From 2fadb6d44ddd80cd8ff8585ef64552de1126212a Mon Sep 17 00:00:00 2001 From: drbob Date: Wed, 31 Oct 2012 23:27:13 +0000 Subject: [PATCH 117/222] disabled debug msg git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5749 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/services/p3idservice.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index c016aa263..d82af1770 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -59,8 +59,8 @@ p3IdService::p3IdService(RsGeneralDataService *gds, RsNetworkExchangeService *ne void p3IdService::service_tick() { - std::cerr << "p3IdService::service_tick()"; - std::cerr << std::endl; + //std::cerr << "p3IdService::service_tick()"; + //std::cerr << std::endl; // Disable for now. // background_tick(); From cfef2cc0523e752722bc304633e63af31cfa2598 Mon Sep 17 00:00:00 2001 From: drbob Date: Wed, 31 Oct 2012 23:32:56 +0000 Subject: [PATCH 118/222] Modified Identity & Wiki GXS code so that it compiles. - Just commented out the issues - still needs to be converted to new system. - Included it in build - Not actually enabled in the GUI yet. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5750 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/RetroShare.pro | 26 +-- retroshare-gui/src/gui/Identity/IdDialog.cpp | 13 +- .../src/gui/Identity/IdEditDialog.cpp | 9 +- .../src/gui/WikiPoos/WikiAddDialog.cpp | 7 +- .../src/gui/WikiPoos/WikiDialog.cpp | 219 +++++++++++------- retroshare-gui/src/gui/WikiPoos/WikiDialog.h | 2 +- .../src/gui/WikiPoos/WikiEditDialog.cpp | 58 +++-- .../src/gui/WikiPoos/WikiEditDialog.h | 8 +- .../src/gui/gxs/WikiGroupDialog.cpp | 57 ++++- retroshare-gui/src/gui/gxs/WikiGroupDialog.h | 14 +- 10 files changed, 275 insertions(+), 138 deletions(-) diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index 1e27b598e..e56ff437d 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -2,9 +2,9 @@ CONFIG += qt gui uic qrc resources uitools idle bitdht # Below is for GXS services. CONFIG += photoshare -#CONFIG += wikipoos +CONFIG += wikipoos #CONFIG += thewire -#CONFIG += identities +CONFIG += identities #CONFIG += forumsv2 CONFIG += posted CONFIG += unfinished @@ -194,15 +194,15 @@ freebsd-* { # ########################################### bitdht { - #LIBS += ../../libbitdht/src/lib/libbitdht.a - #PRE_TARGETDEPS *= ../../libbitdht/src/lib/libbitdht.a + LIBS += ../../libbitdht/src/lib/libbitdht.a + PRE_TARGETDEPS *= ../../libbitdht/src/lib/libbitdht.a #LIBS += C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a #PRE_TARGETDEPS *= C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a # Chris version. - LIBS += ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a - PRE_TARGETDEPS *= ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a + #LIBS += ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a + #PRE_TARGETDEPS *= ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a } win32 { @@ -1007,22 +1007,22 @@ posted { gxsgui { HEADERS += gui/gxs/GxsGroupDialog.h \ - gui/gxs/GxsCommentTreeWidget.h - # gui/gxs/ForumV2GroupDialog.h \ - # gui/gxs/WikiGroupDialog.h \ + gui/gxs/GxsCommentTreeWidget.h \ + gui/gxs/WikiGroupDialog.h \ +# gui/gxs/ForumV2GroupDialog.h \ # gui/gxs/GxsMsgDialog.h \ FORMS += gui/gxs/GxsGroupDialog.ui \ + # gui/gxs/GxsMsgDialog.ui \ # gui/gxs/GxsCommentTreeWidget.ui \ SOURCES += gui/gxs/GxsGroupDialog.cpp \ - gui/gxs/GxsCommentTreeWidget.cpp - #gui/gxs/ForumV2GroupDialog.cpp \ -# gui/gxs/WikiGroupDialog.cpp \ -# + gui/gxs/GxsCommentTreeWidget.cpp \ + gui/gxs/WikiGroupDialog.cpp \ + #gui/gxs/ForumV2GroupDialog.cpp \ # gui/gxs/GxsMsgDialog.cpp \ diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 048ffd39e..4d38443b9 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -79,8 +79,9 @@ IdDialog::IdDialog(QWidget *parent) timer->start(1000); rsIdentity->generateDummyData(); - +#if 0 mIdQueue = new TokenQueue(rsIdentity, this); +#endif } @@ -145,8 +146,10 @@ void IdDialog::requestIdDetails(std::string &id) void IdDialog::insertIdDetails(uint32_t token) { /* get details from libretroshare */ - RsIdGroup data; + RsGxsIdGroup data; +#if 0 if (!rsIdentity->getGroupData(token, data)) +#endif { ui.lineEdit_KeyId->setText("ERROR GETTING KEY!"); return; @@ -287,8 +290,12 @@ void IdDialog::insertIdList(uint32_t token) //for(it = ids.begin(); it != ids.end(); it++) //{ - RsIdGroup data; + RsGxsIdGroup data; +#if 0 while(rsIdentity->getGroupData(token, data)) +#else + while(0) +#endif { /* do filtering */ diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp index ca3a9fa90..3c8f8bc0c 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp @@ -41,8 +41,9 @@ IdEditDialog::IdEditDialog(QWidget *parent) connect(ui.radioButton_Pseudo, SIGNAL( toggled( bool ) ), this, SLOT( IdTypeToggled( bool ) ) ); connect(ui.pushButton_Update, SIGNAL( clicked( void ) ), this, SLOT( updateId( void ) ) ); connect(ui.pushButton_Cancel, SIGNAL( clicked( void ) ), this, SLOT( cancelId( void ) ) ); - +#if 0 mIdQueue = new TokenQueue(rsIdentity, this); +#endif } void IdEditDialog::setupNewId(bool pseudo) @@ -122,8 +123,10 @@ void IdEditDialog::loadExistingId(uint32_t token) ui.radioButton_Pseudo->setEnabled(false); /* get details from libretroshare */ - RsIdGroup data; + RsGxsIdGroup data; +#if 0 if (!rsIdentity->getGroupData(token, data)) +#endif { ui.lineEdit_KeyId->setText("ERROR KEYID INVALID"); ui.lineEdit_Nickname->setText(""); @@ -184,7 +187,7 @@ void IdEditDialog::loadExistingId(uint32_t token) void IdEditDialog::updateId() { - RsIdGroup rid; + RsGxsIdGroup rid; // Must set, Nickname, KeyId(if existing), mIdType, GpgId. rid.mMeta.mGroupName = ui.lineEdit_Nickname->text().toStdString(); diff --git a/retroshare-gui/src/gui/WikiPoos/WikiAddDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiAddDialog.cpp index 99cb57215..782d5f3c2 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiAddDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiAddDialog.cpp @@ -53,21 +53,26 @@ void WikiAddDialog::createGroup() std::cerr << std::endl; - RsWikiGroup group; + RsWikiCollection group; +#if 0 group.mShareOptions.mShareType = 0; group.mShareOptions.mShareGroupId = "unknown"; group.mShareOptions.mPublishKey = "unknown"; group.mShareOptions.mCommentMode = 0; group.mShareOptions.mResizeMode = 0; +#endif group.mMeta.mGroupName = ui.lineEdit_Name->text().toStdString(); group.mCategory = "Unknown"; uint32_t token; bool isNew = true; + +#if 0 // Don't worry about getting the response? rsWiki->createGroup(token, group, isNew); +#endif clearDialog(); diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp index e21b2757b..0b1f50bde 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp @@ -76,7 +76,9 @@ WikiDialog::WikiDialog(QWidget *parent) timer->start(1000); /* setup TokenQueue */ +#if 0 mWikiQueue = new TokenQueue(rsWiki, this); +#endif } @@ -114,7 +116,7 @@ void WikiDialog::OpenOrShowAddPageDialog() std::cerr << std::endl; #if 0 - RsWikiGroup group; + RsWikiCollection group; if (!rsWiki->getGroup(groupId, group)) { std::cerr << "WikiDialog::OpenOrShowAddPageDialog() Failed to Get Group"; @@ -154,8 +156,8 @@ void WikiDialog::OpenOrShowAddGroupDialog() void WikiDialog::newGroup() { - WikiGroupDialog cf (this); - cf.newGroup(); + WikiGroupDialog cf(mWikiQueue, this); + //cf.newGroup(); cf.exec (); } @@ -171,10 +173,9 @@ void WikiDialog::showGroupDetails() } - WikiGroupDialog cf (this); - cf.existingGroup(groupId, GXS_GROUP_DIALOG_SHOW_MODE); - - cf.exec (); + //RsWikiCollection collection; + //WikiGroupDialog cf (collection, this); + //cf.exec (); } void WikiDialog::editGroupDetails() @@ -188,10 +189,10 @@ void WikiDialog::editGroupDetails() } - WikiGroupDialog cf (this); - cf.existingGroup(groupId, GXS_GROUP_DIALOG_EDIT_MODE); + //WikiGroupDialog cf (this); + //cf.existingGroup(groupId, GXS_GROUP_DIALOG_EDIT_MODE); - cf.exec (); + //cf.exec (); } @@ -235,11 +236,11 @@ void WikiDialog::OpenOrShowEditDialog() } #if 0 - RsWikiGroup group; + RsWikiCollection group; rsWiki->getGroup(groupId, group); mEditDialog->setGroup(group); - RsWikiPage page; + RsWikiSnapshot page; rsWiki->getPage(realPageId, page); mEditDialog->setPreviousPage(page); #endif @@ -297,7 +298,7 @@ void WikiDialog::modTreeChanged() } -void WikiDialog::updateWikiPage(const RsWikiPage &page) +void WikiDialog::updateWikiPage(const RsWikiSnapshot &page) { ui.textBrowser->setPlainText(QString::fromStdString(page.mPage)); } @@ -329,6 +330,7 @@ void WikiDialog::clearModsTree() #define WIKI_GROUP_COL_ORIGPAGEID 2 +// THIS WAS ALREADY COMMENTED OUT!!! #if 0 ######################################################### void WikiDialog::insertWikiGroups() @@ -348,7 +350,7 @@ void WikiDialog::insertWikiGroups() for(it = groupIds.begin(); it != groupIds.end(); it++) { /* add a group Item */ - RsWikiGroup group; + RsWikiCollection group; rsWiki->getGroup(*it, group); QTreeWidgetItem *groupItem = new QTreeWidgetItem(NULL); @@ -370,7 +372,7 @@ void WikiDialog::insertWikiGroups() std::cerr << std::endl; /* get newest page */ - RsWikiPage page; + RsWikiSnapshot page; std::string latestPageId; if (!rsWiki->getLatestPage(*pit, latestPageId)) { @@ -506,7 +508,7 @@ void WikiDialog::insertModsForPage(std::string &origPageId) for(it = pageIds.begin(); it != pageIds.end(); it++) { - RsWikiPage page; + RsWikiSnapshot page; rsWiki->getPage(*it, page); QTreeWidgetItem *modItem = new QTreeWidgetItem(NULL); @@ -589,7 +591,9 @@ void WikiDialog::requestGroupData(const std::list &groupIds) { RsTokReqOptions opts; uint32_t token; +#if 0 mWikiQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, WIKIDIALOG_LISTING_GROUPDATA); +#endif } void WikiDialog::loadGroupData(const uint32_t &token) @@ -602,8 +606,12 @@ void WikiDialog::loadGroupData(const uint32_t &token) bool moreData = true; while(moreData) { - RsWikiGroup group; + RsWikiCollection group; +#if 0 if (rsWiki->getGroupData(token, group)) +#else + if (0) +#endif { /* Add Widget, and request Pages */ @@ -645,7 +653,11 @@ void WikiDialog::loadOriginalPages(const uint32_t &token) /* translate into latest pages */ std::list msgIds; +#if 0 if (rsWiki->getMsgList(token, msgIds)) +#else + if (0) +#endif { std::cerr << "WikiDialog::loadOriginalPages() Loaded " << msgIds.size(); std::cerr << std::endl; @@ -666,7 +678,23 @@ void WikiDialog::requestLatestPages(const std::list &msgIds) RsTokReqOptions opts; opts.mOptions = RS_TOKREQOPT_MSG_LATEST; uint32_t token; +#if 0 mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, msgIds, WIKIDIALOG_LISTING_LATESTPAGES); +#endif + +} + +void convert_result_to_list(const GxsMsgIdResult &result, std::list &list) +{ + GxsMsgIdResult::const_iterator it; + for(it = result.begin(); it != result.end(); it++) + { + std::vector::const_iterator vit; + for (vit = it->second.begin(); vit != it->second.end(); vit++) + { + list.push_back(*vit); + } + } } void WikiDialog::loadLatestPages(const uint32_t &token) @@ -674,7 +702,8 @@ void WikiDialog::loadLatestPages(const uint32_t &token) std::cerr << "WikiDialog::loadLatestPages()"; std::cerr << std::endl; - std::list msgIds; + //std::list msgIds; + GxsMsgIdResult msgIds; if (rsWiki->getMsgList(token, msgIds)) { std::cerr << "WikiDialog::loadLatestPages() Loaded " << msgIds.size(); @@ -687,17 +716,22 @@ void WikiDialog::loadLatestPages(const uint32_t &token) return; } + std::list list; + convert_result_to_list(msgIds, list); + /* request actual data */ - requestPages(msgIds); + //requestPages(list); } -void WikiDialog::requestPages(const std::list &msgIds) +#if 0 +void WikiDialog::requestPages(std::list &msgids) { RsTokReqOptions opts; uint32_t token; mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, WIKIDIALOG_LISTING_PAGES); } +#endif void WikiDialog::loadPages(const uint32_t &token) { @@ -708,56 +742,54 @@ void WikiDialog::loadPages(const uint32_t &token) QTreeWidgetItem *groupItem = NULL; + std::vector snapshots; + std::vector::iterator vit; + if (!rsWiki->getSnapshots(token, snapshots)) + { + // ERROR + return; + } - bool moreData = true; - while(moreData) - { - RsWikiPage page; - if (rsWiki->getMsgData(token, page)) - { - if (!groupItem) - { - /* find the entry */ - int itemCount = ui.treeWidget_Pages->topLevelItemCount(); - for (int nIndex = 0; nIndex < itemCount;) - { - QTreeWidgetItem *tmpItem = ui.treeWidget_Pages->topLevelItem(nIndex); - std::string tmpid = tmpItem->data(WIKI_GROUP_COL_GROUPID, - Qt::DisplayRole).toString().toStdString(); - if (tmpid == page.mMeta.mGroupId) - { - groupItem = tmpItem; - break; - } - } - - if (!groupItem) + for(vit = snapshots.begin(); vit != snapshots.end(); vit++) + { + RsWikiSnapshot page = *vit; + if (!groupItem) + { + /* find the entry */ + int itemCount = ui.treeWidget_Pages->topLevelItemCount(); + for (int nIndex = 0; nIndex < itemCount;) + { + QTreeWidgetItem *tmpItem = ui.treeWidget_Pages->topLevelItem(nIndex); + std::string tmpid = tmpItem->data(WIKI_GROUP_COL_GROUPID, + Qt::DisplayRole).toString().toStdString(); + if (tmpid == page.mMeta.mGroupId) { - /* error */ - std::cerr << "WikiDialog::loadPages() ERROR Unable to find group"; - std::cerr << std::endl; - return; + groupItem = tmpItem; + break; } } + + if (!groupItem) + { + /* error */ + std::cerr << "WikiDialog::loadPages() ERROR Unable to find group"; + std::cerr << std::endl; + return; + } + } - std::cerr << "WikiDialog::loadPages() PageId: " << page.mMeta.mMsgId; - std::cerr << " Page: " << page.mMeta.mMsgName; - std::cerr << std::endl; + std::cerr << "WikiDialog::loadPages() PageId: " << page.mMeta.mMsgId; + std::cerr << " Page: " << page.mMeta.mMsgName; + std::cerr << std::endl; - QTreeWidgetItem *pageItem = new QTreeWidgetItem(); - pageItem->setText(WIKI_GROUP_COL_PAGENAME, QString::fromStdString(page.mMeta.mMsgName)); - pageItem->setText(WIKI_GROUP_COL_PAGEID, QString::fromStdString(page.mMeta.mMsgId)); - pageItem->setText(WIKI_GROUP_COL_ORIGPAGEID, QString::fromStdString(page.mMeta.mOrigMsgId)); + QTreeWidgetItem *pageItem = new QTreeWidgetItem(); + pageItem->setText(WIKI_GROUP_COL_PAGENAME, QString::fromStdString(page.mMeta.mMsgName)); + pageItem->setText(WIKI_GROUP_COL_PAGEID, QString::fromStdString(page.mMeta.mMsgId)); + pageItem->setText(WIKI_GROUP_COL_ORIGPAGEID, QString::fromStdString(page.mMeta.mOrigMsgId)); - groupItem->addChild(pageItem); - - } - else - { - moreData = false; - } - } + groupItem->addChild(pageItem); + } //return true; } @@ -778,7 +810,9 @@ void WikiDialog::requestModPageList(const std::string &origMsgId) msgIds.push_back(origMsgId); uint32_t token; +#if 0 mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, msgIds, WIKIDIALOG_MOD_LIST); +#endif } @@ -788,7 +822,9 @@ void WikiDialog::loadModPageList(const uint32_t &token) std::cerr << std::endl; /* translate into latest pages */ - std::list msgIds; + //std::list msgIds; + GxsMsgIdResult msgIds; + if (rsWiki->getMsgList(token, msgIds)) { std::cerr << "WikiDialog::loadModPageList() Loaded " << msgIds.size(); @@ -801,16 +837,20 @@ void WikiDialog::loadModPageList(const uint32_t &token) return; } - requestModPages(msgIds); + std::list list; + convert_result_to_list(msgIds, list); + requestModPages(list); } -void WikiDialog::requestModPages(const std::list &msgIds) +void WikiDialog::requestModPages(const std::list &msgIds) { RsTokReqOptions opts; uint32_t token; +#if 0 mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, WIKIDIALOG_MOD_PAGES); +#endif } @@ -822,8 +862,11 @@ void WikiDialog::loadModPages(const uint32_t &token) bool moreData = true; while(moreData) { - RsWikiPage page; + RsWikiSnapshot page; +#if 0 if (rsWiki->getMsgData(token, page)) +#endif + if (0) { std::cerr << "WikiDialog::loadModPages() PageId: " << page.mMeta.mMsgId; std::cerr << " Page: " << page.mMeta.mMsgName; @@ -855,7 +898,9 @@ void WikiDialog::requestWikiPage(const std::string &msgId) msgIds.push_back(msgId); uint32_t token; +#if 0 mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, WIKIDIALOG_WIKI_PAGE); +#endif } @@ -865,23 +910,33 @@ void WikiDialog::loadWikiPage(const uint32_t &token) std::cerr << std::endl; // Should only have one WikiPage.... - bool moreData = true; - while(moreData) - { - RsWikiPage page; - if (rsWiki->getMsgData(token, page)) - { - std::cerr << "WikiDialog::loadModPages() PageId: " << page.mMeta.mMsgId; - std::cerr << " Page: " << page.mMeta.mMsgName; - std::cerr << std::endl; + std::vector snapshots; + if (!rsWiki->getSnapshots(token, snapshots)) + { + // ERROR + return; + } - updateWikiPage(page); - } - else - { - moreData = false; - } - } + if (snapshots.size() < 1) + { + // ERROR + return; + } + + + if (snapshots.size() > 1) + { + // ERROR + return; + } + + RsWikiSnapshot page = snapshots[0]; + + std::cerr << "WikiDialog::loadModPages() PageId: " << page.mMeta.mMsgId; + std::cerr << " Page: " << page.mMeta.mMsgName; + std::cerr << std::endl; + + updateWikiPage(page); } diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.h b/retroshare-gui/src/gui/WikiPoos/WikiDialog.h index 5cc3d0977..ce91b3785 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.h +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.h @@ -68,7 +68,7 @@ void clearModsTree(); void insertWikiGroups(); void insertModsForPage(const std::string &origPageId); -void updateWikiPage(const RsWikiPage &page); +void updateWikiPage(const RsWikiSnapshot &page); bool getSelectedPage(std::string &pageId, std::string &origPageId); std::string getSelectedPage(); diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp index da95f920c..4111f8dee 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp @@ -36,25 +36,27 @@ WikiEditDialog::WikiEditDialog(QWidget *parent) connect(ui.pushButton_Revert, SIGNAL( clicked( void ) ), this, SLOT( revertEdit( void ) ) ); connect(ui.pushButton_Submit, SIGNAL( clicked( void ) ), this, SLOT( submitEdit( void ) ) ); +#if 0 mWikiQueue = new TokenQueue(rsWiki, this); +#endif } -void WikiEditDialog::setGroup(RsWikiGroup &group) +void WikiEditDialog::setGroup(RsWikiCollection &group) { - mWikiGroup = group; + mWikiCollection = group; - ui.lineEdit_Group->setText(QString::fromStdString(mWikiGroup.mMeta.mGroupName)); + ui.lineEdit_Group->setText(QString::fromStdString(mWikiCollection.mMeta.mGroupName)); } -void WikiEditDialog::setPreviousPage(RsWikiPage &page) +void WikiEditDialog::setPreviousPage(RsWikiSnapshot &page) { mNewPage = false; - mWikiPage = page; + mWikiSnapshot = page; - ui.lineEdit_Page->setText(QString::fromStdString(mWikiPage.mMeta.mMsgName)); - ui.lineEdit_PrevVersion->setText(QString::fromStdString(mWikiPage.mMeta.mMsgId)); - ui.textEdit->setPlainText(QString::fromStdString(mWikiPage.mPage)); + ui.lineEdit_Page->setText(QString::fromStdString(mWikiSnapshot.mMeta.mMsgName)); + ui.lineEdit_PrevVersion->setText(QString::fromStdString(mWikiSnapshot.mMeta.mMsgId)); + ui.textEdit->setPlainText(QString::fromStdString(mWikiSnapshot.mPage)); } @@ -81,7 +83,7 @@ void WikiEditDialog::revertEdit() } else { - ui.textEdit->setPlainText(QString::fromStdString(mWikiPage.mPage)); + ui.textEdit->setPlainText(QString::fromStdString(mWikiSnapshot.mPage)); } } @@ -90,23 +92,29 @@ void WikiEditDialog::submitEdit() { if (mNewPage) { - mWikiPage.mMeta.mGroupId = mWikiGroup.mMeta.mGroupId; - mWikiPage.mMeta.mOrigMsgId = ""; - mWikiPage.mMeta.mMsgId = ""; - mWikiPage.mPrevId = ""; + mWikiSnapshot.mMeta.mGroupId = mWikiCollection.mMeta.mGroupId; + mWikiSnapshot.mMeta.mOrigMsgId = ""; + mWikiSnapshot.mMeta.mMsgId = ""; +#if 0 + mWikiSnapshot.mPrevId = ""; +#endif } else { - mWikiPage.mPrevId = mWikiPage.mMeta.mMsgId; - mWikiPage.mMeta.mMsgId = ""; +#if 0 + mWikiSnapshot.mPrevId = mWikiSnapshot.mMeta.mMsgId; +#endif + mWikiSnapshot.mMeta.mMsgId = ""; } - mWikiPage.mMeta.mMsgName = ui.lineEdit_Page->text().toStdString(); - mWikiPage.mPage = ui.textEdit->toPlainText().toStdString(); + mWikiSnapshot.mMeta.mMsgName = ui.lineEdit_Page->text().toStdString(); + mWikiSnapshot.mPage = ui.textEdit->toPlainText().toStdString(); uint32_t token; bool isNew = mNewPage; - rsWiki->createPage(token, mWikiPage, isNew); +#if 0 + rsWiki->createPage(token, mWikiSnapshot, isNew); +#endif hide(); } @@ -144,8 +152,12 @@ void WikiEditDialog::loadGroup(const uint32_t &token) std::cerr << "WikiEditDialog::loadGroup()"; std::cerr << std::endl; - RsWikiGroup group; + RsWikiCollection group; +#if 0 if (rsWiki->getGroupData(token, group)) +#else + if (0) +#endif { setGroup(group); } @@ -161,7 +173,9 @@ void WikiEditDialog::requestPage(const std::string &msgId) RsTokReqOptions opts; uint32_t token; +#if 0 mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, 0); +#endif } void WikiEditDialog::loadPage(const uint32_t &token) @@ -169,8 +183,12 @@ void WikiEditDialog::loadPage(const uint32_t &token) std::cerr << "WikiEditDialog::loadPage()"; std::cerr << std::endl; - RsWikiPage page; + RsWikiSnapshot page; +#if 0 if (rsWiki->getMsgData(token, page)) +#else + if (0) +#endif { setPreviousPage(page); } diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h index 631f83c5e..5c04b13c5 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h @@ -49,8 +49,8 @@ void submitEdit(); private: -void setGroup(RsWikiGroup &group); -void setPreviousPage(RsWikiPage &page); +void setGroup(RsWikiCollection &group); +void setPreviousPage(RsWikiSnapshot &page); void requestPage(const std::string &msgId); void loadPage(const uint32_t &token); @@ -58,8 +58,8 @@ void requestGroup(const std::string &groupId); void loadGroup(const uint32_t &token); bool mNewPage; - RsWikiGroup mWikiGroup; - RsWikiPage mWikiPage; + RsWikiCollection mWikiCollection; + RsWikiSnapshot mWikiSnapshot; Ui::WikiEditDialog ui; diff --git a/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp b/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp index 7a7875f43..6cf8e612d 100644 --- a/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp @@ -24,8 +24,8 @@ #include #include -WikiGroupDialog::WikiGroupDialog(QWidget *parent) - :GxsGroupDialog(rsWiki, parent) +WikiGroupDialog::WikiGroupDialog(TokenQueue *tokenQueue, QWidget *parent) + :GxsGroupDialog(tokenQueue, parent, GXS_GROUP_DIALOG_CREATE_MODE) { // To start with we only have open forums - with distribution controls. @@ -58,7 +58,32 @@ WikiGroupDialog::WikiGroupDialog(QWidget *parent) GXS_GROUP_DEFAULTS_COMMENTS_NO | 0); - setFlags(enabledFlags, readonlyFlags, defaultsFlags); + //setFlags(enabledFlags, readonlyFlags, defaultsFlags); + setFlags(enabledFlags, defaultsFlags); + +} + +WikiGroupDialog::WikiGroupDialog(const RsWikiCollection &collection, QWidget *parent) + :GxsGroupDialog(NULL, parent, GXS_GROUP_DIALOG_SHOW_MODE) +{ + + // To start with we only have open forums - with distribution controls. + + uint32_t enabledFlags = ( GXS_GROUP_FLAGS_ICON | + GXS_GROUP_FLAGS_DESCRIPTION | + GXS_GROUP_FLAGS_DISTRIBUTION | + GXS_GROUP_FLAGS_SHAREKEYS | + 0); + + uint32_t readonlyFlags = 0; + + uint32_t defaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC | + GXS_GROUP_DEFAULTS_PUBLISH_OPEN | + GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED | + GXS_GROUP_DEFAULTS_COMMENTS_NO | + 0); + + setFlags(enabledFlags, defaultsFlags); } @@ -66,20 +91,37 @@ WikiGroupDialog::WikiGroupDialog(QWidget *parent) bool WikiGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) { // Specific Function. - RsWikiGroup grp; + RsWikiCollection grp; grp.mMeta = meta; //grp.mDescription = std::string(desc.toUtf8()); - rsWiki->createGroup(token, grp, true); + rsWiki->submitCollection(token, grp); return true; } +QPixmap WikiGroupDialog::service_getLogo() +{ + return QPixmap(); // null pixmap +} + +QString WikiGroupDialog::service_getDescription() +{ + return QString(); +} + +RsGroupMetaData WikiGroupDialog::service_getMeta() +{ + return mGrp.mMeta; +} + + +#if 0 void WikiGroupDialog::service_loadExistingGroup(const uint32_t &token) { std::cerr << "WikiGroupDialog::service_loadExistingGroup()"; std::cerr << std::endl; - RsWikiGroup group; + RsWikiCollection group; if (!rsWiki->getGroupData(token, group)) { std::cerr << "WikiGroupDialog::service_loadExistingGroup() ERROR Getting Group"; @@ -94,7 +136,6 @@ void WikiGroupDialog::service_loadExistingGroup(const uint32_t &token) /* now load any extra data we feel like */ } - - +#endif diff --git a/retroshare-gui/src/gui/gxs/WikiGroupDialog.h b/retroshare-gui/src/gui/gxs/WikiGroupDialog.h index 946763e93..6be72f0d9 100644 --- a/retroshare-gui/src/gui/gxs/WikiGroupDialog.h +++ b/retroshare-gui/src/gui/gxs/WikiGroupDialog.h @@ -24,19 +24,27 @@ #define _WIKI_GROUP_DIALOG_H #include "GxsGroupDialog.h" +#include "retroshare/rswiki.h" class WikiGroupDialog : public GxsGroupDialog { Q_OBJECT public: - WikiGroupDialog(QWidget *parent); + WikiGroupDialog(TokenQueue *tokenQueue, QWidget *parent); + WikiGroupDialog(const RsWikiCollection &collection, QWidget *parent); protected: virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); -// virtual bool service_CompleteCreateGroup(const RsGroupMetaData &meta); + virtual QPixmap service_getLogo(); + virtual QString service_getDescription(); + virtual RsGroupMetaData service_getMeta(); - virtual void service_loadExistingGroup(const uint32_t &token); + //virtual void service_loadExistingGroup(const uint32_t &token); + +private: + + RsWikiCollection mGrp; }; From 99f2813bed917be2957471367c1c81568efee065 Mon Sep 17 00:00:00 2001 From: drbob Date: Thu, 1 Nov 2012 00:19:02 +0000 Subject: [PATCH 119/222] Added Identity and Wiki GUIs to RS. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5751 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/gui/unfinished/ApplicationWindow.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp index 8011e80e1..c7ec34997 100644 --- a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp +++ b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp @@ -26,14 +26,14 @@ #include +#include "gui/Identity/IdDialog.h" #include "gui/PhotoShare/PhotoShare.h" +#include "gui/WikiPoos/WikiDialog.h" #include "gui/Posted/PostedDialog.h" // THESE HAVE TO BE CONVERTED TO VEG FORMAT #if USE_VEG_SERVICE -#include "gui/WikiPoos/WikiDialog.h" #include "gui/TheWire/WireDialog.h" -#include "gui/Identity/IdDialog.h" #include "gui/ForumsV2Dialog.h" #endif @@ -85,12 +85,9 @@ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) //ui.stackPages->add(calDialog = new CalDialog(ui.stackPages), // createPageAction(QIcon(IMAGE_CALENDAR), tr("Shared Calendars"), grp)); -// THESE HAVE TO BE CONVERTED TO VEG FORMAT -#if USE_VEG_SERVICE IdDialog *idDialog = NULL; ui.stackPages->add(idDialog = new IdDialog(ui.stackPages), createPageAction(QIcon(IMAGE_LIBRARY), tr("Identities"), grp)); -#endif PhotoShare *photoShare = NULL; ui.stackPages->add(photoShare = new PhotoShare(ui.stackPages), @@ -99,12 +96,13 @@ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) PostedDialog *postedDialog = NULL; ui.stackPages->add(postedDialog = new PostedDialog(ui.stackPages), createPageAction(QIcon(IMAGE_LIBRARY), tr("Posted Links"), grp)); -// THESE HAVE TO BE CONVERTED TO VEG FORMAT -#if USE_VEG_SERVICE + WikiDialog *wikiDialog = NULL; ui.stackPages->add(wikiDialog = new WikiDialog(ui.stackPages), createPageAction(QIcon(IMAGE_LIBRARY), tr("Wiki Pages"), grp)); +// THESE HAVE TO BE CONVERTED TO VEG FORMAT +#if USE_VEG_SERVICE WireDialog *wireDialog = NULL; ui.stackPages->add(wireDialog = new WireDialog(ui.stackPages), createPageAction(QIcon(IMAGE_BWGRAPH), tr("The Wire"), grp)); From c46acc29dea9030d60098c0832095909a9e9c0d9 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Thu, 1 Nov 2012 09:51:22 +0000 Subject: [PATCH 120/222] Fixed compile with Qt 4.7 and higher. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5753 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index 9ff64cb06..9c89cd4bf 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -18,7 +18,7 @@ PhotoDialog::PhotoDialog(RsPhotoV2 *rs_photo, const RsPhotoPhoto &photo, QWidget connect(ui->fullscreenButton, SIGNAL(clicked()),this, SLOT(setFullScreen())); #if QT_VERSION >= 0x040700 - ui.lineEdit->setPlaceholderText(tr("Write a comment...")) ; + ui->lineEdit->setPlaceholderText(tr("Write a comment...")) ; #endif setUp(); From bd6b17a30154856d4421fd09669cb3edd19ed741 Mon Sep 17 00:00:00 2001 From: drbob Date: Fri, 2 Nov 2012 00:45:50 +0000 Subject: [PATCH 121/222] Improvements to Identity service. * Added Id & Wiki serialisers to constructors. * Enabled cache_tick()... thought it doesn't process anything yet. * Added debug to Id Key cache system. * Fixed requests to match expected params. * Added cachetest basics - this is not finished. * Enabled generation of Lots of Dummy Ids - This demonstrates some queuing issues. * Added #define to easily enable GxsId as only new service - for testing. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5756 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgxsdataaccess.cc | 8 +- libretroshare/src/rsserver/rsinit.cc | 13 +- libretroshare/src/services/p3idservice.cc | 228 +++++++++++++++++++--- libretroshare/src/services/p3wiki.cc | 2 +- 4 files changed, 221 insertions(+), 30 deletions(-) diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index c3cf80619..f01a7407c 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -95,13 +95,13 @@ bool RsGxsDataAccess::requestGroupInfo(uint32_t &token, uint32_t ansType, const if(req == NULL) { - std::cerr << "RsGxsDataAccess::requestMsgInfo() request type not recognised, type " + std::cerr << "RsGxsDataAccess::requestGroupInfo() request type not recognised, type " << reqType << std::endl; return false; }else { generateToken(token); - std::cerr << "RsGxsDataAccess::requestMsgInfo() gets Token: " << token << std::endl; + std::cerr << "RsGxsDataAccess::requestGroupInfo() gets Token: " << token << std::endl; } setReq(req, token, ansType, opts); @@ -134,13 +134,13 @@ bool RsGxsDataAccess::requestGroupInfo(uint32_t &token, uint32_t ansType, const if(req == NULL) { - std::cerr << "RsGxsDataAccess::requestMsgInfo() request type not recognised, type " + std::cerr << "RsGxsDataAccess::requestGroupInfo() request type not recognised, type " << reqType << std::endl; return false; }else { generateToken(token); - std::cerr << "RsGxsDataAccess::requestMsgInfo() gets Token: " << token << std::endl; + std::cerr << "RsGxsDataAccess::requestGroupInfo() gets Token: " << token << std::endl; } setReq(req, token, ansType, opts); diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index a8c437fbd..b39d683d0 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1814,6 +1814,7 @@ RsTurtle *rsTurtle = NULL ; #define ENABLE_GXS_SERVICES 1 #define ENABLE_GXS_CORE 1 +#define ENABLE_OTHER_GXS_SERVICES 1 // DISABLE TO LEAVE ONLY GXSID (for testing) #ifdef ENABLE_GXS_CORE #include "gxs/gxscoreserver.h" @@ -2314,7 +2315,7 @@ int RsServer::StartupRetroShare() RS_SERVICE_GXSV1_TYPE_GXSID, gxsid_ds, nxsMgr, mGxsIdService); - +#if ENABLE_OTHER_GXS_SERVICES /**** Photo service ****/ p3PhotoServiceV2 *mPhotoV2 = NULL; @@ -2362,7 +2363,7 @@ int RsServer::StartupRetroShare() // create GXS photo service RsGxsNetService* wiki_ns = new RsGxsNetService( RS_SERVICE_GXSV1_TYPE_WIKI, wiki_ds, nxsMgr, mWiki); - +#endif #endif // ENABLE_GXS_SERVICES @@ -2372,21 +2373,27 @@ int RsServer::StartupRetroShare() GxsCoreServer* mGxsCore = new GxsCoreServer(); mGxsCore->addService(mGxsIdService); +#if ENABLE_OTHER_GXS_SERVICES mGxsCore->addService(mPhotoV2); mGxsCore->addService(mPosted); mGxsCore->addService(mWiki); +#endif // cores ready start up GXS net servers createThread(*gxsid_ns); +#if ENABLE_OTHER_GXS_SERVICES createThread(*photo_ns); createThread(*posted_ns); createThread(*wiki_ns); +#endif // now add to p3service pqih->addService(gxsid_ns); +#if ENABLE_OTHER_GXS_SERVICES pqih->addService(photo_ns); pqih->addService(posted_ns); pqih->addService(wiki_ns); +#endif // start up gxs core server createThread(*mGxsCore); @@ -2653,9 +2660,11 @@ int RsServer::StartupRetroShare() // Testing of new cache system interfaces. rsIdentity = mGxsIdService; +#if ENABLE_OTHER_GXS_SERVICES rsWiki = mWiki; rsPosted = mPosted; rsPhotoV2 = mPhotoV2; +#endif rsWireVEG = mWire; rsForumsVEG = mForumsV2; diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index d82af1770..58a2d0707 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -51,7 +51,7 @@ RsIdentity *rsIdentity = NULL; /********************************************************************************/ p3IdService::p3IdService(RsGeneralDataService *gds, RsNetworkExchangeService *nes) - : RsGxsIdExchange(gds, nes, NULL, RS_SERVICE_GXSV1_TYPE_GXSID), RsIdentity(this), + : RsGxsIdExchange(gds, nes, new RsGxsIdSerialiser(), RS_SERVICE_GXSV1_TYPE_GXSID), RsIdentity(this), mIdMtx("p3IdService") { @@ -65,13 +65,19 @@ void p3IdService::service_tick() // Disable for now. // background_tick(); - //cache_tick(); + cache_tick(); + + // internal testing - request keys. (NOT FINISHED YET) + //cachetest_tick(); return; } void p3IdService::notifyChanges(std::vector &changes) { + std::cerr << "p3IdService::notifyChanges()"; + std::cerr << std::endl; + receiveChanges(changes); } @@ -279,6 +285,9 @@ RsGxsIdCache::RsGxsIdCache(const RsGxsIdGroupItem *item) id = item->meta.mGroupId; name = item->meta.mGroupName; + std::cerr << "RsGxsIdCache::RsGxsIdCache() for: " << id; + std::cerr << std::endl; + /* extract key from keys */ bool key_ok = false; @@ -320,8 +329,14 @@ bool p3IdService::cache_is_loaded(const RsGxsId &id) it = mCacheDataMap.find(id); if (it == mCacheDataMap.end()) { + std::cerr << "p3IdService::cache_is_loaded(" << id << ") false"; + std::cerr << std::endl; + return false; } + std::cerr << "p3IdService::cache_is_loaded(" << id << ") false"; + std::cerr << std::endl; + return true; } @@ -334,9 +349,15 @@ bool p3IdService::cache_fetch(const RsGxsId &id, RsGxsIdCache &data) it = mCacheDataMap.find(id); if (it == mCacheDataMap.end()) { + std::cerr << "p3IdService::cache_fetch(" << id << ") false"; + std::cerr << std::endl; + return false; } + std::cerr << "p3IdService::cache_fetch(" << id << ") OK"; + std::cerr << std::endl; + data = it->second; /* update ts on data */ @@ -351,6 +372,11 @@ bool p3IdService::cache_fetch(const RsGxsId &id, RsGxsIdCache &data) bool p3IdService::cache_store(const RsGxsIdGroupItem *item) { + std::cerr << "p3IdService::cache_store() Item: "; + std::cerr << std::endl; + //item->print(std::cerr, 0); NEEDS CONST!!!! TODO + std::cerr << std::endl; + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ // Create Cache Data. @@ -362,6 +388,8 @@ bool p3IdService::cache_store(const RsGxsIdGroupItem *item) if (it != mCacheDataMap.end()) { // ERROR. + std::cerr << "p3IdService::cache_store() ERROR entry exists already"; + std::cerr << std::endl; return false; } @@ -383,6 +411,9 @@ bool p3IdService::locked_cache_update_lrumap(const RsGxsId &key, time_t old_ts, { if (old_ts == 0) { + std::cerr << "p3IdService::locked_cache_update_lrumap(" << key << ") just insert!"; + std::cerr << std::endl; + LruData data; data.key = key; /* new insertion */ @@ -401,20 +432,30 @@ bool p3IdService::locked_cache_update_lrumap(const RsGxsId &key, time_t old_ts, { LruData data = mit->second; mCacheLruMap.erase(mit); + std::cerr << "p3IdService::locked_cache_update_lrumap(" << key << ") rm old"; + std::cerr << std::endl; if (new_ts != 0) // == 0, means remove. { + std::cerr << "p3IdService::locked_cache_update_lrumap(" << key << ") added new_ts"; + std::cerr << std::endl; mCacheLruMap.insert(std::make_pair(new_ts, data)); } return true; } } + std::cerr << "p3IdService::locked_cache_update_lrumap(" << key << ") ERROR"; + std::cerr << std::endl; + return false; } bool p3IdService::cache_resize() { + std::cerr << "p3IdService::cache_resize()"; + std::cerr << std::endl; + int count_to_clear = 0; { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ @@ -424,12 +465,15 @@ bool p3IdService::cache_resize() (mCacheLruMap.size() != mCacheDataCount)) { // ERROR. - + std::cerr << "p3IdService::cache_resize() CONSISTENCY ERROR"; + std::cerr << std::endl; } if (mCacheDataCount > MAX_CACHE_SIZE) { count_to_clear = mCacheDataCount - MAX_CACHE_SIZE; + std::cerr << "p3IdService::cache_resize() to_clear: " << count_to_clear; + std::cerr << std::endl; } } @@ -466,6 +510,8 @@ bool p3IdService::cache_discard_LRU(int count_to_clear) } else { + std::cerr << "p3IdService::cache_discard_LRU() removing: " << data.key; + std::cerr << std::endl; mCacheDataMap.erase(it); mCacheDataCount--; } @@ -491,11 +537,8 @@ bool p3IdService::cache_discard_LRU(int count_to_clear) int p3IdService::cache_tick() { - std::cerr << "p3IdService::cache_tick()"; - std::cerr << std::endl; - - // Run Background Stuff. - background_checkTokenRequest(); + //std::cerr << "p3IdService::cache_tick()"; + //std::cerr << std::endl; /* every minute - run a background check */ time_t now = time(NULL); @@ -522,6 +565,9 @@ int p3IdService::cache_tick() bool p3IdService::cache_request_load(const RsGxsId &id) { + std::cerr << "p3IdService::cache_request_load(" << id << ")"; + std::cerr << std::endl; + bool start = false; { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ @@ -548,10 +594,6 @@ bool p3IdService::cache_start_load() { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mCacheLoad_LastCycle = time(NULL); - - mCacheLoad_Status = 1; - /* now we process the modGroupList -> a map so we can use it easily later, and create id list too */ std::list::iterator it; for(it = mCacheLoad_ToCache.begin(); it != mCacheLoad_ToCache.end(); it++) @@ -562,15 +604,25 @@ bool p3IdService::cache_start_load() mCacheLoad_ToCache.clear(); } - uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; - RsTokReqOptions opts; - uint32_t token = 0; - - RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts, groupIds); - + if (groupIds.size() > 0) { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mCacheLoad_Tokens.push_back(token); + std::cerr << "p3IdService::cache_start_load() #Groups: " << groupIds.size(); + std::cerr << std::endl; + + mCacheLoad_LastCycle = time(NULL); + mCacheLoad_Status = 1; + + uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + uint32_t token = 0; + + RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts, groupIds); + + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + mCacheLoad_Tokens.push_back(token); + } } return 1; } @@ -584,6 +636,9 @@ bool p3IdService::cache_check_loading() RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ for(it = mCacheLoad_Tokens.begin(); it != mCacheLoad_Tokens.end();) { + std::cerr << "p3IdService::cache_check_loading() token: " << *it; + std::cerr << std::endl; + uint32_t token = *it; uint32_t status = RsGenExchange::getTokenService()->requestStatus(token); //checkRequestStatus(token, status, reqtype, anstype, ts); @@ -656,6 +711,136 @@ bool p3IdService::cache_check_consistency() return false; } +/************************************************************************************/ +/************************************************************************************/ + +#if 0 +bool p3IdService::cachetest_tick() +{ + /* every minute - run a background check */ + time_t now = time(NULL); + bool doCycle = false; + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + if (now - mCacheTest_LastTs > TEST_PERIOD) + { + doTest = true; + mCacheTest_LastTs = now; + } + } + + if (doCycle) + { + cachetest_getlist(); + } + + cachetest_request(); + return true; +} + +bool p3IdService::cachetest_getlist() +{ + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + if (mCacheTest_Active) + { + return false; + } + } + + uint32_t ansType = RS_TOKREQ_ANSTYPE_LIST; + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_LIST; + uint32_t token = 0; + + RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts); + + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + mCacheTest_Token = token; + mCacheTest_Active = true; + } + return true; +} + + +bool p3IdService::cachetest_request() +{ + uint32_t token = 0; + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + if (!mCacheTest_Active) + { + return false; + } + token = mCacheTest_Token; + } + + uint32_t status = RsGenExchange::getTokenService()->requestStatus(token); + + if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + { + std::cerr << "p3IdService::cache_load_for_token() : " << token; + std::cerr << std::endl; + + std::vector grpIds; + bool ok = RsGenExchange::getGroupList(token, grpIds); + + if(ok) + { + std::vector::iterator vit = grpIds.begin(); + for(; vit != grpIds.end(); vit++) + { + /* 5% chance of checking it! */ + if (RsRandom::f32() < 0.05) + { + /* try the cache! */ + if (!haveKey(*vit)) + { + std::list nullpeers; + requestKey(*vit, nullpeers); + } + else + { + RsTlvSecurityKey seckey; + if (getKey(*vit, seckey)) + { + // success! + + } + } + + /* try private key too! */ + if (!havePrivateKey(*vit)) + { + requestPrivateKey(*vit); + } + else + { + RsTlvSecurityKey seckey; + if (getPrivateKey(*vit, seckey)) + { + // success! + + } + } + } + } + } + else + { + std::cerr << "p3IdService::cache_load_for_token() ERROR no data"; + std::cerr << std::endl; + + return false; + } + } + return true; +} + +#endif + + /************************************************************************************/ /************************************************************************************/ @@ -678,9 +863,6 @@ void p3IdService::generateDummyData() { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - // Temporarily disable - until system is properly tested. - return; - /* grab all the gpg ids... and make some ids */ std::list gpgids; diff --git a/libretroshare/src/services/p3wiki.cc b/libretroshare/src/services/p3wiki.cc index ab1195aa2..d84cf0f98 100644 --- a/libretroshare/src/services/p3wiki.cc +++ b/libretroshare/src/services/p3wiki.cc @@ -34,7 +34,7 @@ RsWiki *rsWiki = NULL; p3Wiki::p3Wiki(RsGeneralDataService* gds, RsNetworkExchangeService* nes) - :RsGenExchange(gds, nes, NULL, RS_SERVICE_GXSV1_TYPE_WIKI), RsWiki(this) + :RsGenExchange(gds, nes, new RsGxsWikiSerialiser(), RS_SERVICE_GXSV1_TYPE_WIKI), RsWiki(this) { From 563e3df91e2c0b2f49c9827ec06dd942961a5503 Mon Sep 17 00:00:00 2001 From: drbob Date: Fri, 2 Nov 2012 00:49:06 +0000 Subject: [PATCH 122/222] Fixed up Identity requests. - The GUI now displays the dummy Ids (once they've had time to generate ;) - Generation from the GUI appears broken! git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5757 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/Identity/IdDialog.cpp | 43 ++++++++++++------- .../src/gui/Identity/IdEditDialog.cpp | 25 +++++++---- 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 4d38443b9..696acae20 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -79,9 +79,7 @@ IdDialog::IdDialog(QWidget *parent) timer->start(1000); rsIdentity->generateDummyData(); -#if 0 - mIdQueue = new TokenQueue(rsIdentity, this); -#endif + mIdQueue = new TokenQueue(rsIdentity->getTokenService(), this); } @@ -134,6 +132,7 @@ void IdDialog::blankSelection() void IdDialog::requestIdDetails(std::string &id) { RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; uint32_t token; std::list groupIds; @@ -147,14 +146,22 @@ void IdDialog::insertIdDetails(uint32_t token) { /* get details from libretroshare */ RsGxsIdGroup data; -#if 0 - if (!rsIdentity->getGroupData(token, data)) -#endif + std::vector datavector; + if (!rsIdentity->getGroupData(token, datavector)) { ui.lineEdit_KeyId->setText("ERROR GETTING KEY!"); return; } + if (datavector.size() != 1) + { + std::cerr << "IdDialog::insertIdDetails() Invalid datavector size"; + ui.lineEdit_KeyId->setText("INVALID DV SIZE"); + return; + } + + data = datavector[0]; + /* get GPG Details from rsPeers */ std::string gpgid = rsPeers->getGPGOwnId(); RsPeerDetails details; @@ -263,11 +270,13 @@ void IdDialog::OpenOrShowEditDialog() void IdDialog::requestIdList() { RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; uint32_t token; std::list groupIds; - mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, IDDIALOG_IDLIST); + //mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, IDDIALOG_IDLIST); + mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, IDDIALOG_IDLIST); } @@ -286,17 +295,19 @@ void IdDialog::insertIdList(uint32_t token) bool acceptFriends = ui.radioButton_ListFriends->isChecked(); bool acceptOthers = ui.radioButton_ListOthers->isChecked(); - //rsIdentity->getIdentityList(ids); - - //for(it = ids.begin(); it != ids.end(); it++) - //{ RsGxsIdGroup data; -#if 0 - while(rsIdentity->getGroupData(token, data)) -#else - while(0) -#endif + std::vector datavector; + std::vector::iterator vit; + if (!rsIdentity->getGroupData(token, datavector)) { + std::cerr << "IdDialog::insertIdList() Error getting GroupData"; + std::cerr << std::endl; + return; + } + + for(vit = datavector.begin(); vit != datavector.end(); vit++) + { + data = (*vit); /* do filtering */ bool ok = false; diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp index 3c8f8bc0c..17abb84d7 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp @@ -41,9 +41,7 @@ IdEditDialog::IdEditDialog(QWidget *parent) connect(ui.radioButton_Pseudo, SIGNAL( toggled( bool ) ), this, SLOT( IdTypeToggled( bool ) ) ); connect(ui.pushButton_Update, SIGNAL( clicked( void ) ), this, SLOT( updateId( void ) ) ); connect(ui.pushButton_Cancel, SIGNAL( clicked( void ) ), this, SLOT( cancelId( void ) ) ); -#if 0 - mIdQueue = new TokenQueue(rsIdentity, this); -#endif + mIdQueue = new TokenQueue(rsIdentity->getTokenService(), this); } void IdEditDialog::setupNewId(bool pseudo) @@ -123,11 +121,19 @@ void IdEditDialog::loadExistingId(uint32_t token) ui.radioButton_Pseudo->setEnabled(false); /* get details from libretroshare */ - RsGxsIdGroup data; -#if 0 - if (!rsIdentity->getGroupData(token, data)) -#endif - { + RsGxsIdGroup data; + std::vector datavector; + if (!rsIdentity->getGroupData(token, datavector)) + { + ui.lineEdit_KeyId->setText("ERROR GETTING KEY!"); + return; + } + + if (datavector.size() != 1) + { + std::cerr << "IdDialog::insertIdDetails() Invalid datavector size"; + std::cerr << std::endl; + ui.lineEdit_KeyId->setText("ERROR KEYID INVALID"); ui.lineEdit_Nickname->setText(""); @@ -137,6 +143,9 @@ void IdEditDialog::loadExistingId(uint32_t token) ui.lineEdit_GpgEmail->setText("N/A"); return; } + + data = datavector[0]; + bool pseudo = (data.mIdType & RSID_TYPE_PSEUDONYM); if (pseudo) From 6f6f55c166d27fd53a01e75e3b97f20fb23f1973 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Fri, 2 Nov 2012 23:35:10 +0000 Subject: [PATCH 123/222] Refactored signature creation to Gxs security Fixed signing of msgs Added signing of groups (follows p3distrib grp creation method) Refactored GxsGroupDialog in 2 new UIs, GxsCreateGroupDialog and GxsViewGroup for ease of logic, retaining flexibility across GXS services. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5762 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/gxssecurity.cc | 32 ++++- libretroshare/src/gxs/gxssecurity.h | 10 ++ libretroshare/src/gxs/rsgenexchange.cc | 118 ++++++++++-------- libretroshare/src/gxs/rsgenexchange.h | 51 +++++++- .../src/gui/gxs/GxsCreateGroupDialog.cpp | 26 ++++ .../src/gui/gxs/GxsCreateGroupDialog.h | 23 ++++ .../src/gui/gxs/GxsCreateGroupDialog.ui | 18 +++ retroshare-gui/src/gui/gxs/GxsViewGroup.cpp | 26 ++++ retroshare-gui/src/gui/gxs/GxsViewGroup.h | 23 ++++ retroshare-gui/src/gui/gxs/GxsViewGroup.ui | 21 ++++ 10 files changed, 286 insertions(+), 62 deletions(-) create mode 100644 retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.cpp create mode 100644 retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.h create mode 100644 retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.ui create mode 100644 retroshare-gui/src/gui/gxs/GxsViewGroup.cpp create mode 100644 retroshare-gui/src/gui/gxs/GxsViewGroup.h create mode 100644 retroshare-gui/src/gui/gxs/GxsViewGroup.ui diff --git a/libretroshare/src/gxs/gxssecurity.cc b/libretroshare/src/gxs/gxssecurity.cc index 0c3f0318b..35c5ba796 100644 --- a/libretroshare/src/gxs/gxssecurity.cc +++ b/libretroshare/src/gxs/gxssecurity.cc @@ -1,10 +1,10 @@ /* - * libretroshare/src/distrib: p3distribverify.cc + * libretroshare/src/gxs: gxssecurity.cc * * * Copyright 2008-2010 by Robert Fernie - * 2011 Christopher Evi-Parker + * 2011-2012 Christopher Evi-Parker * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -49,6 +49,30 @@ RSA *GxsSecurity::extractPublicKey(RsTlvSecurityKey& key) return rsakey; } +bool GxsSecurity::getSignature(char* data, uint32_t data_len, RsTlvSecurityKey* privKey, RsTlvKeySignature& sign) +{ + RSA* rsa_pub = extractPrivateKey(*privKey); + EVP_PKEY *key_pub = EVP_PKEY_new(); + EVP_PKEY_assign_RSA(key_pub, rsa_pub); + + /* calc and check signature */ + EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); + bool ok = EVP_SignInit(mdctx, EVP_sha1()) == 1; + ok &= EVP_SignUpdate(mdctx, data, data_len) == 1; + + unsigned int siglen = EVP_PKEY_size(key_pub); + unsigned char sigbuf[siglen]; + ok &= EVP_SignFinal(mdctx, sigbuf, &siglen, key_pub) == 1; + + // clean up + EVP_MD_CTX_destroy(mdctx); + EVP_PKEY_free(key_pub); + + sign.signData.setBinData(sigbuf, siglen); + sign.keyId = privKey->keyId; + + return ok; +} bool GxsSecurity::validateNxsMsg(RsNxsMsg *msg, RsTlvKeySignature& sign, RsTlvSecurityKeySet& key) { @@ -135,7 +159,7 @@ bool GxsSecurity::validateNxsMsg(RsNxsMsg *msg, RsTlvKeySignature& sign, RsTlvSe // std::cerr << std::endl; //#endif - // return false; + return false; } @@ -321,7 +345,7 @@ std::string GxsSecurity::getRsaKeySign(RSA *pubkey) bool GxsSecurity::validateNxsGrp(RsNxsGrp *newGrp, RsTlvKeySignature& sign, RsTlvSecurityKey& key) { - + return false; } void GxsSecurity::setRSAPublicKey(RsTlvSecurityKey & key, RSA *rsa_pub) diff --git a/libretroshare/src/gxs/gxssecurity.h b/libretroshare/src/gxs/gxssecurity.h index 10329bf2c..826072e6a 100644 --- a/libretroshare/src/gxs/gxssecurity.h +++ b/libretroshare/src/gxs/gxssecurity.h @@ -130,6 +130,16 @@ public: * @return false if verfication of signature is not passed */ static bool validateNxsMsg(RsNxsMsg *msg, RsTlvKeySignature& sign, RsTlvSecurityKeySet& key); + + + /*! + * @param data data to be signed + * @param data_len length of data to be signed + * @param privKey private key to used to make signature + * @param sign the signature is stored here + * @return false if signature creation failed, true is signature created + */ + static bool getSignature(char* data, uint32_t data_len, RsTlvSecurityKey* privKey, RsTlvKeySignature& sign); }; #endif // GXSSECURITY_H diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 8d6cf42fa..555d1513a 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -125,7 +125,7 @@ bool RsGenExchange::acknowledgeTokenGrp(const uint32_t& token, return true; } -void RsGenExchange::createGroup(RsNxsGrp *grp) +bool RsGenExchange::createGroup(RsNxsGrp *grp) { /* create Keys */ @@ -162,17 +162,40 @@ void RsGenExchange::createGroup(RsNxsGrp *grp) adminKey.endTS = 0; /* no end */ RsGxsGrpMetaData* meta = grp->metaData; - /* add keys to grp */ + /* add public keys to grp */ meta->keys.keys[adminKey.keyId] = adminKey; - meta->keys.keys[privAdminKey.keyId] = privAdminKey; meta->keys.keys[pubKey.keyId] = pubKey; + + // group is self signing + // for the creation of group signature + // only public admin and publish keys are present + // key set + uint32_t metaDataLen = meta->serial_size(); + uint32_t allGrpDataLen = metaDataLen + grp->grp.bin_len; + char* metaData = new char[metaDataLen]; + char* allGrpData = new char[allGrpDataLen]; // msgData + metaData + + meta->serialise(metaData, metaDataLen); + + // copy msg data and meta in allMsgData buffer + memcpy(allGrpData, grp->grp.bin_data, grp->grp.bin_len); + memcpy(allGrpData+(grp->grp.bin_len), metaData, metaDataLen); + + RsTlvKeySignature adminSign; + bool ok = GxsSecurity::getSignature(allGrpData, allGrpDataLen, &privAdminKey, adminSign); + + /* now add private keys to grp */ + meta->keys.keys[privAdminKey.keyId] = privAdminKey; meta->keys.keys[privPubKey.keyId] = privPubKey; + // add admin sign to grpMeta + meta->signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_ADMIN] = adminSign; + pqihash hash; // get hash of msg data to create msg id - hash.addData(grp->grp.bin_data, grp->grp.bin_len); + hash.addData(allGrpData, allGrpDataLen); hash.Complete(meta->mGroupId); grp->grpId = meta->mGroupId; @@ -181,12 +204,17 @@ void RsGenExchange::createGroup(RsNxsGrp *grp) privPubKey.TlvClear(); pubKey.TlvClear(); - // free the private key for now, as it is not in use + // clean up RSA_free(rsa_admin); RSA_free(rsa_admin_pub); RSA_free(rsa_publish); RSA_free(rsa_publish_pub); + + delete[] allGrpData; + delete[] metaData; + + return ok; } bool RsGenExchange::createMessage(RsNxsMsg* msg) @@ -198,7 +226,7 @@ bool RsGenExchange::createMessage(RsNxsMsg* msg) metaMap.insert(std::make_pair(id, (RsGxsGrpMetaData*)(NULL))); mDataStore->retrieveGxsGrpMetaData(metaMap); bool ok = true; - RSA* rsa_pub = NULL; + RSA* rsa_pub = NULL; if(!metaMap[id]) { @@ -207,7 +235,7 @@ bool RsGenExchange::createMessage(RsNxsMsg* msg) else { // get publish key - RsGxsGrpMetaData* grpMeta = metaMap[id]; + RsGxsGrpMetaData* grpMeta = metaMap[id]; // public and shared is publish key RsTlvSecurityKeySet& keys = grpMeta->keys; @@ -219,70 +247,56 @@ bool RsGenExchange::createMessage(RsNxsMsg* msg) for(; mit != mit_end; mit++) { - pub_key_found = mit->second.keyFlags & (RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL); + pub_key_found = mit->second.keyFlags & (RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL); if(pub_key_found) break; } if(pub_key_found) { + RsGxsMsgMetaData &meta = *(msg->metaData); + + uint32_t metaDataLen = meta.serial_size(); + uint32_t allMsgDataLen = metaDataLen + msg->msg.bin_len; + char* metaData = new char[metaDataLen]; + char* allMsgData = new char[allMsgDataLen]; // msgData + metaData + + meta.serialise(metaData, &metaDataLen); + + // copy msg data and meta in allmsgData buffer + memcpy(allMsgData, msg->msg.bin_data, msg->msg.bin_len); + memcpy(allMsgData+(msg->msg.bin_len), metaData, metaDataLen); + + // private publish key pubKey = &(mit->second); - rsa_pub = GxsSecurity::extractPrivateKey(*pubKey); - EVP_PKEY *key_pub = EVP_PKEY_new(); - EVP_PKEY_assign_RSA(key_pub, rsa_pub); - /* calc and check signature */ - EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); + RsTlvKeySignatureSet& signSet = meta.signSet; + RsTlvKeySignature pubSign = signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH]; - RsGxsMsgMetaData &meta = *(msg->metaData); + GxsSecurity::getSignature(allMsgData, allMsgDataLen, pubKey, pubSign); - uint32_t metaDataLen = meta.serial_size(); - uint32_t allMsgDataLen = metaDataLen + msg->msg.bin_len; - char* metaData = new char[metaDataLen]; - char* allMsgData = new char[allMsgDataLen]; // msgData + metaData + // get hash of msg data to create msg id + pqihash hash; + hash.addData(allMsgData, allMsgDataLen); + hash.Complete(msg->msgId); - meta.serialise(metaData, &metaDataLen); + // assign msg id to msg meta + msg->metaData->mMsgId = msg->msgId; - // copy msg data and meta in allmsgData buffer - memcpy(allMsgData, msg->msg.bin_data, msg->msg.bin_len); - memcpy(allMsgData+(msg->msg.bin_len), metaData, metaDataLen); - - ok = EVP_SignInit(mdctx, EVP_sha1()) == 1; - ok = EVP_SignUpdate(mdctx, allMsgData, allMsgDataLen) == 1; - - unsigned int siglen = EVP_PKEY_size(key_pub); - unsigned char sigbuf[siglen]; - ok = EVP_SignFinal(mdctx, sigbuf, &siglen, key_pub) == 1; - - //place signature in msg meta - - RsTlvKeySignatureSet& signSet = meta.signSet; - RsTlvKeySignature pubSign = signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH]; - pubSign.signData.setBinData(sigbuf, siglen); - pubSign.keyId = pubKey->keyId; - - // get hash of msg data to create msg id - pqihash hash; - hash.addData(allMsgData, allMsgDataLen); - hash.Complete(msg->msgId); - - msg->metaData->mMsgId = msg->msgId; + //place signature in msg meta + signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH] = pubSign; // clean up - EVP_MD_CTX_destroy(mdctx); - //RSA_free(rsa_pub); - EVP_PKEY_free(key_pub); - // no need to free rsa key as evp key is considered parent key by SSL - delete[] metaData; - delete[] allMsgData; + delete[] metaData; + delete[] allMsgData; } else { ok = false; } - delete grpMeta; + delete grpMeta; } return ok; @@ -694,11 +708,11 @@ void RsGenExchange::publishGrps() grpItem->meta.mPublishTs = time(NULL); *(grp->metaData) = grpItem->meta; grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; - createGroup(grp); + ok &= createGroup(grp); size = grp->metaData->serial_size(); char mData[size]; grp->metaData->mGroupId = grp->grpId; - ok = grp->metaData->serialise(mData, size); + ok &= grp->metaData->serialise(mData, size); grp->meta.setBinData(mData, size); RsGxsGroupId grpId = grp->grpId; mDataAccess->addGroupData(grp); diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 363711386..1bf9caa97 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -158,7 +158,7 @@ protected: /*! * @param grpItem - * @deprecated only here to temporarily to testing + * @deprecated only here temporarily for testing */ void createDummyGroup(RsGxsGrpItem* grpItem); @@ -231,7 +231,7 @@ public: bool acknowledgeTokenMsg(const uint32_t& token, RsGxsGrpMsgIdPair& msgId); /*! - * This allows the client service to acknowledge that their grps has \n + * This allows the client service to acknowledge that their grps has \n * been created/modified and retrieve the create/modified grp ids * @param token the token related to modification/create request * @param msgIds vector of ids of groups created/modified @@ -270,20 +270,46 @@ public: /*! * sets the group subscribe flag * @param token this is set to token value associated to this request - * @param + * @param grpId Id of group whose subscribe file will be changed + * @param status + * @param mask */ void setGroupSubscribeFlags(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status, const uint32_t& mask); + /*! + * sets the group subscribe flag + * @param token this is set to token value associated to this request + * @param grpId Id of group whose subscribe file will be changed + * @param status + * @param mask + */ void setGroupStatusFlags(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status, const uint32_t& mask); + /*! + * sets the group service string + * @param token this is set to token value associated to this request + * @param grpId Id of group whose subscribe file will be changed + * @param servString + */ void setGroupServiceString(uint32_t& token, const RsGxsGroupId& grpId, const std::string& servString); + /*! + * sets the msg status flag + * @param token this is set to token value associated to this request + * @param grpId Id of group whose subscribe file will be changed + * @param status + * @param mask Mask to apply to status flag + */ void setMsgStatusFlags(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const uint32_t& status, const uint32_t& mask); + /*! + * sets the message service string + * @param token this is set to token value associated to this request + * @param msgId Id of message whose service string will be changed + * @param servString The service string to set msg to + */ void setMsgServiceString(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const std::string& servString ); - - protected: /** Notifications **/ @@ -324,7 +350,20 @@ private: */ void processGrpMetaChanges(); - void createGroup(RsNxsGrp* grp); + /*! + * This completes the creation of an instance on RsNxsGrp + * by assigning it a groupId and signature via SHA1 and EVP_sign respectively + * @param grp Nxs group to create + */ + bool createGroup(RsNxsGrp* grp); + + /*! + * This completes the creation of an instance on RsNxsMsg + * by assigning it a groupId and signature via SHA1 and EVP_sign respectively + * What signatures are calculated are based on the authentication policy + * of the service + * @param msg the Nxs message to create + */ bool createMessage(RsNxsMsg* msg); diff --git a/retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.cpp new file mode 100644 index 000000000..a2e4b14be --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.cpp @@ -0,0 +1,26 @@ +#include "GxsCreateGroupDialog.h" +#include "ui_GxsCreateGroupDialog.h" + +GxsCreateGroupDialog::GxsCreateGroupDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::GxsCreateGroupDialog) +{ + ui->setupUi(this); +} + +GxsCreateGroupDialog::~GxsCreateGroupDialog() +{ + delete ui; +} + +void GxsCreateGroupDialog::changeEvent(QEvent *e) +{ + QDialog::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} diff --git a/retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.h b/retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.h new file mode 100644 index 000000000..4808e79ee --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.h @@ -0,0 +1,23 @@ +#ifndef GXSCREATEGROUPDIALOG_H +#define GXSCREATEGROUPDIALOG_H + +#include + +namespace Ui { + class GxsCreateGroupDialog; +} + +class GxsCreateGroupDialog : public QDialog { + Q_OBJECT +public: + GxsCreateGroupDialog(QWidget *parent = 0); + ~GxsCreateGroupDialog(); + +protected: + void changeEvent(QEvent *e); + +private: + Ui::GxsCreateGroupDialog *ui; +}; + +#endif // GXSCREATEGROUPDIALOG_H diff --git a/retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.ui b/retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.ui new file mode 100644 index 000000000..9d504cc9e --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.ui @@ -0,0 +1,18 @@ + + GxsCreateGroupDialog + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + diff --git a/retroshare-gui/src/gui/gxs/GxsViewGroup.cpp b/retroshare-gui/src/gui/gxs/GxsViewGroup.cpp new file mode 100644 index 000000000..c6e1d4fdd --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsViewGroup.cpp @@ -0,0 +1,26 @@ +#include "GxsViewGroup.h" +#include "ui_GxsViewGroup.h" + +GxsViewGroup::GxsViewGroup(QWidget *parent) : + QWidget(parent), + ui(new Ui::GxsViewGroup) +{ + ui->setupUi(this); +} + +GxsViewGroup::~GxsViewGroup() +{ + delete ui; +} + +void GxsViewGroup::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + switch (e->type()) { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } +} diff --git a/retroshare-gui/src/gui/gxs/GxsViewGroup.h b/retroshare-gui/src/gui/gxs/GxsViewGroup.h new file mode 100644 index 000000000..ef12e8d73 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsViewGroup.h @@ -0,0 +1,23 @@ +#ifndef GXSVIEWGROUP_H +#define GXSVIEWGROUP_H + +#include + +namespace Ui { + class GxsViewGroup; +} + +class GxsViewGroup : public QWidget { + Q_OBJECT +public: + GxsViewGroup(QWidget *parent = 0); + ~GxsViewGroup(); + +protected: + void changeEvent(QEvent *e); + +private: + Ui::GxsViewGroup *ui; +}; + +#endif // GXSVIEWGROUP_H diff --git a/retroshare-gui/src/gui/gxs/GxsViewGroup.ui b/retroshare-gui/src/gui/gxs/GxsViewGroup.ui new file mode 100644 index 000000000..f30578df5 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsViewGroup.ui @@ -0,0 +1,21 @@ + + + + + GxsViewGroup + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + From e0d332f564f3f7fb8451eec89c01022d7d4ec98f Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sat, 3 Nov 2012 00:02:50 +0000 Subject: [PATCH 124/222] added priority to nxs items (low, same as cache transfer items) git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5763 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/serialiser/itempriorities.h | 3 +++ libretroshare/src/serialiser/rsnxsitems.h | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/libretroshare/src/serialiser/itempriorities.h b/libretroshare/src/serialiser/itempriorities.h index b86e635d4..b6d7586f8 100644 --- a/libretroshare/src/serialiser/itempriorities.h +++ b/libretroshare/src/serialiser/itempriorities.h @@ -90,3 +90,6 @@ const uint8_t QOS_PRIORITY_RS_BWCTRL_ALLOWED_ITEM = 9 ; const uint8_t QOS_PRIORITY_RS_DSDV_ROUTE = 4 ; const uint8_t QOS_PRIORITY_RS_DSDV_DATA = 2 ; +// GXS +// +const uint8_t QOS_PRIORITY_RS_GXS_NET = 3 ; diff --git a/libretroshare/src/serialiser/rsnxsitems.h b/libretroshare/src/serialiser/rsnxsitems.h index 37a4fffe8..8df77fb27 100644 --- a/libretroshare/src/serialiser/rsnxsitems.h +++ b/libretroshare/src/serialiser/rsnxsitems.h @@ -34,7 +34,6 @@ #include "serialiser/rstlvbase.h" #include "serialiser/rstlvtypes.h" #include "serialiser/rstlvkeys.h" - #include "gxs/rsgxsdata.h" @@ -69,7 +68,11 @@ class RsNxsItem : public RsItem public: RsNxsItem(uint16_t servtype, uint8_t subtype) - : RsItem(RS_PKT_VERSION_SERVICE, servtype, subtype), transactionNumber(0) { return; } + : RsItem(RS_PKT_VERSION_SERVICE, servtype, subtype), transactionNumber(0) + { + setPriorityLevel(QOS_PRIORITY_RS_GXS_NET); + return; + } virtual void clear() = 0; virtual std::ostream &print(std::ostream &out, uint16_t indent = 0) = 0; From df1755316b7b787b4bc750570954e606cc7a3441 Mon Sep 17 00:00:00 2001 From: drbob Date: Sat, 3 Nov 2012 11:57:27 +0000 Subject: [PATCH 125/222] * Fixed up Key Caching. * Added testing for Key Extraction. * Added Interface Fns for PrivateKey extraction. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5764 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgixs.h | 2 + libretroshare/src/services/p3idservice.cc | 161 +++++++++++++++------- libretroshare/src/services/p3idservice.h | 20 ++- 3 files changed, 132 insertions(+), 51 deletions(-) diff --git a/libretroshare/src/gxs/rsgixs.h b/libretroshare/src/gxs/rsgixs.h index 25b1d7a25..4c01d5b96 100644 --- a/libretroshare/src/gxs/rsgixs.h +++ b/libretroshare/src/gxs/rsgixs.h @@ -149,6 +149,8 @@ public: * @return will */ virtual bool requestKey(const RsGxsId &id, const std::list &peers) = 0; + virtual bool requestPrivateKey(const RsGxsId &id) = 0; + /*! * Retrieves a key identity diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 58a2d0707..455ecaff4 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -54,6 +54,9 @@ p3IdService::p3IdService(RsGeneralDataService *gds, RsNetworkExchangeService *ne : RsGxsIdExchange(gds, nes, new RsGxsIdSerialiser(), RS_SERVICE_GXSV1_TYPE_GXSID), RsIdentity(this), mIdMtx("p3IdService") { + mCacheTest_LastTs = 0; + mCacheLoad_LastCycle = 0; + mCacheTest_Active = false; } @@ -68,7 +71,7 @@ void p3IdService::service_tick() cache_tick(); // internal testing - request keys. (NOT FINISHED YET) - //cachetest_tick(); + cachetest_tick(); return; } @@ -151,6 +154,11 @@ int p3IdService::getKey(const RsGxsId &id, RsTlvSecurityKey &key) return -1; } +bool p3IdService::requestPrivateKey(const RsGxsId &id) +{ + return false; +} + int p3IdService::getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key) { /* TODO */ @@ -280,45 +288,19 @@ RsGxsIdCache::RsGxsIdCache() return; } -RsGxsIdCache::RsGxsIdCache(const RsGxsIdGroupItem *item) +RsGxsIdCache::RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvSecurityKey &in_pkey) { id = item->meta.mGroupId; name = item->meta.mGroupName; + pubkey = in_pkey; std::cerr << "RsGxsIdCache::RsGxsIdCache() for: " << id; std::cerr << std::endl; - /* extract key from keys */ - bool key_ok = false; - - /**** OKAY, I can't do this ???? how do I access the keys? ****/ -#if 0 - std::map::iterator kit; - - for (kit = item->meta.keys.keys.begin(); kit != item->meta.keys.keys.end(); kit++) - { - if (kit->second.keyFlags == RSTLV_KEY_DISTRIB_PUBLIC | RSTLV_KEY_TYPE_PUBLIC_ONLY) - { - std::cerr << "RsGxsIdCache::load() Found Public Key"; - std::cerr << std::endl; - - pubkey = kit->second; - key_ok = true; - } - } -#endif - - if (!key_ok) - { - std::cerr << "RsGxsIdCache::load() ERROR No Public Key Found"; - std::cerr << std::endl; - } - reputation = 0; /* TODO: extract from string - This will need to be refreshed!!! */ lastUsedTs = 0; -}; - +} bool p3IdService::cache_is_loaded(const RsGxsId &id) @@ -334,7 +316,7 @@ bool p3IdService::cache_is_loaded(const RsGxsId &id) return false; } - std::cerr << "p3IdService::cache_is_loaded(" << id << ") false"; + std::cerr << "p3IdService::cache_is_loaded(" << id << ") true"; std::cerr << std::endl; return true; @@ -377,10 +359,48 @@ bool p3IdService::cache_store(const RsGxsIdGroupItem *item) //item->print(std::cerr, 0); NEEDS CONST!!!! TODO std::cerr << std::endl; + /* extract key from keys */ + RsTlvSecurityKeySet keySet; + RsTlvSecurityKey pubkey; + bool key_ok = false; + + if (!getGroupKeys(item->meta.mGroupId, keySet)) + { + std::cerr << "p3IdService::cache_store() ERROR getting GroupKeys for: "; + std::cerr << item->meta.mGroupId; + std::cerr << std::endl; + return false; + } + + std::map::iterator kit; + + //std::cerr << "p3IdService::cache_store() KeySet is:"; + //keySet.print(std::cerr, 10); + + for (kit = keySet.keys.begin(); kit != keySet.keys.end(); kit++) + { + if (kit->second.keyFlags | RSTLV_KEY_DISTRIB_PRIVATE) + { + std::cerr << "p3IdService::cache_store() Found Publish Key"; + std::cerr << std::endl; + + pubkey = kit->second; + key_ok = true; + } + } + + if (!key_ok) + { + std::cerr << "p3IdService::cache_store() ERROR No Public Key Found"; + std::cerr << std::endl; + return false; + } + + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ // Create Cache Data. - RsGxsIdCache cache(item); + RsGxsIdCache cache(item, pubkey); // For consistency std::map::iterator it; @@ -399,7 +419,6 @@ bool p3IdService::cache_store(const RsGxsIdGroupItem *item) /* add new lrumap entry */ time_t old_ts = 0; time_t new_ts = time(NULL); - it->second.lastUsedTs = new_ts; locked_cache_update_lrumap(cache.id, old_ts, new_ts); @@ -714,12 +733,13 @@ bool p3IdService::cache_check_consistency() /************************************************************************************/ /************************************************************************************/ -#if 0 +#define TEST_PERIOD 60 + bool p3IdService::cachetest_tick() { /* every minute - run a background check */ time_t now = time(NULL); - bool doCycle = false; + bool doTest = false; { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ if (now - mCacheTest_LastTs > TEST_PERIOD) @@ -729,8 +749,10 @@ bool p3IdService::cachetest_tick() } } - if (doCycle) + if (doTest) { + std::cerr << "p3IdService::cachetest_tick() starting"; + std::cerr << std::endl; cachetest_getlist(); } @@ -740,17 +762,23 @@ bool p3IdService::cachetest_tick() bool p3IdService::cachetest_getlist() { + { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ if (mCacheTest_Active) { + std::cerr << "p3IdService::cachetest_getlist() Already active"; + std::cerr << std::endl; return false; } } + std::cerr << "p3IdService::cachetest_getlist() making request"; + std::cerr << std::endl; + uint32_t ansType = RS_TOKREQ_ANSTYPE_LIST; RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_LIST; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; uint32_t token = 0; RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts); @@ -776,37 +804,62 @@ bool p3IdService::cachetest_request() token = mCacheTest_Token; } + std::cerr << "p3IdService::cachetest_request() checking request"; + std::cerr << std::endl; + uint32_t status = RsGenExchange::getTokenService()->requestStatus(token); if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) { - std::cerr << "p3IdService::cache_load_for_token() : " << token; + std::cerr << "p3IdService::cachetest_request() token ready: " << token; std::cerr << std::endl; - std::vector grpIds; + std::list grpIds; bool ok = RsGenExchange::getGroupList(token, grpIds); + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + mCacheTest_Active = false; + } + if(ok) { - std::vector::iterator vit = grpIds.begin(); + std::list::iterator vit = grpIds.begin(); for(; vit != grpIds.end(); vit++) { /* 5% chance of checking it! */ - if (RsRandom::f32() < 0.05) + if (RSRandom::random_f32() < 0.05) { + std::cerr << "p3IdService::cachetest_request() Testing Id: " << *vit; + std::cerr << std::endl; + /* try the cache! */ if (!haveKey(*vit)) { std::list nullpeers; requestKey(*vit, nullpeers); + + std::cerr << "p3IdService::cachetest_request() Requested Key Id: " << *vit; + std::cerr << std::endl; } else { RsTlvSecurityKey seckey; if (getKey(*vit, seckey)) { - // success! + std::cerr << "p3IdService::cachetest_request() Got Key OK Id: " << *vit; + std::cerr << std::endl; + // success! + seckey.print(std::cerr, 10); + std::cerr << std::endl; + + + } + else + { + std::cerr << "p3IdService::cachetest_request() ERROR no Key for Id: " << *vit; + std::cerr << std::endl; } } @@ -814,6 +867,8 @@ bool p3IdService::cachetest_request() if (!havePrivateKey(*vit)) { requestPrivateKey(*vit); + std::cerr << "p3IdService::cachetest_request() Requested PrivateKey Id: " << *vit; + std::cerr << std::endl; } else { @@ -821,7 +876,13 @@ bool p3IdService::cachetest_request() if (getPrivateKey(*vit, seckey)) { // success! - + std::cerr << "p3IdService::cachetest_request() Got PrivateKey OK Id: " << *vit; + std::cerr << std::endl; + } + else + { + std::cerr << "p3IdService::cachetest_request() ERROR no PrivateKey for Id: " << *vit; + std::cerr << std::endl; } } } @@ -838,9 +899,6 @@ bool p3IdService::cachetest_request() return true; } -#endif - - /************************************************************************************/ /************************************************************************************/ @@ -873,6 +931,7 @@ void p3IdService::generateDummyData() std::string ownId = rsPeers->getGPGOwnId(); gpgids.push_back(ownId); + int genCount = 0; int i; for(it = gpgids.begin(); it != gpgids.end(); it++) { @@ -928,11 +987,15 @@ void p3IdService::generateDummyData() id.mGpgIdKnown = false; } - //mIds[id.mKeyId] = id; - //mIdProxy->addGroup(id); - // STORE uint32_t dummyToken = 0; createGroup(dummyToken, id); + +// LIMIT - AS GENERATION IS BROKEN. +#define MAX_TEST_GEN 25 + if (++genCount > MAX_TEST_GEN) + { + return; + } } } diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index 7096ad3bc..bce0d47bc 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -80,7 +80,7 @@ class RsGxsIdCache { public: RsGxsIdCache(); - RsGxsIdCache(const RsGxsIdGroupItem *item); + RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvSecurityKey &in_pkey); RsGxsId id; std::string name; @@ -144,9 +144,11 @@ virtual bool createIdentity(uint32_t& token, RsIdentityParameters ¶ms); * */ virtual bool haveKey(const RsGxsId &id); -virtual bool havePrivateKey(const RsGxsId &id); virtual bool requestKey(const RsGxsId &id, const std::list &peers); virtual int getKey(const RsGxsId &id, RsTlvSecurityKey &key); + +virtual bool havePrivateKey(const RsGxsId &id); +virtual bool requestPrivateKey(const RsGxsId &id); virtual int getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key); /**************** RsGixsReputation Implementation @@ -199,6 +201,20 @@ virtual bool getReputation(const RsGxsId &id, const GixsReputation &rep); std::list mCacheLoad_Tokens; +/************************************************************************ + * Test fns for Caching. + * + */ + bool cachetest_tick(); + bool cachetest_getlist(); + bool cachetest_request(); + + /* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */ + + time_t mCacheTest_LastTs; + bool mCacheTest_Active; + uint32_t mCacheTest_Token; + /************************************************************************ * Below is the background task for processing opinions => reputations * From a074c40e6f2912e346e5d69c7a7d0a24bb18fb33 Mon Sep 17 00:00:00 2001 From: drbob Date: Sat, 3 Nov 2012 12:41:11 +0000 Subject: [PATCH 126/222] adding basic caching functionality. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5765 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/util/rsmemcache.h | 273 ++++++++++++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 libretroshare/src/util/rsmemcache.h diff --git a/libretroshare/src/util/rsmemcache.h b/libretroshare/src/util/rsmemcache.h new file mode 100644 index 000000000..6d707f78d --- /dev/null +++ b/libretroshare/src/util/rsmemcache.h @@ -0,0 +1,273 @@ +/* + * libretroshare/src/util: rsmemcache.h + * + * Identity interface for RetroShare. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ +#ifndef RS_MEM_CACHE +#define RS_MEM_CACHE + +#include +#include + +/************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ + +/* Generic Memoory Cache + * + * This is probably crude and crap to start with. + * Want Least Recently Used (LRU) discard policy, without having to search whole cache. + * Use two maps: + * - mDataMap[key] => data. + * - mLruMap[AccessTS] => key (multimap) + */ + +#define DEFAULT_MEM_CACHE_SIZE 10 + +template class RsMemCache +{ + RsMemCache(uint32_t max_size = DEFAULT_MEM_CACHE_SIZE) + :mMaxSize(max_size) { return; } + + bool is_cached(const Key &key) const; + bool fetch(const Key &key, Value &data); + bool store(const Key &key, const Value &data); + + private: + + bool update_lrumap(const Key &key, time_t old_ts, time_t new_ts); + bool discard_LRU(int count_to_clear); + bool resize(); + + // internal class. + class cache_data + { + public: + cache_data() { return; } + cache_data(Key in_key, Value in_data, time_t in_ts) + :key(in_key), data(in_data), ts(in_ts) { return; } + Key key; + Value data; + time_t ts; + }; + + + std::map mDataMap; + std::multimap mLruMap; + uint32_t mDataCount; + uint32_t mMaxSize; +}; + + +template bool RsMemCache::is_cached(const Key &key) const +{ + std::map::const_iterator it; + it = mDataMap.find(key); + if (it == mDataMap.end()) + { + std::cerr << "RsMemCache::is_cached(" << key << ") false"; + std::cerr << std::endl; + + return false; + } + std::cerr << "RsMemCache::is_cached(" << key << ") false"; + std::cerr << std::endl; + return true; + +} + + +template bool RsMemCache::fetch(const Key &key, Value &data) +{ + std::map::const_iterator it; + //std::map >::iterator it; + it = mDataMap.find(key); + if (it == mDataMap.end()) + { + std::cerr << "RsMemCache::fetch(" << key << ") false"; + std::cerr << std::endl; + + return false; + } + + std::cerr << "RsMemCache::fetch(" << key << ") OK"; + std::cerr << std::endl; + + data = it->second.data; + + /* update ts on data */ + time_t old_ts = it->second.ts; + time_t new_ts = time(NULL); + it->second.ts = new_ts; + + update_lrumap(key, old_ts, new_ts); + + return true; +} + +template bool RsMemCache::store(const Key &key, const Value &data) +{ + std::cerr << "RsMemCache::store()"; + std::cerr << std::endl; + + // For consistency + std::map::const_iterator it; + it = mDataMap.find(key); + if (it != mDataMap.end()) + { + // ERROR. + std::cerr << "RsMemCache::store() ERROR entry exists already"; + std::cerr << std::endl; + return false; + } + + /* add new lrumap entry */ + time_t old_ts = 0; + time_t new_ts = time(NULL); + + mDataMap[key] = cache_data(key, data, new_ts); + mDataCount++; + + update_lrumap(key, old_ts, new_ts); + + return true; +} + + +template bool RsMemCache::update_lrumap(const Key &key, time_t old_ts, time_t new_ts) +{ + if (old_ts == 0) + { + std::cerr << "p3IdService::locked_cache_update_lrumap(" << key << ") just insert!"; + std::cerr << std::endl; + + /* new insertion */ + mLruMap.insert(std::make_pair(new_ts, key)); + return true; + } + + /* find old entry */ + std::multimap::iterator mit; + std::multimap::iterator sit = mLruMap.lower_bound(old_ts); + std::multimap::iterator eit = mLruMap.upper_bound(old_ts); + + for(mit = sit; mit != eit; mit++) + { + if (mit->second == key) + { + mLruMap.erase(mit); + std::cerr << "p3IdService::locked_cache_update_lrumap(" << key << ") rm old"; + std::cerr << std::endl; + + if (new_ts != 0) // == 0, means remove. + { + std::cerr << "p3IdService::locked_cache_update_lrumap(" << key << ") added new_ts"; + std::cerr << std::endl; + mLruMap.insert(std::make_pair(new_ts, key)); + } + return true; + } + } + std::cerr << "p3IdService::locked_cache_update_lrumap(" << key << ") ERROR"; + std::cerr << std::endl; + + return false; +} + +template bool RsMemCache::resize() +{ + std::cerr << "RsMemCache::resize()"; + std::cerr << std::endl; + + int count_to_clear = 0; + { + // consistency check. + if ((mDataMap.size() != mDataCount) || + (mLruMap.size() != mDataCount)) + { + // ERROR. + std::cerr << "RsMemCache::resize() CONSISTENCY ERROR"; + std::cerr << std::endl; + } + + if (mDataCount > mMaxSize) + { + count_to_clear = mDataCount - mMaxSize; + std::cerr << "RsMemCache::resize() to_clear: " << count_to_clear; + std::cerr << std::endl; + } + } + + if (count_to_clear > 0) + { + discard_LRU(count_to_clear); + } + return true; +} + + + +template bool RsMemCache::discard_LRU(int count_to_clear) +{ + while(count_to_clear > 0) + { + std::multimap::iterator mit = mLruMap.begin(); + if (mit != mLruMap.end()) + { + Key key = mit->second; + mLruMap.erase(mit); + + /* now clear from real cache */ + //std::map >::iterator it; + std::map::iterator it; + it = mDataMap.find(key); + if (it == mDataMap.end()) + { + // ERROR + std::cerr << "RsMemCache::discard_LRU(): ERROR Missing key: " << key; + std::cerr << std::endl; + return false; + } + else + { + std::cerr << "RsMemCache::discard_LRU() removing: " << key; + std::cerr << std::endl; + mDataMap.erase(it); + mDataCount--; + } + } + else + { + // No More Data, ERROR. + std::cerr << "RsMemCache::discard_LRU(): INFO more more cache data"; + std::cerr << std::endl; + return true; + } + count_to_clear--; + } + return true; +} + + + + +#endif // RS_MEM_CACHE From ffa829971816d7bcac4bf2867fb4e7078049a27c Mon Sep 17 00:00:00 2001 From: drbob Date: Sat, 3 Nov 2012 13:15:21 +0000 Subject: [PATCH 127/222] * Fixed iterator bug in rsmemcache.h * Added rsmemcache.h to libretroshare.pro * initialised variables in p3idservice (was killing caching). git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5766 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/libretroshare.pro | 3 ++- libretroshare/src/services/p3idservice.cc | 6 ++++- libretroshare/src/services/p3idservice.h | 2 ++ libretroshare/src/util/rsmemcache.h | 27 ++++++++++++----------- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 86abb1c0d..0e259ca4c 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -429,7 +429,8 @@ HEADERS += retroshare/rsgame.h \ util/rswin.h \ util/rsrandom.h \ util/radix64.h \ - util/pugiconfig.h + util/pugiconfig.h \ + util/rsmemcache.h SOURCES += dbase/cachestrapper.cc \ dbase/fimonitor.cc \ diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 455ecaff4..e35b769fc 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -55,9 +55,13 @@ p3IdService::p3IdService(RsGeneralDataService *gds, RsNetworkExchangeService *ne mIdMtx("p3IdService") { mCacheTest_LastTs = 0; - mCacheLoad_LastCycle = 0; mCacheTest_Active = false; + mCacheLoad_LastCycle = 0; + mCacheLoad_Status = 0; + + mCacheDataCount = 0; + } void p3IdService::service_tick() diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index bce0d47bc..db4947362 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -34,6 +34,8 @@ #include #include +#include "util/rsmemcache.h" + /* * Identity Service * diff --git a/libretroshare/src/util/rsmemcache.h b/libretroshare/src/util/rsmemcache.h index 6d707f78d..d08dac717 100644 --- a/libretroshare/src/util/rsmemcache.h +++ b/libretroshare/src/util/rsmemcache.h @@ -22,11 +22,13 @@ * Please report all bugs and problems to "retroshare@lunamutt.com". * */ -#ifndef RS_MEM_CACHE -#define RS_MEM_CACHE +#ifndef RS_UTIL_MEM_CACHE +#define RS_UTIL_MEM_CACHE #include #include +#include +#include /************************************************************************************/ /************************************************************************************/ @@ -46,7 +48,7 @@ template class RsMemCache { RsMemCache(uint32_t max_size = DEFAULT_MEM_CACHE_SIZE) - :mMaxSize(max_size) { return; } + :mMaxSize(max_size), mDataCount(0) { return; } bool is_cached(const Key &key) const; bool fetch(const Key &key, Value &data); @@ -80,7 +82,7 @@ template class RsMemCache template bool RsMemCache::is_cached(const Key &key) const { - std::map::const_iterator it; + typename std::map::const_iterator it; it = mDataMap.find(key); if (it == mDataMap.end()) { @@ -98,8 +100,7 @@ template bool RsMemCache::is_cached(const Ke template bool RsMemCache::fetch(const Key &key, Value &data) { - std::map::const_iterator it; - //std::map >::iterator it; + typename std::map::const_iterator it; it = mDataMap.find(key); if (it == mDataMap.end()) { @@ -130,7 +131,7 @@ template bool RsMemCache::store(const Key &k std::cerr << std::endl; // For consistency - std::map::const_iterator it; + typename std::map::const_iterator it; it = mDataMap.find(key); if (it != mDataMap.end()) { @@ -166,9 +167,9 @@ template bool RsMemCache::update_lrumap(cons } /* find old entry */ - std::multimap::iterator mit; - std::multimap::iterator sit = mLruMap.lower_bound(old_ts); - std::multimap::iterator eit = mLruMap.upper_bound(old_ts); + typename std::multimap::iterator mit; + typename std::multimap::iterator sit = mLruMap.lower_bound(old_ts); + typename std::multimap::iterator eit = mLruMap.upper_bound(old_ts); for(mit = sit; mit != eit; mit++) { @@ -230,7 +231,7 @@ template bool RsMemCache::discard_LRU(int co { while(count_to_clear > 0) { - std::multimap::iterator mit = mLruMap.begin(); + typename std::multimap::iterator mit = mLruMap.begin(); if (mit != mLruMap.end()) { Key key = mit->second; @@ -238,7 +239,7 @@ template bool RsMemCache::discard_LRU(int co /* now clear from real cache */ //std::map >::iterator it; - std::map::iterator it; + typename std::map::iterator it; it = mDataMap.find(key); if (it == mDataMap.end()) { @@ -270,4 +271,4 @@ template bool RsMemCache::discard_LRU(int co -#endif // RS_MEM_CACHE +#endif // RS_UTIL_MEM_CACHE From e42cc1123cd79012e438375c2618295066538b68 Mon Sep 17 00:00:00 2001 From: drbob Date: Sat, 3 Nov 2012 14:07:26 +0000 Subject: [PATCH 128/222] Switched to RsMemCache for Key caching. - supports both private and public caching now. - bug fix in RsMemCache git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5767 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/services/p3idservice.cc | 283 +++++----------------- libretroshare/src/services/p3idservice.h | 29 ++- libretroshare/src/util/rsmemcache.h | 11 +- 3 files changed, 77 insertions(+), 246 deletions(-) diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index e35b769fc..4d839b2c1 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -59,9 +59,6 @@ p3IdService::p3IdService(RsGeneralDataService *gds, RsNetworkExchangeService *ne mCacheLoad_LastCycle = 0; mCacheLoad_Status = 0; - - mCacheDataCount = 0; - } void p3IdService::service_tick() @@ -126,31 +123,28 @@ bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) bool p3IdService::haveKey(const RsGxsId &id) { - /* is it in the cache? */ - return cache_is_loaded(id); + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + return mPublicKeyCache.is_cached(id); } bool p3IdService::havePrivateKey(const RsGxsId &id) { - /* TODO */ - return false; + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + return mPrivateKeyCache.is_cached(id); } bool p3IdService::requestKey(const RsGxsId &id, const std::list &peers) { - /* basic version first --- don't have to worry about network load - * request it for the cache - */ - if (cache_is_loaded(id)) + if (haveKey(id)) return true; - return cache_request_load(id); } int p3IdService::getKey(const RsGxsId &id, RsTlvSecurityKey &key) { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ RsGxsIdCache data; - if (cache_fetch(id, data)) + if (mPublicKeyCache.fetch(id, data)) { key = data.pubkey; return 1; @@ -160,12 +154,20 @@ int p3IdService::getKey(const RsGxsId &id, RsTlvSecurityKey &key) bool p3IdService::requestPrivateKey(const RsGxsId &id) { - return false; + if (havePrivateKey(id)) + return true; + return cache_request_load(id); } int p3IdService::getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key) { - /* TODO */ + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + RsGxsIdCache data; + if (mPrivateKeyCache.fetch(id, data)) + { + key = data.pubkey; + return 1; + } return -1; } @@ -306,56 +308,6 @@ RsGxsIdCache::RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvSecurityKey } - -bool p3IdService::cache_is_loaded(const RsGxsId &id) -{ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it; - it = mCacheDataMap.find(id); - if (it == mCacheDataMap.end()) - { - std::cerr << "p3IdService::cache_is_loaded(" << id << ") false"; - std::cerr << std::endl; - - return false; - } - std::cerr << "p3IdService::cache_is_loaded(" << id << ") true"; - std::cerr << std::endl; - - return true; - -} - -bool p3IdService::cache_fetch(const RsGxsId &id, RsGxsIdCache &data) -{ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it; - it = mCacheDataMap.find(id); - if (it == mCacheDataMap.end()) - { - std::cerr << "p3IdService::cache_fetch(" << id << ") false"; - std::cerr << std::endl; - - return false; - } - - std::cerr << "p3IdService::cache_fetch(" << id << ") OK"; - std::cerr << std::endl; - - data = it->second; - - /* update ts on data */ - time_t old_ts = it->second.lastUsedTs; - time_t new_ts = time(NULL); - it->second.lastUsedTs = new_ts; - - locked_cache_update_lrumap(id, old_ts, new_ts); - - return true; -} - bool p3IdService::cache_store(const RsGxsIdGroupItem *item) { std::cerr << "p3IdService::cache_store() Item: "; @@ -366,9 +318,12 @@ bool p3IdService::cache_store(const RsGxsIdGroupItem *item) /* extract key from keys */ RsTlvSecurityKeySet keySet; RsTlvSecurityKey pubkey; - bool key_ok = false; + RsTlvSecurityKey fullkey; + bool pub_key_ok = false; + bool full_key_ok = false; - if (!getGroupKeys(item->meta.mGroupId, keySet)) + RsGxsId id = item->meta.mGroupId; + if (!getGroupKeys(id, keySet)) { std::cerr << "p3IdService::cache_store() ERROR getting GroupKeys for: "; std::cerr << item->meta.mGroupId; @@ -383,176 +338,47 @@ bool p3IdService::cache_store(const RsGxsIdGroupItem *item) for (kit = keySet.keys.begin(); kit != keySet.keys.end(); kit++) { - if (kit->second.keyFlags | RSTLV_KEY_DISTRIB_PRIVATE) + if (kit->second.keyFlags | RSTLV_KEY_DISTRIB_ADMIN) { - std::cerr << "p3IdService::cache_store() Found Publish Key"; + std::cerr << "p3IdService::cache_store() Found Admin Key"; std::cerr << std::endl; + /* save full key - if we have it */ + if (kit->second.keyFlags | RSTLV_KEY_TYPE_FULL) + { + fullkey = kit->second; + full_key_ok = true; + } + + /* cache public key always */ pubkey = kit->second; - key_ok = true; + pub_key_ok = true; } } - if (!key_ok) + if (!pub_key_ok) { std::cerr << "p3IdService::cache_store() ERROR No Public Key Found"; std::cerr << std::endl; return false; } - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ // Create Cache Data. - RsGxsIdCache cache(item, pubkey); + RsGxsIdCache pubcache(item, pubkey); + mPublicKeyCache.store(id, pubcache); - // For consistency - std::map::iterator it; - it = mCacheDataMap.find(cache.id); - if (it != mCacheDataMap.end()) + if (full_key_ok) { - // ERROR. - std::cerr << "p3IdService::cache_store() ERROR entry exists already"; - std::cerr << std::endl; - return false; + RsGxsIdCache fullcache(item, fullkey); + mPrivateKeyCache.store(id, fullcache); } - mCacheDataMap[cache.id] = cache; - mCacheDataCount++; - - /* add new lrumap entry */ - time_t old_ts = 0; - time_t new_ts = time(NULL); - - locked_cache_update_lrumap(cache.id, old_ts, new_ts); - return true; } -bool p3IdService::locked_cache_update_lrumap(const RsGxsId &key, time_t old_ts, time_t new_ts) -{ - if (old_ts == 0) - { - std::cerr << "p3IdService::locked_cache_update_lrumap(" << key << ") just insert!"; - std::cerr << std::endl; - - LruData data; - data.key = key; - /* new insertion */ - mCacheLruMap.insert(std::make_pair(new_ts, data)); - return true; - } - - /* find old entry */ - std::multimap::iterator mit; - std::multimap::iterator sit = mCacheLruMap.lower_bound(old_ts); - std::multimap::iterator eit = mCacheLruMap.upper_bound(old_ts); - - for(mit = sit; mit != eit; mit++) - { - if (mit->second.key == key) - { - LruData data = mit->second; - mCacheLruMap.erase(mit); - std::cerr << "p3IdService::locked_cache_update_lrumap(" << key << ") rm old"; - std::cerr << std::endl; - - if (new_ts != 0) // == 0, means remove. - { - std::cerr << "p3IdService::locked_cache_update_lrumap(" << key << ") added new_ts"; - std::cerr << std::endl; - mCacheLruMap.insert(std::make_pair(new_ts, data)); - } - return true; - } - } - std::cerr << "p3IdService::locked_cache_update_lrumap(" << key << ") ERROR"; - std::cerr << std::endl; - - return false; -} - - -bool p3IdService::cache_resize() -{ - std::cerr << "p3IdService::cache_resize()"; - std::cerr << std::endl; - - int count_to_clear = 0; - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - // consistency check. - if ((mCacheDataMap.size() != mCacheDataCount) || - (mCacheLruMap.size() != mCacheDataCount)) - { - // ERROR. - std::cerr << "p3IdService::cache_resize() CONSISTENCY ERROR"; - std::cerr << std::endl; - } - - if (mCacheDataCount > MAX_CACHE_SIZE) - { - count_to_clear = mCacheDataCount - MAX_CACHE_SIZE; - std::cerr << "p3IdService::cache_resize() to_clear: " << count_to_clear; - std::cerr << std::endl; - } - } - - if (count_to_clear > 0) - { - cache_discard_LRU(count_to_clear); - } - return true; -} - - - -bool p3IdService::cache_discard_LRU(int count_to_clear) -{ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - while(count_to_clear > 0) - { - std::multimap::iterator mit = mCacheLruMap.begin(); - if (mit != mCacheLruMap.end()) - { - LruData data = mit->second; - mCacheLruMap.erase(mit); - - /* now clear from real cache */ - std::map::iterator it; - it = mCacheDataMap.find(data.key); - if (it == mCacheDataMap.end()) - { - // ERROR - std::cerr << "p3IdService::cache_discard_LRU(): ERROR Missing key: " << data.key; - std::cerr << std::endl; - return false; - } - else - { - std::cerr << "p3IdService::cache_discard_LRU() removing: " << data.key; - std::cerr << std::endl; - mCacheDataMap.erase(it); - mCacheDataCount--; - } - } - else - { - // No More Data, ERROR. - std::cerr << "p3IdService::cache_discard_LRU(): INFO more more cache data"; - std::cerr << std::endl; - return true; - } - count_to_clear--; - } - return true; -} - - - /***** BELOW LOADS THE CACHE FROM GXS DATASTORE *****/ @@ -655,6 +481,8 @@ bool p3IdService::cache_check_loading() /* check the status of all active tokens */ std::list toload; std::list::iterator it; + + bool stuffToLoad = false; { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ for(it = mCacheLoad_Tokens.begin(); it != mCacheLoad_Tokens.end();) @@ -670,6 +498,7 @@ bool p3IdService::cache_check_loading() { it = mCacheLoad_Tokens.erase(it); toload.push_back(token); + stuffToLoad = true; } else { @@ -678,9 +507,16 @@ bool p3IdService::cache_check_loading() } } - for(it = toload.begin(); it != toload.end(); it++) + if (stuffToLoad) { - cache_load_for_token(*it); + for(it = toload.begin(); it != toload.end(); it++) + { + cache_load_for_token(*it); + } + + // cleanup. + mPrivateKeyCache.resize(); + mPublicKeyCache.resize(); } return 1; @@ -718,22 +554,10 @@ bool p3IdService::cache_load_for_token(uint32_t token) return false; } - - - /* drop old entries */ - cache_resize(); - return true; } - -bool p3IdService::cache_check_consistency() -{ - - return false; -} - /************************************************************************************/ /************************************************************************************/ @@ -832,7 +656,7 @@ bool p3IdService::cachetest_request() for(; vit != grpIds.end(); vit++) { /* 5% chance of checking it! */ - if (RSRandom::random_f32() < 0.05) + if (RSRandom::random_f32() < 0.25) { std::cerr << "p3IdService::cachetest_request() Testing Id: " << *vit; std::cerr << std::endl; @@ -995,13 +819,14 @@ void p3IdService::generateDummyData() createGroup(dummyToken, id); // LIMIT - AS GENERATION IS BROKEN. -#define MAX_TEST_GEN 25 +#define MAX_TEST_GEN 50 if (++genCount > MAX_TEST_GEN) { return; } } } + return; #define MAX_RANDOM_GPGIDS 10 //1000 #define MAX_RANDOM_PSEUDOIDS 50 //5000 diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index db4947362..593cf3fbf 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -175,33 +175,36 @@ virtual bool getReputation(const RsGxsId &id, const GixsReputation &rep); */ int cache_tick(); - bool cache_is_loaded(const RsGxsId &id); - bool cache_fetch(const RsGxsId &key, RsGxsIdCache &data); - bool cache_store(const RsGxsIdGroupItem *item); - bool cache_store(const RsGxsIdGroup &group); - bool cache_resize(); - bool cache_discard_LRU(int count_to_clear); + //bool cache_is_loaded(const RsGxsId &id); + //bool cache_fetch(const RsGxsId &key, RsGxsIdCache &data); + + //bool cache_store(const RsGxsIdGroup &group); + //bool cache_resize(); + //bool cache_discard_LRU(int count_to_clear); bool cache_request_load(const RsGxsId &id); bool cache_start_load(); bool cache_check_loading(); bool cache_load_for_token(uint32_t token); - bool cache_check_consistency(); + + bool cache_store(const RsGxsIdGroupItem *item); /* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */ - - bool locked_cache_update_lrumap(const RsGxsId &key, time_t old_ts, time_t new_ts); - - std::map mCacheDataMap; - std::multimap mCacheLruMap; - uint32_t mCacheDataCount; + //bool locked_cache_update_lrumap(const RsGxsId &key, time_t old_ts, time_t new_ts); + //std::map mCacheDataMap; + //std::multimap mCacheLruMap; + //uint32_t mCacheDataCount; time_t mCacheLoad_LastCycle; int mCacheLoad_Status; std::list mCacheLoad_ToCache; std::list mCacheLoad_Tokens; + // Switching to RsMemCache for Key Caching. + RsMemCache mPublicKeyCache; + RsMemCache mPrivateKeyCache; + /************************************************************************ * Test fns for Caching. diff --git a/libretroshare/src/util/rsmemcache.h b/libretroshare/src/util/rsmemcache.h index d08dac717..66087ce34 100644 --- a/libretroshare/src/util/rsmemcache.h +++ b/libretroshare/src/util/rsmemcache.h @@ -43,22 +43,25 @@ * - mLruMap[AccessTS] => key (multimap) */ -#define DEFAULT_MEM_CACHE_SIZE 10 +#define DEFAULT_MEM_CACHE_SIZE 100 template class RsMemCache { + public: + RsMemCache(uint32_t max_size = DEFAULT_MEM_CACHE_SIZE) - :mMaxSize(max_size), mDataCount(0) { return; } + :mDataCount(0), mMaxSize(max_size) { return; } bool is_cached(const Key &key) const; bool fetch(const Key &key, Value &data); bool store(const Key &key, const Value &data); + bool resize(); // should be called periodically to cleanup old entries. + private: bool update_lrumap(const Key &key, time_t old_ts, time_t new_ts); bool discard_LRU(int count_to_clear); - bool resize(); // internal class. class cache_data @@ -100,7 +103,7 @@ template bool RsMemCache::is_cached(const Ke template bool RsMemCache::fetch(const Key &key, Value &data) { - typename std::map::const_iterator it; + typename std::map::iterator it; it = mDataMap.find(key); if (it == mDataMap.end()) { From 49096d29d25915f05b13ae90cb0f099c05f7f887 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sun, 4 Nov 2012 01:38:48 +0000 Subject: [PATCH 129/222] - Added service_createGroup function which gives access to group keys and grpItem just before GXS group creation - Temp fix for GXS services hang on dummy data generation. Given each GXS service own thread and chunked grp creation (separate thread may need to be permanent, no obvious around move grp gen cost away from critical path of tick, but unscientifically increases each services thread tick period to reduce cpu cost) - change grpId assignment from hash of grp data to admin keyid git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5772 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgenexchange.cc | 233 ++++++++++++++++--------- libretroshare/src/gxs/rsgenexchange.h | 26 ++- libretroshare/src/rsserver/rsinit.cc | 23 ++- 3 files changed, 189 insertions(+), 93 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 555d1513a..bc007bde2 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -57,6 +57,22 @@ RsGenExchange::~RsGenExchange() } +void RsGenExchange::run() +{ + + double timeDelta = 0.06; // slow tick + + while(true) + { + tick(); + +#ifndef WINDOWS_SYS + usleep((int) (timeDelta * 1000000)); +#else + Sleep((int) (timeDelta * 1000)); +#endif + } +} void RsGenExchange::tick() { @@ -125,7 +141,7 @@ bool RsGenExchange::acknowledgeTokenGrp(const uint32_t& token, return true; } -bool RsGenExchange::createGroup(RsNxsGrp *grp) +void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet) { /* create Keys */ @@ -149,6 +165,17 @@ bool RsGenExchange::createGroup(RsNxsGrp *grp) GxsSecurity::setRSAPublicKey(pubKey, rsa_publish_pub); GxsSecurity::setRSAPrivateKey(privPubKey, rsa_publish); + adminKey.startTS = time(NULL); + adminKey.endTS = 0; /* no end */ + + privAdminKey.startTS = time(NULL); + privAdminKey.endTS = 0; /* no end */ + + pubKey.startTS = time(NULL); + pubKey.endTS = 0; /* no end */ + + privPubKey.startTS = time(NULL); + privPubKey.endTS = 0; /* no end */ // for now all public adminKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_PUBLIC_ONLY; @@ -158,51 +185,11 @@ bool RsGenExchange::createGroup(RsNxsGrp *grp) pubKey.keyFlags = RSTLV_KEY_DISTRIB_PUBLIC | RSTLV_KEY_TYPE_PUBLIC_ONLY; privPubKey.keyFlags = RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL; - adminKey.startTS = time(NULL); - adminKey.endTS = 0; /* no end */ - RsGxsGrpMetaData* meta = grp->metaData; + keySet.keys[adminKey.keyId] = adminKey; + keySet.keys[pubKey.keyId] = pubKey; - /* add public keys to grp */ - - meta->keys.keys[adminKey.keyId] = adminKey; - meta->keys.keys[pubKey.keyId] = pubKey; - - // group is self signing - // for the creation of group signature - // only public admin and publish keys are present - // key set - uint32_t metaDataLen = meta->serial_size(); - uint32_t allGrpDataLen = metaDataLen + grp->grp.bin_len; - char* metaData = new char[metaDataLen]; - char* allGrpData = new char[allGrpDataLen]; // msgData + metaData - - meta->serialise(metaData, metaDataLen); - - // copy msg data and meta in allMsgData buffer - memcpy(allGrpData, grp->grp.bin_data, grp->grp.bin_len); - memcpy(allGrpData+(grp->grp.bin_len), metaData, metaDataLen); - - RsTlvKeySignature adminSign; - bool ok = GxsSecurity::getSignature(allGrpData, allGrpDataLen, &privAdminKey, adminSign); - - /* now add private keys to grp */ - meta->keys.keys[privAdminKey.keyId] = privAdminKey; - meta->keys.keys[privPubKey.keyId] = privPubKey; - - // add admin sign to grpMeta - meta->signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_ADMIN] = adminSign; - - pqihash hash; - - // get hash of msg data to create msg id - hash.addData(allGrpData, allGrpDataLen); - hash.Complete(meta->mGroupId); - grp->grpId = meta->mGroupId; - - adminKey.TlvClear(); - privAdminKey.TlvClear(); - privPubKey.TlvClear(); - pubKey.TlvClear(); + keySet.keys[privAdminKey.keyId] = privAdminKey; + keySet.keys[privPubKey.keyId] = privPubKey; // clean up RSA_free(rsa_admin); @@ -210,7 +197,59 @@ bool RsGenExchange::createGroup(RsNxsGrp *grp) RSA_free(rsa_publish); RSA_free(rsa_publish_pub); +} +bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet) +{ + + + RsGxsGrpMetaData* meta = grp->metaData; + + /* add keys to grp */ + meta->keys = keySet; + + // find private admin key + RsTlvSecurityKey privAdminKey; + std::map::iterator mit = keySet.keys.begin(); + + for(; mit != keySet.keys.end(); mit++) + { + RsTlvSecurityKey& pk = mit->second; + + if(pk.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL)) + { + privAdminKey = pk; + break; + } + } + + if(mit == keySet.keys.end()) + return false; + + // group is self signing + // for the creation of group signature + // only public admin and publish keys are present + // key set + uint32_t metaDataLen = meta->serial_size(); + uint32_t allGrpDataLen = metaDataLen + grp->grp.bin_len; + char* metaData = new char[metaDataLen]; + char* allGrpData = new char[allGrpDataLen]; // msgData + metaData + + meta->serialise(metaData, metaDataLen); + + // copy msg data and meta in allMsgData buffer + memcpy(allGrpData, grp->grp.bin_data, grp->grp.bin_len); + memcpy(allGrpData+(grp->grp.bin_len), metaData, metaDataLen); + + RsTlvKeySignature adminSign; + bool ok = GxsSecurity::getSignature(allGrpData, allGrpDataLen, &privAdminKey, adminSign); + + // add admin sign to grpMeta + meta->signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_ADMIN] = adminSign; + + grp->grpId = meta->mGroupId = privAdminKey.keyId; + + // clean up delete[] allGrpData; delete[] metaData; @@ -684,64 +723,89 @@ void RsGenExchange::publishMsgs() mMsgsToPublish.clear(); } +void RsGenExchange::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet) +{ +#ifdef GEN_EXCH_DEBUG + std::cerr << "RsGenExchange::service_CreateGroup(): Does nothing" + << std::endl; +#endif + return; +} + + +#define GEN_EXCH_GRP_CHUNK 3 + void RsGenExchange::publishGrps() { RsStackMutex stack(mGenMtx); std::map::iterator mit = mGrpsToPublish.begin(); - + std::vector toRemove; + int i = 0; for(; mit != mGrpsToPublish.end(); mit++) { + toRemove.push_back(mit->first); + i++; + if(i > GEN_EXCH_GRP_CHUNK) break; - RsNxsGrp* grp = new RsNxsGrp(mServType); - RsGxsGrpItem* grpItem = mit->second; - uint32_t size = mSerialiser->size(grpItem); + RsNxsGrp* grp = new RsNxsGrp(mServType); + RsGxsGrpItem* grpItem = mit->second; + uint32_t size = mSerialiser->size(grpItem); - char gData[size]; - bool ok = mSerialiser->serialise(grpItem, gData, &size); - grp->grp.setBinData(gData, size); + RsTlvSecurityKeySet keySet; + generateGroupKeys(keySet); - if(ok) - { - grp->metaData = new RsGxsGrpMetaData(); - grpItem->meta.mPublishTs = time(NULL); - *(grp->metaData) = grpItem->meta; - grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; - ok &= createGroup(grp); - size = grp->metaData->serial_size(); - char mData[size]; - grp->metaData->mGroupId = grp->grpId; - ok &= grp->metaData->serialise(mData, size); - grp->meta.setBinData(mData, size); - RsGxsGroupId grpId = grp->grpId; - mDataAccess->addGroupData(grp); + service_CreateGroup(grpItem, keySet); - // add to published to allow acknowledgement - mGrpNotify.insert(std::make_pair(mit->first, grpId)); - mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE); - } + char gData[size]; + bool ok = mSerialiser->serialise(grpItem, gData, &size); + grp->grp.setBinData(gData, size); - if(!ok) - { + if(ok) + { + grp->metaData = new RsGxsGrpMetaData(); + grpItem->meta.mPublishTs = time(NULL); + *(grp->metaData) = grpItem->meta; + grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; + ok &= createGroup(grp, keySet); + size = grp->metaData->serial_size(); + char mData[size]; + grp->metaData->mGroupId = grp->grpId; + ok &= grp->metaData->serialise(mData, size); + grp->meta.setBinData(mData, size); + RsGxsGroupId grpId = grp->grpId; + mDataAccess->addGroupData(grp); + + // add to published to allow acknowledgement + mGrpNotify.insert(std::make_pair(mit->first, grpId)); + mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE); + } + + if(!ok) + { #ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::publishGrps() failed to publish grp " << std::endl; + std::cerr << "RsGenExchange::publishGrps() failed to publish grp " << std::endl; #endif - delete grp; + delete grp; - // add to published to allow acknowledgement, grpid is empty as grp creation failed - mGrpNotify.insert(std::make_pair(mit->first, RsGxsGroupId(""))); - mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED); - continue; - } + // add to published to allow acknowledgement, grpid is empty as grp creation failed + mGrpNotify.insert(std::make_pair(mit->first, RsGxsGroupId(""))); + mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED); + continue; + } + + delete grpItem; - delete grpItem; } // clear grp list as we're done publishing them and entries // are invalid - mGrpsToPublish.clear(); + + + for(int i = 0; i < toRemove.size(); i++) + mGrpsToPublish.erase(toRemove[i]); } @@ -801,13 +865,18 @@ void RsGenExchange::createDummyGroup(RsGxsGrpItem *grpItem) bool ok = mSerialiser->serialise(grpItem, gData, &size); grp->grp.setBinData(gData, size); + RsTlvSecurityKeySet keySet; + generateGroupKeys(keySet); + + service_CreateGroup(grpItem, keySet); + if(ok) { grp->metaData = new RsGxsGrpMetaData(); grpItem->meta.mPublishTs = time(NULL); *(grp->metaData) = grpItem->meta; grp->metaData->mSubscribeFlags = ~GXS_SERV::GROUP_SUBSCRIBE_MASK; - createGroup(grp); + createGroup(grp, keySet); size = grp->metaData->serial_size(); char mData[size]; grp->metaData->mGroupId = grp->grpId; diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 1bf9caa97..fe18fc74d 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -64,7 +64,7 @@ typedef std::map > GxsMsgMetaMap; class RsGixs; -class RsGenExchange : public RsGxsService, public RsNxsObserver +class RsGenExchange : public RsGxsService, public RsNxsObserver, public RsThread { public: @@ -117,6 +117,8 @@ public: */ RsTokenService* getTokenService(); + void run(); + public: /** data access functions **/ @@ -265,6 +267,20 @@ protected: */ void publishMsg(uint32_t& token, RsGxsMsgItem* msgItem); + /*! + * This represents the group before its signature is calculated + * Reimplement this function if you need to access keys to further extend + * security of your group items using keyset properties + * @warning do not modify keySet! + * @param grp The group which is stored by GXS prior + * service can make specific modifications need + * in particular access to its keys and meta + * @param keySet this is the key set used to define the group + * contains private and public admin and publish keys + * (use key flags to distinguish) + */ + virtual void service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet); + public: /*! @@ -355,7 +371,7 @@ private: * by assigning it a groupId and signature via SHA1 and EVP_sign respectively * @param grp Nxs group to create */ - bool createGroup(RsNxsGrp* grp); + bool createGroup(RsNxsGrp* grp, RsTlvSecurityKeySet& keySet); /*! * This completes the creation of an instance on RsNxsMsg @@ -373,6 +389,12 @@ private: */ bool locked_validateGrpMetaChange(GrpLocMetaData&); + /*! + * Generate a set of keys that can define a GXS group + * @param keySet this is set generated keys + */ + void generateGroupKeys(RsTlvSecurityKeySet& keySet); + private: RsMutex mGenMtx; diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index b39d683d0..4d85f3d19 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1830,7 +1830,7 @@ RsTurtle *rsTurtle = NULL ; #include "services/p3photoserviceV2.h" // Not too many to convert now! -//#include "services/p3wikiserviceVEG.h" +#include "services/p3wikiserviceVEG.h" #include "services/p3wireVEG.h" //#include "services/p3idserviceVEG.h" #include "services/p3forumsVEG.h" @@ -2281,8 +2281,8 @@ int RsServer::StartupRetroShare() #ifdef ENABLE_GXS_SERVICES // Testing New Cache Services. - //p3WikiServiceVEG *mWikis = new p3WikiServiceVEG(RS_SERVICE_GXSV1_TYPE_WIKI); - //pqih -> addService(mWikis); + p3WikiServiceVEG *mWikis = new p3WikiServiceVEG(RS_SERVICE_GXSV1_TYPE_WIKI); + pqih -> addService(mWikis); // Testing New Cache Services. p3WireVEG *mWire = new p3WireVEG(RS_SERVICE_GXSV1_TYPE_WIRE); @@ -2371,12 +2371,17 @@ int RsServer::StartupRetroShare() /*** start up GXS core runner ***/ - GxsCoreServer* mGxsCore = new GxsCoreServer(); - mGxsCore->addService(mGxsIdService); +// GxsCoreServer* mGxsCore = new GxsCoreServer(); + //mGxsCore->addService(mGxsIdService); #if ENABLE_OTHER_GXS_SERVICES - mGxsCore->addService(mPhotoV2); - mGxsCore->addService(mPosted); - mGxsCore->addService(mWiki); + createThread(*mGxsIdService); + createThread(*mPhotoV2); + createThread(*mPosted); + createThread(*mWiki); +// +// mGxsCore->addService(mPhotoV2); +// mGxsCore->addService(mPosted); +// mGxsCore->addService(mWiki); #endif // cores ready start up GXS net servers @@ -2396,7 +2401,7 @@ int RsServer::StartupRetroShare() #endif // start up gxs core server - createThread(*mGxsCore); + //createThread(*mGxsCore); #endif From e803b2c447d0e5f83cc9b9bae665f174d812affd Mon Sep 17 00:00:00 2001 From: defnax Date: Sun, 4 Nov 2012 14:07:55 +0000 Subject: [PATCH 130/222] Changed to switch Start/Stop button text, when Slide is running or not. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5773 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp | 4 ++++ retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.ui | 10 ++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp index 2e9f925bb..f64120908 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp @@ -106,10 +106,14 @@ void PhotoSlideShow::StartStop() if (mRunning) { mRunning = false; + ui.pushButton_StartStop->setText(tr("Start")); + ui.pushButton_StartStop->setToolTip(tr("Start Slide Show")); } else { mRunning = true; + ui.pushButton_StartStop->setText(tr("Stop")); + ui.pushButton_StartStop->setToolTip(tr("Stop Slide Show")); if (!mShotActive) // make sure only one timer running { mShotActive = true; diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.ui b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.ui index be5148197..bc771eec0 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.ui @@ -10,6 +10,9 @@ 671 + + false + @@ -99,7 +102,7 @@ :/images/window_fullscreen.png:/images/window_fullscreen.png - true + false @@ -112,8 +115,11 @@ + + + - Stop/Run + Stop From 17e42f1ceb304500e0c2597705ee1a33364cff28 Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 5 Nov 2012 22:28:08 +0000 Subject: [PATCH 131/222] Added core code for pgphash calculations. - Reworked GxsIdGroup members... moved IdType -> groupFlags, so Hash & Sign are only ones. - Reworked GroupServiceString storage. - Added core processing functions - yet to test! git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5777 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/retroshare/rsidentity.h | 20 +- libretroshare/src/serialiser/rsgxsiditems.cc | 26 +- libretroshare/src/services/p3idservice.cc | 764 +++++++++++++++---- libretroshare/src/services/p3idservice.h | 118 ++- libretroshare/src/util/rsid.h | 11 + 5 files changed, 736 insertions(+), 203 deletions(-) diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index 13209655b..50dce4257 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -37,6 +37,12 @@ class RsIdentity; extern RsIdentity *rsIdentity; + +// GroupFlags: Only one so far: +#define RSGXSID_GROUPFLAG_REALID 0x0001 + + +// THESE ARE FLAGS FOR INTERFACE. #define RSID_TYPE_MASK 0xff00 #define RSID_RELATION_MASK 0x00ff @@ -61,8 +67,7 @@ class RsGxsIdGroup // In GroupMetaData. //std::string mNickname; (mGroupName) //std::string mKeyId; (mGroupId) - - uint32_t mIdType; + //uint32_t mIdType; (mGroupFlags) // SHA(KeyId + Gpg Fingerprint) -> can only be IDed if GPG known. // The length of the input must be long enough to make brute force search implausible. @@ -70,14 +75,11 @@ class RsGxsIdGroup // Easy to do 1e9 SHA-1 hash computations per second on a GPU. // We will need a minimum of 256 bits, ideally 1024 bits or 2048 bits. - std::string mGpgIdHash; + // Actually PgpIdHash is SHA1(.mMeta.mGroupId + PGPHandler->GpgFingerprint(ownId)) + // ??? 160 bits. - // NOTE: These cannot be transmitted as part of underlying messages.... - // Must use ServiceString. - bool mGpgIdKnown; // if GpgIdHash has been identified. - std::string mGpgId; // if known. - std::string mGpgName; // if known. - std::string mGpgEmail; // if known. + std::string mPgpIdHash; + std::string mPgpIdSign; // Need a signature as proof - otherwise anyone could add others Hashes. }; diff --git a/libretroshare/src/serialiser/rsgxsiditems.cc b/libretroshare/src/serialiser/rsgxsiditems.cc index ebacdc7a1..cc788053f 100644 --- a/libretroshare/src/serialiser/rsgxsiditems.cc +++ b/libretroshare/src/serialiser/rsgxsiditems.cc @@ -120,14 +120,8 @@ RsItem* RsGxsIdSerialiser::deserialise(void* data, uint32_t* size) void RsGxsIdGroupItem::clear() { - group.mGpgIdHash.clear(); - group.mIdType = 0; - - // Others that aren't serialised. - but should be cleared anyway - group.mGpgIdKnown = false; - group.mGpgId.clear(); - group.mGpgName.clear(); - group.mGpgEmail.clear(); + group.mPgpIdHash.clear(); + group.mPgpIdSign.clear(); } std::ostream& RsGxsIdGroupItem::print(std::ostream& out, uint16_t indent) @@ -136,9 +130,9 @@ std::ostream& RsGxsIdGroupItem::print(std::ostream& out, uint16_t indent) uint16_t int_Indent = indent + 2; printIndent(out, int_Indent); - out << "IdType: " << group.mIdType << std::endl; + out << "PgpIdHash: " << group.mPgpIdHash << std::endl; printIndent(out, int_Indent); - out << "GpgIdHash: " << group.mGpgIdHash << std::endl; + out << "PgpIdSign: " << group.mPgpIdSign << std::endl; printRsItemEnd(out ,"RsGxsIdGroupItem", indent); return out; @@ -151,8 +145,8 @@ uint32_t RsGxsIdSerialiser::sizeGxsIdGroupItem(RsGxsIdGroupItem *item) const RsGxsIdGroup& group = item->group; uint32_t s = 8; // header - s += 4; // mIdType. - s += GetTlvStringSize(group.mGpgIdHash); + s += GetTlvStringSize(group.mPgpIdHash); + s += GetTlvStringSize(group.mPgpIdSign); return s; } @@ -185,8 +179,8 @@ bool RsGxsIdSerialiser::serialiseGxsIdGroupItem(RsGxsIdGroupItem *item, void *da offset += 8; /* GxsIdGroupItem */ - ok &= setRawUInt32(data, tlvsize, &offset, item->group.mIdType); - ok &= SetTlvString(data, tlvsize, &offset, 1, item->group.mGpgIdHash); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->group.mPgpIdHash); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->group.mPgpIdSign); if(offset != tlvsize) { @@ -246,8 +240,8 @@ RsGxsIdGroupItem* RsGxsIdSerialiser::deserialiseGxsIdGroupItem(void *data, uint3 /* skip the header */ offset += 8; - ok &= getRawUInt32(data, rssize, &offset, &(item->group.mIdType)); - ok &= GetTlvString(data, rssize, &offset, 1, item->group.mGpgIdHash); + ok &= GetTlvString(data, rssize, &offset, 1, item->group.mPgpIdHash); + ok &= GetTlvString(data, rssize, &offset, 1, item->group.mPgpIdSign); if (offset != rssize) { diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 4d839b2c1..a7fa605f6 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -27,6 +27,10 @@ #include "serialiser/rsgxsiditems.h" #include "util/rsrandom.h" +#include "util/rsstring.h" + +#include "pqi/authgpg.h" + #include #include @@ -44,6 +48,24 @@ RsIdentity *rsIdentity = NULL; +/****** + * Some notes: + * Identity tasks: + * - Provide keys for signing / validating author signatures. + * - Reputations + * - Identify Known Friend's IDs. + * - Provide details to other services (nicknames, reputations, gpg ids, etc) + * + * Background services: + * - Lookup and cache keys / details of identities. + * - Check GPGHashes. + * - Calculate Reputations. + * + * We have a lot of information to store in Service Strings. + * - GPGId or last check ts. + * - Reputation stuff. + */ + #define RSGXSID_MAX_SERVICE_STRING 1024 /********************************************************************************/ @@ -272,6 +294,176 @@ bool p3IdService::createMsg(uint32_t& token, RsGxsIdOpinion &opinion) /************************************************************************************/ /************************************************************************************/ +/* Encoding / Decoding Group Service String stuff + * + * Pgp stuff. + * + * If flagged as pgp id.... + * then we need to know if its been matched, or when we last tried to match. + * + */ + +bool SSGxsIdPgp::load(const std::string &input) +{ + char pgpline[RSGXSID_MAX_SERVICE_STRING]; + int timestamp = 0; + if (1 == sscanf(input.c_str(), "K:1 I:%[^)]", pgpline)) + { + idKnown = true; + pgpId = pgpline; + } + else if (1 == sscanf(input.c_str(), "K:0 T:%d", ×tamp)) + { + lastCheckTs = timestamp; + idKnown = false; + } + else + { + return false; + } + return true; +} + +std::string SSGxsIdPgp::save() const +{ + std::string output; + if (idKnown) + { + output += "K:1 I:"; + output += pgpId; + } + else + { + rs_sprintf(output, "K:0 T:%d", lastCheckTs); + } + return output; +} + +bool SSGxsIdScore::load(const std::string &input) +{ + return (1 == sscanf(input.c_str(), "%d", &score)); +} + +std::string SSGxsIdScore::save() const +{ + std::string output; + rs_sprintf(output, "%d", score); + return output; +} + +bool SSGxsIdCumulator::load(const std::string &input) +{ + return (4 == sscanf(input.c_str(), "%d %d %lf %lf", &count, &nullcount, &sum, &sumsq)); +} + +std::string SSGxsIdCumulator::save() const +{ + std::string output; + rs_sprintf(output, "%d %d %lf %lf", count, nullcount, sum, sumsq); + return output; +} + +bool SSGxsIdGroup::load(const std::string &input) +{ + char pgpstr[RSGXSID_MAX_SERVICE_STRING]; + char scorestr[RSGXSID_MAX_SERVICE_STRING]; + char opinionstr[RSGXSID_MAX_SERVICE_STRING]; + char repstr[RSGXSID_MAX_SERVICE_STRING]; + + // split into two parts. + if (4 != sscanf(input.c_str(), "v1 {%[^}]} {%[^}]} {%[^}]} {%[^}]}", pgpstr, scorestr, opinionstr, repstr)) + { + std::cerr << "SSGxsIdGroup::load() Failed to extract 4 Parts"; + std::cerr << std::endl; + return false; + } + + bool ok = true; + if (0 == strncmp(pgpstr, "P:", 2)) + { + std::cerr << "SSGxsIdGroup::load() pgpstr: " << pgpstr; + std::cerr << std::endl; + ok &= pgp.load(pgpstr); + } + else + { + std::cerr << "SSGxsIdGroup::load() Invalid pgpstr: " << pgpstr; + std::cerr << std::endl; + ok = false; + } + + if (0 == strncmp(scorestr, "Y:", 2)) + { + std::cerr << "SSGxsIdGroup::load() scorestr: " << scorestr; + std::cerr << std::endl; + ok &= score.load(scorestr); + } + else + { + std::cerr << "SSGxsIdGroup::load() Invalid scorestr: " << scorestr; + std::cerr << std::endl; + ok = false; + } + + if (0 == strncmp(opinionstr, "O:", 2)) + { + std::cerr << "SSGxsIdGroup::load() opinionstr: " << opinionstr; + std::cerr << std::endl; + ok &= opinion.load(opinionstr); + } + else + { + std::cerr << "SSGxsIdGroup::load() Invalid opinionstr: " << opinionstr; + std::cerr << std::endl; + ok = false; + } + + if (0 == strncmp(repstr, "R:", 2)) + { + std::cerr << "SSGxsIdGroup::load() repstr: " << repstr; + std::cerr << std::endl; + ok &= reputation.load(repstr); + } + else + { + std::cerr << "SSGxsIdGroup::load() Invalid repstr: " << repstr; + std::cerr << std::endl; + ok = false; + } + + return ok; +} + +std::string SSGxsIdGroup::save() const +{ + std::string output = "v1 "; + + output += "{P:"; + output += pgp.save(); + output += "}"; + + output += "{Y:"; + output += score.save(); + output += "}"; + + output += "{O:"; + output += opinion.save(); + output += "}"; + + output += "{R:"; + output += reputation.save(); + output += "}"; + + std::cerr << "SSGxsIdGroup::save() output: " << output; + std::cerr << std::endl; + + return output; +} + +/************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ + /* Cache of recently used keys * * It is expensive to fetch the keys, so we want to keep them around if possible. @@ -727,6 +919,403 @@ bool p3IdService::cachetest_request() return true; } +/************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ + +/* Task to determine GPGHash matches + * + * Info to be stored in GroupServiceString + Cache. + * + * Actually - it must be a Signature here - otherwise, you could + * put in a hash from someone else! + * + * Don't think that we need to match very often - maybe once a day? + * Actually - we should scale the matching based on number of keys we have. + * + * imagine - 10^6 rsa keys + 10^3 gpg keys => 10^9 combinations. + * -- far too many to check all quickly. + * + * Need to grab and cache data we need... then check over slowly. + * + * maybe grab a list of all gpgids - that we know of: store id list. + * then big GroupRequest, and iterate through these. + **/ + +//const int SHA_DIGEST_LENGTH = 20; + +typedef t_RsGenericIdType GxsIdPgpHash; + +static void calcPGPHash(const RsGxsId &id, const PGPFingerprintType &pgp, GxsIdPgpHash &hash); + + +void p3IdService::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet) +{ + RsGxsIdGroupItem *item = dynamic_cast(grpItem); + if (!item) + { + std::cerr << "p3IdService::service_CreateGroup() ERROR invalid cast"; + std::cerr << std::endl; + return; + } + + std::cerr << "p3IdService::service_CreateGroup() for : " << item->group.mMeta.mGroupId; + std::cerr << std::endl; + + if (item->group.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID) + { + /* create the hash */ + GxsIdPgpHash hash; + + /* */ + PGPFingerprintType ownFinger; + PGPIdType ownId(AuthGPG::getAuthGPG()->getGPGOwnId()); + + if (!AuthGPG::getAuthGPG()->getKeyFingerprint(ownId,ownFinger)) + { + std::cerr << "p3IdService::service_CreateGroup() ERROR Own Finger is stuck"; + std::cerr << std::endl; + return; // abandon attempt! + } + + calcPGPHash(item->group.mMeta.mGroupId, ownFinger, hash); + item->group.mPgpIdHash = hash.toStdString(); + + /* do signature */ + +#define MAX_SIGN_SIZE 2048 + uint8_t signarray[MAX_SIGN_SIZE]; + unsigned int sign_size = MAX_SIGN_SIZE; + if (!AuthGPG::getAuthGPG()->SignDataBin((void *) hash.toByteArray(), hash.SIZE_IN_BYTES, signarray, &sign_size)) + { + /* error */ + std::cerr << "p3IdService::service_CreateGroup() ERROR Signing stuff"; + std::cerr << std::endl; + } + else + { + /* push binary into string -> really bad! */ + item->group.mPgpIdSign = ""; + for(unsigned int i = 0; i < sign_size; i++) + { + item->group.mPgpIdSign += signarray[i]; + } + } + /* done! */ + } +} + + + + +bool p3IdService::pgphash_tick() +{ + /* every minute - run a background check */ + time_t now = time(NULL); + bool doHash = false; + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + if (now - mHashPgp_LastTs > TEST_PERIOD) + { + doHash = true; + mHashPgp_LastTs = now; + } + } + + if (doHash) + { + std::cerr << "p3IdService::pgphash_tick() starting"; + std::cerr << std::endl; + pgphash_getlist(); + } + + pgphash_request(); + pgphash_process(); + + return true; +} + +bool p3IdService::pgphash_getlist() +{ + + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + if (mHashPgp_Active) + { + std::cerr << "p3IdService::cachetest_getlist() Already active"; + std::cerr << std::endl; + return false; + } + } + + std::cerr << "p3IdService::cachetest_getlist() making request"; + std::cerr << std::endl; + + uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; + uint32_t token = 0; + + RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts); + + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + mHashPgp_Token = token; + mHashPgp_Active = true; + } + return true; +} + + +bool p3IdService::pgphash_request() +{ + uint32_t token = 0; + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + if (!mHashPgp_Active) + { + return false; + } + token = mHashPgp_Token; + } + + std::cerr << "p3IdService::pgphash_request() checking request"; + std::cerr << std::endl; + + uint32_t status = RsGenExchange::getTokenService()->requestStatus(token); + + if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + { + std::cerr << "p3IdService::pgphash_request() token ready: " << token; + std::cerr << std::endl; + + // We need full data - for access to Hash & Signature. + // Perhaps we will change this to an initial pass through Meta, + // and use this to discard lots of things. + + // Even better - we can set flags in the Meta Data, (IdType), + // And use GXS to filter out all the AnonIds, and only have to process + // Proper Ids. + + // We Will do this later! + + std::vector groups; + std::vector groupsToProcess; + bool ok = getGroupData(token, groups); + + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + mHashPgp_Active = false; + } + + if(ok) + { + std::vector::iterator vit; + for(vit = groups.begin(); vit != groups.end(); vit++) + { + /* Filter based on IdType */ + if (!(vit->mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)) + { + std::cerr << "p3IdService::pgphash_request() discarding AnonID"; + std::cerr << std::endl; + continue; + } + + /* now we need to decode the Service String - see what is saved there */ + SSGxsIdGroup ssdata; + if (ssdata.load(vit->mMeta.mServiceString)) + { + if (ssdata.pgp.idKnown) + { + std::cerr << "p3IdService::pgphash_request() discarding Already Known"; + std::cerr << std::endl; + continue; + } + + /* Have a linear attempt policy - + * if zero checks - try now. + * if 1 check, at least a day. + * if 2 checks: 2days, etc. + */ + +#define SECS_PER_DAY (3600 * 24) + time_t age = time(NULL) - ssdata.pgp.lastCheckTs; + time_t wait_period = ssdata.pgp.checkAttempts * SECS_PER_DAY; + if (wait_period > 30 * SECS_PER_DAY) + { + wait_period = 30 * SECS_PER_DAY; + } + + if (age < wait_period) + { + std::cerr << "p3IdService::pgphash_request() discarding Recently Check"; + std::cerr << std::endl; + continue; + } + } + + /* if we get here -> then its to be processed */ + std::cerr << "p3IdService::cachetest_request() Requested Key Id: " << *vit; + std::cerr << std::endl; + + mGroupsToProcess.push_back(*vit); + } + } + } + return true; +} + +bool p3IdService::pgphash_process() +{ + /* each time this is called - process one Id from mGroupsToProcess */ + if (mGroupsToProcess.empty()) + { + return true; + } + + RsGxsIdGroup pg = mGroupsToProcess.front(); + mGroupsToProcess.pop_front(); + + SSGxsIdGroup ssdata; + ssdata.load(pg.mMeta.mServiceString); // attempt load - okay if fails. + + PGPIdType pgpId; + + if (checkId(pg, pgpId)) + { + /* found a match - update everything */ + /* Consistency issues here - what if Reputation was recently updated? */ + + + /* update */ + ssdata.pgp.idKnown = true; + ssdata.pgp.pgpId = pgpId.toStdString(); + +// SHOULD BE PUSHED TO CACHE! +#if 0 + id.mGpgIdKnown = true; + + id.mGpgId = *it; + id.mGpgName = details.name; + id.mGpgEmail = details.email; + + if (*it == ownId) + { + id.mIdType |= RSID_RELATION_YOURSELF; + } + else if (rsPeers->isGPGAccepted(*it)) + { + id.mIdType |= RSID_RELATION_FRIEND; + } + else + { + id.mIdType |= RSID_RELATION_OTHER; + } + +#endif + + } + else + { + ssdata.pgp.lastCheckTs = time(NULL); + ssdata.pgp.checkAttempts++; + } + + /* set new Group ServiceString */ + uint32_t dummyToken = 0; + std::string serviceString = ssdata.save(); + setGroupServiceString(dummyToken, pg.mMeta.mGroupId, serviceString); + + return true; + +} + + + +bool p3IdService::checkId(const RsGxsIdGroup &grp, PGPIdType &pgpId) +{ + std::cerr << "p3IdService::checkId() Starting Match Check for RsGxsId: "; + std::cerr << grp.mMeta.mGroupId; + std::cerr << std::endl; + + /* iterate through and check hash */ + GxsIdPgpHash ans(grp.mPgpIdHash); + + std::map::iterator mit; + for(mit = mPgpFingerprintMap.begin(); mit != mPgpFingerprintMap.end(); mit++) + { + GxsIdPgpHash hash; + calcPGPHash(grp.mMeta.mGroupId, mit->second, hash); + if (ans == hash) + { + std::cerr << "p3IdService::checkId() HASH MATCH!"; + std::cerr << std::endl; + + /* miracle match! */ + /* check signature too */ + if (AuthGPG::getAuthGPG()->VerifySignBin((void *) hash.toByteArray(), hash.SIZE_IN_BYTES, + (unsigned char *) grp.mPgpIdSign.c_str(), grp.mPgpIdSign.length(), + mit->second.toStdString())) + { + std::cerr << "p3IdService::checkId() Signature Okay too!"; + std::cerr << std::endl; + + pgpId = mit->first; + return true; + } + + /* error */ + std::cerr << "p3IdService::checkId() ERROR Signature Failed"; + std::cerr << std::endl; + } + } + + std::cerr << "p3IdService::checkId() Checked " << mPgpFingerprintMap.size() << " Hashes without Match"; + std::cerr << std::endl; + + return false; +} + + +/* worker functions */ +void p3IdService::getPgpIdList() +{ + std::cerr << "p3IdService::getPgpIdList() Starting...."; + std::cerr << std::endl; + + std::list list; + AuthGPG::getAuthGPG()->getGPGFilteredList(list); + + std::list::iterator it; + for(it = list.begin(); it != list.end(); it++) + { + PGPIdType pgpId(*it); + PGPFingerprintType fp; + AuthGPG::getAuthGPG()->getKeyFingerprint(pgpId, fp); + + mPgpFingerprintMap[pgpId] = fp; + } + + std::cerr << "p3IdService::getPgpIdList() Items: " << mPgpFingerprintMap.size(); + std::cerr << std::endl; +} + + +void calcPGPHash(const RsGxsId &id, const PGPFingerprintType &pgp, GxsIdPgpHash &hash) +{ + unsigned char signature[SHA_DIGEST_LENGTH]; + /* hash id + pubkey => pgphash */ + SHA_CTX *sha_ctx = new SHA_CTX; + SHA1_Init(sha_ctx); + + SHA1_Update(sha_ctx, id.c_str(), id.length()); // TO FIX ONE DAY. + SHA1_Update(sha_ctx, pgp.toByteArray(), pgp.SIZE_IN_BYTES); + SHA1_Final(signature, sha_ctx); + hash = GxsIdPgpHash(signature); + + delete sha_ctx; +} + /************************************************************************************/ /************************************************************************************/ @@ -773,8 +1362,9 @@ void p3IdService::generateDummyData() //id.mKeyId = genRandomId(); id.mMeta.mGroupId = genRandomId(); - id.mIdType = RSID_TYPE_REALID; - id.mGpgIdHash = genRandomId(); + id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID; + id.mPgpIdHash = genRandomId(); + id.mPgpIdSign = genRandomId(); if (rsPeers->getPeerDetails(*it, details)) { @@ -783,36 +1373,16 @@ void p3IdService::generateDummyData() //id.mNickname = out.str(); id.mMeta.mGroupName = out.str(); - - id.mGpgIdKnown = true; - id.mGpgId = *it; - id.mGpgName = details.name; - id.mGpgEmail = details.email; - - if (*it == ownId) - { - id.mIdType |= RSID_RELATION_YOURSELF; - } - else if (rsPeers->isGPGAccepted(*it)) - { - id.mIdType |= RSID_RELATION_FRIEND; - } - else - { - id.mIdType |= RSID_RELATION_OTHER; - } - + } else { std::cerr << "p3IdService::generateDummyData() missing" << std::endl; std::cerr << std::endl; - id.mIdType |= RSID_RELATION_OTHER; //id.mNickname = genRandomId(); id.mMeta.mGroupName = genRandomId(); - id.mGpgIdKnown = false; } uint32_t dummyToken = 0; @@ -841,22 +1411,13 @@ void p3IdService::generateDummyData() RsPeerDetails details; - //id.mKeyId = genRandomId(); - id.mMeta.mGroupId = genRandomId(); - id.mIdType = RSID_TYPE_REALID; - id.mGpgIdHash = genRandomId(); - - id.mIdType |= RSID_RELATION_OTHER; - //id.mNickname = genRandomId(); id.mMeta.mGroupName = genRandomId(); - id.mGpgIdKnown = false; - id.mGpgId = ""; - id.mGpgName = ""; - id.mGpgEmail = ""; - //mIds[id.mKeyId] = id; - //mIdProxy->addGroup(id); - // STORE + id.mMeta.mGroupId = genRandomId(); + id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID; + id.mPgpIdHash = genRandomId(); + id.mPgpIdSign = genRandomId(); + uint32_t dummyToken = 0; createGroup(dummyToken, id); } @@ -868,21 +1429,14 @@ void p3IdService::generateDummyData() RsPeerDetails details; - //id.mKeyId = genRandomId(); - id.mMeta.mGroupId = genRandomId(); - id.mIdType = RSID_TYPE_PSEUDONYM; - id.mGpgIdHash = ""; - - //id.mNickname = genRandomId(); id.mMeta.mGroupName = genRandomId(); - id.mGpgIdKnown = false; - id.mGpgId = ""; - id.mGpgName = ""; - id.mGpgEmail = ""; - //mIds[id.mKeyId] = id; - //mIdProxy->addGroup(id); - // STORE + id.mMeta.mGroupId = genRandomId(); + id.mMeta.mGroupFlags = 0; + id.mPgpIdHash = ""; + id.mPgpIdSign = ""; + + uint32_t dummyToken = 0; createGroup(dummyToken, id); } @@ -1291,10 +1845,8 @@ bool p3IdService::background_processNewMessages() mit->second.mGroupStatus |= ID_LOCAL_STATUS_INC_CALC_FLAG; - std::string serviceString; - IdGroupServiceStrData ssData; - - if (!extractIdGroupCache(serviceString, ssData)) + SSGxsIdGroup ssdata; + if (!ssdata.load(mit->second.mServiceString)) { /* error */ std::cerr << "p3IdService::background_processNewMessages() ERROR Extracting"; @@ -1308,8 +1860,9 @@ bool p3IdService::background_processNewMessages() /* store it back in */ std::cerr << "p3IdService::background_processNewMessages() Stored: "; std::cerr << std::endl; - - if (!encodeIdGroupCache(serviceString, ssData)) + + std::string serviceString = ssdata.save(); + if (0) { /* error */ std::cerr << "p3IdService::background_processNewMessages() ERROR Storing"; @@ -1365,75 +1918,6 @@ bool p3IdService::background_processNewMessages() } -bool p3IdService::encodeIdGroupCache(std::string &str, const IdGroupServiceStrData &data) -{ - char line[RSGXSID_MAX_SERVICE_STRING]; - - snprintf(line, RSGXSID_MAX_SERVICE_STRING, "v1 {%s} {Y:%d O:%d %d %f %f R:%d %d %f %f}", - data.pgpId.c_str(), data.ownScore, - data.opinion.count, data.opinion.nullcount, data.opinion.sum, data.opinion.sumsq, - data.reputation.count, data.reputation.nullcount, data.reputation.sum, data.reputation.sumsq); - - str = line; - return true; -} - - -bool p3IdService::extractIdGroupCache(std::string &str, IdGroupServiceStrData &data) -{ - char pgpline[RSGXSID_MAX_SERVICE_STRING]; - char scoreline[RSGXSID_MAX_SERVICE_STRING]; - - uint32_t iOwnScore; - IdRepCumulScore iOpin; - IdRepCumulScore iRep; - - // split into two parts. - if (2 != sscanf(str.c_str(), "v1 {%[^}]} {%[^}]", pgpline, scoreline)) - { - std::cerr << "p3IdService::extractIdGroupCache() Failed to extract Two Parts"; - std::cerr << std::endl; - return false; - } - - std::cerr << "p3IdService::extractIdGroupCache() pgpline: " << pgpline; - std::cerr << std::endl; - std::cerr << "p3IdService::extractIdGroupCache() scoreline: " << scoreline; - std::cerr << std::endl; - - std::string pgptmp = pgpline; - if (pgptmp.length() > 5) - { - std::cerr << "p3IdService::extractIdGroupCache() Believe to have pgpId: " << pgptmp; - std::cerr << std::endl; - data.pgpIdKnown = true; - data.pgpId = pgptmp; - } - else - { - std::cerr << "p3IdService::extractIdGroupCache() Think pgpId Invalid"; - std::cerr << std::endl; - data.pgpIdKnown = false; - } - - - if (9 == sscanf(scoreline, " Y:%d O:%d %d %lf %lf R:%d %d %lf %lf", &iOwnScore, - &(iOpin.count), &(iOpin.nullcount), &(iOpin.sum), &(iOpin.sumsq), - &(iRep.count), &(iRep.nullcount), &(iRep.sum), &(iRep.sumsq))) - { - data.ownScore = iOwnScore; - data.opinion = iOpin; - data.reputation = iRep; - return true; - } - - std::cerr << "p3IdService::extractIdGroupCache() Failed to extract scores"; - std::cerr << std::endl; - - return false; -} - - bool p3IdService::background_FullCalcRequest() { @@ -1583,23 +2067,14 @@ bool p3IdService::background_processFullCalc() if (validmsgs) { - std::string serviceString; - IdGroupServiceStrData ssData; - - - if (!encodeIdGroupCache(serviceString, ssData)) - { - std::cerr << "p3IdService::background_updateVoteCounts() Failed to encode Votes"; - std::cerr << std::endl; - } - else - { - std::cerr << "p3IdService::background_updateVoteCounts() Encoded String: " << serviceString; - std::cerr << std::endl; - /* store new result */ - uint32_t dummyToken = 0; - setGroupServiceString(dummyToken, groupId, serviceString); - } + SSGxsIdGroup ssdata; + std::string serviceString = ssdata.save(); + + std::cerr << "p3IdService::background_updateVoteCounts() Encoded String: " << serviceString; + std::cerr << std::endl; + /* store new result */ + uint32_t dummyToken = 0; + setGroupServiceString(dummyToken, groupId, serviceString); } { @@ -1633,9 +2108,8 @@ bool p3IdService::background_cleanup() std::ostream &operator<<(std::ostream &out, const RsGxsIdGroup &grp) { out << "RsGxsIdGroup: Meta: " << grp.mMeta; - out << " IdType: " << grp.mIdType << " GpgIdHash: " << grp.mGpgIdHash; - out << "(((Unusable: ( GpgIdKnown: " << grp.mGpgIdKnown << " GpgId: " << grp.mGpgId; - out << " GpgName: " << grp.mGpgName << " GpgEmail: " << grp.mGpgEmail << ") )))"; + out << " PgpIdHash: " << grp.mPgpIdHash; + out << " PgpIdSign: [binary]"; // << grp.mPgpIdSign; out << std::endl; return out; diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index 593cf3fbf..19ef8d315 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -36,6 +36,8 @@ #include "util/rsmemcache.h" +#include "pqi/authgpg.h" + /* * Identity Service * @@ -43,9 +45,52 @@ // INTERNAL DATA TYPES. // Describes data stored in GroupServiceString. -class IdRepCumulScore + +class SSBit +{ + public: +virtual bool load(const std::string &input) = 0; +virtual std::string save() const = 0; +}; + + + +class SSGxsIdPgp: public SSBit +{ + public: + SSGxsIdPgp() + :idKnown(false), lastCheckTs(0), checkAttempts(0) { return; } + +virtual bool load(const std::string &input); +virtual std::string save() const; + + bool idKnown; + time_t lastCheckTs; + uint32_t checkAttempts; + std::string pgpId; +}; + +class SSGxsIdScore: public SSBit +{ + public: + SSGxsIdScore() + :score(0) { return; } + +virtual bool load(const std::string &input); +virtual std::string save() const; + + int score; +}; + +class SSGxsIdCumulator: public SSBit { public: + SSGxsIdCumulator() + :count(0), nullcount(0), sum(0), sumsq(0) { return; } + +virtual bool load(const std::string &input); +virtual std::string save() const; + uint32_t count; uint32_t nullcount; double sum; @@ -54,17 +99,21 @@ public: // derived parameters: }; - -class IdGroupServiceStrData +class SSGxsIdGroup: public SSBit { public: - IdGroupServiceStrData() { pgpIdKnown = false; } - bool pgpIdKnown; - std::string pgpId; - - uint32_t ownScore; - IdRepCumulScore opinion; - IdRepCumulScore reputation; + SSGxsIdGroup() { return; } + +virtual bool load(const std::string &input); +virtual std::string save() const; + + // pgphash status + SSGxsIdPgp pgp; + + // reputation score. + SSGxsIdScore score; + SSGxsIdCumulator opinion; + SSGxsIdCumulator reputation; }; @@ -72,7 +121,6 @@ public: #define ID_LOCAL_STATUS_INC_CALC_FLAG 0x00020000 - #define MAX_CACHE_SIZE 100 // Small for testing.. //#define MAX_CACHE_SIZE 10000 // More useful size @@ -104,9 +152,7 @@ class LruData // Not sure exactly what should be inherited here? // Chris - please correct as necessary. -class p3IdService: - public RsGxsIdExchange, - public RsIdentity +class p3IdService: public RsGxsIdExchange, public RsIdentity { public: p3IdService(RsGeneralDataService* gds, RsNetworkExchangeService* nes); @@ -164,8 +210,11 @@ virtual bool getReputation(const RsGxsId &id, const GixsReputation &rep); protected: - /** Notifications **/ - virtual void notifyChanges(std::vector& changes); + /** Notifications **/ +virtual void notifyChanges(std::vector& changes); + + /** Overloaded to add PgpIdHash to Group Definition **/ +virtual void service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet); private: @@ -175,14 +224,6 @@ virtual bool getReputation(const RsGxsId &id, const GixsReputation &rep); */ int cache_tick(); - - //bool cache_is_loaded(const RsGxsId &id); - //bool cache_fetch(const RsGxsId &key, RsGxsIdCache &data); - - //bool cache_store(const RsGxsIdGroup &group); - //bool cache_resize(); - //bool cache_discard_LRU(int count_to_clear); - bool cache_request_load(const RsGxsId &id); bool cache_start_load(); bool cache_check_loading(); @@ -190,12 +231,6 @@ virtual bool getReputation(const RsGxsId &id, const GixsReputation &rep); bool cache_store(const RsGxsIdGroupItem *item); - /* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */ - //bool locked_cache_update_lrumap(const RsGxsId &key, time_t old_ts, time_t new_ts); - //std::map mCacheDataMap; - //std::multimap mCacheLruMap; - //uint32_t mCacheDataCount; - time_t mCacheLoad_LastCycle; int mCacheLoad_Status; std::list mCacheLoad_ToCache; @@ -220,6 +255,26 @@ virtual bool getReputation(const RsGxsId &id, const GixsReputation &rep); bool mCacheTest_Active; uint32_t mCacheTest_Token; +/************************************************************************ + * pgphash processing. + * + */ + bool pgphash_tick(); + bool pgphash_getlist(); + bool pgphash_request(); + bool pgphash_process(); + + bool checkId(const RsGxsIdGroup &grp, PGPIdType &pgp_id); + void getPgpIdList(); + /* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */ + + time_t mHashPgp_LastTs; + bool mHashPgp_Active; + uint32_t mHashPgp_Token; + + std::map mPgpFingerprintMap; + std::list mGroupsToProcess; + /************************************************************************ * Below is the background task for processing opinions => reputations * @@ -239,9 +294,6 @@ std::string genRandomId(); bool background_cleanup(); - bool encodeIdGroupCache(std::string &str, const IdGroupServiceStrData &data); - bool extractIdGroupCache(std::string &str, IdGroupServiceStrData &data); - RsMutex mIdMtx; /***** below here is locked *****/ diff --git a/libretroshare/src/util/rsid.h b/libretroshare/src/util/rsid.h index 464999a5d..bd1343fcb 100644 --- a/libretroshare/src/util/rsid.h +++ b/libretroshare/src/util/rsid.h @@ -25,6 +25,9 @@ // Warning: never store references to a t_RsGenericIdType accross threads, since the // cached string convertion is not thread safe. // + +#pragma once + #include #include @@ -60,6 +63,14 @@ template class t_RsGenericIdType return !operator==(fp) ; } + bool operator<(const t_RsGenericIdType& fp) const + { + for(uint32_t i=0;i Date: Mon, 5 Nov 2012 22:32:52 +0000 Subject: [PATCH 132/222] Disabled stuff - so it will compile. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5778 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/Identity/IdDialog.cpp | 16 +++++---- .../src/gui/Identity/IdEditDialog.cpp | 35 ++++++++++--------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 696acae20..2a1d78fce 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -171,11 +171,12 @@ void IdDialog::insertIdDetails(uint32_t token) ui.lineEdit_Nickname->setText(QString::fromStdString(data.mMeta.mGroupName)); //ui.lineEdit_KeyId->setText(QString::fromStdString(data.mKeyId)); ui.lineEdit_KeyId->setText(QString::fromStdString(data.mMeta.mGroupId)); - ui.lineEdit_GpgHash->setText(QString::fromStdString(data.mGpgIdHash)); - ui.lineEdit_GpgId->setText(QString::fromStdString(data.mGpgId)); - ui.lineEdit_GpgName->setText(QString::fromStdString(data.mGpgName)); - ui.lineEdit_GpgEmail->setText(QString::fromStdString(data.mGpgEmail)); - + ui.lineEdit_GpgHash->setText(QString::fromStdString(data.mPgpIdHash)); + //ui.lineEdit_GpgId->setText(QString::fromStdString(data.mGpgId)); + //ui.lineEdit_GpgName->setText(QString::fromStdString(data.mGpgName)); + //ui.lineEdit_GpgEmail->setText(QString::fromStdString(data.mGpgEmail)); + +#if 0 if (data.mIdType & RSID_RELATION_YOURSELF) { ui.radioButton_IdYourself->setChecked(true); @@ -210,6 +211,7 @@ void IdDialog::insertIdDetails(uint32_t token) ui.pushButton_Delete->setEnabled(false); ui.pushButton_EditId->setEnabled(false); } +#endif } void IdDialog::checkUpdate() @@ -315,6 +317,7 @@ void IdDialog::insertIdList(uint32_t token) { ok = true; } +#if 0 else if (data.mIdType & RSID_TYPE_PSEUDONYM) { if (acceptPseudo) @@ -351,6 +354,7 @@ void IdDialog::insertIdList(uint32_t token) } } } +#endif if (!ok) { @@ -363,7 +367,7 @@ void IdDialog::insertIdList(uint32_t token) //item->setText(RSID_COL_KEYID, QString::fromStdString(data.mKeyId)); item->setText(RSID_COL_NICKNAME, QString::fromStdString(data.mMeta.mGroupName)); item->setText(RSID_COL_KEYID, QString::fromStdString(data.mMeta.mGroupId)); - item->setText(RSID_COL_IDTYPE, QString::fromStdString(rsIdTypeToString(data.mIdType))); + //item->setText(RSID_COL_IDTYPE, QString::fromStdString(rsIdTypeToString(data.mIdType))); tree->addTopLevelItem(item); } diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp index 17abb84d7..8f3bfd407 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp @@ -146,7 +146,8 @@ void IdEditDialog::loadExistingId(uint32_t token) data = datavector[0]; - bool pseudo = (data.mIdType & RSID_TYPE_PSEUDONYM); + + bool pseudo = false; //(data.mIdType & RSID_TYPE_PSEUDONYM); if (pseudo) { @@ -175,13 +176,13 @@ void IdEditDialog::loadExistingId(uint32_t token) } else { - ui.lineEdit_GpgHash->setText(QString::fromStdString(data.mGpgIdHash)); + ui.lineEdit_GpgHash->setText(QString::fromStdString(data.mPgpIdHash)); - if (data.mGpgIdKnown) + if (0) //if (data.mGpgIdKnown) { - ui.lineEdit_GpgId->setText(QString::fromStdString(data.mGpgId)); - ui.lineEdit_GpgName->setText(QString::fromStdString(data.mGpgName)); - ui.lineEdit_GpgEmail->setText(QString::fromStdString(data.mGpgEmail)); + //ui.lineEdit_GpgId->setText(QString::fromStdString(data.mGpgId)); + //ui.lineEdit_GpgName->setText(QString::fromStdString(data.mGpgName)); + //ui.lineEdit_GpgEmail->setText(QString::fromStdString(data.mGpgEmail)); } else { @@ -208,7 +209,7 @@ void IdEditDialog::updateId() return; } - rid.mIdType = RSID_RELATION_YOURSELF; + //rid.mIdType = RSID_RELATION_YOURSELF; if (ui.checkBox_NewId->isChecked()) { rid.mMeta.mGroupId = ""; @@ -220,21 +221,21 @@ void IdEditDialog::updateId() if (ui.radioButton_GpgId->isChecked()) { - rid.mIdType |= RSID_TYPE_REALID; + //rid.mIdType |= RSID_TYPE_REALID; - rid.mGpgId = ui.lineEdit_GpgId->text().toStdString(); - rid.mGpgIdHash = ui.lineEdit_GpgHash->text().toStdString(); - rid.mGpgName = ui.lineEdit_GpgName->text().toStdString(); - rid.mGpgEmail = ui.lineEdit_GpgEmail->text().toStdString(); + //rid.mGpgId = ui.lineEdit_GpgId->text().toStdString(); + rid.mPgpIdHash = ui.lineEdit_GpgHash->text().toStdString(); + //rid.mGpgName = ui.lineEdit_GpgName->text().toStdString(); + //rid.mGpgEmail = ui.lineEdit_GpgEmail->text().toStdString(); } else { - rid.mIdType |= RSID_TYPE_PSEUDONYM; + //rid.mIdType |= RSID_TYPE_PSEUDONYM; - rid.mGpgId = ""; - rid.mGpgIdHash = ""; - rid.mGpgName = ""; - rid.mGpgEmail = ""; + //rid.mGpgId = ""; + rid.mPgpIdHash = ""; + //rid.mGpgName = ""; + //rid.mGpgEmail = ""; } // TODO. From c09cab443930677a487faa741e93336259000a79 Mon Sep 17 00:00:00 2001 From: drbob Date: Tue, 6 Nov 2012 19:18:11 +0000 Subject: [PATCH 133/222] * Added back idKnown, and pgpHash to rsIdentity Group type. (needed in GUI) * added in scheduling_tick() for coordinating background and pgphash ticks. * disabled Signatures until thread-safe version is present. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5782 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/retroshare/rsidentity.h | 5 + libretroshare/src/serialiser/rsgxsiditems.cc | 4 + libretroshare/src/services/p3idservice.cc | 143 +++++++++++++++++-- libretroshare/src/services/p3idservice.h | 19 ++- 4 files changed, 158 insertions(+), 13 deletions(-) diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index 50dce4257..eabf977fd 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -60,6 +60,7 @@ std::string rsIdTypeToString(uint32_t idtype); class RsGxsIdGroup { public: + RsGxsIdGroup():mPgpKnown(false) { return; } RsGroupMetaData mMeta; @@ -80,6 +81,10 @@ class RsGxsIdGroup std::string mPgpIdHash; std::string mPgpIdSign; // Need a signature as proof - otherwise anyone could add others Hashes. + + // Serialised - for GUI's benefit. + bool mPgpKnown; + std::string mPgpId; }; diff --git a/libretroshare/src/serialiser/rsgxsiditems.cc b/libretroshare/src/serialiser/rsgxsiditems.cc index cc788053f..565569e7c 100644 --- a/libretroshare/src/serialiser/rsgxsiditems.cc +++ b/libretroshare/src/serialiser/rsgxsiditems.cc @@ -122,6 +122,10 @@ void RsGxsIdGroupItem::clear() { group.mPgpIdHash.clear(); group.mPgpIdSign.clear(); + + group.mPgpKnown = false; + group.mPgpId.clear(); + } std::ostream& RsGxsIdGroupItem::print(std::ostream& out, uint16_t indent) diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index a7fa605f6..c092da41d 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -68,6 +68,9 @@ RsIdentity *rsIdentity = NULL; #define RSGXSID_MAX_SERVICE_STRING 1024 +#define BG_PGPHASH 1 +#define BG_REPUTATION 2 + /********************************************************************************/ /******************* Startup / Tick ******************************************/ /********************************************************************************/ @@ -81,6 +84,11 @@ p3IdService::p3IdService(RsGeneralDataService *gds, RsNetworkExchangeService *ne mCacheLoad_LastCycle = 0; mCacheLoad_Status = 0; + + mHashPgp_SearchActive = false; + + mBgSchedule_Mode = 0; + mBgSchedule_Active = false; } void p3IdService::service_tick() @@ -96,6 +104,9 @@ void p3IdService::service_tick() // internal testing - request keys. (NOT FINISHED YET) cachetest_tick(); + // background stuff. + //scheduling_tick(); + return; } @@ -223,6 +234,20 @@ bool p3IdService::getGroupData(const uint32_t &token, std::vector RsGxsIdGroupItem* item = dynamic_cast(*vit); RsGxsIdGroup group = item->group; group.mMeta = item->meta; + + // Decode information from serviceString. + SSGxsIdGroup ssdata; + if (ssdata.load(group.mMeta.mServiceString)) + { + group.mPgpKnown = ssdata.pgp.idKnown; + group.mPgpId = ssdata.pgp.pgpId; + } + else + { + group.mPgpKnown = false; + group.mPgpId = ""; + } + groups.push_back(group); } } @@ -919,6 +944,65 @@ bool p3IdService::cachetest_request() return true; } +/************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ + +/* + * We have two background tasks that use the ServiceString: PGPHash & Reputation. + * + * Only one task can be run at a time - otherwise potential overwrite issues. + * So this part coordinates that part of the code. + * + * + * + * + */ + +#define ID_BACKGROUND_PERIOD 60 + +int p3IdService::scheduling_tick() +{ + std::cerr << "p3IdService::scheduling_tick()"; + std::cerr << std::endl; + + /*** MUTEX TODO ***/ + + if (mBgSchedule_Active) + { + bool done = false; + if (mBgSchedule_Mode == BG_PGPHASH) + { + done = pgphash_continue(); + } + else + { + done = reputation_continue(); + } + + if (done) + { + mBgSchedule_Active = false; + } + } + else + { + if (pgphash_start()) + { + mBgSchedule_Mode = BG_PGPHASH; + mBgSchedule_Active = true; + } + else if (reputation_start()) + { + mBgSchedule_Mode = BG_REPUTATION; + mBgSchedule_Active = true; + } + } + + return 1; +} + + /************************************************************************************/ /************************************************************************************/ /************************************************************************************/ @@ -983,6 +1067,7 @@ void p3IdService::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet /* do signature */ +#if ENABLE_PGP_SIGNATURES #define MAX_SIGN_SIZE 2048 uint8_t signarray[MAX_SIGN_SIZE]; unsigned int sign_size = MAX_SIGN_SIZE; @@ -1002,20 +1087,25 @@ void p3IdService::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet } } /* done! */ +#else + item->group.mPgpIdSign = ""; +#endif + } } +#define HASHPGP_PERIOD 180 -bool p3IdService::pgphash_tick() +bool p3IdService::pgphash_start() { /* every minute - run a background check */ time_t now = time(NULL); bool doHash = false; { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - if (now - mHashPgp_LastTs > TEST_PERIOD) + if (now - mHashPgp_LastTs > HASHPGP_PERIOD) { doHash = true; mHashPgp_LastTs = now; @@ -1027,20 +1117,33 @@ bool p3IdService::pgphash_tick() std::cerr << "p3IdService::pgphash_tick() starting"; std::cerr << std::endl; pgphash_getlist(); + return true; } - - pgphash_request(); - pgphash_process(); - - return true; + return false; } + +bool p3IdService::pgphash_continue() +{ + if (mHashPgp_SearchActive) + { + pgphash_request(); + } + else + { + return pgphash_process(); + } + return false; +} + + + bool p3IdService::pgphash_getlist() { { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - if (mHashPgp_Active) + if (mHashPgp_SearchActive) { std::cerr << "p3IdService::cachetest_getlist() Already active"; std::cerr << std::endl; @@ -1061,7 +1164,7 @@ bool p3IdService::pgphash_getlist() { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ mHashPgp_Token = token; - mHashPgp_Active = true; + mHashPgp_SearchActive = true; } return true; } @@ -1072,7 +1175,7 @@ bool p3IdService::pgphash_request() uint32_t token = 0; { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - if (!mHashPgp_Active) + if (!mHashPgp_SearchActive) { return false; } @@ -1105,7 +1208,7 @@ bool p3IdService::pgphash_request() { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mHashPgp_Active = false; + mHashPgp_SearchActive = false; } if(ok) @@ -1251,6 +1354,7 @@ bool p3IdService::checkId(const RsGxsIdGroup &grp, PGPIdType &pgpId) std::cerr << "p3IdService::checkId() HASH MATCH!"; std::cerr << std::endl; +#if ENABLE_PGP_SIGNATURES /* miracle match! */ /* check signature too */ if (AuthGPG::getAuthGPG()->VerifySignBin((void *) hash.toByteArray(), hash.SIZE_IN_BYTES, @@ -1267,6 +1371,12 @@ bool p3IdService::checkId(const RsGxsIdGroup &grp, PGPIdType &pgpId) /* error */ std::cerr << "p3IdService::checkId() ERROR Signature Failed"; std::cerr << std::endl; +#else + std::cerr << "p3IdService::checkId() Skipping Signature check for now... Hash Okay"; + std::cerr << std::endl; + return true; +#endif + } } @@ -1552,6 +1662,17 @@ std::string rsIdTypeToString(uint32_t idtype) * */ +bool p3IdService::reputation_start() +{ + return false; +} + + +bool p3IdService::reputation_continue() +{ + return true; +} + #define ID_BACKGROUND_PERIOD 60 diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index 19ef8d315..72e752740 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -255,11 +255,23 @@ virtual void service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& key bool mCacheTest_Active; uint32_t mCacheTest_Token; + +/************************************************************************ + * for processing background tasks that use the serviceString. + * - must be mutually exclusive to avoid clashes. + */ + int scheduling_tick(); + + bool mBgSchedule_Active; + uint32_t mBgSchedule_Mode; + /************************************************************************ * pgphash processing. * */ - bool pgphash_tick(); + bool pgphash_start(); + bool pgphash_continue(); + bool pgphash_getlist(); bool pgphash_request(); bool pgphash_process(); @@ -269,7 +281,7 @@ virtual void service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& key /* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */ time_t mHashPgp_LastTs; - bool mHashPgp_Active; + bool mHashPgp_SearchActive; uint32_t mHashPgp_Token; std::map mPgpFingerprintMap; @@ -284,6 +296,9 @@ virtual void generateDummyData(); std::string genRandomId(); + bool reputation_start(); + bool reputation_continue(); + int background_tick(); bool background_checkTokenRequest(); bool background_requestGroups(); From aebd08f106ce0f638fc01f1544b5a6e213180273 Mon Sep 17 00:00:00 2001 From: drbob Date: Tue, 6 Nov 2012 19:18:56 +0000 Subject: [PATCH 134/222] Fixed up the Id GUI to match new data types and use rsPeers for other info. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5783 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/Identity/IdDialog.cpp | 147 +++++++++++------- .../src/gui/Identity/IdEditDialog.cpp | 50 +++--- 2 files changed, 114 insertions(+), 83 deletions(-) diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 2a1d78fce..3270bc5d7 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -25,6 +25,7 @@ #include #include +#include "gxs/rsgxsflags.h" #include #include @@ -163,43 +164,67 @@ void IdDialog::insertIdDetails(uint32_t token) data = datavector[0]; /* get GPG Details from rsPeers */ - std::string gpgid = rsPeers->getGPGOwnId(); - RsPeerDetails details; - rsPeers->getPeerDetails(gpgid, details); + std::string ownPgpId = rsPeers->getGPGOwnId(); - //ui.lineEdit_Nickname->setText(QString::fromStdString(data.mNickname)); ui.lineEdit_Nickname->setText(QString::fromStdString(data.mMeta.mGroupName)); - //ui.lineEdit_KeyId->setText(QString::fromStdString(data.mKeyId)); ui.lineEdit_KeyId->setText(QString::fromStdString(data.mMeta.mGroupId)); ui.lineEdit_GpgHash->setText(QString::fromStdString(data.mPgpIdHash)); - //ui.lineEdit_GpgId->setText(QString::fromStdString(data.mGpgId)); - //ui.lineEdit_GpgName->setText(QString::fromStdString(data.mGpgName)); - //ui.lineEdit_GpgEmail->setText(QString::fromStdString(data.mGpgEmail)); + ui.lineEdit_GpgId->setText(QString::fromStdString(data.mPgpId)); -#if 0 - if (data.mIdType & RSID_RELATION_YOURSELF) + if (data.mPgpKnown) + { + RsPeerDetails details; + rsPeers->getGPGDetails(data.mPgpId, details); + ui.lineEdit_GpgName->setText(QString::fromStdString(details.name)); + ui.lineEdit_GpgEmail->setText(QString::fromStdString(details.email)); + } + else + { + if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID) + { + ui.lineEdit_GpgName->setText("Unknown Real Name"); + ui.lineEdit_GpgEmail->setText("Unknown Email"); + } + else + { + ui.lineEdit_GpgName->setText("Anonymous Id"); + ui.lineEdit_GpgEmail->setText("-- N/A --"); + } + } + + bool isOwnId = (data.mPgpKnown && (data.mPgpId == ownPgpId)) || + (data.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN); + + if (isOwnId) { ui.radioButton_IdYourself->setChecked(true); } - else if (data.mIdType & RSID_TYPE_PSEUDONYM) + else if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID) + { + if (data.mPgpKnown) + { + if (rsPeers->isGPGAccepted(data.mPgpId)) + { + ui.radioButton_IdFriend->setChecked(true); + } + else + { + ui.radioButton_IdFOF->setChecked(true); + } + } + else + { + ui.radioButton_IdOther->setChecked(true); + } + } + else { ui.radioButton_IdPseudo->setChecked(true); } - else if (data.mIdType & RSID_RELATION_FRIEND) - { - ui.radioButton_IdFriend->setChecked(true); - } - else if (data.mIdType & RSID_RELATION_FOF) - { - ui.radioButton_IdFOF->setChecked(true); - } - else - { - ui.radioButton_IdOther->setChecked(true); - } - + ui.pushButton_NewId->setEnabled(true); - if (data.mIdType & RSID_RELATION_YOURSELF) + + if (isOwnId) { ui.pushButton_Reputation->setEnabled(false); ui.pushButton_Delete->setEnabled(true); @@ -211,7 +236,6 @@ void IdDialog::insertIdDetails(uint32_t token) ui.pushButton_Delete->setEnabled(false); ui.pushButton_EditId->setEnabled(false); } -#endif } void IdDialog::checkUpdate() @@ -307,67 +331,74 @@ void IdDialog::insertIdList(uint32_t token) return; } + std::string ownPgpId = rsPeers->getGPGOwnId(); + for(vit = datavector.begin(); vit != datavector.end(); vit++) { data = (*vit); + bool isOwnId = (data.mPgpKnown && (data.mPgpId == ownPgpId)) || + (data.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN); + /* do filtering */ bool ok = false; if (acceptAll) { ok = true; } -#if 0 - else if (data.mIdType & RSID_TYPE_PSEUDONYM) + else if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID) + { + if (isOwnId && acceptYourself) + { + ok = true; + } + else + { + if (data.mPgpKnown) + { + if (acceptFriends) + { + ok = true; + } + } + else + { + if (acceptOthers) + { + ok = true; + } + } + } + } + else { if (acceptPseudo) { ok = true; } - if ((data.mIdType & RSID_RELATION_YOURSELF) && (acceptYourself)) + if (isOwnId && acceptYourself) { ok = true; } } - else - { - if (data.mIdType & RSID_RELATION_YOURSELF) - { - if (acceptYourself) - { - ok = true; - } - } - else if (data.mIdType & (RSID_RELATION_FRIEND | RSID_RELATION_FOF)) - { - if (acceptFriends) - { - ok = true; - } - } - else - { - if (acceptOthers) - { - ok = true; - } - } - } -#endif if (!ok) { continue; } - QTreeWidgetItem *item = new QTreeWidgetItem(); - //item->setText(RSID_COL_NICKNAME, QString::fromStdString(data.mNickname)); - //item->setText(RSID_COL_KEYID, QString::fromStdString(data.mKeyId)); item->setText(RSID_COL_NICKNAME, QString::fromStdString(data.mMeta.mGroupName)); item->setText(RSID_COL_KEYID, QString::fromStdString(data.mMeta.mGroupId)); - //item->setText(RSID_COL_IDTYPE, QString::fromStdString(rsIdTypeToString(data.mIdType))); + if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID) + { + item->setText(RSID_COL_IDTYPE, "PGP Linked Id"); + } + else + { + item->setText(RSID_COL_IDTYPE, "Anon Id"); + } tree->addTopLevelItem(item); } diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp index 8f3bfd407..5a7b9b69e 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp @@ -146,51 +146,51 @@ void IdEditDialog::loadExistingId(uint32_t token) data = datavector[0]; + bool realid = (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID); - bool pseudo = false; //(data.mIdType & RSID_TYPE_PSEUDONYM); - - if (pseudo) + if (realid) { - ui.radioButton_Pseudo->setChecked(true); + ui.radioButton_GpgId->setChecked(true); } else { - ui.radioButton_GpgId->setChecked(true); + ui.radioButton_Pseudo->setChecked(true); } // DOES THIS TRIGGER ALREADY??? // force - incase it wasn't triggered. IdTypeToggled(true); - //ui.lineEdit_Nickname->setText(QString::fromStdString(data.mNickname)); - //ui.lineEdit_KeyId->setText(QString::fromStdString(data.mKeyId)); ui.lineEdit_Nickname->setText(QString::fromStdString(data.mMeta.mGroupName)); ui.lineEdit_KeyId->setText(QString::fromStdString(data.mMeta.mGroupId)); - if (pseudo) + if (realid) + { + ui.lineEdit_GpgHash->setText(QString::fromStdString(data.mPgpIdHash)); + + if (data.mPgpKnown) + { + RsPeerDetails details; + rsPeers->getGPGDetails(data.mPgpId, details); + ui.lineEdit_GpgName->setText(QString::fromStdString(details.name)); + ui.lineEdit_GpgEmail->setText(QString::fromStdString(details.email)); + + ui.lineEdit_GpgId->setText(QString::fromStdString(data.mPgpId)); + } + else + { + ui.lineEdit_GpgId->setText("Unknown PgpId"); + ui.lineEdit_GpgName->setText("Unknown Real Name"); + ui.lineEdit_GpgEmail->setText("Unknown Email"); + } + } + else { ui.lineEdit_GpgHash->setText("N/A"); ui.lineEdit_GpgId->setText("N/A"); ui.lineEdit_GpgName->setText("N/A"); ui.lineEdit_GpgEmail->setText("N/A"); } - else - { - ui.lineEdit_GpgHash->setText(QString::fromStdString(data.mPgpIdHash)); - - if (0) //if (data.mGpgIdKnown) - { - //ui.lineEdit_GpgId->setText(QString::fromStdString(data.mGpgId)); - //ui.lineEdit_GpgName->setText(QString::fromStdString(data.mGpgName)); - //ui.lineEdit_GpgEmail->setText(QString::fromStdString(data.mGpgEmail)); - } - else - { - ui.lineEdit_GpgId->setText("EXIST Unknown"); - ui.lineEdit_GpgName->setText("Unknown"); - ui.lineEdit_GpgEmail->setText("Unknown"); - } - } return; } From 0327b47cccbd6f072d2d82dbd64c82307ce1c53c Mon Sep 17 00:00:00 2001 From: drbob Date: Wed, 7 Nov 2012 21:38:43 +0000 Subject: [PATCH 135/222] * Enabled pgphash background work. * Fixed lots of little bugs: ServiceString decoding, not saving to variables, etc. * Added createIdentity fns. - Can create Anon, but not PGPLinked ones yet? no idea why. * Added lots more debugging. * Added mutex protection for class variables. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5789 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/retroshare/rsidentity.h | 5 +- libretroshare/src/services/p3idservice.cc | 193 ++++++++++++++++++---- 2 files changed, 164 insertions(+), 34 deletions(-) diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index eabf977fd..cc7f8fa3d 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -181,8 +181,9 @@ class RsIdOpinion class RsIdentityParameters { public: - - int IdType; + RsIdentityParameters(): isPgpLinked(false) { return; } + bool isPgpLinked; + std::string nickname; }; diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index c092da41d..784bacb7d 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -86,6 +86,7 @@ p3IdService::p3IdService(RsGeneralDataService *gds, RsNetworkExchangeService *ne mCacheLoad_Status = 0; mHashPgp_SearchActive = false; + mHashPgp_LastTs = 0; mBgSchedule_Mode = 0; mBgSchedule_Active = false; @@ -105,7 +106,7 @@ void p3IdService::service_tick() cachetest_tick(); // background stuff. - //scheduling_tick(); + scheduling_tick(); return; } @@ -146,7 +147,21 @@ bool p3IdService::submitOpinion(uint32_t& token, RsIdOpinion &opinion) bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) { - return false; + + RsGxsIdGroup id; + + id.mMeta.mGroupName = params.nickname; + if (params.isPgpLinked) + { + id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID; + } + else + { + id.mMeta.mGroupFlags = 0; + } + + createGroup(token, id); + return true; } @@ -241,11 +256,21 @@ bool p3IdService::getGroupData(const uint32_t &token, std::vector { group.mPgpKnown = ssdata.pgp.idKnown; group.mPgpId = ssdata.pgp.pgpId; + + std::cerr << "p3IdService::getGroupData() Success decoding ServiceString"; + std::cerr << std::endl; + std::cerr << "\t mGpgKnown: " << group.mPgpKnown; + std::cerr << std::endl; + std::cerr << "\t mGpgId: " << group.mPgpId; + std::cerr << std::endl; } else { group.mPgpKnown = false; group.mPgpId = ""; + + std::cerr << "p3IdService::getGroupData() Failed to decode ServiceString"; + std::cerr << std::endl; } groups.push_back(group); @@ -396,7 +421,7 @@ bool SSGxsIdGroup::load(const std::string &input) char repstr[RSGXSID_MAX_SERVICE_STRING]; // split into two parts. - if (4 != sscanf(input.c_str(), "v1 {%[^}]} {%[^}]} {%[^}]} {%[^}]}", pgpstr, scorestr, opinionstr, repstr)) + if (4 != sscanf(input.c_str(), "v1 {P:%[^}]} {Y:%[^}]} {O:%[^}]} {R:%[^}]}", pgpstr, scorestr, opinionstr, repstr)) { std::cerr << "SSGxsIdGroup::load() Failed to extract 4 Parts"; std::cerr << std::endl; @@ -404,11 +429,10 @@ bool SSGxsIdGroup::load(const std::string &input) } bool ok = true; - if (0 == strncmp(pgpstr, "P:", 2)) + if (pgp.load(pgpstr)) { std::cerr << "SSGxsIdGroup::load() pgpstr: " << pgpstr; std::cerr << std::endl; - ok &= pgp.load(pgpstr); } else { @@ -417,11 +441,10 @@ bool SSGxsIdGroup::load(const std::string &input) ok = false; } - if (0 == strncmp(scorestr, "Y:", 2)) + if (score.load(scorestr)) { std::cerr << "SSGxsIdGroup::load() scorestr: " << scorestr; std::cerr << std::endl; - ok &= score.load(scorestr); } else { @@ -430,11 +453,10 @@ bool SSGxsIdGroup::load(const std::string &input) ok = false; } - if (0 == strncmp(opinionstr, "O:", 2)) + if (opinion.load(opinionstr)) { std::cerr << "SSGxsIdGroup::load() opinionstr: " << opinionstr; std::cerr << std::endl; - ok &= opinion.load(opinionstr); } else { @@ -443,11 +465,10 @@ bool SSGxsIdGroup::load(const std::string &input) ok = false; } - if (0 == strncmp(repstr, "R:", 2)) + if (reputation.load(repstr)) { std::cerr << "SSGxsIdGroup::load() repstr: " << repstr; std::cerr << std::endl; - ok &= reputation.load(repstr); } else { @@ -456,6 +477,11 @@ bool SSGxsIdGroup::load(const std::string &input) ok = false; } + std::cerr << "SSGxsIdGroup::load() regurgitated: " << save(); + std::cerr << std::endl; + + std::cerr << "SSGxsIdGroup::load() isOkay?: " << ok; + std::cerr << std::endl; return ok; } @@ -479,8 +505,8 @@ std::string SSGxsIdGroup::save() const output += reputation.save(); output += "}"; - std::cerr << "SSGxsIdGroup::save() output: " << output; - std::cerr << std::endl; + //std::cerr << "SSGxsIdGroup::save() output: " << output; + //std::cerr << std::endl; return output; } @@ -963,15 +989,22 @@ bool p3IdService::cachetest_request() int p3IdService::scheduling_tick() { - std::cerr << "p3IdService::scheduling_tick()"; - std::cerr << std::endl; + //std::cerr << "p3IdService::scheduling_tick()"; + //std::cerr << std::endl; /*** MUTEX TODO ***/ + bool active; + uint32_t mode; + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + active = mBgSchedule_Active; + mode = mBgSchedule_Mode; + } - if (mBgSchedule_Active) + if (active) { bool done = false; - if (mBgSchedule_Mode == BG_PGPHASH) + if (mode == BG_PGPHASH) { done = pgphash_continue(); } @@ -982,6 +1015,7 @@ int p3IdService::scheduling_tick() if (done) { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ mBgSchedule_Active = false; } } @@ -989,11 +1023,13 @@ int p3IdService::scheduling_tick() { if (pgphash_start()) { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ mBgSchedule_Mode = BG_PGPHASH; mBgSchedule_Active = true; } else if (reputation_start()) { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ mBgSchedule_Mode = BG_REPUTATION; mBgSchedule_Active = true; } @@ -1042,6 +1078,31 @@ void p3IdService::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet std::cerr << std::endl; return; } + + + /********************* TEMP HACK UNTIL GXS FILLS IN GROUP_ID *****************/ + // find private admin key + std::map::iterator mit = keySet.keys.begin(); + for(; mit != keySet.keys.end(); mit++) + { + RsTlvSecurityKey& pk = mit->second; + + if(pk.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL)) + { + item->group.mMeta.mGroupId = pk.keyId; + break; + } + } + + if(mit == keySet.keys.end()) + { + std::cerr << "p3IdService::service_CreateGroup() ERROR no admin key"; + std::cerr << std::endl; + return; + } + + + /********************* TEMP HACK UNTIL GXS FILLS IN GROUP_ID *****************/ std::cerr << "p3IdService::service_CreateGroup() for : " << item->group.mMeta.mGroupId; std::cerr << std::endl; @@ -1125,7 +1186,15 @@ bool p3IdService::pgphash_start() bool p3IdService::pgphash_continue() { - if (mHashPgp_SearchActive) + std::cerr << "p3IdService::pgphash_continue()"; + std::cerr << std::endl; + bool active; + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + active = mHashPgp_SearchActive; + } + + if (active) { pgphash_request(); } @@ -1145,18 +1214,26 @@ bool p3IdService::pgphash_getlist() RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ if (mHashPgp_SearchActive) { - std::cerr << "p3IdService::cachetest_getlist() Already active"; + std::cerr << "p3IdService::pgphash_getlist() Already active"; std::cerr << std::endl; return false; } } - std::cerr << "p3IdService::cachetest_getlist() making request"; + std::cerr << "p3IdService::pgphash_getlist() making request"; std::cerr << std::endl; - uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; + getPgpIdList(); + + // ACTUALLY only need summary - but have written code for data. + // Also need to use opts.groupFlags to filter stuff properly to REALID's only. + // TODO + + //uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; + uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; + //opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; uint32_t token = 0; RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts); @@ -1177,6 +1254,9 @@ bool p3IdService::pgphash_request() RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ if (!mHashPgp_SearchActive) { + std::cerr << "p3IdService::pgphash_request() Search Not Active returning false"; + std::cerr << std::endl; + return false; } token = mHashPgp_Token; @@ -1213,9 +1293,15 @@ bool p3IdService::pgphash_request() if(ok) { + std::cerr << "p3IdService::pgphash_request() Have " << groups.size() << " Groups"; + std::cerr << std::endl; + std::vector::iterator vit; for(vit = groups.begin(); vit != groups.end(); vit++) { + std::cerr << "p3IdService::pgphash_request() Group Id: " << vit->mMeta.mGroupId; + std::cerr << std::endl; + /* Filter based on IdType */ if (!(vit->mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)) { @@ -1251,19 +1337,26 @@ bool p3IdService::pgphash_request() if (age < wait_period) { - std::cerr << "p3IdService::pgphash_request() discarding Recently Check"; + std::cerr << "p3IdService::pgphash_request() discarding Recent Check"; std::cerr << std::endl; continue; } } /* if we get here -> then its to be processed */ - std::cerr << "p3IdService::cachetest_request() Requested Key Id: " << *vit; + std::cerr << "p3IdService::pgphash_request() ToProcess Group: " << vit->mMeta.mGroupId; std::cerr << std::endl; + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ mGroupsToProcess.push_back(*vit); } } + else + { + std::cerr << "p3IdService::pgphash_request() getGroupData ERROR"; + std::cerr << std::endl; + } + } return true; } @@ -1271,13 +1364,22 @@ bool p3IdService::pgphash_request() bool p3IdService::pgphash_process() { /* each time this is called - process one Id from mGroupsToProcess */ - if (mGroupsToProcess.empty()) + RsGxsIdGroup pg; { - return true; - } + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + if (mGroupsToProcess.empty()) + { + std::cerr << "p3IdService::pgphash_process() List Empty... Done"; + std::cerr << std::endl; + return true; + } - RsGxsIdGroup pg = mGroupsToProcess.front(); - mGroupsToProcess.pop_front(); + pg = mGroupsToProcess.front(); + mGroupsToProcess.pop_front(); + + std::cerr << "p3IdService::pgphash_process() Popped Group: " << pg.mMeta.mGroupId; + std::cerr << std::endl; + } SSGxsIdGroup ssdata; ssdata.load(pg.mMeta.mServiceString); // attempt load - okay if fails. @@ -1289,6 +1391,9 @@ bool p3IdService::pgphash_process() /* found a match - update everything */ /* Consistency issues here - what if Reputation was recently updated? */ + std::cerr << "p3IdService::pgphash_process() CheckId Success for Group: " << pg.mMeta.mGroupId; + std::cerr << " PgpId: " << pgpId.toStdString(); + std::cerr << std::endl; /* update */ ssdata.pgp.idKnown = true; @@ -1320,6 +1425,9 @@ bool p3IdService::pgphash_process() } else { + std::cerr << "p3IdService::pgphash_process() No Match for Group: " << pg.mMeta.mGroupId; + std::cerr << std::endl; + ssdata.pgp.lastCheckTs = time(NULL); ssdata.pgp.checkAttempts++; } @@ -1329,8 +1437,7 @@ bool p3IdService::pgphash_process() std::string serviceString = ssdata.save(); setGroupServiceString(dummyToken, pg.mMeta.mGroupId, serviceString); - return true; - + return false; // as there are more items on the queue to process. } @@ -1344,6 +1451,11 @@ bool p3IdService::checkId(const RsGxsIdGroup &grp, PGPIdType &pgpId) /* iterate through and check hash */ GxsIdPgpHash ans(grp.mPgpIdHash); + std::cerr << "\tExpected Answer: " << ans.toStdString(); + std::cerr << std::endl; + + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + std::map::iterator mit; for(mit = mPgpFingerprintMap.begin(); mit != mPgpFingerprintMap.end(); mit++) { @@ -1372,6 +1484,7 @@ bool p3IdService::checkId(const RsGxsIdGroup &grp, PGPIdType &pgpId) std::cerr << "p3IdService::checkId() ERROR Signature Failed"; std::cerr << std::endl; #else + pgpId = mit->first; std::cerr << "p3IdService::checkId() Skipping Signature check for now... Hash Okay"; std::cerr << std::endl; return true; @@ -1396,6 +1509,10 @@ void p3IdService::getPgpIdList() std::list list; AuthGPG::getAuthGPG()->getGPGFilteredList(list); + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + mPgpFingerprintMap.clear(); + std::list::iterator it; for(it = list.begin(); it != list.end(); it++) { @@ -1403,6 +1520,9 @@ void p3IdService::getPgpIdList() PGPFingerprintType fp; AuthGPG::getAuthGPG()->getKeyFingerprint(pgpId, fp); + std::cerr << "p3IdService::getPgpIdList() Id: " << pgpId.toStdString() << " => " << fp.toStdString(); + std::cerr << std::endl; + mPgpFingerprintMap[pgpId] = fp; } @@ -1423,6 +1543,15 @@ void calcPGPHash(const RsGxsId &id, const PGPFingerprintType &pgp, GxsIdPgpHash SHA1_Final(signature, sha_ctx); hash = GxsIdPgpHash(signature); + std::cerr << "calcPGPHash():"; + std::cerr << std::endl; + std::cerr << "\tRsGxsId: " << id; + std::cerr << std::endl; + std::cerr << "\tFingerprint: " << pgp.toStdString(); + std::cerr << std::endl; + std::cerr << "\tFinal Hash: " << hash.toStdString(); + std::cerr << std::endl; + delete sha_ctx; } @@ -1499,7 +1628,7 @@ void p3IdService::generateDummyData() createGroup(dummyToken, id); // LIMIT - AS GENERATION IS BROKEN. -#define MAX_TEST_GEN 50 +#define MAX_TEST_GEN 5 if (++genCount > MAX_TEST_GEN) { return; From 1b865612c59502b82ce2fff367cce5145174b17c Mon Sep 17 00:00:00 2001 From: drbob Date: Wed, 7 Nov 2012 21:40:07 +0000 Subject: [PATCH 136/222] * fixed up the display of PGP linked name etc. * made createIdentity work (plumbing) * disabled editId until GXS supports it. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5790 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/Identity/IdDialog.cpp | 14 ++++++++++++-- retroshare-gui/src/gui/Identity/IdEditDialog.cpp | 11 +++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 3270bc5d7..0fcb8591d 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -228,7 +228,8 @@ void IdDialog::insertIdDetails(uint32_t token) { ui.pushButton_Reputation->setEnabled(false); ui.pushButton_Delete->setEnabled(true); - ui.pushButton_EditId->setEnabled(true); + // No Editing Ids yet! + //ui.pushButton_EditId->setEnabled(true); } else { @@ -393,7 +394,16 @@ void IdDialog::insertIdList(uint32_t token) item->setText(RSID_COL_KEYID, QString::fromStdString(data.mMeta.mGroupId)); if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID) { - item->setText(RSID_COL_IDTYPE, "PGP Linked Id"); + if (data.mPgpKnown) + { + RsPeerDetails details; + rsPeers->getGPGDetails(data.mPgpId, details); + item->setText(RSID_COL_IDTYPE, QString::fromStdString(details.name)); + } + else + { + item->setText(RSID_COL_IDTYPE, "PGP Linked Id"); + } } else { diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp index 5a7b9b69e..3bad7dead 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp @@ -200,6 +200,7 @@ void IdEditDialog::updateId() RsGxsIdGroup rid; // Must set, Nickname, KeyId(if existing), mIdType, GpgId. + rid.mMeta.mGroupName = ui.lineEdit_Nickname->text().toStdString(); if (rid.mMeta.mGroupName.size() < 2) @@ -238,8 +239,14 @@ void IdEditDialog::updateId() //rid.mGpgEmail = ""; } - // TODO. - //rsIdentity->updateIdentity(rid); + + // Can only create Identities for the moment! + RsIdentityParameters params; + params.nickname = rid.mMeta.mGroupName; + params.isPgpLinked = (ui.radioButton_GpgId->isChecked()); + + uint32_t dummyToken = 0; + rsIdentity->createIdentity(dummyToken, params); hide(); return; From 817069702999a82134208ad841745eee3ea2b0bf Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Wed, 7 Nov 2012 23:24:23 +0000 Subject: [PATCH 137/222] Decided again creating new Gxs dialogs. Decided on final form of GXS group create Added Post and Comment create disabled wiki git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5791 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/RetroShare.pro | 30 +++--- .../gui/Posted/PostedCreateCommentDialog.cpp | 14 +++ .../gui/Posted/PostedCreateCommentDialog.h | 22 +++++ .../gui/Posted/PostedCreateCommentDialog.ui | 71 ++++++++++++++ .../src/gui/Posted/PostedCreatePostDialog.cpp | 21 ++++ .../src/gui/Posted/PostedCreatePostDialog.h | 38 ++++++++ .../src/gui/Posted/PostedCreatePostDialog.ui | 96 +++++++++++++++++++ .../src/gui/Posted/PostedGroupDialog.cpp | 72 ++++---------- .../src/gui/Posted/PostedGroupDialog.h | 12 +-- .../src/gui/Posted/PostedListDialog.cpp | 48 ++-------- .../src/gui/Posted/PostedListDialog.h | 1 + .../src/gui/gxs/GxsCreateGroupDialog.cpp | 26 ----- .../src/gui/gxs/GxsCreateGroupDialog.h | 23 ----- .../src/gui/gxs/GxsCreateGroupDialog.ui | 18 ---- retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp | 45 ++------- retroshare-gui/src/gui/gxs/GxsGroupDialog.h | 45 ++++----- retroshare-gui/src/gui/gxs/GxsViewGroup.cpp | 26 ----- retroshare-gui/src/gui/gxs/GxsViewGroup.h | 23 ----- retroshare-gui/src/gui/gxs/GxsViewGroup.ui | 21 ---- .../src/gui/unfinished/ApplicationWindow.cpp | 6 +- 20 files changed, 346 insertions(+), 312 deletions(-) create mode 100644 retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.cpp create mode 100644 retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.h create mode 100644 retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.ui create mode 100644 retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp create mode 100644 retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h create mode 100644 retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui delete mode 100644 retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.cpp delete mode 100644 retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.h delete mode 100644 retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.ui delete mode 100644 retroshare-gui/src/gui/gxs/GxsViewGroup.cpp delete mode 100644 retroshare-gui/src/gui/gxs/GxsViewGroup.h delete mode 100644 retroshare-gui/src/gui/gxs/GxsViewGroup.ui diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index e56ff437d..c695cbc25 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -2,7 +2,7 @@ CONFIG += qt gui uic qrc resources uitools idle bitdht # Below is for GXS services. CONFIG += photoshare -CONFIG += wikipoos +#CONFIG += wikipoos #CONFIG += thewire CONFIG += identities #CONFIG += forumsv2 @@ -194,11 +194,11 @@ freebsd-* { # ########################################### bitdht { - LIBS += ../../libbitdht/src/lib/libbitdht.a - PRE_TARGETDEPS *= ../../libbitdht/src/lib/libbitdht.a + #LIBS += ../../libbitdht/src/lib/libbitdht.a + #PRE_TARGETDEPS *= ../../libbitdht/src/lib/libbitdht.a - #LIBS += C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a - #PRE_TARGETDEPS *= C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a + LIBS += C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a + PRE_TARGETDEPS *= C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a # Chris version. #LIBS += ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a @@ -420,7 +420,7 @@ HEADERS += rshare.h \ gui/groups/CreateGroup.h \ gui/dht/DhtWindow.h \ gui/bwctrl/BwCtrlWindow.h \ - gui/GetStartedDialog.h \ + gui/GetStartedDialog.h @@ -703,7 +703,8 @@ SOURCES += main.cpp \ gui/groups/CreateGroup.cpp \ gui/dht/DhtWindow.cpp \ gui/bwctrl/BwCtrlWindow.cpp \ - gui/GetStartedDialog.cpp + gui/GetStartedDialog.cpp \ + @@ -989,18 +990,24 @@ posted { gui/Posted/PostedComments.h \ util/TokenQueueVEG.h \ gui/Posted/PostedGroupDialog.h \ + gui/Posted/PostedCreatePostDialog.h \ + gui/Posted/PostedCreateCommentDialog.h FORMS += gui/Posted/PostedDialog.ui \ gui/Posted/PostedListDialog.ui \ gui/Posted/PostedItem.ui \ gui/Posted/PostedComments.ui \ + gui/Posted/PostedCreatePostDialog.ui \ + gui/Posted/PostedCreateCommentDialog.ui SOURCES += gui/Posted/PostedDialog.cpp \ gui/Posted/PostedListDialog.cpp \ gui/Posted/PostedItem.cpp \ gui/Posted/PostedComments.cpp \ util/TokenQueueVEG.cpp \ - gui/Posted/PostedGroupDialog.cpp + gui/Posted/PostedGroupDialog.cpp \ + gui/Posted/PostedCreatePostDialog.cpp \ + gui/Posted/PostedCreateCommentDialog.cpp } @@ -1008,19 +1015,18 @@ gxsgui { HEADERS += gui/gxs/GxsGroupDialog.h \ gui/gxs/GxsCommentTreeWidget.h \ - gui/gxs/WikiGroupDialog.h \ + # gui/gxs/WikiGroupDialog.h \ # gui/gxs/ForumV2GroupDialog.h \ # gui/gxs/GxsMsgDialog.h \ - FORMS += gui/gxs/GxsGroupDialog.ui \ - + FORMS += gui/gxs/GxsGroupDialog.ui \ # gui/gxs/GxsMsgDialog.ui \ # gui/gxs/GxsCommentTreeWidget.ui \ SOURCES += gui/gxs/GxsGroupDialog.cpp \ gui/gxs/GxsCommentTreeWidget.cpp \ - gui/gxs/WikiGroupDialog.cpp \ + # gui/gxs/WikiGroupDialog.cpp \ #gui/gxs/ForumV2GroupDialog.cpp \ # gui/gxs/GxsMsgDialog.cpp \ diff --git a/retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.cpp new file mode 100644 index 000000000..e9a020f14 --- /dev/null +++ b/retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.cpp @@ -0,0 +1,14 @@ +#include "PostedCreateCommentDialog.h" +#include "ui_PostedCreateCommentDialog.h" + +PostedCreateCommentDialog::PostedCreateCommentDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::PostedCreateCommentDialog) +{ + ui->setupUi(this); +} + +PostedCreateCommentDialog::~PostedCreateCommentDialog() +{ + delete ui; +} diff --git a/retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.h b/retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.h new file mode 100644 index 000000000..22ff82598 --- /dev/null +++ b/retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.h @@ -0,0 +1,22 @@ +#ifndef POSTEDCREATECOMMENTDIALOG_H +#define POSTEDCREATECOMMENTDIALOG_H + +#include + +namespace Ui { + class PostedCreateCommentDialog; +} + +class PostedCreateCommentDialog : public QDialog +{ + Q_OBJECT + +public: + explicit PostedCreateCommentDialog(QWidget *parent = 0); + ~PostedCreateCommentDialog(); + +private: + Ui::PostedCreateCommentDialog *ui; +}; + +#endif // POSTEDCREATECOMMENTDIALOG_H diff --git a/retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.ui b/retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.ui new file mode 100644 index 000000000..c35128f27 --- /dev/null +++ b/retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.ui @@ -0,0 +1,71 @@ + + + + + PostedCreateCommentDialog + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + 30 + 240 + 341 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + buttonBox + accepted() + PostedCreateCommentDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + PostedCreateCommentDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp new file mode 100644 index 000000000..f17fb2486 --- /dev/null +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp @@ -0,0 +1,21 @@ +#include "PostedCreatePostDialog.h" +#include "ui_PostedCreatePostDialog.h" + +PostedCreatePostDialog::PostedCreatePostDialog(TokenQueue* tokenQ, RsPosted *posted, QWidget *parent): + QDialog(parent), mTokenQueue(tokenQ), mPosted(posted), + ui(new Ui::PostedCreatePostDialog) +{ + ui->setupUi(this); +} + +void PostedCreatePostDialog::createPost() +{ + + + close(); +} + +PostedCreatePostDialog::~PostedCreatePostDialog() +{ + delete ui; +} diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h new file mode 100644 index 000000000..d2fe3e45a --- /dev/null +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h @@ -0,0 +1,38 @@ +#ifndef POSTEDCREATEPOSTDIALOG_H +#define POSTEDCREATEPOSTDIALOG_H + +#include +#include "retroshare/rsposted.h" +#include "util/TokenQueue.h" + +namespace Ui { + class PostedCreatePostDialog; +} + +class PostedCreatePostDialog : public QDialog +{ + Q_OBJECT + +public: + + /*! + * @param tokenQ parent callee token + * @param posted + */ + explicit PostedCreatePostDialog(TokenQueue* tokenQ, RsPosted* posted, QWidget *parent = 0); + ~PostedCreatePostDialog(); + +private: + + void createPost(); + +private: + Ui::PostedCreatePostDialog *ui; + + QString mLink; + QString mNotes; + RsPosted* mPosted; + TokenQueue* mTokenQueue; +}; + +#endif // POSTEDCREATEPOSTDIALOG_H diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui new file mode 100644 index 000000000..cd9e01abf --- /dev/null +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui @@ -0,0 +1,96 @@ + + + PostedCreatePostDialog + + + + 0 + 0 + 406 + 168 + + + + Create Post + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Link</span></p></body></html> + + + + + + + + + + + + + + Notes + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + PostedCreatePostDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + PostedCreatePostDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp index 93d0a5164..358ab9ef6 100644 --- a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp @@ -25,58 +25,30 @@ #include #include -PostedGroupDialog::PostedGroupDialog(TokenQueue* tokenQueue, QWidget *parent) - :GxsGroupDialog(tokenQueue, parent, GXS_GROUP_DIALOG_CREATE_MODE) +#define POSTED_ENABLE_FLAG ( GXS_GROUP_FLAGS_ICON | \ + GXS_GROUP_FLAGS_DESCRIPTION | \ + GXS_GROUP_FLAGS_DISTRIBUTION | \ + GXS_GROUP_FLAGS_PUBLISHSIGN | \ + GXS_GROUP_FLAGS_SHAREKEYS | \ + GXS_GROUP_FLAGS_PERSONALSIGN | \ + GXS_GROUP_FLAGS_COMMENTS | \ + 0) + +#define POSTED_CREATE_DEFAULT_FLAG ( GXS_GROUP_DEFAULTS_DISTRIB_LOCAL | \ + GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED | \ + GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | \ + GXS_GROUP_DEFAULTS_COMMENTS_NO | \ + 0) + +PostedGroupDialog::PostedGroupDialog(TokenQueue* tokenQueue, RsPosted* posted, QWidget *parent) + :GxsGroupDialog(tokenQueue, POSTED_ENABLE_FLAG, POSTED_CREATE_DEFAULT_FLAG, parent), + mPosted(posted) { - - // To start with we only have open forums - with distribution controls. - - uint32_t enabledFlags = ( GXS_GROUP_FLAGS_ICON | - GXS_GROUP_FLAGS_DESCRIPTION | - GXS_GROUP_FLAGS_DISTRIBUTION | - GXS_GROUP_FLAGS_PUBLISHSIGN | - GXS_GROUP_FLAGS_SHAREKEYS | - GXS_GROUP_FLAGS_PERSONALSIGN | - GXS_GROUP_FLAGS_COMMENTS | - 0); - - uint32_t readonlyFlags = 0; - - uint32_t defaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_LOCAL | - GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED | - GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | - GXS_GROUP_DEFAULTS_COMMENTS_NO | - 0); - - setFlags(enabledFlags, defaultsFlags); - } -PostedGroupDialog::PostedGroupDialog(const RsPostedGroup &grp, QWidget *parent) - :GxsGroupDialog(NULL, parent, GXS_GROUP_DIALOG_SHOW_MODE), mGrp(grp) +PostedGroupDialog::PostedGroupDialog(const RsPostedGroup& grp, uint32_t mode, QWidget *parent) + :GxsGroupDialog(grp.mMeta, mode, parent), mGrp(grp) { - - // To start with we only have open forums - with distribution controls. - - uint32_t enabledFlags = ( GXS_GROUP_FLAGS_ICON | - GXS_GROUP_FLAGS_DESCRIPTION | - GXS_GROUP_FLAGS_DISTRIBUTION | - GXS_GROUP_FLAGS_PUBLISHSIGN | - GXS_GROUP_FLAGS_SHAREKEYS | - GXS_GROUP_FLAGS_PERSONALSIGN | - GXS_GROUP_FLAGS_COMMENTS | - 0); - - uint32_t readonlyFlags = 0; - - uint32_t defaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_LOCAL | - GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED | - GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | - GXS_GROUP_DEFAULTS_COMMENTS_NO | - 0); - - setFlags(enabledFlags, defaultsFlags); - } @@ -100,10 +72,6 @@ QString PostedGroupDialog::service_getDescription() return QString(); } -RsGroupMetaData PostedGroupDialog::service_getMeta() -{ - return mGrp.mMeta; -} diff --git a/retroshare-gui/src/gui/Posted/PostedGroupDialog.h b/retroshare-gui/src/gui/Posted/PostedGroupDialog.h index 7d832fae1..09dac9043 100644 --- a/retroshare-gui/src/gui/Posted/PostedGroupDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedGroupDialog.h @@ -35,12 +35,12 @@ public: /*! * This constructs a create dialog */ - PostedGroupDialog(TokenQueue* tokenQueue, QWidget *parent = NULL); + PostedGroupDialog(TokenQueue* tokenQueue, RsPosted* posted, QWidget *parent = NULL); /*! * This constructs a show dialog which displays an already existing group */ - PostedGroupDialog(const RsPostedGroup& grp, QWidget *parent = NULL); + PostedGroupDialog(const RsPostedGroup& grp, uint32_t mode, QWidget *parent = NULL); protected: @@ -59,16 +59,10 @@ protected: */ virtual QString service_getDescription(); - /*! - * Used in show mode, returns a meta type - * @return the meta of existing grpMeta - */ - virtual RsGroupMetaData service_getMeta(); - - private: RsPostedGroup mGrp; + RsPosted* mPosted; }; diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp index ba74ae4b6..3bcc144dc 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp @@ -24,6 +24,7 @@ #include "PostedListDialog.h" #include "gui/Posted/PostedGroupDialog.h" +#include "gui/Posted/PostedCreatePostDialog.h" #include #include @@ -107,46 +108,17 @@ void PostedListDialog::groupListCustomPopupMenu( QPoint /*point*/ ) { QMenu contextMnu( this ); - QAction *action = contextMnu.addAction(QIcon(IMAGE_SUBSCRIBE), tr("Subscribe to Forum"), this, SLOT(subscribeToForum())); - //action->setDisabled (mCurrTopicId.empty() || IS_FORUM_SUBSCRIBED(subscribeFlags)); - - action = contextMnu.addAction(QIcon(IMAGE_UNSUBSCRIBE), tr("Unsubscribe to Forum"), this, SLOT(unsubscribeToForum())); - //action->setEnabled (!mCurrTopicId.empty() && IS_FORUM_SUBSCRIBED(subscribeFlags)); - - contextMnu.addSeparator(); - - contextMnu.addAction(QIcon(IMAGE_NEWFORUM), tr("New Forum"), this, SLOT(newforum())); - - action = contextMnu.addAction(QIcon(IMAGE_INFO), tr("Show Forum Details"), this, SLOT(showForumDetails())); - action->setEnabled (!mCurrTopicId.empty ()); - - action = contextMnu.addAction(QIcon(":/images/settings16.png"), tr("Edit Forum Details"), this, SLOT(editForumDetails())); - //action->setEnabled (!mCurrTopicId.empty () && IS_FORUM_ADMIN(subscribeFlags)); - - QAction *shareKeyAct = new QAction(QIcon(":/images/gpgp_key_generate.png"), tr("Share Forum"), &contextMnu); - connect( shareKeyAct, SIGNAL( triggered() ), this, SLOT( shareKey() ) ); - //shareKeyAct->setEnabled(!mCurrTopicId.empty() && IS_FORUM_ADMIN(subscribeFlags)); - contextMnu.addAction( shareKeyAct); - - QAction *restoreKeysAct = new QAction(QIcon(":/images/settings16.png"), tr("Restore Publish Rights for Forum" ), &contextMnu); - connect( restoreKeysAct , SIGNAL( triggered() ), this, SLOT( restoreForumKeys() ) ); - //restoreKeysAct->setEnabled(!mCurrTopicId.empty() && !IS_FORUM_ADMIN(subscribeFlags)); - contextMnu.addAction( restoreKeysAct); - - action = contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyForumLink())); - action->setEnabled(!mCurrTopicId.empty()); - - contextMnu.addSeparator(); - - action = contextMnu.addAction(QIcon(":/images/message-mail-read.png"), tr("Mark all as read"), this, SLOT(markMsgAsReadAll())); - //action->setEnabled (!mCurrTopicId.empty () && IS_FORUM_SUBSCRIBED(subscribeFlags)); - - action = contextMnu.addAction(QIcon(":/images/message-mail.png"), tr("Mark all as unread"), this, SLOT(markMsgAsUnreadAll())); - //action->setEnabled (!mCurrTopicId.empty () && IS_FORUM_SUBSCRIBED(subscribeFlags)); + QAction *action = contextMnu.addAction(QIcon(IMAGE_MESSAGE), tr("Create Post"), this, SLOT(createPost())); + action->setDisabled (mCurrTopicId.empty()); contextMnu.exec(QCursor::pos()); } +void PostedListDialog::createPost() +{ + +} + void PostedListDialog::updateDisplay() { std::list groupIds; @@ -277,7 +249,7 @@ void PostedListDialog::periodChanged( int index ) void PostedListDialog::newGroup() { - PostedGroupDialog cf (mPostedQueue, this); + PostedGroupDialog cf (mPostedQueue, rsPosted, this); cf.exec (); } @@ -288,7 +260,7 @@ void PostedListDialog::showGroupDetails() return; } - PostedGroupDialog cf(mGroups[mCurrTopicId], this); + PostedGroupDialog cf(mGroups[mCurrTopicId], GXS_GROUP_DIALOG_SHOW_MODE, this); cf.exec (); } diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.h b/retroshare-gui/src/gui/Posted/PostedListDialog.h index 52e2367d1..a0dc4cf25 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.h @@ -76,6 +76,7 @@ void periodChanged( int index ); void newGroup(); void showGroupDetails(); void editGroupDetails(); + void createPost(); private: diff --git a/retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.cpp deleted file mode 100644 index a2e4b14be..000000000 --- a/retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "GxsCreateGroupDialog.h" -#include "ui_GxsCreateGroupDialog.h" - -GxsCreateGroupDialog::GxsCreateGroupDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::GxsCreateGroupDialog) -{ - ui->setupUi(this); -} - -GxsCreateGroupDialog::~GxsCreateGroupDialog() -{ - delete ui; -} - -void GxsCreateGroupDialog::changeEvent(QEvent *e) -{ - QDialog::changeEvent(e); - switch (e->type()) { - case QEvent::LanguageChange: - ui->retranslateUi(this); - break; - default: - break; - } -} diff --git a/retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.h b/retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.h deleted file mode 100644 index 4808e79ee..000000000 --- a/retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef GXSCREATEGROUPDIALOG_H -#define GXSCREATEGROUPDIALOG_H - -#include - -namespace Ui { - class GxsCreateGroupDialog; -} - -class GxsCreateGroupDialog : public QDialog { - Q_OBJECT -public: - GxsCreateGroupDialog(QWidget *parent = 0); - ~GxsCreateGroupDialog(); - -protected: - void changeEvent(QEvent *e); - -private: - Ui::GxsCreateGroupDialog *ui; -}; - -#endif // GXSCREATEGROUPDIALOG_H diff --git a/retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.ui b/retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.ui deleted file mode 100644 index 9d504cc9e..000000000 --- a/retroshare-gui/src/gui/gxs/GxsCreateGroupDialog.ui +++ /dev/null @@ -1,18 +0,0 @@ - - GxsCreateGroupDialog - - - - 0 - 0 - 400 - 300 - - - - Dialog - - - - - diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index d196e4e55..ca987bbe1 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -50,8 +50,8 @@ #define GXSGROUP_LOADGROUP 2 /** Constructor */ -GxsGroupDialog::GxsGroupDialog(TokenQueue* tokenQueue, QWidget *parent, uint32_t mode) -: QDialog(parent), mTokenQueue(tokenQueue), mMode(mode) +GxsGroupDialog::GxsGroupDialog(TokenQueue *tokenQueue, uint32_t enableFlags, uint16_t defaultFlags, QWidget *parent) +: QDialog(parent), mTokenQueue(tokenQueue), mMode(GXS_GROUP_DIALOG_CREATE_MODE), mEnabledFlags(enableFlags), mDefaultsFlags(defaultFlags), mReadonlyFlags(0) { /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); @@ -64,7 +64,8 @@ GxsGroupDialog::GxsGroupDialog(TokenQueue* tokenQueue, QWidget *parent, uint32_ connect( ui.groupLogo, SIGNAL(clicked() ), this , SLOT(addGroupLogo())); connect( ui.addLogoButton, SIGNAL(clicked() ), this , SLOT(addGroupLogo())); - if (!ui.pubKeyShare_cb->isChecked()) { + if (!ui.pubKeyShare_cb->isChecked()) + { ui.contactsdockWidget->hide(); this->resize(this->size().width() - ui.contactsdockWidget->size().width(), this->size().height()); } @@ -74,32 +75,13 @@ GxsGroupDialog::GxsGroupDialog(TokenQueue* tokenQueue, QWidget *parent, uint32_ ui.keyShareList->setModus(FriendSelectionWidget::MODUS_CHECK); ui.keyShareList->start(); - /* Setup Reasonable Defaults */ - uint32_t enabledFlags = ( GXS_GROUP_FLAGS_ICON | - GXS_GROUP_FLAGS_DESCRIPTION | - GXS_GROUP_FLAGS_DISTRIBUTION | - GXS_GROUP_FLAGS_PUBLISHSIGN | - GXS_GROUP_FLAGS_SHAREKEYS | - GXS_GROUP_FLAGS_PERSONALSIGN | - GXS_GROUP_FLAGS_COMMENTS ); - - - uint32_t defaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC | - GXS_GROUP_DEFAULTS_PUBLISH_THREADS | - GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | - GXS_GROUP_DEFAULTS_COMMENTS_YES | - 0); - - setFlags(enabledFlags, defaultsFlags); - setMode(mode); } -void GxsGroupDialog::setFlags(uint32_t enabledFlags, uint32_t defaultsFlags) -{ - mEnabledFlags = enabledFlags; - mDefaultsFlags = defaultsFlags; +GxsGroupDialog::GxsGroupDialog(const RsGroupMetaData &grpMeta, uint32_t mode, QWidget *parent) + : QDialog(parent), mMode(mode), mGrpMeta(grpMeta) { + } void GxsGroupDialog::setMode(uint32_t mode) @@ -120,7 +102,7 @@ void GxsGroupDialog::setMode(uint32_t mode) ui.createButton->setText(tr("Close")); } break; - +//TODO // case GXS_GROUP_DIALOG_EDIT_MODE: // { // ui.createButton->setText(tr("Submit Changes")); @@ -269,17 +251,6 @@ void GxsGroupDialog::newGroup() } - -void GxsGroupDialog::loadExistingGroupMetaData(const RsGroupMetaData &meta) -{ - /* should set stuff - according to parameters */ - setGroupSignFlags(meta.mSignFlags); - ui.groupName->setText(QString::fromUtf8(meta.mGroupName.c_str())); - - return; -} - - void GxsGroupDialog::submitGroup() { std::cerr << "GxsGroupDialog::submitGroup()"; diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h index bf62723c4..b318b7863 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h @@ -55,6 +55,8 @@ public: }; +/*** Group flags affect what is visually enabled that gets input into the grpMeta ***/ + #define GXS_GROUP_FLAGS_ICON 0x00000001 #define GXS_GROUP_FLAGS_DESCRIPTION 0x00000002 #define GXS_GROUP_FLAGS_DISTRIBUTION 0x00000004 @@ -65,6 +67,10 @@ public: #define GXS_GROUP_FLAGS_EXTRA 0x00000100 +/*** Default flags are used to determine privacy of group, signatures required *** + *** whether publish or id and whether comments are allowed or not ***/ + + #define GXS_GROUP_DEFAULTS_DISTRIB_MASK 0x0000000f #define GXS_GROUP_DEFAULTS_PUBLISH_MASK 0x000000f0 #define GXS_GROUP_DEFAULTS_PERSONAL_MASK 0x00000f00 @@ -105,27 +111,29 @@ public: */ class GxsGroupDialog : public QDialog { - Q_OBJECT + Q_OBJECT public: /*! - * - * @param tokenQueue This should be the token service of the services Dialog \n + * Constructs a GxsGroupDialog for creating group + * @param tokenQueue This should be the TokenQueue of the (parent) service * in order to receive acknowledgement of group creation, if set to NULL with create mode \n * creation will not happen + * @param enableFlags This determines what options are enabled such as Icon, Description, publish type and key sharing + * @param defaultFlags This deter * @param parent The parent dialog * @param mode */ - GxsGroupDialog(TokenQueue* tokenQueue, QWidget *parent = NULL, uint32_t mode = GXS_GROUP_DIALOG_SHOW_MODE); + GxsGroupDialog(TokenQueue* tokenQueue, uint32_t enableFlags, uint16_t defaultFlags, QWidget *parent = NULL); /*! - * - * @param enabledFlags This determines what options are enabled - * @param readonlyFlags This determines what is modifiable is particularly relevant to what mode the - * @param defaultFlags + * Contructs a GxsGroupDialog for display a group or editing + * @param grpMeta This is used to fill out the dialog + * @param mode This determines whether the dialog starts in show or edit mode (Edit not supported yet) + * @param parent */ - void setFlags(uint32_t enabledFlags, uint32_t defaultFlags); + GxsGroupDialog(const RsGroupMetaData& grpMeta, uint32_t mode = GXS_GROUP_DIALOG_SHOW_MODE, QWidget *parent = NULL); private: void newGroup(); @@ -134,8 +142,8 @@ private: // Functions that can be overloaded for specific stuff. protected slots: - void submitGroup(); - void addGroupLogo(); + void submitGroup(); + void addGroupLogo(); protected: @@ -150,7 +158,7 @@ protected: /*! * This should return a group logo \n * Will be called when GxsGroupDialog is initialised in show mode - * + * @return The logo for the service */ virtual QPixmap service_getLogo() = 0; @@ -160,18 +168,6 @@ protected: */ virtual QString service_getDescription() = 0; - /*! - * Used in show mode, returns a meta type - * @return the meta of existing grpMeta - */ - virtual RsGroupMetaData service_getMeta() = 0; - - /*! - * Loads meta data for group to GUI dialog - * @param meta the meta loaded fir group - */ - void loadExistingGroupMetaData(const RsGroupMetaData &meta); - private slots: @@ -196,6 +192,7 @@ private: std::list mShareList; QPixmap picture; TokenQueue *mTokenQueue; + RsGroupMetaData mGrpMeta; uint32_t mMode; uint32_t mEnabledFlags; diff --git a/retroshare-gui/src/gui/gxs/GxsViewGroup.cpp b/retroshare-gui/src/gui/gxs/GxsViewGroup.cpp deleted file mode 100644 index c6e1d4fdd..000000000 --- a/retroshare-gui/src/gui/gxs/GxsViewGroup.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "GxsViewGroup.h" -#include "ui_GxsViewGroup.h" - -GxsViewGroup::GxsViewGroup(QWidget *parent) : - QWidget(parent), - ui(new Ui::GxsViewGroup) -{ - ui->setupUi(this); -} - -GxsViewGroup::~GxsViewGroup() -{ - delete ui; -} - -void GxsViewGroup::changeEvent(QEvent *e) -{ - QWidget::changeEvent(e); - switch (e->type()) { - case QEvent::LanguageChange: - ui->retranslateUi(this); - break; - default: - break; - } -} diff --git a/retroshare-gui/src/gui/gxs/GxsViewGroup.h b/retroshare-gui/src/gui/gxs/GxsViewGroup.h deleted file mode 100644 index ef12e8d73..000000000 --- a/retroshare-gui/src/gui/gxs/GxsViewGroup.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef GXSVIEWGROUP_H -#define GXSVIEWGROUP_H - -#include - -namespace Ui { - class GxsViewGroup; -} - -class GxsViewGroup : public QWidget { - Q_OBJECT -public: - GxsViewGroup(QWidget *parent = 0); - ~GxsViewGroup(); - -protected: - void changeEvent(QEvent *e); - -private: - Ui::GxsViewGroup *ui; -}; - -#endif // GXSVIEWGROUP_H diff --git a/retroshare-gui/src/gui/gxs/GxsViewGroup.ui b/retroshare-gui/src/gui/gxs/GxsViewGroup.ui deleted file mode 100644 index f30578df5..000000000 --- a/retroshare-gui/src/gui/gxs/GxsViewGroup.ui +++ /dev/null @@ -1,21 +0,0 @@ - - - - - GxsViewGroup - - - - 0 - 0 - 400 - 300 - - - - Form - - - - - diff --git a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp index c7ec34997..c77b630e3 100644 --- a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp +++ b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp @@ -97,9 +97,9 @@ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) ui.stackPages->add(postedDialog = new PostedDialog(ui.stackPages), createPageAction(QIcon(IMAGE_LIBRARY), tr("Posted Links"), grp)); - WikiDialog *wikiDialog = NULL; - ui.stackPages->add(wikiDialog = new WikiDialog(ui.stackPages), - createPageAction(QIcon(IMAGE_LIBRARY), tr("Wiki Pages"), grp)); +// WikiDialog *wikiDialog = NULL; +// ui.stackPages->add(wikiDialog = new WikiDialog(ui.stackPages), +// createPageAction(QIcon(IMAGE_LIBRARY), tr("Wiki Pages"), grp)); // THESE HAVE TO BE CONVERTED TO VEG FORMAT #if USE_VEG_SERVICE From eeb96c5e627ca6fb70bbcb1db79dedb3d03c2d19 Mon Sep 17 00:00:00 2001 From: drbob Date: Fri, 9 Nov 2012 00:56:07 +0000 Subject: [PATCH 138/222] Lots of progress with Gxs Services: - Added gxsForum interface, service + serialiser to libretroshare. - Bugfix in rsgenservices getSize() at the wrong point, Added lots of debug too. - Dummy Collections to Wiki, can now create and retrieve Groups from the GUI. - Bugfix in rsinit (wrong backend for wiki) + added forum to startup. - improved debugging in GxsId serialiser. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5797 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgenexchange.cc | 44 +- libretroshare/src/libretroshare.pro | 8 + libretroshare/src/retroshare/rsgxsforums.h | 87 ++++ libretroshare/src/retroshare/rswiki.h | 6 + libretroshare/src/rsserver/rsinit.cc | 34 +- .../src/serialiser/rsgxsforumitems.cc | 402 ++++++++++++++++++ .../src/serialiser/rsgxsforumitems.h | 95 +++++ libretroshare/src/serialiser/rsgxsiditems.cc | 8 +- libretroshare/src/serialiser/rswikiitems.cc | 2 +- libretroshare/src/services/p3gxsforums.cc | 369 ++++++++++++++++ libretroshare/src/services/p3gxsforums.h | 73 ++++ libretroshare/src/services/p3wiki.cc | 101 ++++- libretroshare/src/services/p3wiki.h | 4 +- 13 files changed, 1214 insertions(+), 19 deletions(-) create mode 100644 libretroshare/src/retroshare/rsgxsforums.h create mode 100644 libretroshare/src/serialiser/rsgxsforumitems.cc create mode 100644 libretroshare/src/serialiser/rsgxsforumitems.h create mode 100644 libretroshare/src/services/p3gxsforums.cc create mode 100644 libretroshare/src/services/p3gxsforums.h diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index bc007bde2..54ca3a115 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -201,6 +201,8 @@ void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet) bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet) { + std::cerr << "RsGenExchange::createGroup()"; + std::cerr << std::endl; RsGxsGrpMetaData* meta = grp->metaData; @@ -224,7 +226,12 @@ bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet) } if(mit == keySet.keys.end()) + { + std::cerr << "RsGenExchange::createGroup() Missing ADMIN Key"; + std::cerr << std::endl; + return false; + } // group is self signing // for the creation of group signature @@ -253,6 +260,12 @@ bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet) delete[] allGrpData; delete[] metaData; + if (!ok) + { + std::cerr << "RsGenExchange::createGroup() ERROR !okay (getSignature error)"; + std::cerr << std::endl; + } + return ok; } @@ -412,6 +425,9 @@ bool RsGenExchange::getGroupData(const uint32_t &token, std::vector::iterator lit = nxsGrps.begin(); + std::cerr << "RsGenExchange::getGroupData() RsNxsGrp::len: " << nxsGrps.size(); + std::cerr << std::endl; + if(ok) { for(; lit != nxsGrps.end(); lit++) @@ -426,6 +442,11 @@ bool RsGenExchange::getGroupData(const uint32_t &token, std::vectorsecond; - uint32_t size = mSerialiser->size(grpItem); RsTlvSecurityKeySet keySet; generateGroupKeys(keySet); service_CreateGroup(grpItem, keySet); + uint32_t size = mSerialiser->size(grpItem); char gData[size]; bool ok = mSerialiser->serialise(grpItem, gData, &size); + if (!ok) + { + std::cerr << "RsGenExchange::publishGrps() !ok ERROR After First Serialise" << std::endl; + } + grp->grp.setBinData(gData, size); if(ok) @@ -769,14 +795,26 @@ void RsGenExchange::publishGrps() *(grp->metaData) = grpItem->meta; grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; ok &= createGroup(grp, keySet); + if (!ok) + { + std::cerr << "RsGenExchange::publishGrps() !ok ERROR After createGroup" << std::endl; + } + size = grp->metaData->serial_size(); char mData[size]; grp->metaData->mGroupId = grp->grpId; ok &= grp->metaData->serialise(mData, size); + if (!ok) + { + std::cerr << "RsGenExchange::publishGrps() !ok ERROR After Meta Serialise" << std::endl; + } + grp->meta.setBinData(mData, size); RsGxsGroupId grpId = grp->grpId; mDataAccess->addGroupData(grp); + std::cerr << "RsGenExchange::publishGrps() ok -> pushing to notifies" << std::endl; + // add to published to allow acknowledgement mGrpNotify.insert(std::make_pair(mit->first, grpId)); mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE); @@ -786,8 +824,8 @@ void RsGenExchange::publishGrps() { #ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::publishGrps() failed to publish grp " << std::endl; #endif + std::cerr << "RsGenExchange::publishGrps() failed to publish grp " << std::endl; delete grp; // add to published to allow acknowledgement, grpid is empty as grp creation failed @@ -890,8 +928,8 @@ void RsGenExchange::createDummyGroup(RsGxsGrpItem *grpItem) { #ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::createDummyGroup(); failed to publish grp " << std::endl; #endif + std::cerr << "RsGenExchange::createDummyGroup(); failed to publish grp " << std::endl; delete grp; } diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 0e259ca4c..6b3331d93 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -642,6 +642,14 @@ HEADERS += retroshare/rsgame.h \ SOURCES += services/p3idservice.cc \ serialiser/rsgxsiditems.cc \ + # GxsForums Service + HEADERS += retroshare/rsgxsforums.h \ + services/p3gxsforums.h \ + serialiser/rsgxsforumitems.h + + SOURCES += services/p3gxsforums.cc \ + serialiser/rsgxsforumitems.cc \ + # Wiki Service HEADERS += retroshare/rswiki.h \ services/p3wiki.h \ diff --git a/libretroshare/src/retroshare/rsgxsforums.h b/libretroshare/src/retroshare/rsgxsforums.h new file mode 100644 index 000000000..7fb0da1af --- /dev/null +++ b/libretroshare/src/retroshare/rsgxsforums.h @@ -0,0 +1,87 @@ +#ifndef RETROSHARE_GXS_FORUM_GUI_INTERFACE_H +#define RETROSHARE_GXS_FORUM_GUI_INTERFACE_H + +/* + * libretroshare/src/retroshare: rsgxsforum.h + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include +#include +#include + +#include "gxs/rstokenservice.h" +#include "gxs/rsgxsifaceimpl.h" + +/* The Main Interface Class - for information about your Peers */ +class RsGxsForums; +extern RsGxsForums *rsGxsForums; + +class RsGxsForumGroup +{ + public: + RsGroupMetaData mMeta; + std::string mDescription; +}; + +class RsGxsForumMsg +{ + public: + RsMsgMetaData mMeta; + std::string mMsg; +}; + + +//typedef std::map > GxsForumMsgResult; + +std::ostream &operator<<(std::ostream &out, const RsGxsForumGroup &group); +std::ostream &operator<<(std::ostream &out, const RsGxsForumMsg &msg); + +class RsGxsForums: public RsGxsIfaceImpl +{ + public: + + RsGxsForums(RsGenExchange *gxs) + :RsGxsIfaceImpl(gxs) { return; } +virtual ~RsGxsForums() { return; } + + /* Specific Service Data */ +virtual bool getGroupData(const uint32_t &token, std::vector &groups) = 0; +virtual bool getMsgData(const uint32_t &token, std::vector &msgs) = 0; + + ////////////////////////////////////////////////////////////////////////////// +//virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask); +//virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask); + +//virtual bool groupRestoreKeys(const std::string &groupId); +//virtual bool groupShareKeys(const std::string &groupId, std::list& peers); + +virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group) = 0; +virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg) = 0; + + +}; + + + +#endif diff --git a/libretroshare/src/retroshare/rswiki.h b/libretroshare/src/retroshare/rswiki.h index 07e527791..3a4648e2b 100644 --- a/libretroshare/src/retroshare/rswiki.h +++ b/libretroshare/src/retroshare/rswiki.h @@ -108,6 +108,10 @@ class RsWikiComment std::string mComment; }; +std::ostream &operator<<(std::ostream &out, const RsWikiCollection &group); +std::ostream &operator<<(std::ostream &out, const RsWikiSnapshot &shot); +std::ostream &operator<<(std::ostream &out, const RsWikiComment &comment); + class RsWiki: public RsGxsIfaceImpl { @@ -125,6 +129,8 @@ virtual bool submitCollection(uint32_t &token, RsWikiCollection &collection) = 0 virtual bool submitSnapshot(uint32_t &token, RsWikiSnapshot &snapshot) = 0; virtual bool submitComment(uint32_t &token, RsWikiComment &comment) = 0; + // for testing only. +virtual void generateDummyData() = 0; }; diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 4d85f3d19..925c303cc 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1828,12 +1828,13 @@ RsTurtle *rsTurtle = NULL ; #include "services/p3wiki.h" #include "services/p3posted.h" #include "services/p3photoserviceV2.h" +#include "services/p3gxsforums.h" // Not too many to convert now! #include "services/p3wikiserviceVEG.h" #include "services/p3wireVEG.h" //#include "services/p3idserviceVEG.h" -#include "services/p3forumsVEG.h" +//#include "services/p3forumsVEG.h" #endif #ifndef PQI_DISABLE_TUNNEL @@ -2281,16 +2282,16 @@ int RsServer::StartupRetroShare() #ifdef ENABLE_GXS_SERVICES // Testing New Cache Services. - p3WikiServiceVEG *mWikis = new p3WikiServiceVEG(RS_SERVICE_GXSV1_TYPE_WIKI); - pqih -> addService(mWikis); + //p3WikiServiceVEG *mWikis = new p3WikiServiceVEG(RS_SERVICE_GXSV1_TYPE_WIKI); + //pqih -> addService(mWikis); // Testing New Cache Services. p3WireVEG *mWire = new p3WireVEG(RS_SERVICE_GXSV1_TYPE_WIRE); pqih -> addService(mWire); // Testing New Cache Services. - p3ForumsVEG *mForumsV2 = new p3ForumsVEG(RS_SERVICE_GXSV1_TYPE_FORUMS); - pqih -> addService(mForumsV2); + //p3ForumsVEG *mForumsV2 = new p3ForumsVEG(RS_SERVICE_GXSV1_TYPE_FORUMS); + //pqih -> addService(mForumsV2); // TODO: temporary to store GXS service data, remove @@ -2358,11 +2359,26 @@ int RsServer::StartupRetroShare() wiki_ds->resetDataStore(); //TODO: remove, new service data per RS session, for testing - mWiki = new p3Wiki(posted_ds, NULL); + mWiki = new p3Wiki(wiki_ds, NULL); // create GXS photo service RsGxsNetService* wiki_ns = new RsGxsNetService( RS_SERVICE_GXSV1_TYPE_WIKI, wiki_ds, nxsMgr, mWiki); + + /**** Forum GXS service ****/ + + p3GxsForums *mGxsForums = NULL; + + RsGeneralDataService* gxsforums_ds = new RsDataService("./" + mLinkMgr->getOwnId()+ "/", "gxsforums_db", + RS_SERVICE_GXSV1_TYPE_FORUMS); + + gxsforums_ds->resetDataStore(); //TODO: remove, new service data per RS session, for testing + + mGxsForums = new p3GxsForums(gxsforums_ds, NULL); + + // create GXS photo service + RsGxsNetService* gxsforums_ns = new RsGxsNetService( + RS_SERVICE_GXSV1_TYPE_FORUMS, gxsforums_ds, nxsMgr, mGxsForums); #endif #endif // ENABLE_GXS_SERVICES @@ -2378,6 +2394,7 @@ int RsServer::StartupRetroShare() createThread(*mPhotoV2); createThread(*mPosted); createThread(*mWiki); + createThread(*mGxsForums); // // mGxsCore->addService(mPhotoV2); // mGxsCore->addService(mPosted); @@ -2390,6 +2407,7 @@ int RsServer::StartupRetroShare() createThread(*photo_ns); createThread(*posted_ns); createThread(*wiki_ns); + createThread(*gxsforums_ns); #endif // now add to p3service @@ -2398,6 +2416,7 @@ int RsServer::StartupRetroShare() pqih->addService(photo_ns); pqih->addService(posted_ns); pqih->addService(wiki_ns); + pqih->addService(gxsforums_ns); #endif // start up gxs core server @@ -2669,10 +2688,11 @@ int RsServer::StartupRetroShare() rsWiki = mWiki; rsPosted = mPosted; rsPhotoV2 = mPhotoV2; + rsGxsForums = mGxsForums; #endif rsWireVEG = mWire; - rsForumsVEG = mForumsV2; + //rsForumsVEG = mForumsV2; #endif // ENABLE_GXS_SERVICES diff --git a/libretroshare/src/serialiser/rsgxsforumitems.cc b/libretroshare/src/serialiser/rsgxsforumitems.cc new file mode 100644 index 000000000..2d0f90430 --- /dev/null +++ b/libretroshare/src/serialiser/rsgxsforumitems.cc @@ -0,0 +1,402 @@ +/* + * libretroshare/src/serialiser: rsgxsforumitems.cc + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include + +#include "rsgxsforumitems.h" +#include "serialiser/rstlvbase.h" +#include "serialiser/rsbaseserial.h" + +#define GXSFORUM_DEBUG 1 + + +uint32_t RsGxsForumSerialiser::size(RsItem *item) +{ + RsGxsForumGroupItem* grp_item = NULL; + RsGxsForumMsgItem* op_item = NULL; + + if((grp_item = dynamic_cast(item)) != NULL) + { + return sizeGxsForumGroupItem(grp_item); + } + else if((op_item = dynamic_cast(item)) != NULL) + { + return sizeGxsForumMsgItem(op_item); + } + std::cerr << "RsGxsForumSerialiser::size() ERROR invalid item" << std::endl; + return 0; +} + +bool RsGxsForumSerialiser::serialise(RsItem *item, void *data, uint32_t *size) +{ + RsGxsForumGroupItem* grp_item = NULL; + RsGxsForumMsgItem* op_item = NULL; + + if((grp_item = dynamic_cast(item)) != NULL) + { + return serialiseGxsForumGroupItem(grp_item, data, size); + } + else if((op_item = dynamic_cast(item)) != NULL) + { + return serialiseGxsForumMsgItem(op_item, data, size); + } + std::cerr << "RsGxsForumSerialiser::serialise() ERROR invalid item" << std::endl; + return false; +} + +RsItem* RsGxsForumSerialiser::deserialise(void* data, uint32_t* size) +{ + +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialise()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_FORUMS != getRsItemService(rstype))) + { + return NULL; /* wrong type */ + } + + switch(getRsItemSubType(rstype)) + { + + case RS_PKT_SUBTYPE_GXSFORUM_GROUP_ITEM: + return deserialiseGxsForumGroupItem(data, size); + break; + case RS_PKT_SUBTYPE_GXSFORUM_MESSAGE_ITEM: + return deserialiseGxsForumMsgItem(data, size); + break; + default: +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialise(): unknown subtype"; + std::cerr << std::endl; +#endif + break; + } + return NULL; +} + + + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + + +void RsGxsForumGroupItem::clear() +{ + mGroup.mDescription.clear(); +} + +std::ostream& RsGxsForumGroupItem::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsGxsForumGroupItem", indent); + uint16_t int_Indent = indent + 2; + + printIndent(out, int_Indent); + out << "Description: " << mGroup.mDescription << std::endl; + + printRsItemEnd(out ,"RsGxsForumGroupItem", indent); + return out; +} + + +uint32_t RsGxsForumSerialiser::sizeGxsForumGroupItem(RsGxsForumGroupItem *item) +{ + + const RsGxsForumGroup& group = item->mGroup; + uint32_t s = 8; // header + + s += GetTlvStringSize(group.mDescription); + + return s; +} + +bool RsGxsForumSerialiser::serialiseGxsForumGroupItem(RsGxsForumGroupItem *item, void *data, uint32_t *size) +{ + +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::serialiseGxsForumGroupItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsForumGroupItem(item); + uint32_t offset = 0; + + if(*size < tlvsize) + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::serialiseGxsForumGroupItem() Size too small" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsForumGroupItem */ + ok &= SetTlvString(data, tlvsize, &offset, 1, item->mGroup.mDescription); + + if(offset != tlvsize) + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::serialiseGxsForumGroupItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef GXSFORUM_DEBUG + if (!ok) + { + std::cerr << "RsGxsForumSerialiser::serialiseGxsForumGroupItem() NOK" << std::endl; + } +#endif + + return ok; + } + +RsGxsForumGroupItem* RsGxsForumSerialiser::deserialiseGxsForumGroupItem(void *data, uint32_t *size) +{ + +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialiseGxsForumGroupItem()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_FORUMS != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_GXSFORUM_GROUP_ITEM != getRsItemSubType(rstype))) + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialiseGxsForumGroupItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialiseGxsForumGroupItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsForumGroupItem* item = new RsGxsForumGroupItem(); + /* skip the header */ + offset += 8; + + ok &= GetTlvString(data, rssize, &offset, 1, item->mGroup.mDescription); + + if (offset != rssize) + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialiseGxsForumGroupItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialiseGxsForumGroupItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + + + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + + +void RsGxsForumMsgItem::clear() +{ + mMsg.mMsg.clear(); +} + +std::ostream& RsGxsForumMsgItem::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsGxsForumMsgItem", indent); + uint16_t int_Indent = indent + 2; + + printIndent(out, int_Indent); + out << "Msg: " << mMsg.mMsg << std::endl; + + printRsItemEnd(out ,"RsGxsForumMsgItem", indent); + return out; +} + + +uint32_t RsGxsForumSerialiser::sizeGxsForumMsgItem(RsGxsForumMsgItem *item) +{ + + const RsGxsForumMsg& msg = item->mMsg; + uint32_t s = 8; // header + + s += 4; // mMsg. + + return s; +} + +bool RsGxsForumSerialiser::serialiseGxsForumMsgItem(RsGxsForumMsgItem *item, void *data, uint32_t *size) +{ + +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::serialiseGxsForumMsgItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsForumMsgItem(item); + uint32_t offset = 0; + + if(*size < tlvsize) + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::serialiseGxsForumMsgItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsForumMsgItem */ + ok &= SetTlvString(data, tlvsize, &offset, 1, item->mMsg.mMsg); + + if(offset != tlvsize) + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::serialiseGxsForumMsgItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef GXSFORUM_DEBUG + if (!ok) + { + std::cerr << "RsGxsForumSerialiser::serialiseGxsForumGroupItem() NOK" << std::endl; + } +#endif + + return ok; + } + +RsGxsForumMsgItem* RsGxsForumSerialiser::deserialiseGxsForumMsgItem(void *data, uint32_t *size) +{ + +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialiseGxsForumMsgItem()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_FORUMS != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_GXSFORUM_MESSAGE_ITEM != getRsItemSubType(rstype))) + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialiseGxsForumMsgItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialiseGxsForumMsgItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsForumMsgItem* item = new RsGxsForumMsgItem(); + /* skip the header */ + offset += 8; + + ok &= GetTlvString(data, rssize, &offset, 1, item->mMsg.mMsg); + + if (offset != rssize) + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialiseGxsForumMsgItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef GXSFORUM_DEBUG + std::cerr << "RsGxsForumSerialiser::deserialiseGxsForumMsgItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + diff --git a/libretroshare/src/serialiser/rsgxsforumitems.h b/libretroshare/src/serialiser/rsgxsforumitems.h new file mode 100644 index 000000000..3729f3a91 --- /dev/null +++ b/libretroshare/src/serialiser/rsgxsforumitems.h @@ -0,0 +1,95 @@ +/* + * libretroshare/src/serialiser: rsgxsforumitems.h + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#ifndef RS_GXS_FORUM_ITEMS_H +#define RS_GXS_FORUM_ITEMS_H + +#include + +#include "serialiser/rsserviceids.h" +#include "serialiser/rsserial.h" +#include "serialiser/rstlvtypes.h" + +#include "rsgxsitems.h" +#include "retroshare/rsgxsforums.h" + +const uint8_t RS_PKT_SUBTYPE_GXSFORUM_GROUP_ITEM = 0x02; +const uint8_t RS_PKT_SUBTYPE_GXSFORUM_MESSAGE_ITEM = 0x03; + +class RsGxsForumGroupItem : public RsGxsGrpItem +{ + +public: + + RsGxsForumGroupItem(): RsGxsGrpItem(RS_SERVICE_GXSV1_TYPE_FORUMS, + RS_PKT_SUBTYPE_GXSFORUM_GROUP_ITEM) { return;} + virtual ~RsGxsForumGroupItem() { return;} + + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + + RsGxsForumGroup mGroup; +}; + +class RsGxsForumMsgItem : public RsGxsMsgItem +{ +public: + + RsGxsForumMsgItem(): RsGxsMsgItem(RS_SERVICE_GXSV1_TYPE_FORUMS, + RS_PKT_SUBTYPE_GXSFORUM_MESSAGE_ITEM) {return; } + virtual ~RsGxsForumMsgItem() { return;} + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + RsGxsForumMsg mMsg; +}; + +class RsGxsForumSerialiser : public RsSerialType +{ +public: + + RsGxsForumSerialiser() + :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXSV1_TYPE_FORUMS) + { return; } + virtual ~RsGxsForumSerialiser() { return; } + + uint32_t size(RsItem *item); + bool serialise (RsItem *item, void *data, uint32_t *size); + RsItem * deserialise(void *data, uint32_t *size); + + private: + + uint32_t sizeGxsForumGroupItem(RsGxsForumGroupItem *item); + bool serialiseGxsForumGroupItem (RsGxsForumGroupItem *item, void *data, uint32_t *size); + RsGxsForumGroupItem * deserialiseGxsForumGroupItem(void *data, uint32_t *size); + + uint32_t sizeGxsForumMsgItem(RsGxsForumMsgItem *item); + bool serialiseGxsForumMsgItem (RsGxsForumMsgItem *item, void *data, uint32_t *size); + RsGxsForumMsgItem * deserialiseGxsForumMsgItem(void *data, uint32_t *size); + +}; + +#endif /* RS_GXS_FORUM_ITEMS_H */ diff --git a/libretroshare/src/serialiser/rsgxsiditems.cc b/libretroshare/src/serialiser/rsgxsiditems.cc index 565569e7c..02e316bec 100644 --- a/libretroshare/src/serialiser/rsgxsiditems.cc +++ b/libretroshare/src/serialiser/rsgxsiditems.cc @@ -50,7 +50,8 @@ uint32_t RsGxsIdSerialiser::size(RsItem *item) { return sizeGxsIdCommentItem(com_item); } - return NULL; + std::cerr << "RsGxsIdSerialiser::size() ERROR invalid item" << std::endl; + return 0; } bool RsGxsIdSerialiser::serialise(RsItem *item, void *data, uint32_t *size) @@ -71,13 +72,14 @@ bool RsGxsIdSerialiser::serialise(RsItem *item, void *data, uint32_t *size) { return serialiseGxsIdCommentItem(com_item, data, size); } + std::cerr << "RsGxsIdSerialiser::serialise() ERROR invalid item" << std::endl; return false; } RsItem* RsGxsIdSerialiser::deserialise(void* data, uint32_t* size) { -#ifdef RSSERIAL_DEBUG +#ifdef GXSID_DEBUG std::cerr << "RsGxsIdSerialiser::deserialise()" << std::endl; #endif /* get the type and size */ @@ -168,7 +170,7 @@ bool RsGxsIdSerialiser::serialiseGxsIdGroupItem(RsGxsIdGroupItem *item, void *da if(*size < tlvsize) { #ifdef GXSID_DEBUG - std::cerr << "RsGxsIdSerialiser::serialiseGxsIdGroupItem()" << std::endl; + std::cerr << "RsGxsIdSerialiser::serialiseGxsIdGroupItem() Size too small" << std::endl; #endif return false; } diff --git a/libretroshare/src/serialiser/rswikiitems.cc b/libretroshare/src/serialiser/rswikiitems.cc index 2d1bcb272..56d20bb6b 100644 --- a/libretroshare/src/serialiser/rswikiitems.cc +++ b/libretroshare/src/serialiser/rswikiitems.cc @@ -77,7 +77,7 @@ bool RsGxsWikiSerialiser::serialise(RsItem *item, void *data, uint32_t *size) RsItem* RsGxsWikiSerialiser::deserialise(void* data, uint32_t* size) { -#ifdef RSSERIAL_DEBUG +#ifdef GXSID_DEBUG std::cerr << "RsGxsWikiSerialiser::deserialise()" << std::endl; #endif /* get the type and size */ diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc new file mode 100644 index 000000000..85e693d9d --- /dev/null +++ b/libretroshare/src/services/p3gxsforums.cc @@ -0,0 +1,369 @@ +/* + * libretroshare/src/services p3gxsforums.cc + * + * GxsForums interface for RetroShare. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "services/p3gxsforums.h" +#include "serialiser/rsgxsforumitems.h" + +#include "util/rsrandom.h" +#include + +/**** + * #define GXSFORUM_DEBUG 1 + ****/ + +RsGxsForums *rsGxsForums = NULL; + + + +/********************************************************************************/ +/******************* Startup / Tick ******************************************/ +/********************************************************************************/ + +p3GxsForums::p3GxsForums(RsGeneralDataService *gds, RsNetworkExchangeService *nes) + : RsGenExchange(gds, nes, new RsGxsForumSerialiser(), RS_SERVICE_GXSV1_TYPE_FORUMS), RsGxsForums(this) +{ +} + +void p3GxsForums::notifyChanges(std::vector &changes) +{ + receiveChanges(changes); +} + +void p3GxsForums::service_tick() +{ + return; +} + +bool p3GxsForums::getGroupData(const uint32_t &token, std::vector &groups) +{ + std::vector grpData; + bool ok = RsGenExchange::getGroupData(token, grpData); + + if(ok) + { + std::vector::iterator vit = grpData.begin(); + + for(; vit != grpData.end(); vit++) + { + RsGxsForumGroupItem* item = dynamic_cast(*vit); + RsGxsForumGroup grp = item->mGroup; + item->mGroup.mMeta = item->meta; + grp.mMeta = item->mGroup.mMeta; + delete item; + groups.push_back(grp); + } + } + return ok; +} + +/* Okay - chris is not going to be happy with this... + * but I can't be bothered with crazy data structures + * at the moment - fix it up later + */ + +bool p3GxsForums::getMsgData(const uint32_t &token, std::vector &msgs) +{ + GxsMsgDataMap msgData; + bool ok = RsGenExchange::getMsgData(token, msgData); + + if(ok) + { + GxsMsgDataMap::iterator mit = msgData.begin(); + + for(; mit != msgData.end(); mit++) + { + RsGxsGroupId grpId = mit->first; + std::vector& msgItems = mit->second; + std::vector::iterator vit = msgItems.begin(); + + for(; vit != msgItems.end(); vit++) + { + RsGxsForumMsgItem* item = dynamic_cast(*vit); + + if(item) + { + RsGxsForumMsg msg = item->mMsg; + msg.mMeta = item->meta; + msgs.push_back(msg); + delete item; + } + else + { + std::cerr << "Not a GxsForumMsgItem, deleting!" << std::endl; + delete *vit; + } + } + } + } + + return ok; +} + +/********************************************************************************************/ + +bool p3GxsForums::createGroup(uint32_t &token, RsGxsForumGroup &group) +{ + std::cerr << "p3GxsForums::createGroup()" << std::endl; + + RsGxsForumGroupItem* grpItem = new RsGxsForumGroupItem(); + grpItem->mGroup = group; + grpItem->meta = group.mMeta; + + RsGenExchange::publishGroup(token, grpItem); + return true; +} + + +bool p3GxsForums::createMsg(uint32_t &token, RsGxsForumMsg &msg) +{ + std::cerr << "p3GxsForums::createForumMsg() GroupId: " << msg.mMeta.mGroupId; + std::cerr << std::endl; + + RsGxsForumMsgItem* msgItem = new RsGxsForumMsgItem(); + msgItem->mMsg = msg; + msgItem->meta = msg.mMeta; + + RsGenExchange::publishMsg(token, msgItem); + return true; +} + + +/********************************************************************************************/ + + +std::string p3GxsForums::genRandomId() +{ + std::string randomId; + for(int i = 0; i < 20; i++) + { + randomId += (char) ('a' + (RSRandom::random_u32() % 26)); + } + + return randomId; +} + +bool p3GxsForums::generateDummyData() +{ + return false; +} + + +#if 0 + +bool p3GxsForums::generateDummyData() +{ + /* so we want to generate 100's of forums */ +#define MAX_FORUMS 10 //100 +#define MAX_THREADS 10 //1000 +#define MAX_MSGS 100 //10000 + + std::list mGroups; + std::list::iterator git; + + std::list mMsgs; + std::list::iterator mit; + +#define DUMMY_NAME_MAX_LEN 10000 + char name[DUMMY_NAME_MAX_LEN]; + int i, j; + time_t now = time(NULL); + + for(i = 0; i < MAX_FORUMS; i++) + { + /* generate a new forum */ + RsForumV2Group forum; + + /* generate a temp id */ + forum.mMeta.mGroupId = genRandomId(); + + snprintf(name, DUMMY_NAME_MAX_LEN, "TestForum_%d", i+1); + + forum.mMeta.mGroupId = genRandomId(); + forum.mMeta.mGroupName = name; + + forum.mMeta.mPublishTs = now - (RSRandom::random_f32() * 100000); + /* key fields to fill in: + * GroupId. + * Name. + * Flags. + * Pop. + */ + + + + /* use probability to decide which are subscribed / own / popularity. + */ + + float rnd = RSRandom::random_f32(); + if (rnd < 0.1) + { + forum.mMeta.mSubscribeFlags = RSGXS_GROUP_SUBSCRIBE_ADMIN; + + } + else if (rnd < 0.3) + { + forum.mMeta.mSubscribeFlags = RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED; + } + else + { + forum.mMeta.mSubscribeFlags = 0; + } + + forum.mMeta.mPop = (int) (RSRandom::random_f32() * 10.0); + + mGroups.push_back(forum); + + + //std::cerr << "p3GxsForums::generateDummyData() Generated Forum: " << forum.mMeta; + //std::cerr << std::endl; + } + + + for(i = 0; i < MAX_THREADS; i++) + { + /* generate a base thread */ + + /* rotate the Forum Groups Around, then pick one. + */ + + int rnd = (int) (RSRandom::random_f32() * 10.0); + + for(j = 0; j < rnd; j++) + { + RsForumV2Group head = mGroups.front(); + mGroups.pop_front(); + mGroups.push_back(head); + } + + RsForumV2Group forum = mGroups.front(); + + /* now create a new thread */ + + RsForumV2Msg msg; + + /* fill in key data + * GroupId + * MsgId + * OrigMsgId + * ThreadId + * ParentId + * PublishTS (take Forum TS + a bit ). + * + * ChildTS ???? + */ + snprintf(name, DUMMY_NAME_MAX_LEN, "%s => ThreadMsg_%d", forum.mMeta.mGroupName.c_str(), i+1); + msg.mMeta.mMsgName = name; + + msg.mMeta.mGroupId = forum.mMeta.mGroupId; + msg.mMeta.mMsgId = genRandomId(); + msg.mMeta.mOrigMsgId = msg.mMeta.mMsgId; + msg.mMeta.mThreadId = msg.mMeta.mMsgId; + msg.mMeta.mParentId = ""; + + msg.mMeta.mPublishTs = forum.mMeta.mPublishTs + (RSRandom::random_f32() * 10000); + if (msg.mMeta.mPublishTs > now) + msg.mMeta.mPublishTs = now - 1; + + mMsgs.push_back(msg); + + //std::cerr << "p3GxsForums::generateDummyData() Generated Thread: " << msg.mMeta; + //std::cerr << std::endl; + + } + + for(i = 0; i < MAX_MSGS; i++) + { + /* generate a base thread */ + + /* rotate the Forum Groups Around, then pick one. + */ + + int rnd = (int) (RSRandom::random_f32() * 10.0); + + for(j = 0; j < rnd; j++) + { + RsForumV2Msg head = mMsgs.front(); + mMsgs.pop_front(); + mMsgs.push_back(head); + } + + RsForumV2Msg parent = mMsgs.front(); + + /* now create a new child msg */ + + RsForumV2Msg msg; + + /* fill in key data + * GroupId + * MsgId + * OrigMsgId + * ThreadId + * ParentId + * PublishTS (take Forum TS + a bit ). + * + * ChildTS ???? + */ + snprintf(name, DUMMY_NAME_MAX_LEN, "%s => Msg_%d", parent.mMeta.mMsgName.c_str(), i+1); + msg.mMeta.mMsgName = name; + msg.mMsg = name; + + msg.mMeta.mGroupId = parent.mMeta.mGroupId; + msg.mMeta.mMsgId = genRandomId(); + msg.mMeta.mOrigMsgId = msg.mMeta.mMsgId; + msg.mMeta.mThreadId = parent.mMeta.mThreadId; + msg.mMeta.mParentId = parent.mMeta.mOrigMsgId; + + msg.mMeta.mPublishTs = parent.mMeta.mPublishTs + (RSRandom::random_f32() * 10000); + if (msg.mMeta.mPublishTs > now) + msg.mMeta.mPublishTs = now - 1; + + mMsgs.push_back(msg); + + //std::cerr << "p3GxsForums::generateDummyData() Generated Child Msg: " << msg.mMeta; + //std::cerr << std::endl; + + } + + + mUpdated = true; + + /* Then - at the end, we push them all into the Proxy */ + for(git = mGroups.begin(); git != mGroups.end(); git++) + { + /* pushback */ + mForumProxy->addForumGroup(*git); + + } + + for(mit = mMsgs.begin(); mit != mMsgs.end(); mit++) + { + /* pushback */ + mForumProxy->addForumMsg(*mit); + } + + return true; +} + +#endif diff --git a/libretroshare/src/services/p3gxsforums.h b/libretroshare/src/services/p3gxsforums.h new file mode 100644 index 000000000..db765c980 --- /dev/null +++ b/libretroshare/src/services/p3gxsforums.h @@ -0,0 +1,73 @@ +/* + * libretroshare/src/services: p3gxsforums.h + * + * GxsForum interface for RetroShare. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#ifndef P3_GXSFORUMS_SERVICE_HEADER +#define P3_GXSFORUMS_SERVICE_HEADER + + +#include "retroshare/rsgxsforums.h" +#include "gxs/rsgenexchange.h" + +#include +#include + +/* + * + */ + +class p3GxsForums: public RsGenExchange, public RsGxsForums +{ + public: + + p3GxsForums(RsGeneralDataService* gds, RsNetworkExchangeService* nes); + + protected: + +virtual void notifyChanges(std::vector& changes); +virtual void service_tick(); + + public: + +virtual bool getGroupData(const uint32_t &token, std::vector &groups); +virtual bool getMsgData(const uint32_t &token, std::vector &msgs); + + ////////////////////////////////////////////////////////////////////////////// +//virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask); +//virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask); + +//virtual bool groupRestoreKeys(const std::string &groupId); +//virtual bool groupShareKeys(const std::string &groupId, std::list& peers); + +virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group); +virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg); + + private: + +std::string genRandomId(); +bool generateDummyData(); + +}; + +#endif diff --git a/libretroshare/src/services/p3wiki.cc b/libretroshare/src/services/p3wiki.cc index d84cf0f98..da98038b0 100644 --- a/libretroshare/src/services/p3wiki.cc +++ b/libretroshare/src/services/p3wiki.cc @@ -26,6 +26,8 @@ #include "services/p3wiki.h" #include "serialiser/rswikiitems.h" +#include "util/rsrandom.h" + /**** * #define WIKI_DEBUG 1 ****/ @@ -48,12 +50,18 @@ void p3Wiki::service_tick() void p3Wiki::notifyChanges(std::vector& changes) { + std::cerr << "p3Wiki::notifyChanges() New stuff"; + std::cerr << std::endl; + receiveChanges(changes); } /* Specific Service Data */ bool p3Wiki::getCollections(const uint32_t &token, std::vector &collections) { + std::cerr << "p3Wiki::getCollections()"; + std::cerr << std::endl; + std::vector grpData; bool ok = RsGenExchange::getGroupData(token, grpData); @@ -64,10 +72,25 @@ bool p3Wiki::getCollections(const uint32_t &token, std::vector for(; vit != grpData.end(); vit++) { RsGxsWikiCollectionItem* item = dynamic_cast(*vit); - RsWikiCollection collection = item->collection; - collection.mMeta = item->collection.mMeta; - delete item; - collections.push_back(collection); + + if (item) + { + RsWikiCollection collection = item->collection; + collection.mMeta = item->meta; + delete item; + collections.push_back(collection); + + std::cerr << "p3Wiki::getCollections() Adding Collection to Vector: "; + std::cerr << std::endl; + std::cerr << collection; + std::cerr << std::endl; + } + else + { + std::cerr << "Not a WikiCollectionItem, deleting!" << std::endl; + delete *vit; + } + } } return ok; @@ -159,6 +182,15 @@ bool p3Wiki::submitCollection(uint32_t &token, RsWikiCollection &collection) RsGxsWikiCollectionItem* collectionItem = new RsGxsWikiCollectionItem(); collectionItem->collection = collection; collectionItem->meta = collection.mMeta; + + std::cerr << "p3Wiki::submitCollection(): "; + std::cerr << std::endl; + std::cerr << collection; + std::cerr << std::endl; + + std::cerr << "p3Wiki::submitCollection() pushing to RsGenExchange"; + std::cerr << std::endl; + RsGenExchange::publishGroup(token, collectionItem); return true; } @@ -188,3 +220,64 @@ bool p3Wiki::submitComment(uint32_t &token, RsWikiComment &comment) } + +std::ostream &operator<<(std::ostream &out, const RsWikiCollection &group) +{ + out << "RsWikiCollection [ "; + out << " Name: " << group.mMeta.mGroupName; + out << " Desc: " << group.mDescription; + out << " Category: " << group.mCategory; + out << " ]"; + return out; +} + +std::ostream &operator<<(std::ostream &out, const RsWikiSnapshot &shot) +{ + out << "RsWikiSnapshot [ "; + out << "Title: " << shot.mMeta.mMsgName; + out << "]"; + return out; +} + +std::ostream &operator<<(std::ostream &out, const RsWikiComment &comment) +{ + out << "RsWikiComment [ "; + out << "Title: " << comment.mMeta.mMsgName; + out << "]"; + return out; +} + + +/***** FOR TESTING *****/ + +std::string p3Wiki::genRandomId() +{ + std::string randomId; + for(int i = 0; i < 20; i++) + { + randomId += (char) ('a' + (RSRandom::random_u32() % 26)); + } + + return randomId; +} + +void p3Wiki::generateDummyData() +{ + +#define GEN_COLLECTIONS 10 + + int i; + for(i = 0; i < GEN_COLLECTIONS; i++) + { + RsWikiCollection wiki; + wiki.mMeta.mGroupId = genRandomId(); + wiki.mMeta.mGroupFlags = 0; + wiki.mMeta.mGroupName = genRandomId(); + + uint32_t dummyToken = 0; + submitCollection(dummyToken, wiki); + } +} + + + diff --git a/libretroshare/src/services/p3wiki.h b/libretroshare/src/services/p3wiki.h index 7a8f74b2a..11e347cf1 100644 --- a/libretroshare/src/services/p3wiki.h +++ b/libretroshare/src/services/p3wiki.h @@ -60,9 +60,11 @@ virtual bool submitCollection(uint32_t &token, RsWikiCollection &collection); virtual bool submitSnapshot(uint32_t &token, RsWikiSnapshot &snapshot); virtual bool submitComment(uint32_t &token, RsWikiComment &comment); +virtual void generateDummyData(); + private: -//std::string genRandomId(); +std::string genRandomId(); // RsMutex mWikiMtx; From c9831b7bea6d539fa27b5396961dfe6c589957d9 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sat, 10 Nov 2012 23:42:38 +0000 Subject: [PATCH 139/222] Added message validation, not enabled at the moment as msg sync seems to have stopped working. will fix (qos priority change?). Added validated field to msg meta Removed serviceString from msg transport. Added grp flag setting to album create to test msg validation git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5800 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/gxssecurity.cc | 144 +++++----- libretroshare/src/gxs/gxssecurity.h | 2 +- libretroshare/src/gxs/rsgenexchange.cc | 255 +++++++++++++++++- libretroshare/src/gxs/rsgenexchange.h | 37 ++- libretroshare/src/gxs/rsgixs.h | 3 - libretroshare/src/gxs/rsgxsdata.cc | 3 - libretroshare/src/gxs/rsgxsdata.h | 1 + libretroshare/src/gxs/rsgxsflags.h | 27 +- libretroshare/src/gxs/rsgxsnetservice.cc | 4 +- libretroshare/src/rsserver/rsinit.cc | 19 +- .../src/services/p3photoserviceV2.cc | 6 +- libretroshare/src/services/p3photoserviceV2.h | 3 +- .../src/gui/PhotoShare/AlbumCreateDialog.cpp | 21 ++ .../src/gui/PhotoShare/AlbumCreateDialog.ui | 9 +- 14 files changed, 427 insertions(+), 107 deletions(-) diff --git a/libretroshare/src/gxs/gxssecurity.cc b/libretroshare/src/gxs/gxssecurity.cc index 35c5ba796..f0e4b9be7 100644 --- a/libretroshare/src/gxs/gxssecurity.cc +++ b/libretroshare/src/gxs/gxssecurity.cc @@ -74,90 +74,102 @@ bool GxsSecurity::getSignature(char* data, uint32_t data_len, RsTlvSecurityKey* return ok; } -bool GxsSecurity::validateNxsMsg(RsNxsMsg *msg, RsTlvKeySignature& sign, RsTlvSecurityKeySet& key) +bool GxsSecurity::validateNxsMsg(RsNxsMsg& msg, RsTlvKeySignature& sign, RsTlvSecurityKey& key) { - //#ifdef GXS_SECURITY_DEBUG - // std::cerr << "GxsSecurity::validateNxsMsg()"; - // std::cerr << std::endl; - // std::cerr << "RsNxsMsg :"; - // std::cerr << std::endl; - // msg->print(std::cerr, 10); - // std::cerr << std::endl; - //#endif + #ifdef GXS_SECURITY_DEBUG + std::cerr << "GxsSecurity::validateNxsMsg()"; + std::cerr << std::endl; + std::cerr << "RsNxsMsg :"; + std::cerr << std::endl; + msg.print(std::cerr, 10); + std::cerr << std::endl; + #endif + RsGxsMsgMetaData& msgMeta = *(msg.metaData); // /********************* check signature *******************/ - // /* check signature timeperiod */ - // if ((newMsg->timestamp < kit->second.startTS) || - // (newMsg->timestamp > kit->second.endTS)) - // { - //#ifdef DISTRIB_DEBUG - // std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() TS out of range"; - // std::cerr << std::endl; - //#endif - // return false; - // } + /* check signature timeperiod */ + if ((msgMeta.mPublishTs < key.startTS) || + (msgMeta.mPublishTs > key.endTS)) + { + #ifdef GXS_SECURITY_DEBUG + std::cerr << " GxsSecurity::validateNxsMsg() TS out of range"; + std::cerr << std::endl; + #endif + return false; + } - // /* decode key */ - // const unsigned char *keyptr = (const unsigned char *) kit->second.keyData.bin_data; - // long keylen = kit->second.keyData.bin_len; - // unsigned int siglen = newMsg->publishSignature.signData.bin_len; - // unsigned char *sigbuf = (unsigned char *) newMsg->publishSignature.signData.bin_data; + /* decode key */ + const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data; + long keylen = key.keyData.bin_len; + unsigned int siglen = sign.signData.bin_len; + unsigned char *sigbuf = (unsigned char *) sign.signData.bin_data; - //#ifdef DISTRIB_DEBUG - // std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Decode Key"; - // std::cerr << " keylen: " << keylen << " siglen: " << siglen; - // std::cerr << std::endl; - //#endif + #ifdef DISTRIB_DEBUG + std::cerr << "GxsSecurity::validateNxsMsg() Decode Key"; + std::cerr << " keylen: " << keylen << " siglen: " << siglen; + std::cerr << std::endl; + #endif - // /* extract admin key */ - // RSA *rsakey = d2i_RSAPublicKey(NULL, &(keyptr), keylen); + /* extract admin key */ + RSA *rsakey = d2i_RSAPublicKey(NULL, &(keyptr), keylen); - // if (!rsakey) - // { - //#ifdef DISTRIB_DEBUG - // std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg()"; - // std::cerr << " Invalid RSA Key"; - // std::cerr << std::endl; + if (!rsakey) + { + #ifdef GXS_SECURITY_DEBUG + std::cerr << "GxsSecurity::validateNxsMsg()"; + std::cerr << " Invalid RSA Key"; + std::cerr << std::endl; - // unsigned long err = ERR_get_error(); - // std::cerr << "RSA Load Failed .... CODE(" << err << ")" << std::endl; - // std::cerr << ERR_error_string(err, NULL) << std::endl; - - // kit->second.print(std::cerr, 10); - //#endif - // } + key.print(std::cerr, 10); + #endif + } - // EVP_PKEY *signKey = EVP_PKEY_new(); - // EVP_PKEY_assign_RSA(signKey, rsakey); + RsTlvKeySignatureSet signSet = msgMeta.signSet; + msgMeta.signSet.TlvClear(); - // /* calc and check signature */ - // EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); + uint32_t metaDataLen = msgMeta.serial_size(); + uint32_t allMsgDataLen = metaDataLen + msg.msg.bin_len; + char* metaData = new char[metaDataLen]; + char* allMsgData = new char[allMsgDataLen]; // msgData + metaData - // EVP_VerifyInit(mdctx, EVP_sha1()); - // EVP_VerifyUpdate(mdctx, newMsg->packet.bin_data, newMsg->packet.bin_len); - // int signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey); + msgMeta.serialise(metaData, &metaDataLen); - // /* clean up */ - // EVP_PKEY_free(signKey); - // EVP_MD_CTX_destroy(mdctx); + // copy msg data and meta in allmsgData buffer + memcpy(allMsgData, msg.msg.bin_data, msg.msg.bin_len); + memcpy(allMsgData+(msg.msg.bin_len), metaData, metaDataLen); - // if (signOk == 1) - // { - //#ifdef GXS_SECURITY_DEBUG - // std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Signature OK"; - // std::cerr << std::endl; - //#endif - // return true; - // } + EVP_PKEY *signKey = EVP_PKEY_new(); + EVP_PKEY_assign_RSA(signKey, rsakey); - //#ifdef DISTRIB_DEBUG - // std::cerr << "p3GroupDistrib::locked_validateDistribSignedMsg() Signature invalid"; - // std::cerr << std::endl; - //#endif + /* calc and check signature */ + EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); + + EVP_VerifyInit(mdctx, EVP_sha1()); + EVP_VerifyUpdate(mdctx, allMsgData, allMsgDataLen); + int signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey); + + /* clean up */ + EVP_PKEY_free(signKey); + EVP_MD_CTX_destroy(mdctx); + + + if (signOk == 1) + { + #ifdef GXS_SECURITY_DEBUG + std::cerr << "GxsSecurity::validateNxsMsg() Signature OK"; + std::cerr << std::endl; + #endif + return true; + } + + #ifdef GXS_SECURITY_DEBUG + std::cerr << "GxsSecurity::validateNxsMsg() Signature invalid"; + std::cerr << std::endl; + #endif return false; } diff --git a/libretroshare/src/gxs/gxssecurity.h b/libretroshare/src/gxs/gxssecurity.h index 826072e6a..889006017 100644 --- a/libretroshare/src/gxs/gxssecurity.h +++ b/libretroshare/src/gxs/gxssecurity.h @@ -129,7 +129,7 @@ public: * @param key the public key to use to check signature * @return false if verfication of signature is not passed */ - static bool validateNxsMsg(RsNxsMsg *msg, RsTlvKeySignature& sign, RsTlvSecurityKeySet& key); + static bool validateNxsMsg(RsNxsMsg& msg, RsTlvKeySignature& sign, RsTlvSecurityKey& key); /*! diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 54ca3a115..4e04d7788 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -34,10 +34,23 @@ #include "gxssecurity.h" #include "util/contentvalue.h" #include "rsgxsflags.h" +#include "rsgixs.h" -RsGenExchange::RsGenExchange(RsGeneralDataService *gds, - RsNetworkExchangeService *ns, RsSerialType *serviceSerialiser, uint16_t servType, RsGixs* gixs) -: mGenMtx("GenExchange"), mDataStore(gds), mNetService(ns), mSerialiser(serviceSerialiser), mServType(servType), mGixs(gixs) + +#define PUB_GRP_MASK 0x000f +#define RESTR_GRP_MASK 0x00f0 +#define PRIV_GRP_MASK 0x0f00 +#define GRP_OPTIONS_MASK 0xf000 + +#define PUB_GRP_OFFSET 0 +#define RESTR_GRP_OFFSET 8 +#define PRIV_GRP_OFFSET 16 +#define GRP_OPTIONS_OFFSET 24 + +RsGenExchange::RsGenExchange(RsGeneralDataService *gds, RsNetworkExchangeService *ns, + RsSerialType *serviceSerialiser, uint16_t servType, RsGixs* gixs, uint32_t authenPolicy) +: mGenMtx("GenExchange"), mDataStore(gds), mNetService(ns), mSerialiser(serviceSerialiser), + mServType(servType), mGixs(gixs), mAuthenPolicy(authenPolicy) { mDataAccess = new RsGxsDataAccess(gds); @@ -60,7 +73,7 @@ RsGenExchange::~RsGenExchange() void RsGenExchange::run() { - double timeDelta = 0.06; // slow tick + double timeDelta = 0.1; // slow tick while(true) { @@ -145,7 +158,7 @@ void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet) { /* create Keys */ - // admin keys + // admin keys RSA *rsa_admin = RSA_generate_key(2048, 65537, NULL, NULL); RSA *rsa_admin_pub = RSAPublicKey_dup(rsa_admin); @@ -168,13 +181,13 @@ void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet) adminKey.startTS = time(NULL); adminKey.endTS = 0; /* no end */ - privAdminKey.startTS = time(NULL); + privAdminKey.startTS = adminKey.startTS; privAdminKey.endTS = 0; /* no end */ - pubKey.startTS = time(NULL); - pubKey.endTS = 0; /* no end */ + pubKey.startTS = adminKey.startTS; + pubKey.endTS = pubKey.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */ - privPubKey.startTS = time(NULL); + privPubKey.startTS = adminKey.startTS; privPubKey.endTS = 0; /* no end */ // for now all public @@ -354,6 +367,160 @@ bool RsGenExchange::createMessage(RsNxsMsg* msg) return ok; } +bool RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSecurityKeySet& grpKeySet) +{ + bool isParent = false; + bool checkPublishSign, checkIdentitySign; + bool valid = true; + + // publish signature is determined by whether group is public or not + // for private group signature is not needed as it needs decrypting with + // the private publish key anyways + + // restricted is a special case which heeds whether publish sign needs to be checked or not + // one may or may not want + + if(msg->metaData->mParentId.empty()) + { + isParent = false; + } + else + { + isParent = true; + } + + + if(isParent) + { + checkIdentitySign = false; + checkPublishSign = false; + + if(grpFlag & GXS_SERV::FLAG_PRIVACY_PUBLIC) + { + checkPublishSign = false; + + if(checkMsgAuthenFlag(PUBLIC_GRP_BITS, GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN)) + checkIdentitySign = true; + + } + else if(grpFlag & GXS_SERV::FLAG_PRIVACY_RESTRICTED) + { + checkPublishSign = true; + + if(checkMsgAuthenFlag(RESTRICTED_GRP_BITS, GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN)) + checkIdentitySign = true; + } + else if(grpFlag & GXS_SERV::FLAG_PRIVACY_PRIVATE) + { + checkPublishSign = false; + + if(checkMsgAuthenFlag(PRIVATE_GRP_BITS, GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN)) + checkIdentitySign = true; + } + + }else + { + if(grpFlag & GXS_SERV::FLAG_PRIVACY_PUBLIC) + { + checkPublishSign = false; + + if(checkMsgAuthenFlag(PUBLIC_GRP_BITS, GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN)) + checkIdentitySign = true; + + } + else if(grpFlag & GXS_SERV::FLAG_PRIVACY_RESTRICTED) + { + if(checkMsgAuthenFlag(RESTRICTED_GRP_BITS, GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN)) + checkPublishSign = true; + + if(checkMsgAuthenFlag(RESTRICTED_GRP_BITS, GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN)) + checkIdentitySign = true; + } + else if(grpFlag & GXS_SERV::FLAG_PRIVACY_PRIVATE) + { + checkPublishSign = false; + + if(checkMsgAuthenFlag(PRIVATE_GRP_BITS, GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN)) + checkIdentitySign = true; + } + } + + RsGxsMsgMetaData& metaData = *(msg->metaData); + + if(checkPublishSign) + { + RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH]; + + if(grpKeySet.keys.find(sign.keyId) != grpKeySet.keys.end()) + { + RsTlvSecurityKey publishKey = grpKeySet.keys[sign.keyId]; + valid &= GxsSecurity::validateNxsMsg(*msg, sign, publishKey); + } + else + { + valid = false; + } + + } + + + if(checkIdentitySign) + { + bool haveKey = mGixs->haveKey(metaData.mAuthorId); + + if(haveKey) + { + std::list peers; + mGixs->requestKey(metaData.mAuthorId, peers); + + RsTlvSecurityKey authorKey; + + double timeDelta = 0.002; // fast polling + time_t now = time(NULL); + // poll immediately but, don't spend more than a second polling + while( (mGixs->getKey(metaData.mAuthorId, authorKey) == -1) && + ((now + 1) >> time(NULL)) + ) + { +#ifndef WINDOWS_SYS + usleep((int) (timeDelta * 1000000)); +#else + Sleep((int) (timeDelta * 1000)); +#endif + } + + RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH]; + valid &= GxsSecurity::validateNxsMsg(*msg, sign, authorKey); + }else + { + valid = false; + } + } + + return valid; +} + +bool RsGenExchange::checkMsgAuthenFlag(const PrivacyBitPos& pos, const uint8_t& flag) const +{ + switch(pos) + { + case PUBLIC_GRP_BITS: + return mAuthenPolicy & flag; + break; + case RESTRICTED_GRP_BITS: + return flag & (mAuthenPolicy >> RESTR_GRP_OFFSET); + break; + case PRIVATE_GRP_BITS: + return flag & (mAuthenPolicy >> PRIV_GRP_OFFSET); + break; + case GRP_OPTION_BITS: + return flag & (mAuthenPolicy >> GRP_OPTIONS_OFFSET); + break; + default: + std::cerr << "pos option not recognised"; + return false; + } +} bool RsGenExchange::getGroupList(const uint32_t &token, std::list &groupIds) { @@ -494,6 +661,36 @@ RsTokenService* RsGenExchange::getTokenService() } +bool RsGenExchange::setAuthenPolicyFlag(const uint8_t &msgFlag, uint32_t& authenFlag, const PrivacyBitPos &pos) +{ + uint32_t temp = 0; + temp = msgFlag; + + switch(pos) + { + case PUBLIC_GRP_BITS: + authenFlag &= ~PUB_GRP_MASK; + authenFlag |= temp; + break; + case RESTRICTED_GRP_BITS: + authenFlag &= ~RESTR_GRP_MASK; + authenFlag |= (temp << RESTR_GRP_OFFSET); + break; + case PRIVATE_GRP_BITS: + authenFlag &= ~PRIV_GRP_MASK; + authenFlag |= (temp << PRIV_GRP_OFFSET); + break; + case GRP_OPTION_BITS: + authenFlag &= ~GRP_OPTIONS_MASK; + authenFlag |= (temp << GRP_OPTIONS_OFFSET); + break; + default: + std::cerr << "pos option not recognised"; + return false; + } + return true; +} + void RsGenExchange::notifyNewGroups(std::vector &groups) { std::vector::iterator vit = groups.begin(); @@ -953,7 +1150,18 @@ void RsGenExchange::processRecvdMessages() GxsMsgReq msgIds; std::map msgs; + std::map grpMetas; + + // coalesce group meta retrieval for performance for(; vit != mReceivedMsgs.end(); vit++) + { + RsNxsMsg* msg = *vit; + grpMetas.insert(std::make_pair(msg->grpId, (RsGxsGrpMetaData*)NULL)); + } + + mDataStore->retrieveGxsGrpMetaData(grpMetas); + + for(vit = mReceivedMsgs.begin(); vit != mReceivedMsgs.end(); vit++) { RsNxsMsg* msg = *vit; RsGxsMsgMetaData* meta = new RsGxsMsgMetaData(); @@ -961,10 +1169,25 @@ void RsGenExchange::processRecvdMessages() if(ok) { - msgs.insert(std::make_pair(msg, meta)); - msgIds[msg->grpId].push_back(msg->msgId); + std::map::iterator mit = grpMetas.find(msg->grpId); + + // validate msg + if(mit != grpMetas.end()){ + RsGxsGrpMetaData* grpMeta = mit->second; + ok = true; + //&= validateMsg(msg, grpMeta->mGroupFlags, grpMeta->keys); + } + else + ok = false; + + if(ok) + { + msgs.insert(std::make_pair(msg, meta)); + msgIds[msg->grpId].push_back(msg->msgId); + } } - else + + if(!ok) { #ifdef GXS_GENX_DEBUG std::cerr << "failed to deserialise incoming meta, grpId: " @@ -975,6 +1198,14 @@ void RsGenExchange::processRecvdMessages() } } + std::map::iterator mit = grpMetas.begin(); + + // clean up resources + for(; mit != grpMetas.end(); mit++) + { + delete mit->second; + } + if(!msgIds.empty()) { mDataStore->storeMessage(msgs); diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index fe18fc74d..232deab1b 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -41,7 +41,6 @@ typedef std::map > GxsMsgDataMap; typedef std::map GxsGroupDataMap; typedef std::map > GxsMsgMetaMap; - /*! * This should form the parent class to \n * all gxs services. This provides access to service's msg/grp data \n @@ -76,10 +75,12 @@ public: * @param serviceSerialiser The users service needs this \n * in order for gen exchange to deal with its data types * @param mServType This should be service type used by the serialiser - * @param This is used for verification of msgs and groups received by Gen Exchange using identities, set to NULL if \n + * @param gixs This is used for verification of msgs and groups received by Gen Exchange using identities, set to NULL if \n * identity verification is not wanted + * @param authenPolicy This determines the authentication used for verfying authorship of msgs and groups */ - RsGenExchange(RsGeneralDataService* gds, RsNetworkExchangeService* ns, RsSerialType* serviceSerialiser, uint16_t mServType, RsGixs* gixs = NULL); + RsGenExchange(RsGeneralDataService* gds, RsNetworkExchangeService* ns, + RsSerialType* serviceSerialiser, uint16_t mServType, RsGixs* gixs = NULL, uint32_t authenPolicy = 0); virtual ~RsGenExchange(); @@ -119,6 +120,21 @@ public: void run(); + /*! + * Policy bit pattern portion + */ + enum PrivacyBitPos { PUBLIC_GRP_BITS, RESTRICTED_GRP_BITS, PRIVATE_GRP_BITS, GRP_OPTION_BITS } ; + + /*! + * Convenience function for setting bit patterns of the individual privacy level authentication + * policy and group options + * @param flag the bit pattern (and policy) set for the privacy policy + * @param authenFlag Only the policy portion chosen will be modified with 'flag' + * @param pos The policy portion to modify + * @see PrivacyBitPos + */ + static bool setAuthenPolicyFlag(const uint8_t& flag, uint32_t& authenFlag, const PrivacyBitPos& pos); + public: /** data access functions **/ @@ -382,7 +398,6 @@ private: */ bool createMessage(RsNxsMsg* msg); - /*! * check meta change is legal * @return false if meta change is not legal @@ -395,6 +410,17 @@ private: */ void generateGroupKeys(RsTlvSecurityKeySet& keySet); + /*! + * Attempts to validate msg + * @param msg message to be validated + * @param grpFlag the flag for the group the message belongs to + * @param grpKeySet + * @return true if msg validates, false otherwise + */ + bool validateMsg(RsNxsMsg* msg, const uint32_t& grpFlag, RsTlvSecurityKeySet& grpKeySet); + + bool checkMsgAuthenFlag(const PrivacyBitPos& pos, const uint8_t& flag) const; + private: RsMutex mGenMtx; @@ -422,6 +448,9 @@ private: /// service type uint16_t mServType; + /// authentication policy + uint32_t mAuthenPolicy; + private: diff --git a/libretroshare/src/gxs/rsgixs.h b/libretroshare/src/gxs/rsgixs.h index 4c01d5b96..b7f37768d 100644 --- a/libretroshare/src/gxs/rsgixs.h +++ b/libretroshare/src/gxs/rsgixs.h @@ -31,9 +31,6 @@ #include "serialiser/rstlvkeys.h" -//#include -//#include - /*! * GIXP: General Identity Exchange Service. * diff --git a/libretroshare/src/gxs/rsgxsdata.cc b/libretroshare/src/gxs/rsgxsdata.cc index d77ad1dbd..3e5ee08fa 100644 --- a/libretroshare/src/gxs/rsgxsdata.cc +++ b/libretroshare/src/gxs/rsgxsdata.cc @@ -149,7 +149,6 @@ uint32_t RsGxsMsgMetaData::serial_size() s += GetTlvStringSize(mParentId); s += GetTlvStringSize(mOrigMsgId); s += GetTlvStringSize(mAuthorId); - s += GetTlvStringSize(mServiceString); s += signSet.TlvSize(); s += GetTlvStringSize(mMsgName); @@ -206,7 +205,6 @@ bool RsGxsMsgMetaData::serialise(void *data, uint32_t *size) ok &= SetTlvString(data, *size, &offset, 0, mParentId); ok &= SetTlvString(data, *size, &offset, 0, mOrigMsgId); ok &= SetTlvString(data, *size, &offset, 0, mAuthorId); - ok &= SetTlvString(data, *size, &offset, 0, mServiceString); ok &= signSet.SetTlv(data, *size, &offset); ok &= SetTlvString(data, *size, &offset, 0, mMsgName); @@ -234,7 +232,6 @@ bool RsGxsMsgMetaData::deserialise(void *data, uint32_t *size) ok &= GetTlvString(data, *size, &offset, 0, mParentId); ok &= GetTlvString(data, *size, &offset, 0, mOrigMsgId); ok &= GetTlvString(data, *size, &offset, 0, mAuthorId); - ok &= GetTlvString(data, *size, &offset, 0, mServiceString); ok &= signSet.GetTlv(data, *size, &offset); ok &= GetTlvString(data, *size, &offset, 0, mMsgName); diff --git a/libretroshare/src/gxs/rsgxsdata.h b/libretroshare/src/gxs/rsgxsdata.h index 78dd3c8e4..88d4044f1 100644 --- a/libretroshare/src/gxs/rsgxsdata.h +++ b/libretroshare/src/gxs/rsgxsdata.h @@ -112,6 +112,7 @@ public: uint32_t mMsgStatus; time_t mChildTs; + bool validated; }; diff --git a/libretroshare/src/gxs/rsgxsflags.h b/libretroshare/src/gxs/rsgxsflags.h index c769b06cc..ba352171b 100644 --- a/libretroshare/src/gxs/rsgxsflags.h +++ b/libretroshare/src/gxs/rsgxsflags.h @@ -51,16 +51,35 @@ namespace GXS_SERV { /** END authentication **/ + /** START msg authentication flags **/ + + static const uint8_t MSG_AUTHEN_MASK = 0x0f; + + static const uint8_t MSG_AUTHEN_ROOT_PUBLISH_SIGN = 0x01; + + static const uint8_t MSG_AUTHEN_CHILD_PUBLISH_SIGN = 0x02; + + static const uint8_t MSG_AUTHEN_ROOT_AUTHOR_SIGN = 0x04; + + static const uint8_t MSG_AUTHEN_CHILD_AUTHOR_SIGN = 0x08; + + /** END msg authentication flags **/ + + /** START group options flag **/ + + static const uint8_t GRP_OPTION_AUTHEN_AUTHOR_SIGN = 0x01; + + /** END group options flag **/ /** START Subscription Flags. (LOCAL) **/ - static const uint32_t GROUP_SUBSCRIBE_ADMIN = 0x00000001; + static const uint32_t GROUP_SUBSCRIBE_ADMIN = 0x01; - static const uint32_t GROUP_SUBSCRIBE_PUBLISH = 0x00000002; + static const uint32_t GROUP_SUBSCRIBE_PUBLISH = 0x02; - static const uint32_t GROUP_SUBSCRIBE_SUBSCRIBED = 0x00000004; + static const uint32_t GROUP_SUBSCRIBE_SUBSCRIBED = 0x04; - static const uint32_t GROUP_SUBSCRIBE_NOT_SUBSCRIBED = 0x00000008; + static const uint32_t GROUP_SUBSCRIBE_NOT_SUBSCRIBED = 0x08; static const uint32_t GROUP_SUBSCRIBE_MASK = 0x0000000f; diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 0723b7ed1..f1a60973c 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -363,8 +363,8 @@ void RsGxsNetService::run(){ bool RsGxsNetService::locked_checkTransacTimedOut(NxsTransaction* tr) { - return tr->mTimeOut < ((uint32_t) time(NULL)); - // return false; + // return tr->mTimeOut < ((uint32_t) time(NULL)); + return false; } void RsGxsNetService::processTransactions(){ diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 925c303cc..240a5b1f2 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1818,9 +1818,9 @@ RsTurtle *rsTurtle = NULL ; #ifdef ENABLE_GXS_CORE #include "gxs/gxscoreserver.h" - #include "gxs/rsdataservice.h" #include "gxs/rsgxsnetservice.h" +#include "gxs/rsgxsflags.h" #endif #ifdef ENABLE_GXS_SERVICES @@ -2319,6 +2319,20 @@ int RsServer::StartupRetroShare() #if ENABLE_OTHER_GXS_SERVICES /**** Photo service ****/ + // create photo authentication policy + + uint32_t photoAuthenPolicy = 0; + + uint8_t flag = 0; + + flag = GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN; + RsGenExchange::setAuthenPolicyFlag(flag, photoAuthenPolicy, + RsGenExchange::RESTRICTED_GRP_BITS); + + flag = GXS_SERV::GRP_OPTION_AUTHEN_AUTHOR_SIGN; + RsGenExchange::setAuthenPolicyFlag(flag, photoAuthenPolicy, + RsGenExchange::GRP_OPTION_BITS); + p3PhotoServiceV2 *mPhotoV2 = NULL; @@ -2327,8 +2341,9 @@ int RsServer::StartupRetroShare() photo_ds->resetDataStore(); //TODO: remove, new service data per RS session, for testing + // init gxs services - mPhotoV2 = new p3PhotoServiceV2(photo_ds, NULL); + mPhotoV2 = new p3PhotoServiceV2(photo_ds, NULL, mGxsIdService, photoAuthenPolicy); // create GXS photo service RsGxsNetService* photo_ns = new RsGxsNetService( diff --git a/libretroshare/src/services/p3photoserviceV2.cc b/libretroshare/src/services/p3photoserviceV2.cc index f14691210..82d871d8f 100644 --- a/libretroshare/src/services/p3photoserviceV2.cc +++ b/libretroshare/src/services/p3photoserviceV2.cc @@ -79,8 +79,10 @@ std::ostream &operator<<(std::ostream &out, const RsPhotoAlbum &album) return out; } -p3PhotoServiceV2::p3PhotoServiceV2(RsGeneralDataService* gds, RsNetworkExchangeService* nes) - : RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_GXSV1_TYPE_PHOTO), mPhotoMutex(std::string("Photo Mutex")) +p3PhotoServiceV2::p3PhotoServiceV2(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs, + uint32_t authenPolicy) + : RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_GXSV1_TYPE_PHOTO, gixs, authenPolicy), + mPhotoMutex(std::string("Photo Mutex")) { // create dummy grps diff --git a/libretroshare/src/services/p3photoserviceV2.h b/libretroshare/src/services/p3photoserviceV2.h index 0401ad4d7..0ddccf4db 100644 --- a/libretroshare/src/services/p3photoserviceV2.h +++ b/libretroshare/src/services/p3photoserviceV2.h @@ -34,7 +34,8 @@ class p3PhotoServiceV2 : public RsPhotoV2, public RsGenExchange { public: - p3PhotoServiceV2(RsGeneralDataService* gds, RsNetworkExchangeService* nes); + p3PhotoServiceV2(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs, + uint32_t authenPolicy); public: diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp index c76286d1c..a8712322b 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp @@ -4,6 +4,7 @@ #include "ui_AlbumCreateDialog.h" #include "util/misc.h" +#include "gxs/rsgxsflags.h" AlbumCreateDialog::AlbumCreateDialog(TokenQueue *photoQueue, RsPhotoV2 *rs_photo, QWidget *parent): QDialog(parent), @@ -20,6 +21,10 @@ AlbumCreateDialog::~AlbumCreateDialog() delete ui; } +#define PUBLIC_INDEX 0 +#define RESTRICTED_INDEX 1 +#define PRIVATE_INDEX 2 + void AlbumCreateDialog::publishAlbum() { // get fields for album to publish, publish and then exit dialog @@ -33,6 +38,22 @@ void AlbumCreateDialog::publishAlbum() album.mPhotographer = ui->lineEdit_Photographer->text().toStdString(); getAlbumThumbnail(album.mThumbnail); + + int currIndex = ui->privacyComboBox->currentIndex(); + + switch(currIndex) + { + case PUBLIC_INDEX: + album.mMeta.mGroupFlags |= GXS_SERV::FLAG_PRIVACY_PUBLIC; + break; + case RESTRICTED_INDEX: + album.mMeta.mGroupFlags |= GXS_SERV::FLAG_PRIVACY_RESTRICTED; + break; + case PRIVATE_INDEX: + album.mMeta.mGroupFlags |= GXS_SERV::FLAG_PRIVACY_PRIVATE; + break; + } + uint32_t token; mRsPhoto->submitAlbumDetails(token, album); mPhotoQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, 0); diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui index 5c881bfb9..4e0e3dcb4 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui @@ -7,7 +7,7 @@ 0 0 465 - 356 + 365 @@ -198,7 +198,7 @@ border-radius: 10px; - + 0 @@ -210,11 +210,6 @@ border-radius: 10px; Public - - - All Friends - - Restricted From 6906f47fa7c7aa083312317c71cba4f430c35dc8 Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 11 Nov 2012 15:56:34 +0000 Subject: [PATCH 140/222] Bits and pieces to get forums compiled. - Added some MACROS - could be moved to GXS headers? - fixed some GXS compile warnings. - added MsgReadStatus to forums interface git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5806 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/retroshare/rsgxsforums.h | 9 +++++++++ libretroshare/src/retroshare/rsidentityVEG.h | 7 ++++--- libretroshare/src/serialiser/rsnxsitems.h | 8 ++++---- libretroshare/src/services/p3gxsforums.cc | 18 ++++++++++++++++++ libretroshare/src/services/p3gxsforums.h | 2 ++ libretroshare/src/services/p3wiki.cc | 3 +++ 6 files changed, 40 insertions(+), 7 deletions(-) diff --git a/libretroshare/src/retroshare/rsgxsforums.h b/libretroshare/src/retroshare/rsgxsforums.h index 7fb0da1af..34d57b89d 100644 --- a/libretroshare/src/retroshare/rsgxsforums.h +++ b/libretroshare/src/retroshare/rsgxsforums.h @@ -33,6 +33,13 @@ #include "gxs/rstokenservice.h" #include "gxs/rsgxsifaceimpl.h" + +#define IS_MSG_UNREAD(status) (status & GXS_SERV::GXS_MSG_STATUS_UNREAD) +#define IS_GROUP_ADMIN(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) +#define IS_GROUP_SUBSCRIBED(subscribeFlags) (subscribeFlags & (GXS_SERV::GROUP_SUBSCRIBE_ADMIN | GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)) + + + /* The Main Interface Class - for information about your Peers */ class RsGxsForums; extern RsGxsForums *rsGxsForums; @@ -70,6 +77,8 @@ virtual bool getGroupData(const uint32_t &token, std::vector &g virtual bool getMsgData(const uint32_t &token, std::vector &msgs) = 0; ////////////////////////////////////////////////////////////////////////////// +virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) = 0; + //virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask); //virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask); diff --git a/libretroshare/src/retroshare/rsidentityVEG.h b/libretroshare/src/retroshare/rsidentityVEG.h index 7a759b782..6cb50fc42 100644 --- a/libretroshare/src/retroshare/rsidentityVEG.h +++ b/libretroshare/src/retroshare/rsidentityVEG.h @@ -206,9 +206,10 @@ class RsTokReqOptionsVEG // Some MACROS for EASE OF USE. (USED BY FORUMSV2 At the moment. -#define IS_MSG_UNREAD(status) ((status & RSGXS_MSG_STATUS_READ) == 0 || (status & RSGXS_MSG_STATUS_UNREAD_BY_USER)) -#define IS_GROUP_ADMIN(subscribeFlags) (subscribeFlags & RSGXS_GROUP_SUBSCRIBE_ADMIN) -#define IS_GROUP_SUBSCRIBED(subscribeFlags) (subscribeFlags & (RSGXS_GROUP_SUBSCRIBE_ADMIN | RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED)) +// MOVED TO REAL GXS STUFF +//#define IS_MSG_UNREAD(status) ((status & RSGXS_MSG_STATUS_READ) == 0 || (status & RSGXS_MSG_STATUS_UNREAD_BY_USER)) +//#define IS_GROUP_ADMIN(subscribeFlags) (subscribeFlags & RSGXS_GROUP_SUBSCRIBE_ADMIN) +//#define IS_GROUP_SUBSCRIBED(subscribeFlags) (subscribeFlags & (RSGXS_GROUP_SUBSCRIBE_ADMIN | RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED)) diff --git a/libretroshare/src/serialiser/rsnxsitems.h b/libretroshare/src/serialiser/rsnxsitems.h index 8df77fb27..381c78e93 100644 --- a/libretroshare/src/serialiser/rsnxsitems.h +++ b/libretroshare/src/serialiser/rsnxsitems.h @@ -262,7 +262,7 @@ class RsNxsMsg : public RsNxsItem { public: - RsNxsMsg(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_MSG), msg(servtype), meta(servtype), + RsNxsMsg(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_MSG), meta(servtype), msg(servtype), metaData(NULL) { clear(); return; } ~RsNxsMsg() { if(metaData) delete metaData; } @@ -299,7 +299,7 @@ public: virtual ~RsNxsSearchReq() { return;} virtual void clear() { return;} - virtual std::ostream &print(std::ostream &out, uint16_t indent) { return out; } + virtual std::ostream &print(std::ostream &out, uint16_t /*indent*/) { return out; } uint8_t nHops; /// how many peers to jump to uint32_t token; // search token @@ -337,7 +337,7 @@ public: RsNxsSearchResultMsg() : context(0) { return;} void clear() {} - std::ostream &print(std::ostream &out, uint16_t indent) { return out; } + std::ostream &print(std::ostream &out, uint16_t /*indent*/) { return out; } uint32_t token; // search token to be redeemed RsTlvBinaryData context; // used by client service @@ -358,7 +358,7 @@ public: RsNxsSearchResultGrp(); void clear() {} - std::ostream &print(std::ostream &out, uint16_t indent) { return out; } + std::ostream &print(std::ostream &out, uint16_t /*indent*/) { return out; } uint32_t token; // search token to be redeemed diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index 85e693d9d..6d0bd2985 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -27,6 +27,7 @@ #include "serialiser/rsgxsforumitems.h" #include "util/rsrandom.h" +#include "gxs/rsgxsflags.h" #include /**** @@ -150,6 +151,23 @@ bool p3GxsForums::createMsg(uint32_t &token, RsGxsForumMsg &msg) } +/********************************************************************************************/ +/********************************************************************************************/ + +void p3GxsForums::setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) +{ + uint32_t mask = GXS_SERV::GXS_MSG_STATUS_UNREAD; + uint32_t status = GXS_SERV::GXS_MSG_STATUS_UNREAD; + if (read) + { + status = 0; + } + + setMsgStatusFlags(token, msgId, status, mask); + +} + +/********************************************************************************************/ /********************************************************************************************/ diff --git a/libretroshare/src/services/p3gxsforums.h b/libretroshare/src/services/p3gxsforums.h index db765c980..8ed77ab80 100644 --- a/libretroshare/src/services/p3gxsforums.h +++ b/libretroshare/src/services/p3gxsforums.h @@ -54,6 +54,8 @@ virtual bool getGroupData(const uint32_t &token, std::vector &g virtual bool getMsgData(const uint32_t &token, std::vector &msgs); ////////////////////////////////////////////////////////////////////////////// +virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read); + //virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask); //virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask); diff --git a/libretroshare/src/services/p3wiki.cc b/libretroshare/src/services/p3wiki.cc index da98038b0..ab75282cd 100644 --- a/libretroshare/src/services/p3wiki.cc +++ b/libretroshare/src/services/p3wiki.cc @@ -198,6 +198,9 @@ bool p3Wiki::submitCollection(uint32_t &token, RsWikiCollection &collection) bool p3Wiki::submitSnapshot(uint32_t &token, RsWikiSnapshot &snapshot) { + std::cerr << "p3Wiki::submitSnapshot(): " << snapshot; + std::cerr << std::endl; + RsGxsWikiSnapshotItem* snapshotItem = new RsGxsWikiSnapshotItem(); snapshotItem->snapshot = snapshot; snapshotItem->meta = snapshot.mMeta; From d8dc2a042024f130317dee2f840c068d8c568909 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sun, 11 Nov 2012 23:45:22 +0000 Subject: [PATCH 141/222] publish key not generated for public groups anymore, added signature creation for publish and id keys (used in main line of code, correctly initialise ur gxs services) groupid assigned to group before service_CreateGroup now (to help with identity using pgp hashes) fixed up dummy group creation for photo service and ui completed basic functions of GxsGroupDialog git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5809 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsdataservice.h | 2 +- libretroshare/src/gxs/rsgenexchange.cc | 594 ++++++++++++------ libretroshare/src/gxs/rsgenexchange.h | 24 +- libretroshare/src/gxs/rsgxsnetservice.cc | 6 +- libretroshare/src/pqi/pqihash.h | 5 +- libretroshare/src/retroshare/rsposted.h | 1 + libretroshare/src/rsserver/rsinit.cc | 5 + libretroshare/src/serialiser/rsnxsitems.h | 2 +- .../src/services/p3photoserviceV2.cc | 2 + .../src/tests/gxs/nxstestscenario.cc | 3 + .../src/gui/PhotoShare/AlbumDialog.cpp | 8 + .../src/gui/PhotoShare/AlbumDialog.ui | 4 +- .../src/gui/PhotoShare/PhotoDialog.cpp | 4 +- .../src/gui/Posted/PostedGroupDialog.cpp | 10 +- .../src/gui/Posted/PostedGroupDialog.h | 13 - retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp | 8 + retroshare-gui/src/gui/gxs/GxsGroupDialog.h | 12 +- 17 files changed, 467 insertions(+), 236 deletions(-) diff --git a/libretroshare/src/gxs/rsdataservice.h b/libretroshare/src/gxs/rsdataservice.h index 4daa24111..7a8a8fb25 100644 --- a/libretroshare/src/gxs/rsdataservice.h +++ b/libretroshare/src/gxs/rsdataservice.h @@ -6,7 +6,7 @@ * * General Data service, interface for RetroShare. * - * Copyright 2011-2011 by Evi-Parker Christopher + * Copyright 2011-2012 by Evi-Parker Christopher * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 4e04d7788..7096fd9dd 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -154,7 +154,7 @@ bool RsGenExchange::acknowledgeTokenGrp(const uint32_t& token, return true; } -void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet) +void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet, bool genPublishKeys) { /* create Keys */ @@ -162,85 +162,96 @@ void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet) RSA *rsa_admin = RSA_generate_key(2048, 65537, NULL, NULL); RSA *rsa_admin_pub = RSAPublicKey_dup(rsa_admin); - // publish keys - RSA *rsa_publish = RSA_generate_key(2048, 65537, NULL, NULL); - RSA *rsa_publish_pub = RSAPublicKey_dup(rsa_admin); - - /* set keys */ + /* set admin keys */ RsTlvSecurityKey adminKey, privAdminKey; - /* set publish keys */ - RsTlvSecurityKey pubKey, privPubKey; - GxsSecurity::setRSAPublicKey(adminKey, rsa_admin_pub); GxsSecurity::setRSAPrivateKey(privAdminKey, rsa_admin); - GxsSecurity::setRSAPublicKey(pubKey, rsa_publish_pub); - GxsSecurity::setRSAPrivateKey(privPubKey, rsa_publish); - adminKey.startTS = time(NULL); adminKey.endTS = 0; /* no end */ privAdminKey.startTS = adminKey.startTS; privAdminKey.endTS = 0; /* no end */ - pubKey.startTS = adminKey.startTS; - pubKey.endTS = pubKey.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */ - - privPubKey.startTS = adminKey.startTS; - privPubKey.endTS = 0; /* no end */ - // for now all public adminKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_PUBLIC_ONLY; privAdminKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL; - // for now all public - pubKey.keyFlags = RSTLV_KEY_DISTRIB_PUBLIC | RSTLV_KEY_TYPE_PUBLIC_ONLY; - privPubKey.keyFlags = RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL; - keySet.keys[adminKey.keyId] = adminKey; - keySet.keys[pubKey.keyId] = pubKey; - keySet.keys[privAdminKey.keyId] = privAdminKey; - keySet.keys[privPubKey.keyId] = privPubKey; // clean up RSA_free(rsa_admin); RSA_free(rsa_admin_pub); - RSA_free(rsa_publish); - RSA_free(rsa_publish_pub); + if(genPublishKeys) + { + // publish keys + RSA *rsa_publish = RSA_generate_key(2048, 65537, NULL, NULL); + RSA *rsa_publish_pub = RSAPublicKey_dup(rsa_publish); + + /* set publish keys */ + RsTlvSecurityKey pubKey, privPubKey; + + GxsSecurity::setRSAPublicKey(pubKey, rsa_publish_pub); + GxsSecurity::setRSAPrivateKey(privPubKey, rsa_publish); + + pubKey.startTS = adminKey.startTS; + pubKey.endTS = pubKey.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */ + + privPubKey.startTS = adminKey.startTS; + privPubKey.endTS = 0; /* no end */ + + // for now all public + pubKey.keyFlags = RSTLV_KEY_DISTRIB_PUBLIC | RSTLV_KEY_TYPE_PUBLIC_ONLY; + privPubKey.keyFlags = RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL; + + keySet.keys[pubKey.keyId] = pubKey; + keySet.keys[privPubKey.keyId] = privPubKey; + + RSA_free(rsa_publish); + RSA_free(rsa_publish_pub); + } + } bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet) { - std::cerr << "RsGenExchange::createGroup()"; - std::cerr << std::endl; - + std::cerr << "RsGenExchange::createGroup()"; + std::cerr << std::endl; RsGxsGrpMetaData* meta = grp->metaData; - /* add keys to grp */ - meta->keys = keySet; + /* add public admin and publish keys to grp */ // find private admin key RsTlvSecurityKey privAdminKey; std::map::iterator mit = keySet.keys.begin(); + bool privKeyFound = false; for(; mit != keySet.keys.end(); mit++) { - RsTlvSecurityKey& pk = mit->second; + RsTlvSecurityKey& key = mit->second; - if(pk.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL)) + // add public admin key + if(key.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_PUBLIC_ONLY)) + meta->keys.keys.insert(std::make_pair(key.keyId, key)); + + // add public publish key + if(key.keyFlags & (RSTLV_KEY_DISTRIB_PUBLIC | RSTLV_KEY_TYPE_PUBLIC_ONLY)) + meta->keys.keys.insert(std::make_pair(key.keyId, key)); + + if(key.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL)) { - privAdminKey = pk; - break; + privAdminKey = key; + privKeyFound = true; } } - if(mit == keySet.keys.end()) + if(!privKeyFound) { - std::cerr << "RsGenExchange::createGroup() Missing ADMIN Key"; + std::cerr << "RsGenExchange::createGroup() Missing private ADMIN Key"; std::cerr << std::endl; return false; @@ -248,8 +259,7 @@ bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet) // group is self signing // for the creation of group signature - // only public admin and publish keys are present - // key set + // only public admin and publish keys are present in meta uint32_t metaDataLen = meta->serial_size(); uint32_t allGrpDataLen = metaDataLen + grp->grp.bin_len; char* metaData = new char[metaDataLen]; @@ -267,7 +277,14 @@ bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet) // add admin sign to grpMeta meta->signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_ADMIN] = adminSign; - grp->grpId = meta->mGroupId = privAdminKey.keyId; + // set meta to be transported as meta without private + // key components + grp->meta.setBinData(metaData, metaDataLen); + + // but meta that is stored locally + // has all keys + // nxs net transports only bin data + meta->keys = keySet; // clean up delete[] allGrpData; @@ -282,6 +299,167 @@ bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet) return ok; } +bool RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinaryData& msgData, + const RsGxsMsgMetaData& msgMeta, RsGxsGrpMetaData& grpMeta) +{ + bool isParent = false; + bool needPublishSign, needIdentitySign; + bool ok = true; + uint32_t grpFlag = grpMeta.mGroupFlags; + + // publish signature is determined by whether group is public or not + // for private group signature is not needed as it needs decrypting with + // the private publish key anyways + + // restricted is a special case which heeds whether publish sign needs to be checked or not + // one may or may not want + + if(msgMeta.mParentId.empty()) + { + isParent = true; + } + else + { + isParent = false; + } + + + if(isParent) + { + needIdentitySign = false; + needPublishSign = false; + + if(grpFlag & GXS_SERV::FLAG_PRIVACY_PUBLIC) + { + needPublishSign = false; + + if(checkMsgAuthenFlag(PUBLIC_GRP_BITS, GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN)) + needIdentitySign = true; + + } + else if(grpFlag & GXS_SERV::FLAG_PRIVACY_RESTRICTED) + { + needPublishSign = true; + + if(checkMsgAuthenFlag(RESTRICTED_GRP_BITS, GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN)) + needIdentitySign = true; + } + else if(grpFlag & GXS_SERV::FLAG_PRIVACY_PRIVATE) + { + needPublishSign = false; + + if(checkMsgAuthenFlag(PRIVATE_GRP_BITS, GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN)) + needIdentitySign = true; + } + + }else + { + if(grpFlag & GXS_SERV::FLAG_PRIVACY_PUBLIC) + { + needPublishSign = false; + + if(checkMsgAuthenFlag(PUBLIC_GRP_BITS, GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN)) + needIdentitySign = true; + + } + else if(grpFlag & GXS_SERV::FLAG_PRIVACY_RESTRICTED) + { + if(checkMsgAuthenFlag(RESTRICTED_GRP_BITS, GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN)) + needPublishSign = true; + + if(checkMsgAuthenFlag(RESTRICTED_GRP_BITS, GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN)) + needIdentitySign = true; + } + else if(grpFlag & GXS_SERV::FLAG_PRIVACY_PRIVATE) + { + needPublishSign = false; + + if(checkMsgAuthenFlag(PRIVATE_GRP_BITS, GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN)) + needIdentitySign = true; + } + } + + if(needPublishSign) + { + + // public and shared is publish key + RsTlvSecurityKeySet& keys = grpMeta.keys; + RsTlvSecurityKey* pubKey; + + std::map::iterator mit = + keys.keys.begin(), mit_end = keys.keys.end(); + bool pub_key_found = false; + for(; mit != mit_end; mit++) + { + + pub_key_found = mit->second.keyFlags & (RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL); + if(pub_key_found) + break; + } + + // private publish key + pubKey = &(mit->second); + + RsTlvKeySignature pubSign = signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH]; + + ok &= GxsSecurity::getSignature((char*)msgData.bin_data, msgData.bin_len, pubKey, pubSign); + + //place signature in msg meta + signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH] = pubSign; + } + + + if(needIdentitySign) + { + if(mGixs) + { + bool haveKey = mGixs->havePrivateKey(msgMeta.mAuthorId); + + if(haveKey) + { + mGixs->requestPrivateKey(msgMeta.mAuthorId); + + RsTlvSecurityKey authorKey; + + double timeDelta = 0.002; // fast polling + time_t now = time(NULL); + + // poll immediately but, don't spend more than a second polling + while( (mGixs->getPrivateKey(msgMeta.mAuthorId, authorKey) == -1) && + ((now + 1) >> time(NULL)) + ) + { + #ifndef WINDOWS_SYS + usleep((int) (timeDelta * 1000000)); + #else + Sleep((int) (timeDelta * 1000)); + #endif + } + + + RsTlvKeySignature sign; + ok &= GxsSecurity::getSignature((char*)msgData.bin_data, msgData.bin_len, + &authorKey, sign); + signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_IDENTITY] = sign; + + }else + { + ok = false; + } + } + else + { +#ifdef GEN_EXHANGE_DEBUG + std::cerr << "Gixs not enabled while request identity signature validation!" << std::endl; +#endif + } + } + + return ok; + + +} + bool RsGenExchange::createMessage(RsNxsMsg* msg) { const RsGxsGroupId& id = msg->grpId; @@ -290,78 +468,48 @@ bool RsGenExchange::createMessage(RsNxsMsg* msg) metaMap.insert(std::make_pair(id, (RsGxsGrpMetaData*)(NULL))); mDataStore->retrieveGxsGrpMetaData(metaMap); - bool ok = true; - RSA* rsa_pub = NULL; + bool ok = true; + RsGxsMsgMetaData &meta = *(msg->metaData); if(!metaMap[id]) { - return false; + return false; } else { - // get publish key - RsGxsGrpMetaData* grpMeta = metaMap[id]; + // get publish key + RsGxsGrpMetaData* grpMeta = metaMap[id]; - // public and shared is publish key - RsTlvSecurityKeySet& keys = grpMeta->keys; - RsTlvSecurityKey* pubKey; + uint32_t metaDataLen = meta.serial_size(); + uint32_t allMsgDataLen = metaDataLen + msg->msg.bin_len; + char* metaData = new char[metaDataLen]; + char* allMsgData = new char[allMsgDataLen]; // msgData + metaData - std::map::iterator mit = - keys.keys.begin(), mit_end = keys.keys.end(); - bool pub_key_found = false; - for(; mit != mit_end; mit++) - { + meta.serialise(metaData, &metaDataLen); - pub_key_found = mit->second.keyFlags & (RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL); - if(pub_key_found) - break; - } + // copy msg data and meta in allmsgData buffer + memcpy(allMsgData, msg->msg.bin_data, msg->msg.bin_len); + memcpy(allMsgData+(msg->msg.bin_len), metaData, metaDataLen); - if(pub_key_found) - { - RsGxsMsgMetaData &meta = *(msg->metaData); + RsTlvBinaryData msgData(0); - uint32_t metaDataLen = meta.serial_size(); - uint32_t allMsgDataLen = metaDataLen + msg->msg.bin_len; - char* metaData = new char[metaDataLen]; - char* allMsgData = new char[allMsgDataLen]; // msgData + metaData + msgData.setBinData(allMsgData, allMsgDataLen); - meta.serialise(metaData, &metaDataLen); + // create signatures + ok &= createMsgSignatures(meta.signSet, msgData, meta, *grpMeta); - // copy msg data and meta in allmsgData buffer - memcpy(allMsgData, msg->msg.bin_data, msg->msg.bin_len); - memcpy(allMsgData+(msg->msg.bin_len), metaData, metaDataLen); + // get hash of msg data to create msg id + pqihash hash; + hash.addData(allMsgData, allMsgDataLen); + hash.Complete(msg->msgId); - // private publish key - pubKey = &(mit->second); + // assign msg id to msg meta + msg->metaData->mMsgId = msg->msgId; - RsTlvKeySignatureSet& signSet = meta.signSet; - RsTlvKeySignature pubSign = signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH]; + delete[] metaData; + delete[] allMsgData; - GxsSecurity::getSignature(allMsgData, allMsgDataLen, pubKey, pubSign); - - // get hash of msg data to create msg id - pqihash hash; - hash.addData(allMsgData, allMsgDataLen); - hash.Complete(msg->msgId); - - // assign msg id to msg meta - msg->metaData->mMsgId = msg->msgId; - - //place signature in msg meta - signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH] = pubSign; - - // clean up - - delete[] metaData; - delete[] allMsgData; - } - else - { - ok = false; - } - - delete grpMeta; + delete grpMeta; } return ok; @@ -382,11 +530,11 @@ bool RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSec if(msg->metaData->mParentId.empty()) { - isParent = false; + isParent = true; } else { - isParent = true; + isParent = false; } @@ -464,37 +612,49 @@ bool RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSec } + if(checkIdentitySign) { - bool haveKey = mGixs->haveKey(metaData.mAuthorId); - - if(haveKey) + if(mGixs) { - std::list peers; - mGixs->requestKey(metaData.mAuthorId, peers); + bool haveKey = mGixs->haveKey(metaData.mAuthorId); - RsTlvSecurityKey authorKey; - - double timeDelta = 0.002; // fast polling - time_t now = time(NULL); - // poll immediately but, don't spend more than a second polling - while( (mGixs->getKey(metaData.mAuthorId, authorKey) == -1) && - ((now + 1) >> time(NULL)) - ) + if(haveKey) { -#ifndef WINDOWS_SYS - usleep((int) (timeDelta * 1000000)); -#else - Sleep((int) (timeDelta * 1000)); -#endif - } + std::list peers; + mGixs->requestKey(metaData.mAuthorId, peers); - RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH]; - valid &= GxsSecurity::validateNxsMsg(*msg, sign, authorKey); - }else + RsTlvSecurityKey authorKey; + + double timeDelta = 0.002; // fast polling + time_t now = time(NULL); + // poll immediately but, don't spend more than a second polling + while( (mGixs->getKey(metaData.mAuthorId, authorKey) == -1) && + ((now + 1) >> time(NULL)) + ) + { + #ifndef WINDOWS_SYS + usleep((int) (timeDelta * 1000000)); + #else + Sleep((int) (timeDelta * 1000)); + #endif + } + + RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH]; + valid &= GxsSecurity::validateNxsMsg(*msg, sign, authorKey); + }else + { + valid = false; + } + } + else { +#ifdef GEN_EXHANGE_DEBUG + std::cerr << "Gixs not enabled while request identity signature validation!" << std::endl; +#endif valid = false; } + } return valid; @@ -956,91 +1116,114 @@ void RsGenExchange::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeyS void RsGenExchange::publishGrps() { - RsStackMutex stack(mGenMtx); + RsStackMutex stack(mGenMtx); - std::map::iterator mit = mGrpsToPublish.begin(); - std::vector toRemove; - int i = 0; - for(; mit != mGrpsToPublish.end(); mit++) - { - toRemove.push_back(mit->first); - i++; - if(i > GEN_EXCH_GRP_CHUNK) break; + std::map::iterator mit = mGrpsToPublish.begin(); + std::vector toRemove; + int i = 0; + for(; mit != mGrpsToPublish.end(); mit++) + { + toRemove.push_back(mit->first); + i++; + if(i > GEN_EXCH_GRP_CHUNK) break; - RsNxsGrp* grp = new RsNxsGrp(mServType); - RsGxsGrpItem* grpItem = mit->second; + RsNxsGrp* grp = new RsNxsGrp(mServType); + RsGxsGrpItem* grpItem = mit->second; - RsTlvSecurityKeySet keySet; - generateGroupKeys(keySet); + RsTlvSecurityKeySet keySet; + generateGroupKeys(keySet, + !(grpItem->meta.mGroupFlags & GXS_SERV::FLAG_PRIVACY_PUBLIC)); - service_CreateGroup(grpItem, keySet); + // find private admin key + RsTlvSecurityKey privAdminKey; + std::map::iterator mit_keys = keySet.keys.begin(); - uint32_t size = mSerialiser->size(grpItem); - char gData[size]; - bool ok = mSerialiser->serialise(grpItem, gData, &size); - if (!ok) - { - std::cerr << "RsGenExchange::publishGrps() !ok ERROR After First Serialise" << std::endl; - } + bool privKeyFound = false; + for(; mit_keys != keySet.keys.end(); mit_keys++) + { + RsTlvSecurityKey& key = mit_keys->second; - grp->grp.setBinData(gData, size); - - if(ok) + if(key.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL)) { - grp->metaData = new RsGxsGrpMetaData(); - grpItem->meta.mPublishTs = time(NULL); - *(grp->metaData) = grpItem->meta; - grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; - ok &= createGroup(grp, keySet); - if (!ok) - { - std::cerr << "RsGenExchange::publishGrps() !ok ERROR After createGroup" << std::endl; - } + privAdminKey = key; + privKeyFound = true; + } + } - size = grp->metaData->serial_size(); - char mData[size]; - grp->metaData->mGroupId = grp->grpId; - ok &= grp->metaData->serialise(mData, size); - if (!ok) - { - std::cerr << "RsGenExchange::publishGrps() !ok ERROR After Meta Serialise" << std::endl; - } + bool ok = true; - grp->meta.setBinData(mData, size); - RsGxsGroupId grpId = grp->grpId; - mDataAccess->addGroupData(grp); + if(privKeyFound) + { + // get group id from private admin key id + grpItem->meta.mGroupId = grp->grpId = privAdminKey.keyId; + } + else + { + ok = false; + } - std::cerr << "RsGenExchange::publishGrps() ok -> pushing to notifies" << std::endl; - // add to published to allow acknowledgement - mGrpNotify.insert(std::make_pair(mit->first, grpId)); - mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE); + service_CreateGroup(grpItem, keySet); + + uint32_t size = mSerialiser->size(grpItem); + char gData[size]; + ok = mSerialiser->serialise(grpItem, gData, &size); + + if (!ok) + { + std::cerr << "RsGenExchange::publishGrps() !ok ERROR After First Serialise" << std::endl; + } + + grp->grp.setBinData(gData, size); + + if(ok) + { + grp->metaData = new RsGxsGrpMetaData(); + grpItem->meta.mPublishTs = time(NULL); + *(grp->metaData) = grpItem->meta; + grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; + + ok &= createGroup(grp, keySet); + + if (!ok) + { + std::cerr << "RsGenExchange::publishGrps() !ok ERROR After createGroup" << std::endl; } - if(!ok) - { + RsGxsGroupId grpId = grp->grpId; + mDataAccess->addGroupData(grp); + + std::cerr << "RsGenExchange::publishGrps() ok -> pushing to notifies" << std::endl; + + // add to published to allow acknowledgement + mGrpNotify.insert(std::make_pair(mit->first, grpId)); + mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE); + } + + if(!ok) + { #ifdef GEN_EXCH_DEBUG #endif - std::cerr << "RsGenExchange::publishGrps() failed to publish grp " << std::endl; - delete grp; + std::cerr << "RsGenExchange::publishGrps() failed to publish grp " << std::endl; + delete grp; - // add to published to allow acknowledgement, grpid is empty as grp creation failed - mGrpNotify.insert(std::make_pair(mit->first, RsGxsGroupId(""))); - mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED); - continue; - } + // add to published to allow acknowledgement, grpid is empty as grp creation failed + mGrpNotify.insert(std::make_pair(mit->first, RsGxsGroupId(""))); + mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED); + continue; + } - delete grpItem; + delete grpItem; - } + } - // clear grp list as we're done publishing them and entries - // are invalid + // clear grp list as we're done publishing them and entries + // are invalid - for(int i = 0; i < toRemove.size(); i++) - mGrpsToPublish.erase(toRemove[i]); + for(int i = 0; i < toRemove.size(); i++) + mGrpsToPublish.erase(toRemove[i]); } @@ -1090,33 +1273,54 @@ bool RsGenExchange::getGroupKeys(const RsGxsGroupId &grpId, RsTlvSecurityKeySet void RsGenExchange::createDummyGroup(RsGxsGrpItem *grpItem) { - RsStackMutex stack(mGenMtx); - RsNxsGrp* grp = new RsNxsGrp(mServType); uint32_t size = mSerialiser->size(grpItem); char gData[size]; bool ok = mSerialiser->serialise(grpItem, gData, &size); grp->grp.setBinData(gData, size); - RsTlvSecurityKeySet keySet; - generateGroupKeys(keySet); + RsTlvSecurityKeySet keySet; + generateGroupKeys(keySet, + !(grpItem->meta.mGroupFlags & GXS_SERV::FLAG_PRIVACY_PUBLIC)); - service_CreateGroup(grpItem, keySet); + // find private admin key + RsTlvSecurityKey privAdminKey; + std::map::iterator mit_keys = keySet.keys.begin(); + + bool privKeyFound = false; + for(; mit_keys != keySet.keys.end(); mit_keys++) + { + RsTlvSecurityKey& key = mit_keys->second; + + if(key.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL)) + { + privAdminKey = key; + privKeyFound = true; + } + } + + + if(privKeyFound) + { + // get group id from private admin key id + grpItem->meta.mGroupId = grp->grpId = privAdminKey.keyId; + } + else + { + ok = false; + } + + service_CreateGroup(grpItem, keySet); if(ok) { grp->metaData = new RsGxsGrpMetaData(); grpItem->meta.mPublishTs = time(NULL); *(grp->metaData) = grpItem->meta; - grp->metaData->mSubscribeFlags = ~GXS_SERV::GROUP_SUBSCRIBE_MASK; + grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; createGroup(grp, keySet); - size = grp->metaData->serial_size(); - char mData[size]; - grp->metaData->mGroupId = grp->grpId; - ok = grp->metaData->serialise(mData, size); - grp->meta.setBinData(mData, size); mDataAccess->addGroupData(grp); } diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 232deab1b..73169dc58 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -384,7 +384,8 @@ private: /*! * This completes the creation of an instance on RsNxsGrp - * by assigning it a groupId and signature via SHA1 and EVP_sign respectively + * by assigning it a groupId and signature via SHA1 and EVP_sign respectively \n + * Meta is serialised and stored in group at this point also * @param grp Nxs group to create */ bool createGroup(RsNxsGrp* grp, RsTlvSecurityKeySet& keySet); @@ -398,6 +399,16 @@ private: */ bool createMessage(RsNxsMsg* msg); + /*! + * convenience function to create sign + * @param signSet signatures are stored here + * @param msgData message data to be signed + * @param grpMeta the meta data for group the message belongs to + * @return false if signature creation for any required signature fails, true otherwise + */ + bool createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinaryData& msgData, + const RsGxsMsgMetaData& msgMeta, RsGxsGrpMetaData& grpMeta); + /*! * check meta change is legal * @return false if meta change is not legal @@ -407,8 +418,9 @@ private: /*! * Generate a set of keys that can define a GXS group * @param keySet this is set generated keys + * @param genPublicKeys should public keys also be generated */ - void generateGroupKeys(RsTlvSecurityKeySet& keySet); + void generateGroupKeys(RsTlvSecurityKeySet& keySet, bool genPublishKeys); /*! * Attempts to validate msg @@ -419,8 +431,16 @@ private: */ bool validateMsg(RsNxsMsg* msg, const uint32_t& grpFlag, RsTlvSecurityKeySet& grpKeySet); + /*! + * Checks flag against a given privacy bit block + * @param pos Determines 8 bit wide privacy block to check + * @param flag the flag to and(&) against + * @param the result of the (bit-block & flag) + */ bool checkMsgAuthenFlag(const PrivacyBitPos& pos, const uint8_t& flag) const; + void groupShareKeys(std::list peers); + private: RsMutex mGenMtx; diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index f1a60973c..b572c3336 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -363,8 +363,8 @@ void RsGxsNetService::run(){ bool RsGxsNetService::locked_checkTransacTimedOut(NxsTransaction* tr) { - // return tr->mTimeOut < ((uint32_t) time(NULL)); - return false; + return tr->mTimeOut < ((uint32_t) time(NULL)); + // return false; } void RsGxsNetService::processTransactions(){ @@ -1022,7 +1022,7 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr) uint32_t transN = locked_getTransactionId(); - // store grp items to send in transaction + // store msg items to send in transaction GxsMsgResult::iterator mit = msgs.begin(); std::string peerId = tr->mTransaction->PeerId(); uint32_t msgSize = 0; diff --git a/libretroshare/src/pqi/pqihash.h b/libretroshare/src/pqi/pqihash.h index 7bf3cd506..7e08868ff 100644 --- a/libretroshare/src/pqi/pqihash.h +++ b/libretroshare/src/pqi/pqihash.h @@ -23,6 +23,9 @@ * */ +#ifndef PQI_HASH_ +#define PQI_HASH_ + #include #include #include @@ -86,4 +89,4 @@ void Complete(std::string &hash) SHA_CTX *sha_ctx; }; - +#endif diff --git a/libretroshare/src/retroshare/rsposted.h b/libretroshare/src/retroshare/rsposted.h index a1324e468..c5becb9ff 100644 --- a/libretroshare/src/retroshare/rsposted.h +++ b/libretroshare/src/retroshare/rsposted.h @@ -42,6 +42,7 @@ class RsPostedGroup { public: RsGroupMetaData mMeta; + std::string mDescription; RsPostedGroup() { return; } }; diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 240a5b1f2..ee455565f 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -2329,6 +2329,11 @@ int RsServer::StartupRetroShare() RsGenExchange::setAuthenPolicyFlag(flag, photoAuthenPolicy, RsGenExchange::RESTRICTED_GRP_BITS); +// Re-enable later, photo not using gixs yet +// flag = GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN; +// RsGenExchange::setAuthenPolicyFlag(flag, photoAuthenPolicy, +// RsGenExchange::RESTRICTED_GRP_BITS); + flag = GXS_SERV::GRP_OPTION_AUTHEN_AUTHOR_SIGN; RsGenExchange::setAuthenPolicyFlag(flag, photoAuthenPolicy, RsGenExchange::GRP_OPTION_BITS); diff --git a/libretroshare/src/serialiser/rsnxsitems.h b/libretroshare/src/serialiser/rsnxsitems.h index 381c78e93..1a7f72fcd 100644 --- a/libretroshare/src/serialiser/rsnxsitems.h +++ b/libretroshare/src/serialiser/rsnxsitems.h @@ -70,7 +70,7 @@ public: RsNxsItem(uint16_t servtype, uint8_t subtype) : RsItem(RS_PKT_VERSION_SERVICE, servtype, subtype), transactionNumber(0) { - setPriorityLevel(QOS_PRIORITY_RS_GXS_NET); + setPriorityLevel(QOS_PRIORITY_RS_VOIP_PING); return; } diff --git a/libretroshare/src/services/p3photoserviceV2.cc b/libretroshare/src/services/p3photoserviceV2.cc index 82d871d8f..febb7e44b 100644 --- a/libretroshare/src/services/p3photoserviceV2.cc +++ b/libretroshare/src/services/p3photoserviceV2.cc @@ -90,8 +90,10 @@ p3PhotoServiceV2::p3PhotoServiceV2(RsGeneralDataService* gds, RsNetworkExchangeS RsGxsPhotoAlbumItem* item1 = new RsGxsPhotoAlbumItem(), *item2 = new RsGxsPhotoAlbumItem(); item1->meta.mGroupName = "Dummy Album 1"; + item1->meta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_RESTRICTED; item1->album.mCaption = "Dummy 1"; item2->meta.mGroupName = "Dummy Album 2"; + item2->meta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_RESTRICTED; item2->album.mCaption = "Dummy 2"; createDummyGroup(item1); diff --git a/libretroshare/src/tests/gxs/nxstestscenario.cc b/libretroshare/src/tests/gxs/nxstestscenario.cc index e6973cf0c..73a720c36 100644 --- a/libretroshare/src/tests/gxs/nxstestscenario.cc +++ b/libretroshare/src/tests/gxs/nxstestscenario.cc @@ -7,6 +7,7 @@ #include "nxstestscenario.h" #include "gxs/rsdataservice.h" +#include "gxs/rsgxsflags.h" #include "data_support.h" #include @@ -147,6 +148,8 @@ void NxsMessageTestObserver::notifyNewGroups(std::vector &groups) { RsNxsGrp* grp = *vit; RsGxsGrpMetaData* meta = new RsGxsGrpMetaData(); + meta->deserialise(grp->meta.bin_data, grp->meta.bin_len); + meta->mSubscribeFlags |= GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED; meta->mGroupId = grp->grpId; grps.insert(std::make_pair(grp, meta)); } diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp index c39825bdf..4d9234ee8 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp @@ -2,6 +2,7 @@ #include "AlbumDialog.h" #include "ui_AlbumDialog.h" +#include "gxs/rsgxsflags.h" AlbumDialog::AlbumDialog(const RsPhotoAlbum& album, TokenQueue* photoQueue, RsPhotoV2* rs_Photo, QWidget *parent) : QDialog(parent), @@ -13,6 +14,12 @@ AlbumDialog::AlbumDialog(const RsPhotoAlbum& album, TokenQueue* photoQueue, RsPh connect(ui->pushButton_DeletePhoto, SIGNAL(clicked()), this, SLOT(deletePhoto())); mPhotoDrop = ui->scrollAreaWidgetContents; + + if(!(mAlbum.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)) + { + ui->scrollAreaPhotos->setEnabled(false); + ui->pushButton_DeletePhoto->setEnabled(false); + } mPhotoDrop->setPhotoItemHolder(this); setUp(); @@ -32,6 +39,7 @@ void AlbumDialog::setUp() } void AlbumDialog::updateAlbumPhotos(){ + QSet photos; mPhotoDrop->getPhotos(photos); diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui index b5568d690..5d42b38cf 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui @@ -285,7 +285,7 @@ p, li { white-space: pre-wrap; } 0 0 627 - 107 + 116 @@ -344,7 +344,7 @@ p, li { white-space: pre-wrap; } - Publish Photos + Publish Photos / Close diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index 9c89cd4bf..e471859f5 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -2,7 +2,7 @@ #include #include "PhotoDialog.h" #include "ui_PhotoDialog.h" - +#include "retroshare/rsidentity.h" #include "AddCommentDialog.h" PhotoDialog::PhotoDialog(RsPhotoV2 *rs_photo, const RsPhotoPhoto &photo, QWidget *parent) : @@ -37,8 +37,6 @@ void PhotoDialog::setUp() ui->label_Photo->setPixmap(qtn); ui->lineEdit_Title->setText(QString::fromStdString(mPhotoDetails.mMeta.mMsgName)); - //ui->scrollAreaWidgetContents->setLayout(new QVBoxLayout()); - requestComments(); } diff --git a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp index 358ab9ef6..71381fb84 100644 --- a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp @@ -56,21 +56,13 @@ bool PostedGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaDa { // Specific Function. RsPostedGroup grp; + grp.mDescription = getDescription().toStdString(); grp.mMeta = meta; rsPosted->submitGroup(token, grp); return true; } -QPixmap PostedGroupDialog::service_getLogo() -{ - return QPixmap(); // null pixmap -} - -QString PostedGroupDialog::service_getDescription() -{ - return QString(); -} diff --git a/retroshare-gui/src/gui/Posted/PostedGroupDialog.h b/retroshare-gui/src/gui/Posted/PostedGroupDialog.h index 09dac9043..187f1416d 100644 --- a/retroshare-gui/src/gui/Posted/PostedGroupDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedGroupDialog.h @@ -46,19 +46,6 @@ protected: bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); - /*! - * This should return a group logo \n - * Will be called when GxsGroupDialog is initialised in show mode - * - */ - virtual QPixmap service_getLogo(); - - /*! - * This should return a group description string - * @return group description string - */ - virtual QString service_getDescription(); - private: RsPostedGroup mGrp; diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index ca987bbe1..29f428486 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -399,7 +399,15 @@ void GxsGroupDialog::addGroupLogo() ui.groupLogo->setIcon(picture); } +QPixmap GxsGroupDialog::getLogo() +{ + return picture; +} +QString GxsGroupDialog::getDescription() +{ + return ui.groupDesc->document()->toPlainText(); +} /*********************************************************************************** Share Lists. diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h index b318b7863..a417621e5 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h @@ -149,24 +149,24 @@ protected: /*! * Main purpose is to help tansfer meta data to service - * and also + * * @param token This should be set to the token retrieved * @param meta The deriving GXS service should set their grp meta to this value */ virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) = 0; /*! - * This should return a group logo \n - * Will be called when GxsGroupDialog is initialised in show mode + * This returns a group logo from the ui \n + * Should be calleld by deriving service * @return The logo for the service */ - virtual QPixmap service_getLogo() = 0; + QPixmap getLogo(); /*! - * This should return a group description string + * This returns a group description string from the ui * @return group description string */ - virtual QString service_getDescription() = 0; + virtual QString getDescription(); private slots: From 8d556955c5bcccf62d0c60e5e17009a25bb95ab2 Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 12 Nov 2012 20:47:55 +0000 Subject: [PATCH 142/222] Big Chunk of GUI work. - Ported Forums to GxsForums. Not functioning yet, waiting on some GXS core functions. - Fixed up plumbing in Wiki. - Minor fixes to TokenQueue git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5812 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/RetroShare.pro | 56 +- retroshare-gui/src/gui/GxsForumsDialog.cpp | 2422 +++++++++++++++++ retroshare-gui/src/gui/GxsForumsDialog.h | 272 ++ retroshare-gui/src/gui/GxsForumsDialog.ui | 1251 +++++++++ .../src/gui/PhotoShare/PhotoDialog.cpp | 3 +- .../src/gui/WikiPoos/WikiDialog.cpp | 645 ++--- retroshare-gui/src/gui/WikiPoos/WikiDialog.h | 31 +- retroshare-gui/src/gui/WikiPoos/WikiDialog.ui | 11 +- .../src/gui/WikiPoos/WikiEditDialog.cpp | 141 +- .../src/gui/WikiPoos/WikiEditDialog.h | 8 +- .../src/gui/gxs/GxsForumGroupDialog.cpp | 83 + .../src/gui/gxs/GxsForumGroupDialog.h | 42 + retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp | 3 + .../src/gui/gxs/WikiGroupDialog.cpp | 79 +- retroshare-gui/src/gui/gxs/WikiGroupDialog.h | 5 - .../src/gui/gxsforums/CreateGxsForum.cpp | 234 ++ .../src/gui/gxsforums/CreateGxsForum.h | 67 + .../src/gui/gxsforums/CreateGxsForum.ui | 374 +++ .../src/gui/gxsforums/CreateGxsForumMsg.cpp | 442 +++ .../src/gui/gxsforums/CreateGxsForumMsg.h | 86 + .../src/gui/gxsforums/CreateGxsForumMsg.ui | 333 +++ .../src/gui/gxsforums/EditGxsForumDetails.cpp | 89 + .../src/gui/gxsforums/EditGxsForumDetails.h | 53 + .../src/gui/gxsforums/EditGxsForumDetails.ui | 130 + .../src/gui/gxsforums/GxsForumDetails.cpp | 146 + .../src/gui/gxsforums/GxsForumDetails.h | 67 + .../src/gui/gxsforums/GxsForumDetails.ui | 201 ++ .../src/gui/unfinished/ApplicationWindow.cpp | 20 +- retroshare-gui/src/util/TokenQueue.cpp | 37 +- retroshare-gui/src/util/TokenQueue.h | 2 +- 30 files changed, 6823 insertions(+), 510 deletions(-) create mode 100644 retroshare-gui/src/gui/GxsForumsDialog.cpp create mode 100644 retroshare-gui/src/gui/GxsForumsDialog.h create mode 100644 retroshare-gui/src/gui/GxsForumsDialog.ui create mode 100644 retroshare-gui/src/gui/gxs/GxsForumGroupDialog.cpp create mode 100644 retroshare-gui/src/gui/gxs/GxsForumGroupDialog.h create mode 100644 retroshare-gui/src/gui/gxsforums/CreateGxsForum.cpp create mode 100644 retroshare-gui/src/gui/gxsforums/CreateGxsForum.h create mode 100644 retroshare-gui/src/gui/gxsforums/CreateGxsForum.ui create mode 100644 retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp create mode 100644 retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.h create mode 100644 retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.ui create mode 100644 retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.cpp create mode 100644 retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.h create mode 100644 retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.ui create mode 100644 retroshare-gui/src/gui/gxsforums/GxsForumDetails.cpp create mode 100644 retroshare-gui/src/gui/gxsforums/GxsForumDetails.h create mode 100644 retroshare-gui/src/gui/gxsforums/GxsForumDetails.ui diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index c695cbc25..c3d92e32e 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -2,10 +2,10 @@ CONFIG += qt gui uic qrc resources uitools idle bitdht # Below is for GXS services. CONFIG += photoshare -#CONFIG += wikipoos +CONFIG += wikipoos #CONFIG += thewire CONFIG += identities -#CONFIG += forumsv2 +CONFIG += gxsforums CONFIG += posted CONFIG += unfinished CONFIG += gxsgui @@ -194,11 +194,11 @@ freebsd-* { # ########################################### bitdht { - #LIBS += ../../libbitdht/src/lib/libbitdht.a - #PRE_TARGETDEPS *= ../../libbitdht/src/lib/libbitdht.a + LIBS += ../../libbitdht/src/lib/libbitdht.a + PRE_TARGETDEPS *= ../../libbitdht/src/lib/libbitdht.a - LIBS += C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a - PRE_TARGETDEPS *= C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a + #LIBS += C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a + #PRE_TARGETDEPS *= C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a # Chris version. #LIBS += ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a @@ -959,25 +959,25 @@ identities { } -forumsv2 { +gxsforums { - HEADERS += gui/ForumsV2Dialog.h \ - gui/forumsv2/ForumV2Details.h \ - gui/forumsv2/EditForumV2Details.h \ - gui/forumsv2/CreateForumV2.h \ - gui/forumsv2/CreateForumV2Msg.h \ + HEADERS += gui/GxsForumsDialog.h \ + gui/gxsforums/GxsForumDetails.h \ + gui/gxsforums/EditGxsForumDetails.h \ + gui/gxsforums/CreateGxsForum.h \ + gui/gxsforums/CreateGxsForumMsg.h \ - FORMS += gui/ForumsV2Dialog.ui \ - gui/forumsv2/ForumV2Details.ui \ - gui/forumsv2/EditForumV2Details.ui \ - gui/forumsv2/CreateForumV2.ui \ - gui/forumsv2/CreateForumV2Msg.ui \ + FORMS += gui/GxsForumsDialog.ui \ + gui/gxsforums/GxsForumDetails.ui \ + gui/gxsforums/EditGxsForumDetails.ui \ + gui/gxsforums/CreateGxsForum.ui \ + gui/gxsforums/CreateGxsForumMsg.ui \ - SOURCES += gui/ForumsV2Dialog.cpp \ - gui/forumsv2/ForumV2Details.cpp \ - gui/forumsv2/EditForumV2Details.cpp \ - gui/forumsv2/CreateForumV2.cpp \ - gui/forumsv2/CreateForumV2Msg.cpp \ + SOURCES += gui/GxsForumsDialog.cpp \ + gui/gxsforums/GxsForumDetails.cpp \ + gui/gxsforums/EditGxsForumDetails.cpp \ + gui/gxsforums/CreateGxsForum.cpp \ + gui/gxsforums/CreateGxsForumMsg.cpp \ } @@ -1014,10 +1014,10 @@ posted { gxsgui { HEADERS += gui/gxs/GxsGroupDialog.h \ - gui/gxs/GxsCommentTreeWidget.h \ - # gui/gxs/WikiGroupDialog.h \ + gui/gxs/GxsCommentTreeWidget.h \ + gui/gxs/WikiGroupDialog.h \ + gui/gxs/GxsForumGroupDialog.h \ -# gui/gxs/ForumV2GroupDialog.h \ # gui/gxs/GxsMsgDialog.h \ FORMS += gui/gxs/GxsGroupDialog.ui \ @@ -1025,10 +1025,10 @@ gxsgui { # gui/gxs/GxsCommentTreeWidget.ui \ SOURCES += gui/gxs/GxsGroupDialog.cpp \ - gui/gxs/GxsCommentTreeWidget.cpp \ - # gui/gxs/WikiGroupDialog.cpp \ + gui/gxs/GxsCommentTreeWidget.cpp \ + gui/gxs/WikiGroupDialog.cpp \ + gui/gxs/GxsForumGroupDialog.cpp \ - #gui/gxs/ForumV2GroupDialog.cpp \ # gui/gxs/GxsMsgDialog.cpp \ diff --git a/retroshare-gui/src/gui/GxsForumsDialog.cpp b/retroshare-gui/src/gui/GxsForumsDialog.cpp new file mode 100644 index 000000000..1ff4ebaa5 --- /dev/null +++ b/retroshare-gui/src/gui/GxsForumsDialog.cpp @@ -0,0 +1,2422 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "GxsForumsDialog.h" + +#include "gxs/GxsForumGroupDialog.h" + +#include "gxsforums/CreateGxsForumMsg.h" + +#include "msgs/MessageComposer.h" +#include "settings/rsharesettings.h" +#include "common/Emoticons.h" +#include "common/RSItemDelegate.h" +#include "common/PopularityDefs.h" +#include "RetroShareLink.h" +#include "channels/ShareKey.h" +#include "notifyqt.h" +#include "util/HandleRichText.h" + +#include +#include + +// These should be in retroshare/ folder. +#include "gxs/rsgxsflags.h" + +#include + +//#define DEBUG_FORUMS + +/* Images for context menu icons */ +#define IMAGE_MESSAGE ":/images/folder-draft.png" +#define IMAGE_MESSAGEREPLY ":/images/mail_reply.png" +#define IMAGE_MESSAGEREMOVE ":/images/mail_delete.png" +#define IMAGE_DOWNLOAD ":/images/start.png" +#define IMAGE_DOWNLOADALL ":/images/startall.png" + +/* Images for TreeWidget */ +#define IMAGE_FOLDER ":/images/folder16.png" +#define IMAGE_FOLDERGREEN ":/images/folder_green.png" +#define IMAGE_FOLDERRED ":/images/folder_red.png" +#define IMAGE_FOLDERYELLOW ":/images/folder_yellow.png" +#define IMAGE_FORUM ":/images/konversation.png" +#define IMAGE_SUBSCRIBE ":/images/edit_add24.png" +#define IMAGE_UNSUBSCRIBE ":/images/cancel.png" +#define IMAGE_INFO ":/images/info16.png" +#define IMAGE_NEWFORUM ":/images/new_forum16.png" +#define IMAGE_FORUMAUTHD ":/images/konv_message2.png" +#define IMAGE_COPYLINK ":/images/copyrslink.png" + +#define VIEW_LAST_POST 0 +#define VIEW_THREADED 1 +#define VIEW_FLAT 2 + +/* Thread constants */ +#define COLUMN_THREAD_COUNT 6 +#define COLUMN_THREAD_TITLE 0 +#define COLUMN_THREAD_READ 1 +#define COLUMN_THREAD_DATE 2 +#define COLUMN_THREAD_AUTHOR 3 +#define COLUMN_THREAD_SIGNED 4 +#define COLUMN_THREAD_CONTENT 5 + +#define COLUMN_THREAD_DATA 0 // column for storing the userdata like msgid and parentid + +#define ROLE_THREAD_MSGID Qt::UserRole +#define ROLE_THREAD_STATUS Qt::UserRole + 1 +#define ROLE_THREAD_MISSING Qt::UserRole + 2 +// no need to copy, don't count in ROLE_THREAD_COUNT +#define ROLE_THREAD_READCHILDREN Qt::UserRole + 3 +#define ROLE_THREAD_UNREADCHILDREN Qt::UserRole + 4 + +#define ROLE_THREAD_COUNT 3 + + +static int FilterColumnFromComboBox(int nIndex) +{ + switch (nIndex) { + case 0: + return COLUMN_THREAD_DATE; + case 1: + return COLUMN_THREAD_TITLE; + case 2: + return COLUMN_THREAD_AUTHOR; + case 3: + return COLUMN_THREAD_CONTENT; + } + + return COLUMN_THREAD_TITLE; +} + +static int FilterColumnToComboBox(int nIndex) +{ + switch (nIndex) { + case COLUMN_THREAD_DATE: + return 0; + case COLUMN_THREAD_TITLE: + return 1; + case COLUMN_THREAD_AUTHOR: + return 2; + case COLUMN_THREAD_CONTENT: + return 3; + } + + return FilterColumnToComboBox(COLUMN_THREAD_TITLE); +} + + +/* + * Transformation Notes: + * there are still a couple of things that the new forums differ from Old version. + * these will need to be addressed in the future. + * -> Missing Messages are not handled yet. + * -> Child TS (for sorting) is not handled by GXS, this will probably have to be done in the GUI. + * -> Need to handle IDs properly. + * -> Popularity not handled in GXS yet. + * -> Much more to do. + */ + +/** Constructor */ +GxsForumsDialog::GxsForumsDialog(QWidget *parent) +: RsAutoUpdatePage(1000,parent) +{ + /* Invoke the Qt Designer generated object setup routine */ + ui.setupUi(this); + + m_bProcessSettings = false; + subscribeFlags = 0; + inMsgAsReadUnread = false; + + + /* Setup Queue */ + mForumQueue = new TokenQueue(rsGxsForums->getTokenService(), this); + + + + connect( ui.forumTreeWidget, SIGNAL( treeCustomContextMenuRequested( QPoint ) ), this, SLOT( forumListCustomPopupMenu( QPoint ) ) ); + connect( ui.threadTreeWidget, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( threadListCustomPopupMenu( QPoint ) ) ); + + connect(ui.newForumButton, SIGNAL(clicked()), this, SLOT(newforum())); + connect(ui.newmessageButton, SIGNAL(clicked()), this, SLOT(createmessage())); + connect(ui.newthreadButton, SIGNAL(clicked()), this, SLOT(createthread())); + + connect( ui.forumTreeWidget, SIGNAL( treeCurrentItemChanged(QString) ), this, SLOT( changedForum(QString) ) ); + + connect( ui.threadTreeWidget, SIGNAL( itemSelectionChanged() ), this, SLOT( changedThread () ) ); + connect( ui.threadTreeWidget, SIGNAL( itemClicked(QTreeWidgetItem*,int)), this, SLOT( clickedThread (QTreeWidgetItem*,int) ) ); + connect( ui.viewBox, SIGNAL( currentIndexChanged ( int ) ), this, SLOT( changedViewBox () ) ); + + connect(ui.expandButton, SIGNAL(clicked()), this, SLOT(togglethreadview())); + connect(ui.previousButton, SIGNAL(clicked()), this, SLOT(previousMessage())); + connect(ui.nextButton, SIGNAL(clicked()), this, SLOT(nextMessage())); + connect(ui.nextUnreadButton, SIGNAL(clicked()), this, SLOT(nextUnreadMessage())); + + connect(ui.downloadButton, SIGNAL(clicked()), this, SLOT(downloadAllFiles())); + + connect(ui.filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterItems(QString))); + connect(ui.filterColumnComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterColumnChanged())); + + connect(NotifyQt::getInstance(), SIGNAL(forumMsgReadSatusChanged(QString,QString,int)), this, SLOT(forumMsgReadSatusChanged(QString,QString,int))); + + /* Set initial size the splitter */ + QList sizes; + sizes << 300 << width(); // Qt calculates the right sizes + //ui.splitter->setSizes(sizes); + + /* Set own item delegate */ + RSItemDelegate *itemDelegate = new RSItemDelegate(this); + itemDelegate->setSpacing(QSize(0, 2)); + ui.threadTreeWidget->setItemDelegate(itemDelegate); + + /* Set header resize modes and initial section sizes */ + QHeaderView * ttheader = ui.threadTreeWidget->header () ; + ttheader->setResizeMode (COLUMN_THREAD_TITLE, QHeaderView::Interactive); + ttheader->resizeSection (COLUMN_THREAD_DATE, 140); + ttheader->resizeSection (COLUMN_THREAD_TITLE, 290); + + ui.threadTreeWidget->sortItems( COLUMN_THREAD_DATE, Qt::DescendingOrder ); + + /* Set text of column "Read" to empty - without this the column has a number as header text */ + QTreeWidgetItem *headerItem = ui.threadTreeWidget->headerItem(); + headerItem->setText(COLUMN_THREAD_READ, ""); + + m_ForumNameFont = QFont("Times", 12, QFont::Bold); + ui.forumName->setFont(m_ForumNameFont); + ui.threadTitle->setFont(m_ForumNameFont); + + /* Initialize group tree */ + ui.forumTreeWidget->initDisplayMenu(ui.displayButton); + + /* create forum tree */ + yourForums = ui.forumTreeWidget->addCategoryItem(tr("Your Forums"), QIcon(IMAGE_FOLDER), true); + subscribedForums = ui.forumTreeWidget->addCategoryItem(tr("Subscribed Forums"), QIcon(IMAGE_FOLDERRED), true); + popularForums = ui.forumTreeWidget->addCategoryItem(tr("Popular Forums"), QIcon(IMAGE_FOLDERGREEN), false); + otherForums = ui.forumTreeWidget->addCategoryItem(tr("Other Forums"), QIcon(IMAGE_FOLDERYELLOW), false); + + lastViewType = -1; + + // load settings + processSettings(true); + + /* Set header sizes for the fixed columns and resize modes, must be set after processSettings */ + ttheader->resizeSection (COLUMN_THREAD_READ, 24); + ttheader->setResizeMode (COLUMN_THREAD_READ, QHeaderView::Fixed); + ttheader->hideSection (COLUMN_THREAD_CONTENT); + + ui.progressBar->hide(); + ui.progLayOutTxt->hide(); + ui.progressBarLayOut->setEnabled(false); + + mThreadLoading = false; + + insertThreads(); + + ui.threadTreeWidget->installEventFilter(this); + + /* Hide platform specific features */ +#ifdef Q_WS_WIN + +#endif +} + +GxsForumsDialog::~GxsForumsDialog() +{ + // save settings + processSettings(false); +} + +void GxsForumsDialog::processSettings(bool bLoad) +{ + m_bProcessSettings = true; + + QHeaderView *pHeader = ui.threadTreeWidget->header () ; + + Settings->beginGroup(QString("GxsForumsDialog")); + + if (bLoad) { + // load settings + + // expandFiles + bool bValue = Settings->value("expandButton", true).toBool(); + ui.expandButton->setChecked(bValue); + togglethreadview_internal(); + + // filterColumn + int nValue = FilterColumnToComboBox(Settings->value("filterColumn", COLUMN_THREAD_TITLE).toInt()); + ui.filterColumnComboBox->setCurrentIndex(nValue); + + // index of viewBox + ui.viewBox->setCurrentIndex(Settings->value("viewBox", VIEW_THREADED).toInt()); + + // state of thread tree + pHeader->restoreState(Settings->value("ThreadTree").toByteArray()); + + // state of splitter + ui.splitter->restoreState(Settings->value("Splitter").toByteArray()); + ui.threadSplitter->restoreState(Settings->value("threadSplitter").toByteArray()); + } else { + // save settings + + // state of thread tree + Settings->setValue("ThreadTree", pHeader->saveState()); + + // state of splitter + Settings->setValue("Splitter", ui.splitter->saveState()); + Settings->setValue("threadSplitter", ui.threadSplitter->saveState()); + } + + ui.forumTreeWidget->processSettings(Settings, bLoad); + + Settings->endGroup(); + m_bProcessSettings = false; +} + +void GxsForumsDialog::forumListCustomPopupMenu( QPoint /*point*/ ) +{ + QMenu contextMnu( this ); + + QAction *action = contextMnu.addAction(QIcon(IMAGE_SUBSCRIBE), tr("Subscribe to Forum"), this, SLOT(subscribeToForum())); + action->setDisabled (mCurrForumId.empty() || IS_GROUP_SUBSCRIBED(subscribeFlags)); + + action = contextMnu.addAction(QIcon(IMAGE_UNSUBSCRIBE), tr("Unsubscribe to Forum"), this, SLOT(unsubscribeToForum())); + action->setEnabled (!mCurrForumId.empty() && IS_GROUP_SUBSCRIBED(subscribeFlags)); + + contextMnu.addSeparator(); + + contextMnu.addAction(QIcon(IMAGE_NEWFORUM), tr("New Forum"), this, SLOT(newforum())); + + action = contextMnu.addAction(QIcon(IMAGE_INFO), tr("Show Forum Details"), this, SLOT(showForumDetails())); + action->setEnabled (!mCurrForumId.empty ()); + + action = contextMnu.addAction(QIcon(":/images/settings16.png"), tr("Edit Forum Details"), this, SLOT(editForumDetails())); + action->setEnabled (!mCurrForumId.empty () && IS_GROUP_ADMIN(subscribeFlags)); + + QAction *shareKeyAct = new QAction(QIcon(":/images/gpgp_key_generate.png"), tr("Share Forum"), &contextMnu); + connect( shareKeyAct, SIGNAL( triggered() ), this, SLOT( shareKey() ) ); + shareKeyAct->setEnabled(!mCurrForumId.empty() && IS_GROUP_ADMIN(subscribeFlags)); + contextMnu.addAction( shareKeyAct); + + QAction *restoreKeysAct = new QAction(QIcon(":/images/settings16.png"), tr("Restore Publish Rights for Forum" ), &contextMnu); + connect( restoreKeysAct , SIGNAL( triggered() ), this, SLOT( restoreForumKeys() ) ); + restoreKeysAct->setEnabled(!mCurrForumId.empty() && !IS_GROUP_ADMIN(subscribeFlags)); + contextMnu.addAction( restoreKeysAct); + + action = contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyForumLink())); + action->setEnabled(!mCurrForumId.empty()); + + contextMnu.addSeparator(); + + action = contextMnu.addAction(QIcon(":/images/message-mail-read.png"), tr("Mark all as read"), this, SLOT(markMsgAsReadAll())); + action->setEnabled (!mCurrForumId.empty () && IS_GROUP_SUBSCRIBED(subscribeFlags)); + + action = contextMnu.addAction(QIcon(":/images/message-mail.png"), tr("Mark all as unread"), this, SLOT(markMsgAsUnreadAll())); + action->setEnabled (!mCurrForumId.empty () && IS_GROUP_SUBSCRIBED(subscribeFlags)); + +#ifdef DEBUG_FORUMS + contextMnu.addSeparator(); + action = contextMnu.addAction("Generate mass data", this, SLOT(generateMassData())); + action->setEnabled (!mCurrForumId.empty() && IS_GROUP_SUBSCRIBED(subscribeFlags)); +#endif + + contextMnu.exec(QCursor::pos()); +} + +void GxsForumsDialog::threadListCustomPopupMenu( QPoint /*point*/ ) +{ + if (mThreadLoading) { + return; + } + + QMenu contextMnu( this ); + + QAction *replyAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr( "Reply" ), &contextMnu ); + connect( replyAct , SIGNAL( triggered() ), this, SLOT( createmessage() ) ); + + QAction *newthreadAct = new QAction(QIcon(IMAGE_DOWNLOADALL), tr( "Start New Thread" ), &contextMnu ); + newthreadAct->setEnabled (IS_GROUP_SUBSCRIBED(subscribeFlags)); + connect( newthreadAct , SIGNAL( triggered() ), this, SLOT( createthread() ) ); + + QAction *replyauthorAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr( "Reply to Author" ), &contextMnu ); + connect( replyauthorAct , SIGNAL( triggered() ), this, SLOT( replytomessage() ) ); + + QAction* expandAll = new QAction(tr( "Expand all" ), &contextMnu ); + connect( expandAll , SIGNAL( triggered() ), ui.threadTreeWidget, SLOT (expandAll()) ); + + QAction* collapseAll = new QAction(tr( "Collapse all" ), &contextMnu ); + connect( collapseAll , SIGNAL( triggered() ), ui.threadTreeWidget, SLOT(collapseAll()) ); + + QAction *markMsgAsRead = new QAction(QIcon(":/images/message-mail-read.png"), tr("Mark as read"), &contextMnu); + connect(markMsgAsRead , SIGNAL(triggered()), this, SLOT(markMsgAsRead())); + + QAction *markMsgAsReadChildren = new QAction(QIcon(":/images/message-mail-read.png"), tr("Mark as read") + " (" + tr ("with children") + ")", &contextMnu); + connect(markMsgAsReadChildren, SIGNAL(triggered()), this, SLOT(markMsgAsReadChildren())); + + QAction *markMsgAsUnread = new QAction(QIcon(":/images/message-mail.png"), tr("Mark as unread"), &contextMnu); + connect(markMsgAsUnread , SIGNAL(triggered()), this, SLOT(markMsgAsUnread())); + + QAction *markMsgAsUnreadChildren = new QAction(QIcon(":/images/message-mail.png"), tr("Mark as unread") + " (" + tr ("with children") + ")", &contextMnu); + connect(markMsgAsUnreadChildren , SIGNAL(triggered()), this, SLOT(markMsgAsUnreadChildren())); + + if (IS_GROUP_SUBSCRIBED(subscribeFlags)) { + QList Rows; + QList RowsRead; + QList RowsUnread; + int nCount = getSelectedMsgCount (&Rows, &RowsRead, &RowsUnread); + + if (RowsUnread.size() == 0) { + + markMsgAsRead->setDisabled(true); + } + if (RowsRead.size() == 0) { + markMsgAsUnread->setDisabled(true); + } + + bool bHasUnreadChildren = false; + bool bHasReadChildren = false; + int nRowCount = Rows.count(); + for (int i = 0; i < nRowCount; i++) { + if (bHasUnreadChildren || Rows[i]->data(COLUMN_THREAD_DATA, ROLE_THREAD_UNREADCHILDREN).toBool()) { + bHasUnreadChildren = true; + } + if (bHasReadChildren || Rows[i]->data(COLUMN_THREAD_DATA, ROLE_THREAD_READCHILDREN).toBool()) { + bHasReadChildren = true; + } + } + markMsgAsReadChildren->setEnabled(bHasUnreadChildren); + markMsgAsUnreadChildren->setEnabled(bHasReadChildren); + + if (nCount == 1) { + replyAct->setEnabled (true); + replyauthorAct->setEnabled (true); + } else { + replyAct->setDisabled (true); + replyauthorAct->setDisabled (true); + } + } else { + markMsgAsRead->setDisabled(true); + markMsgAsReadChildren->setDisabled(true); + markMsgAsUnread->setDisabled(true); + markMsgAsUnreadChildren->setDisabled(true); + replyAct->setDisabled (true); + replyauthorAct->setDisabled (true); + } + + contextMnu.addAction( replyAct); + contextMnu.addAction( newthreadAct); + contextMnu.addAction( replyauthorAct); + QAction* action = contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr( "Copy RetroShare Link"), this, SLOT(copyMessageLink())); + action->setEnabled(!mCurrForumId.empty() && !mCurrThreadId.empty()); + contextMnu.addSeparator(); + contextMnu.addAction(markMsgAsRead); + contextMnu.addAction(markMsgAsReadChildren); + contextMnu.addAction(markMsgAsUnread); + contextMnu.addAction(markMsgAsUnreadChildren); + contextMnu.addSeparator(); + contextMnu.addAction( expandAll); + contextMnu.addAction( collapseAll); + + contextMnu.exec(QCursor::pos()); +} + +bool GxsForumsDialog::eventFilter(QObject *obj, QEvent *event) +{ + if (obj == ui.threadTreeWidget) { + if (event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(event); + if (keyEvent && keyEvent->key() == Qt::Key_Space) { + // Space pressed + QTreeWidgetItem *item = ui.threadTreeWidget->currentItem (); + clickedThread (item, COLUMN_THREAD_READ); + return true; // eat event + } + } + } + // pass the event on to the parent class + return RsAutoUpdatePage::eventFilter(obj, event); +} + +void GxsForumsDialog::restoreForumKeys(void) +{ +#ifdef TOGXS + rsGxsForums->groupRestoreKeys(mCurrForumId); +#endif +} + +void GxsForumsDialog::togglethreadview() +{ + // save state of button + Settings->setValueToGroup("GxsForumsDialog", "expandButton", ui.expandButton->isChecked()); + + togglethreadview_internal(); +} + +void GxsForumsDialog::togglethreadview_internal() +{ + if (ui.expandButton->isChecked()) { + ui.postText->setVisible(true); + ui.expandButton->setIcon(QIcon(QString(":/images/edit_remove24.png"))); + ui.expandButton->setToolTip(tr("Hide")); + } else { + ui.postText->setVisible(false); + ui.expandButton->setIcon(QIcon(QString(":/images/edit_add24.png"))); + ui.expandButton->setToolTip(tr("Expand")); + } +} + +void GxsForumsDialog::updateDisplay() +{ + std::list forumIds; + std::list::iterator it; + if (!rsGxsForums) + return; + +#if 0 + // TODO groupsChanged... HACK XXX. + if ((rsGxsForums->groupsChanged(forumIds)) || (rsGxsForums->updated())) + { + /* update Forums List */ + insertForums(); + + it = std::find(forumIds.begin(), forumIds.end(), mCurrForumId); + if (it != forumIds.end()) + { + /* update threads as well */ + insertThreads(); + } + } +#endif + + /* The proper version (above) can be done with a data request -> TODO */ + if (rsGxsForums->updated()) + { + /* update Forums List */ + insertForums(); + /* update threads as well */ + insertThreads(); + } +} + +static void CleanupItems (QList &items) +{ + QList::iterator item; + for (item = items.begin (); item != items.end (); item++) { + if (*item) { + delete (*item); + } + } + items.clear(); +} + +void GxsForumsDialog::forumInfoToGroupItemInfo(const RsGroupMetaData &forumInfo, GroupItemInfo &groupItemInfo) +//void GxsForumsDialog::forumInfoToGroupItemInfo(const ForumInfo &forumInfo, GroupItemInfo &groupItemInfo) +{ + + groupItemInfo.id = QString::fromStdString(forumInfo.mGroupId); + groupItemInfo.name = QString::fromUtf8(forumInfo.mGroupName.c_str()); + //groupItemInfo.description = QString::fromUtf8(forumInfo.forumDesc); + groupItemInfo.popularity = forumInfo.mPop; + groupItemInfo.lastpost = QDateTime::fromTime_t(forumInfo.mLastPost); + +#if TOGXS + if (forumInfo.mGroupFlags & RS_DISTRIB_AUTHEN_REQ) { + groupItemInfo.name += " (" + tr("AUTHD") + ")"; + groupItemInfo.icon = QIcon(IMAGE_FORUMAUTHD); + } + else +#endif + { + groupItemInfo.icon = QIcon(IMAGE_FORUM); + } + +// groupItemInfo.id = QString::fromStdString(forumInfo.forumId); +// groupItemInfo.name = QString::fromStdWString(forumInfo.forumName); +// groupItemInfo.description = QString::fromStdWString(forumInfo.forumDesc); +// groupItemInfo.popularity = forumInfo.pop; +// groupItemInfo.lastpost = QDateTime::fromTime_t(forumInfo.lastPost); +// +// if (forumInfo.forumFlags & RS_DISTRIB_AUTHEN_REQ) { +// groupItemInfo.name += " (" + tr("AUTHD") + ")"; +// groupItemInfo.icon = QIcon(IMAGE_FORUMAUTHD); +// } else { +// groupItemInfo.icon = QIcon(IMAGE_FORUM); +// } +} + + +/***** INSERT FORUM LISTS *****/ +void GxsForumsDialog::insertForumsData(const std::list &forumList) +{ + std::list::const_iterator it; + + QList adminList; + QList subList; + QList popList; + QList otherList; + std::multimap popMap; + + for (it = forumList.begin(); it != forumList.end(); it++) { + /* sort it into Publish (Own), Subscribed, Popular and Other */ + uint32_t flags = it->mSubscribeFlags; + + GroupItemInfo groupItemInfo; + forumInfoToGroupItemInfo(*it, groupItemInfo); + + if (IS_GROUP_ADMIN(flags)) { + adminList.push_back(groupItemInfo); + } else if (IS_GROUP_SUBSCRIBED(flags)) { + /* subscribed forum */ + subList.push_back(groupItemInfo); + } else { + /* rate the others by popularity */ + popMap.insert(std::make_pair(it->mPop, groupItemInfo)); + } + } + + /* iterate backwards through popMap - take the top 5 or 10% of list */ + uint32_t popCount = 5; + if (popCount < popMap.size() / 10) + { + popCount = popMap.size() / 10; + } + + uint32_t i = 0; + uint32_t popLimit = 0; + std::multimap::reverse_iterator rit; + for(rit = popMap.rbegin(); ((rit != popMap.rend()) && (i < popCount)); rit++, i++) ; + if (rit != popMap.rend()) { + popLimit = rit->first; + } + + for (rit = popMap.rbegin(); rit != popMap.rend(); rit++) { + if (rit->second.popularity < (int) popLimit) { + otherList.append(rit->second); + } else { + popList.append(rit->second); + } + } + + /* now we can add them in as a tree! */ + ui.forumTreeWidget->fillGroupItems(yourForums, adminList); + ui.forumTreeWidget->fillGroupItems(subscribedForums, subList); + ui.forumTreeWidget->fillGroupItems(popularForums, popList); + ui.forumTreeWidget->fillGroupItems(otherForums, otherList); + + updateMessageSummaryList(""); +} + +void GxsForumsDialog::changedForum(const QString &id) +{ + mCurrForumId = id.toStdString(); + + insertThreads(); +} + +void GxsForumsDialog::changedThread () +{ + if (mThreadLoading) { + return; + } + + /* just grab the ids of the current item */ + QTreeWidgetItem *curr = ui.threadTreeWidget->currentItem(); + + if ((!curr) || (!curr->isSelected())) { + mCurrThreadId = ""; + } else { + mCurrThreadId = curr->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString(); + } + insertPost(); +} + +void GxsForumsDialog::clickedThread (QTreeWidgetItem *item, int column) +{ + if (mCurrForumId.empty() || !IS_GROUP_SUBSCRIBED(subscribeFlags)) { + return; + } + + if (item == NULL) { + return; + } + + if (column == COLUMN_THREAD_READ) { + QList Rows; + Rows.append(item); + uint32_t status = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + setMsgReadStatus(Rows, IS_MSG_UNREAD(status)); + return; + } +} + +void GxsForumsDialog::forumMsgReadStatusChanged(const QString &forumId, const QString &msgId, int status) +{ + if (inMsgAsReadUnread) { + return; + } + + if (forumId.toStdString() == mCurrForumId) { + /* Search exisiting item */ + QTreeWidgetItemIterator itemIterator(ui.threadTreeWidget); + QTreeWidgetItem *item = NULL; + while ((item = *itemIterator) != NULL) { + itemIterator++; + + if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString() == msgId) { + // update status + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, status); + + QTreeWidgetItem *parentItem = item; + while (parentItem->parent()) { + parentItem = parentItem->parent(); + } + CalculateIconsAndFonts(parentItem); + break; + } + } + } + updateMessageSummaryList(forumId.toStdString()); +} + +void GxsForumsDialog::CalculateIconsAndFonts(QTreeWidgetItem *pItem, bool &bHasReadChilddren, bool &bHasUnreadChilddren) +{ + uint32_t status = pItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + + bool bUnread = IS_MSG_UNREAD(status); + bool missing = pItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING).toBool(); + + // set icon + if (missing) { + pItem->setIcon(COLUMN_THREAD_READ, QIcon()); + pItem->setIcon(COLUMN_THREAD_TITLE, QIcon()); + } else { + if (bUnread) { + pItem->setIcon(COLUMN_THREAD_READ, QIcon(":/images/message-state-unread.png")); + } else { + pItem->setIcon(COLUMN_THREAD_READ, QIcon(":/images/message-state-read.png")); + } + if (IS_MSG_UNREAD(status)) { + pItem->setIcon(COLUMN_THREAD_TITLE, QIcon(":/images/message-state-new.png")); + } else { + pItem->setIcon(COLUMN_THREAD_TITLE, QIcon()); + } + } + + int nItem; + int nItemCount = pItem->childCount(); + + bool bMyReadChilddren = false; + bool bMyUnreadChilddren = false; + + for (nItem = 0; nItem < nItemCount; nItem++) { + CalculateIconsAndFonts(pItem->child(nItem), bMyReadChilddren, bMyUnreadChilddren); + } + + // set font + for (int i = 0; i < COLUMN_THREAD_COUNT; i++) { + QFont qf = pItem->font(i); + + if (!IS_GROUP_SUBSCRIBED(subscribeFlags)) { + qf.setBold(false); + pItem->setTextColor(i, Qt::black); + } else if (bUnread) { + qf.setBold(true); + pItem->setTextColor(i, Qt::black); + } else if (bMyUnreadChilddren) { + qf.setBold(true); + pItem->setTextColor(i, Qt::gray); + } else { + qf.setBold(false); + pItem->setTextColor(i, Qt::gray); + } + if (missing) { + /* Missing message */ + pItem->setTextColor(i, Qt::darkRed); + } + pItem->setFont(i, qf); + } + + pItem->setData(COLUMN_THREAD_DATA, ROLE_THREAD_READCHILDREN, bHasReadChilddren || bMyReadChilddren); + pItem->setData(COLUMN_THREAD_DATA, ROLE_THREAD_UNREADCHILDREN, bHasUnreadChilddren || bMyUnreadChilddren); + + bHasReadChilddren = bHasReadChilddren || bMyReadChilddren || !bUnread; + bHasUnreadChilddren = bHasUnreadChilddren || bMyUnreadChilddren || bUnread; +} + +void GxsForumsDialog::CalculateIconsAndFonts(QTreeWidgetItem *pItem /*= NULL*/) +{ + bool bDummy1 = false; + bool bDummy2 = false; + + if (pItem) { + CalculateIconsAndFonts(pItem, bDummy1, bDummy2); + return; + } + + int nItem; + int nItemCount = ui.threadTreeWidget->topLevelItemCount(); + + for (nItem = 0; nItem < nItemCount; nItem++) { + bDummy1 = false; + bDummy2 = false; + CalculateIconsAndFonts(ui.threadTreeWidget->topLevelItem(nItem), bDummy1, bDummy2); + } +} + +void GxsForumsDialog::fillThreadFinished() +{ +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumsDialog::fillThreadFinished" << std::endl; +#endif + + // This is now only called with a successful Load. + // cleanup of incomplete is handled elsewhere. + + // current thread has finished, hide progressbar and release thread + ui.progressBar->hide(); + ui.progLayOutTxt->hide(); + ui.progressBarLayOut->setEnabled(false); + +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumsDialog::fillThreadFinished Add messages" << std::endl; +#endif + ui.threadTreeWidget->setSortingEnabled(false); + + /* add all messages in! */ + if (lastViewType != mThreadLoad.ViewType || lastForumID != mCurrForumId) + { + ui.threadTreeWidget->clear(); + lastViewType = mThreadLoad.ViewType; + lastForumID = mCurrForumId; + ui.threadTreeWidget->insertTopLevelItems(0, mThreadLoad.Items); + + // clear list + mThreadLoad.Items.clear(); + } + else + { + FillThreads (mThreadLoad.Items, mThreadLoad.ExpandNewMessages, mThreadLoad.ItemToExpand); + + // cleanup list + CleanupItems (mThreadLoad.Items); + } + + ui.threadTreeWidget->setSortingEnabled(true); + + if (mThreadLoad.FocusMsgId.empty() == false) + { + /* Search exisiting item */ + QTreeWidgetItemIterator itemIterator(ui.threadTreeWidget); + QTreeWidgetItem *item = NULL; + while ((item = *itemIterator) != NULL) + { + itemIterator++; + + if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString() == mThreadLoad.FocusMsgId) + { + ui.threadTreeWidget->setCurrentItem(item); + ui.threadTreeWidget->setFocus(); + break; + } + } + } + + QList::iterator Item; + for (Item = mThreadLoad.ItemToExpand.begin(); Item != mThreadLoad.ItemToExpand.end(); Item++) + { + if ((*Item)->isHidden() == false) + { + (*Item)->setExpanded(true); + } + } + mThreadLoad.ItemToExpand.clear(); + + if (ui.filterLineEdit->text().isEmpty() == false) { + filterItems(ui.filterLineEdit->text()); + } + + insertPost (); + CalculateIconsAndFonts(); + + ui.newthreadButton->setEnabled (IS_GROUP_SUBSCRIBED(subscribeFlags)); + + mThreadLoading = false; + +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumsDialog::fillThreadFinished done" << std::endl; +#endif +} + +void GxsForumsDialog::fillThreadProgress(int current, int count) +{ + // show fill progress + if (count) { + ui.progressBar->setValue(current * ui.progressBar->maximum() / count); + } + +} + +void GxsForumsDialog::insertThreads() +{ +#ifdef DEBUG_FORUMS + /* get the current Forum */ + std::cerr << "GxsForumsDialog::insertThreads()" << std::endl; +#endif + + subscribeFlags = 0; + + ui.newmessageButton->setEnabled (false); + ui.newthreadButton->setEnabled (false); + + ui.postText->clear(); + ui.threadTitle->clear(); + + if (mCurrForumId.empty()) + { + /* not an actual forum - clear */ + ui.threadTreeWidget->clear(); + /* when no Thread selected - clear */ + ui.forumName->clear(); + /* clear last stored forumID */ + mCurrForumId.erase(); + lastForumID.erase(); + +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumsDialog::insertThreads() Current Thread Invalid" << std::endl; +#endif + + return; + } + + // Get Current Forum Info... then complete insertForumThreads(). + requestGroupSummary_CurrentForum(mCurrForumId); +} + + +void GxsForumsDialog::insertForumThreads(const RsGroupMetaData &fi) +{ + subscribeFlags = fi.mSubscribeFlags; + ui.forumName->setText(QString::fromUtf8(fi.mGroupName.c_str())); + + ui.progressBarLayOut->setEnabled(true); + + ui.progLayOutTxt->show(); + ui.progressBar->reset(); + ui.progressBar->show(); + +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumsDialog::insertThreads() Start filling Forum threads" << std::endl; +#endif + + loadCurrentForumThreads(fi.mGroupId); +} + + + + +void GxsForumsDialog::FillThreads(QList &ThreadList, bool expandNewMessages, QList &itemToExpand) +{ +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumsDialog::FillThreads()" << std::endl; +#endif + + int Index = 0; + QTreeWidgetItem *Thread; + QList::iterator NewThread; + + // delete not existing + while (Index < ui.threadTreeWidget->topLevelItemCount ()) { + Thread = ui.threadTreeWidget->topLevelItem (Index); + + // search existing new thread + int Found = -1; + for (NewThread = ThreadList.begin (); NewThread != ThreadList.end (); NewThread++) { + if (Thread->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == (*NewThread)->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { + // found it + Found = Index; + break; + } + } + if (Found >= 0) { + Index++; + } else { + delete (ui.threadTreeWidget->takeTopLevelItem (Index)); + } + } + + // iterate all new threads + for (NewThread = ThreadList.begin (); NewThread != ThreadList.end (); NewThread++) { + // search existing thread + int Found = -1; + int Count = ui.threadTreeWidget->topLevelItemCount (); + for (Index = 0; Index < Count; Index++) { + Thread = ui.threadTreeWidget->topLevelItem (Index); + if (Thread->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == (*NewThread)->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { + // found it + Found = Index; + break; + } + } + + if (Found >= 0) { + // set child data + int i; + for (i = 0; i < COLUMN_THREAD_COUNT; i++) { + Thread->setText (i, (*NewThread)->text (i)); + } + for (i = 0; i < ROLE_THREAD_COUNT; i++) { + Thread->setData (COLUMN_THREAD_DATA, Qt::UserRole + i, (*NewThread)->data (COLUMN_THREAD_DATA, Qt::UserRole + i)); + } + + // fill recursive + FillChildren (Thread, *NewThread, expandNewMessages, itemToExpand); + } else { + // add new thread + ui.threadTreeWidget->addTopLevelItem (*NewThread); + Thread = *NewThread; + *NewThread = NULL; + } + + uint32_t status = Thread->data (COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + if (expandNewMessages && IS_MSG_UNREAD(status)) { + QTreeWidgetItem *pParent = Thread; + while ((pParent = pParent->parent()) != NULL) { + if (std::find(itemToExpand.begin(), itemToExpand.end(), pParent) == itemToExpand.end()) { + itemToExpand.push_back(pParent); + } + } + } + } + +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumsDialog::FillThreads() done" << std::endl; +#endif +} + +void GxsForumsDialog::FillChildren(QTreeWidgetItem *Parent, QTreeWidgetItem *NewParent, bool expandNewMessages, QList &itemToExpand) +{ + int Index = 0; + int NewIndex; + int NewCount = NewParent->childCount(); + + QTreeWidgetItem *Child; + QTreeWidgetItem *NewChild; + + // delete not existing + while (Index < Parent->childCount ()) { + Child = Parent->child (Index); + + // search existing new child + int Found = -1; + int Count = NewParent->childCount(); + for (NewIndex = 0; NewIndex < Count; NewIndex++) { + NewChild = NewParent->child (NewIndex); + if (NewChild->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == Child->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { + // found it + Found = Index; + break; + } + } + if (Found >= 0) { + Index++; + } else { + delete (Parent->takeChild (Index)); + } + } + + // iterate all new children + for (NewIndex = 0; NewIndex < NewCount; NewIndex++) { + NewChild = NewParent->child (NewIndex); + + // search existing child + int Found = -1; + int Count = Parent->childCount(); + for (Index = 0; Index < Count; Index++) { + Child = Parent->child (Index); + if (Child->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == NewChild->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { + // found it + Found = Index; + break; + } + } + + if (Found >= 0) { + // set child data + int i; + for (i = 0; i < COLUMN_THREAD_COUNT; i++) { + Child->setText (i, NewChild->text (i)); + } + for (i = 0; i < ROLE_THREAD_COUNT; i++) { + Child->setData (COLUMN_THREAD_DATA, Qt::UserRole + i, NewChild->data (COLUMN_THREAD_DATA, Qt::UserRole + i)); + } + + // fill recursive + FillChildren (Child, NewChild, expandNewMessages, itemToExpand); + } else { + // add new child + Child = NewParent->takeChild(NewIndex); + Parent->addChild (Child); + NewIndex--; + NewCount--; + } + + uint32_t status = Child->data (COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + if (expandNewMessages && IS_MSG_UNREAD(status)) { + QTreeWidgetItem *pParent = Child; + while ((pParent = pParent->parent()) != NULL) { + if (std::find(itemToExpand.begin(), itemToExpand.end(), pParent) == itemToExpand.end()) { + itemToExpand.push_back(pParent); + } + } + } + } +} + +QString GxsForumsDialog::titleFromInfo(const RsMsgMetaData &meta) +{ + // NOTE - NOTE SURE HOW THIS WILL WORK! +#ifdef TOGXS + if (meta.mMsgStatus & RS_DISTRIB_MISSING_MSG) { + return QApplication::translate("GxsForumsDialog", "[ ... Missing Message ... ]"); + } +#endif + + return QString::fromUtf8(meta.mMsgName.c_str()); +} + +QString GxsForumsDialog::messageFromInfo(const RsGxsForumMsg &msg) +{ +#ifdef TOGXS + if (msg.mMeta.mMsgStatus & RS_DISTRIB_MISSING_MSG) { + return QApplication::translate("GxsForumsDialog", "Placeholder for missing Message"); + } +#endif + + return QString::fromUtf8(msg.mMsg.c_str()); +} + +void GxsForumsDialog::insertPost() +{ + if ((mCurrForumId == "") || (mCurrThreadId == "")) + { + ui.postText->setText(""); + ui.threadTitle->setText(""); + ui.previousButton->setEnabled(false); + ui.nextButton->setEnabled(false); + ui.newmessageButton->setEnabled (false); + return; + } + + QTreeWidgetItem *curr = ui.threadTreeWidget->currentItem(); + if (curr) { + QTreeWidgetItem *Parent = curr->parent (); + int Index = Parent ? Parent->indexOfChild (curr) : ui.threadTreeWidget->indexOfTopLevelItem (curr); + int Count = Parent ? Parent->childCount () : ui.threadTreeWidget->topLevelItemCount (); + ui.previousButton->setEnabled (Index > 0); + ui.nextButton->setEnabled (Index < Count - 1); + } else { + // there is something wrong + ui.previousButton->setEnabled(false); + ui.nextButton->setEnabled(false); + return; + } + + ui.newmessageButton->setEnabled (IS_GROUP_SUBSCRIBED(subscribeFlags) && mCurrThreadId.empty() == false); + + /* blank text, incase we get nothing */ + ui.postText->setText(""); + /* request Post */ + + RsGxsGrpMsgIdPair postId = std::make_pair(mCurrForumId, mCurrThreadId); + requestMsgData_InsertPost(postId); + +} + + + +void GxsForumsDialog::insertPostData(const RsGxsForumMsg &msg) +{ + /* As some time has elapsed since request - check that this is still the current msg. + * otherwise, another request will fill the data + */ + + if ((msg.mMeta.mGroupId != mCurrForumId) || (msg.mMeta.mMsgId != mCurrThreadId)) + { + std::cerr << "GxsForumsDialog::insertPostData() Ignoring Invalid Data...."; + std::cerr << std::endl; + std::cerr << "\t CurrForumId: " << mCurrForumId << " != msg.GroupId: " << msg.mMeta.mGroupId; + std::cerr << std::endl; + std::cerr << "\t or CurrThdId: " << mCurrThreadId << " != msg.MsgId: " << msg.mMeta.mMsgId; + std::cerr << std::endl; + std::cerr << std::endl; + return; + } + + QTreeWidgetItem *curr = ui.threadTreeWidget->currentItem(); + + bool bSetToReadOnActive = Settings->getForumMsgSetToReadOnActivate(); + uint32_t status = curr->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + + QList Row; + Row.append(curr); + + if (bSetToReadOnActive && IS_MSG_UNREAD(status)) + { + setMsgReadStatus(Row, true); + } + + QString extraTxt = RsHtml().formatText(ui.postText->document(), messageFromInfo(msg), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS); + + ui.postText->setHtml(extraTxt); + ui.threadTitle->setText(titleFromInfo(msg.mMeta)); +} + + +void GxsForumsDialog::previousMessage () +{ + QTreeWidgetItem *Item = ui.threadTreeWidget->currentItem (); + if (Item == NULL) { + return; + } + + QTreeWidgetItem *Parent = Item->parent (); + int Index = Parent ? Parent->indexOfChild (Item) : ui.threadTreeWidget->indexOfTopLevelItem (Item); + if (Index > 0) { + QTreeWidgetItem *Previous = Parent ? Parent->child (Index - 1) : ui.threadTreeWidget->topLevelItem (Index - 1); + if (Previous) { + ui.threadTreeWidget->setCurrentItem (Previous); + } + } +} + +void GxsForumsDialog::nextMessage () +{ + QTreeWidgetItem *Item = ui.threadTreeWidget->currentItem (); + if (Item == NULL) { + return; + } + + QTreeWidgetItem *Parent = Item->parent (); + int Index = Parent ? Parent->indexOfChild (Item) : ui.threadTreeWidget->indexOfTopLevelItem (Item); + int Count = Parent ? Parent->childCount () : ui.threadTreeWidget->topLevelItemCount (); + if (Index < Count - 1) { + QTreeWidgetItem *Next = Parent ? Parent->child (Index + 1) : ui.threadTreeWidget->topLevelItem (Index + 1); + if (Next) { + ui.threadTreeWidget->setCurrentItem (Next); + } + } +} + +void GxsForumsDialog::downloadAllFiles() +{ + QStringList urls; + if (RsHtml::findAnchors(ui.postText->toHtml(), urls) == false) { + return; + } + + if (urls.count() == 0) { + return; + } + + RetroShareLink::process(urls, RetroShareLink::TYPE_FILE/*, true*/); +} + +void GxsForumsDialog::nextUnreadMessage() +{ + QTreeWidgetItem* currentItem = ui.threadTreeWidget->currentItem(); + if( !currentItem ) + { + currentItem = ui.threadTreeWidget->topLevelItem(0); + if( !currentItem ) + return; + } + + do + { + uint32_t status = currentItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + if( IS_MSG_UNREAD(status) ) + { + ui.threadTreeWidget->setCurrentItem(currentItem); + return; + } + } while( (currentItem = ui.threadTreeWidget->itemBelow(currentItem)) != NULL ); +} + +// TODO +#if 0 +void GxsForumsDialog::removemessage() +{ + //std::cerr << "GxsForumsDialog::removemessage()" << std::endl; + std::string cid, mid; + if (!getCurrentMsg(cid, mid)) + { + //std::cerr << "GxsForumsDialog::removemessage()"; + //std::cerr << " No Message selected" << std::endl; + return; + } + + rsMsgs -> MessageDelete(mid); +} +#endif + +/* get selected messages + the messages tree is single selected, but who knows ... */ +int GxsForumsDialog::getSelectedMsgCount(QList *pRows, QList *pRowsRead, QList *pRowsUnread) +{ + if (pRowsRead) pRowsRead->clear(); + if (pRowsUnread) pRowsUnread->clear(); + + QList selectedItems = ui.threadTreeWidget->selectedItems(); + for(QList::iterator it = selectedItems.begin(); it != selectedItems.end(); it++) { + if (pRows) pRows->append(*it); + if (pRowsRead || pRowsUnread) { + uint32_t status = (*it)->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + if (IS_MSG_UNREAD(status)) { + if (pRowsUnread) pRowsUnread->append(*it); + } else { + if (pRowsRead) pRowsRead->append(*it); + } + } + } + + return selectedItems.size(); +} + +void GxsForumsDialog::setMsgReadStatus(QList &Rows, bool bRead) +{ + QList::iterator Row; + std::list changedItems; + + inMsgAsReadUnread = true; + + for (Row = Rows.begin(); Row != Rows.end(); Row++) { + if ((*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING).toBool()) { + /* Missing message */ + continue; + } + + uint32_t status = (*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + + uint32_t statusNew = (status & ~GXS_SERV::GXS_MSG_STATUS_UNREAD); // orig status, without UNREAD. + if (!bRead) { + statusNew |= GXS_SERV::GXS_MSG_STATUS_UNREAD; + } + + if (IS_MSG_UNREAD(status) == bRead) // is it different? + { + std::string msgId = (*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString(); + + // NB: MUST BE PART OF ACTIVE THREAD--- OR ELSE WE MUST STORE GROUPID SOMEWHERE!. + // LIKE THIS BELOW... + //std::string grpId = (*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_GROUPID).toString().toStdString(); + + RsGxsGrpMsgIdPair msgPair = std::make_pair(mCurrForumId, msgId); + + uint32_t token; + rsGxsForums->setMessageReadStatus(token, msgPair, bRead); + + (*Row)->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, statusNew); + + QTreeWidgetItem *parentItem = *Row; + while (parentItem->parent()) { + parentItem = parentItem->parent(); + } + if (std::find(changedItems.begin(), changedItems.end(), parentItem) == changedItems.end()) { + changedItems.push_back(parentItem); + } + } + } + + inMsgAsReadUnread = false; + + if (changedItems.size()) { + for (std::list::iterator it = changedItems.begin(); it != changedItems.end(); it++) { + CalculateIconsAndFonts(*it); + } + updateMessageSummaryList(mCurrForumId); + } +} + +void GxsForumsDialog::markMsgAsReadUnread (bool bRead, bool bChildren, bool bForum) +{ + if (mCurrForumId.empty() || !IS_GROUP_SUBSCRIBED(subscribeFlags)) { + return; + } + + /* get selected messages */ + QList Rows; + if (bForum) { + int itemCount = ui.threadTreeWidget->topLevelItemCount(); + for (int item = 0; item < itemCount; item++) { + Rows.push_back(ui.threadTreeWidget->topLevelItem(item)); + } + } else { + getSelectedMsgCount (&Rows, NULL, NULL); + } + + if (bChildren) { + /* add children */ + QList AllRows; + + while (Rows.isEmpty() == false) { + QTreeWidgetItem *pRow = Rows.takeFirst(); + + /* add only items with the right state or with not RSGXS_MSG_STATUS_READ */ + uint32_t status = pRow->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + if (IS_MSG_UNREAD(status) == bRead) { + AllRows.append(pRow); + } + + for (int i = 0; i < pRow->childCount(); i++) { + /* add child to main list and let the main loop do the work */ + Rows.append(pRow->child(i)); + } + } + + if (AllRows.isEmpty()) { + /* nothing to do */ + return; + } + + setMsgReadStatus(AllRows, bRead); + + return; + } + + setMsgReadStatus(Rows, bRead); +} + +void GxsForumsDialog::markMsgAsRead() +{ + markMsgAsReadUnread(true, false, false); +} + +void GxsForumsDialog::markMsgAsReadChildren() +{ + markMsgAsReadUnread(true, true, false); +} + +void GxsForumsDialog::markMsgAsReadAll() +{ + markMsgAsReadUnread(true, true, true); +} + +void GxsForumsDialog::markMsgAsUnread() +{ + markMsgAsReadUnread(false, false, false); +} + +void GxsForumsDialog::markMsgAsUnreadChildren() +{ + markMsgAsReadUnread(false, true, false); +} + +void GxsForumsDialog::markMsgAsUnreadAll() +{ + markMsgAsReadUnread(false, true, true); +} + +void GxsForumsDialog::copyForumLink() +{ + if (mCurrForumId.empty()) { + return; + } + +// THIS CODE CALLS getForumInfo() to verify that the Ids are valid. +// As we are switching to Request/Response this is now harder to do... +// So not bothering any more - shouldn't be necessary. +// IF we get errors - fix them, rather than patching here. +#if 0 + ForumInfo fi; + if (rsGxsForums->getForumInfo(mCurrForumId, fi)) { + RetroShareLink link; + if (link.createForum(fi.forumId, "")) { + QList urls; + urls.push_back(link); + RSLinkClipboard::copyLinks(urls); + } + } +#endif + + { + RetroShareLink link; + if (link.createForum(mCurrForumId, "")) + { + QList urls; + urls.push_back(link); + RSLinkClipboard::copyLinks(urls); + } + } +} + + + + +void GxsForumsDialog::copyMessageLink() +{ + if (mCurrForumId.empty() || mCurrThreadId.empty()) { + return; + } + +// SEE NOTE In fn above. +#if 0 + ForumInfo fi; + if (rsGxsForums->getForumInfo(mCurrForumId, fi)) { + RetroShareLink link; + if (link.createForum(mCurrForumId, mCurrThreadId)) { + QList urls; + urls.push_back(link); + RSLinkClipboard::copyLinks(urls); + } + } +#endif + + { + RetroShareLink link; + if (link.createForum(mCurrForumId, mCurrThreadId)) + { + QList urls; + urls.push_back(link); + RSLinkClipboard::copyLinks(urls); + } + } +} + + +void GxsForumsDialog::newforum() +{ + GxsForumGroupDialog cf (mForumQueue, this); + //cf.newGroup(); + + cf.exec (); +} + +void GxsForumsDialog::createmessage() +{ + if (mCurrForumId.empty () || !IS_GROUP_SUBSCRIBED(subscribeFlags)) { + return; + } + + CreateGxsForumMsg *cfm = new CreateGxsForumMsg(mCurrForumId, mCurrThreadId); + cfm->show(); + + /* window will destroy itself! */ +} + +void GxsForumsDialog::createthread() +{ + if (mCurrForumId.empty ()) { + QMessageBox::information(this, tr("RetroShare"), tr("No Forum Selected!")); + return; + } + + CreateGxsForumMsg *cfm = new CreateGxsForumMsg(mCurrForumId, ""); + cfm->setWindowTitle(tr("Start New Thread")); + cfm->show(); + + /* window will destroy itself! */ +} + +void GxsForumsDialog::subscribeToForum() +{ + forumSubscribe(true); +} + +void GxsForumsDialog::unsubscribeToForum() +{ + forumSubscribe(false); +} + +void GxsForumsDialog::forumSubscribe(bool subscribe) +{ + if (mCurrForumId.empty()) { + return; + } + + uint32_t token; + rsGxsForums->subscribeToGroup(token, mCurrForumId, subscribe); +} + +void GxsForumsDialog::showForumDetails() +{ + if (mCurrForumId.empty()) { + return; + } + + RsGxsForumGroup grp; + grp.mMeta.mGroupId = mCurrForumId; + + GxsForumGroupDialog cf(grp, this); + + cf.exec (); +} + +void GxsForumsDialog::editForumDetails() +{ + if (mCurrForumId.empty()) { + return; + } + + RsGxsForumGroup grp; + grp.mMeta.mGroupId = mCurrForumId; + + GxsForumGroupDialog cf(grp, this); + + //GxsForumGroupDialog cf (mForumQueue, this, mCurrForumId, GXS_GROUP_DIALOG_EDIT_MODE); + + cf.exec (); +} + +static QString buildReplyHeader(const RsMsgMetaData &meta) +{ + RetroShareLink link; + link.createMessage(meta.mAuthorId, ""); + QString from = link.toHtml(); + + QDateTime qtime; + qtime.setTime_t(meta.mPublishTs); + + QString header = QString("-----%1-----").arg(QApplication::translate("GxsForumsDialog", "Original Message")); + header += QString("
%1: %2
").arg(QApplication::translate("GxsForumsDialog", "From"), from); + + header += QString("
%1: %2
").arg(QApplication::translate("GxsForumsDialog", "Sent"), qtime.toString(Qt::SystemLocaleLongDate)); + header += QString("%1: %2

").arg(QApplication::translate("GxsForumsDialog", "Subject"), QString::fromUtf8(meta.mMsgName.c_str())); + header += "
"; + + header += QApplication::translate("GxsForumsDialog", "On %1, %2 wrote:").arg(qtime.toString(Qt::SystemLocaleShortDate), from); + + return header; +} + +void GxsForumsDialog::replytomessage() +{ + if (mCurrForumId.empty() || mCurrThreadId.empty()) { + QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to a non-existant Message")); + return; + } + + RsGxsGrpMsgIdPair postId = std::make_pair(mCurrForumId, mCurrThreadId); + requestMsgData_ReplyMessage(postId); +} + +void GxsForumsDialog::replyMessageData(const RsGxsForumMsg &msg) +{ + if ((msg.mMeta.mGroupId != mCurrForumId) || (msg.mMeta.mMsgId != mCurrThreadId)) + { + std::cerr << "GxsForumsDialog::replyMessageData() ERROR Message Ids have changed!"; + std::cerr << std::endl; + return; + } + + // NB: TODO REMOVE rsPeers references. + if (rsPeers->getPeerName(msg.mMeta.mAuthorId) !="") + { + MessageComposer *nMsgDialog = MessageComposer::newMsg(); + nMsgDialog->setTitleText(QString::fromUtf8(msg.mMeta.mMsgName.c_str()), MessageComposer::REPLY); + + nMsgDialog->setQuotedMsg(QString::fromUtf8(msg.mMsg.c_str()), buildReplyHeader(msg.mMeta)); + + nMsgDialog->addRecipient(MessageComposer::TO, msg.mMeta.mAuthorId, false); + nMsgDialog->show(); + nMsgDialog->activateWindow(); + + /* window will destroy itself! */ + } + else + { + QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to an Anonymous Author")); + } +} + +void GxsForumsDialog::changedViewBox() +{ + if (m_bProcessSettings) { + return; + } + + // save index + Settings->setValueToGroup("GxsForumsDialog", "viewBox", ui.viewBox->currentIndex()); + + insertThreads(); +} + +void GxsForumsDialog::filterColumnChanged() +{ + if (m_bProcessSettings) { + return; + } + + int filterColumn = FilterColumnFromComboBox(ui.filterColumnComboBox->currentIndex()); + if (filterColumn == COLUMN_THREAD_CONTENT) { + // need content ... refill + insertThreads(); + } else { + filterItems(ui.filterLineEdit->text()); + } + + // save index + Settings->setValueToGroup("GxsForumsDialog", "filterColumn", filterColumn); +} + +void GxsForumsDialog::filterItems(const QString& text) +{ + int filterColumn = FilterColumnFromComboBox(ui.filterColumnComboBox->currentIndex()); + + int nCount = ui.threadTreeWidget->topLevelItemCount (); + for (int nIndex = 0; nIndex < nCount; nIndex++) { + filterItem(ui.threadTreeWidget->topLevelItem(nIndex), text, filterColumn); + } +} + +void GxsForumsDialog::shareKey() +{ + ShareKey shareUi(this, 0, mCurrForumId, FORUM_KEY_SHARE); + shareUi.exec(); +} + +bool GxsForumsDialog::filterItem(QTreeWidgetItem *pItem, const QString &text, int filterColumn) +{ + bool bVisible = true; + + if (text.isEmpty() == false) { + if (pItem->text(filterColumn).contains(text, Qt::CaseInsensitive) == false) { + bVisible = false; + } + } + + int nVisibleChildCount = 0; + int nCount = pItem->childCount(); + for (int nIndex = 0; nIndex < nCount; nIndex++) { + if (filterItem(pItem->child(nIndex), text, filterColumn)) { + nVisibleChildCount++; + } + } + + if (bVisible || nVisibleChildCount) { + pItem->setHidden(false); + } else { + pItem->setHidden(true); + } + + return (bVisible || nVisibleChildCount); +} + +void GxsForumsDialog::updateMessageSummaryList(std::string forumId) +{ + QTreeWidgetItem *items[2] = { yourForums, subscribedForums }; + + for (int item = 0; item < 2; item++) { + int child; + int childCount = items[item]->childCount(); + for (child = 0; child < childCount; child++) { + QTreeWidgetItem *childItem = items[item]->child(child); + std::string childId = ui.forumTreeWidget->itemId(childItem).toStdString(); + if (childId.empty()) { + continue; + } + + if (forumId.empty() || childId == forumId) { + /* calculate unread messages */ + unsigned int newMessageCount = 0; + unsigned int unreadMessageCount = 0; + //rsGxsForums->getMessageCount(childId, newMessageCount, unreadMessageCount); + std::cerr << "IMPLEMENT rsGxsForums->getMessageCount()"; + std::cerr << std::endl; + + ui.forumTreeWidget->setUnreadCount(childItem, unreadMessageCount); + + if (forumId.empty() == false) { + /* Calculate only this forum */ + break; + } + } + } + } +} + +bool GxsForumsDialog::navigate(const std::string& forumId, const std::string& msgId) +{ + if (forumId.empty()) { + return false; + } + + if (ui.forumTreeWidget->activateId(QString::fromStdString(forumId), msgId.empty()) == NULL) { + return false; + } + + /* Threads are filled in changedForum */ + if (mCurrForumId != forumId) { + return false; + } + + if (msgId.empty()) { + return true; + } + + if (mThreadLoading) { + mThreadLoad.FocusMsgId = msgId; + return true; + } + + /* Search exisiting item */ + QTreeWidgetItemIterator itemIterator(ui.threadTreeWidget); + QTreeWidgetItem *item = NULL; + while ((item = *itemIterator) != NULL) { + itemIterator++; + + if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString() == msgId) { + ui.threadTreeWidget->setCurrentItem(item); + ui.threadTreeWidget->setFocus(); + return true; + } + } + + return false; +} + +void GxsForumsDialog::generateMassData() +{ +#ifdef DEBUG_FORUMS + if (mCurrForumId.empty ()) { + return; + } + + if (QMessageBox::question(this, "Generate mass data", "Do you really want to generate mass data ?", QMessageBox::Yes|QMessageBox::No, QMessageBox::No) == QMessageBox::No) { + return; + } + + for (int thread = 1; thread < 1000; thread++) { + ForumMsgInfo threadInfo; + threadInfo.forumId = mCurrForumId; + threadInfo.title = QString("Test %1").arg(thread, 3, 10, QChar('0')).toStdWString(); + threadInfo.msg = QString("That is only a test").toStdWString(); + + if (rsGxsForums->ForumMessageSend(threadInfo) == false) { + return; + } + + for (int msg = 1; msg < 3; msg++) { + ForumMsgInfo msgInfo; + msgInfo.forumId = mCurrForumId; + msgInfo.threadId = threadInfo.msgId; + msgInfo.parentId = threadInfo.msgId; + msgInfo.title = threadInfo.title; + msgInfo.msg = threadInfo.msg; + + if (rsGxsForums->ForumMessageSend(msgInfo) == false) { + return; + } + } + } +#endif +} + + + +/*********************** **** **** **** ***********************/ +/** Request / Response of Data ********************************/ +/*********************** **** **** **** ***********************/ + +#define FORUMSV2DIALOG_LISTING 1 +#define FORUMSV2DIALOG_CURRENTFORUM 2 +#define FORUMSV2DIALOG_INSERTTHREADS 3 +#define FORUMSV2DIALOG_INSERTCHILD 4 +#define FORUMV2DIALOG_INSERT_POST 5 +#define FORUMV2DIALOG_REPLY_MESSAGE 6 + + +void GxsForumsDialog::insertForums() +{ + requestGroupSummary(); +} + +void GxsForumsDialog::requestGroupSummary() +{ + std::cerr << "GxsForumsDialog::requestGroupSummary()"; + std::cerr << std::endl; + + std::list ids; + RsTokReqOptions opts; + uint32_t token; + mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, ids, FORUMSV2DIALOG_LISTING); +} + +void GxsForumsDialog::loadGroupSummary(const uint32_t &token) +{ + std::cerr << "GxsForumsDialog::loadGroupSummary()"; + std::cerr << std::endl; + + std::list groupInfo; + rsGxsForums->getGroupSummary(token, groupInfo); + + if (groupInfo.size() > 0) + { + insertForumsData(groupInfo); + } + else + { + std::cerr << "GxsForumsDialog::loadGroupSummary() ERROR No Groups..."; + std::cerr << std::endl; + } +} + +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ + + + +void GxsForumsDialog::requestGroupSummary_CurrentForum(const std::string &forumId) +{ + RsTokReqOptions opts; + + std::list grpIds; + grpIds.push_back(forumId); + + std::cerr << "GxsForumsDialog::requestGroupSummary_CurrentForum(" << forumId << ")"; + std::cerr << std::endl; + + uint32_t token; + mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, FORUMSV2DIALOG_CURRENTFORUM); +} + +void GxsForumsDialog::loadGroupSummary_CurrentForum(const uint32_t &token) +{ + std::cerr << "GxsForumsDialog::loadGroupSummary_CurrentForum()"; + std::cerr << std::endl; + + std::list groupInfo; + rsGxsForums->getGroupSummary(token, groupInfo); + + if (groupInfo.size() == 1) + { + RsGroupMetaData fi = groupInfo.front(); + insertForumThreads(fi); + } + else + { + std::cerr << "GxsForumsDialog::loadGroupSummary_CurrentForum() ERROR Invalid Number of Groups..."; + std::cerr << std::endl; + } +} + +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ + + + +void GxsForumsDialog::loadCurrentForumThreads(const std::string &forumId) +{ + + std::cerr << "GxsForumsDialog::loadCurrentForumThreads(" << forumId << ")"; + std::cerr << std::endl; + + /* if already active -> kill current loading */ + if (mThreadLoading) + { + /* Cleanup */ + std::cerr << "GxsForumsDialog::loadCurrentForumThreads() Cleanup old Threads"; + std::cerr << std::endl; + + /* Wipe Widget Tree */ + mThreadLoad.Items.clear(); + + /* Stop all active requests */ + std::map::iterator it; + for(it = mThreadLoad.MsgTokens.begin(); it != mThreadLoad.MsgTokens.end(); it++) + { + std::cerr << "GxsForumsDialog::loadCurrentForumThreads() Canceling Request: " << it->first; + std::cerr << std::endl; + + mForumQueue->cancelRequest(it->first); + } + + mThreadLoad.MsgTokens.clear(); + mThreadLoad.ItemToExpand.clear(); + } + + /* initiate loading */ + std::cerr << "GxsForumsDialog::loadCurrentForumThreads() Initiating Loading"; + std::cerr << std::endl; + + mThreadLoading = true; + + mThreadLoad.ForumId = mCurrForumId; + mThreadLoad.FilterColumn = FilterColumnFromComboBox(ui.filterColumnComboBox->currentIndex()); + mThreadLoad.ViewType = ui.viewBox->currentIndex(); + mThreadLoad.FillComplete = false; + + if (lastViewType != mThreadLoad.ViewType || lastForumID != mCurrForumId) { + mThreadLoad.FillComplete = true; + } + + mThreadLoad.FlatView = false; + mThreadLoad.UseChildTS = false; + mThreadLoad.ExpandNewMessages = Settings->getExpandNewMessages(); + mThreadLoad.SubscribeFlags = subscribeFlags; + + if (mThreadLoad.ViewType == VIEW_FLAT) { + ui.threadTreeWidget->setRootIsDecorated(false); + } else { + ui.threadTreeWidget->setRootIsDecorated(true); + } + + switch(mThreadLoad.ViewType) + { + case VIEW_LAST_POST: + mThreadLoad.UseChildTS = true; + break; + case VIEW_FLAT: + mThreadLoad.FlatView = true; + break; + case VIEW_THREADED: + break; + } + + requestGroupThreadData_InsertThreads(forumId); +} + + + +void GxsForumsDialog::requestGroupThreadData_InsertThreads(const std::string &forumId) +{ + RsTokReqOptions opts; + + opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; + + std::list grpIds; + grpIds.push_back(forumId); + + std::cerr << "GxsForumsDialog::requestGroupThreadData_InsertThreads(" << forumId << ")"; + std::cerr << std::endl; + + uint32_t token; + mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, FORUMSV2DIALOG_INSERTTHREADS); +} + + +void GxsForumsDialog::loadGroupThreadData_InsertThreads(const uint32_t &token) +{ + std::cerr << "GxsForumsDialog::loadGroupThreadData_InsertThreads()"; + std::cerr << std::endl; + + bool someData = false; + + std::vector msgs; + std::vector::iterator vit; + if (rsGxsForums->getMsgData(token, msgs)) + { + for(vit = msgs.begin(); vit != msgs.end(); vit++) + { + std::cerr << "GxsForumsDialog::loadGroupThreadData_InsertThreads() MsgId: " << vit->mMeta.mMsgId; + std::cerr << std::endl; + + loadForumBaseThread(*vit); + someData = true; + } + } + + /* completed with no data */ + if (!someData) + { + fillThreadFinished(); + } +} + +bool GxsForumsDialog::convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, std::string authorName, + bool useChildTS, uint32_t filterColumn, QTreeWidgetItem *item) +{ + QString text; + + { + QDateTime qtime; + if (useChildTS) + qtime.setTime_t(msgInfo.mMeta.mChildTs); + else + qtime.setTime_t(msgInfo.mMeta.mPublishTs); + + text = qtime.toString("yyyy-MM-dd hh:mm:ss"); + if (useChildTS) + { + QDateTime qtime2; + qtime2.setTime_t(msgInfo.mMeta.mPublishTs); + QString timestamp2 = qtime2.toString("yyyy-MM-dd hh:mm:ss"); + text += " / "; + text += timestamp2; + } + item->setText(COLUMN_THREAD_DATE, text); + } + + item->setText(COLUMN_THREAD_TITLE, GxsForumsDialog::titleFromInfo(msgInfo.mMeta)); + + text = QString::fromUtf8(authorName.c_str()); + + if (text.isEmpty()) + { + item->setText(COLUMN_THREAD_AUTHOR, tr("Anonymous")); + } + else + { + item->setText(COLUMN_THREAD_AUTHOR, text); + } + +#ifdef TOGXS + if (msgInfo.mMeta.mMsgFlags & RS_DISTRIB_AUTHEN_REQ) + { + item->setText(COLUMN_THREAD_SIGNED, tr("signed")); + item->setIcon(COLUMN_THREAD_SIGNED, QIcon(":/images/mail-signed.png")); + } + else + { + item->setText(COLUMN_THREAD_SIGNED, tr("none")); + item->setIcon(COLUMN_THREAD_SIGNED, QIcon(":/images/mail-signature-unknown.png")); + } +#endif + + if (filterColumn == COLUMN_THREAD_CONTENT) { + // need content for filter + QTextDocument doc; + doc.setHtml(QString::fromUtf8(msgInfo.mMsg.c_str())); + item->setText(COLUMN_THREAD_CONTENT, doc.toPlainText().replace(QString("\n"), QString(" "))); + } + + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID, QString::fromStdString(msgInfo.mMeta.mMsgId)); + +#if 0 + if (IS_GROUP_SUBSCRIBED(subscribeFlags) && !(msginfo.mMsgFlags & RS_DISTRIB_MISSING_MSG)) { + rsGxsForums->getMessageStatus(msginfo.forumId, msginfo.msgId, status); + } else { + // show message as read + status = RSGXS_MSG_STATUS_READ; + } +#endif + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, msgInfo.mMeta.mMsgStatus); + +#ifdef TOGXS + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING, (msgInfo.mMeta.mMsgFlags & RS_DISTRIB_MISSING_MSG) ? true : false); +#endif + + return true; +} + + +void GxsForumsDialog::loadForumBaseThread(const RsGxsForumMsg &msg) +{ + std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); + + QTreeWidgetItem *item = new QTreeWidgetItem(); // no Parent. + + convertMsgToThreadWidget(msg, authorName, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, item); + + /* request Children Data */ + uint32_t token; + RsGxsGrpMsgIdPair parentId = std::make_pair(msg.mMeta.mGroupId, msg.mMeta.mMsgId); + requestChildData_InsertThreads(token, parentId); + + /* store pair of (token, item) */ + mThreadLoad.MsgTokens[token] = item; + + /* add item to final tree */ + mThreadLoad.Items.append(item); +} + + + +/*********************** **** **** **** ***********************/ + +void GxsForumsDialog::requestChildData_InsertThreads(uint32_t &token, const RsGxsGrpMsgIdPair &parentId) +{ + RsTokReqOptions opts; + + opts.mOptions = RS_TOKREQOPT_MSG_PARENT | RS_TOKREQOPT_MSG_LATEST; + + std::cerr << "GxsForumsDialog::requestChildData_InsertThreads(" << parentId.first << "," << parentId.second << ")"; + std::cerr << std::endl; + + mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, parentId, FORUMSV2DIALOG_INSERTCHILD); +} + + +void GxsForumsDialog::loadChildData_InsertThreads(const uint32_t &token) +{ + std::cerr << "GxsForumsDialog::loadChildData_InsertThreads()"; + std::cerr << std::endl; + + /* find the matching *item */ + std::map::iterator it; + it = mThreadLoad.MsgTokens.find(token); + if (it == mThreadLoad.MsgTokens.end()) + { + std::cerr << "GxsForumsDialog::loadChildData_InsertThreads() ERROR Missing Token->Parent in Map"; + std::cerr << std::endl; + /* finished with this one */ + return; + } + + QTreeWidgetItem *parent = it->second; + // cleanup map. + mThreadLoad.MsgTokens.erase(it); + + std::cerr << "GxsForumsDialog::loadChildData_InsertThreads()"; + std::cerr << std::endl; + + + std::vector msgs; + std::vector::iterator vit; + if (rsGxsForums->getMsgData(token, msgs)) + { + for(vit = msgs.begin(); vit != msgs.end(); vit++) + { + std::cerr << "GxsForumsDialog::loadChildData_InsertThreads() MsgId: " << vit->mMeta.mMsgId; + std::cerr << std::endl; + + loadForumChildMsg(*vit, parent); + } + } + else + { + std::cerr << "GxsForumsDialog::loadChildData_InsertThreads() Error getting MsgData"; + std::cerr << std::endl; + } + + /* check for completion */ + if (mThreadLoad.MsgTokens.size() == 0) + { + /* finished */ + /* push data into GUI */ + fillThreadFinished(); + } +} + +void GxsForumsDialog::loadForumChildMsg(const RsGxsForumMsg &msg, QTreeWidgetItem *parent) +{ + std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); + + QTreeWidgetItem *child = NULL; + + if (mThreadLoad.FlatView) + { + child = new QTreeWidgetItem(); // no Parent. + } + else + { + child = new QTreeWidgetItem(parent); + } + + + convertMsgToThreadWidget(msg, authorName, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, child); + + /* request Children Data */ + uint32_t token; + RsGxsGrpMsgIdPair parentId = std::make_pair(msg.mMeta.mGroupId, msg.mMeta.mMsgId); + requestChildData_InsertThreads(token, parentId); + + /* store pair of (token, item) */ + mThreadLoad.MsgTokens[token] = child; + + // Leave this here... BUT IT WILL NEED TO BE FIXED. + if (mThreadLoad.FillComplete && mThreadLoad.ExpandNewMessages && IS_MSG_UNREAD(msg.mMeta.mMsgStatus)) + { + QTreeWidgetItem *pParent = child; + while ((pParent = pParent->parent()) != NULL) + { + if (std::find(mThreadLoad.ItemToExpand.begin(), mThreadLoad.ItemToExpand.end(), pParent) == mThreadLoad.ItemToExpand.end()) + { + mThreadLoad.ItemToExpand.push_back(pParent); + } + } + } + + if (mThreadLoad.FlatView) + { + /* add item to final tree */ + mThreadLoad.Items.append(child); + } +} + + + +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ + +void GxsForumsDialog::requestMsgData_InsertPost(const RsGxsGrpMsgIdPair &msgId) +{ + RsTokReqOptions opts; + + std::cerr << "GxsForumsDialog::requestMsgData_InsertPost(" << msgId.first << "," << msgId.second << ")"; + std::cerr << std::endl; + + + uint32_t token; + mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgId, FORUMV2DIALOG_INSERT_POST); +} + + +void GxsForumsDialog::loadMsgData_InsertPost(const uint32_t &token) +{ + std::cerr << "GxsForumsDialog::loadMsgData_InsertPost()"; + std::cerr << std::endl; + + std::vector msgs; + if (rsGxsForums->getMsgData(token, msgs)) + { + if (msgs.size() != 1) + { + std::cerr << "GxsForumsDialog::loadMsgData_InsertPost() ERROR Wrong number of answers"; + std::cerr << std::endl; + return; + } + insertPostData(msgs[0]); + } + else + { + std::cerr << "GxsForumsDialog::loadMsgData_InsertPost() ERROR Missing Message Data..."; + std::cerr << std::endl; + } +} + + +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ + +void GxsForumsDialog::requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId) +{ + RsTokReqOptions opts; + + std::cerr << "GxsForumsDialog::requestMsgData_ReplyMessage(" << msgId.first << "," << msgId.second << ")"; + std::cerr << std::endl; + + uint32_t token; + mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgId, FORUMV2DIALOG_REPLY_MESSAGE); +} + + +void GxsForumsDialog::loadMsgData_ReplyMessage(const uint32_t &token) +{ + std::cerr << "GxsForumsDialog::loadMsgData_ReplyMessage()"; + std::cerr << std::endl; + + std::vector msgs; + if (rsGxsForums->getMsgData(token, msgs)) + { + if (msgs.size() != 1) + { + std::cerr << "GxsForumsDialog::loadMsgData_ReplyMessage() ERROR Wrong number of answers"; + std::cerr << std::endl; + return; + } + + replyMessageData(msgs[0]); + } + else + { + std::cerr << "GxsForumsDialog::loadMsgData_ReplyMessage() ERROR Missing Message Data..."; + std::cerr << std::endl; + } +} + + +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ + + + +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ + +void GxsForumsDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) +{ + std::cerr << "GxsForumsDialog::loadRequest() UserType: " << req.mUserType; + std::cerr << std::endl; + + if (queue == mForumQueue) + { + /* now switch on req */ + switch(req.mUserType) + { + case FORUMSV2DIALOG_LISTING: + loadGroupSummary(req.mToken); + break; + + case FORUMSV2DIALOG_CURRENTFORUM: + loadGroupSummary_CurrentForum(req.mToken); + break; + + case FORUMSV2DIALOG_INSERTTHREADS: + loadGroupThreadData_InsertThreads(req.mToken); + break; + + case FORUMSV2DIALOG_INSERTCHILD: + loadChildData_InsertThreads(req.mToken); + break; + + case FORUMV2DIALOG_INSERT_POST: + loadMsgData_InsertPost(req.mToken); + break; + + case FORUMV2DIALOG_REPLY_MESSAGE: + loadMsgData_ReplyMessage(req.mToken); + break; + + default: + std::cerr << "GxsForumsDialog::loadRequest() ERROR: INVALID TYPE"; + std::cerr << std::endl; + break; + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/GxsForumsDialog.h b/retroshare-gui/src/gui/GxsForumsDialog.h new file mode 100644 index 000000000..db042b54d --- /dev/null +++ b/retroshare-gui/src/gui/GxsForumsDialog.h @@ -0,0 +1,272 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#ifndef _GXSFORUMSDIALOG_H +#define _GXSFORUMSDIALOG_H + +#include + +#include "mainpage.h" +#include "RsAutoUpdatePage.h" +#include "ui_GxsForumsDialog.h" + +#include + +#include "util/TokenQueue.h" + +#include + +class ForumInfo; + + +/* These are all the parameters that are required for thread loading. + * They are kept static for the load duration. + */ + +class GxsForumsThreadLoadParameters +{ + public: + + std::string ForumId; + std::string FocusMsgId; + + uint32_t SubscribeFlags; + int ViewType; + uint32_t FilterColumn; + + std::map MsgTokens; + QList Items; + QList ItemToExpand; + + bool FillComplete; + bool FlatView; + bool UseChildTS; + bool ExpandNewMessages; +}; + + + + + + +class GxsForumsDialog : public RsAutoUpdatePage, public TokenResponse +{ + Q_OBJECT + +public: + GxsForumsDialog(QWidget *parent = 0); + ~GxsForumsDialog(); + + bool navigate(const std::string& forumId, const std::string& msgId); + + /* overloaded from RsAuthUpdatePage */ + virtual void updateDisplay(); + + // Callback for all Loads. +virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); + +protected: + bool eventFilter(QObject *obj, QEvent *ev); + +private slots: + /** Create the context popup menu and it's submenus */ + void forumListCustomPopupMenu( QPoint point ); + void threadListCustomPopupMenu( QPoint point ); + void restoreForumKeys(); + void newforum(); + + void changedForum(const QString &id); + void changedThread(); + void clickedThread (QTreeWidgetItem *item, int column); + + void replytomessage(); + void replyMessageData(const RsGxsForumMsg &msg); + + //void print(); + //void printpreview(); + + //void removemessage(); + void markMsgAsRead(); + void markMsgAsReadChildren(); + void markMsgAsReadAll(); + void markMsgAsUnread(); + void markMsgAsUnreadAll(); + void markMsgAsUnreadChildren(); + void copyForumLink(); + void copyMessageLink(); + + /* handle splitter */ + void togglethreadview(); + + void createthread(); + void createmessage(); + + void subscribeToForum(); + void unsubscribeToForum(); + + void showForumDetails(); + void editForumDetails(); + + void previousMessage (); + void nextMessage (); + void nextUnreadMessage(); + void downloadAllFiles(); + + void changedViewBox(); + + void filterColumnChanged(); + //void filterRegExpChanged(); + ///void clearFilter(); + + void generateMassData(); + + void fillThreadFinished(); + void fillThreadProgress(int current, int count); + + void shareKey(); + +private: + void insertForums(); + void insertThreads(); + void insertPost(); + void insertPostData(const RsGxsForumMsg &msg); // Second Half. + + // Utility Fns. + QString titleFromInfo(const RsMsgMetaData &meta); + QString messageFromInfo(const RsGxsForumMsg &msg); + + void forumMsgReadStatusChanged(const QString &forumId, const QString &msgId, int status); + + void updateMessageSummaryList(std::string forumId); + //void forumInfoToGroupItemInfo(const ForumInfo &forumInfo, GroupItemInfo &groupItemInfo); + void forumInfoToGroupItemInfo(const RsGroupMetaData &forumInfo, GroupItemInfo &groupItemInfo); + + void forumSubscribe(bool subscribe); + void FillThreads(QList &ThreadList, bool bExpandNewMessages, QList &itemToExpand); + void FillChildren(QTreeWidgetItem *Parent, QTreeWidgetItem *NewParent, bool bExpandNewMessages, QList &itemToExpand); + + int getSelectedMsgCount(QList *pRows, QList *pRowsRead, QList *pRowsUnread); + + void setMsgReadStatus(QList &Rows, bool bRead); + void markMsgAsReadUnread(bool bRead, bool bChildren, bool bForum); + void CalculateIconsAndFonts(QTreeWidgetItem *pItem = NULL); + void CalculateIconsAndFonts(QTreeWidgetItem *pItem, bool &bHasReadChilddren, bool &bHasUnreadChilddren); + + void processSettings(bool bLoad); + void togglethreadview_internal(); + + void filterItems(const QString& text); + bool filterItem(QTreeWidgetItem *pItem, const QString &text, int filterColumn); + + // New Request/Response Loading Functions. + void insertForumsData(const std::list &forumList); + void insertForumThreads(const RsGroupMetaData &fi); + + void requestGroupSummary(); + void loadGroupSummary(const uint32_t &token); + + void requestGroupSummary_CurrentForum(const std::string &forumId); + void loadGroupSummary_CurrentForum(const uint32_t &token); + + void loadCurrentForumThreads(const std::string &forumId); + void requestGroupThreadData_InsertThreads(const std::string &forumId); + void loadGroupThreadData_InsertThreads(const uint32_t &token); + void loadForumBaseThread(const RsGxsForumMsg &msg); + + void requestChildData_InsertThreads(uint32_t &token, const RsGxsGrpMsgIdPair &parentId); + void loadChildData_InsertThreads(const uint32_t &token); + void loadForumChildMsg(const RsGxsForumMsg &msg, QTreeWidgetItem *parent); + + void requestMsgData_InsertPost(const RsGxsGrpMsgIdPair &msgId); + void loadMsgData_InsertPost(const uint32_t &token); + void requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId); + void loadMsgData_ReplyMessage(const uint32_t &token); + + bool convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, std::string authorName, + bool useChildTS, uint32_t filterColumn, QTreeWidgetItem *item); + + TokenQueue *mForumQueue; + + + bool m_bProcessSettings; + + QTreeWidgetItem *yourForums; + QTreeWidgetItem *subscribedForums; + QTreeWidgetItem *popularForums; + QTreeWidgetItem *otherForums; + + std::string mCurrForumId; + std::string mCurrThreadId; + int subscribeFlags; + + QFont m_ForumNameFont; + int lastViewType; + std::string lastForumID; + + bool inMsgAsReadUnread; + //GxsForumsFillThread *fillThread; + + // New Datatypes to replace the FillThread. + bool mThreadLoading; + GxsForumsThreadLoadParameters mThreadLoad; + + + /** Qt Designer generated object */ + Ui::GxsForumsDialog ui; +}; + +#if 0 +class GxsForumsFillThread : public QThread +{ + Q_OBJECT + +public: + GxsForumsFillThread(GxsForumsDialog *parent); + ~GxsForumsFillThread(); + + void run(); + void stop(); + bool wasStopped() { return stopped; } + +signals: + void progress(int current, int count); + +public: + std::string forumId; + int filterColumn; + int subscribeFlags; + bool fillComplete; + int viewType; + bool expandNewMessages; + std::string focusMsgId; + + QList Items; + QList ItemToExpand; + +private: + volatile bool stopped; +}; + +#endif + + +#endif + diff --git a/retroshare-gui/src/gui/GxsForumsDialog.ui b/retroshare-gui/src/gui/GxsForumsDialog.ui new file mode 100644 index 000000000..e4e824574 --- /dev/null +++ b/retroshare-gui/src/gui/GxsForumsDialog.ui @@ -0,0 +1,1251 @@ + + + GxsForumsDialog + + + + 0 + 0 + 732 + 420 + + + + + 0 + 2 + + + + + 60 + 0 + + + + + + + + + 0 + 0 + 0 + + + + + + + 208 + 208 + 208 + + + + + + + 255 + 255 + 255 + + + + + + + 247 + 247 + 247 + + + + + + + 104 + 104 + 104 + + + + + + + 139 + 139 + 139 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 240 + 240 + 240 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 128 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 255 + + + + + + + 255 + 0 + 255 + + + + + + + 231 + 231 + 231 + + + + + + + + + 0 + 0 + 0 + + + + + + + 208 + 208 + 208 + + + + + + + 255 + 255 + 255 + + + + + + + 247 + 247 + 247 + + + + + + + 104 + 104 + 104 + + + + + + + 139 + 139 + 139 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 240 + 240 + 240 + + + + + + + 0 + 0 + 0 + + + + + + + 192 + 192 + 192 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 255 + + + + + + + 255 + 0 + 255 + + + + + + + 231 + 231 + 231 + + + + + + + + + 104 + 104 + 104 + + + + + + + 208 + 208 + 208 + + + + + + + 255 + 255 + 255 + + + + + + + 247 + 247 + 247 + + + + + + + 104 + 104 + 104 + + + + + + + 139 + 139 + 139 + + + + + + + 104 + 104 + 104 + + + + + + + 255 + 255 + 255 + + + + + + + 104 + 104 + 104 + + + + + + + 240 + 240 + 240 + + + + + + + 240 + 240 + 240 + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 128 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 255 + + + + + + + 255 + 0 + 255 + + + + + + + 231 + 231 + 231 + + + + + + + + + Arial + 8 + 50 + false + false + false + false + + + + Qt::DefaultContextMenu + + + + 9 + + + 9 + + + + + Qt::Horizontal + + + + + 300 + 300 + + + + QFrame#frame{border: none;} + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + + + QFrame#chheaderframe{ +background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #FEFEFE, stop:1 #E8E8E8); + +border: 1px solid #CCCCCC;} + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + + + 0 + + + + + + 24 + 24 + + + + + + + :/images/konversation.png + + + true + + + + + + + + Arial + 10 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Arial'; font-weight:600;">Forums</span></p></body></html> + + + + + + + + + Qt::Horizontal + + + + 123 + 13 + + + + + + + + Qt::NoFocus + + + Display + + + QPushButton::menu-indicator { + subcontrol-origin: padding; + subcontrol-position: bottom right; + } + + QPushButton::menu-indicator:pressed, QPushButton::menu-indicator:open { + position: relative; + top: 2px; left: 2px; /* shift the arrow by 2 px */ + } + + QPushButton:hover { + border: 1px solid #CCCCCC; + } + + + + :/images/looknfeel.png:/images/looknfeel.png + + + true + + + + + + + Qt::NoFocus + + + Create Forum + + + + :/images/new_forum16.png:/images/new_forum16.png + + + true + + + + + + + + + + + 0 + 0 + + + + + 9 + + + + + -1 + -1 + + + + + + + + + Qt::Vertical + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + 10 + 75 + true + + + + Forum: + + + + + + + + 2 + 0 + + + + + 0 + 0 + + + + + 16777215 + 1677215 + + + + +border: 2px solid #CCCCCC; +border-radius:6px; +background: white; + + + + + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + + Last Post + + + + + Threaded View + + + + + Flat View + + + + + + + + + + + 9 + + + + Qt::CustomContextMenu + + + true + + + true + + + + Title + + + + + + + + + :/images/message-state-header.png:/images/message-state-header.png + + + + + Date + + + + + Author + + + + + Signed + + + + + + + + + + + 0 + 0 + + + + + 10 + 75 + true + + + + Thread: + + + + + + + QLabel#threadTitle{ +border: 2px solid #CCCCCC; +border-radius: 6px; +background: white;} + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + false + + + + 0 + 0 + + + + + 24 + 24 + + + + + 24 + 24 + + + + Qt::NoFocus + + + Previous Thread + + + + + + + :/images/back.png:/images/back.png + + + + + + + false + + + + 0 + 0 + + + + + 24 + 24 + + + + + 24 + 24 + + + + Qt::NoFocus + + + Next Thread + + + + + + + :/images/forward.png:/images/forward.png + + + + + + + + 24 + 24 + + + + Qt::NoFocus + + + + + + + :/images/edit_remove24.png:/images/edit_remove24.png + + + true + + + true + + + + + + + + 24 + 24 + + + + Qt::NoFocus + + + Download all files + + + + :/images/down.png:/images/down.png + + + + + + + + 0 + 0 + + + + Next unread + + + + + + + + + + 0 + 32 + + + + QFrame#frame_2{ +background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #FEFEFE, stop:1 #E8E8E8); + +border: 1px solid #CCCCCC;} + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + + + 2 + + + + + + + + :/images/find-16.png + + + + + + + Search forums + + + + + + + + + + 0 + 0 + + + + + MS Shell Dlg 2 + + + + 1 + + + + Date + + + + + Title + + + + + Author + + + + + Content + + + + + + + + + 24 + 24 + + + + Qt::NoFocus + + + Reply Message + + + + :/images/mail_reply.png:/images/mail_reply.png + + + true + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 40 + 20 + + + + + + + + + 24 + 24 + + + + Qt::NoFocus + + + Start new Thread for Selected Forum + + + + :/images/mail_new.png:/images/mail_new.png + + + true + + + + + + + + + + + + + 10 + 75 + true + + + + Loading + + + + + + + + 16777215 + 25 + + + + 1000 + + + 0 + + + + + + + + + + + 0 + 10 + + + + + 9 + + + + + + + + + + Print + + + + + PrintPreview + + + + + + GroupTreeWidget + QWidget +
gui/common/GroupTreeWidget.h
+ 1 +
+ + LineEditClear + QLineEdit +
gui/common/LineEditClear.h
+
+ + LinkTextBrowser + QTextBrowser +
gui/common/LinkTextBrowser.h
+
+
+ + + + +
diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index e471859f5..b97f6f8b4 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -93,7 +93,8 @@ void PhotoDialog::requestComments() uint32_t token; msgId.first = mPhotoDetails.mMeta.mGroupId; msgId.second = mPhotoDetails.mMeta.mMsgId; - mPhotoQueue->requestMsgRelatedInfo(token, opts, msgId, 0); + uint32_t anstype = RS_TOKREQ_ANSTYPE_LIST; + mPhotoQueue->requestMsgRelatedInfo(token, anstype, opts, msgId, 0); } void PhotoDialog::createComment() diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp index 0b1f50bde..3d79cd90a 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp @@ -43,15 +43,14 @@ #define WIKI_DEBUG 1 -#define WIKIDIALOG_LISTING_GROUPLIST 1 #define WIKIDIALOG_LISTING_GROUPDATA 2 -#define WIKIDIALOG_LISTING_ORIGINALPAGES 3 -#define WIKIDIALOG_LISTING_LATESTPAGES 4 #define WIKIDIALOG_LISTING_PAGES 5 #define WIKIDIALOG_MOD_LIST 6 #define WIKIDIALOG_MOD_PAGES 7 #define WIKIDIALOG_WIKI_PAGE 8 +#define WIKIDIALOG_EDITTREE_DATA 9 + /** Constructor */ WikiDialog::WikiDialog(QWidget *parent) @@ -67,6 +66,10 @@ WikiDialog::WikiDialog(QWidget *parent) connect( ui.toolButton_NewGroup, SIGNAL(clicked()), this, SLOT(OpenOrShowAddGroupDialog())); connect( ui.toolButton_NewPage, SIGNAL(clicked()), this, SLOT(OpenOrShowAddPageDialog())); connect( ui.toolButton_Edit, SIGNAL(clicked()), this, SLOT(OpenOrShowEditDialog())); + connect( ui.toolButton_Republish, SIGNAL(clicked()), this, SLOT(OpenOrShowRepublishDialog())); + + // Usurped until Refresh works normally + connect( ui.toolButton_Delete, SIGNAL(clicked()), this, SLOT(insertWikiGroups())); connect( ui.treeWidget_Pages, SIGNAL(itemSelectionChanged()), this, SLOT(groupTreeChanged())); connect( ui.treeWidget_Mods, SIGNAL(itemSelectionChanged()), this, SLOT(modTreeChanged())); @@ -76,9 +79,8 @@ WikiDialog::WikiDialog(QWidget *parent) timer->start(1000); /* setup TokenQueue */ -#if 0 - mWikiQueue = new TokenQueue(rsWiki, this); -#endif + rsWiki->generateDummyData(); + mWikiQueue = new TokenQueue(rsWiki->getTokenService(), this); } @@ -133,6 +135,7 @@ void WikiDialog::OpenOrShowAddPageDialog() } + void WikiDialog::OpenOrShowAddGroupDialog() { #if 0 @@ -199,27 +202,23 @@ void WikiDialog::editGroupDetails() void WikiDialog::OpenOrShowEditDialog() { - std::string groupId = getSelectedGroup(); - if (groupId == "") - { - std::cerr << "WikiDialog::OpenOrShowAddPageDialog() No Group selected"; - std::cerr << std::endl; - return; - } - - std::string modId = getSelectedMod(); - std::string realPageId; - + std::string groupId; std::string pageId; std::string origPageId; - if (!getSelectedPage(pageId, origPageId)) + if (!getSelectedPage(groupId, pageId, origPageId)) { - std::cerr << "WikiDialog::OpenOrShowAddPageDialog() No PageId selected"; + std::cerr << "WikiDialog::OpenOrShowAddPageDialog() No Group or PageId selected"; std::cerr << std::endl; return; } + std::cerr << "WikiDialog::OpenOrShowAddPageDialog()"; + std::cerr << std::endl; + + std::string modId = getSelectedMod(); + std::string realPageId; + if (modId == "") { realPageId = pageId; @@ -235,29 +234,41 @@ void WikiDialog::OpenOrShowEditDialog() mEditDialog = new WikiEditDialog(NULL); } -#if 0 - RsWikiCollection group; - rsWiki->getGroup(groupId, group); - mEditDialog->setGroup(group); - - RsWikiSnapshot page; - rsWiki->getPage(realPageId, page); - mEditDialog->setPreviousPage(page); -#endif mEditDialog->setupData(groupId, realPageId); - mEditDialog->show(); } +void WikiDialog::OpenOrShowRepublishDialog() +{ + OpenOrShowEditDialog(); + + std::string groupId; + std::string pageId; + std::string origPageId; + + if (!getSelectedPage(groupId, pageId, origPageId)) + { + std::cerr << "WikiDialog::OpenOrShowAddRepublishDialog() No Group or PageId selected"; + std::cerr << std::endl; + if (mEditDialog) + { + mEditDialog->hide(); + } + return; + } + + mEditDialog->setRepublishMode(origPageId); +} void WikiDialog::groupTreeChanged() { /* */ + std::string groupId; std::string pageId; std::string origPageId; - getSelectedPage(pageId, origPageId); + getSelectedPage(groupId, pageId, origPageId); if (pageId == mPageSelected) { return; /* nothing changed */ @@ -275,26 +286,32 @@ void WikiDialog::groupTreeChanged() clearModsTree(); - insertModsForPage(origPageId); - requestWikiPage(pageId); + + RsGxsGrpMsgIdPair origPagePair = std::make_pair(groupId, origPageId); + RsGxsGrpMsgIdPair pagepair = std::make_pair(groupId, pageId); + + insertModsForPage(origPagePair); + requestWikiPage(pagepair); } void WikiDialog::modTreeChanged() { /* */ + std::string groupId = getSelectedGroup(); std::string pageId = getSelectedMod(); if (pageId == mModSelected) { return; /* nothing changed */ } - if (pageId == "") + if ((pageId == "") || (groupId == "")) { clearWikiPage(); return; } - requestWikiPage(pageId); + RsGxsGrpMsgIdPair pagepair = std::make_pair(groupId, pageId); + requestWikiPage(pagepair); } @@ -330,86 +347,7 @@ void WikiDialog::clearModsTree() #define WIKI_GROUP_COL_ORIGPAGEID 2 -// THIS WAS ALREADY COMMENTED OUT!!! -#if 0 -######################################################### -void WikiDialog::insertWikiGroups() -{ - - std::cerr << "WikiDialog::insertWikiGroups()"; - std::cerr << std::endl; - - /* clear it all */ - clearGroupTree(); - - std::list groupIds; - std::list::iterator it; - - rsWiki->getGroupList(groupIds); - - for(it = groupIds.begin(); it != groupIds.end(); it++) - { - /* add a group Item */ - RsWikiCollection group; - rsWiki->getGroup(*it, group); - - QTreeWidgetItem *groupItem = new QTreeWidgetItem(NULL); - groupItem->setText(WIKI_GROUP_COL_GROUPNAME, QString::fromStdString(group.mName)); - groupItem->setText(WIKI_GROUP_COL_GROUPID, QString::fromStdString(group.mGroupId)); - ui.treeWidget_Pages->addTopLevelItem(groupItem); - - std::cerr << "Group: " << group.mName; - std::cerr << std::endl; - - std::list pageIds; - std::list::iterator pit; - - rsWiki->getOrigPageList(*it, pageIds); - - for(pit = pageIds.begin(); pit != pageIds.end(); pit++) - { - std::cerr << "\tOrigPageId: " << *pit; - std::cerr << std::endl; - - /* get newest page */ - RsWikiSnapshot page; - std::string latestPageId; - if (!rsWiki->getLatestPage(*pit, latestPageId)) - { - std::cerr << "\tgetLatestPage() Failed"; - std::cerr << std::endl; - } - - if (!rsWiki->getPage(latestPageId, page)) - { - std::cerr << "\tgetPage() Failed"; - std::cerr << std::endl; - } - - std::cerr << "\tLatestPageId: " << latestPageId; - std::cerr << std::endl; - std::cerr << "\tExtracted OrigPageId: " << page.mOrigPageId; - std::cerr << std::endl; - std::cerr << "\tExtracted PageId: " << page.mPageId; - std::cerr << std::endl; - - QTreeWidgetItem *pageItem = new QTreeWidgetItem(NULL); - pageItem->setText(WIKI_GROUP_COL_PAGENAME, QString::fromStdString(page.mName)); - pageItem->setText(WIKI_GROUP_COL_PAGEID, QString::fromStdString(page.mPageId)); - pageItem->setText(WIKI_GROUP_COL_ORIGPAGEID, QString::fromStdString(page.mOrigPageId)); - - groupItem->addChild(pageItem); - - std::cerr << "\tPage: " << page.mName; - std::cerr << std::endl; - } - } -} -######################################################### -#endif - - -bool WikiDialog::getSelectedPage(std::string &pageId, std::string &origPageId) +bool WikiDialog::getSelectedPage(std::string &groupId, std::string &pageId, std::string &origPageId) { #ifdef WIKI_DEBUG std::cerr << "WikiDialog::getSelectedPage()" << std::endl; @@ -439,6 +377,7 @@ bool WikiDialog::getSelectedPage(std::string &pageId, std::string &origPageId) /* check if it has changed */ + groupId = parent->text(WIKI_GROUP_COL_GROUPID).toStdString(); pageId = item->text(WIKI_GROUP_COL_PAGEID).toStdString(); origPageId = item->text(WIKI_GROUP_COL_ORIGPAGEID).toStdString(); @@ -489,37 +428,7 @@ std::string WikiDialog::getSelectedGroup() #define WIKI_MODS_COL_ORIGPAGEID 0 #define WIKI_MODS_COL_PAGEID 1 - -#if 0 -######################################################### -void WikiDialog::insertModsForPage(std::string &origPageId) -{ - /* clear it all */ - //clearPhotos(); - //ui.photoLayout->clear(); - - /* create a list of albums */ - - std::list pageIds; - std::list::const_iterator it; - - rsWiki->getPageVersions(origPageId, pageIds); - - - for(it = pageIds.begin(); it != pageIds.end(); it++) - { - RsWikiSnapshot page; - rsWiki->getPage(*it, page); - - QTreeWidgetItem *modItem = new QTreeWidgetItem(NULL); - modItem->setText(WIKI_MODS_COL_ORIGPAGEID, QString::fromStdString(page.mOrigPageId)); - modItem->setText(WIKI_MODS_COL_PAGEID, QString::fromStdString(page.mPageId)); - ui.treeWidget_Mods->addTopLevelItem(modItem); - } -} -######################################################### -#endif - +#define WIKI_MODS_COL_PARENTID 2 std::string WikiDialog::getSelectedMod() @@ -562,39 +471,13 @@ void WikiDialog::requestGroupList() std::cerr << "WikiDialog::requestGroupList()"; std::cerr << std::endl; - std::list ids; RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + uint32_t token; - mWikiQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, ids, WIKIDIALOG_LISTING_GROUPLIST); + mWikiQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, WIKIDIALOG_LISTING_GROUPDATA); } -void WikiDialog::loadGroupList(const uint32_t &token) -{ - std::cerr << "WikiDialog::loadGroupList()"; - std::cerr << std::endl; - - std::list groupIds; - rsWiki->getGroupList(token, groupIds); - - if (groupIds.size() > 0) - { - requestGroupData(groupIds); - } - else - { - std::cerr << "WikiDialog::loadGroupList() ERROR No Groups..."; - std::cerr << std::endl; - } -} - -void WikiDialog::requestGroupData(const std::list &groupIds) -{ - RsTokReqOptions opts; - uint32_t token; -#if 0 - mWikiQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, WIKIDIALOG_LISTING_GROUPDATA); -#endif -} void WikiDialog::loadGroupData(const uint32_t &token) { @@ -603,139 +486,57 @@ void WikiDialog::loadGroupData(const uint32_t &token) clearGroupTree(); - bool moreData = true; - while(moreData) + std::vector datavector; + std::vector::iterator vit; + + if (!rsWiki->getCollections(token, datavector)) { - RsWikiCollection group; -#if 0 - if (rsWiki->getGroupData(token, group)) -#else - if (0) -#endif - { - /* Add Widget, and request Pages */ - - std::cerr << "WikiDialog::addGroup() GroupId: " << group.mMeta.mGroupId; - std::cerr << " Group: " << group.mMeta.mGroupName; - std::cerr << std::endl; - - QTreeWidgetItem *groupItem = new QTreeWidgetItem(); - groupItem->setText(WIKI_GROUP_COL_GROUPNAME, QString::fromStdString(group.mMeta.mGroupName)); - groupItem->setText(WIKI_GROUP_COL_GROUPID, QString::fromStdString(group.mMeta.mGroupId)); - ui.treeWidget_Pages->addTopLevelItem(groupItem); - - /* request pages */ - std::list groupIds; - groupIds.push_back(group.mMeta.mGroupId); - - requestOriginalPages(groupIds); - } - else - { - moreData = false; - } + std::cerr << "WikiDialog::loadGroupData() Error getting GroupData"; + std::cerr << std::endl; + return; + } + + for(vit = datavector.begin(); vit != datavector.end(); vit++) + { + RsWikiCollection &group = *vit; + + /* Add Widget, and request Pages */ + + std::cerr << "WikiDialog::addGroup() GroupId: " << group.mMeta.mGroupId; + std::cerr << " Group: " << group.mMeta.mGroupName; + std::cerr << std::endl; + + QTreeWidgetItem *groupItem = new QTreeWidgetItem(); + groupItem->setText(WIKI_GROUP_COL_GROUPNAME, QString::fromStdString(group.mMeta.mGroupName)); + groupItem->setText(WIKI_GROUP_COL_GROUPID, QString::fromStdString(group.mMeta.mGroupId)); + ui.treeWidget_Pages->addTopLevelItem(groupItem); + + /* request pages */ + std::list groupIds; + groupIds.push_back(group.mMeta.mGroupId); + + requestPages(groupIds); + //requestOriginalPages(groupIds); } - //return true; } -void WikiDialog::requestOriginalPages(const std::list &groupIds) -{ - RsTokReqOptions opts; - opts.mOptions = RS_TOKREQOPT_MSG_ORIGMSG; - uint32_t token; - mWikiQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, groupIds, WIKIDIALOG_LISTING_ORIGINALPAGES); -} -void WikiDialog::loadOriginalPages(const uint32_t &token) +void WikiDialog::requestPages(const std::list &groupIds) { - std::cerr << "WikiDialog::loadOriginalPages()"; + std::cerr << "WikiDialog::requestPages()"; std::cerr << std::endl; - /* translate into latest pages */ - std::list msgIds; -#if 0 - if (rsWiki->getMsgList(token, msgIds)) -#else - if (0) -#endif - { - std::cerr << "WikiDialog::loadOriginalPages() Loaded " << msgIds.size(); - std::cerr << std::endl; - } - else - { - std::cerr << "WikiDialog::loadOriginalPages() ERROR No Data"; - std::cerr << std::endl; - return; - } - - requestLatestPages(msgIds); - -} - -void WikiDialog::requestLatestPages(const std::list &msgIds) -{ RsTokReqOptions opts; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + opts.mOptions = (RS_TOKREQOPT_MSG_LATEST | RS_TOKREQOPT_MSG_THREAD); // We want latest version of Thread Heads. uint32_t token; -#if 0 - mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, msgIds, WIKIDIALOG_LISTING_LATESTPAGES); -#endif - + mWikiQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, WIKIDIALOG_LISTING_PAGES); } -void convert_result_to_list(const GxsMsgIdResult &result, std::list &list) -{ - GxsMsgIdResult::const_iterator it; - for(it = result.begin(); it != result.end(); it++) - { - std::vector::const_iterator vit; - for (vit = it->second.begin(); vit != it->second.end(); vit++) - { - list.push_back(*vit); - } - } -} - -void WikiDialog::loadLatestPages(const uint32_t &token) -{ - std::cerr << "WikiDialog::loadLatestPages()"; - std::cerr << std::endl; - - //std::list msgIds; - GxsMsgIdResult msgIds; - if (rsWiki->getMsgList(token, msgIds)) - { - std::cerr << "WikiDialog::loadLatestPages() Loaded " << msgIds.size(); - std::cerr << std::endl; - } - else - { - std::cerr << "WikiDialog::loadLatestPages() ERROR No Data"; - std::cerr << std::endl; - return; - } - - std::list list; - convert_result_to_list(msgIds, list); - - /* request actual data */ - //requestPages(list); - -} - -#if 0 -void WikiDialog::requestPages(std::list &msgids) -{ - RsTokReqOptions opts; - uint32_t token; - mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, WIKIDIALOG_LISTING_PAGES); -} -#endif void WikiDialog::loadPages(const uint32_t &token) { - std::cerr << "WikiDialog::loadLatestPages()"; + std::cerr << "WikiDialog::loadPages()"; std::cerr << std::endl; /* find parent in GUI Tree - stick children */ @@ -757,7 +558,7 @@ void WikiDialog::loadPages(const uint32_t &token) { /* find the entry */ int itemCount = ui.treeWidget_Pages->topLevelItemCount(); - for (int nIndex = 0; nIndex < itemCount;) + for (int nIndex = 0; nIndex < itemCount; nIndex++) { QTreeWidgetItem *tmpItem = ui.treeWidget_Pages->topLevelItem(nIndex); std::string tmpid = tmpItem->data(WIKI_GROUP_COL_GROUPID, @@ -790,35 +591,30 @@ void WikiDialog::loadPages(const uint32_t &token) groupItem->addChild(pageItem); } - //return true; } /***** Mods *****/ -void WikiDialog::insertModsForPage(const std::string &origPageId) +void WikiDialog::insertModsForPage(const RsGxsGrpMsgIdPair &origPageId) { requestModPageList(origPageId); } -void WikiDialog::requestModPageList(const std::string &origMsgId) +void WikiDialog::requestModPageList(const RsGxsGrpMsgIdPair &origMsgId) { RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; opts.mOptions = RS_TOKREQOPT_MSG_VERSIONS; - std::list msgIds; - msgIds.push_back(origMsgId); - uint32_t token; -#if 0 - mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, msgIds, WIKIDIALOG_MOD_LIST); -#endif + mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, origMsgId, WIKIDIALOG_MOD_LIST); } void WikiDialog::loadModPageList(const uint32_t &token) { - std::cerr << "WikiDialog::loadModPages()"; + std::cerr << "WikiDialog::loadModPageList()"; std::cerr << std::endl; /* translate into latest pages */ @@ -827,8 +623,18 @@ void WikiDialog::loadModPageList(const uint32_t &token) if (rsWiki->getMsgList(token, msgIds)) { - std::cerr << "WikiDialog::loadModPageList() Loaded " << msgIds.size(); - std::cerr << std::endl; + GxsMsgIdResult::iterator git; + for(git = msgIds.begin(); git != msgIds.end(); git++) + { + std::cerr << "WikiDialog::loadModPageList() Loaded GroupId: " << git->first; + std::cerr << std::endl; + std::vector::iterator vit; + for(vit = git->second.begin(); vit != git->second.end(); vit++) + { + std::cerr << "\tMsgId: " << *vit; + std::cerr << std::endl; + } + } } else { @@ -837,20 +643,21 @@ void WikiDialog::loadModPageList(const uint32_t &token) return; } - std::list list; - convert_result_to_list(msgIds, list); - requestModPages(list); - + requestModPages(msgIds); } -void WikiDialog::requestModPages(const std::list &msgIds) +void WikiDialog::requestModPages(const GxsMsgIdResult &msgIds) { + std::cerr << "WikiDialog::requestModPages()"; + std::cerr << std::endl; + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; uint32_t token; -#if 0 - mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, WIKIDIALOG_MOD_PAGES); -#endif + mWikiQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, WIKIDIALOG_MOD_PAGES); + + //mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, WIKIDIALOG_MOD_PAGES); } @@ -859,80 +666,195 @@ void WikiDialog::loadModPages(const uint32_t &token) std::cerr << "WikiDialog::loadModPages()"; std::cerr << std::endl; - bool moreData = true; - while(moreData) - { - RsWikiSnapshot page; -#if 0 - if (rsWiki->getMsgData(token, page)) -#endif - if (0) - { - std::cerr << "WikiDialog::loadModPages() PageId: " << page.mMeta.mMsgId; - std::cerr << " Page: " << page.mMeta.mMsgName; - std::cerr << std::endl; - QTreeWidgetItem *modItem = new QTreeWidgetItem(); - modItem->setText(WIKI_MODS_COL_ORIGPAGEID, QString::fromStdString(page.mMeta.mOrigMsgId)); - modItem->setText(WIKI_MODS_COL_PAGEID, QString::fromStdString(page.mMeta.mMsgId)); - ui.treeWidget_Mods->addTopLevelItem(modItem); + std::vector snapshots; + std::vector::iterator vit; + if (!rsWiki->getSnapshots(token, snapshots)) + { + // ERROR + std::cerr << "WikiDialog::loadModPages() ERROR"; + std::cerr << std::endl; + return; + } - } - else - { - moreData = false; - } + for(vit = snapshots.begin(); vit != snapshots.end(); vit++) + { + RsWikiSnapshot &page = *vit; + + std::cerr << "WikiDialog::loadModPages() PageId: " << page.mMeta.mMsgId; + std::cerr << " Page: " << page.mMeta.mMsgName; + std::cerr << std::endl; + + //QTreeWidgetItem *modItem = new QTreeWidgetItem(); + //modItem->setText(WIKI_MODS_COL_ORIGPAGEID, QString::fromStdString(page.mMeta.mOrigMsgId)); + //modItem->setText(WIKI_MODS_COL_PAGEID, QString::fromStdString(page.mMeta.mMsgId)); + //ui.treeWidget_Mods->addTopLevelItem(modItem); } + + + /* then we need to request all pages from this thread */ + requestEditTreeData(); } +void WikiDialog::requestEditTreeData() //const RsGxsGroupId &groupId) +{ + std::string groupId = getSelectedGroup(); + + // SWITCH THIS TO A THREAD REQUEST - WHEN WE CAN! + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST; + + std::list groupIds; + groupIds.push_back(groupId); + + uint32_t token; + mWikiQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, WIKIDIALOG_EDITTREE_DATA); +} + + + +void WikiDialog::loadEditTreeData(const uint32_t &token) +{ + std::cerr << "WikiDialog::loadEditTreeData()"; + std::cerr << std::endl; + + + std::vector snapshots; + std::vector::iterator vit; + if (!rsWiki->getSnapshots(token, snapshots)) + { + // ERROR + std::cerr << "WikiDialog::loadEditTreeData() ERROR"; + std::cerr << std::endl; + return; + } + + std::cerr << "WikiDialog::loadEditTreeData() Loaded " << snapshots.size(); + std::cerr << std::endl; + + std::map items; + std::map::iterator iit; + std::list unparented; + std::list::iterator uit; + + for(vit = snapshots.begin(); vit != snapshots.end(); vit++) + { + RsWikiSnapshot &snapshot = *vit; + + std::cerr << "Result: PageTitle: " << snapshot.mMeta.mMsgName; + std::cerr << " GroupId: " << snapshot.mMeta.mGroupId; + std::cerr << std::endl; + std::cerr << "\tOrigMsgId: " << snapshot.mMeta.mOrigMsgId; + std::cerr << " MsgId: " << snapshot.mMeta.mMsgId; + std::cerr << std::endl; + std::cerr << "\tThreadId: " << snapshot.mMeta.mThreadId; + std::cerr << " ParentId: " << snapshot.mMeta.mParentId; + std::cerr << std::endl; + + /* create an Entry */ + QTreeWidgetItem *modItem = new QTreeWidgetItem(); + modItem->setText(WIKI_MODS_COL_ORIGPAGEID, QString::fromStdString(snapshot.mMeta.mOrigMsgId)); + modItem->setText(WIKI_MODS_COL_PAGEID, QString::fromStdString(snapshot.mMeta.mMsgId)); + modItem->setText(WIKI_MODS_COL_PARENTID, QString::fromStdString(snapshot.mMeta.mParentId)); + + /* if no parentId */ + if (snapshot.mMeta.mParentId == "") + { + /* we've found one the missing ones */ + ui.treeWidget_Mods->addTopLevelItem(modItem); + + /* index by MsgId --> SPECIAL HACK FOR HERE! */ + items[snapshot.mMeta.mMsgId] = modItem; + continue; + } + + /* find the parent */ + iit = items.find(snapshot.mMeta.mParentId); + if (iit != items.end()) + { + (iit->second)->addChild(modItem); + } + else + { + unparented.push_back(modItem); + } + items[snapshot.mMeta.mOrigMsgId] = modItem; + } + + for(uit = unparented.begin(); uit != unparented.end(); uit++) + { + std::string parentId = (*uit)->text(WIKI_MODS_COL_PARENTID).toStdString(); + + iit = items.find(parentId); + if (iit != items.end()) + { + (iit->second)->addChild(*uit); + } + else + { + /* ERROR */ + std::cerr << "Unparented!!!"; + std::cerr << std::endl; + } + } +} + /***** Wiki *****/ -void WikiDialog::requestWikiPage(const std::string &msgId) +void WikiDialog::requestWikiPage(const RsGxsGrpMsgIdPair &msgId) { - RsTokReqOptions opts; + std::cerr << "WikiDialog::requestWikiPage(" << msgId.first << "," << msgId.second << ")"; + std::cerr << std::endl; - std::list msgIds; - msgIds.push_back(msgId); + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; uint32_t token; -#if 0 - mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, WIKIDIALOG_WIKI_PAGE); -#endif + + GxsMsgReq msgIds; + std::vector &vect_msgIds = msgIds[msgId.first]; + vect_msgIds.push_back(msgId.second); + + mWikiQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, WIKIDIALOG_WIKI_PAGE); + + //mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, WIKIDIALOG_WIKI_PAGE); } void WikiDialog::loadWikiPage(const uint32_t &token) { - std::cerr << "WikiDialog::loadModPages()"; + std::cerr << "WikiDialog::loadWikiPage()"; std::cerr << std::endl; // Should only have one WikiPage.... std::vector snapshots; if (!rsWiki->getSnapshots(token, snapshots)) { + std::cerr << "WikiDialog::loadWikiPage() ERROR"; + std::cerr << std::endl; + // ERROR return; } - if (snapshots.size() < 1) + if (snapshots.size() != 1) { + std::cerr << "WikiDialog::loadWikiPage() SIZE ERROR"; + std::cerr << std::endl; + // ERROR return; } - if (snapshots.size() > 1) - { - // ERROR - return; - } - RsWikiSnapshot page = snapshots[0]; - std::cerr << "WikiDialog::loadModPages() PageId: " << page.mMeta.mMsgId; + std::cerr << "WikiDialog::loadWikiPage() PageId: " << page.mMeta.mMsgId; std::cerr << " Page: " << page.mMeta.mMsgName; std::cerr << std::endl; @@ -951,22 +873,10 @@ void WikiDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) /* now switch on req */ switch(req.mUserType) { - case WIKIDIALOG_LISTING_GROUPLIST: - loadGroupList(req.mToken); - break; - case WIKIDIALOG_LISTING_GROUPDATA: loadGroupData(req.mToken); break; - case WIKIDIALOG_LISTING_ORIGINALPAGES: - loadOriginalPages(req.mToken); - break; - - case WIKIDIALOG_LISTING_LATESTPAGES: - loadLatestPages(req.mToken); - break; - case WIKIDIALOG_LISTING_PAGES: loadPages(req.mToken); break; @@ -979,12 +889,19 @@ void WikiDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) loadModPages(req.mToken); break; + case WIKIDIALOG_EDITTREE_DATA: + loadEditTreeData(req.mToken); + break; + case WIKIDIALOG_WIKI_PAGE: loadWikiPage(req.mToken); break; - +#define GXSGROUP_NEWGROUPID 1 + case GXSGROUP_NEWGROUPID: + insertWikiGroups(); + break; default: - std::cerr << "PhotoDialog::loadRequest() ERROR: INVALID TYPE"; + std::cerr << "WikiDialog::loadRequest() ERROR: INVALID TYPE"; std::cerr << std::endl; break; } diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.h b/retroshare-gui/src/gui/WikiPoos/WikiDialog.h index ce91b3785..970f61894 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.h +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.h @@ -51,6 +51,7 @@ private slots: void OpenOrShowAddPageDialog(); void OpenOrShowAddGroupDialog(); void OpenOrShowEditDialog(); + void OpenOrShowRepublishDialog(); void groupTreeChanged(); void modTreeChanged(); @@ -59,18 +60,21 @@ private slots: void showGroupDetails(); void editGroupDetails(); + void insertWikiGroups(); + private: void clearWikiPage(); void clearGroupTree(); void clearModsTree(); -void insertWikiGroups(); void insertModsForPage(const std::string &origPageId); +void insertModsForPage(const RsGxsGrpMsgIdPair &origPageId); + void updateWikiPage(const RsWikiSnapshot &page); -bool getSelectedPage(std::string &pageId, std::string &origPageId); +bool getSelectedPage(std::string &groupId, std::string &pageId, std::string &origPageId); std::string getSelectedPage(); std::string getSelectedGroup(); std::string getSelectedMod(); @@ -78,23 +82,26 @@ std::string getSelectedMod(); void requestGroupList(); -void loadGroupList(const uint32_t &token); -void requestGroupData(const std::list &groupIds); void loadGroupData(const uint32_t &token); -void requestOriginalPages(const std::list &groupIds); -void loadOriginalPages(const uint32_t &token); -void requestLatestPages(const std::list &msgIds); -void loadLatestPages(const uint32_t &token); -void requestPages(const std::list &msgIds); + +//void requestOriginalPages(const std::list &groupIds); +//void loadOriginalPages(const uint32_t &token); +//void requestLatestPages(const std::list &msgIds); +//void loadLatestPages(const uint32_t &token); +void requestPages(const std::list &groupIds); +//void requestPages(const std::list &msgIds); void loadPages(const uint32_t &token); -void requestModPageList(const std::string &origMsgId); +void requestModPageList(const RsGxsGrpMsgIdPair &origMsgId); void loadModPageList(const uint32_t &token); -void requestModPages(const std::list &msgIds); +void requestModPages(const GxsMsgIdResult &msgIds); void loadModPages(const uint32_t &token); -void requestWikiPage(const std::string &msgId); +void requestEditTreeData(); +void loadEditTreeData(const uint32_t &token); + +void requestWikiPage(const RsGxsGrpMsgIdPair &msgId); void loadWikiPage(const uint32_t &token); diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui index 433002c13..72e14a6b1 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui @@ -139,6 +139,13 @@
+ + + + Republish + + + @@ -180,10 +187,10 @@ - false + true - Delete + Refresh diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp index 4111f8dee..52a0d75c0 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp @@ -36,13 +36,15 @@ WikiEditDialog::WikiEditDialog(QWidget *parent) connect(ui.pushButton_Revert, SIGNAL( clicked( void ) ), this, SLOT( revertEdit( void ) ) ); connect(ui.pushButton_Submit, SIGNAL( clicked( void ) ), this, SLOT( submitEdit( void ) ) ); -#if 0 - mWikiQueue = new TokenQueue(rsWiki, this); -#endif + mWikiQueue = new TokenQueue(rsWiki->getTokenService(), this); + mRepublishMode = false; } void WikiEditDialog::setGroup(RsWikiCollection &group) { + std::cerr << "WikiEditDialog::setGroup(): " << group; + std::cerr << std::endl; + mWikiCollection = group; ui.lineEdit_Group->setText(QString::fromStdString(mWikiCollection.mMeta.mGroupName)); @@ -51,6 +53,9 @@ void WikiEditDialog::setGroup(RsWikiCollection &group) void WikiEditDialog::setPreviousPage(RsWikiSnapshot &page) { + std::cerr << "WikiEditDialog::setPreviousPage(): " << page; + std::cerr << std::endl; + mNewPage = false; mWikiSnapshot = page; @@ -63,12 +68,21 @@ void WikiEditDialog::setPreviousPage(RsWikiSnapshot &page) void WikiEditDialog::setNewPage() { mNewPage = true; + mRepublishMode = false; ui.lineEdit_Page->setText(""); ui.lineEdit_PrevVersion->setText(""); ui.textEdit->setPlainText(""); } +void WikiEditDialog::setRepublishMode(RsGxsMessageId &origMsgId) +{ + mRepublishMode = true; + mRepublishOrigId = origMsgId; +} + + + void WikiEditDialog::cancelEdit() { hide(); @@ -90,6 +104,9 @@ void WikiEditDialog::revertEdit() void WikiEditDialog::submitEdit() { + std::cerr << "WikiEditDialog::submitEdit()"; + std::cerr << std::endl; + if (mNewPage) { mWikiSnapshot.mMeta.mGroupId = mWikiCollection.mMeta.mGroupId; @@ -98,28 +115,78 @@ void WikiEditDialog::submitEdit() #if 0 mWikiSnapshot.mPrevId = ""; #endif + std::cerr << "WikiEditDialog::submitEdit() Is New Page"; + std::cerr << std::endl; + } + else if (mRepublishMode) + { + std::cerr << "WikiEditDialog::submitEdit() In Republish Mode"; + std::cerr << std::endl; + // A New Version of the ThreadHead. + mWikiSnapshot.mMeta.mGroupId = mWikiCollection.mMeta.mGroupId; + mWikiSnapshot.mMeta.mOrigMsgId = mRepublishOrigId; + mWikiSnapshot.mMeta.mParentId = ""; + mWikiSnapshot.mMeta.mThreadId = ""; + mWikiSnapshot.mMeta.mMsgId = ""; } else { -#if 0 - mWikiSnapshot.mPrevId = mWikiSnapshot.mMeta.mMsgId; -#endif + std::cerr << "WikiEditDialog::submitEdit() In Child Edit Mode"; + std::cerr << std::endl; + + // A Child of the current message. + bool isFirstChild = false; + if (mWikiSnapshot.mMeta.mParentId == "") + { + isFirstChild = true; + } + + mWikiSnapshot.mMeta.mGroupId = mWikiCollection.mMeta.mGroupId; + + if (isFirstChild) + { + mWikiSnapshot.mMeta.mThreadId = mWikiSnapshot.mMeta.mOrigMsgId; + // Special HACK here... parentId points to specific Msg, rather than OrigMsgId. + // This allows versioning to work well. + mWikiSnapshot.mMeta.mParentId = mWikiSnapshot.mMeta.mMsgId; + } + else + { + // ThreadId is the same. + mWikiSnapshot.mMeta.mParentId = mWikiSnapshot.mMeta.mOrigMsgId; + } + mWikiSnapshot.mMeta.mMsgId = ""; + mWikiSnapshot.mMeta.mOrigMsgId = ""; } + mWikiSnapshot.mMeta.mMsgName = ui.lineEdit_Page->text().toStdString(); mWikiSnapshot.mPage = ui.textEdit->toPlainText().toStdString(); + std::cerr << "WikiEditDialog::submitEdit() PageTitle: " << mWikiSnapshot.mMeta.mMsgName; + std::cerr << std::endl; + std::cerr << "WikiEditDialog::submitEdit() GroupId: " << mWikiSnapshot.mMeta.mGroupId; + std::cerr << std::endl; + std::cerr << "WikiEditDialog::submitEdit() OrigMsgId: " << mWikiSnapshot.mMeta.mOrigMsgId; + std::cerr << std::endl; + std::cerr << "WikiEditDialog::submitEdit() MsgId: " << mWikiSnapshot.mMeta.mMsgId; + std::cerr << std::endl; + std::cerr << "WikiEditDialog::submitEdit() ThreadId: " << mWikiSnapshot.mMeta.mThreadId; + std::cerr << std::endl; + std::cerr << "WikiEditDialog::submitEdit() ParentId: " << mWikiSnapshot.mMeta.mParentId; + std::cerr << std::endl; + uint32_t token; - bool isNew = mNewPage; -#if 0 - rsWiki->createPage(token, mWikiSnapshot, isNew); -#endif + //bool isNew = mNewPage; + //rsWiki->createPage(token, mWikiSnapshot, isNew); + rsWiki->submitSnapshot(token, mWikiSnapshot); hide(); } void WikiEditDialog::setupData(const std::string &groupId, const std::string &pageId) { + mRepublishMode = false; if (groupId != "") { requestGroup(groupId); @@ -127,7 +194,8 @@ void WikiEditDialog::setupData(const std::string &groupId, const std::string &pa if (pageId != "") { - requestPage(pageId); + RsGxsGrpMsgIdPair msgId = std::make_pair(groupId, pageId); + requestPage(msgId); } } @@ -143,6 +211,7 @@ void WikiEditDialog::requestGroup(const std::string &groupId) ids.push_back(groupId); RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; uint32_t token; mWikiQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, 0); } @@ -152,30 +221,33 @@ void WikiEditDialog::loadGroup(const uint32_t &token) std::cerr << "WikiEditDialog::loadGroup()"; std::cerr << std::endl; - RsWikiCollection group; -#if 0 - if (rsWiki->getGroupData(token, group)) -#else - if (0) -#endif + std::vector groups; + if (rsWiki->getCollections(token, groups)) { - setGroup(group); + if (groups.size() != 1) + { + std::cerr << "WikiEditDialog::loadGroup() ERROR No group data"; + std::cerr << std::endl; + return; + } + setGroup(groups[0]); } } -void WikiEditDialog::requestPage(const std::string &msgId) +void WikiEditDialog::requestPage(const RsGxsGrpMsgIdPair &msgId) { - std::cerr << "WikiEditDialog::requestGroup()"; + std::cerr << "WikiEditDialog::requestPage()"; std::cerr << std::endl; - std::list ids; - ids.push_back(msgId); RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + + GxsMsgReq msgIds; + std::vector &vect_msgIds = msgIds[msgId.first]; + vect_msgIds.push_back(msgId.second); uint32_t token; -#if 0 - mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, 0); -#endif + mWikiQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, 0); } void WikiEditDialog::loadPage(const uint32_t &token) @@ -183,14 +255,17 @@ void WikiEditDialog::loadPage(const uint32_t &token) std::cerr << "WikiEditDialog::loadPage()"; std::cerr << std::endl; - RsWikiSnapshot page; -#if 0 - if (rsWiki->getMsgData(token, page)) -#else - if (0) -#endif + std::vector snapshots; + + if (rsWiki->getSnapshots(token, snapshots)) { - setPreviousPage(page); + if (snapshots.size() != 1) + { + std::cerr << "WikiEditDialog::loadGroup() ERROR No group data"; + std::cerr << std::endl; + return; + } + setPreviousPage(snapshots[0]); } } @@ -207,7 +282,7 @@ void WikiEditDialog::loadRequest(const TokenQueue *queue, const TokenRequest &re case TOKENREQ_GROUPINFO: loadGroup(req.mToken); break; - case TOKENREQ_MSGRELATEDINFO: + case TOKENREQ_MSGINFO: loadPage(req.mToken); break; default: diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h index 5c04b13c5..851777b73 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h @@ -41,6 +41,8 @@ void setNewPage(); void setupData(const std::string &groupId, const std::string &pageId); void loadRequest(const TokenQueue *queue, const TokenRequest &req); +void setRepublishMode(RsGxsMessageId &origMsgId); + private slots: void cancelEdit(); @@ -52,12 +54,16 @@ private: void setGroup(RsWikiCollection &group); void setPreviousPage(RsWikiSnapshot &page); -void requestPage(const std::string &msgId); +void requestPage(const RsGxsGrpMsgIdPair &msgId); void loadPage(const uint32_t &token); void requestGroup(const std::string &groupId); void loadGroup(const uint32_t &token); bool mNewPage; + + bool mRepublishMode; + RsGxsMessageId mRepublishOrigId; + RsWikiCollection mWikiCollection; RsWikiSnapshot mWikiSnapshot; diff --git a/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.cpp new file mode 100644 index 000000000..75232c960 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.cpp @@ -0,0 +1,83 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include "GxsForumGroupDialog.h" + +#include +#include + +// To start with we only have open forums - with distribution controls. + +const uint32_t ForumCreateEnabledFlags = ( GXS_GROUP_FLAGS_ICON | + GXS_GROUP_FLAGS_DESCRIPTION | + GXS_GROUP_FLAGS_DISTRIBUTION | + // GXS_GROUP_FLAGS_PUBLISHSIGN | + GXS_GROUP_FLAGS_SHAREKEYS | + // GXS_GROUP_FLAGS_PERSONALSIGN | + // GXS_GROUP_FLAGS_COMMENTS | + 0); + +const uint32_t ForumCreateDefaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC | + //GXS_GROUP_DEFAULTS_DISTRIB_GROUP | + //GXS_GROUP_DEFAULTS_DISTRIB_LOCAL | + + GXS_GROUP_DEFAULTS_PUBLISH_OPEN | + //GXS_GROUP_DEFAULTS_PUBLISH_THREADS | + //GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED | + //GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED | + + //GXS_GROUP_DEFAULTS_PERSONAL_GPG | + GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED | + //GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | + + //GXS_GROUP_DEFAULTS_COMMENTS_YES | + GXS_GROUP_DEFAULTS_COMMENTS_NO | + 0); + + + +GxsForumGroupDialog::GxsForumGroupDialog(TokenQueue *tokenQueue, QWidget *parent) + :GxsGroupDialog(tokenQueue, ForumCreateEnabledFlags, ForumCreateDefaultsFlags, parent) +{ + + +} + +GxsForumGroupDialog::GxsForumGroupDialog(const RsGxsForumGroup &group, QWidget *parent) + :GxsGroupDialog(group.mMeta, GXS_GROUP_DIALOG_SHOW_MODE, parent) +{ + return; +} + + + +bool GxsForumGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) +{ + // Specific Function. + RsGxsForumGroup grp; + grp.mMeta = meta; + //grp.mDescription = std::string(desc.toUtf8()); + + rsGxsForums->createGroup(token, grp); + return true; +} + + diff --git a/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.h b/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.h new file mode 100644 index 000000000..8d27e0864 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.h @@ -0,0 +1,42 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + + +#ifndef _GXSFORUM_GROUP_DIALOG_H +#define _GXSFORUM_GROUP_DIALOG_H + +#include "GxsGroupDialog.h" +#include + +class GxsForumGroupDialog : public GxsGroupDialog +{ + Q_OBJECT + +public: + GxsForumGroupDialog(TokenQueue *tokenQueue, QWidget *parent); + GxsForumGroupDialog(const RsGxsForumGroup &group, QWidget *parent); + +protected: + virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); +}; + +#endif + diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index 29f428486..99d062f00 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -285,6 +285,9 @@ void GxsGroupDialog::submitGroup() void GxsGroupDialog::createGroup() { + std::cerr << "GxsGroupDialog::createGroup()"; + std::cerr << std::endl; + QString name = misc::removeNewLine(ui.groupName->text()); uint32_t flags = 0; diff --git a/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp b/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp index 6cf8e612d..3485ea605 100644 --- a/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp @@ -24,12 +24,39 @@ #include #include +const uint32_t WikiCreateEnabledFlags = ( GXS_GROUP_FLAGS_ICON | + GXS_GROUP_FLAGS_DESCRIPTION | + GXS_GROUP_FLAGS_DISTRIBUTION | + // GXS_GROUP_FLAGS_PUBLISHSIGN | + GXS_GROUP_FLAGS_SHAREKEYS | + // GXS_GROUP_FLAGS_PERSONALSIGN | + // GXS_GROUP_FLAGS_COMMENTS | + 0); + +uint32_t WikiCreateDefaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC | + //GXS_GROUP_DEFAULTS_DISTRIB_GROUP | + //GXS_GROUP_DEFAULTS_DISTRIB_LOCAL | + + GXS_GROUP_DEFAULTS_PUBLISH_OPEN | + //GXS_GROUP_DEFAULTS_PUBLISH_THREADS | + //GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED | + //GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED | + + //GXS_GROUP_DEFAULTS_PERSONAL_GPG | + GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED | + //GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | + + //GXS_GROUP_DEFAULTS_COMMENTS_YES | + GXS_GROUP_DEFAULTS_COMMENTS_NO | + 0); + + WikiGroupDialog::WikiGroupDialog(TokenQueue *tokenQueue, QWidget *parent) - :GxsGroupDialog(tokenQueue, parent, GXS_GROUP_DIALOG_CREATE_MODE) + :GxsGroupDialog(tokenQueue, WikiCreateEnabledFlags, WikiCreateDefaultsFlags, parent) { // To start with we only have open forums - with distribution controls. - +#if 0 uint32_t enabledFlags = ( GXS_GROUP_FLAGS_ICON | GXS_GROUP_FLAGS_DESCRIPTION | GXS_GROUP_FLAGS_DISTRIBUTION | @@ -60,12 +87,15 @@ WikiGroupDialog::WikiGroupDialog(TokenQueue *tokenQueue, QWidget *parent) //setFlags(enabledFlags, readonlyFlags, defaultsFlags); setFlags(enabledFlags, defaultsFlags); +#endif } WikiGroupDialog::WikiGroupDialog(const RsWikiCollection &collection, QWidget *parent) - :GxsGroupDialog(NULL, parent, GXS_GROUP_DIALOG_SHOW_MODE) + :GxsGroupDialog(collection.mMeta, GXS_GROUP_DIALOG_SHOW_MODE, parent) + { +#if 0 // To start with we only have open forums - with distribution controls. @@ -84,6 +114,7 @@ WikiGroupDialog::WikiGroupDialog(const RsWikiCollection &collection, QWidget *pa 0); setFlags(enabledFlags, defaultsFlags); +#endif } @@ -94,48 +125,12 @@ bool WikiGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData RsWikiCollection grp; grp.mMeta = meta; //grp.mDescription = std::string(desc.toUtf8()); + std::cerr << "WikiGroupDialog::service_CreateGroup() storing to Queue"; + std::cerr << std::endl; rsWiki->submitCollection(token, grp); + return true; } -QPixmap WikiGroupDialog::service_getLogo() -{ - return QPixmap(); // null pixmap -} - -QString WikiGroupDialog::service_getDescription() -{ - return QString(); -} - -RsGroupMetaData WikiGroupDialog::service_getMeta() -{ - return mGrp.mMeta; -} - - -#if 0 -void WikiGroupDialog::service_loadExistingGroup(const uint32_t &token) -{ - std::cerr << "WikiGroupDialog::service_loadExistingGroup()"; - std::cerr << std::endl; - - RsWikiCollection group; - if (!rsWiki->getGroupData(token, group)) - { - std::cerr << "WikiGroupDialog::service_loadExistingGroup() ERROR Getting Group"; - std::cerr << std::endl; - - return; - } - - /* must call metadata loader */ - loadExistingGroupMetaData(group.mMeta); - - /* now load any extra data we feel like */ - -} -#endif - diff --git a/retroshare-gui/src/gui/gxs/WikiGroupDialog.h b/retroshare-gui/src/gui/gxs/WikiGroupDialog.h index 6be72f0d9..fb217d36a 100644 --- a/retroshare-gui/src/gui/gxs/WikiGroupDialog.h +++ b/retroshare-gui/src/gui/gxs/WikiGroupDialog.h @@ -36,11 +36,6 @@ public: protected: virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); - virtual QPixmap service_getLogo(); - virtual QString service_getDescription(); - virtual RsGroupMetaData service_getMeta(); - - //virtual void service_loadExistingGroup(const uint32_t &token); private: diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForum.cpp b/retroshare-gui/src/gui/gxsforums/CreateGxsForum.cpp new file mode 100644 index 000000000..3c2a190d4 --- /dev/null +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForum.cpp @@ -0,0 +1,234 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include + +#include "util/misc.h" +#include "CreateGxsForum.h" +#include "gui/common/PeerDefs.h" + +#include + +#include +#include + +#include + +#define CREATEGXSFORUMS_NEWFORUMID 1 + + +/** Constructor */ +CreateGxsForum::CreateGxsForum(QWidget *parent) +: QDialog(parent) +{ + /* Invoke the Qt Designer generated object setup routine */ + ui.setupUi(this); + + mForumQueue = new TokenQueue(rsGxsForums->getTokenService(), this); + + // connect up the buttons. + connect( ui.cancelButton, SIGNAL( clicked ( bool ) ), this, SLOT( cancelForum( ) ) ); + connect( ui.createButton, SIGNAL( clicked ( bool ) ), this, SLOT( createForum( ) ) ); + connect( ui.pubKeyShare_cb, SIGNAL( clicked() ), this, SLOT( setShareList( ) )); + + if (!ui.pubKeyShare_cb->isChecked()) { + ui.contactsdockWidget->hide(); + this->resize(this->size().width() - ui.contactsdockWidget->size().width(), this->size().height()); + } + + /* initialize key share list */ + ui.keyShareList->setHeaderText(tr("Contacts:")); + ui.keyShareList->setModus(FriendSelectionWidget::MODUS_CHECK); + ui.keyShareList->start(); + + newForum(); +} + +void CreateGxsForum::newForum() +{ + /* enforce Public for the moment */ + ui.typePublic->setChecked(true); + + ui.typePrivate->setEnabled(false); + ui.typeEncrypted->setEnabled(true); + +#ifdef RS_RELEASE_VERSION + ui.typePrivate->setVisible(false); + ui.typeEncrypted->setVisible(true); +#endif + + ui.msgAnon->setChecked(true); + //ui.msgAuth->setEnabled(false); + + ui.forumName->clear(); + ui.forumDesc->clear(); + + ui.forumName->setFocus(); +} + +void CreateGxsForum::createForum() +{ + QString name = misc::removeNewLine(ui.forumName->text()); + QString desc = ui.forumDesc->toPlainText(); //toHtml(); + uint32_t flags = 0; + + if(name.isEmpty()) { + /* error message */ + QMessageBox::warning(this, "RetroShare", tr("Please add a Name"), QMessageBox::Ok, QMessageBox::Ok); + return; //Don't add a empty name!! + } + +#ifdef TOGXS + if (ui.typePublic->isChecked()) { + flags |= RS_DISTRIB_PUBLIC; + } else if (ui.typePrivate->isChecked()) { + flags |= RS_DISTRIB_PRIVATE; + } else if (ui.typeEncrypted->isChecked()) { + flags |= RS_DISTRIB_ENCRYPTED; + } + + if (ui.msgAuth->isChecked()) { + flags |= RS_DISTRIB_AUTHEN_REQ; + } else if (ui.msgAnon->isChecked()) { + flags |= RS_DISTRIB_AUTHEN_ANON; + } +#endif + + if (rsGxsForums) { + + + uint32_t token; + RsGxsForumGroup grp; + grp.mMeta.mGroupName = std::string(name.toUtf8()); + grp.mDescription = std::string(desc.toUtf8()); + grp.mMeta.mGroupFlags = flags; + + rsGxsForums->createGroup(token, grp); + + // get the Queue to handle response. + mForumQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_SUMMARY, CREATEGXSFORUMS_NEWFORUMID); + + } +} + +void CreateGxsForum::completeCreateNewForum(const RsGroupMetaData &newForumMeta) +{ + sendShareList(newForumMeta.mGroupId); + + close(); +} + + +void CreateGxsForum::sendShareList(std::string forumId) +{ + if (!rsGxsForums) + { + std::cerr << "CreateGxsForum::sendShareList() GxsForums not active"; + std::cerr << std::endl; + return; + } + + if (ui.pubKeyShare_cb->isChecked()) + { + std::list shareList; + ui.keyShareList->selectedSslIds(shareList, false); +#ifdef TOGXS + rsGxsForums->groupShareKeys(forumId, shareList); +#endif + } + close(); +} + + + + + + +void CreateGxsForum::setShareList() +{ + if (ui.pubKeyShare_cb->isChecked()){ + this->resize(this->size().width() + ui.contactsdockWidget->size().width(), this->size().height()); + ui.contactsdockWidget->show(); + } else { // hide share widget + ui.contactsdockWidget->hide(); + this->resize(this->size().width() - ui.contactsdockWidget->size().width(), this->size().height()); + } +} + +void CreateGxsForum::cancelForum() +{ + close(); +} + + + + +void CreateGxsForum::loadNewForumId(const uint32_t &token) +{ + std::cerr << "CreateGxsForum::loadNewForumId()"; + std::cerr << std::endl; + + std::list groupInfo; + rsGxsForums->getGroupSummary(token, groupInfo); + + if (groupInfo.size() == 1) + { + RsGroupMetaData fi = groupInfo.front(); + completeCreateNewForum(fi); + } + else + { + std::cerr << "CreateGxsForum::loadNewForumId() ERROR INVALID Number of Forums Created"; + std::cerr << std::endl; + } +} + + + + + + + + +void CreateGxsForum::loadRequest(const TokenQueue *queue, const TokenRequest &req) +{ + std::cerr << "CreateGxsForum::loadRequest() UserType: " << req.mUserType; + std::cerr << std::endl; + + if (queue == mForumQueue) + { + /* now switch on req */ + switch(req.mUserType) + { + + case CREATEGXSFORUMS_NEWFORUMID: + loadNewForumId(req.mToken); + break; + default: + std::cerr << "CreateGxsForum::loadRequest() UNKNOWN UserType "; + std::cerr << std::endl; + + } + } +} + + + diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForum.h b/retroshare-gui/src/gui/gxsforums/CreateGxsForum.h new file mode 100644 index 000000000..05ca6d1c5 --- /dev/null +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForum.h @@ -0,0 +1,67 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + + +#ifndef _CREATE_GXSFORUM_DIALOG_H +#define _CREATE_GXSFORUM_DIALOG_H + +#include "ui_CreateGxsForum.h" + +#include "util/TokenQueue.h" + +class CreateGxsForum : public QDialog, public TokenResponse +{ + Q_OBJECT + +public: + CreateGxsForum(QWidget *parent = 0); + + void newForum(); /* cleanup */ + + // Callback for all Loads. +virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); + +private slots: + /* actions to take.... */ + void createForum(); + void cancelForum(); + + // set private forum key share list + void setShareList(); + +private: + void sendShareList(std::string forumId); + void completeCreateNewForum(const RsGroupMetaData &newForumMeta); + void loadNewForumId(const uint32_t &token); + + + std::list mShareList; + + QPixmap picture; + + TokenQueue *mForumQueue; + + /** Qt Designer generated object */ + Ui::CreateGxsForum ui; +}; + +#endif + diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForum.ui b/retroshare-gui/src/gui/gxsforums/CreateGxsForum.ui new file mode 100644 index 000000000..85f7acf24 --- /dev/null +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForum.ui @@ -0,0 +1,374 @@ + + + CreateGxsForum + + + + 0 + 0 + 672 + 495 + + + + Create new Forum + + + + :/images/rstray3.png:/images/rstray3.png + + + + 0 + + + 0 + + + + + + 16777215 + 64 + + + + QFrame#frame_2{background-image: url(:/images/connect/connectFriendBanner.png);} + + + QFrame::NoFrame + + + QFrame::Raised + + + + 6 + + + 6 + + + + + + 48 + 48 + + + + + + + + + + :/images/konversation64.png + + + true + + + + + + + color: rgb(255, 255, 255); + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Arial'; font-size:24pt; font-weight:600; color:#ffffff;">New Forum</span></p></body></html> + + + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + + + + + Name + + + + + + + + + + + + true + + + + 0 + 0 + + + + + 300 + 524287 + + + + + 220 + 0 + + + + + 0 + 0 + + + + check peers you would like to share private publish key with + + + false + + + QDockWidget::NoDockWidgetFeatures + + + Share Key With + + + + + 0 + + + 0 + + + + + + 0 + 4 + + + + + 20 + 0 + + + + + 300 + 16777215 + + + + + 220 + 0 + + + + + 200 + 0 + + + + + + + + + + + + + + Description + + + + + + + + + + + + Type: + + + + 6 + + + + + Public - Anyone can read and publish (Shared Publish Key) + + + + + + + Restricted - Anyone can read, limited publishing (Private Publish Key) + + + + + + + Private - (Private Publish Key required to view Messages) + + + + + + + + + + Key Sharing + + + + 0 + + + 6 + + + + + Key recipients can publish to restricted-type channels, and can view and publish for private-type channels + + + Share Private Publish Key + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + Allowed Messages + + + + 0 + + + 6 + + + + + Authenticated Messages + + + + + + + Anonymous Messages + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + Qt::Horizontal + + + + 238 + 20 + + + + + + + + Cancel + + + + + + + Create + + + true + + + + + + + + + + + FriendSelectionWidget + QWidget +
gui/common/FriendSelectionWidget.h
+ 1 +
+
+ + + + +
diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp new file mode 100644 index 000000000..82fe2ce4e --- /dev/null +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp @@ -0,0 +1,442 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include "CreateGxsForumMsg.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "gui/settings/rsharesettings.h" +#include "gui/RetroShareLink.h" +#include "gui/common/Emoticons.h" + +#include "util/misc.h" + +#include +#include + + +#define CREATEGXSFORUMMSG_FORUMINFO 1 +#define CREATEGXSFORUMMSG_PARENTMSG 2 + + +/** Constructor */ +CreateGxsForumMsg::CreateGxsForumMsg(std::string fId, std::string pId) +: QMainWindow(NULL), mForumId(fId), mParentId(pId) +{ + /* Invoke the Qt Designer generated object setup routine */ + ui.setupUi(this); + setAttribute(Qt::WA_DeleteOnClose, true); + + /* Setup Queue */ + mForumQueue = new TokenQueue(rsGxsForums->getTokenService(), this); + + Settings->loadWidgetInformation(this); + + connect( ui.forumMessage, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( forumMessageCostumPopupMenu( QPoint ) ) ); + + connect(ui.hashBox, SIGNAL(fileHashingFinished(QList)), this, SLOT(fileHashingFinished(QList))); + + // connect up the buttons. + connect( ui.postmessage_action, SIGNAL( triggered (bool) ), this, SLOT( createMsg( ) ) ); + connect( ui.close_action, SIGNAL( triggered (bool) ), this, SLOT( cancelMsg( ) ) ); + connect( ui.emoticonButton, SIGNAL(clicked()), this, SLOT(smileyWidgetForums())); + connect( ui.attachFileButton, SIGNAL(clicked() ), this , SLOT(addFile())); + connect( ui.pastersButton, SIGNAL(clicked() ), this , SLOT(pasteLink())); + + setAcceptDrops(true); + ui.hashBox->setDropWidget(this); + ui.hashBox->setAutoHide(false); + + mParentMsgLoaded = false; + mForumMetaLoaded = false; + + newMsg(); +} + +/** context menu searchTablewidget2 **/ +void CreateGxsForumMsg::forumMessageCostumPopupMenu( QPoint /*point*/ ) +{ + QMenu *contextMnu = ui.forumMessage->createStandardContextMenu(); + + contextMnu->addSeparator(); + QAction *pasteLinkAct = contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste RetroShare Link"), this, SLOT(pasteLink())); + QAction *pasteLinkFullAct = contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste full RetroShare Link"), this, SLOT(pasteLinkFull())); + contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste own certificate link"), this, SLOT(pasteOwnCertificateLink())); + + if (RSLinkClipboard::empty()) { + pasteLinkAct->setDisabled (true); + pasteLinkFullAct->setDisabled (true); + } + + contextMnu->exec(QCursor::pos()); + delete(contextMnu); +} + +void CreateGxsForumMsg::newMsg() +{ + /* clear all */ + mParentMsgLoaded = false; + mForumMetaLoaded = false; + + /* request Data */ + { + RsTokReqOptions opts; + + std::list groupIds; + groupIds.push_back(mForumId); + + std::cerr << "ForumsV2Dialog::newMsg() Requesting Group Summary(" << mForumId << ")"; + std::cerr << std::endl; + + uint32_t token; + mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, groupIds, CREATEGXSFORUMMSG_FORUMINFO); + + } + + if (mParentId != "") + { + + RsTokReqOptions opts; + + std::list msgIds; + msgIds.push_back(mParentId); + + std::cerr << "ForumsV2Dialog::newMsg() Requesting Parent Summary(" << mParentId << ")"; + std::cerr << std::endl; + + uint32_t token; +#ifdef TOGXS + mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, CREATEGXSFORUMMSG_PARENTMSG); +#endif + } +} + + +void CreateGxsForumMsg::saveForumInfo(const RsGroupMetaData &meta) +{ + mForumMeta = meta; + mForumMetaLoaded = true; + + loadFormInformation(); +} + +void CreateGxsForumMsg::saveParentMsg(const RsGxsForumMsg &msg) +{ + mParentMsg = msg; + mParentMsgLoaded = true; + + loadFormInformation(); +} + +void CreateGxsForumMsg::loadFormInformation() +{ + if ((!mParentMsgLoaded) && (mParentId != "")) + { + std::cerr << "CreateGxsForumMsg::loadMsgInformation() ParentMsg not Loaded Yet"; + std::cerr << std::endl; + return; + } + + if (!mForumMetaLoaded) + { + std::cerr << "CreateGxsForumMsg::loadMsgInformation() ForumMeta not Loaded Yet"; + std::cerr << std::endl; + return; + } + + std::cerr << "CreateGxsForumMsg::loadMsgInformation() Data Available!"; + std::cerr << std::endl; + + QString name = QString::fromUtf8(mForumMeta.mGroupName.c_str()); + QString subj; + if (mParentId != "") + { + QString title = QString::fromUtf8(mParentMsg.mMeta.mMsgName.c_str()); + name += " " + tr("In Reply to") + ": "; + name += title; + + QString text = title; + + if (text.startsWith("Re:", Qt::CaseInsensitive)) + { + subj = title; + } + else + { + subj = "Re: " + title; + } + + } + + ui.forumName->setText(misc::removeNewLine(name)); + ui.forumSubject->setText(misc::removeNewLine(subj)); + + if (!ui.forumSubject->text().isEmpty()) + { + ui.forumMessage->setFocus(); + } + else + { + ui.forumSubject->setFocus(); + } + +#ifdef TOGXS + if (mForumMeta.mGroupFlags & RS_DISTRIB_AUTHEN_REQ) +#else + if (1) +#endif + { + ui.signBox->setChecked(true); + ui.signBox->setEnabled(false); + } + else + { + /* Uncheck sign box by default for anonymous forums */ + ui.signBox->setChecked(false); + ui.signBox->setEnabled(true); + } + + ui.forumMessage->setText(""); +} + + + +void CreateGxsForumMsg::createMsg() +{ + QString name = misc::removeNewLine(ui.forumSubject->text()); + QString desc = ui.forumMessage->toHtml(); + + if(desc == QTextDocument(ui.forumMessage->toPlainText()).toHtml()) + desc = ui.forumMessage->toPlainText() ; + + if(name.isEmpty()) + { /* error message */ + QMessageBox::warning(this, tr("RetroShare"),tr("Please set a Forum Subject and Forum Message"), + QMessageBox::Ok, QMessageBox::Ok); + + return; //Don't add a empty Subject!! + } + + RsGxsForumMsg msg; + msg.mMeta.mGroupId = mForumId; + msg.mMeta.mParentId = mParentId; + msg.mMeta.mMsgId = ""; + if (mParentMsgLoaded) + { + msg.mMeta.mThreadId = mParentMsg.mMeta.mThreadId; + } + + msg.mMeta.mMsgName = std::string(name.toUtf8()); + msg.mMsg = std::string(desc.toUtf8()); +#ifdef TOGXS + msg.mMeta.mMsgFlags = RS_DISTRIB_AUTHEN_REQ; +#endif + + if ((msg.mMsg == "") && (msg.mMeta.mMsgName == "")) + return; /* do nothing */ + + uint32_t token; + rsGxsForums->createMsg(token, msg); + close(); + + + // Previous Info - for reference. + + //ForumMsgInfo msgInfo; + + //msgInfo.forumId = mForumId; + //msgInfo.threadId = ""; + //msgInfo.parentId = mParentId; + //msgInfo.msgId = ""; + + //msgInfo.title = name.toStdWString(); + //msgInfo.msg = desc.toStdWString(); + //msgInfo.msgflags = 0; + + //if (ui.signBox->isChecked()) + //{ + // msgInfo.msgflags = RS_DISTRIB_AUTHEN_REQ; + //} + + //if ((msgInfo.msg == L"") && (msgInfo.title == L"")) + // return; /* do nothing */ + + //if (rsForumsV2->ForumMessageSend(msgInfo) == true) { + // close(); + //} +} + + + + +void CreateGxsForumMsg::closeEvent (QCloseEvent * /*event*/) +{ + Settings->saveWidgetInformation(this); +} + +void CreateGxsForumMsg::cancelMsg() +{ + close(); +} + +void CreateGxsForumMsg::smileyWidgetForums() +{ + Emoticons::showSmileyWidget(this, ui.emoticonButton, SLOT(addSmileys()), false); +} + +void CreateGxsForumMsg::addSmileys() +{ + ui.forumMessage->textCursor().insertText(qobject_cast(sender())->toolTip().split("|").first()); +} + +void CreateGxsForumMsg::addFile() +{ + QStringList files; + if (misc::getOpenFileNames(this, RshareSettings::LASTDIR_EXTRAFILE, tr("Add Extra File"), "", files)) { + ui.hashBox->addAttachments(files); + } +} + +void CreateGxsForumMsg::fileHashingFinished(QList hashedFiles) +{ + std::cerr << "CreateGxsForumMsg::fileHashingFinished() started." << std::endl; + + QString mesgString; + + QList::iterator it; + for (it = hashedFiles.begin(); it != hashedFiles.end(); ++it) { + HashedFile& hashedFile = *it; + RetroShareLink link; + if (link.createFile(hashedFile.filename, hashedFile.size, QString::fromStdString(hashedFile.hash))) { + mesgString += link.toHtmlSize() + "
"; + } + } + +#ifdef CHAT_DEBUG + std::cerr << "CreateGxsForumMsg::anchorClicked mesgString : " << mesgString.toStdString() << std::endl; +#endif + + if (!mesgString.isEmpty()) { + ui.forumMessage->textCursor().insertHtml(mesgString); + } + + ui.forumMessage->setFocus( Qt::OtherFocusReason ); +} + +void CreateGxsForumMsg::pasteLink() +{ + ui.forumMessage->insertHtml(RSLinkClipboard::toHtml()) ; +} + +void CreateGxsForumMsg::pasteLinkFull() +{ + ui.forumMessage->insertHtml(RSLinkClipboard::toHtmlFull()) ; +} + +void CreateGxsForumMsg::pasteOwnCertificateLink() +{ + RetroShareLink link ; + std::string ownId = rsPeers->getOwnId() ; + if( link.createCertificate(ownId) ) { + ui.forumMessage->insertHtml(link.toHtml() + " "); + } +} + + + + +void CreateGxsForumMsg::loadForumInfo(const uint32_t &token) +{ + std::cerr << "CreateGxsForumMsg::loadForumInfo()"; + std::cerr << std::endl; + + std::list groupInfo; + rsGxsForums->getGroupSummary(token, groupInfo); + + if (groupInfo.size() == 1) + { + RsGroupMetaData fi = groupInfo.front(); + saveForumInfo(fi); + } + else + { + std::cerr << "CreateGxsForumMsg::loadForumInfo() ERROR INVALID Number of Forums"; + std::cerr << std::endl; + } +} + + +void CreateGxsForumMsg::loadParentMsg(const uint32_t &token) +{ + std::cerr << "CreateGxsForumMsg::loadParentMsg()"; + std::cerr << std::endl; + + // Only grab one.... ignore more (shouldn't be any). + std::vector msgs; + if (rsGxsForums->getMsgData(token, msgs)) + { + if (msgs.size() != 1) + { + /* error */ + std::cerr << "CreateGxsForumMsg::loadParentMsg() ERROR wrong number of msgs"; + std::cerr << std::endl; + + + } + saveParentMsg(msgs[0]); + } +} + + + +void CreateGxsForumMsg::loadRequest(const TokenQueue *queue, const TokenRequest &req) +{ + std::cerr << "CreateGxsForum::loadRequest() UserType: " << req.mUserType; + std::cerr << std::endl; + + if (queue == mForumQueue) + { + /* now switch on req */ + switch(req.mUserType) + { + case CREATEGXSFORUMMSG_FORUMINFO: + loadForumInfo(req.mToken); + break; + + case CREATEGXSFORUMMSG_PARENTMSG: + loadParentMsg(req.mToken); + break; + default: + std::cerr << "CreateGxsForum::loadRequest() UNKNOWN UserType "; + std::cerr << std::endl; + + } + } +} + diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.h b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.h new file mode 100644 index 000000000..a3be9e183 --- /dev/null +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.h @@ -0,0 +1,86 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + + +#ifndef _CREATE_GXSFORUM_MSG_DIALOG_H +#define _CREATE_GXSFORUM_MSG_DIALOG_H + +#include "ui_CreateGxsForumMsg.h" + +#include "util/TokenQueue.h" + +#include + + +class CreateGxsForumMsg : public QMainWindow, public TokenResponse +{ + Q_OBJECT + +public: + CreateGxsForumMsg(std::string fId, std::string pId); + + void newMsg(); /* cleanup */ + virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); + +private slots: + /** Create the context popup menu and it's submenus */ + void forumMessageCostumPopupMenu( QPoint point ); + + void fileHashingFinished(QList hashedFiles); + /* actions to take.... */ + void createMsg(); + void cancelMsg(); + void pasteLink(); + void pasteLinkFull(); + void pasteOwnCertificateLink(); + + void smileyWidgetForums(); + void addSmileys(); + void addFile(); + +protected: + void closeEvent (QCloseEvent * event); + +private: + + void saveForumInfo(const RsGroupMetaData &meta); + void saveParentMsg(const RsGxsForumMsg &msg); + void loadFormInformation(); + + void loadForumInfo(const uint32_t &token); + void loadParentMsg(const uint32_t &token); + + std::string mForumId; + std::string mParentId; + + bool mParentMsgLoaded; + bool mForumMetaLoaded; + RsGxsForumMsg mParentMsg; + RsGroupMetaData mForumMeta; + + TokenQueue *mForumQueue; + + /** Qt Designer generated object */ + Ui::CreateGxsForumMsg ui; +}; + +#endif + diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.ui b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.ui new file mode 100644 index 000000000..d71364f87 --- /dev/null +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.ui @@ -0,0 +1,333 @@ + + + CreateGxsForumMsg + + + Qt::NonModal + + + + 0 + 0 + 482 + 448 + + + + Post Forum Message + + + + :/images/rstray3.png:/images/rstray3.png + + + QToolBar#toolBar{background-image: url(:/images/connect/connectFriendBanner.png)} + + + Qt::ToolButtonTextUnderIcon + + + + + 0 + + + 0 + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 6 + + + 6 + + + + + + + Forum + + + + + + + false + + + + + + + + + + + Subject + + + + + + + + + + + + + + + + 16777215 + 38 + + + + QFrame#frame_2{ +background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, +stop:0 #FEFEFE, stop:1 #E8E8E8); + +border: 1px solid #CCCCCC;} + + + QFrame::Raised + + + + 6 + + + + + Qt::NoFocus + + + Attach File + + + + + + + :/images/add-share24.png:/images/add-share24.png + + + + 24 + 24 + + + + true + + + + + + + Qt::NoFocus + + + + + + + :/images/emoticons/kopete/kopete020.png:/images/emoticons/kopete/kopete020.png + + + + 24 + 24 + + + + true + + + + + + + Qt::NoFocus + + + Sign Message + + + + :/images/pgp.png:/images/pgp.png + + + + 24 + 24 + + + + true + + + + + + + Qt::Horizontal + + + + 40 + 15 + + + + + + + + Qt::NoFocus + + + Paste RetroShare Link + + + + + + + :/images/pasterslink.png:/images/pasterslink.png + + + true + + + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 6 + + + 6 + + + + + Forum Post + + + + + + Qt::CustomContextMenu + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></p></body></html> + + + + + + + + + + Attach files via drag and drop + + + + + + + 0 + 0 + + + + You can attach files via drag and drop here in this window + + + true + + + + + + + + + + + + + + + + toolBar + + + TopToolBarArea + + + false + + + + + + + + :/images/mail_send24.png:/images/mail_send24.png + + + Post Forum Msg + + + + + + :/images/button_cancel.png:/images/button_cancel.png + + + Close + + + + + + HashBox + QScrollArea +
gui/common/HashBox.h
+ 1 +
+
+ + + + +
diff --git a/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.cpp b/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.cpp new file mode 100644 index 000000000..13ebfe43e --- /dev/null +++ b/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.cpp @@ -0,0 +1,89 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2010 RetroShare Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include "EditGxsForumDetails.h" + +#include + +#include "util/misc.h" + +#include +#include +#include + + +/** Default constructor */ +EditGxsForumDetails::EditGxsForumDetails(std::string forumId, QWidget *parent, Qt::WFlags flags) + : QDialog(parent, flags), m_forumId(forumId) +{ + /* Invoke Qt Designer generated QObject setup routine */ + ui.setupUi(this); + + connect(ui.applyButton, SIGNAL(clicked()), this, SLOT(applyDialog())); + + loadForum(); +} + +void EditGxsForumDetails::loadForum() +{ + if (!rsGxsForums) { + return; + } + +#warning "EditGxsForumDetails incomplete" +#if 0 + ForumInfo info; + rsGxsForums->getForumInfo(m_forumId, info); + + // set name + ui.nameline->setText(QString::fromStdWString(info.forumName)); + + // set description + ui.DescriptiontextEdit->setText(QString::fromStdWString(info.forumDesc)); +#endif + +} + +void EditGxsForumDetails::applyDialog() +{ + if (!rsGxsForums) { + return; + } + + // if text boxes have not been edited leave alone + if (!ui.nameline->isModified() && !ui.DescriptiontextEdit->document()->isModified()) { + return; + } + +#warning "EditGxsForumDetails incomplete" +#if 0 + + ForumInfo info; + + info.forumName = misc::removeNewLine(ui.nameline->text()).toStdWString(); + info.forumDesc = ui.DescriptiontextEdit->document()->toPlainText().toStdWString(); + + rsGxsForums->setForumInfo(m_forumId, info); +#endif + + /* close the Dialog after the Changes applied */ + close(); +} diff --git a/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.h b/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.h new file mode 100644 index 000000000..3a38cc7c9 --- /dev/null +++ b/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.h @@ -0,0 +1,53 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2010 RetroShare Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#ifndef _EDITGXSFORUMDETAILS_H +#define _EDITGXSFORUMDETAILS_H + +#include + +#include "ui_EditGxsForumDetails.h" + +class EditGxsForumDetails : public QDialog +{ + Q_OBJECT + +public: + /** Default constructor */ + EditGxsForumDetails(std::string forumId = "", QWidget *parent = 0, Qt::WFlags flags = 0); + +signals: + void configChanged(); + +private slots: + void applyDialog(); + +private: + void loadForum(); + + std::string m_forumId; + + /** Qt Designer generated object */ + Ui::EditGxsForumDetails ui; +}; + +#endif + diff --git a/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.ui b/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.ui new file mode 100644 index 000000000..b211bd0e6 --- /dev/null +++ b/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.ui @@ -0,0 +1,130 @@ + + + EditGxsForumDetails + + + + 0 + 0 + 436 + 355 + + + + Forum Details + + + + :/images/rstray3.png:/images/rstray3.png + + + + + + + + Qt::Horizontal + + + + 311 + 20 + + + + + + + + Cancel + + + + + + + OK + + + false + + + true + + + + + + + + + 0 + + + + + :/images/info16.png:/images/info16.png + + + Edit Forum Details + + + + + + Forum Info + + + + + + Forum Name + + + + + + + + + + Forum Description + + + + + + + + + + + + + + + + + + + + + + + cancelButton + clicked() + EditForumDetails + close() + + + 307 + 333 + + + 217 + 177 + + + + + diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumDetails.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumDetails.cpp new file mode 100644 index 000000000..3f26dc1c5 --- /dev/null +++ b/retroshare-gui/src/gui/gxsforums/GxsForumDetails.cpp @@ -0,0 +1,146 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2009 RetroShare Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ +#include "GxsForumDetails.h" + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + + +/* Define the format used for displaying the date and time */ +#define DATETIME_FMT "MMM dd hh:mm:ss" + +/** Default constructor */ +GxsForumDetails::GxsForumDetails(QWidget *parent, Qt::WFlags flags) + : QDialog(parent, flags) +{ + /* Invoke Qt Designer generated QObject setup routine */ + ui.setupUi(this); + + connect(ui.applyButton, SIGNAL(clicked()), this, SLOT(applyDialog())); + connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(closeinfodlg())); + + ui.applyButton->setToolTip(tr("Apply and Close")); + + ui.nameline ->setReadOnly(true); + ui.popline ->setReadOnly(true); + ui.postline ->setReadOnly(true); + ui.IDline ->setReadOnly(true); + ui.DescriptiontextEdit ->setReadOnly(true); + + ui.radioButton_authd->setEnabled(false); + ui.radioButton_anonymous->setEnabled(false); +} + + +/** + Overloads the default show() slot so we can set opacity*/ + +void +GxsForumDetails::show() +{ + //loadSettings(); + if(!this->isVisible()) { + QDialog::show(); + + } +} + +void GxsForumDetails::closeEvent (QCloseEvent * event) +{ + QWidget::closeEvent(event); +} + +void GxsForumDetails::closeinfodlg() +{ + close(); +} + +void GxsForumDetails::showDetails(std::string mCurrForumId) +{ + fId = mCurrForumId; + loadDialog(); +} + +void GxsForumDetails::loadDialog() +{ + if (!rsGxsForums) + { + return; + } + +#warning "GxsForumDetails Incomplete" +#if 0 + ForumInfo fi; + rsGxsForums->getForumInfo(fId, fi); + + // Set Forum Name + ui.nameline->setText(QString::fromStdWString(fi.forumName)); + + // Set Popularity + ui.popline->setText(QString::number(fi.pop)); + + // Set Last Post Date + if (fi.lastPost) { + QDateTime qtime; + qtime.setTime_t(fi.lastPost); + QString timestamp = qtime.toString("yyyy-MM-dd hh:mm:ss"); + ui.postline->setText(timestamp); + } + + // Set Forum ID + ui.IDline->setText(QString::fromStdString(fi.forumId)); + + // Set Forum Description + ui.DescriptiontextEdit->setText(QString::fromStdWString(fi.forumDesc)); + + if (fi.forumFlags & RS_DISTRIB_AUTHEN_REQ) + { + ui.radioButton_authd->setChecked(true); + ui.radioButton_anonymous->setChecked(false); + } + if (fi.forumFlags & RS_DISTRIB_AUTHEN_ANON) + { + ui.radioButton_authd->setChecked(false); + ui.radioButton_anonymous->setChecked(true); + } +#endif + +} + +void GxsForumDetails::applyDialog() +{ + + /* reload now */ + loadDialog(); + + /* close the Dialog after the Changes applied */ + closeinfodlg(); + +} diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumDetails.h b/retroshare-gui/src/gui/gxsforums/GxsForumDetails.h new file mode 100644 index 000000000..a45f9d018 --- /dev/null +++ b/retroshare-gui/src/gui/gxsforums/GxsForumDetails.h @@ -0,0 +1,67 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2009 RetroShare Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#ifndef _GXSFORUMDETAILS_H +#define _GXSFORUMDETAILS_H + +#include + +#include "ui_GxsForumDetails.h" + +class GxsForumDetails : public QDialog +{ + Q_OBJECT + + public: + + /** Default constructor */ + GxsForumDetails(QWidget *parent = 0, Qt::WFlags flags = 0); + /** Default destructor */ + + void showDetails(std::string mCurrForumId); + +signals: + void configChanged() ; + +public slots: + /** Overloaded QWidget.show */ + void show(); + +protected: + void closeEvent (QCloseEvent * event); + +private slots: + + void closeinfodlg(); + void applyDialog(); + +private: + + void loadDialog(); + + std::string fId; + /** Qt Designer generated object */ + Ui::GxsForumDetails ui; + +}; + +#endif + diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumDetails.ui b/retroshare-gui/src/gui/gxsforums/GxsForumDetails.ui new file mode 100644 index 000000000..182d7bc63 --- /dev/null +++ b/retroshare-gui/src/gui/gxsforums/GxsForumDetails.ui @@ -0,0 +1,201 @@ + + + GxsForumDetails + + + + 0 + 0 + 436 + 355 + + + + Forum Details + + + + :/images/rstray3.png:/images/rstray3.png + + + + + + 0 + + + + + :/images/info16.png:/images/info16.png + + + Forum Details + + + + + + Forum Info + + + + + + Forum Name + + + + + + + + + + Popularity + + + + + + + true + + + + + + + Last Post + + + + + + + true + + + + + + + Forum ID + + + + + + + + + + Forum Description + + + + + + + + + + + + + + + + + :/images/encrypted22.png:/images/encrypted22.png + + + Security + + + + + + Allowed Messages + + + + + + Authenticated Messages + + + + + + + Anonymous Messages + + + true + + + + + + + + + + Qt::Vertical + + + + 358 + 172 + + + + + + + + + + + + + + Qt::Horizontal + + + + 311 + 20 + + + + + + + + Cancel + + + + + + + OK + + + false + + + true + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp index c77b630e3..1c7672295 100644 --- a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp +++ b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp @@ -30,12 +30,11 @@ #include "gui/PhotoShare/PhotoShare.h" #include "gui/WikiPoos/WikiDialog.h" #include "gui/Posted/PostedDialog.h" +#include "gui/GxsForumsDialog.h" // THESE HAVE TO BE CONVERTED TO VEG FORMAT #if USE_VEG_SERVICE #include "gui/TheWire/WireDialog.h" -#include "gui/ForumsV2Dialog.h" - #endif //#include "GamesDialog.h" @@ -54,7 +53,7 @@ #define IMAGE_CALENDAR ":/images/calendar.png" #define IMAGE_LIBRARY ":/images/library.png" #define IMAGE_PLUGINS ":/images/extension_32.png" -#define IMAGE_FORUMSV2 ":/images/konversation.png" +#define IMAGE_GXSFORUMS ":/images/konversation.png" /** Constructor */ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) @@ -97,9 +96,13 @@ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) ui.stackPages->add(postedDialog = new PostedDialog(ui.stackPages), createPageAction(QIcon(IMAGE_LIBRARY), tr("Posted Links"), grp)); -// WikiDialog *wikiDialog = NULL; -// ui.stackPages->add(wikiDialog = new WikiDialog(ui.stackPages), -// createPageAction(QIcon(IMAGE_LIBRARY), tr("Wiki Pages"), grp)); + WikiDialog *wikiDialog = NULL; + ui.stackPages->add(wikiDialog = new WikiDialog(ui.stackPages), + createPageAction(QIcon(IMAGE_LIBRARY), tr("Wiki Pages"), grp)); + + GxsForumsDialog *gxsforumsDialog = NULL; + ui.stackPages->add(gxsforumsDialog = new GxsForumsDialog(ui.stackPages), + createPageAction(QIcon(IMAGE_GXSFORUMS), tr("GxsForums"), grp)); // THESE HAVE TO BE CONVERTED TO VEG FORMAT #if USE_VEG_SERVICE @@ -107,11 +110,6 @@ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) ui.stackPages->add(wireDialog = new WireDialog(ui.stackPages), createPageAction(QIcon(IMAGE_BWGRAPH), tr("The Wire"), grp)); - ForumsV2Dialog *forumsV2Dialog = NULL; - ui.stackPages->add(forumsV2Dialog = new ForumsV2Dialog(ui.stackPages), - createPageAction(QIcon(IMAGE_FORUMSV2), tr("ForumsV2"), grp)); - - #endif /* Create the toolbar */ diff --git a/retroshare-gui/src/util/TokenQueue.cpp b/retroshare-gui/src/util/TokenQueue.cpp index 75031dea1..02d9ebee0 100644 --- a/retroshare-gui/src/util/TokenQueue.cpp +++ b/retroshare-gui/src/util/TokenQueue.cpp @@ -67,10 +67,9 @@ bool TokenQueue::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokRe } -bool TokenQueue::requestMsgRelatedInfo(uint32_t &token, const RsTokReqOptions &opts, const RsGxsGrpMsgIdPair &msgId, uint32_t usertype) +bool TokenQueue::requestMsgRelatedInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, const RsGxsGrpMsgIdPair &msgId, uint32_t usertype) { uint32_t basictype = TOKENREQ_MSGINFO; - uint32_t anstype = RS_TOKREQ_ANSTYPE_LIST; // always a list answer mService->requestMsgRelatedInfo(token, anstype, opts, msgId); queueRequest(token, basictype, anstype, usertype); @@ -125,21 +124,39 @@ void TokenQueue::pollRequests() { double pollPeriod = 1.0; // max poll period. - TokenRequest req; - if(mRequests.size() > 0){ - req = mRequests.front(); - }else - { - return; - } + if (mRequests.empty()) + { + return; + } + + TokenRequest req; + req = mRequests.front(); + mRequests.pop_front(); if (checkForRequest(req.mToken)) { /* clean it up and handle */ loadRequest(req); - mRequests.pop_front(); } + else + { + +#define MAX_REQUEST_AGE 30 + + /* drop old requests too */ + if (time(NULL) - req.mRequestTs.tv_sec < MAX_REQUEST_AGE) + { + mRequests.push_back(req); + } + else + { + std::cerr << "TokenQueue::loadRequest(): "; + std::cerr << "Dropping old Token: " << req.mToken << " Type: " << req.mType; + std::cerr << std::endl; + } + + } if (mRequests.size() > 0) { diff --git a/retroshare-gui/src/util/TokenQueue.h b/retroshare-gui/src/util/TokenQueue.h index 417266e06..d0cb4fb26 100644 --- a/retroshare-gui/src/util/TokenQueue.h +++ b/retroshare-gui/src/util/TokenQueue.h @@ -93,7 +93,7 @@ public: bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, const GxsMsgReq& grpIds, uint32_t usertype); - bool requestMsgRelatedInfo(uint32_t &token, const RsTokReqOptions &opts, const RsGxsGrpMsgIdPair& msgId, uint32_t usertype); + bool requestMsgRelatedInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, const RsGxsGrpMsgIdPair& msgId, uint32_t usertype); bool cancelRequest(const uint32_t token); From f74a328d61c2fb481a7e3beeee01f8690d396dd0 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Tue, 13 Nov 2012 22:36:06 +0000 Subject: [PATCH 143/222] Bug fix for ES_GXS_MSG_COMMENTS option Fix for run thread loop of RsGenExchange (was using logic rather than isRunning, which led to some crashes on rs close Added request and get MsgRelated function for ids, meta and data added template function to ease getting meta data from back end; Updated Nxs tests, tests passed (failed initially because of change option requirements) Added test for msgrelated Ids, still need to add test for all msgRelated functions (bug with mask, not filtering correctly) Made changes for forum and wiki gui to use new API but gui needs to call correct get functions now (Bob). git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5817 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgds.h | 1 + libretroshare/src/gxs/rsgenexchange.cc | 80 +++- libretroshare/src/gxs/rsgenexchange.h | 77 ++++ libretroshare/src/gxs/rsgxs.h | 4 + libretroshare/src/gxs/rsgxsdataaccess.cc | 411 ++++++++++++------ libretroshare/src/gxs/rsgxsdataaccess.h | 27 +- libretroshare/src/gxs/rsgxsifaceimpl.cc | 12 + libretroshare/src/gxs/rsgxsifaceimpl.h | 17 + libretroshare/src/gxs/rsgxsrequesttypes.h | 6 +- libretroshare/src/gxs/rstokenservice.h | 6 +- libretroshare/src/retroshare/rsphotoV2.h | 12 + .../src/services/p3photoserviceV2.cc | 72 +-- libretroshare/src/services/p3photoserviceV2.h | 2 +- .../src/tests/gxs/genexchangetester.cpp | 229 +++++++--- .../src/tests/gxs/genexchangetester.h | 13 +- .../src/tests/gxs/genexchangetestservice.cpp | 20 +- .../src/tests/gxs/genexchangetestservice.h | 12 +- libretroshare/src/tests/gxs/nxs_tests.pro | 53 +-- libretroshare/src/tests/gxs/rsdummyservices.h | 69 +++ .../src/tests/gxs/rsgenexchange_test.cc | 19 +- retroshare-gui/src/gui/ForumsV2Dialog.cpp | 4 +- retroshare-gui/src/gui/GxsForumsDialog.cpp | 13 +- .../src/gui/PhotoShare/PhotoDialog.cpp | 12 +- .../src/gui/WikiPoos/WikiDialog.cpp | 5 +- .../src/gui/forumsv2/CreateForumV2Msg.cpp | 2 +- retroshare-gui/src/util/TokenQueue.cpp | 2 +- retroshare-gui/src/util/TokenQueue.h | 2 +- 27 files changed, 872 insertions(+), 310 deletions(-) diff --git a/libretroshare/src/gxs/rsgds.h b/libretroshare/src/gxs/rsgds.h index e80af47bc..abe39f363 100644 --- a/libretroshare/src/gxs/rsgds.h +++ b/libretroshare/src/gxs/rsgds.h @@ -76,6 +76,7 @@ public: }; typedef std::map > NxsMsgDataResult; +typedef std::map > NxsMsgRelatedDataResult; typedef std::map > GxsMsgResult; // /*! diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 7096fd9dd..dbf6e5600 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -75,7 +75,7 @@ void RsGenExchange::run() double timeDelta = 0.1; // slow tick - while(true) + while(isRunning()) { tick(); @@ -303,7 +303,7 @@ bool RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBina const RsGxsMsgMetaData& msgMeta, RsGxsGrpMetaData& grpMeta) { bool isParent = false; - bool needPublishSign, needIdentitySign; + bool needPublishSign = false, needIdentitySign = false; bool ok = true; uint32_t grpFlag = grpMeta.mGroupFlags; @@ -452,6 +452,7 @@ bool RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBina #ifdef GEN_EXHANGE_DEBUG std::cerr << "Gixs not enabled while request identity signature validation!" << std::endl; #endif + ok = false; } } @@ -694,6 +695,11 @@ bool RsGenExchange::getMsgList(const uint32_t &token, return mDataAccess->getMsgList(token, msgIds); } +bool RsGenExchange::getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult &msgIds) +{ + return mDataAccess->getMsgRelatedList(token, msgIds); +} + bool RsGenExchange::getGroupMeta(const uint32_t &token, std::list &groupInfo) { std::list metaL; @@ -744,6 +750,36 @@ bool RsGenExchange::getMsgMeta(const uint32_t &token, return ok; } +bool RsGenExchange::getMsgRelatedMeta(const uint32_t &token, GxsMsgRelatedMetaMap &msgMeta) +{ + MsgRelatedMetaResult result; + bool ok = mDataAccess->getMsgRelatedSummary(token, result); + + MsgRelatedMetaResult::iterator mit = result.begin(); + + for(; mit != result.end(); mit++) + { + std::vector& metaV = mit->second; + + msgMeta[mit->first] = std::vector(); + std::vector& msgInfoV = msgMeta[mit->first]; + + std::vector::iterator vit = metaV.begin(); + RsMsgMetaData meta; + for(; vit != metaV.end(); vit++) + { + RsGxsMsgMetaData& m = *(*vit); + meta = m; + msgInfoV.push_back(meta); + delete *vit; + } + metaV.clear(); + } + + return ok; +} + + bool RsGenExchange::getGroupData(const uint32_t &token, std::vector& grpItem) { @@ -814,6 +850,46 @@ bool RsGenExchange::getMsgData(const uint32_t &token, return ok; } +bool RsGenExchange::getMsgRelatedData(const uint32_t &token, GxsMsgRelatedDataMap &msgItems) +{ + + RsStackMutex stack(mGenMtx); + NxsMsgRelatedDataResult msgResult; + bool ok = mDataAccess->getMsgRelatedData(token, msgResult); + NxsMsgRelatedDataResult::iterator mit = msgResult.begin(); + + if(ok) + { + for(; mit != msgResult.end(); mit++) + { + std::vector gxsMsgItems; + const RsGxsGrpMsgIdPair& msgId = mit->first; + std::vector& nxsMsgsV = mit->second; + std::vector::iterator vit + = nxsMsgsV.begin(); + for(; vit != nxsMsgsV.end(); vit++) + { + RsNxsMsg*& msg = *vit; + + RsItem* item = mSerialiser->deserialise(msg->msg.bin_data, + &msg->msg.bin_len); + RsGxsMsgItem* mItem = dynamic_cast(item); + + if(mItem != NULL) + { + mItem->meta = *((*vit)->metaData); // get meta info from nxs msg + gxsMsgItems.push_back(mItem); + } + delete msg; + } + msgItems[msgId] = gxsMsgItems; + } + } + return ok; +} + + + RsTokenService* RsGenExchange::getTokenService() { diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 73169dc58..0efd32343 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -39,7 +39,9 @@ typedef std::map > GxsMsgDataMap; typedef std::map GxsGroupDataMap; +typedef std::map > GxsMsgRelatedDataMap; typedef std::map > GxsMsgMetaMap; +typedef std::map > GxsMsgRelatedMetaMap; /*! * This should form the parent class to \n @@ -151,14 +153,24 @@ public: * Retrieve msg list for a given token sectioned by group Ids * @param token token to be redeemed * @param msgIds a map of grpId -> msgList (vector) + * @return false if could not redeem token */ bool getMsgList(const uint32_t &token, GxsMsgIdResult &msgIds); + /*! + * Retrieve msg list for a given token for message related info + * @param token token to be redeemed + * @param msgIds a map of RsGxsGrpMsgIdPair -> msgList (vector) + * @return false if could not redeem token + */ + bool getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult& msgIds); + /*! * retrieve group meta data associated to a request token * @param token * @param groupInfo + * @return false if could not redeem token */ bool getGroupMeta(const uint32_t &token, std::list &groupInfo); @@ -169,6 +181,14 @@ public: */ bool getMsgMeta(const uint32_t &token, GxsMsgMetaMap &msgInfo); + /*! + * Retrieve msg meta for a given token for message related info + * @param token token to be redeemed + * @param msgIds a map of RsGxsGrpMsgIdPair -> msgList (vector) + * @return false if could not redeem token + */ + bool getMsgRelatedMeta(const uint32_t &token, GxsMsgRelatedMetaMap& msgMeta); + @@ -194,6 +214,63 @@ protected: */ bool getMsgData(const uint32_t &token, GxsMsgDataMap& msgItems); + /*! + * retrieves message related data associated to a request token + * @param token token to be redeemed for message item retrieval + * @param msgItems + */ + bool getMsgRelatedData(const uint32_t &token, GxsMsgRelatedDataMap& msgItems); + + /*! + * Convenience template function for retrieve + * msg related data from + * @param GxsMsgType This represent derived msg class type of the service (i.e. msg type that derives from RsGxsMsgItem + * @param MsgType Represents the final type the core data is converted to + * @param token token to be redeemed + */ + template + bool getMsgRelatedDataT(const uint32_t &token, std::map > &msgItems) + { + + RsStackMutex stack(mGenMtx); + NxsMsgRelatedDataResult msgResult; + bool ok = mDataAccess->getMsgRelatedData(token, msgResult); + NxsMsgRelatedDataResult::iterator mit = msgResult.begin(); + + if(ok) + { + for(; mit != msgResult.end(); mit++) + { + std::vector gxsMsgItems; + const RsGxsGrpMsgIdPair& msgId = mit->first; + std::vector& nxsMsgsV = mit->second; + std::vector::iterator vit + = nxsMsgsV.begin(); + for(; vit != nxsMsgsV.end(); vit++) + { + RsNxsMsg*& msg = *vit; + + RsItem* item = mSerialiser->deserialise(msg->msg.bin_data, + &msg->msg.bin_len); + GxsMsgType* mItem = dynamic_cast(item); + + if(mItem == NULL){ + delete msg; + continue; + } + + mItem->meta = *((*vit)->metaData); // get meta info from nxs msg + // GxsMsgType m = (*mItem); // doesn't work! don't know why, even with overloading done. + MsgType theServMsg = (MsgType)*mItem; + gxsMsgItems.push_back(theServMsg); + delete msg; + } + msgItems[msgId] = gxsMsgItems; + } + } + return ok; + } + /*! * Assigns a token value to passed integer * The status of the token can still be queried from request status feature diff --git a/libretroshare/src/gxs/rsgxs.h b/libretroshare/src/gxs/rsgxs.h index 5fef2a329..6ef240f6c 100644 --- a/libretroshare/src/gxs/rsgxs.h +++ b/libretroshare/src/gxs/rsgxs.h @@ -40,6 +40,10 @@ typedef std::map > GxsMsgReq; typedef std::map > GxsMsgIdResult; typedef std::map > GxsMsgMetaResult; typedef std::map > MsgMetaResult; +typedef std::map > MsgRelatedMetaResult; +typedef std::map > MsgRelatedIdResult; + + class RsGxsService { diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index f01a7407c..6a56b6112 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -270,11 +270,11 @@ bool RsGxsDataAccess::requestMsgInfo(uint32_t &token, uint32_t ansType, } bool RsGxsDataAccess::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, - const RsGxsGrpMsgIdPair &msgIds) + const std::vector &msgIds) { MsgRelatedInfoReq* req = new MsgRelatedInfoReq(); - req->mMsgId = msgIds; + req->mMsgIds = msgIds; generateToken(token); @@ -422,13 +422,15 @@ bool RsGxsDataAccess::getMsgData(const uint32_t& token, NxsMsgDataResult& msgDat return false; }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ - MsgDataReq* mdreq = dynamic_cast(req); + MsgDataReq* mdreq = dynamic_cast(req); if(mdreq) { - msgData = mdreq->mMsgData; - locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); - }else{ + msgData = mdreq->mMsgData; + locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); + } + else + { std::cerr << "RsGxsDataAccess::getMsgData() Req found, failed caste" << std::endl; return false; } @@ -440,6 +442,42 @@ bool RsGxsDataAccess::getMsgData(const uint32_t& token, NxsMsgDataResult& msgDat return true; } +bool RsGxsDataAccess::getMsgRelatedData(const uint32_t &token, NxsMsgRelatedDataResult &msgData) +{ + + RsStackMutex stack(mDataMutex); + + GxsRequest* req = locked_retrieveRequest(token); + + if(req == NULL){ + + std::cerr << "RsGxsDataAccess::getMsgRelatedData() Unable to retrieve group data" << std::endl; + return false; + }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ + + MsgRelatedInfoReq* mrireq = dynamic_cast(req); + + if(req->Options.mReqType != GXS_REQUEST_TYPE_MSG_RELATED_DATA) + return false; + + if(mrireq) + { + msgData = mrireq->mMsgDataResult; + locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); + } + else + { + std::cerr << "RsGxsDataAccess::getMsgRelatedData() Req found, failed caste" << std::endl; + return false; + } + }else{ + std::cerr << "RsGxsDataAccess::getMsgRelatedData() Req not ready" << std::endl; + return false; + } + + return true; +} + bool RsGxsDataAccess::getMsgSummary(const uint32_t& token, GxsMsgMetaResult& msgInfo) { @@ -457,10 +495,12 @@ bool RsGxsDataAccess::getMsgSummary(const uint32_t& token, GxsMsgMetaResult& msg if(mmreq) { - msgInfo = mmreq->mMsgMetaData; - locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); + msgInfo = mmreq->mMsgMetaData; + locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); - }else{ + } + else + { std::cerr << "RsGxsDataAccess::getMsgSummary() Req found, failed caste" << std::endl; return false; } @@ -472,6 +512,83 @@ bool RsGxsDataAccess::getMsgSummary(const uint32_t& token, GxsMsgMetaResult& msg return true; } +bool RsGxsDataAccess::getMsgRelatedSummary(const uint32_t &token, MsgRelatedMetaResult &msgMeta) +{ + + RsStackMutex stack(mDataMutex); + + GxsRequest* req = locked_retrieveRequest(token); + + + + if(req == NULL){ + + std::cerr << "RsGxsDataAccess::getMsgRelatedSummary() Unable to retrieve message summary" << std::endl; + return false; + }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ + + if(req->Options.mReqType != GXS_REQUEST_TYPE_MSG_RELATED_META) + return false; + + MsgRelatedInfoReq* mrireq = dynamic_cast(req); + + if(mrireq) + { + msgMeta = mrireq->mMsgMetaResult; + locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); + } + else + { + std::cerr << "RsGxsDataAccess::getMsgRelatedSummary() Req found, failed caste" << std::endl; + return false; + } + } + else + { + std::cerr << "RsGxsDataAccess::getMsgRelatedSummary() Req not ready" << std::endl; + return false; + } + + return true; +} + + +bool RsGxsDataAccess::getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult &msgIds) +{ + RsStackMutex stack(mDataMutex); + + GxsRequest* req = locked_retrieveRequest(token); + + if(req == NULL){ + + std::cerr << "RsGxsDataAccess::getMsgRelatedList() Unable to retrieve message data" << std::endl; + return false; + }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ + + if(req->Options.mReqType != GXS_REQUEST_TYPE_MSG_RELATED_IDS) + return false; + + MsgRelatedInfoReq* mrireq = dynamic_cast(req); + + if(mrireq) + { + msgIds = mrireq->mMsgIdResult; + locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); + } + else{ + std::cerr << "RsGxsDataAccess::getMsgRelatedList() Req found, failed caste" << std::endl; + return false; + } + } + else + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() Req not ready" << std::endl; + return false; + } + + return true; +} + bool RsGxsDataAccess::getMsgList(const uint32_t& token, GxsMsgIdResult& msgIds) { RsStackMutex stack(mDataMutex); @@ -480,23 +597,17 @@ bool RsGxsDataAccess::getMsgList(const uint32_t& token, GxsMsgIdResult& msgIds) if(req == NULL){ - std::cerr << "RsGxsDataAccess::getMsgList() Unable to retrieve group data" << std::endl; + std::cerr << "RsGxsDataAccess::getMsgList() Unable to retrieve msg Ids" << std::endl; return false; }else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE){ - MsgIdReq* mireq = dynamic_cast(req); - MsgRelatedInfoReq* mrireq = dynamic_cast(req); + MsgIdReq* mireq = dynamic_cast(req); if(mireq) { msgIds = mireq->mMsgIdResult; locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); } - else if(mrireq) - { - msgIds = mrireq->mMsgIdResult; - locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); - } else{ std::cerr << "RsGxsDataAccess::getMsgList() Req found, failed caste" << std::endl; return false; @@ -517,7 +628,7 @@ bool RsGxsDataAccess::getGroupList(const uint32_t& token, std::liststatus == GXS_REQUEST_V2_STATUS_COMPLETE){ @@ -1007,159 +1118,185 @@ bool RsGxsDataAccess::getMsgRelatedInfo(MsgRelatedInfoReq *req) return true; } - MsgMetaFilter filterMap; + std::vector::iterator vit_msgIds = req->mMsgIds.begin(); - // get meta data for all in group - GxsMsgMetaResult result; - GxsMsgReq msgIds; - msgIds.insert(std::make_pair(req->mMsgId.first, std::vector())); - mDataStore->retrieveGxsMsgMetaData(msgIds, result); - std::vector& metaV = result[req->mMsgId.first]; - std::vector::iterator vit_meta; - - // msg id to relate to - const RsGxsMessageId& msgId = req->mMsgId.second; - const RsGxsGroupId& grpId = req->mMsgId.first; - - std::vector outMsgIds; - - - - RsGxsMsgMetaData* origMeta = NULL; - for(vit_meta = metaV.begin(); vit_meta != metaV.end(); vit_meta++) + for(; vit_msgIds != req->mMsgIds.end(); vit_msgIds++) { - RsGxsMsgMetaData* meta = *vit_meta; + MsgMetaFilter filterMap; - if(msgId == meta->mMsgId) + + const RsGxsGrpMsgIdPair& grpMsgIdPair = *vit_msgIds; + + // get meta data for all in group + GxsMsgMetaResult result; + GxsMsgReq msgIds; + msgIds.insert(std::make_pair(grpMsgIdPair.first, std::vector())); + mDataStore->retrieveGxsMsgMetaData(msgIds, result); + std::vector& metaV = result[grpMsgIdPair.first]; + std::vector::iterator vit_meta; + + // msg id to relate to + const RsGxsMessageId& msgId = grpMsgIdPair.second; + const RsGxsGroupId& grpId = grpMsgIdPair.first; + + std::vector outMsgIds; + + RsGxsMsgMetaData* origMeta = NULL; + for(vit_meta = metaV.begin(); vit_meta != metaV.end(); vit_meta++) { - origMeta = meta; - break; - } - } + RsGxsMsgMetaData* meta = *vit_meta; - if(!origMeta) - { - std::cerr << "RsGxsDataAccess::getMsgRelatedInfo(): Cannot find meta of msgId (to relate to)!" - << std::endl; - cleanseMsgMetaMap(result); - return false; - } - - const RsGxsMessageId& origMsgId = origMeta->mOrigMsgId; - std::map& metaMap = filterMap[grpId]; - - if (onlyLatestMsgs) - { - if (onlyChildMsgs || onlyThreadMsgs) - { - // RUN THROUGH ALL MSGS... in map origId -> TS. - std::map > origMsgTs; - std::map >::iterator oit; - for(vit_meta = metaV.begin(); vit_meta != metaV.end(); vit_meta++) + if(msgId == meta->mMsgId) { + origMeta = meta; + break; + } + } - RsGxsMsgMetaData* meta = *vit_meta; + if(!origMeta) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedInfo(): Cannot find meta of msgId (to relate to)!" + << std::endl; + cleanseMsgMetaMap(result); + return false; + } - // skip msgs that aren't children. - if (onlyChildMsgs) + const RsGxsMessageId& origMsgId = origMeta->mOrigMsgId; + std::map& metaMap = filterMap[grpId]; + + if (onlyLatestMsgs) + { + if (onlyChildMsgs || onlyThreadMsgs) + { + // RUN THROUGH ALL MSGS... in map origId -> TS. + std::map > origMsgTs; + std::map >::iterator oit; + for(vit_meta = metaV.begin(); vit_meta != metaV.end(); vit_meta++) { - if (meta->mParentId != origMsgId) + + RsGxsMsgMetaData* meta = *vit_meta; + + // skip msgs that aren't children. + if (onlyChildMsgs) { - continue; + if (meta->mParentId != origMsgId) + { + continue; + } } - } - else /* onlyThreadMsgs */ - { - if (meta->mThreadId != msgId) + else /* onlyThreadMsgs */ { - continue; + if (meta->mThreadId != msgId) + { + continue; + } + } + + + oit = origMsgTs.find(meta->mOrigMsgId); + + bool addMsg = false; + if (oit == origMsgTs.end()) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() Found New OrigMsgId: "; + std::cerr << meta->mOrigMsgId; + std::cerr << " MsgId: " << meta->mMsgId; + std::cerr << " TS: " << meta->mPublishTs; + std::cerr << std::endl; + + addMsg = true; + } + // check timestamps. + else if (oit->second.second < meta->mPublishTs) + { + std::cerr << "RsGxsDataAccess::getMsgRelatedList() Found Later Msg. OrigMsgId: "; + std::cerr << meta->mOrigMsgId; + std::cerr << " MsgId: " << meta->mMsgId; + std::cerr << " TS: " << meta->mPublishTs; + + addMsg = true; + } + + if (addMsg) + { + // add as latest. (overwriting if necessary) + origMsgTs[meta->mOrigMsgId] = std::make_pair(meta->mMsgId, meta->mPublishTs); + metaMap.insert(std::make_pair(meta->mOrigMsgId, meta)); } } - - oit = origMsgTs.find(meta->mOrigMsgId); - - bool addMsg = false; - if (oit == origMsgTs.end()) + // Add the discovered Latest Msgs. + for(oit = origMsgTs.begin(); oit != origMsgTs.end(); oit++) { - std::cerr << "RsGxsDataAccess::getMsgRelatedList() Found New OrigMsgId: "; - std::cerr << meta->mOrigMsgId; - std::cerr << " MsgId: " << meta->mMsgId; - std::cerr << " TS: " << meta->mPublishTs; - std::cerr << std::endl; - - addMsg = true; - } - // check timestamps. - else if (oit->second.second < meta->mPublishTs) - { - std::cerr << "RsGxsDataAccess::getMsgRelatedList() Found Later Msg. OrigMsgId: "; - std::cerr << meta->mOrigMsgId; - std::cerr << " MsgId: " << meta->mMsgId; - std::cerr << " TS: " << meta->mPublishTs; - - addMsg = true; - } - - if (addMsg) - { - // add as latest. (overwriting if necessary) - origMsgTs[meta->mOrigMsgId] = std::make_pair(meta->mMsgId, meta->mPublishTs); - metaMap.insert(std::make_pair(meta->mOrigMsgId, meta)); + outMsgIds.push_back(oit->second.first); } } - - // Add the discovered Latest Msgs. - for(oit = origMsgTs.begin(); oit != origMsgTs.end(); oit++) + else { - outMsgIds.push_back(oit->second.first); + + /* first guess is potentially better than Orig (can't be worse!) */ + time_t latestTs = 0; + RsGxsMessageId latestMsgId; + RsGxsMsgMetaData* latestMeta; + + for(vit_meta = metaV.begin(); vit_meta != metaV.end(); vit_meta++) + { + RsGxsMsgMetaData* meta = *vit_meta; + + if (meta->mOrigMsgId == origMsgId) + { + if (meta->mPublishTs > latestTs) + { + latestTs = meta->mPublishTs; + latestMsgId = meta->mMsgId; + latestMeta = meta; + } + } + } + outMsgIds.push_back(latestMsgId); + metaMap.insert(std::make_pair(latestMsgId, latestMeta)); } } - else + else if (onlyAllVersions) { - - /* first guess is potentially better than Orig (can't be worse!) */ - time_t latestTs = 0; - RsGxsMessageId latestMsgId; - RsGxsMsgMetaData* latestMeta; - for(vit_meta = metaV.begin(); vit_meta != metaV.end(); vit_meta++) { RsGxsMsgMetaData* meta = *vit_meta; if (meta->mOrigMsgId == origMsgId) { - if (meta->mPublishTs > latestTs) - { - latestTs = meta->mPublishTs; - latestMsgId = meta->mMsgId; - latestMeta = meta; - } + outMsgIds.push_back(meta->mMsgId); + metaMap.insert(std::make_pair(meta->mMsgId, meta)); } } - outMsgIds.push_back(latestMsgId); - metaMap.insert(std::make_pair(latestMsgId, latestMeta)); } - } - else if (onlyAllVersions) - { - for(vit_meta = metaV.begin(); vit_meta != metaV.end(); vit_meta++) + + GxsMsgIdResult filteredOutMsgIds; + filteredOutMsgIds[grpId] = outMsgIds; + filterMsgList(filteredOutMsgIds, opts, filterMap); + + if(req->Options.mReqType == GXS_REQUEST_TYPE_MSG_RELATED_IDS) { - RsGxsMsgMetaData* meta = *vit_meta; - - if (meta->mOrigMsgId == origMsgId) - { - outMsgIds.push_back(meta->mMsgId); - metaMap.insert(std::make_pair(meta->mOrigMsgId, meta)); - } + req->mMsgIdResult[grpMsgIdPair] = filteredOutMsgIds[grpId]; } + else if(req->Options.mReqType == GXS_REQUEST_TYPE_MSG_RELATED_META) + { + GxsMsgMetaResult metaResult; + mDataStore->retrieveGxsMsgMetaData(filteredOutMsgIds, metaResult); + req->mMsgMetaResult[grpMsgIdPair] = metaResult[grpId]; + } + else if(req->Options.mReqType == GXS_REQUEST_TYPE_MSG_RELATED_DATA) + { + GxsMsgResult msgResult; + mDataStore->retrieveNxsMsgs(filteredOutMsgIds, msgResult, false, true); + req->mMsgDataResult[grpMsgIdPair] = msgResult[grpId]; + } + + outMsgIds.clear(); + filteredOutMsgIds.clear(); + + cleanseMsgMetaMap(result); } - - req->mMsgIdResult[grpId] = outMsgIds; - filterMsgList(req->mMsgIdResult, opts, filterMap); - - cleanseMsgMetaMap(result); - return true; } diff --git a/libretroshare/src/gxs/rsgxsdataaccess.h b/libretroshare/src/gxs/rsgxsdataaccess.h index c0c3ac90f..f8703477d 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.h +++ b/libretroshare/src/gxs/rsgxsdataaccess.h @@ -90,7 +90,7 @@ public: * @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs * @return true if request successful false otherwise */ - bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const RsGxsGrpMsgIdPair &msgIds); + bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::vector &msgIds); /* Poll */ uint32_t requestStatus(const uint32_t token); @@ -143,6 +143,14 @@ public: */ bool getMsgList(const uint32_t &token, GxsMsgIdResult &msgIds); + /*! + * Retrieve msg list for a given token for message related info + * @param token token to be redeemed + * @param msgIds a map of RsGxsGrpMsgIdPair -> msgList (vector) + * @return false if could not redeem token + */ + bool getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult& msgIds); + /*! * @param token request token to be redeemed @@ -157,6 +165,15 @@ public: */ bool getMsgSummary(const uint32_t &token, GxsMsgMetaResult &msgInfo); + + /*! + * Retrieve msg meta for a given token for message related info + * @param token token to be redeemed + * @param msgIds a map of RsGxsGrpMsgIdPair -> msgList (vector) + * @return false if could not redeem token + */ + bool getMsgRelatedSummary(const uint32_t &token, MsgRelatedMetaResult& msgMeta); + /*! * * @param token request token to be redeemed @@ -172,6 +189,14 @@ public: */ bool getMsgData(const uint32_t &token, NxsMsgDataResult& msgData); + /*! + * + * @param token request token to be redeemed + * @param msgData + * @return false if data cannot be found for token + */ + bool getMsgRelatedData(const uint32_t &token, NxsMsgRelatedDataResult& msgData); + private: /** helper functions to implement token service **/ diff --git a/libretroshare/src/gxs/rsgxsifaceimpl.cc b/libretroshare/src/gxs/rsgxsifaceimpl.cc index 1d79986d6..c3162f034 100644 --- a/libretroshare/src/gxs/rsgxsifaceimpl.cc +++ b/libretroshare/src/gxs/rsgxsifaceimpl.cc @@ -120,6 +120,11 @@ bool RsGxsIfaceImpl::getMsgList(const uint32_t &token, return mGxs->getMsgList(token, msgIds); } +bool RsGxsIfaceImpl::getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult &msgIds) +{ + return mGxs->getMsgRelatedList(token, msgIds); +} + /* Generic Summary */ bool RsGxsIfaceImpl::getGroupSummary(const uint32_t &token, std::list &groupInfo) @@ -135,6 +140,13 @@ bool RsGxsIfaceImpl::getMsgSummary(const uint32_t &token, return mGxs->getMsgMeta(token, msgInfo); } +bool RsGxsIfaceImpl::getMsgrelatedSummary(const uint32_t &token, GxsMsgRelatedMetaMap &msgInfo) +{ + return mGxs->getMsgRelatedMeta(token, msgInfo); +} + + + bool RsGxsIfaceImpl::subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe) { if(subscribe) diff --git a/libretroshare/src/gxs/rsgxsifaceimpl.h b/libretroshare/src/gxs/rsgxsifaceimpl.h index df105cd91..73d314259 100644 --- a/libretroshare/src/gxs/rsgxsifaceimpl.h +++ b/libretroshare/src/gxs/rsgxsifaceimpl.h @@ -108,6 +108,15 @@ public: bool getMsgList(const uint32_t &token, GxsMsgIdResult& msgIds); + /*! + * Retrieves list of msg related ids associated to a request token + * @param token token to be redeemed for this request + * @param msgIds the ids return for given request token + * @return false if request token is invalid, check token status for error report + */ + bool getMsgRelatedList(const uint32_t &token, + MsgRelatedIdResult& msgIds); + /*! * @param token token to be redeemed for group summary request * @param groupInfo the ids returned for given request token @@ -124,6 +133,14 @@ public: bool getMsgSummary(const uint32_t &token, GxsMsgMetaMap &msgInfo); + /*! + * @param token token to be redeemed for message related summary request + * @param msgInfo the message metadata returned for given request token + * @return false if request token is invalid, check token status for error report + */ + bool getMsgrelatedSummary(const uint32_t &token, + GxsMsgRelatedMetaMap &msgInfo); + /*! * subscribes to group, and returns token which can be used * to be acknowledged to get group Id diff --git a/libretroshare/src/gxs/rsgxsrequesttypes.h b/libretroshare/src/gxs/rsgxsrequesttypes.h index bd2723de5..7d2f6977f 100644 --- a/libretroshare/src/gxs/rsgxsrequesttypes.h +++ b/libretroshare/src/gxs/rsgxsrequesttypes.h @@ -100,8 +100,10 @@ class MsgRelatedInfoReq : public GxsRequest { public: - RsGxsGrpMsgIdPair mMsgId; - GxsMsgIdResult mMsgIdResult; + std::vector mMsgIds; + MsgRelatedIdResult mMsgIdResult; + MsgRelatedMetaResult mMsgMetaResult; + NxsMsgRelatedDataResult mMsgDataResult; }; class GroupSetFlagReq : public GxsRequest diff --git a/libretroshare/src/gxs/rstokenservice.h b/libretroshare/src/gxs/rstokenservice.h index cb6fee0b9..c2e768ade 100644 --- a/libretroshare/src/gxs/rstokenservice.h +++ b/libretroshare/src/gxs/rstokenservice.h @@ -40,6 +40,10 @@ #define GXS_REQUEST_TYPE_MSG_META 0x00100000 #define GXS_REQUEST_TYPE_MSG_IDS 0x00200000 +#define GXS_REQUEST_TYPE_MSG_RELATED_DATA 0x00400000 +#define GXS_REQUEST_TYPE_MSG_RELATED_META 0x00800000 +#define GXS_REQUEST_TYPE_MSG_RELATED_IDS 0x01000000 + // This bit will be filled out over time. @@ -171,7 +175,7 @@ public: * @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs * @return true if request successful false otherwise */ - virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const RsGxsGrpMsgIdPair& msgIds) = 0; + virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::vector& msgIds) = 0; /* Poll */ diff --git a/libretroshare/src/retroshare/rsphotoV2.h b/libretroshare/src/retroshare/rsphotoV2.h index f678105d1..55880ee4a 100644 --- a/libretroshare/src/retroshare/rsphotoV2.h +++ b/libretroshare/src/retroshare/rsphotoV2.h @@ -153,11 +153,16 @@ class RsPhotoAlbum uint32_t mModFlags; }; +class RsGxsPhotoCommentItem; class RsPhotoComment { public: RsPhotoComment(); + RsPhotoComment(const RsGxsPhotoCommentItem& comment); + + RsPhotoComment& operator=(const RsGxsPhotoCommentItem& comment); + RsMsgMetaData mMeta; std::string mComment; @@ -169,6 +174,7 @@ std::ostream &operator<<(std::ostream &out, const RsPhotoAlbum &album); typedef std::map > PhotoResult; typedef std::map > PhotoCommentResult; +typedef std::map > PhotoRelatedCommentResult; class RsPhotoV2 { @@ -273,6 +279,12 @@ public: */ virtual bool getPhotoComment(const uint32_t &token, PhotoCommentResult& comments) = 0; + /*! + * @param token token to be redeemed for photo request + * @param photo the photo returned for given request token + * @return false if request token is invalid, check token status for error report + */ + virtual bool getPhotoRelatedComment(const uint32_t &token, PhotoRelatedCommentResult &comments) = 0; /*! * submits album, which returns a token that needs diff --git a/libretroshare/src/services/p3photoserviceV2.cc b/libretroshare/src/services/p3photoserviceV2.cc index febb7e44b..ab5d48727 100644 --- a/libretroshare/src/services/p3photoserviceV2.cc +++ b/libretroshare/src/services/p3photoserviceV2.cc @@ -62,6 +62,13 @@ RsPhotoComment::RsPhotoComment() } +RsPhotoComment::RsPhotoComment(const RsGxsPhotoCommentItem &comment) + : mComment(""), mCommentFlag(0) { + + *this = comment.comment; + (*this).mMeta = comment.meta; + +} std::ostream &operator<<(std::ostream &out, const RsPhotoPhoto &photo) { out << "RsPhotoPhoto [ "; @@ -247,39 +254,52 @@ bool p3PhotoServiceV2::getPhoto(const uint32_t& token, PhotoResult& photos) bool p3PhotoServiceV2::getPhotoComment(const uint32_t &token, PhotoCommentResult &comments) { - GxsMsgDataMap msgData; - bool ok = RsGenExchange::getMsgData(token, msgData); + GxsMsgDataMap msgData; + bool ok = RsGenExchange::getMsgData(token, msgData); - if(ok) + if(ok) + { + GxsMsgDataMap::iterator mit = msgData.begin(); + + for(; mit != msgData.end(); mit++) { - GxsMsgDataMap::iterator mit = msgData.begin(); + RsGxsGroupId grpId = mit->first; + std::vector& msgItems = mit->second; + std::vector::iterator vit = msgItems.begin(); - for(; mit != msgData.end(); mit++) + for(; vit != msgItems.end(); vit++) + { + RsGxsPhotoCommentItem* item = dynamic_cast(*vit); + + if(item) { - RsGxsGroupId grpId = mit->first; - std::vector& msgItems = mit->second; - std::vector::iterator vit = msgItems.begin(); - - for(; vit != msgItems.end(); vit++) - { - RsGxsPhotoCommentItem* item = dynamic_cast(*vit); - - if(item) - { - RsPhotoComment comment = item->comment; - comment.mMeta = item->meta; - comments[grpId].push_back(comment); - delete item; - }else - { - std::cerr << "Not a comment Item, deleting!" << std::endl; - delete *vit; - } - } + RsPhotoComment comment = item->comment; + comment.mMeta = item->meta; + comments[grpId].push_back(comment); + delete item; + }else + { + std::cerr << "Not a comment Item, deleting!" << std::endl; + delete *vit; } + } } + } + + return ok; +} + +RsPhotoComment& RsPhotoComment::operator=(const RsGxsPhotoCommentItem& comment) +{ + *this = comment.comment; + return *this; +} + +bool p3PhotoServiceV2::getPhotoRelatedComment(const uint32_t &token, PhotoRelatedCommentResult &comments) +{ + + return RsGenExchange::getMsgRelatedDataT(token, comments); - return ok; } bool p3PhotoServiceV2::submitAlbumDetails(uint32_t& token, RsPhotoAlbum& album) diff --git a/libretroshare/src/services/p3photoserviceV2.h b/libretroshare/src/services/p3photoserviceV2.h index 0ddccf4db..dc2ce80cb 100644 --- a/libretroshare/src/services/p3photoserviceV2.h +++ b/libretroshare/src/services/p3photoserviceV2.h @@ -29,7 +29,6 @@ #include "gxs/rsgenexchange.h" #include "retroshare/rsphotoV2.h" - class p3PhotoServiceV2 : public RsPhotoV2, public RsGenExchange { public: @@ -80,6 +79,7 @@ public: bool getAlbum(const uint32_t &token, std::vector &albums); bool getPhoto(const uint32_t &token, PhotoResult &photos); bool getPhotoComment(const uint32_t &token, PhotoCommentResult &comments); + bool getPhotoRelatedComment(const uint32_t &token, PhotoRelatedCommentResult &comments); public: diff --git a/libretroshare/src/tests/gxs/genexchangetester.cpp b/libretroshare/src/tests/gxs/genexchangetester.cpp index 5826e1fcb..f86be53c3 100644 --- a/libretroshare/src/tests/gxs/genexchangetester.cpp +++ b/libretroshare/src/tests/gxs/genexchangetester.cpp @@ -3,7 +3,6 @@ #include "gxs/rsdataservice.h" #include "gxs/rsgxsflags.h" - GenExchangeTester::GenExchangeTester() : mGenTestMutex("genTest") { @@ -15,24 +14,28 @@ void GenExchangeTester::setUp() { mDataStore = new RsDataService("./", "testServiceDb", RS_SERVICE_TYPE_DUMMY, NULL); mNxs = new RsDummyNetService(); - mTestService = new GenExchangeTestService(mDataStore, mNxs); - mGxsCore.addService(mTestService); + + RsGixsDummy* gixsDummy = new RsGixsDummy("incoming", "outgoing"); + + mTestService = new GenExchangeTestService(mDataStore, mNxs, gixsDummy, 0); mTokenService = mTestService->getTokenService(); - mGxsCore.start(); + mTestService->start(); } -void GenExchangeTester::setUpGrps() +void GenExchangeTester::setUpGrps(uint32_t grpFlags) { // create some random grps to allow msg testing RsDummyGrp* dgrp1 = new RsDummyGrp(); RsDummyGrp* dgrp2 = new RsDummyGrp(); RsDummyGrp* dgrp3 = new RsDummyGrp(); + init(dgrp1); + dgrp1->meta.mGroupFlags = grpFlags; uint32_t token; mTestService->publishDummyGrp(token, dgrp1); - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mReqType = 45000; pollForToken(token, opts); @@ -40,11 +43,15 @@ void GenExchangeTester::setUpGrps() mTestService->acknowledgeTokenGrp(token, grpId); mRandGrpIds.push_back(grpId); + init(dgrp2); + dgrp2->meta.mGroupFlags = grpFlags; mTestService->publishDummyGrp(token, dgrp2); pollForToken(token, opts); mTestService->acknowledgeTokenGrp(token, grpId); mRandGrpIds.push_back(grpId); + init(dgrp3); + dgrp3->meta.mGroupFlags = grpFlags; mTestService->publishDummyGrp(token, dgrp3); pollForToken(token, opts); mTestService->acknowledgeTokenGrp(token, grpId); @@ -54,10 +61,8 @@ void GenExchangeTester::setUpGrps() void GenExchangeTester::breakDown() { + mTestService->join(); - mGxsCore.join(); // indicate server to stop - - mGxsCore.removeService(mTestService); delete mTestService; // a bit protracted, but start a new db and use to clear up junk @@ -147,7 +152,7 @@ bool GenExchangeTester::testGrpSubmissionRetrieval() init(dgrp2); init(dgrp3); - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mReqType = 45000; uint32_t token; RsGxsGroupId grpId; @@ -240,7 +245,7 @@ bool GenExchangeTester::testGrpMetaRetrieval() init(dgrp2); init(dgrp3); - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mReqType = 45000; uint32_t token; RsGxsGroupId grpId; @@ -316,7 +321,7 @@ bool GenExchangeTester::testGrpIdRetrieval() setUpLargeGrps(30); // create a large amount of grps - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; uint32_t token; std::list grpIds; @@ -369,7 +374,7 @@ bool GenExchangeTester::testGrpMetaModRequest() init(dgrp3); uint32_t token; - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mReqType = 45000; std::vector grpIds; RsGxsGroupId grpId; @@ -449,7 +454,7 @@ void GenExchangeTester::setUpLargeGrps(uint32_t nGrps) RsGxsGroupId grpId; uint32_t token; init(dgrp); - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mReqType = 4000; mTestService->publishDummyGrp(token, dgrp); pollForToken(token, opts); @@ -473,7 +478,7 @@ bool GenExchangeTester::testMsgMetaModRequest() mTestService->publishDummyMsg(token, msg); // poll will block until found - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mReqType = 4200; pollForToken(token, opts); RsGxsGrpMsgIdPair msgId; @@ -554,7 +559,7 @@ bool GenExchangeTester::testMsgSubmissionRetrieval() // start up setUp(); - setUpGrps(); + setUpGrps(GXS_SERV::FLAG_PRIVACY_PUBLIC); /********************/ @@ -568,8 +573,8 @@ bool GenExchangeTester::testMsgSubmissionRetrieval() mTestService->publishDummyMsg(token, msg); // poll will block until found - RsTokReqOptionsV2 opts; - opts.mReqType = 4200; + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; pollForToken(token, opts); RsGxsGrpMsgIdPair msgId; @@ -644,7 +649,7 @@ bool GenExchangeTester::testMsgIdRetrieval() // start up setUp(); - setUpGrps(); + setUpGrps(GXS_SERV::FLAG_PRIVACY_PUBLIC); /********************/ @@ -656,7 +661,7 @@ bool GenExchangeTester::testMsgIdRetrieval() int nMsgs = (rand()%121)+2; // test a large number of msgs std::vector msgs; createMsgs(msgs, nMsgs); - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mReqType = 4000; uint32_t token; @@ -725,14 +730,13 @@ bool GenExchangeTester::testMsgIdRetrieval() return true; } - -bool GenExchangeTester::testMsgChildRetrieval() +bool GenExchangeTester::testMsgAllVersions() { // start up setUp(); - setUpGrps(); + setUpGrps(GXS_SERV::FLAG_PRIVACY_PUBLIC); - /********************/ + // want to create several msgs of the same version (i.e. same origMsgId) // create msgs @@ -741,31 +745,27 @@ bool GenExchangeTester::testMsgChildRetrieval() int nMsgs = (rand()%50)+2; // test a large number of msgs std::vector msgs; createMsgs(msgs, nMsgs); - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mReqType = 4000; uint32_t token; bool first = true; RsGxsGrpMsgIdPair firstMsgId; - // everyone is parent of first msg - + // everyone is a version of first msg for(int i=0; i < nMsgs; i++) { RsDummyMsg* msg = msgs[i]; - int j = rand()%5; - - if(first){ msg->meta.mParentId = ""; - msg->meta.mOrigMsgId = ""; + msg->meta.mOrigMsgId = ""; // don't worry GXS sets origid to first } else { - msg->meta.mParentId = firstMsgId.second; + msg->meta.mParentId = ""; msg->meta.mGroupId = firstMsgId.first; - msg->meta.mOrigMsgId = ""; + msg->meta.mOrigMsgId = firstMsgId.second; } mTestService->publishDummyMsg(token, msg); @@ -773,13 +773,6 @@ bool GenExchangeTester::testMsgChildRetrieval() RsGxsGrpMsgIdPair msgId; mTestService->acknowledgeTokenMsg(token, msgId); - // less than half have no parents - if(first){ - firstMsgId.second = msgId.second; - firstMsgId.first = msgId.first; - - } - if(msgId.first.empty() || msgId.second.empty()) { breakDown(); @@ -787,23 +780,30 @@ bool GenExchangeTester::testMsgChildRetrieval() return false; } - if(!first) - { - mMsgIdsOut[msgId.first].push_back(msgId.second); + + + // less than half have no parents + if(first){ + firstMsgId.second = msgId.second; + firstMsgId.first = msgId.first; first = false; + } + mMsgRelatedIdsOut[firstMsgId].push_back(msgId.second); } - opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; - opts.mOptions = RS_TOKREQOPT_MSG_PARENT | RS_TOKREQOPT_MSG_LATEST; - mTokenService->requestMsgRelatedInfo(token, 0, opts, firstMsgId); + opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_IDS; + opts.mOptions = RS_TOKREQOPT_MSG_VERSIONS; + std::vector msgIdList; + msgIdList.push_back(firstMsgId); + mTokenService->requestMsgRelatedInfo(token, 0, opts, msgIdList); pollForToken(token, opts); - GxsMsgIdResult::iterator mit = mMsgIdsOut.begin(); - for(; mit != mMsgIdsOut.end(); mit++) + MsgRelatedIdResult::iterator mit = mMsgRelatedIdsOut.begin(); + for(; mit != mMsgRelatedIdsOut.end(); mit++) { std::vector msgIdsOut, msgIdsIn; msgIdsOut = mit->second; @@ -813,7 +813,7 @@ bool GenExchangeTester::testMsgChildRetrieval() for(; vit_out != msgIdsOut.end(); vit_out++) { bool found = false; - msgIdsIn = mMsgIdsIn[mit->first]; + msgIdsIn = mMsgRelatedIdsIn[mit->first]; vit_in = msgIdsIn.begin(); for(; vit_in != msgIdsIn.end(); vit_in++) @@ -830,21 +830,129 @@ bool GenExchangeTester::testMsgChildRetrieval() } } - /********************/ - // complete breakDown(); return true; } +bool GenExchangeTester::testMsgChildRetrieval() +{ +// // start up +// setUp(); +// setUpGrps(GXS_SERV::FLAG_PRIVACY_PUBLIC); + +// /********************/ + + +// // create msgs +// // then make all requests immediately then poll afterwards for each and run outbound test +// // we want only latest for now +// int nMsgs = (rand()%50)+2; // test a large number of msgs +// std::vector msgs; +// createMsgs(msgs, nMsgs); +// RsTokReqOptions opts; +// opts.mReqType = 4000; +// uint32_t token; + +// bool first = true; +// RsGxsGrpMsgIdPair firstMsgId; + +// // everyone is parent of first msg + +// for(int i=0; i < nMsgs; i++) +// { +// RsDummyMsg* msg = msgs[i]; + +// if(first){ +// msg->meta.mParentId = ""; +// msg->meta.mOrigMsgId = ""; +// } +// else +// { +// msg->meta.mParentId = firstMsgId.second; +// msg->meta.mGroupId = firstMsgId.first; +// msg->meta.mOrigMsgId = ""; +// } + +// mTestService->publishDummyMsg(token, msg); +// pollForToken(token, opts); +// RsGxsGrpMsgIdPair msgId; +// mTestService->acknowledgeTokenMsg(token, msgId); + + +// if(msgId.first.empty() || msgId.second.empty()) +// { +// breakDown(); +// std::cerr << "serious error: Acknowledgement failed! " << std::endl; +// return false; +// } + +// if(!first) +// { +// mMsgIdsOut[msgId.first].push_back(msgId.second); +// } + +// if(first){ +// firstMsgId.second = msgId.second; +// firstMsgId.first = msgId.first; +// first = false; +// } + +// } + + +// opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; +// opts.mOptions = RS_TOKREQOPT_MSG_PARENT | RS_TOKREQOPT_MSG_LATEST; +// std::vector msgIdList; +// msgIdList.push_back(firstMsgId); +// mTokenService->requestMsgRelatedInfo(token, 0, opts, msgIdList); + +// pollForToken(token, opts); + +// GxsMsgIdResult::iterator mit = mMsgIdsOut.begin(); +// for(; mit != mMsgIdsOut.end(); mit++) +// { +// std::vector msgIdsOut, msgIdsIn; +// msgIdsOut = mit->second; + +// std::vector::iterator vit_out = msgIdsOut.begin(), vit_in; + +// for(; vit_out != msgIdsOut.end(); vit_out++) +// { +// bool found = false; +// msgIdsIn = mMsgIdsIn[mit->first]; +// vit_in = msgIdsIn.begin(); + +// for(; vit_in != msgIdsIn.end(); vit_in++) +// { +// if(*vit_in == *vit_out) +// found = true; +// } + +// if(!found){ +// breakDown(); +// return false; +// } + +// } +// } + +// /********************/ + +// // complete +// breakDown(); + +// return true; +} + bool GenExchangeTester::testSpecificMsgMetaRetrieval() { // start up setUp(); - setUpGrps(); + setUpGrps(GXS_SERV::FLAG_PRIVACY_PUBLIC); /********************/ @@ -858,7 +966,7 @@ bool GenExchangeTester::testSpecificMsgMetaRetrieval() mTestService->publishDummyMsg(token, msg); // poll will block until found - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mReqType = 4200; pollForToken(token, opts); RsGxsGrpMsgIdPair msgId; @@ -955,7 +1063,7 @@ bool GenExchangeTester::testMsgIdRetrieval_OptParents() int nMsgs = (rand()%50)+2; // test a large number of msgs std::vector msgs; createMsgs(msgs, nMsgs); - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mReqType = 4000; uint32_t token; @@ -1053,7 +1161,7 @@ bool GenExchangeTester::testMsgIdRetrieval_OptOrigMsgId() int nMsgs = (rand()%50)+2; // test a large number of msgs std::vector msgs; createMsgs(msgs, nMsgs); - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mReqType = 4000; uint32_t token; @@ -1153,7 +1261,7 @@ bool GenExchangeTester::testMsgIdRetrieval_OptLatest() int nMsgs = (rand()%50)+2; // test a large number of msgs std::vector msgs; createMsgs(msgs, nMsgs); - RsTokReqOptionsV2 opts; + RsTokReqOptions opts; opts.mReqType = 4000; uint32_t token; @@ -1499,7 +1607,7 @@ void GenExchangeTester::init(RsDummyMsg *msgItem) const init(msgItem->meta); } -void GenExchangeTester::pollForToken(uint32_t token, const RsTokReqOptionsV2 &opts) +void GenExchangeTester::pollForToken(uint32_t token, const RsTokReqOptions &opts) { double timeDelta = 0.2; @@ -1511,8 +1619,8 @@ void GenExchangeTester::pollForToken(uint32_t token, const RsTokReqOptionsV2 &op Sleep((int) (timeDelta * 1000)); #endif - if(RsTokenServiceV2::GXS_REQUEST_V2_STATUS_COMPLETE == - mTokenService->requestStatus(token)) + if((RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE == mTokenService->requestStatus(token)) + || (RsTokenService::GXS_REQUEST_V2_STATUS_FAILED == mTokenService->requestStatus(token))) { switch(opts.mReqType) { @@ -1534,6 +1642,9 @@ void GenExchangeTester::pollForToken(uint32_t token, const RsTokReqOptionsV2 &op case GXS_REQUEST_TYPE_MSG_IDS: mTestService->getMsgListTS(token, mMsgIdsIn); break; + case GXS_REQUEST_TYPE_MSG_RELATED_IDS: + mTestService->getMsgRelatedListTS(token, mMsgRelatedIdsIn); + break; } break; } diff --git a/libretroshare/src/tests/gxs/genexchangetester.h b/libretroshare/src/tests/gxs/genexchangetester.h index 83f6150e6..02d6c4140 100644 --- a/libretroshare/src/tests/gxs/genexchangetester.h +++ b/libretroshare/src/tests/gxs/genexchangetester.h @@ -21,10 +21,11 @@ class GenExchangeTester { public: - void pollForToken(uint32_t, const RsTokReqOptionsV2& opts); + void pollForToken(uint32_t, const RsTokReqOptions& opts); GenExchangeTester(); + // message tests bool testMsgSubmissionRetrieval(); bool testMsgIdRetrieval(); bool testMsgIdRetrieval_OptParents(); @@ -32,9 +33,12 @@ public: bool testMsgIdRetrieval_OptLatest(); bool testSpecificMsgMetaRetrieval(); + // request msg related tests bool testMsgChildRetrieval(); + bool testMsgAllVersions(); + // group tests bool testGrpSubmissionRetrieval(); bool testSpecificGrpRetrieval(); bool testGrpIdRetrieval(); @@ -52,7 +56,7 @@ private: void breakDown(); - void setUpGrps(); // to be called at start of msg tests + void setUpGrps(uint32_t grpFlag=0); // to be called at start of msg tests /*! * Can be called at start grpId or grpMeta test @@ -92,17 +96,18 @@ private: GxsMsgMetaMap mMsgMetaDataOut, mMsgMetaDataIn; GxsMsgIdResult mMsgIdsOut, mMsgIdsIn; + MsgRelatedIdResult mMsgRelatedIdsOut, mMsgRelatedIdsIn; + std::vector mRandGrpIds; // ids that exist to help group testing private: GenExchangeTestService* mTestService; - RsTokenServiceV2* mTokenService; + RsTokenService* mTokenService; RsNetworkExchangeService* mNxs; RsGeneralDataService* mDataStore; - GxsCoreServer mGxsCore; }; diff --git a/libretroshare/src/tests/gxs/genexchangetestservice.cpp b/libretroshare/src/tests/gxs/genexchangetestservice.cpp index 7fe38add8..59e0bdbed 100644 --- a/libretroshare/src/tests/gxs/genexchangetestservice.cpp +++ b/libretroshare/src/tests/gxs/genexchangetestservice.cpp @@ -1,7 +1,8 @@ #include "genexchangetestservice.h" -GenExchangeTestService::GenExchangeTestService(RsGeneralDataService *dataServ, RsNetworkExchangeService * netService) - : RsGenExchange(dataServ, netService, new RsDummySerialiser(), RS_SERVICE_TYPE_DUMMY) +GenExchangeTestService::GenExchangeTestService(RsGeneralDataService *dataServ, RsNetworkExchangeService * netService, + RsGixs* gixs, uint32_t authenPolicy) + : RsGenExchange(dataServ, netService, new RsDummySerialiser(), RS_SERVICE_TYPE_DUMMY, gixs, authenPolicy) { } @@ -51,6 +52,11 @@ bool GenExchangeTestService::getMsgListTS(const uint32_t &token, GxsMsgIdResult return getMsgList(token, msgIds); } +bool GenExchangeTestService::getMsgRelatedListTS(const uint32_t &token, MsgRelatedIdResult &msgIds) +{ + return getMsgRelatedList(token, msgIds); +} + void GenExchangeTestService::setGroupServiceStringTS(uint32_t &token, const RsGxsGroupId &grpId, const std::string &servString) { RsGenExchange::setGroupServiceString(token, grpId, servString); @@ -58,12 +64,12 @@ void GenExchangeTestService::setGroupServiceStringTS(uint32_t &token, const RsGx void GenExchangeTestService::setGroupStatusFlagTS(uint32_t &token, const RsGxsGroupId &grpId, const uint32_t &status) { - RsGenExchange::setGroupStatusFlag(token, grpId, status); + RsGenExchange::setGroupStatusFlags(token, grpId, status, 0xff); } void GenExchangeTestService::setGroupSubscribeFlagTS(uint32_t &token, const RsGxsGroupId &grpId, const uint32_t &status) { - RsGenExchange::setGroupSubscribeFlag(token, grpId, status); + RsGenExchange::setGroupSubscribeFlags(token, grpId, status, 0xff); } void GenExchangeTestService::setMsgServiceStringTS(uint32_t &token, const RsGxsGrpMsgIdPair &msgId, const std::string &servString) @@ -73,6 +79,10 @@ void GenExchangeTestService::setMsgServiceStringTS(uint32_t &token, const RsGxsG void GenExchangeTestService::setMsgStatusFlagTS(uint32_t &token, const RsGxsGrpMsgIdPair &msgId, const uint32_t &status) { - RsGenExchange::setMsgStatusFlag(token, msgId, status); + RsGenExchange::setMsgStatusFlags(token, msgId, status, 0xff); } +void GenExchangeTestService::service_tick() +{ + +} diff --git a/libretroshare/src/tests/gxs/genexchangetestservice.h b/libretroshare/src/tests/gxs/genexchangetestservice.h index 0a1249619..00657e9af 100644 --- a/libretroshare/src/tests/gxs/genexchangetestservice.h +++ b/libretroshare/src/tests/gxs/genexchangetestservice.h @@ -2,12 +2,13 @@ #define GENEXCHANGETESTSERVICE_H #include "gxs/rsgenexchange.h" +#include "gxs/rsgxsifaceimpl.h" #include "rsdummyservices.h" class GenExchangeTestService : public RsGenExchange { public: - GenExchangeTestService(RsGeneralDataService* dataServ, RsNetworkExchangeService*); + GenExchangeTestService(RsGeneralDataService* dataServ, RsNetworkExchangeService*, RsGixs* gixs, uint32_t authenPolicy); void notifyChanges(std::vector& changes); @@ -59,6 +60,13 @@ public: */ bool getMsgDataTS(const uint32_t &token, GxsMsgDataMap& msgItems); + /*! + * Retrieve msg related list for a given token sectioned by group Ids + * @param token token to be redeemed + * @param msgIds a map of grpMsgIdPair -> msgList (vector) + */ + bool getMsgRelatedListTS(const uint32_t &token, MsgRelatedIdResult &msgIds); + void setGroupSubscribeFlagTS(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status); @@ -70,6 +78,8 @@ public: void setMsgServiceStringTS(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const std::string& servString ); + void service_tick(); + }; #endif // GENEXCHANGETESTSERVICE_H diff --git a/libretroshare/src/tests/gxs/nxs_tests.pro b/libretroshare/src/tests/gxs/nxs_tests.pro index 7aabd0eb9..3bc6c4f02 100644 --- a/libretroshare/src/tests/gxs/nxs_tests.pro +++ b/libretroshare/src/tests/gxs/nxs_tests.pro @@ -15,13 +15,13 @@ CONFIG += gen_exchange_target #CONFIG += dstore_target #CONFIG += gxsdata_target - +CONFIG += bitdht gen_exchange_target { -TARGET = gen_exchange_test +#TARGET = gen_exchange_test } @@ -33,7 +33,7 @@ TARGET = nxs_net_test gxsdata_target { -TARGET = gxsdata_test +#TARGET = gxsdata_test } @@ -130,7 +130,10 @@ win32 { GPGME_DIR = ../../../../gpgme-1.1.8 GPG_ERROR_DIR = ../../../../lib/libgpg-error-1.7 GPGME_DIR = ../../../../lib/gpgme-1.1.8 - INCLUDEPATH += . $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src + SSL_DIR = ../../../../../OpenSSL + OPENPGPSDK_DIR = ../../../../openpgpsdk/src + INCLUDEPATH += . $${SSL_DIR}/include $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src \ + $${OPENPGPSDK_DIR} SQLITE_DIR = ../../../../../../Libraries/sqlite/sqlite-autoconf-3070900 INCLUDEPATH += . \ @@ -186,48 +189,6 @@ gen_exchange_target { } -nxs_net_test { - SOURCES += \ - support.cc \ - nxstesthub.cc \ - rsgxsnetservice_test.cc \ - nxstestscenario.cc \ - data_support.cc - - - HEADERS += support.h \ - nxstesthub.h \ - rsgxsnetservice_test.h \ - nxstestscenario.h \ - data_support.h -} - - -dstore_target { - TARGET = rs_dstore_test - SOURCES += \ - support.cc \ - rsdataservice_test.cc \ - data_support.cc - - HEADERS += support.h \ - rsdataservice_test.h \ - data_support.h - - -} - -gxsdata_target { - - SOURCES += \ - support.cc \ - data_support.cc \ - rsgxsdata_test.cc - -HEADERS += \ - support.h \ - rsgxsdata_test.h -} INCLUDEPATH += ../../ diff --git a/libretroshare/src/tests/gxs/rsdummyservices.h b/libretroshare/src/tests/gxs/rsdummyservices.h index e727b9767..0ba00a906 100644 --- a/libretroshare/src/tests/gxs/rsdummyservices.h +++ b/libretroshare/src/tests/gxs/rsdummyservices.h @@ -5,6 +5,7 @@ // dummy services to make #include "gxs/rsnxs.h" +#include "gxs/rsgixs.h" #include "serialiser/rsgxsitems.h" class RsDummyNetService: public RsNetworkExchangeService @@ -90,7 +91,75 @@ public: }; +/*! + * Dummy implementation of Gixs service for + * testing + * Limited to creating two ids upon construction which can be used + * for signing data + */ +class RsGixsDummy : public RsGixs +{ +public: + + /*! + * constructs keys for both incoming and outgoing id (no private keys for incoming id) + * @param + * @param dummyId This is is the only id thats exists in this dummy interface + */ + RsGixsDummy(const RsGxsId& incomingId, const RsGxsId& outgoingId){} + + /*! + * + * @return id used for signing incoming data (should have both public and private components) + */ + const RsGxsId& getOutgoing(){ return mOutgoingId; } + + /*! + * + * @return id used for signing outgoing data(only have public parts) + */ + const RsGxsId& getIncoming(){ return mIncomingId; } + + // Key related interface - used for validating msgs and groups. + /*! + * Use to query a whether given key is available by its key reference + * @param keyref the keyref of key that is being checked for + * @return true if available, false otherwise + */ + bool haveKey(const RsGxsId &id){ return false;} + + /*! + * Use to query whether private key member of the given key reference is available + * @param keyref the KeyRef of the key being checked for + * @return true if private key is held here, false otherwise + */ + bool havePrivateKey(const RsGxsId &id){ return false; } + + // The fetchKey has an optional peerList.. this is people that had the msg with the signature. + // These same people should have the identity - so we ask them first. + /*! + * Use to request a given key reference + * @param keyref the KeyRef of the key being requested + * @return will + */ + bool requestKey(const RsGxsId &id, const std::list &peers){ return false ;} + bool requestPrivateKey(const RsGxsId &id){ return false;} + + + /*! + * Retrieves a key identity + * @param keyref + * @return a pointer to a valid profile if successful, otherwise NULL + * + */ + int getKey(const RsGxsId &id, RsTlvSecurityKey &key){ return false; } + int getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key){ return false; } // For signing outgoing messages. + +private: + + RsGxsId mIncomingId, mOutgoingId; +}; #endif // RSDUMMYSERVICES_H diff --git a/libretroshare/src/tests/gxs/rsgenexchange_test.cc b/libretroshare/src/tests/gxs/rsgenexchange_test.cc index 7067e87f6..26fadd84d 100644 --- a/libretroshare/src/tests/gxs/rsgenexchange_test.cc +++ b/libretroshare/src/tests/gxs/rsgenexchange_test.cc @@ -14,19 +14,20 @@ int main() { GenExchangeTester tester; - CHECK(tester.testMsgSubmissionRetrieval()); REPORT("testMsgSubmissionRetrieval()"); +// CHECK(tester.testMsgSubmissionRetrieval()); REPORT("testMsgSubmissionRetrieval()"); // CHECK(tester.testSpecificMsgMetaRetrieval()); REPORT("testSpecificMsgMetaRetrieval()"); -// CHECK(tester.testMsgIdRetrieval()); REPORT("tester.testMsgIdRetrieval()"); +// CHECK(tester.testMsgIdRetrieval()); REPORT("tester.testMsgIdRetrieval()"); // CHECK(tester.testMsgIdRetrieval_OptParents()); REPORT("tester.testRelatedMsgIdRetrieval_Parents()"); -// CHECK(tester.testMsgIdRetrieval_OptOrigMsgId()); REPORT("tester.testRelatedMsgIdRetrieval_OrigMsgId()"); -// CHECK(tester.testMsgIdRetrieval_OptLatest()); REPORT("tester.testRelatedMsgIdRetrieval_Latest()"); + CHECK(tester.testMsgIdRetrieval_OptOrigMsgId()); REPORT("tester.testRelatedMsgIdRetrieval_OrigMsgId()"); + CHECK(tester.testMsgIdRetrieval_OptLatest()); REPORT("tester.testRelatedMsgIdRetrieval_Latest()"); CHECK(tester.testMsgMetaModRequest()); REPORT("tester.testMsgMetaModRequest()"); - CHECK(tester.testMsgChildRetrieval()); REPORT("tester.testMsgMetaModRequest()"); + // CHECK(tester.testMsgChildRetrieval()); REPORT("tester.testMsgMetaModRequest()"); + CHECK(tester.testMsgAllVersions()); REPORT("tester.testMsgAllVersions()"); - CHECK(tester.testGrpSubmissionRetrieval()); REPORT("tester.testGrpSubmissionRetrieval()"); - CHECK(tester.testGrpMetaRetrieval()); REPORT("tester.testGrpMetaRetrieval()"); - CHECK(tester.testGrpIdRetrieval()); REPORT("tester.testGrpIdRetrieval()"); - CHECK(tester.testGrpMetaModRequest()); REPORT("tester.testGrpMetaModRequest()"); +// CHECK(tester.testGrpSubmissionRetrieval()); REPORT("tester.testGrpSubmissionRetrieval()"); +// CHECK(tester.testGrpMetaRetrieval()); REPORT("tester.testGrpMetaRetrieval()"); +// CHECK(tester.testGrpIdRetrieval()); REPORT("tester.testGrpIdRetrieval()"); +// CHECK(tester.testGrpMetaModRequest()); REPORT("tester.testGrpMetaModRequest()"); FINALREPORT("RsGenExchangeTest"); diff --git a/retroshare-gui/src/gui/ForumsV2Dialog.cpp b/retroshare-gui/src/gui/ForumsV2Dialog.cpp index 09b390e1b..62ec6061c 100644 --- a/retroshare-gui/src/gui/ForumsV2Dialog.cpp +++ b/retroshare-gui/src/gui/ForumsV2Dialog.cpp @@ -2148,7 +2148,7 @@ void ForumsV2Dialog::requestChildData_InsertThreads(uint32_t &token, const std:: std::cerr << "ForumsV2Dialog::requestChildData_InsertThreads(" << parentId << ")"; std::cerr << std::endl; - mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMSV2DIALOG_INSERTCHILD); + //mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMSV2DIALOG_INSERTCHILD); } @@ -2264,7 +2264,7 @@ void ForumsV2Dialog::requestMsgData_InsertPost(const std::string &msgId) uint32_t token; - mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_INSERT_POST); + //mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_INSERT_POST); } diff --git a/retroshare-gui/src/gui/GxsForumsDialog.cpp b/retroshare-gui/src/gui/GxsForumsDialog.cpp index 1ff4ebaa5..e1013bad9 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/GxsForumsDialog.cpp @@ -2157,7 +2157,9 @@ void GxsForumsDialog::requestChildData_InsertThreads(uint32_t &token, const RsGx std::cerr << "GxsForumsDialog::requestChildData_InsertThreads(" << parentId.first << "," << parentId.second << ")"; std::cerr << std::endl; - mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, parentId, FORUMSV2DIALOG_INSERTCHILD); + std::vector msgIds; + msgIds.push_back(parentId); + mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMSV2DIALOG_INSERTCHILD); } @@ -2270,9 +2272,10 @@ void GxsForumsDialog::requestMsgData_InsertPost(const RsGxsGrpMsgIdPair &msgId) std::cerr << "GxsForumsDialog::requestMsgData_InsertPost(" << msgId.first << "," << msgId.second << ")"; std::cerr << std::endl; - + std::vector msgIds; + msgIds.push_back(msgId); uint32_t token; - mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgId, FORUMV2DIALOG_INSERT_POST); + mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_INSERT_POST); } @@ -2310,8 +2313,10 @@ void GxsForumsDialog::requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId std::cerr << "GxsForumsDialog::requestMsgData_ReplyMessage(" << msgId.first << "," << msgId.second << ")"; std::cerr << std::endl; + std::vector msgIds; + msgIds.push_back(msgId); uint32_t token; - mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgId, FORUMV2DIALOG_REPLY_MESSAGE); + mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_REPLY_MESSAGE); } diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index b97f6f8b4..b56f0b13d 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -88,13 +88,15 @@ void PhotoDialog::requestComments() opts.mMsgFlagFilter = RsPhotoV2::FLAG_MSG_TYPE_PHOTO_COMMENT; opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; + opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; opts.mOptions = RS_TOKREQOPT_MSG_PARENT | RS_TOKREQOPT_MSG_LATEST; RsGxsGrpMsgIdPair msgId; uint32_t token; msgId.first = mPhotoDetails.mMeta.mGroupId; msgId.second = mPhotoDetails.mMeta.mMsgId; - uint32_t anstype = RS_TOKREQ_ANSTYPE_LIST; - mPhotoQueue->requestMsgRelatedInfo(token, anstype, opts, msgId, 0); + std::vector msgIdV; + msgIdV.push_back(msgId); + mPhotoQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIdV, 0); } void PhotoDialog::createComment() @@ -163,10 +165,10 @@ void PhotoDialog::loadComment(uint32_t token) clearComments(); - PhotoCommentResult results; - mRsPhoto->getPhotoComment(token, results); + PhotoRelatedCommentResult results; + mRsPhoto->getPhotoRelatedComment(token, results); - PhotoCommentResult::iterator mit = results.begin(); + PhotoRelatedCommentResult::iterator mit = results.begin(); for(; mit != results.end(); mit++) { diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp index 3d79cd90a..f8350736a 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp @@ -606,9 +606,10 @@ void WikiDialog::requestModPageList(const RsGxsGrpMsgIdPair &origMsgId) RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; opts.mOptions = RS_TOKREQOPT_MSG_VERSIONS; - + std::vector msgIds; + msgIds.push_back(origMsgId); uint32_t token; - mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, origMsgId, WIKIDIALOG_MOD_LIST); + mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, msgIds, WIKIDIALOG_MOD_LIST); } diff --git a/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.cpp b/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.cpp index 19920ac91..6ace6db7e 100644 --- a/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.cpp +++ b/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.cpp @@ -131,7 +131,7 @@ void CreateForumV2Msg::newMsg() std::cerr << std::endl; uint32_t token; - mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, CREATEFORUMV2MSG_PARENTMSG); + //mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, CREATEFORUMV2MSG_PARENTMSG); } } diff --git a/retroshare-gui/src/util/TokenQueue.cpp b/retroshare-gui/src/util/TokenQueue.cpp index 02d9ebee0..9184926e0 100644 --- a/retroshare-gui/src/util/TokenQueue.cpp +++ b/retroshare-gui/src/util/TokenQueue.cpp @@ -67,7 +67,7 @@ bool TokenQueue::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokRe } -bool TokenQueue::requestMsgRelatedInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, const RsGxsGrpMsgIdPair &msgId, uint32_t usertype) +bool TokenQueue::requestMsgRelatedInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, const std::vector &msgId, uint32_t usertype) { uint32_t basictype = TOKENREQ_MSGINFO; mService->requestMsgRelatedInfo(token, anstype, opts, msgId); diff --git a/retroshare-gui/src/util/TokenQueue.h b/retroshare-gui/src/util/TokenQueue.h index d0cb4fb26..2bffd6d44 100644 --- a/retroshare-gui/src/util/TokenQueue.h +++ b/retroshare-gui/src/util/TokenQueue.h @@ -93,7 +93,7 @@ public: bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, const GxsMsgReq& grpIds, uint32_t usertype); - bool requestMsgRelatedInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, const RsGxsGrpMsgIdPair& msgId, uint32_t usertype); + bool requestMsgRelatedInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, const std::vector& msgId, uint32_t usertype); bool cancelRequest(const uint32_t token); From 81e172d6f85a3a2a7fa14e2058484bb6a3b3a127 Mon Sep 17 00:00:00 2001 From: drbob Date: Wed, 14 Nov 2012 21:27:34 +0000 Subject: [PATCH 144/222] Modifications to use MsgRelatedData for Wiki pages. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5820 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/gui/WikiPoos/WikiDialog.cpp | 133 +++++++++--------- retroshare-gui/src/gui/WikiPoos/WikiDialog.h | 11 +- 2 files changed, 67 insertions(+), 77 deletions(-) diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp index f8350736a..db0253ec0 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp @@ -598,70 +598,20 @@ void WikiDialog::loadPages(const uint32_t &token) void WikiDialog::insertModsForPage(const RsGxsGrpMsgIdPair &origPageId) { - requestModPageList(origPageId); + requestModPages(origPageId); } -void WikiDialog::requestModPageList(const RsGxsGrpMsgIdPair &origMsgId) +void WikiDialog::requestModPages(const RsGxsGrpMsgIdPair &origMsgId) { RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; + opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; opts.mOptions = RS_TOKREQOPT_MSG_VERSIONS; std::vector msgIds; msgIds.push_back(origMsgId); uint32_t token; - mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, msgIds, WIKIDIALOG_MOD_LIST); + mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, WIKIDIALOG_MOD_PAGES); } - -void WikiDialog::loadModPageList(const uint32_t &token) -{ - std::cerr << "WikiDialog::loadModPageList()"; - std::cerr << std::endl; - - /* translate into latest pages */ - //std::list msgIds; - GxsMsgIdResult msgIds; - - if (rsWiki->getMsgList(token, msgIds)) - { - GxsMsgIdResult::iterator git; - for(git = msgIds.begin(); git != msgIds.end(); git++) - { - std::cerr << "WikiDialog::loadModPageList() Loaded GroupId: " << git->first; - std::cerr << std::endl; - std::vector::iterator vit; - for(vit = git->second.begin(); vit != git->second.end(); vit++) - { - std::cerr << "\tMsgId: " << *vit; - std::cerr << std::endl; - } - } - } - else - { - std::cerr << "WikiDialog::loadModPageList() ERROR No Data"; - std::cerr << std::endl; - return; - } - - requestModPages(msgIds); -} - -void WikiDialog::requestModPages(const GxsMsgIdResult &msgIds) -{ - std::cerr << "WikiDialog::requestModPages()"; - std::cerr << std::endl; - - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - - uint32_t token; - mWikiQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, WIKIDIALOG_MOD_PAGES); - - //mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, WIKIDIALOG_MOD_PAGES); -} - - void WikiDialog::loadModPages(const uint32_t &token) { std::cerr << "WikiDialog::loadModPages()"; @@ -670,7 +620,7 @@ void WikiDialog::loadModPages(const uint32_t &token) std::vector snapshots; std::vector::iterator vit; - if (!rsWiki->getSnapshots(token, snapshots)) + if (!rsWiki->getRelatedSnapshots(token, snapshots)) { // ERROR std::cerr << "WikiDialog::loadModPages() ERROR"; @@ -682,17 +632,23 @@ void WikiDialog::loadModPages(const uint32_t &token) { RsWikiSnapshot &page = *vit; - std::cerr << "WikiDialog::loadModPages() PageId: " << page.mMeta.mMsgId; - std::cerr << " Page: " << page.mMeta.mMsgName; - std::cerr << std::endl; + std::cerr << "WikiDialog::loadModPages() TopLevel Result: PageTitle: " << page.mMeta.mMsgName; + std::cerr << " GroupId: " << page.mMeta.mGroupId; + std::cerr << std::endl; + std::cerr << "\tOrigMsgId: " << page.mMeta.mOrigMsgId; + std::cerr << " MsgId: " << page.mMeta.mMsgId; + std::cerr << std::endl; + std::cerr << "\tThreadId: " << page.mMeta.mThreadId; + std::cerr << " ParentId: " << page.mMeta.mParentId; + std::cerr << std::endl; - //QTreeWidgetItem *modItem = new QTreeWidgetItem(); - //modItem->setText(WIKI_MODS_COL_ORIGPAGEID, QString::fromStdString(page.mMeta.mOrigMsgId)); - //modItem->setText(WIKI_MODS_COL_PAGEID, QString::fromStdString(page.mMeta.mMsgId)); - //ui.treeWidget_Mods->addTopLevelItem(modItem); + QTreeWidgetItem *modItem = new QTreeWidgetItem(); + modItem->setText(WIKI_MODS_COL_ORIGPAGEID, QString::fromStdString(page.mMeta.mOrigMsgId)); + modItem->setText(WIKI_MODS_COL_PAGEID, QString::fromStdString(page.mMeta.mMsgId)); + modItem->setText(WIKI_MODS_COL_PARENTID, QString::fromStdString(page.mMeta.mParentId)); + ui.treeWidget_Mods->addTopLevelItem(modItem); } - /* then we need to request all pages from this thread */ requestEditTreeData(); } @@ -733,14 +689,43 @@ void WikiDialog::loadEditTreeData(const uint32_t &token) return; } + std::string groupId; + std::string pageId; + std::string origPageId; + if (!getSelectedPage(groupId, pageId, origPageId)) + { + // ERROR + std::cerr << "WikiDialog::loadEditTreeData() ERROR 2"; + std::cerr << std::endl; + return; + } + std::cerr << "WikiDialog::loadEditTreeData() Loaded " << snapshots.size(); std::cerr << std::endl; + std::cerr << "WikiDialog::loadEditTreeData() Using ThreadId: " << origPageId; + std::cerr << std::endl; + + + + std::map items; std::map::iterator iit; std::list unparented; std::list::iterator uit; + // Grab the existing TopLevelItems, and insert into map. + int itemCount = ui.treeWidget_Mods->topLevelItemCount(); + for (int nIndex = 0; nIndex < itemCount; nIndex++) + { + QTreeWidgetItem *item = ui.treeWidget_Mods->topLevelItem(nIndex); + + /* index by MsgId --> ONLY For Wiki Thread Head Items... SPECIAL HACK FOR HERE! */ + std::string msgId = item->text(WIKI_MODS_COL_PAGEID).toStdString(); + items[msgId] = item; + } + + for(vit = snapshots.begin(); vit != snapshots.end(); vit++) { RsWikiSnapshot &snapshot = *vit; @@ -755,12 +740,29 @@ void WikiDialog::loadEditTreeData(const uint32_t &token) std::cerr << " ParentId: " << snapshot.mMeta.mParentId; std::cerr << std::endl; + if (snapshot.mMeta.mParentId == "") + { + /* Ignore! */ + std::cerr << "Ignoring ThreadHead Item"; + std::cerr << std::endl; + continue; + } + + if (snapshot.mMeta.mThreadId != origPageId) + { + /* Ignore! */ + std::cerr << "Ignoring Different Thread Item"; + std::cerr << std::endl; + continue; + } + /* create an Entry */ QTreeWidgetItem *modItem = new QTreeWidgetItem(); modItem->setText(WIKI_MODS_COL_ORIGPAGEID, QString::fromStdString(snapshot.mMeta.mOrigMsgId)); modItem->setText(WIKI_MODS_COL_PAGEID, QString::fromStdString(snapshot.mMeta.mMsgId)); modItem->setText(WIKI_MODS_COL_PARENTID, QString::fromStdString(snapshot.mMeta.mParentId)); +#if 0 /* if no parentId */ if (snapshot.mMeta.mParentId == "") { @@ -771,6 +773,7 @@ void WikiDialog::loadEditTreeData(const uint32_t &token) items[snapshot.mMeta.mMsgId] = modItem; continue; } +#endif /* find the parent */ iit = items.find(snapshot.mMeta.mParentId); @@ -882,10 +885,6 @@ void WikiDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) loadPages(req.mToken); break; - case WIKIDIALOG_MOD_LIST: - loadModPageList(req.mToken); - break; - case WIKIDIALOG_MOD_PAGES: loadModPages(req.mToken); break; diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.h b/retroshare-gui/src/gui/WikiPoos/WikiDialog.h index 970f61894..c9a1663a7 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.h +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.h @@ -84,18 +84,10 @@ std::string getSelectedMod(); void requestGroupList(); void loadGroupData(const uint32_t &token); -//void requestOriginalPages(const std::list &groupIds); -//void loadOriginalPages(const uint32_t &token); -//void requestLatestPages(const std::list &msgIds); -//void loadLatestPages(const uint32_t &token); void requestPages(const std::list &groupIds); -//void requestPages(const std::list &msgIds); void loadPages(const uint32_t &token); - -void requestModPageList(const RsGxsGrpMsgIdPair &origMsgId); -void loadModPageList(const uint32_t &token); -void requestModPages(const GxsMsgIdResult &msgIds); +void requestModPages(const RsGxsGrpMsgIdPair &origMsgId); void loadModPages(const uint32_t &token); void requestEditTreeData(); @@ -107,7 +99,6 @@ void loadWikiPage(const uint32_t &token); TokenQueue *mWikiQueue; - WikiAddDialog *mAddPageDialog; WikiAddDialog *mAddGroupDialog; WikiEditDialog *mEditDialog; From b5910e03149b47b02d9e10066e71c6ed71bff6a2 Mon Sep 17 00:00:00 2001 From: drbob Date: Wed, 14 Nov 2012 21:27:37 +0000 Subject: [PATCH 145/222] * Updated wiki service to support new MsgRelated data. * Added Wiki Dummy pages to explain it briefly. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5821 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/libretroshare.pro | 3 + libretroshare/src/retroshare/rswiki.h | 2 + libretroshare/src/services/p3wiki.cc | 262 +++++++++++++++++++++++++- libretroshare/src/services/p3wiki.h | 14 ++ 4 files changed, 280 insertions(+), 1 deletion(-) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 6b3331d93..7a84059c1 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -482,6 +482,7 @@ HEADERS += retroshare/rsgame.h \ pqi/pqiqosstreamer.cc \ pqi/sslfns.cc \ pqi/pqinetstatebox.cc + SOURCES += rsserver/p3discovery.cc \ rsserver/p3face-config.cc \ rsserver/p3face-msgs.cc \ @@ -495,9 +496,11 @@ HEADERS += retroshare/rsgame.h \ rsserver/rsloginhandler.cc \ rsserver/rstypes.cc \ rsserver/p3serverconfig.cc + SOURCES += plugins/pluginmanager.cc \ plugins/dlfcn_win32.cc \ serialiser/rspluginitems.cc + SOURCES += serialiser/rsbaseitems.cc \ serialiser/rsbaseserial.cc \ serialiser/rsblogitems.cc \ diff --git a/libretroshare/src/retroshare/rswiki.h b/libretroshare/src/retroshare/rswiki.h index 3a4648e2b..0c5d507d3 100644 --- a/libretroshare/src/retroshare/rswiki.h +++ b/libretroshare/src/retroshare/rswiki.h @@ -125,6 +125,8 @@ virtual bool getCollections(const uint32_t &token, std::vector virtual bool getSnapshots(const uint32_t &token, std::vector &snapshots) = 0; virtual bool getComments(const uint32_t &token, std::vector &comments) = 0; +virtual bool getRelatedSnapshots(const uint32_t &token, std::vector &snapshots) = 0; + virtual bool submitCollection(uint32_t &token, RsWikiCollection &collection) = 0; virtual bool submitSnapshot(uint32_t &token, RsWikiSnapshot &snapshot) = 0; virtual bool submitComment(uint32_t &token, RsWikiComment &comment) = 0; diff --git a/libretroshare/src/services/p3wiki.cc b/libretroshare/src/services/p3wiki.cc index ab75282cd..508f5fed9 100644 --- a/libretroshare/src/services/p3wiki.cc +++ b/libretroshare/src/services/p3wiki.cc @@ -40,10 +40,14 @@ p3Wiki::p3Wiki(RsGeneralDataService* gds, RsNetworkExchangeService* nes) { + // Setup of dummy Pages. + mAboutActive = false; + mImprovActive = false; } void p3Wiki::service_tick() { + dummyTick(); return; } @@ -136,6 +140,44 @@ bool p3Wiki::getSnapshots(const uint32_t &token, std::vector &sn } +bool p3Wiki::getRelatedSnapshots(const uint32_t &token, std::vector &snapshots) +{ + GxsMsgRelatedDataMap msgData; + bool ok = RsGenExchange::getMsgRelatedData(token, msgData); + + if(ok) + { + GxsMsgRelatedDataMap::iterator mit = msgData.begin(); + + for(; mit != msgData.end(); mit++) + { + std::vector& msgItems = mit->second; + std::vector::iterator vit = msgItems.begin(); + + for(; vit != msgItems.end(); vit++) + { + RsGxsWikiSnapshotItem* item = dynamic_cast(*vit); + + if(item) + { + RsWikiSnapshot snapshot = item->snapshot; + snapshot.mMeta = item->meta; + snapshots.push_back(snapshot); + delete item; + } + else + { + std::cerr << "Not a WikiSnapshot Item, deleting!" << std::endl; + delete *vit; + } + } + } + } + + return ok; +} + + bool p3Wiki::getComments(const uint32_t &token, std::vector &comments) { GxsMsgDataMap msgData; @@ -264,10 +306,44 @@ std::string p3Wiki::genRandomId() return randomId; } +const int about_len = 10; +const std::string about_txt[] = + { "Welcome to RsWiki, a fully distributed Wiki system that anyone can edit.", + "Please read through these dummy Wiki pages to learn how it should work\n", + "Basic Functionality:", + " - New Group: creates a collection of Wiki Pages, the creator of group", + " and anyone they share the publish keys with) is the moderator\n", + " - New Page: Create a new Wiki Page, only Group Moderators can do this\n", + " - Edit: Anyone Can Edit the Wiki Page, and the changes form a tree under the original\n", + " - RePublish: This is used by the Moderators to accept and reject Edits.", + " the republished page becomes a new version of the Root Page, allowing more edits to be done\n", + "Please read the improvements section to see how we envision the wiki's working", + }; + + +const int improvements_len = 14; +const std::string improvements_txt[] = + { "As you can see, the current Wiki is a basic framework waiting to be expanded.", + "There are lots of potential improvements... some of my ideas are listed below\n", + "Ideas:", + " - Formatting: No HTML, lets use Markdown or something similar.\n", + " - Diffs, lots of edits will lead to complex merges - a robust merge tool is essential\n", + " - Read Mode... hide all the Edits, and only show the most recently published versions\n", + " - Easy Duplication - to take over an Abandoned or badly moderated Wiki. Copies All base versions to a new group\n", + " - WikiLinks. A generic Wiki Cross Linking system. This should be combined with Easy Duplication option,\n", + " to allow easy replacement of groups if necessary... A good design here is critical to a successful Wiki ecosystem", + " the republished page becomes a new version of the Root Page, allowing more edits to be done\n", + " - work out how to include media (photos, audio, video, etc) without embedding in pages", + " this would leverage the turtle transfer system somehow - maybe like channels.\n", + " - Comments, reviews etc can be incorporated - ideas here are welcome.\n", + " - Any other suggestion???" + }; + + void p3Wiki::generateDummyData() { -#define GEN_COLLECTIONS 10 +#define GEN_COLLECTIONS 0 int i; for(i = 0; i < GEN_COLLECTIONS; i++) @@ -280,7 +356,191 @@ void p3Wiki::generateDummyData() uint32_t dummyToken = 0; submitCollection(dummyToken, wiki); } + + + RsWikiCollection wiki; + wiki.mMeta.mGroupFlags = 0; + wiki.mMeta.mGroupName = "About RsWiki"; + + submitCollection(mAboutToken, wiki); + + wiki.mMeta.mGroupFlags = 0; + wiki.mMeta.mGroupName = "RsWiki Improvements"; + + submitCollection(mImprovToken, wiki); + + mAboutLines = 0; + mImprovLines = 0; + + mAboutActive = true; + mImprovActive = true; +} + + +bool generateNextDummyPage(const RsGxsMessageId &threadId, const int lines, const RsGxsGrpMsgIdPair &parentId, + const std::string *page_lines, const int num_pagelines, RsWikiSnapshot &snapshot) +{ + snapshot.mMeta.mGroupId = parentId.first; + + // Create an About Page. +#define NUM_SUB_PAGES 3 + + if ((lines % NUM_SUB_PAGES == 0) || (lines == num_pagelines)) + { + /* do a new baseline */ + snapshot.mMeta.mOrigMsgId = threadId; + } + else + { + snapshot.mMeta.mParentId = parentId.second; + snapshot.mMeta.mThreadId = threadId; + } + + std::string page; + for(int i = 0; (i < lines) && (i < num_pagelines); i++) + { + snapshot.mPage += page_lines[i]; + snapshot.mPage += '\n'; + } + + return (lines <= num_pagelines); +} + + +void p3Wiki::dummyTick() +{ + if (mAboutActive) + { + std::cerr << "p3Wiki::dummyTick() AboutActive"; + std::cerr << std::endl; + + uint32_t status = RsGenExchange::getTokenService()->requestStatus(mAboutToken); + + if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + { + std::cerr << "p3Wiki::dummyTick() AboutActive, Lines: " << mAboutLines; + std::cerr << std::endl; + + if (mAboutLines == 0) + { + /* get the group Id */ + RsGxsGroupId groupId; + if (!acknowledgeTokenGrp(mAboutToken, groupId)) + { + std::cerr << " ERROR "; + std::cerr << std::endl; + mAboutActive = false; + } + + /* create baseline snapshot */ + RsWikiSnapshot page; + page.mMeta.mGroupId = groupId; + page.mPage = "Baseline page... a placeholder for About Wiki"; + page.mMeta.mMsgName = "About RsWiki"; + + submitSnapshot(mAboutToken, page); + mAboutLines++; + } + else + { + /* get the msg Id, and generate next snapshot */ + RsGxsGrpMsgIdPair msgId; + if (!acknowledgeTokenMsg(mAboutToken, msgId)) + { + std::cerr << " ERROR "; + std::cerr << std::endl; + mAboutActive = false; + } + + if (mAboutLines == 1) + { + mAboutThreadId = msgId.second; + } + + RsWikiSnapshot page; + page.mMeta.mMsgName = "About RsWiki"; + if (!generateNextDummyPage(mAboutThreadId, mAboutLines, msgId, about_txt, about_len, page)) + { + std::cerr << "About Pages Done"; + std::cerr << std::endl; + mAboutActive = false; + } + else + { + mAboutLines++; + submitSnapshot(mAboutToken, page); + } + } + } + } + + if (mImprovActive) + { + std::cerr << "p3Wiki::dummyTick() ImprovActive"; + std::cerr << std::endl; + + uint32_t status = RsGenExchange::getTokenService()->requestStatus(mImprovToken); + + if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + { + std::cerr << "p3Wiki::dummyTick() ImprovActive, Lines: " << mImprovLines; + std::cerr << std::endl; + + if (mImprovLines == 0) + { + /* get the group Id */ + RsGxsGroupId groupId; + if (!acknowledgeTokenGrp(mImprovToken, groupId)) + { + std::cerr << " ERROR "; + std::cerr << std::endl; + mImprovActive = false; + } + + /* create baseline snapshot */ + RsWikiSnapshot page; + page.mMeta.mGroupId = groupId; + page.mPage = "Baseline page... a placeholder for Improv Wiki"; + page.mMeta.mMsgName = "Improv RsWiki"; + + submitSnapshot(mImprovToken, page); + mImprovLines++; + } + else + { + /* get the msg Id, and generate next snapshot */ + RsGxsGrpMsgIdPair msgId; + if (!acknowledgeTokenMsg(mImprovToken, msgId)) + { + std::cerr << " ERROR "; + std::cerr << std::endl; + mImprovActive = false; + } + + if (mImprovLines == 1) + { + mImprovThreadId = msgId.second; + } + + RsWikiSnapshot page; + page.mMeta.mMsgName = "Improv RsWiki"; + if (!generateNextDummyPage(mImprovThreadId, mImprovLines, msgId, improvements_txt, improvements_len, page)) + { + std::cerr << "Improv Pages Done"; + std::cerr << std::endl; + mImprovActive = false; + } + else + { + mImprovLines++; + submitSnapshot(mImprovToken, page); + } + } + } + } } + + diff --git a/libretroshare/src/services/p3wiki.h b/libretroshare/src/services/p3wiki.h index 11e347cf1..01d82767e 100644 --- a/libretroshare/src/services/p3wiki.h +++ b/libretroshare/src/services/p3wiki.h @@ -56,6 +56,8 @@ virtual bool getCollections(const uint32_t &token, std::vector virtual bool getSnapshots(const uint32_t &token, std::vector &snapshots); virtual bool getComments(const uint32_t &token, std::vector &comments); +virtual bool getRelatedSnapshots(const uint32_t &token, std::vector &snapshots); + virtual bool submitCollection(uint32_t &token, RsWikiCollection &collection); virtual bool submitSnapshot(uint32_t &token, RsWikiSnapshot &snapshot); virtual bool submitComment(uint32_t &token, RsWikiComment &comment); @@ -68,6 +70,18 @@ std::string genRandomId(); // RsMutex mWikiMtx; + // Dummy Stuff. + void dummyTick(); + + bool mAboutActive; + uint32_t mAboutToken; + int mAboutLines; + RsGxsMessageId mAboutThreadId; + + bool mImprovActive; + uint32_t mImprovToken; + int mImprovLines; + RsGxsMessageId mImprovThreadId; }; #endif From 2230bd1a9614e7b35d434ab127b481cd28570a51 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Thu, 15 Nov 2012 23:09:56 +0000 Subject: [PATCH 146/222] Added getMsgRelatedData test Fixed bug with getmsgRelatedFucntion for msgs with no relatives (message with no relatives would end of pulling itself, i.e. the id/data/meta of message whose relative are being searched for) git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5827 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgxsdataaccess.cc | 31 ++--- .../src/tests/gxs/genexchangetester.cpp | 118 +++++++++++++++++- .../src/tests/gxs/genexchangetester.h | 4 +- .../src/tests/gxs/genexchangetestservice.cpp | 5 + .../src/tests/gxs/genexchangetestservice.h | 8 ++ .../src/tests/gxs/rsgenexchange_test.cc | 10 +- 6 files changed, 154 insertions(+), 22 deletions(-) diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index 6a56b6112..fd5e828d4 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -1275,21 +1275,24 @@ bool RsGxsDataAccess::getMsgRelatedInfo(MsgRelatedInfoReq *req) filteredOutMsgIds[grpId] = outMsgIds; filterMsgList(filteredOutMsgIds, opts, filterMap); - if(req->Options.mReqType == GXS_REQUEST_TYPE_MSG_RELATED_IDS) + if(!outMsgIds.empty()) { - req->mMsgIdResult[grpMsgIdPair] = filteredOutMsgIds[grpId]; - } - else if(req->Options.mReqType == GXS_REQUEST_TYPE_MSG_RELATED_META) - { - GxsMsgMetaResult metaResult; - mDataStore->retrieveGxsMsgMetaData(filteredOutMsgIds, metaResult); - req->mMsgMetaResult[grpMsgIdPair] = metaResult[grpId]; - } - else if(req->Options.mReqType == GXS_REQUEST_TYPE_MSG_RELATED_DATA) - { - GxsMsgResult msgResult; - mDataStore->retrieveNxsMsgs(filteredOutMsgIds, msgResult, false, true); - req->mMsgDataResult[grpMsgIdPair] = msgResult[grpId]; + if(req->Options.mReqType == GXS_REQUEST_TYPE_MSG_RELATED_IDS) + { + req->mMsgIdResult[grpMsgIdPair] = filteredOutMsgIds[grpId]; + } + else if(req->Options.mReqType == GXS_REQUEST_TYPE_MSG_RELATED_META) + { + GxsMsgMetaResult metaResult; + mDataStore->retrieveGxsMsgMetaData(filteredOutMsgIds, metaResult); + req->mMsgMetaResult[grpMsgIdPair] = metaResult[grpId]; + } + else if(req->Options.mReqType == GXS_REQUEST_TYPE_MSG_RELATED_DATA) + { + GxsMsgResult msgResult; + mDataStore->retrieveNxsMsgs(filteredOutMsgIds, msgResult, false, true); + req->mMsgDataResult[grpMsgIdPair] = msgResult[grpId]; + } } outMsgIds.clear(); diff --git a/libretroshare/src/tests/gxs/genexchangetester.cpp b/libretroshare/src/tests/gxs/genexchangetester.cpp index f86be53c3..d02bab577 100644 --- a/libretroshare/src/tests/gxs/genexchangetester.cpp +++ b/libretroshare/src/tests/gxs/genexchangetester.cpp @@ -836,7 +836,7 @@ bool GenExchangeTester::testMsgAllVersions() return true; } -bool GenExchangeTester::testMsgChildRetrieval() +bool GenExchangeTester::testMsgRelatedChildIdRetrieval() { // // start up // setUp(); @@ -899,7 +899,6 @@ bool GenExchangeTester::testMsgChildRetrieval() // first = false; // } -// } // opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; @@ -946,6 +945,118 @@ bool GenExchangeTester::testMsgChildRetrieval() // return true; } +bool GenExchangeTester::testMsgRelatedChildDataRetrieval() +{ + // start up + setUp(); + setUpGrps(GXS_SERV::FLAG_PRIVACY_PUBLIC); + + /********************/ + + + // create msgs + // then make all requests immediately then poll afterwards for each and run outbound test + // we want only latest for now + int nMsgs = (rand()%50)+2; // test a large number of msgs + std::vector msgs; + createMsgs(msgs, nMsgs); + RsTokReqOptions opts; + opts.mReqType = 4000; + uint32_t token; + + bool first = true; + RsGxsGrpMsgIdPair firstMsgId; + + // everyone is parent of first msg + + for(int i=0; i < nMsgs; i++) + { + RsDummyMsg* msg = msgs[i]; + + if(first){ + msg->meta.mParentId = ""; + msg->meta.mOrigMsgId = ""; + } + else + { + msg->meta.mParentId = firstMsgId.second; + msg->meta.mGroupId = firstMsgId.first; + msg->meta.mOrigMsgId = ""; + } + + mTestService->publishDummyMsg(token, msg); + pollForToken(token, opts); + RsGxsGrpMsgIdPair msgId; + mTestService->acknowledgeTokenMsg(token, msgId); + + + if(msgId.first.empty() || msgId.second.empty()) + { + breakDown(); + std::cerr << "serious error: Acknowledgement failed! " << std::endl; + return false; + } + + // don't add the id to be related + if(!first) + { + mMsgRelatedDataMapOut[firstMsgId].push_back(msg); + } + + if(first){ + firstMsgId.second = msgId.second; + firstMsgId.first = msgId.first; + first = false; + } + } + + + + opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; + opts.mOptions = RS_TOKREQOPT_MSG_PARENT | RS_TOKREQOPT_MSG_LATEST; + std::vector msgIdList; + msgIdList.push_back(firstMsgId); + mTokenService->requestMsgRelatedInfo(token, 0, opts, msgIdList); + + pollForToken(token, opts); + + GxsMsgRelatedDataMap::iterator mit = mMsgRelatedDataMapOut.begin(); + for(; mit != mMsgRelatedDataMapOut.end(); mit++) + { + std::vector& msgDataOut = mit->second; + + std::vector::iterator vit_out = msgDataOut.begin(), vit_in; + + for(; vit_out != msgDataOut.end(); vit_out++) + { + bool found = false; + std::vector& msgDataIn = mMsgRelatedDataMapIn[mit->first]; + vit_in = msgDataIn.begin(); + + for(; vit_in != msgDataIn.end(); vit_in++) + { + if(*vit_in == *vit_out) + found = true; + } + + if(!found){ + breakDown(); + return false; + } + + } + } + + /********************/ + + // complete + breakDown(); + + return true; +} + + + bool GenExchangeTester::testSpecificMsgMetaRetrieval() { @@ -1645,6 +1756,9 @@ void GenExchangeTester::pollForToken(uint32_t token, const RsTokReqOptions &opts case GXS_REQUEST_TYPE_MSG_RELATED_IDS: mTestService->getMsgRelatedListTS(token, mMsgRelatedIdsIn); break; + case GXS_REQUEST_TYPE_MSG_RELATED_DATA: + mTestService->getMsgRelatedDataTS(token, mMsgRelatedDataMapIn); + break; } break; } diff --git a/libretroshare/src/tests/gxs/genexchangetester.h b/libretroshare/src/tests/gxs/genexchangetester.h index 02d6c4140..adec76689 100644 --- a/libretroshare/src/tests/gxs/genexchangetester.h +++ b/libretroshare/src/tests/gxs/genexchangetester.h @@ -34,7 +34,8 @@ public: bool testSpecificMsgMetaRetrieval(); // request msg related tests - bool testMsgChildRetrieval(); + bool testMsgRelatedChildIdRetrieval(); + bool testMsgRelatedChildDataRetrieval(); bool testMsgAllVersions(); @@ -97,6 +98,7 @@ private: GxsMsgIdResult mMsgIdsOut, mMsgIdsIn; MsgRelatedIdResult mMsgRelatedIdsOut, mMsgRelatedIdsIn; + GxsMsgRelatedDataMap mMsgRelatedDataMapOut, mMsgRelatedDataMapIn; std::vector mRandGrpIds; // ids that exist to help group testing diff --git a/libretroshare/src/tests/gxs/genexchangetestservice.cpp b/libretroshare/src/tests/gxs/genexchangetestservice.cpp index 59e0bdbed..f8858bb64 100644 --- a/libretroshare/src/tests/gxs/genexchangetestservice.cpp +++ b/libretroshare/src/tests/gxs/genexchangetestservice.cpp @@ -42,6 +42,11 @@ bool GenExchangeTestService::getMsgDataTS(const uint32_t &token, GxsMsgDataMap & return getMsgData(token, msgItems); } +bool GenExchangeTestService::getMsgRelatedDataTS(const uint32_t &token, GxsMsgRelatedDataMap &msgItems) +{ + return getMsgRelatedData(token, msgItems); +} + bool GenExchangeTestService::getMsgMetaTS(const uint32_t &token, GxsMsgMetaMap &msgInfo) { return getMsgMeta(token, msgInfo); diff --git a/libretroshare/src/tests/gxs/genexchangetestservice.h b/libretroshare/src/tests/gxs/genexchangetestservice.h index 00657e9af..6cdb2e041 100644 --- a/libretroshare/src/tests/gxs/genexchangetestservice.h +++ b/libretroshare/src/tests/gxs/genexchangetestservice.h @@ -67,6 +67,14 @@ public: */ bool getMsgRelatedListTS(const uint32_t &token, MsgRelatedIdResult &msgIds); + /*! + * retrieves msg related data msgItems as a map of msg-grpID pair to vector + * of items + * @param token token to be redeemed + * @param msgItems map of msg items + */ + bool getMsgRelatedDataTS(const uint32_t &token, GxsMsgRelatedDataMap& msgItems); + void setGroupSubscribeFlagTS(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status); diff --git a/libretroshare/src/tests/gxs/rsgenexchange_test.cc b/libretroshare/src/tests/gxs/rsgenexchange_test.cc index 26fadd84d..3f572d291 100644 --- a/libretroshare/src/tests/gxs/rsgenexchange_test.cc +++ b/libretroshare/src/tests/gxs/rsgenexchange_test.cc @@ -18,11 +18,11 @@ int main() // CHECK(tester.testSpecificMsgMetaRetrieval()); REPORT("testSpecificMsgMetaRetrieval()"); // CHECK(tester.testMsgIdRetrieval()); REPORT("tester.testMsgIdRetrieval()"); // CHECK(tester.testMsgIdRetrieval_OptParents()); REPORT("tester.testRelatedMsgIdRetrieval_Parents()"); - CHECK(tester.testMsgIdRetrieval_OptOrigMsgId()); REPORT("tester.testRelatedMsgIdRetrieval_OrigMsgId()"); - CHECK(tester.testMsgIdRetrieval_OptLatest()); REPORT("tester.testRelatedMsgIdRetrieval_Latest()"); - CHECK(tester.testMsgMetaModRequest()); REPORT("tester.testMsgMetaModRequest()"); - // CHECK(tester.testMsgChildRetrieval()); REPORT("tester.testMsgMetaModRequest()"); - CHECK(tester.testMsgAllVersions()); REPORT("tester.testMsgAllVersions()"); +// CHECK(tester.testMsgIdRetrieval_OptOrigMsgId()); REPORT("tester.testRelatedMsgIdRetrieval_OrigMsgId()"); +// CHECK(tester.testMsgIdRetrieval_OptLatest()); REPORT("tester.testRelatedMsgIdRetrieval_Latest()"); +// CHECK(tester.testMsgMetaModRequest()); REPORT("tester.testMsgMetaModRequest()"); + CHECK(tester.testMsgRelatedChildDataRetrieval()); REPORT("tester.testMsgRelatedChildDataRetrieval()"); +// CHECK(tester.testMsgAllVersions()); REPORT("tester.testMsgAllVersions()"); // CHECK(tester.testGrpSubmissionRetrieval()); REPORT("tester.testGrpSubmissionRetrieval()"); // CHECK(tester.testGrpMetaRetrieval()); REPORT("tester.testGrpMetaRetrieval()"); From 9373d26be0ec0c7d4474a668adec2c640e95a98c Mon Sep 17 00:00:00 2001 From: drbob Date: Thu, 15 Nov 2012 23:50:54 +0000 Subject: [PATCH 147/222] * Added Dummy Forums and Messages to GxsForums. * Extra GxsForums::getRelatedMessages() fn + HACKs to cover up GXS bugs. * more debugging in rsgenexchange. * fixed up some of wikis text. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5828 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgenexchange.cc | 29 +- libretroshare/src/retroshare/rsgxsforums.h | 2 + .../src/serialiser/rsgxsforumitems.cc | 2 +- libretroshare/src/services/p3gxsforums.cc | 434 ++++++++++-------- libretroshare/src/services/p3gxsforums.h | 27 +- libretroshare/src/services/p3wiki.cc | 8 +- 6 files changed, 293 insertions(+), 209 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index dbf6e5600..5712bf4f6 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -47,6 +47,8 @@ #define PRIV_GRP_OFFSET 16 #define GRP_OPTIONS_OFFSET 24 +#define GEN_EXCH_DEBUG 1 + RsGenExchange::RsGenExchange(RsGeneralDataService *gds, RsNetworkExchangeService *ns, RsSerialType *serviceSerialiser, uint16_t servType, RsGixs* gixs, uint32_t authenPolicy) : mGenMtx("GenExchange"), mDataStore(gds), mNetService(ns), mSerialiser(serviceSerialiser), @@ -952,17 +954,27 @@ void RsGenExchange::publishGroup(uint32_t& token, RsGxsGrpItem *grpItem) { RsStackMutex stack(mGenMtx); - token = mDataAccess->generatePublicToken(); mGrpsToPublish.insert(std::make_pair(token, grpItem)); + +#ifdef GEN_EXCH_DEBUG + std::cerr << "RsGenExchange::publishGroup() token: " << token; + std::cerr << std::endl; +#endif + } void RsGenExchange::publishMsg(uint32_t& token, RsGxsMsgItem *msgItem) { RsStackMutex stack(mGenMtx); - token = mDataAccess->generatePublicToken(); mMsgsToPublish.insert(std::make_pair(token, msgItem)); + +#ifdef GEN_EXCH_DEBUG + std::cerr << "RsGenExchange::publishMsg() token: " << token; + std::cerr << std::endl; +#endif + } void RsGenExchange::setGroupSubscribeFlags(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& flag, const uint32_t& mask) @@ -1125,6 +1137,13 @@ void RsGenExchange::publishMsgs() req.insert(std::make_pair(msg->grpId, msgV)); mDataStore->retrieveGxsMsgMetaData(req, res); msgDoesnExist = res[grpId].empty(); + +#ifdef GEN_EXCH_DEBUG + if (!msgDoesnExist) + { + std::cerr << "RsGenExchange::publishMsgs() msg exists already :( " << std::endl; + } +#endif } if(createOk && msgDoesnExist) @@ -1167,6 +1186,12 @@ void RsGenExchange::publishMsgs() #endif } } + else + { +#ifdef GEN_EXCH_DEBUG + std::cerr << "RsGenExchange::publishMsgs() failed to serialise msg " << std::endl; +#endif + } delete[] mData; delete msgItem; diff --git a/libretroshare/src/retroshare/rsgxsforums.h b/libretroshare/src/retroshare/rsgxsforums.h index 34d57b89d..8c18509e5 100644 --- a/libretroshare/src/retroshare/rsgxsforums.h +++ b/libretroshare/src/retroshare/rsgxsforums.h @@ -75,6 +75,7 @@ virtual ~RsGxsForums() { return; } /* Specific Service Data */ virtual bool getGroupData(const uint32_t &token, std::vector &groups) = 0; virtual bool getMsgData(const uint32_t &token, std::vector &msgs) = 0; +virtual bool getRelatedMessages(const uint32_t &token, std::vector &msgs) = 0; ////////////////////////////////////////////////////////////////////////////// virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) = 0; @@ -88,6 +89,7 @@ virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgI virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group) = 0; virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg) = 0; +virtual bool generateDummyData() = 0; }; diff --git a/libretroshare/src/serialiser/rsgxsforumitems.cc b/libretroshare/src/serialiser/rsgxsforumitems.cc index 2d0f90430..9423ce058 100644 --- a/libretroshare/src/serialiser/rsgxsforumitems.cc +++ b/libretroshare/src/serialiser/rsgxsforumitems.cc @@ -279,7 +279,7 @@ uint32_t RsGxsForumSerialiser::sizeGxsForumMsgItem(RsGxsForumMsgItem *item) const RsGxsForumMsg& msg = item->mMsg; uint32_t s = 8; // header - s += 4; // mMsg. + s += GetTlvStringSize(msg.mMsg); // mMsg. return s; } diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index 6d0bd2985..6c539cd97 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -26,10 +26,14 @@ #include "services/p3gxsforums.h" #include "serialiser/rsgxsforumitems.h" -#include "util/rsrandom.h" + #include "gxs/rsgxsflags.h" #include +// For Dummy Msgs. +#include "util/rsrandom.h" +#include "util/rsstring.h" + /**** * #define GXSFORUM_DEBUG 1 ****/ @@ -45,6 +49,8 @@ RsGxsForums *rsGxsForums = NULL; p3GxsForums::p3GxsForums(RsGeneralDataService *gds, RsNetworkExchangeService *nes) : RsGenExchange(gds, nes, new RsGxsForumSerialiser(), RS_SERVICE_GXSV1_TYPE_FORUMS), RsGxsForums(this) { + // For Dummy Msgs. + mGenActive = false; } void p3GxsForums::notifyChanges(std::vector &changes) @@ -54,6 +60,7 @@ void p3GxsForums::notifyChanges(std::vector &changes) void p3GxsForums::service_tick() { + dummy_tick(); return; } @@ -122,6 +129,65 @@ bool p3GxsForums::getMsgData(const uint32_t &token, std::vector & return ok; } + +bool p3GxsForums::getRelatedMessages(const uint32_t &token, std::vector &msgs) +{ + GxsMsgRelatedDataMap msgData; + bool ok = RsGenExchange::getMsgRelatedData(token, msgData); + + if(ok) + { + GxsMsgRelatedDataMap::iterator mit = msgData.begin(); + + for(; mit != msgData.end(); mit++) + { + std::vector& msgItems = mit->second; + std::vector::iterator vit = msgItems.begin(); + + for(; vit != msgItems.end(); vit++) + { + RsGxsForumMsgItem* item = dynamic_cast(*vit); + + if(item) + { + /* HACK UNTIL CHRIS FIXES RELATED MSGS in GXS */ + if (item->meta.mMsgId == (mit->first).second) + { + std::cerr << "p3GxsForums::getRelatedMessages()"; + std::cerr << " ERROR Found Original - discarding"; + std::cerr << " Id: " << item->meta.mMsgId; + std::cerr << std::endl; + delete item; + continue; + } + + if (item->meta.mParentId != (mit->first).second) + { + std::cerr << "p3GxsForums::getRelatedMessages()"; + std::cerr << " ERROR Found !CHILD - discarding"; + std::cerr << " Id: " << item->meta.mMsgId; + std::cerr << std::endl; + delete item; + continue; + } + + RsGxsForumMsg msg = item->mMsg; + msg.mMeta = item->meta; + msgs.push_back(msg); + delete item; + } + else + { + std::cerr << "Not a GxsForumMsgItem, deleting!" << std::endl; + delete *vit; + } + } + } + } + + return ok; +} + /********************************************************************************************/ bool p3GxsForums::createGroup(uint32_t &token, RsGxsForumGroup &group) @@ -170,218 +236,184 @@ void p3GxsForums::setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& /********************************************************************************************/ /********************************************************************************************/ +/* so we need the same tick idea as wiki for generating dummy forums + */ + +#define MAX_GEN_GROUPS 5 +#define MAX_GEN_MESSAGES 100 std::string p3GxsForums::genRandomId() { - std::string randomId; - for(int i = 0; i < 20; i++) - { - randomId += (char) ('a' + (RSRandom::random_u32() % 26)); - } - - return randomId; + std::string randomId; + for(int i = 0; i < 20; i++) + { + randomId += (char) ('a' + (RSRandom::random_u32() % 26)); + } + + return randomId; } bool p3GxsForums::generateDummyData() { - return false; -} + mGenCount = 0; + mGenRefs.resize(MAX_GEN_MESSAGES); + std::string groupName; + rs_sprintf(groupName, "TestForum_%d", mGenCount); -#if 0 + std::cerr << "p3GxsForums::generateDummyData() Starting off with Group: " << groupName; + std::cerr << std::endl; -bool p3GxsForums::generateDummyData() -{ - /* so we want to generate 100's of forums */ -#define MAX_FORUMS 10 //100 -#define MAX_THREADS 10 //1000 -#define MAX_MSGS 100 //10000 + /* create a new group */ + generateGroup(mGenToken, groupName); - std::list mGroups; - std::list::iterator git; - - std::list mMsgs; - std::list::iterator mit; - -#define DUMMY_NAME_MAX_LEN 10000 - char name[DUMMY_NAME_MAX_LEN]; - int i, j; - time_t now = time(NULL); - - for(i = 0; i < MAX_FORUMS; i++) - { - /* generate a new forum */ - RsForumV2Group forum; - - /* generate a temp id */ - forum.mMeta.mGroupId = genRandomId(); - - snprintf(name, DUMMY_NAME_MAX_LEN, "TestForum_%d", i+1); - - forum.mMeta.mGroupId = genRandomId(); - forum.mMeta.mGroupName = name; - - forum.mMeta.mPublishTs = now - (RSRandom::random_f32() * 100000); - /* key fields to fill in: - * GroupId. - * Name. - * Flags. - * Pop. - */ - - - - /* use probability to decide which are subscribed / own / popularity. - */ - - float rnd = RSRandom::random_f32(); - if (rnd < 0.1) - { - forum.mMeta.mSubscribeFlags = RSGXS_GROUP_SUBSCRIBE_ADMIN; - - } - else if (rnd < 0.3) - { - forum.mMeta.mSubscribeFlags = RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED; - } - else - { - forum.mMeta.mSubscribeFlags = 0; - } - - forum.mMeta.mPop = (int) (RSRandom::random_f32() * 10.0); - - mGroups.push_back(forum); - - - //std::cerr << "p3GxsForums::generateDummyData() Generated Forum: " << forum.mMeta; - //std::cerr << std::endl; - } - - - for(i = 0; i < MAX_THREADS; i++) - { - /* generate a base thread */ - - /* rotate the Forum Groups Around, then pick one. - */ - - int rnd = (int) (RSRandom::random_f32() * 10.0); - - for(j = 0; j < rnd; j++) - { - RsForumV2Group head = mGroups.front(); - mGroups.pop_front(); - mGroups.push_back(head); - } - - RsForumV2Group forum = mGroups.front(); - - /* now create a new thread */ - - RsForumV2Msg msg; - - /* fill in key data - * GroupId - * MsgId - * OrigMsgId - * ThreadId - * ParentId - * PublishTS (take Forum TS + a bit ). - * - * ChildTS ???? - */ - snprintf(name, DUMMY_NAME_MAX_LEN, "%s => ThreadMsg_%d", forum.mMeta.mGroupName.c_str(), i+1); - msg.mMeta.mMsgName = name; - - msg.mMeta.mGroupId = forum.mMeta.mGroupId; - msg.mMeta.mMsgId = genRandomId(); - msg.mMeta.mOrigMsgId = msg.mMeta.mMsgId; - msg.mMeta.mThreadId = msg.mMeta.mMsgId; - msg.mMeta.mParentId = ""; - - msg.mMeta.mPublishTs = forum.mMeta.mPublishTs + (RSRandom::random_f32() * 10000); - if (msg.mMeta.mPublishTs > now) - msg.mMeta.mPublishTs = now - 1; - - mMsgs.push_back(msg); - - //std::cerr << "p3GxsForums::generateDummyData() Generated Thread: " << msg.mMeta; - //std::cerr << std::endl; - - } - - for(i = 0; i < MAX_MSGS; i++) - { - /* generate a base thread */ - - /* rotate the Forum Groups Around, then pick one. - */ - - int rnd = (int) (RSRandom::random_f32() * 10.0); - - for(j = 0; j < rnd; j++) - { - RsForumV2Msg head = mMsgs.front(); - mMsgs.pop_front(); - mMsgs.push_back(head); - } - - RsForumV2Msg parent = mMsgs.front(); - - /* now create a new child msg */ - - RsForumV2Msg msg; - - /* fill in key data - * GroupId - * MsgId - * OrigMsgId - * ThreadId - * ParentId - * PublishTS (take Forum TS + a bit ). - * - * ChildTS ???? - */ - snprintf(name, DUMMY_NAME_MAX_LEN, "%s => Msg_%d", parent.mMeta.mMsgName.c_str(), i+1); - msg.mMeta.mMsgName = name; - msg.mMsg = name; - - msg.mMeta.mGroupId = parent.mMeta.mGroupId; - msg.mMeta.mMsgId = genRandomId(); - msg.mMeta.mOrigMsgId = msg.mMeta.mMsgId; - msg.mMeta.mThreadId = parent.mMeta.mThreadId; - msg.mMeta.mParentId = parent.mMeta.mOrigMsgId; - - msg.mMeta.mPublishTs = parent.mMeta.mPublishTs + (RSRandom::random_f32() * 10000); - if (msg.mMeta.mPublishTs > now) - msg.mMeta.mPublishTs = now - 1; - - mMsgs.push_back(msg); - - //std::cerr << "p3GxsForums::generateDummyData() Generated Child Msg: " << msg.mMeta; - //std::cerr << std::endl; - - } - - - mUpdated = true; - - /* Then - at the end, we push them all into the Proxy */ - for(git = mGroups.begin(); git != mGroups.end(); git++) - { - /* pushback */ - mForumProxy->addForumGroup(*git); - - } - - for(mit = mMsgs.begin(); mit != mMsgs.end(); mit++) - { - /* pushback */ - mForumProxy->addForumMsg(*mit); - } + mGenActive = true; + + return true; +} + + +void p3GxsForums::dummy_tick() +{ + /* check for a new callback */ + + if (mGenActive) + { + std::cerr << "p3Wiki::dummyTick() AboutActive"; + std::cerr << std::endl; + + uint32_t status = RsGenExchange::getTokenService()->requestStatus(mGenToken); + if (status != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + { + std::cerr << "p3GxsForums::dummy_tick() Status: " << status; + std::cerr << std::endl; + + if (status == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED) + { + std::cerr << "p3GxsForums::dummy_tick() generateDummyMsgs() FAILED"; + std::cerr << std::endl; + mGenActive = false; + } + return; + } + + if (mGenCount < MAX_GEN_GROUPS) + { + /* get the group Id */ + RsGxsGroupId groupId; + RsGxsMessageId emptyId; + if (!acknowledgeTokenGrp(mGenToken, groupId)) + { + std::cerr << " ERROR "; + std::cerr << std::endl; + mGenActive = false; + return; + } + + std::cerr << "p3GxsForums::dummy_tick() Acknowledged GroupId: " << groupId; + std::cerr << std::endl; + + ForumDummyRef ref(groupId, emptyId, emptyId); + mGenRefs[mGenCount] = ref; + } + else if (mGenCount < MAX_GEN_MESSAGES) + { + /* get the msg Id, and generate next snapshot */ + RsGxsGrpMsgIdPair msgId; + if (!acknowledgeTokenMsg(mGenToken, msgId)) + { + std::cerr << " ERROR "; + std::cerr << std::endl; + mGenActive = false; + return; + } + + std::cerr << "p3GxsForums::dummy_tick() Acknowledged "; + std::cerr << std::endl; + + /* store results for later selection */ + + ForumDummyRef ref(msgId.first, mGenThreadId, msgId.second); + mGenRefs[mGenCount] = ref; + } + else + { + std::cerr << "p3GxsForums::dummy_tick() Finished"; + std::cerr << std::endl; + + /* done */ + mGenActive = false; + return; + } + + mGenCount++; + + if (mGenCount < MAX_GEN_GROUPS) + { + std::string groupName; + rs_sprintf(groupName, "TestForum_%d", mGenCount); + + std::cerr << "p3GxsForums::dummy_tick() Generating Group: " << groupName; + std::cerr << std::endl; + + /* create a new group */ + generateGroup(mGenToken, groupName); + } + else + { + /* create a new message */ + uint32_t idx = (uint32_t) (mGenCount * RSRandom::random_f32()); + ForumDummyRef &ref = mGenRefs[idx]; + + RsGxsGroupId grpId = ref.mGroupId; + RsGxsMessageId parentId = ref.mMsgId; + mGenThreadId = ref.mThreadId; + if (mGenThreadId.empty()) + { + mGenThreadId = parentId; + } + + std::cerr << "p3GxsForums::dummy_tick() Generating Msg ... "; + std::cerr << " GroupId: " << grpId; + std::cerr << " ThreadId: " << mGenThreadId; + std::cerr << " ParentId: " << parentId; + std::cerr << std::endl; + + generateMessage(mGenToken, grpId, parentId, mGenThreadId); + } + } +} + + +bool p3GxsForums::generateMessage(uint32_t &token, const RsGxsGroupId &grpId, const RsGxsMessageId &parentId, const RsGxsMessageId &threadId) +{ + RsGxsForumMsg msg; + + std::string rndId = genRandomId(); + + rs_sprintf(msg.mMsg, "Forum Msg: GroupId: %s, ThreadId: %s, ParentId: %s + some randomness: %s", + grpId.c_str(), threadId.c_str(), parentId.c_str(), rndId.c_str()); + + msg.mMeta.mMsgName = msg.mMsg; + + msg.mMeta.mGroupId = grpId; + msg.mMeta.mThreadId = threadId; + msg.mMeta.mParentId = parentId; + + createMsg(token, msg); + + return true; +} + + +bool p3GxsForums::generateGroup(uint32_t &token, std::string groupName) +{ + /* generate a new forum */ + RsGxsForumGroup forum; + forum.mMeta.mGroupName = groupName; + + createGroup(token, forum); return true; } -#endif diff --git a/libretroshare/src/services/p3gxsforums.h b/libretroshare/src/services/p3gxsforums.h index 8ed77ab80..a8a45358f 100644 --- a/libretroshare/src/services/p3gxsforums.h +++ b/libretroshare/src/services/p3gxsforums.h @@ -52,6 +52,7 @@ virtual void service_tick(); virtual bool getGroupData(const uint32_t &token, std::vector &groups); virtual bool getMsgData(const uint32_t &token, std::vector &msgs); +virtual bool getRelatedMessages(const uint32_t &token, std::vector &msgs); ////////////////////////////////////////////////////////////////////////////// virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read); @@ -65,11 +66,35 @@ virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgI virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group); virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg); +virtual bool generateDummyData(); private: std::string genRandomId(); -bool generateDummyData(); +void dummy_tick(); + +bool generateMessage(uint32_t &token, const RsGxsGroupId &grpId, + const RsGxsMessageId &parentId, const RsGxsMessageId &threadId); +bool generateGroup(uint32_t &token, std::string groupName); + + class ForumDummyRef + { + public: + ForumDummyRef() { return; } + ForumDummyRef(const RsGxsGroupId &grpId, const RsGxsMessageId &threadId, const RsGxsMessageId &msgId) + :mGroupId(grpId), mThreadId(threadId), mMsgId(msgId) { return; } + + RsGxsGroupId mGroupId; + RsGxsMessageId mThreadId; + RsGxsMessageId mMsgId; + }; + + uint32_t mGenToken; + bool mGenActive; + int mGenCount; + std::vector mGenRefs; + RsGxsMessageId mGenThreadId; + }; #endif diff --git a/libretroshare/src/services/p3wiki.cc b/libretroshare/src/services/p3wiki.cc index 508f5fed9..29cc0200e 100644 --- a/libretroshare/src/services/p3wiki.cc +++ b/libretroshare/src/services/p3wiki.cc @@ -330,13 +330,13 @@ const std::string improvements_txt[] = " - Diffs, lots of edits will lead to complex merges - a robust merge tool is essential\n", " - Read Mode... hide all the Edits, and only show the most recently published versions\n", " - Easy Duplication - to take over an Abandoned or badly moderated Wiki. Copies All base versions to a new group\n", - " - WikiLinks. A generic Wiki Cross Linking system. This should be combined with Easy Duplication option,\n", - " to allow easy replacement of groups if necessary... A good design here is critical to a successful Wiki ecosystem", - " the republished page becomes a new version of the Root Page, allowing more edits to be done\n", + " - WikiLinks. A generic Wiki Cross Linking system. This should be combined with Easy Duplication option,", + " to allow easy replacement of groups if necessary... A good design here is critical to a successful Wiki ecosystem\n", " - work out how to include media (photos, audio, video, etc) without embedding in pages", " this would leverage the turtle transfer system somehow - maybe like channels.\n", " - Comments, reviews etc can be incorporated - ideas here are welcome.\n", - " - Any other suggestion???" + " - Any other suggestion???", + " - Come on more ideas!" }; From eb23479611742bc51d020358e68a62ea623068de Mon Sep 17 00:00:00 2001 From: drbob Date: Thu, 15 Nov 2012 23:51:57 +0000 Subject: [PATCH 148/222] * Made GxsForum messages load again. * Hijacked "Next unread" button => force Reload, until update is working. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5829 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/GxsForumsDialog.cpp | 76 ++++++++++++++++++++-- retroshare-gui/src/gui/GxsForumsDialog.h | 2 + retroshare-gui/src/gui/GxsForumsDialog.ui | 2 +- 3 files changed, 73 insertions(+), 7 deletions(-) diff --git a/retroshare-gui/src/gui/GxsForumsDialog.cpp b/retroshare-gui/src/gui/GxsForumsDialog.cpp index e1013bad9..182626b98 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/GxsForumsDialog.cpp @@ -174,7 +174,10 @@ GxsForumsDialog::GxsForumsDialog(QWidget *parent) connect(ui.expandButton, SIGNAL(clicked()), this, SLOT(togglethreadview())); connect(ui.previousButton, SIGNAL(clicked()), this, SLOT(previousMessage())); connect(ui.nextButton, SIGNAL(clicked()), this, SLOT(nextMessage())); - connect(ui.nextUnreadButton, SIGNAL(clicked()), this, SLOT(nextUnreadMessage())); + + // HACK - TEMPORARY HIJACKING THIS BUTTON FOR REFRESH. + //connect(ui.nextUnreadButton, SIGNAL(clicked()), this, SLOT(nextUnreadMessage())); + connect(ui.nextUnreadButton, SIGNAL(clicked()), this, SLOT(forceUpdateDisplay())); connect(ui.downloadButton, SIGNAL(clicked()), this, SLOT(downloadAllFiles())); @@ -238,6 +241,10 @@ GxsForumsDialog::GxsForumsDialog(QWidget *parent) ui.threadTreeWidget->installEventFilter(this); + + + rsGxsForums->generateDummyData(); + /* Hide platform specific features */ #ifdef Q_WS_WIN @@ -521,6 +528,19 @@ void GxsForumsDialog::updateDisplay() } } +// HACK until update works. +void GxsForumsDialog::forceUpdateDisplay() +{ + std::cerr << "GxsForumsDialog::forceUpdateDisplay()"; + std::cerr << std::endl; + + /* update Forums List */ + insertForums(); + /* update threads as well */ + insertThreads(); +} + + static void CleanupItems (QList &items) { QList::iterator item; @@ -1858,10 +1878,11 @@ void GxsForumsDialog::requestGroupSummary() std::cerr << "GxsForumsDialog::requestGroupSummary()"; std::cerr << std::endl; - std::list ids; RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; + uint32_t token; - mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, ids, FORUMSV2DIALOG_LISTING); + mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, FORUMSV2DIALOG_LISTING); } void GxsForumsDialog::loadGroupSummary(const uint32_t &token) @@ -1891,6 +1912,7 @@ void GxsForumsDialog::loadGroupSummary(const uint32_t &token) void GxsForumsDialog::requestGroupSummary_CurrentForum(const std::string &forumId) { RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; std::list grpIds; grpIds.push_back(forumId); @@ -2005,6 +2027,7 @@ void GxsForumsDialog::loadCurrentForumThreads(const std::string &forumId) void GxsForumsDialog::requestGroupThreadData_InsertThreads(const std::string &forumId) { RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; @@ -2151,7 +2174,7 @@ void GxsForumsDialog::loadForumBaseThread(const RsGxsForumMsg &msg) void GxsForumsDialog::requestChildData_InsertThreads(uint32_t &token, const RsGxsGrpMsgIdPair &parentId) { RsTokReqOptions opts; - + opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; opts.mOptions = RS_TOKREQOPT_MSG_PARENT | RS_TOKREQOPT_MSG_LATEST; std::cerr << "GxsForumsDialog::requestChildData_InsertThreads(" << parentId.first << "," << parentId.second << ")"; @@ -2185,11 +2208,10 @@ void GxsForumsDialog::loadChildData_InsertThreads(const uint32_t &token) std::cerr << "GxsForumsDialog::loadChildData_InsertThreads()"; std::cerr << std::endl; - std::vector msgs; std::vector::iterator vit; - if (rsGxsForums->getMsgData(token, msgs)) + if (rsGxsForums->getRelatedMessages(token, msgs)) { for(vit = msgs.begin(); vit != msgs.end(); vit++) { @@ -2267,7 +2289,9 @@ void GxsForumsDialog::loadForumChildMsg(const RsGxsForumMsg &msg, QTreeWidgetIte void GxsForumsDialog::requestMsgData_InsertPost(const RsGxsGrpMsgIdPair &msgId) { +#if 0 RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; std::cerr << "GxsForumsDialog::requestMsgData_InsertPost(" << msgId.first << "," << msgId.second << ")"; std::cerr << std::endl; @@ -2276,6 +2300,20 @@ void GxsForumsDialog::requestMsgData_InsertPost(const RsGxsGrpMsgIdPair &msgId) msgIds.push_back(msgId); uint32_t token; mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_INSERT_POST); +#else + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + + std::cerr << "GxsForumsDialog::requestMsgData_InsertPost(" << msgId.first << "," << msgId.second << ")"; + std::cerr << std::endl; + + GxsMsgReq msgIds; + std::vector &vect = msgIds[msgId.first]; + vect.push_back(msgId.second); + + uint32_t token; + mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_INSERT_POST); +#endif } @@ -2285,7 +2323,11 @@ void GxsForumsDialog::loadMsgData_InsertPost(const uint32_t &token) std::cerr << std::endl; std::vector msgs; +#if 0 + if (rsGxsForums->getRelatedMessages(token, msgs)) +#else if (rsGxsForums->getMsgData(token, msgs)) +#endif { if (msgs.size() != 1) { @@ -2308,7 +2350,9 @@ void GxsForumsDialog::loadMsgData_InsertPost(const uint32_t &token) void GxsForumsDialog::requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId) { +#if 0 RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; std::cerr << "GxsForumsDialog::requestMsgData_ReplyMessage(" << msgId.first << "," << msgId.second << ")"; std::cerr << std::endl; @@ -2317,6 +2361,22 @@ void GxsForumsDialog::requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId msgIds.push_back(msgId); uint32_t token; mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_REPLY_MESSAGE); +#else + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + + std::cerr << "GxsForumsDialog::requestMsgData_ReplyMessage(" << msgId.first << "," << msgId.second << ")"; + std::cerr << std::endl; + + GxsMsgReq msgIds; + std::vector &vect = msgIds[msgId.first]; + vect.push_back(msgId.second); + + uint32_t token; + mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_REPLY_MESSAGE); +#endif + } @@ -2326,7 +2386,11 @@ void GxsForumsDialog::loadMsgData_ReplyMessage(const uint32_t &token) std::cerr << std::endl; std::vector msgs; +#if 0 + if (rsGxsForums->getRelatedMessages(token, msgs)) +#else if (rsGxsForums->getMsgData(token, msgs)) +#endif { if (msgs.size() != 1) { diff --git a/retroshare-gui/src/gui/GxsForumsDialog.h b/retroshare-gui/src/gui/GxsForumsDialog.h index db042b54d..37d803830 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.h +++ b/retroshare-gui/src/gui/GxsForumsDialog.h @@ -87,6 +87,8 @@ protected: bool eventFilter(QObject *obj, QEvent *ev); private slots: + void forceUpdateDisplay(); // TEMP HACK FN. + /** Create the context popup menu and it's submenus */ void forumListCustomPopupMenu( QPoint point ); void threadListCustomPopupMenu( QPoint point ); diff --git a/retroshare-gui/src/gui/GxsForumsDialog.ui b/retroshare-gui/src/gui/GxsForumsDialog.ui index e4e824574..afe0abccc 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.ui +++ b/retroshare-gui/src/gui/GxsForumsDialog.ui @@ -1004,7 +1004,7 @@ background: white;}
- Next unread + Force Refresh
From c5fee54ee78ccb9797853d58db585fae7c323636 Mon Sep 17 00:00:00 2001 From: defnax Date: Fri, 16 Nov 2012 16:41:59 +0000 Subject: [PATCH 149/222] Added some icons for the Wiki Pages Dialog. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5831 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/RetroShare.pro | 2 +- retroshare-gui/src/gui/GxsForumsDialog.ui | 154 +-- retroshare-gui/src/gui/WikiPoos/WikiDialog.ui | 343 +++-- .../src/gui/WikiPoos/WikiEditDialog.ui | 300 +++-- .../src/gui/WikiPoos/Wiki_images.qrc | 9 +- .../gui/WikiPoos/images/appointment-new.png | Bin 0 -> 3289 bytes .../gui/WikiPoos/images/arrow-left-double.png | Bin 0 -> 1364 bytes .../src/gui/WikiPoos/images/arrow-left.png | Bin 0 -> 1019 bytes .../WikiPoos/images/arrow-right-double.png | Bin 0 -> 1398 bytes .../src/gui/WikiPoos/images/arrow-right.png | Bin 0 -> 1006 bytes .../src/gui/WikiPoos/images/book2_128.png | Bin 0 -> 12425 bytes .../src/gui/WikiPoos/images/book2_16.png | Bin 0 -> 786 bytes .../src/gui/WikiPoos/images/book2_32.png | Bin 0 -> 1858 bytes .../src/gui/WikiPoos/images/book2_48.png | Bin 0 -> 3265 bytes .../src/gui/WikiPoos/images/book2_64.png | Bin 0 -> 4703 bytes .../src/gui/WikiPoos/images/republish.png | Bin 0 -> 2182 bytes .../WikiPoos/images/resource-group-new.png | Bin 0 -> 2266 bytes .../WikiPoos/images/resource-group-new_48.png | Bin 0 -> 3842 bytes .../gui/WikiPoos/images/resource-group.png | Bin 0 -> 1823 bytes .../src/gui/WikiPoos/images/story-editor.png | Bin 0 -> 1646 bytes .../src/gui/WikiPoos/images/view-refresh.png | Bin 0 -> 2182 bytes retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp | 5 +- retroshare-gui/src/gui/gxs/GxsGroupDialog.ui | 1117 ++++++++--------- 23 files changed, 1053 insertions(+), 877 deletions(-) create mode 100644 retroshare-gui/src/gui/WikiPoos/images/appointment-new.png create mode 100644 retroshare-gui/src/gui/WikiPoos/images/arrow-left-double.png create mode 100644 retroshare-gui/src/gui/WikiPoos/images/arrow-left.png create mode 100644 retroshare-gui/src/gui/WikiPoos/images/arrow-right-double.png create mode 100644 retroshare-gui/src/gui/WikiPoos/images/arrow-right.png create mode 100644 retroshare-gui/src/gui/WikiPoos/images/book2_128.png create mode 100644 retroshare-gui/src/gui/WikiPoos/images/book2_16.png create mode 100644 retroshare-gui/src/gui/WikiPoos/images/book2_32.png create mode 100644 retroshare-gui/src/gui/WikiPoos/images/book2_48.png create mode 100644 retroshare-gui/src/gui/WikiPoos/images/book2_64.png create mode 100644 retroshare-gui/src/gui/WikiPoos/images/republish.png create mode 100644 retroshare-gui/src/gui/WikiPoos/images/resource-group-new.png create mode 100644 retroshare-gui/src/gui/WikiPoos/images/resource-group-new_48.png create mode 100644 retroshare-gui/src/gui/WikiPoos/images/resource-group.png create mode 100644 retroshare-gui/src/gui/WikiPoos/images/story-editor.png create mode 100644 retroshare-gui/src/gui/WikiPoos/images/view-refresh.png diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index c3d92e32e..8b1d1c05b 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -708,7 +708,7 @@ SOURCES += main.cpp \ -RESOURCES += gui/images.qrc lang/lang.qrc gui/help/content/content.qrc +RESOURCES += gui/images.qrc lang/lang.qrc gui/help/content/content.qrc gui/WikiPoos/Wiki_images.qrc TRANSLATIONS += \ lang/retroshare_en.ts \ diff --git a/retroshare-gui/src/gui/GxsForumsDialog.ui b/retroshare-gui/src/gui/GxsForumsDialog.ui index afe0abccc..302f20ecb 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.ui +++ b/retroshare-gui/src/gui/GxsForumsDialog.ui @@ -700,38 +700,6 @@ p, li { white-space: pre-wrap; } - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - - 10 - 75 - true - - - - Forum: - - - @@ -753,11 +721,7 @@ p, li { white-space: pre-wrap; } - -border: 2px solid #CCCCCC; -border-radius:6px; -background: white; - + @@ -835,44 +799,8 @@ background: white; - + - - - - - 0 - 0 - - - - - 10 - 75 - true - - - - Thread: - - - - - - - QLabel#threadTitle{ -border: 2px solid #CCCCCC; -border-radius: 6px; -background: white;} - - - true - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse - - - @@ -949,7 +877,7 @@ background: white;}
- + @@ -975,7 +903,7 @@ background: white;}
- + @@ -995,7 +923,7 @@ background: white;}
- + @@ -1008,6 +936,42 @@ background: white;}
+ + + + + 24 + 24 + + + + Qt::NoFocus + + + Reply Message + + + + :/images/mail_reply.png:/images/mail_reply.png + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -1097,29 +1061,6 @@ border: 1px solid #CCCCCC;} - - - - - 24 - 24 - - - - Qt::NoFocus - - - Reply Message - - - - :/images/mail_reply.png:/images/mail_reply.png - - - true - - - @@ -1196,6 +1137,19 @@ border: 1px solid #CCCCCC;} + + + + + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui index 72e14a6b1..e526c49c3 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui @@ -6,93 +6,173 @@ 0 0 - 774 - 608 + 902 + 669 - - + + Qt::Horizontal - - - Qt::Vertical - - - - true + + + + 0 - - - - 0 - 0 - 205 - 285 - - - - - - - - Wiki Group + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 3 + + + + + + 24 + 24 + - - - Page + + + + :/images/book2_32.png + + + true + + + + + + + + 10 + 75 + true + - - - Id + Wiki Pages - + + + + + + New Group + + + + :/images/resource-group-new.png:/images/resource-group-new.png + + + + 24 + 24 + + + + Qt::ToolButtonTextBesideIcon + + + + + + + + + + Qt::Vertical + + + + true + + + + + 0 + 0 + 255 + 301 + + + + + + + + Wiki Group + + + + + Page + + + + + Id + + + + + - - - - - - - true - - - - - 0 - 0 - 205 - 284 - - - - - - - - Page Modification - - - - - By - - + + + + true + + + + + 0 + 0 + 255 + 301 + + + + + + + + Page Modification + + + + + By + + + + + - - - - + + + + + + 0 + @@ -102,6 +182,9 @@ QFrame::Raised + + 2 + @@ -110,6 +193,16 @@ << + + + :/images/arrow-left.png:/images/arrow-left.png + + + + 24 + 24 + + @@ -120,6 +213,16 @@ >> + + + :/images/arrow-right.png:/images/arrow-right.png + + + + 24 + 24 + + @@ -129,13 +232,39 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + false - << Mod + Mod + + + + :/images/arrow-left.png:/images/arrow-left.png + + + + 24 + 24 + + + + Qt::ToolButtonTextBesideIcon @@ -144,6 +273,19 @@ Republish + + + :/images/republish.png:/images/republish.png + + + + 24 + 24 + + + + Qt::ToolButtonTextBesideIcon + @@ -151,6 +293,19 @@ Edit + + + :/images/story-editor.png:/images/story-editor.png + + + + 24 + 24 + + + + Qt::ToolButtonTextBesideIcon + @@ -159,7 +314,20 @@ false - Mod >> + Mod + + + + :/images/arrow-right.png:/images/arrow-right.png + + + + 24 + 24 + + + + Qt::ToolButtonTextBesideIcon @@ -170,18 +338,24 @@ - - - - New Group - - - New Page + + + :/images/appointment-new.png:/images/appointment-new.png + + + + 24 + 24 + + + + Qt::ToolButtonTextBesideIcon + @@ -192,6 +366,19 @@ Refresh + + + :/images/republish.png:/images/republish.png + + + + 24 + 24 + + + + Qt::ToolButtonTextBesideIcon + @@ -210,8 +397,8 @@ 0 0 - 528 - 511 + 616 + 611 diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui index 5e8df9a33..c215c3901 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui @@ -13,154 +13,182 @@ - - - - - Wiki Page + + + 0 + + + 0 + + + + + QFrame::StyledPanel - + + QFrame::Raised + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + - - - Wiki Group: - - - groupBox + + + Wiki Page + + + + + Wiki Group: + + + groupBox + + + + + + + true + + + + + + + Qt::Horizontal + + + + 168 + 20 + + + + + + + + Page Name: + + + + + + + + 10 + 0 + + + + + + + + Edit ID + + + + + + + + + + Previous Version + + + + + + + + 10 + 0 + + + + true + + + + + + + Prev ID + + + + + + + + 1 + 0 + + + + true + + + + - - - - true - - - - - - - Qt::Horizontal - - - - 168 - 20 - - - - - - - Page Name: - - - - - - - - 10 - 0 - - - - - - - - Edit ID - - - - - + - - - Previous Version - - - - - - - - 10 - 0 - - - - true - - - - - - - Prev ID - - - - - - - - 1 - 0 - - - - true - - + + + + + Cancel + + + + + + + Revert + + + + + + + Qt::Horizontal + + + + 228 + 20 + + + + + + + + Submit + + + + - - - - - - - - - Cancel - - - - - - - Revert - - - - - - - Qt::Horizontal - - - - 228 - 20 - - - - - - - - Submit - - - - - diff --git a/retroshare-gui/src/gui/WikiPoos/Wiki_images.qrc b/retroshare-gui/src/gui/WikiPoos/Wiki_images.qrc index 3ab091103..47a905426 100644 --- a/retroshare-gui/src/gui/WikiPoos/Wiki_images.qrc +++ b/retroshare-gui/src/gui/WikiPoos/Wiki_images.qrc @@ -1,5 +1,12 @@ - images/dummy.png + images/arrow-left.png + images/arrow-right.png + images/resource-group-new.png + images/appointment-new.png + images/book2_32.png + images/story-editor.png + images/republish.png + images/resource-group-new_48.png diff --git a/retroshare-gui/src/gui/WikiPoos/images/appointment-new.png b/retroshare-gui/src/gui/WikiPoos/images/appointment-new.png new file mode 100644 index 0000000000000000000000000000000000000000..aa5207585ce3fdce84fc936986262fdef723523d GIT binary patch literal 3289 zcmXw63pf+(7iUIOjj=>-V<&UNnaM(kV1s7A?tI$H`V8oCS=4$p)k3B5wV6z z(VsqAnA^VO9_Bvx|N8#V|9zhGp7(j*bKY~_-#O=b&YOJ2-UfVF_OO6}0QjOU+L6zd zei1~3KO^Q|HSn1z!PYfcKtQhQ7YVw{rpy1@3?rEP{gV8b61OQ-{zAm-k`4Oc-y!O< zIU*o%RPQ3%+$n<1B7;NHd|;jNJ9#zf1GjTN2h>dYtY&0;$rN4ba&))1IF+tuj82Pa z&SG2Fx(pgcLvwG|tAEQF$bzi&tYnbkuU`ytqv_*28>a7ihA!Cj=1)`d$EOFUcb5)g zJqGsnZVarO{?KyIvYMLkm?y(wddIhZe{B0RG94-bPbR{x7P;PBf%LaMa5ZCs$Fapn z($B)3idhOZ<+R;{uOm0$iXb_uhgU)sioEa_tY`ObUaEz+lS{2}2KfrER=RJ7F{H0| zLdF!>kqVoE)3KySg|g{ zNWW+FZeH@|fJc$IE|1raH5L!y-O^1)^01#P)pK9)JDCMqj#ORVTGOm07O_EYQc6u z!>P_)lO_{7c}ah@pYRxQK)dZ+?{4}Ye0jZtTa<1o!CBufaew8vW(+ks?-UxaSs|D< z>0c%*T^$Oj>iuk5m$sn)y-iKxuG6)zCJB*fBhl2~P zPQQ`9{T8<0H7neiGzTcR8-9C$X`+`T?Fhk_wo;fA>=Xw$ji?d+SnMM%cKgLrtwnt~ z{YR{k>8&F;lc^9#+mt!3sGJRIxacLG`Qh=Q$XND*&R)cLj*!~7l}4^kqA!8s8ymLp z{cVn#%L7tr0+rj6^cMx*w~=Ezvjc~@LuSd!l5U_9MuVo61k1E`m2SH9#H-mX{bS7Q zU8%EeO?ojkcF~R~12}fCz;)`XcL_eRe))~@xMS?kfR(7;b{e%Hr=gS$(!eSQeeRxI z9}_;)7BP-6p3vc4&wSWjt4~TCX8RdvPDPqOAoWNZjJlz7J$D}8ahYw4sR%J=?X?Qm zWR);_d&OwYcI&nZE1iqMzCKq5fGlVBL3aNwj`umjYvJI>svhKK;+PBiJ1UyK*Q`Y-&E|Ee5yx zP`kAyuS#U}*b$gp=BdBu{7Slp{FpbN*)3dqOmg z{J8pfCEV$mZ)O9&b=ctznU!9$OKTI#V`s%gI-pTvzEJK}dDv2>D@#lE@l5TkS-&?8 zGujge=N|6y%GUa(C;nk5pS%}Vr^Kq3Q;!q>)=n-POE6(gX2+UGPH9P05ih!coCd=aulyOXCnvD%iJw#zOzVFyfN zOajj>7QY*yQH@>sdk| z((-iNoBTU78y#RaR>CdM=UaX zgEtGwa7)4m7Uc9V?r;|g3kCHn236A7`@znz(oG^h z53Bz7Sll3T$Uir_^ZV-7(~u=i-dL#BwHDl0rxuLia zeQVWpMr>=C{@n1-iXowFnhp7tiH~sF7@f3nfb>6c1FQGBRyu6&nCy$_)_yCImNVLb zPP1mel%pOh+QVX+!6vnPi(>4TZeLG7BU(Q=Tk6ny>5ZNB8U%F+cjxQ(`-_9y?v`Xy zWlF`UlA&frlyEa)n&*cXV;n)N(%s*c;WITZy5>{AJTLpSpZ|;(gPbj%*5U2XKdAEG zY}?a8v>VIad=z#qV`;nYja7{jxB8ekyM6hSFMH=28^{j&*`-G)TS;?!=2a0<0XAOX zs4w+rJaGh1y$xcMK1prWwzy2jL*uW9B^%W=a1n)3tkbOBDd3o$XSq{+xh)3-@HknG zr3qssd8ddKjxD%6Mh%c|=A^ZuLMz*PCRipjzWLz;n2zEV7HB|-<(2stok5tCSEG-< zi~r5Cn1F!nQ}b-1f2aWaD>I(nsnRc~`w%&>k!t`i(MHd?ADg9~!Zmu-Ys79Ii?fD= zh~5?XvkD4~$!AO_NxT&$nyU6N2uSlU>OeZ0?@?8_5`pjI#z}|E+j^=-vu>;~<9^#@(5F+Ss?!1;%h&u+W@ z{!S1zFX{c#P%;9A1VlshbM=Mf&WxrpI{9`riO$f$(>y)(+ssCIVea3_rS@#OaKAqH z^URt`XTwB%MQa}ZtL*E!q|Yf~=r(m%B2hvM8Vi4jL%qe?gQ%&D_S{e zy@RqW&4J)Xw9`bnBufScNQAPOu@AtWEmF4(&oS$x(*rM(wI6|9EK;+?RJjdI(DjE5 zn53WQ+b2pKGr+VYqFRfHf*`mGh1)x~03OP!bO$uo-8*Sct37#c>ld6~s*f{=?v=pm zZ_KI=e?M)VHF~cCXg-jx-Lv8XC{X)gcL*AB1_^LhApnW-2-Vj3_zZ@cXh0VJ1&Zh_ z!H4I#L(7&nQ5?#%DU2GfixF-^&!uR0|;Ob=T70wnQ{n;v2Ns^?U+x(c8-ZQyQnMB>aVGd+q%jKk zJ&d#jP#(i6;46TM;SdDD2hfY)hI+jYks+o%$zXJBLU|rQa5c>cJZJ?8fvQiO#i((8 z_~)mH?-AAO;zX6r+4~9MFQ3u+UL*gzxW!Ug@ z`w?Tg_|~QIJ|Zshzl71L zmWY86dnFJAZ$JqYK@bLDl(|?h;1ZhC0$gpjb3%!qqzyDdSd;~ohQ@KTzSvrqNqT?% z(Wj=^0ESb7=tD*(XqTV64R9_Wp8Hiv z_-i6V#^q5;qJa^p2x4I5r7mZ>TEOP%zed9ogZ*}OM|Ql2Di+rL{67Ue%E=|p!Ndm%2@fVlG)g4$fC;|g?NQVxAG9{c2Z@(Q-ZaKU6A?`$z!GG)yF1(2 znK|b;w{X%fm#l4KV%(E2lbP@A`F{KVpWU1#DJA~Rmlo*10YFa@qvt8rhChD*w3l{+ z;rHXkKi{cdW^CQvbga61%QA#1JEHF!~iBnR*e+L_Krd7 z5;eP~{Qa~HgZQ+#yja|`bq_dk)a^Q80C497kn|I{cwp;+!pPlKaI3;=IH3rOwT|M%8fFF6yTCW2oVJshVjwpmQf?$ zl}BZ|0^y5Dn$Ti^TH64spM^&X;|HHONUVdQ>Qq&DaFtS`tGf$39^YZGG()XfgW!Sh z@(6$l76YIyfTZ6`F|l%BWpVrF?QnG$PSc6{Dj=fpXb6FATehJYjA?H=4)-~PCnD)W zZy$i3rrpqSaowtQh2ho1u!Rlb3h-bE5(*+5suf}QT>$RI5C)9)0O&Bi%q;!&jVm@} zmh>$_&8dN>ID{rb#Q<6el7u4;=VAs#e9vP@(ltnk7J$}%57Eb_WsPkZTu)Zcio+R) zU`c37#KOI+knD>XM8uUKB9Kmy52^q?LrbxSCc8TF!$aLeAfhN-=t3>VR3JxKkpzN7 zqU1S}mhkv}Ok*nTUI5{5bWd;LyKcREutQjAy3HB8JRFiFh!LbFqY6kSBLHZKJShVS zdG}tE8VD3!8*T%X4h-=7S76uLUD?u&627_gHDp!-CXmXdKqi4Kf-nR`Mt~a}$ROTS z>0}ix5CxJ^hLRVHc?@J~_pgBbMDm^&d$!!J-}&4eHdp&MTr?@FLNXx*CjAIMGS%lH{d0(5%tdEnMtx30*`e7!B|leB`#j(jd$I2KE!hXAu6vVlyc=sp8A zPe-%?Nz)#FAdx>vSH36qJNEP&&LY=EFNL#WDHsJ}Kml0cbyhfo618z6lJD{}e$_t& z((b_2pff#MK*7vvhdC=;hXU3Re+{*Vw4fEjpG1{!LQ4Ck!|H^kTgs$RYG1GngUL)F ztwN#lVgSCS7t7W1mn3z$NY4WTN<5Y>bYw1fAXi(Uo(m-sAwYW-P!N-{ zDbM+%^-A@eJ>__PtRLhN;3d1=0mvpe4F}Hmo`>sN=*99w%?&_-yvbi}mYu^lN~OvY zJ^;ftfN20WK=ru9-Zl5R0ALC?Q_x*K1Pm1clWe~Qtq|w^&t%!#c&&8(%ED?FI-8w9 z9iSQ^9Qc)gfwKP?8rpB2ULHA-1DXK2^H2c=A+O@Hx29AneMNWDve#P-Ee44Fv+@eQ z^&Y)lzkNw#hAd=zp@jf)egM?Ic*WaYnJS;J{8jgsrIsU~F=zTOc)O-*mGe`k?JesM ze8ZeK02TC_cgm?Xj{JD@=hEVZ#-GqJHN$@?@T-9@0zcR4&+DI4A_~`&?fC!yJN_Ho W<(=gPznjef0000t6H literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/WikiPoos/images/arrow-left.png b/retroshare-gui/src/gui/WikiPoos/images/arrow-left.png new file mode 100644 index 0000000000000000000000000000000000000000..befac61d1b5e2a4f4354814fbc3e141c881b42dd GIT binary patch literal 1019 zcmV}+N?W@(a5(kxBeKnWoY8$}Na z_R!D;HMWAyqBl?G4-l#-r1esvUe%*iJb5wZ;6YJ5_9!Cgp;SRJZqe*!cXl(s-uH2K z-^hrE2C};;h|e?MnSp_MKJ$Esndc>D#={Je=)Va-&yb{7$$BUN^c+sSG3jjp*P?$+ijo25?BDIvlmctFU36)sZ-r|{A2Qx~4TfRID@`#x-812j|ssMB< zWarP#qv)ymt((a3}!A@6*^S&6LU) zpS%b;BH;xd6e;L#a&M0;XAOWiKmdAyDzI^T@!aB6d8v$$LinK%m82$}LL|w=1^@#B zpensCbN1%S*>bitTS7Z%Ls<%1=&lTaFd&*WND?R`z|egG7{3?j<6J)f;-hmbzlg0{RASBEF zEa-m2i_=rzOvs73oOaRK?|?H5rIjhn3f&M=02X>3V9C96VF?IFfRZDij^2Sw%a=xK zJ2ia$f5NKxTJfnryxq^- z^X_826C$7hnl&OF0U7`$k_SZ{q!2bhHUSp(HxJx@_x@eJqgLA5+opNR`SDS}f{{Fs z-39m;#0Wqx84LQI2l!hK`2&5~Z|}eDp9n)t6Chxe!lWRM0f1|+4QwFc_to{d8D9m7 zUAO|aw2cKR%s=fg9UvMUfPsj&(NvGa53jDu1{tIsvdk-FN2C)DD002ovPDHLkV1jrv(24*6 literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/WikiPoos/images/arrow-right-double.png b/retroshare-gui/src/gui/WikiPoos/images/arrow-right-double.png new file mode 100644 index 0000000000000000000000000000000000000000..082ba71356befdd2298d419e50c905ea8f606a38 GIT binary patch literal 1398 zcmV-+1&R8JP)avLs6EsY5k)Jcqh58g-> z(nuLdN_jA-@E{3KJgG4ejSrCYRq+Ry7_SjAF;O4n3E@F3(U?XmfpAMhr*l0sbLLz= z_v~|$nWh)HOrj62)0OY+y{1{~eBYkQ3^6nQO$f#RRsedPBn^>)2#e_L4?z1!;ugkt zZrOR0hG_>B7Svx-dfPkTVhMoF!%q*djGOUOw2R)DPv1YZe`RM!r`FpWAlk`!IUF51 z8eiM9_PFZAr*j^ZXHZR;v9fM5KyX?P_8OHu#wr7 zLFU;^8V=6ubJLapHM?P;jq=qz`X27X-WT?+vXa)v4ZZ9rt)@cM%E(o77)TG`(4Ipn zD`x3)(T)JxpyZT7GgUj5b|5pDu~w{H0lRL8`;lI(715dM#KDn+@zk=^U7d?rpMU(ktXU?9%n8@%Kd=-np zn70F-4Tl^EiVR62w2DIbY8|M1p@{G`f_2sV+qP~)BAG~EymaxrdZ<_UYySR@1CS|D z^{S|#q79^!5PoFlYm?AaMEi)Io<+z&tpkbv4gHA6{o$M2FA;q$R^@=-G#)mevQ_R8xAPv2dfcE5R;f;?@MFi`m~0@GyVER~8qkjIJ z{rLk3!tMHPc*T5FDOIiXgs*S(^9oIeWQ#T+bf2GAfi=dWqDgfJu1S~Eyws%aV~T7Imk9Sm(P8N-@P<{$d~aCFy;#YkHTnP%WSg(wHep-0h7uU z?m6LGkX*tVe;u+@IoByx$M}T*_Pu{AW&vshs6*5AO&~9U+oIs!s2|cJDiKfuU;~z8 zVV%7mx2{j+om_2nj`=-xzzs*xmF$8g5}2-L|3c2)iA%`R0}b;qV7I#Bxg@SS%@tDQBVsTfbqO#Og!?&hZXeFi{4 zcx+%J3f;C_DCNiasQV(HW@nZj--!Hl+07SnWBiu8L+dTL_Ys&Vl>O4B?9v-OwQH5b z{HFKS9G#V3QF=+~?Hq)$ literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/WikiPoos/images/arrow-right.png b/retroshare-gui/src/gui/WikiPoos/images/arrow-right.png new file mode 100644 index 0000000000000000000000000000000000000000..a8267ff09cb4f75e1c37d6f82605b629d2ad4546 GIT binary patch literal 1006 zcmVldeeX=b(5SL>te!N&3t&QHKS^Au&sj#I29`{ffDB$Wx zS83|?sd?zO4!|`BR~=-E zk+1|Jz`nivaAfkxF1Kp-VxB(joq$VdQyYHbTX@3L_bTg#9ZAeFG&qD~ZyYUE`l~l+ zf!(!x(TfpqZ9>R|kU8O}-AJ--Scxdz4KU!)_(7@-?`&X_R_H^Tz(17xQXOy@Sjj*P zNC2H^D5ap0o{@?G0XWhDiy0i@fCOQpI)R<#+M65E#Sipbks(zn!S=u{2@4DhXhr6`K11tWO6 zy4upsnT;Q`GfRI`8}iJi-X=M%a>ijjw%!hjKQX zciw-=62eqzKU#lr(R$Wg(u<=0e0aVc=)*Iv{a@DGPX|N4eMMiBU!aHeQkPRQrE|K) c{(n3E8wCK%v>nDF{Qv*}07*qoM6N<$g4lb>)c^nh literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/WikiPoos/images/book2_128.png b/retroshare-gui/src/gui/WikiPoos/images/book2_128.png new file mode 100644 index 0000000000000000000000000000000000000000..d612516f2a9ab7a50f77158181753ff12b8e6185 GIT binary patch literal 12425 zcmW+-1yCH%(>)G%g8N|!5*&id1$Pe+9D)Q63m)`v2*G|>a1tyD?k>UoaCdhO*Msl= z-&XBz&DPdV&CKiWH~o5}wKNp*aj0(Q;{M6f)rQ-} z%`Wp)f*Jr|04U47*Yn9bY5V$}_G8Z4ZL~Pk*-*1#Z;RhNW~O>|{6UV??s$2vxRI)O zDw<^#^@$ZDcD;3HCCZB>E>R`%Rk35|^DxF!+B2U&mf8GUrTIFA7I8_*73-SJ<2MVA z1ZSD0EgUuc0!#v%_wi{w0!;kX95JP#%%jX9DOBg1y~B6Ufop5$X0794L{EPuj3)%u zQPnyDSEp~FSf6nj#r)>m@MCV?qRjgq0G)e;a9uTWB+{il52x=yhzU^L;k7T_XMlPh z{@tc%>p}-H^wqZ>KY**BmzU7(+{?q7$i;4^i@(cS;vdlbYlPwFT3lS!%Z(k)iq(6H zm#d(=+~6QWPLyDxUv+lUR!a9N0PAG#bunVcnwAA90y7AXDNvCka=$w9DKbb>*tsok zrM&zQH(YT;_~!3@0vKYo|7LZ_`mXo|alZsY9M!zw!h@K?^Vq|%ZV$a}$lNQ$;jPKZ zbixTxap|WG!jiMr%hiLlxQ;7Gxc!-F){Te7>}7lp#cK5z#S)rfG)vhWMz9B0P+6s8 z*2DSpVEpsDAgVj!J0Mo#n~f&+mkAtj1YHBlV_Cy0NBiwYWWQ#v7-Hox_~Q0l3{$4$ zgUNXLp39-|by1TVvkCLB;VeeeX@Q}Qoyqx)tOoz$b8h&%bx1~$q-J|(kRUL@vfrtI z?ly2sIPeI5FvZ#-jOdy+ug2MwZ}qbI7-ZPkMOAaasY7UhmBPF>*vIW&fgQP8lA3lV zXomK!)8TdzrmhDEl>)5izo5EGz}$nb@|`q*Hxx9 z6rUAJ?zD9sy!`6Vb(mui0Nn@3gI)u~wROB&_ZktqF3)x6bDDJ0 zh{?A+0TsMkfr=vklFz1xad+iiMt#+E%?lUG87a~H0mqDB!V+GDgXJQ7#@CM7uPBXS zf~e1zR_K9$&@H0qyjT6s+BTzgi_HQ~u1P@O=|+My-Ni9w8$OuTIq!g|Z?8K4PGQZl zltqFY-<8qpGnT}q3)CW94Emg(7rL<5H39g8Y7?_T=QnBQ94M5w{qeM-|Glh-o`FQa zZ1%Jy@gxVT^T4^>p68n-&08T^!l(@j$cc}#rp!rCTOvCC7n*rc5%odrVkP=KGpL>y zTMcD+;E~>OvZp+G&kP`_uG+t)QD@{S{RHPZ@k3nCwM$-ZZr^5OUnURSleD)P8M&P< zd1-g^nd(1bO4zTcPCk&=`TDd?SK+g5cQy=T3d%kjg>7QF(k$egV}tbvE4K(Nf?g_~ zQqHIP<8vi^j^UVv0khsRu-udF+2LS67)dWy{|#FvJ;}p+fRSbB{cNZ@csZ*}0OGPv z8TEa|Y^I*ooLz61d(I413WXY`D$=<3Kb+8YN?nhM?<7^U-3+PnwB2d!D4qIkFGe!M zKqTS!GA(R^!h1TC?)ye&LIut?6azGMs$on_UwJ>;NXGB%fz{Vs_3l3*k1}Sbf*k=0dn!D{p;7 z6zJvXJt61|qCezcUJd_Ca>|DXcZXio4x*zeO3~&@-gc}uVbB6{82-HwngjR&!YB{p-X0$Ik0`^(cxF_r-Onq58-9u!OChp&rF??B%d~9>(r}sYUk8h@xyxaV7v?KbLcV_U)>l%hP<7fd;Mr z*Ih(c>2^wru}8oEuHZBm zy05QP4b4ag`qSPCcT!(GA0Mob*JFWkT!|CoR#kUpgM)*A9P0k2#m|qli*ch+B&szy|8!K?5I&@c-n@0EVVBVM zM60Z!O*kOw{W!&UK_@MNv%D#ah2FpdFkMfvU0Q+ZcD`B{?>x#VN^x2W%-8udPeMYX z$3cb@4lJ^FyPaf?%bAy+tgDyV0RG$Rqtky1XM7ha{LE=VcxA0*TDQcV(buk9IE1Jf zW`)KFd#X=)F!towpevFC)Ti*Qu>??QWr5FLQn}Kpusy=Ya!7ea#pUzk+2tT>?)q1H zfFBCo%sT8a@fy;u@;CAox-13Ue4qmlTf zbNn4ayYWJh!WIo9aek;DIYHbIKnRWj-`eVrf7#zjGw-`a(8F=Atf~e=F$pO_AUhkI zLRP?uSEfdBX!+5|n#oTwZIlRcTe?^O8_cAcHJ71PTTN=1XJ+RrN4VVyrG!mXhOyr{|c3*qY@aS?@to_)AAeORN{3s&CVU(Zn|UeF;WlGm1WJ|f%y@*XY`@7or4 z)QlPkE}jY|cChg)et2*V@V2KCl zJ>RX&^bmEu2#|^Ltyw6Taj?k%n9dFET}t>~MLE=oSpd6u<>ow}jNdS!`ZHoQtX8eQ zA(F}asa@Uo!|mpl0EfSRKFzG^f7Pd@~O)K2t88@Rcqjj1$xF~KUymSB zl1H0tR5H_b8(>sMp0j83fYM|VcYps?rI5J&j8G)3-lit7P5t2d8J)Jf&{18h`t`nO z4I5#>eS@*g#Kz*HK|yzSB5jRF3r)0^La1!Tt9-sG!Aj2Tof-Wi!c9F#yUmoY`PM8J zw`j=>mTEE#qD~`;gQVddj9&o2aP{vQhwrhmUtXROVLU_;jHxyg&6aM**$7E|@7QIn z${OeUwug5a*?ke&r|IGNiwgvmHHW0`wuZ&AGhkl2)h zg1sEyVTG6hm9P>A0U1RTjzWSDsQ z1xb%l(p=CgcPd5zz9f}X1O-L*+mcBNHQA2&G?q{WMmuc?8Y!XAr|P8){4?+2ScD+H{o^v}u}3;Y(z@w7Osx_# zB@kjkIBh9gxs{?vlk- z85p9l!^i-p1>pb7k0E<-vTQ!YN3kR8heRn zk2NZQi+ler(%&8BN0W|1Uuf+*G50;h=9{~_#p6Z2)Nr6gA=hKnCBd{erugLc;j-j2 zl<1CCgXf05Wg*$zDvyxZJWStK=RfLh z`QNaFv&Y({lf)5l2FfqC&6{*l=h=44iQIe=^d*OinpW3Dov~P2C3_D3=U(pLV@Wv( zhP&n>?U9Aj*^v3O=$3L`gzW*e=ylgW(@WHPF#z8j!tW=SswUQCMn$`#cGyv~oOUvx zU0A9zZ^~W{6^u*SIJjWeSo(v`try}56k4z#lq0oT7nEoaU!QVhmCxt_yttpIZw4Iq-WMbeww%%mfh1_)dh96dviP{z_hj(dP~<+(eh~8*`(K7fzqQud&bWVOW4v3 zqrlju38;Rk#^7JKMpwK!xL0!5qcktgvCm0uC7Jtwn_E&XV6i|;HmpVMh6+T|q!|=2 z#N+dr#a9EMm9K_2(de(+XT_oyL_T;@M&PgAx~pJ0F3}T(_;~T=kjG`Bmf1{v3>i#U z=D0z#DOMSz?jBd$&5Um}Z4nxeuBB)noEr&cdVbw96oKCq7wx=1ZEU(%@tBK|d?9o> z9Q!ZOw)QQcUqJM3<#77?#rxFLTBPyq+h~bV&SZdSViorC7&XO!8^+AOrEi25Wdv!A zJjZRko9`299I3hONKVhVn&@`R!%Ql>gj0p^FW1dIoAks$0o3bnqM3Eg@ll&6GEy#6 zpFNAAHhkj%+(DFIThbYlXun-u4cGZFD;NQKZpE#WF85CwNibyXebXP;p_r*uaOMJ&EFN zB2dTVR{gvCk`1u(>j}!E$M$0fvnTxL)PWWosqea?b}~^!Zzd$VOV3z{vz(VNxlE5LxaHG!-5 zjr*-ZF{RfbqZ`Ggv4fE@8Yr=q^>YK0P3 zE0tX-?@@9v#eBFj6O5n26uYyD?VDUG^N-cV6QO&5dd40oAk0z;Q3XqBib1oi!dBb%G)2& z!1#pH81(%JfCa;A+FbtAudAKO=WO3xozifF9Oa*fPjtEwM)&muIndslRYaL%&0%*hMgZBqmQn(*>@gbql{dgv$DQd!{<^z!pDi0-$3Gf#Bs=R}vLz&gg0?oJgtzOn~iuz1njKfO1ym=5$2{XTNr|_sjNn z>QWlN5SPsJl5wkXZvMu-El#Vlrx9@)wEs+H9h>V=!{0T$ZzSpc;@!eShcAjfOfX9!(7Q@09EYV{q z)jUDJ)hki!uT-D=)WMVy>9%03U`tBF)D$e#6hNbITtBGdwU(bg&e{NOB#Vf><**<5 z32y<}Rq$WZlp7a3FJHyx+rvx-~YA%+P zH@i4RBr-XBRq(Iw)|DhSSn~z{H25zfNX_7!hertPl4gt?NY(5<%vz zF9Z**Jag<**+>vS(JRB@9VJjF{%VV|Pe52=Zh-Gh9ABaR!3VXB=0DylNdvCD&&07#Z@9&dVb4-#}s!@9Fe11zkCUG(^@H=0m6hTc!j&4+8bf z20`OoZOGhB1Cn-oVS}xFM8*L20susU7S_Zi>SQ~#{AfDpm4rZeO*BROtMH=?YpAdA zbqNYO%(m{-h3fb{t3EdaS*@(-Pd)1=^3D+|uj{%eQaFw{ud=l2b3ep5 zTGAS~W~FSBT>aEft$Qd8@X8M5oiYogxpD7n+qRZ(_3x?kA1|$`uD^tU;xS#AhY1d! zP;p=_`rbb=0kJw}4$@aV_3ZPZD~H!JHKV7MZj%+S*o}n(`8z;Ozkc)zMTRc110YHy zaLT6tl$dD49PPBQkkli(Kudy4;#N685C;Sh5432cpy#oV)rUQV=IJD_E8?&vPQ?Fn zwt;vy;Lq`WMz0EI`Ooz9dM3U0?LF$4h#Ot7Q#MO=HZX6pi*CJ{i0KtRUMB00>v5%J z3M_iUzvsXIXPw$?%e;anOBQXJ&t;^hsRqV0SC&}wAB|#ZQIMPba%RDTincQ`wblO551K>-U1&XRd}Mi+H7tYV+>k)u^sZ zXW=JEWHJsx-8Gcg){Bztn6r$0vLh;tVZWS_4P7b0<`nQ|mGeYaEac6Sh_ZD{|Bn<9 z9DRI{ANAnZWLJ?rfk>z}>Bb>_{ImbgA2$C_mBK~vR=Yvb7hs<%eN4$H3JwVSSkHXM zdybFzMtXKZPO_IXocXjgeX3;OLvOtk5=*#X)TSTPIB;Z+A-EucBflVgraQkR4buR7 z;V(rFhMxeA!G<}XOUmuQnW57zDp(|WEzM?Ndh zEY&N(yd3&CXh|nnieZ=#D+KD+B(aXh!ARuEjCvf)E}>dN(juJaDtbMfxB6K?bhoN< zc>qn^Oei1jAuTaiu;cw7LTOt2c+$o0;$#zTl5oCWnQ4gwu(Gi+QtL{N3utrYO&ewm zqa=c|eXCsLjxnF9m)rPgB>A^(%uh$0ZmEY*CPX8-{6BmlRQ1<_#wWbUyzDQKGPbIK z>itaDdqLZScmk;!P$kLb$n;cqT5zfnIX4}_-;Q%wstrC%m{>M}sCfT!e;rqFHo6D( zu_e+q9p~J@xP%pE4`bOR%4bCDekpmAf6)gK7Zv!8aHcn1s5aTJGb{-zTeJQz2n$2~ zctu3e0vNS&LmBqVn22H6a*6&Gx)&Eg7Xczu$Df5K(Pn7%XpIwh@?%bvd$zIht~ zsoOIQvy>ap#?IRB2b(`~IW${5jc&3mH6jBPE>uZM^64GRD45c=W0gzNSR|WVXz|Un zmEWhzsarp^$|=%Qu{ROrN#0z$snqEf#qT`za10OwO>d5>Sfi>tPaCpI1-zlxoR>bm^V3hbm}IPZ$$B-cuW+I(yaFPx0aTRHc+IB1S{GOe9l=^fb2u-x zXvsFg*?&Lvqm2$19~DO&%l#-SbTRkS_x{2!#n)U!EE26X1D1U)k^$4 zEkx#{D=u=2u#rT%Xe|-;?DD=uu@D|&hssj?U-3hR6gwHKR!U$ecD*H%G-82;xmxED zz9>os-ZOu#{uU@=lKnntg_4PKnwC0YA9LbR$g(ZFb9$I=oo_xAS=hyl?~=5l^=3A4SKqJ9+9l$_)sp1AF4R9bu)_tQTB3p16&!A`rb9(0Bc6aJ+4GUy&l86u&7-?#XE#b_zoe0`TD%Th|xbnLZ0aB9W0?Q<{$@igk03eLMf%rjLD0)prT+YOzSWm_#WR zj_e?2z;zrSuiXY@2w0|EMlRc1#V1I|lFc79eCPww#4sG-^~r)iknSH0{yMBET;j|w z@jh}cosq1J)Dl^dF8U+DxBE&VMBxlSH^)=8@_(b{_qPL zk){6b+15Vdxj97how9W?I?@_>raW=B@bXp}id1Idl`810eVF>cP%0I#yD;Aw^9tlB z&IvX(&yoM5FZ>K1@B%#~G~(zQaI2)Us7!vwg{o z4-o4zqa4!+ZJ*S(S;1JVxo6>KJYFm>@*T*++`%j#ojNFOc!+M79cd|jG$nh9c&>@3 zxQUZIi6b1^q?SuJU=||zSJYw68uh`+w+Nyj(N2j%D0C z&A{cXQ+_jj(MuCuzxiZ3ouz@S{&9Hhq#4l=C3K$uVghFpV(LP(&T7mz^ZkI-~!- z^pZnlh>>j+^?`q3#Eho7Pj6=HImt6U>tNw!41g$c7pggvg^gRZZsysK|Ax?Bnb|t{ zr+${)+{o_tKi{#TUke1!aJg>|*gv1IJ=u|7zLtP>*E=~H-;7q5uI@H-r`lAx*rv)< z0il)|$0fczE56H(GMrQ_3jVinXB=?U6)NqzkSmAeZiT&(ElXZ%YBXwvTCn{OPXGG8 zh<;o8e6KsaB-?&eGPw`x~MRzACH*4(c z=(u}jTkz$7%XR7<7%$s#EdzAz<{kH>8?LT&YPp@OcbaY;LdtDhyHURqyw-KgHQXN0 zL$6ve6bUfB)d9_cowRO)H8lg*@Fd+1{7($5dAo$v5fj5yZ0`Z%vv}lV=p3*$#!}ZSHdnE{9&<_Yho_8B zceNjrHLz3q&hO=Qz0=lLGtH7<`uVu6tDDTC1!Dz+(E=g$B-Z%TFB>)SO;0;^$4fy! z6mj2GEn{`OCunvOC9KTE0}LK)27$&gQ^Oh4Nup|?Vnv2vtoPG#h8<@vDjP{32%&`^ zKuAyh-ad$xk>jILwigH2itRFuUA=46LKjMxLQk9c?cIH@e;>lwo2uqpYv7gob7sel zCfjxlHrJdW{*<5}xc^@~q3?Y=Pk8%@`@s_xcNQY5f+r`xy6{<JwHsZ{vN;u>bXazsb`k$?00t`zpPkp<@?r zv5K1d;+MF>1_+JX#?^0Qb&H$8i!V>2Okka6UB(|bmg2{5P&7_ zbvJW(1oYgn?S7w=T2h?83GP2I zechcUvJQ~?eCsuxzzbA?HcZ_TK&2u`w+NsP`3pJiYYhQ*QR2dBABs4f|%QnMS6Dzsn*Mk!!#_ieide=gHqsN9W5(pYU^-xxSw<4dyZyQzJrT?)_CHc_i)0O4%-I|f_pxIA6Gg! z&N^Oa=5qTnBH`Qkot8c)xWF5viS_5xp`X#?2YVh*A2-`{)D9_ZC2=Y7kA2e{Gf#d` zGjryJD~|4$v+7caZM=qZ1gWOGsL&-&(AIT_Y@rEb+HfLl?_7d#&eLx!(``GMm#r-R z7MrorYe#h~=!VZc=xfB{AydjBX&HlcU|H{qIAKV5VPRn&^X_cuK17;mjiJsznma)$ zk8I!Jhe7bF0>AB@V1`ubXBdNoW{|deCd#V3)Y=WK<&hUJKMn67{Hv*pwDaZG86&cd zIqR#nC;bu>m`1_D^QF-vS!3S9J}}!oH+yUN(tNVKVcuM#bBQNlK+hADvxn4^e6LQM zoq4RM1i3bvN+7@6fg_UbuyA+K<@LR0llLBV_#|b-0e?f~K(;tx7bYR7{9Wix2*|Z$ z76-;$ljp7^2K(iSUJq=SH6Qjyi)lm37lef7iqD3uV*uXY2j~9KZ{*W~!_`QQqxI#q zh4yxB_oguO={!AX_^G>J@0h=W&Ofvx;Nli8!BfRP?%qU;48W8Mn#1l*COj|YVP!K8 zt_NKo+r@7A=Gy<48Y3P0ps#-%pL7vn+=fn0y>=-%=bXdaL5p?mn_5>lhPy z;(Zo9d0{#+(q;v~zayf=d{*2p=%Yu_AO+_0ZxJ)0g>hS2+-dBjI9QB^rly5RX-!n; z7q871$CqJRX*hSMIv8tZ349gsVW&KD{ON}Y|cgU+iAenf90W!}UzAV0X)%$7E~aVG z(byOF5~H?Bb#?EMqQ>LxnH{poU}R+E>e$;PG==E*X#ENO`i@(=zf?TZZ@5o7W12Mi z#Np-!jEq9k7{0L?6dM|sxFdGCoL5_COg@^LVu?wVzROoV(OQ1*aL=#PJylCT2PY2@ zUqu!nX{NPZpn&7>FqCK(z*5WLLLEzA-wfZjvCT~;8LXSLHP|2BVzv|&Yzwm3{y(M* zF0e}^l9Gpa=xKg4&PLukU-YKOH~QYY&!(nPX8tH5!6r}5G-(MeyWIbmFE9Olm!|zr zzB|7CXA3}xcwDfozgqy^-(=YPEKW*(K@|l_-0BZBNTvj1RSLVFo+OGjvVR$sy?G4#n2zuvXh3przz>JO^RIj-9I|FdtjV_wN2T-6v%B)_RCpu$+a!y zpNqS98I>7nh@#TJQbzl>UWT&b?1sIF*#?~(HGoccw;eQ1wU9WTUUIV`=&^yssQmeF zK&s7kZL1!KHYd5?n)*}^zxwG)Q(qxZ;8+=r0gW|Yd)AysM*KGeSr(US@ z?@|J(>GROF)YkTB20iG~uQV&|SMUo-p;K~lmbvc?rHq9>-liF!z?Hixgl7@^94m9H zQ}Kf}t=A&^;{X4B2#TTN;*0#cGpW2{QE@R94NZ4-Y0hkXZ0t3g8J`Sggh{)9dW{|I zA}RMN3^G^#)1Er$tUu^&tM^_};N@=aEaWJ*iDCWJL7uz!XVz9h)}gzkNn#2l;U%#rxo6^=`Bw*U+5OBb+%BYFnx z@EeV&c3R(Q`l%y<nUM8c_*Cbz9qMjU67G#VHmli2iEOzZob=&{(}w$=8`V;h6ka{BU&bcwYa| z@viYjq2lNS?)sq7$Ex{s*McAo=0U9%W#$xKPS2_-8rj zrTm*1&okYBob@E~1yU}e{s9gkhTUx{B|$aKwXKgkap3X8~5tJ;KF~wg&pkLP*d7**x}YU|>qtb8`QFfMlA@`-!?`!9Yz-}(FS_Vi9}`eBTTKL7gi zxw)nITvDc1+G?%ZY*a)cQf2k+$`#{$%jkQOp zfGVge&#cXD8e_iFDcL!IUa$Ab`uh4ix31sO?9DNSxJY++fNDTF{%n9!weSLP3V8Sk z5KRDoBuT>Eot`POz`?MC6~RitiN{I6E5r-Q%<2b=A5L3{Ci90hP1(QG;-C7S?+iOQ z35W!&1jH-e2gc5`{7UhHG3F`2^+u!7UR+#cZ?_Yy6PyIBctirK%E)@G3(PLhygnU% z#IeU=v)SA&6bjtC(NCNN9<`M~P-Q$8oDbxd^QX$S*|Se70NBpua_raJj2^nj-a#2z zVJx1=z|eWK^hW8^lK|iK`+Xf84miB!yqg3VMTWsp5D7>CC!TC6eb-Eam*vk)i{k7{sT}|5s{lA1X{m#V)21|9Akjk;6bezMlmYxU`GA2DCd$lDV0_vcyNUt{CoJuc2(cC~J;DM!8yV5X1B z7_*Y5X|r4|N3VVKvU};pwWL;gRr~ilz54FXZ$DnWdZn?~y%LnWs_IVyL>n6$e{F7V zo_=tzb@TU~?Q7S5x$*5_6zah6q|1E_n50?)P6HV*oa}hO0^_M3sj2|{3kKzIc2q@H Q#sB~S07*qoM6N<$g2NPdIsgCw literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/WikiPoos/images/book2_32.png b/retroshare-gui/src/gui/WikiPoos/images/book2_32.png new file mode 100644 index 0000000000000000000000000000000000000000..2f24325488f0a5c7b9dd2ca700ee2cc5b37ac624 GIT binary patch literal 1858 zcmV-I2fg@-P)}Hb*3Gv6{V)V#Jj`!?=Ucn_MlxUbGL=tQJ<&c{bo(1-)uHJ`zx&!--52;;@iywq{{)X-PxXuJ@1)(%*G!A>t#&1kKNN6{<|ci|Ve&s_S|)EBhY z;b!Ann*fS|fq~TLzVYc7b32SL{_yqhj&^S^?8+3JY$=#zsy-8gDiTmlazO*zo+x}2 zC<3!vCLn}xfPLw7`t#3z>d0rm^zsXjclPG;mSu@#Y#Px+rs_A5S}%je*F=Lvfxgj> z9jSu(oDkxVo2k4^KnStx(4j;B00x5~FtVbPY#}YRp~bvkVxc*Y8&;?{t0>eeuqA+2 z1?-$9KCtAlm;Gdg}{T!$w{)=EL~k)xUNg%c9xOj!*tp`6zp!Q%?Dhm zTv%0YYw&c!z_v|-Afj)iZ~*uS@b*RojF$VU$;rt@$8jhW3i!THbT`Fd_5huB4}tW# zQ5{1mjZ_+?G)k%Ed)e}=wMJ@9erGzj?WvBF$vV+ifpWQAo^TxJs8Wh%v&r0Km4A<) zNA-F%BCkc_mC9F?h=XXGCXFD%whV%1#P+8-gUVo6G z!jt$>uuA^b;K{v)Fq9w!Q4}GSrtfe^fA%rw_(m=mk33(wfB$~jwr#>NBn(5QFO|9W z;PM)uTfvtU5gIJh!1tr&cQAz*c&_^-U~Yv#+4ubkDJ7<9;`=_8a+O=>r`J?2Tfmi$ z^B~bk1yN$hQXqQ{=8poowgi%|*S|`o61HtKFfc&9UPsP5t9)LMjAj#FAFj$q$}#bRxUcwR?s*`!6$10X#N6B*rfHH& zrKr1gX5L)fP=4Do2*L;{)vA1$rXUOzQfoT*rbmG7Z3$?tCGbYMT*fdAy1KgXJP#|# zu386LNjQ#4!w*}687qVq%kS7b)5ZKy`uRs!#q|^b_;aOFX(oj5eV^L(VErI!kW$f% z)GB+F(jZ#YLeY1m<0Ox40X8Bqqm-KVJP)N5VHmPFU8nrkS{pKsLB;jgEKas<;x|`v zqcn8x%{&9-w?d!_j4v!KAcUZ&r-w$PflYc%5W71v_(9YH6och64t@|}2m@1?ScXYq zIKR`%noqU5ur7gQBl()^y33o5AP88zwz|@kVdJoN86(ipWi+&5pW&|Dp_iDA;{-x>IsQOI*VV=ET-bN;E#0XSxg zqA1cVH%XPU?3BAWe&`f?pV^Q1(B;hZt5H*7B?{$*}VTy41jS^K=FMoO<>pirqzO)j7s4U(mn&`Hw1> z|9k1i^xg86nOXNt1lNH%zynk(&ZY+wA;d1=Mt^^QCYQ@GG&IEi;e8AZ?_uQeQ3m=S z!@v-vNcgL??fB(*fxvGB_m;x36zuj?c%LEb<-#&5T#4E*Ov3Bm|;cnVwGIwIxSkSX|1EJ5J)8?vOp$j w4)L~1uriG_5CYAX7A1XQ3-A&l`KUer1FZVWrF~~N_y7O^07*qoM6N<$f(u}TGXMYp literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/WikiPoos/images/book2_48.png b/retroshare-gui/src/gui/WikiPoos/images/book2_48.png new file mode 100644 index 0000000000000000000000000000000000000000..a0ff7814d25dbd0881a518c6ab206add4fef6933 GIT binary patch literal 3265 zcmV;y3_kOTP)1<$xD$Uu2JM6FRqi=jiQ@H%eq(> zOQb~Ic9+Y&&3)$dVRo0Z%Oyq1ZbmrEIWy$!_x=Ch|2vlvQc8ZE4Nw5%n=igJ`}Pn1 z>3c7|^z!q7@vzSmy@&q49YP2JsPj+m&wS_4-}sg>6Tar9JNw0iv!iX^DOMNUm4AEl zzrPaXAWn`bBX8h;XGyN5*4dBnOLNQ#B1Ls2mMq3 zzIf`yzub5oSllk2haw<^Pyp>)zyIy&r@t}(x?c8Q&6QJ6=4Oo9PO56&urI6woBSF% z{K38Rt?G}zd-gAYceg8}EfMJJc>jR|`B(nvn=ht!$=8aN>@$T~b62XUX3bO@fJlaX zyz&8dXsv-AJYFU-lemnGBL3rz)Bo69vj0{}>28OBwi#f+03I_<^AFzqhd2K8D~BE_ zXQz!~$~4CkU+P}P3arh+CiBui6@pzyCJ!~2>@4u`1bTYjrR)0Z#bWUl;Bmt+9^JQZ zpJtX6CU@omh~%0+A{o*S8Z_NHx2!Aiy&k$G#bF7_b>u2f751F}(d{RM5Xa>fJko47X*Qd5yImZ|p?0N9bW{?_ke1h=>DOs`b=pCLC<@1dmHp4LnMhob zu;*B5x0Y6p26l7`@E?{yK?qSyrBY~`hG7^4K|r_LrFx;m$F&dX1gl7*A)xUgkTO~$ zF^q43dK^*HP;q3a?K(1fIl*mY~ol8j+v34#cQPdkr6$m3q6h+J&EIa|s^rXC{ zV>AQ4Wm%m@qk*PrXqrY8McB5DWmy!iW|%*Gh@w7)rWk|Re%4&T4c&g6hr&O;nAhsV z)HJ$w9Pr;bR@!^w?dwN?MPN&II+_7148!a7dL30&(KL-xsYDot*tU&U&oX7qq6)n? z7lBo`!R_viF_DKzGMtGhj(j9z`DmJg>jg+DQB?(_Y~-frb4Q8YZ%fB0fe!GiTCGN3 zMxN(k7zUPQ(YWGZIbFIzo8|5eE;P>Y$;$CHpixpXNw6dLdVO70aQzU8L=h4{2$?-x zd>Y7ZmB5gMq?A$!v9PkTQga+q?A})n|J@~J$C$dW{jf@o14kjljaU2KBvhZ$+ zfdr%!V+xZolIiyu^bJkHaRU?qK@bs2h$1M>XLp!W#tWmt-41~&@JXZ57}P=EksQY% z-7N9M#4|isev!12-N1E-!H$sY-_z87^d*|6;`+hh@6i-x{~yo21f(C9fCcj-K+%rQ`ZT^&u3P*qiw(v7J89 zPuCIXY4}>J)w^+D+=jHj9HQ?@IV#=&6pY; z%O_>1bZviKeJF}R$tvc|;leQ>^{@o0!0FZ1RWwaQRaIQqMF@f8ICwYI2U=t@szYQ1 zgkkJQQ53C{Tzp+J{k8nlK<+^*8cRS*=>s3EuC99Rb{kcVGZ{q@j^kjjxGevCwfE($ zcb-HsC+kDg6g)2^ozmz!!TS1$Vw;U5Onxo57dXHJWVBHR0G5LwSZX$#gF2{GDmadV z<2bY~d1EY+A;}Eaha_#NbZidu)6EFn2R>b0T^$fm zRh2LdaU6$&GBw!R7?uzT;K{6jM36Q#+FftVL=QAo5ClEqNXpOVj{=#8B~S-`)oQiy zeScu50IuueEJg&b90r?kozdw_2+0HKI@_PH)g5;LV^JHde53*j6h)y>D8zNpak%)ew+B<`_0#7>kxPkb#8U1@zdz6=vt;Nhju#AEtT><9 zt!C6CY$Bu0G61oRt~Z-agb)ZJ$mjF8u8VEklx9mq5*VH94{S98MBIWfS~t-3`-))5 z#YidI%yWgW1LhYYu+VC?fOyRu1o8CObzS_MVl3Eo{*NS`(&^a#hV_9EaRHBHa$;ZR zAe-3fg9x;MpLaSP`dJ9W5KYr?U6=Nv&HaaLp z?S|`ItgtWp72qHn$Y@gnz1@McQp#ql)f&iXYHAA4^Kc!P>i>2&8OUO=Ia8z7u-Cax z5^OfD(Y5@wDM^27QPv6*PiBt+`om-ZVi{fQbUHvRBPk`m@8fwMrP-;0>uj_ZmJm)# zd6{skcnnYoL)okK_@5#a6rnKncy>Q9*W1$EHUS&>X%GZaKMPVy3WWl`?_*URF8%ZJ zNL1Ir&XzKCEH7cJYpoB~G&F)x_5iCWLP1qx@TyQK?9I)Z)B4y^`GEv_)9b51!?LWw zl2Ow%f*`>6eRAd8Agak(scC4KDUFWpC!#6_!1`eGnG}u__OA88tAoC&rj;EBW)3lC zvA?Bd8*v?6aU7@AAC0Aygkgy9`-CfNyU+co0!$UsxL!yUf+7@RCltfKCm^3OSZ%o| zLZ$yJn$XB=1)MuR?eh&;TeyD_2)3Pp-cbckc%Fx4SwvAp7={>zf$#e?FLr5vW)Ddq zlhz4)3z%dy)nxR0kv3B*jw6{i%ar^XGS_ny&P_7+=^oyE{4GkCLNTeb|BGb62Yv$l zrQP zOgF>x`@X@mFF#K{pC7Ep=XUL3;^xX%muh#@#ADO;2uLXrLM#Jy&+}$X(5(biD&Y-s9q9_UiFtrSo^iJHnK0(z-ZL3r!_VUV+ZDpkn%G8?&05~GQX2-HcL94M%Q(2-MGT(kIr!N_($Qz z^XKo?THTvBZ&%N?tnhte6S*-Oeb~k;rk)4?J@9w^-Rm$62Tj*CW`1jeSKfMosZ5sk z=O9`E-DRHxyPo67Q%A{UGGsCta=9Gs<_e#kKg+_I(%8QQeNC@Jn zRD}?g$;nBI#UhVB`Y4r3g*|)rP%f7#l}gOb%`rDO$7=m9*Djpo^vPdF7tViLtFN?f zUip0KT)pkT4_qN$G}VarqWrCFC4LzM&P`8GS6+SfRm$Zug+hVZ*;#h%*ulg^F{pN{|9eqf=&tC%?#Igvs^Zsiq$F|=S3n2~xZy!E< z_}Jykm+!XQ?aRPL;1ug+;Q>im$YlF6$ZSZU=Q=6k(N9mb4Dg%4Eb;q<`^1IU=>hJ) zSxJJ89?-&G+vq&ps6N&a=q=q+#Jj_}UP~vM*=y+@xFGR`QKG+53pP04=)T|k8H^+G zKnW%OFNB(C+Q@nTzS3(V(Z&HBjr3^Svc&!mdlnd7zU6%@00000NkvXXu0mjfxAjRq literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/WikiPoos/images/book2_64.png b/retroshare-gui/src/gui/WikiPoos/images/book2_64.png new file mode 100644 index 0000000000000000000000000000000000000000..ac460f5fd06a0ed85b7f0e1cf7905544ad1b1a79 GIT binary patch literal 4703 zcmV-l5}@sgP)nAr5>9BG|EMiKG^i;x;73 zowIX#@7iAu)m>A)%*LS-zrpLSe)YPhzVHA2mwHt#q?G(JHX#In3TV^QyX~1hd#p2W zyxsy@QcC|x{U7Z~9q36kA%sE<+WNyk`o=SdU;5zhYNg;KzTMjEM_%RwKc2bqPv8CF z*Mtz)o)ih<|5E`XHnR$tU-;syyI%Ri$G>Dwh|ffJ`x)P^k1t!dvQ1@$2nkXm8m9Yq zzwzJScWVB(fy$FO_y1D`bO0-W@zTp5Dg4D>edm?Z)7EdRMem@WYfV+Gck*?8Nd%FX zd?&#uL1tZZ`grlV_g-5b1L{Dy({p-X3Fz_T-Mh2j{F6UEHhp;PD_X%n9_HOWZToKN zzV%S`WE%hp5XBq4ww1})%!$&}d#^1Y1Mc$6NI=(*bzRT=-dBHr|Nawue#aE&0(W{NY`s8+OdrXqw` zlXYJUWx&n)rIfX0KkjwG_6&Ch_MR$Fz5S2(J`B9Y`$0elv;|~40Y78g_MeZBkN=us7`vsEW+s!N-ELDT6sX;Daa|YP&<7+OA!+zkYTgPJe}$U& zh(P+ATD9jWslh?AKxl&L6UAp||HByrD(oN|3{!vseErm^Q(qTCP_Ngi*Xsm9fa|(= zo<|f&9^P1F@4;!Llr;Pb6@P`Qw@l4nC5(bi!S-9V2dwOylNy(RZR*UNEbX5CkA>sF zZJsazSw&H-FbuIQ3r*8dRh4$TO%Mb)j)UVkTsnK5>f{}2-YTIC)&<%FWUF9@rNPdN zt||Co$mEH_v}!3wLMQr9z}+6~wWbUi3!*4$tgf!2C<=bD6)7Q-pbCw$F~L*0gJje^Qp%qFk)$&g_bAz3nN>H+8hI_rdF{2Z+<*V--ci2=IYw ztyZJiY@(`a(p}e0y61VA_r^K-f#X=J-FMcKkcjKm3yC|(-j^W+^as4&7@`V+1pFY* zJVLCj zcj~jWf<~XjWuF@ik-3z}NT&A3J!9#K^`(@UhKgF$a^+{TF93F@K-)P1ozil--ELp0 z)oMKoP*s&oCbLGsZJ!|O4Z!WN&0PB~cN^FH{JGcf*MJYsiTdUU0g;r1VN9T=D)>Q! zM6&B>;aQ+eT&!)otyc*y0q@r9^^XKWkbsY(2q8og2)$~^&09CICv~dc3Kee!H*~s8 z4$a|xbZ>Gk5GT`I#-Q2sI)M;0O`+M23&5!ljZ9tr;oQr>9iTTIZK16fJr{wq)oNAN z>-8Q5=(>*Qc?k)x{mW@)E9aSS-Ny;q>q@xas*&8<93d2lAm|)3W2&^;ezL!OFgtA) z^lmoTF8*~1Xae^djmCUB4s=~W(=>eF$8}xIR$)^KN9p)5#2um`bGoTAYiZQmE|HX| z3PcfvDS{PUQ6^3nUI4N@h8qkepc4m{qA0ptuh)}$KvmT^`kQ8w3Diefgs(DcPOv|J zh_X33+^Vb(b}%k?@T{2-oh8F3oyCwThg$UfkMPmF+0TLdn2OJP-25keq@Ac~^3 zl-TkZy?21;%P%o%O|a}NtZVsU1<>$09qZdVwN~u=rmoO-gQ05Me`cNfNLG zyjic;gMK$Cl}h-&kLP)~uFKWa?;)k+>goleC|Vb+l*3$sJ~GxKzoLjF@2jeU>xTmw zL`pDnsxkI_;RtaY*j6CehyWLO=y~4VMx)U~fDj^a1J`x2MV^J$16DfLU%#{+4t9VL zBpFMm*$H+TQ>W4P*AJLT#$L!D04CVxBG0-6bjrDHPj@haCL4c5iVKmgWR8_$bBoim{Gr)(R7y+HO1iaN~G)SjIMN!D* za%*njxV-y=`+Wg#^8%;e@?A1iMG%A$Q50cYDvg$(n$zoAx~ky$A^E+TUAZaqdE%<@ zi4t(W*=#ypH|V-TJ|AD@byc7>txZzlaInLyn$76c8eS(B2*NPxo4-berYrbC01Av9 z&mUo%>2NawLgH-jUZc?Oy~^`_rLY`<%% ziog%z|2cNFxEFYyZMeaP1f=4?rDn59x+aiPVi-n3KzrF^?)BP$RX0tA^jcNdRa`Fw zDNz*g!*Ij(0#XE*pUcjurgEHkJ#*&-blM_trrB)LY&H=>BqXHMq33zb{iHUK-Ui7S z4x~FLYw6S)E?L{4-t;!l9<2R8#S;4Xi-n_XW07PllPbW~Fbr$m^?`02=oUs@0>;a` z*0ub45|&YKz*IT`P*nt85cPuXJC>@(bwb+p%FpMYVH@diQvzhX_PqpLZ!{XDN$94- zt_sA0K^VvZt8R74%QO^RFCb?dR1@p3pDHb*yGD?5gCp6!#OY9fA_R2W5^%BAYSC;q z6Bhs|l}d>MS~Z8O-5w9+lmVwT~+Xts&D=5VHqlp8}z8n8aIlC1NL#Y zxJa^90v3VSUDr+GKsOfHwoMp@i3((0UEg0fsS9*X#n9DG{Xdv0`;XIgm;RtSdL(y< zEvCb*63`@Ge_w7i8n~|8j62xzqYfmGRloG2-Q zgTbIGA^)^Br5Dv>Y+;dPJL~BSz&q`Bn`X0_3<@F0=kxf!A1{(PE_eR@(Uv5f4qn-e zP8dp>$--ya@`HqAOpTTkA{h*-QWMJPi9)v?*w78OL%<$%WxD$i3-XS zBU_SidQKeq-68vX17;U&HlxvUymf=>$aC2Pz|4~*zy4d zRf+3;Dd{PE2CUlGO;t+Tw^+LGm^j2BBl47Gf>t9jKPc_DX_O%_SEdrxf%I2(px zLO{0}hCvVn2?^dpxG9h>*mA*2rM`_*WhCRP#cly4I~gRVgw8smKoNrSq1<7hzy{gi zu?PVC?p@+;i|k zu}M1IE&(BNHhAE=ZbCph9d=bvyXsKA-dxx6-9AyaX}0?pJL$QJB2s^fP$=e2T5gCU zlmzTB5^^*4E_)_(j13k^wnacH4qWzqAIEVLAOM+6hA<4{hbd|vH@`PO)T&*urlDc# z8jY6M0m^_?l@uUFC}@g;WvKXm96XbKD1+Zo6{Zf4A0mF}V`w&bocrpFz|SGRNg4!e zccY|~gkhMFP~2D8z^X7&%HsJU&2}(U!h=>7PmkMrmJzK?>w$}0jqv6i?*IIpi0(C(h+TIm0ozu9T)RBJ*S#;$ z4S-P;VObVY6cGdgjT;Vk{&{JroF~U@s&yBoQv(c>ut=mGt3VYB<)TTw>66iH_T-;t zI@(A6<|x6>1kQi?d^-EyR+^ zfsxpnDM%A#o5e?Mc8z9ew$|hfYc8S)h0)9yyNqdC3l8;r6_%G;j9DXm-a8xwG1E&NZCqUx_o<&}Ro8 z`v((3h~vON0EaBg!Zgjq>fM{C-A8LgLGrP`Ig9|NCu~+$J?xCa=tu^&v4;^+qH?Q2 zb#8_FLXCq{M|kC>FJPJ`-DBIfjb&K~Ay}BZ&(#ZOnZ5iDXW#gRT&*=$S61tD3oEO$ z)mHS=DB>ou)mMn!wIZb)`Yhp2o)%vO&H;zIPmy#LkamSI3>km6h=PJ;8WgM?`^S#Z ztgTRctHs>SIUf0SK6Ua{_I`99wr!*9I+;u+vAFBBxP0*(H?N-O+?mrnc<`WIt+nRw zJy^I^Ye#3=Ui1!efmZE+t^+M%tA`sIc_#|6fG-1ouPBPpbsa@fl7JXRQL_% znwny2?<9rs49A~+nL?pJsZ^p+D6nhSE^@gX*=&|-WrZu}&vJA2GH;$aEmu}6)%k^$ z`FnE<*J`ckbPzF1?8~d2-XykiDAP}EZ?iqN3&fYDVi~vz92*%KLDzN4eV@lw*^Vlf3xiiwWRdE=RFgWNd7V(a}++rlzP@ zSGaTIBCq}U2V8jj&9Gi?FVDVr>;B?$_1#)4e4TjVwQJ!Dv4tJBDeLXDof5DN{4|Q9 zKRAB;xUp~Fz6A8d!~~XQaqZeQe)OXsp?b?qjBu$(W6wWRnDJ3&*{^rIeYeOI}F2Hzzs`NW}P6qL|lK>mG%3NxUcQ_hm%5xUjaTVg!oIKB&D1O-UDs`SAbi@si{H?xJA6a*u6mMoDnz#_!jKNQq7A*Lpp`badk2@PWXqYX-|G^Br&q=F$>Qi+zP5MsM!mpA*k zuf20;?#!HXoIAVOWm%yVoA{l4@5#OM_&bhbJb6n1`H5BQ;7S*8aYsrg z(%8Ii3;uED#FnEM{<>~)`;y+z_k9UfuL=Wd3^^--)HY-9vi9Yh?_cu(n!Jfy$zTS8 zFo2)}vyvn?9M|-r={nrdg{hj@bLQ6=E!AfxklAj3tAllJUis0Fqv}*~qbQ*$kCrho zG=SmJ;ke;A=O|2uVNMJp+ zu;cEWP$ayjH}ek0J-mASRn(kXt0W9x0rd%pBpxKBqw^{10_ z%oVjGo>@EUS*iKf;$&9;O=?7MYMcQXV9*`JiNOiUq?uH19(+43b^r%Qh*N0-8PySL@{C>NTq zmAl*&&j?%;7m=-I(Us~#EHN?vgcGQQ0hk0J4Qw(qsrZhsSEW?J(B&a8Ns-d@z$hB4 z&i!^|7&j3whr5FWPw_8BZN)_edGBODPKjlmU)OlN& z4dJ>|3B=t!-WZQFVw^yzWIt}A)jJn2p(fkv>~xUJ=8+4c!VW>LUW;RQ#vRl~YN%eT z0!}M&0-I$B!U~}7K&Z}?pjDR^9 zW{w1fBn%*okZ2@|Mo`dfPy?U|ddU}J(~;eB;yI9g(5#EJY7>RVjYkxMPzh1xRX_*Q zgGN}L>lt#-?Jo$$M-mwReI4(mI02!^YNO`Zp&|eVz{136M>f%FB&97#EC=ugZbOBQ z1{xQHVXx5y)hVYs5kve(BsILL3O2L2eVrEoM3QY?Kgcb3@949XR>=y| zN9HIt>tOA)An!&l_%Kg4mvO7o?ddELGctBk@|Iqbzuk#2Bo z&hBJ8ZldsmjWTmA?MYAi&~*-)hk2IVeh$Mc&Y~^q*Rk^U(roGHs0>XDKJW)w2D&} zLr@aI9y*b6*=b_SODgY>+mHwoplwY`2+TZC2}AP}PN!W?UpF;VD9pM2G~W zv=zcESwU4AVsN?%Clyk$t6K5CULaO>RB3=w+Hwq`F$PVc@dDDMA*^l<0R@VEwgoBC zK!`SB>s*LjR9s;~MEqP3GO_+i2^oFJ_AnvesgxX9l+N^$J}LPp={csqlMPa&i2+9F zj44oKhzaYFr6Ez$U5wc-8i@dIWNt}C(P%E(pO2sm(K&6A^9rN6E-jV4e5RI?33*KZ zT*_Gq#1IGMUb2DoFS?k2bZmYj#*0&+QxLHOlOr$$LS29}0T6%)0v1HT&Bz{0YhaLo z5K{6CO^Wlcm!ukdMp#^1ui8avBL6 zumS>~gG4_FIunN4<@%g)A+7>w`9$QyDB!rPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01ejw01ejxLMWSf00007bV*G`2igb} z3n~f|k<>Q;00>%1L_t(o!?l)ca8=b6$A5dDdvESd2)PN5gb*G-nf>q;hroObEH#+~w?D2D`8$DkB)%Ed8F5`3Frdgjd@nwlRo1FL+l;GP7|iTFIz5=#i>q4b zv(401)+$B<8Gd@|?!eQu5~tqjg-K-&)e%Mifq-522msR_R#er6==Oxxtig-|dfEA{ zv{qa&<>>g1E59=lfR_+{iJYi$Kf?1AzLf{AnK@}L*e8r|wy_q+DpKP-`NzzIN*cy+p3sR3x4-!^6Bgcpufl8HY+keyWdJ2Yq2S|NOL-y61zRW6^K62NF+=I_FZVah zf%-Ynnt`?q_y%-RZ#rRs2@7xFXLsJb=;`Oygl0{yp{k;s08Qf=4J^8R9^(m4E`d{wv@j-f^GXuUtC`DDRt$pl&0=&{x!S#&;UwOCTy)ENbUN)O2 zpLh_$<=99W;*?^YFj7eK;|UY^%X^=*eNR7wqrkXd?oGOo=>WyUmNz~lm})#^c0Uv=%z>Gym)tt>fG>)pZhlp z%Z71nH0qunia@S_WDBBzk!XARy>~69w7XOUs}PH_0iqOwLKz~j4o6wtVLna_=pG~DC;AE&%AjT60Mnf;|q&FsP{ZGH6W;R&=MkaI2McS95ZF& zp3gpiCunH6f*m^^D+)|o9hP`pm{2n!*Eq2j(F5V$Oh?$!T2Q)}YS!Z8aYyt?d-|lQ z+UN-4gb}4t2-tv7;F230e75YIYIgQ6}c-L&-|5yF`_6ME*fxPa` z7_O?gmPwN)gV>`nQew%avrX~yuiJJqg-rvvF63Mxmxo+l$hlB(9S-z;!PfSt%xjSTA@{x?syvT6X&Eehw|p(kI2$rm&|>HQ|1 zR%Eh}$qMN#;DmYg&u`GYV;B2d6EyAICEIuJWA@pz2DiMw@#Fz~4{}GnQ1n24$RmB3 zUKz|<(pe#$75WAYjdd3>d&YEnaxQJjltd~jgR2+Jr#tUlGxy^8Cl7!ybn2pbZfNYf z(3|Yn>8y~+2&rs9xG&DFH$6((_(n!lR#010L(QnsxRZ=k;!Cm5X#3+ z<(cpPL?!*WE(tp-m&>Vw=h4^OH|gNP!|N7ay*zdObw9Z0>MNIo0j{`W>G1%{lGEFQ zn<@^(z9{j-WD6pm8>X^*2GPyeaB#zTmFzHNa(Td_wI-2BAR>IYX%kiH0d{@*3F&m2 z_V)dR9F2%5&vWVN>#s<(cKk}fTfXeNKUBttO*syre}H_gsBCe)JKOV=-Db zz01fEBa4MqDXdsff?zQitQeF+Wpi0-t4FPvJ9plHWxx3_+qO}zHT|D{iWMQzmO$&G2ShAN>0-AO zh7Mxzd{cj1FF4i?9qQa&K76>1MPrVm9T6)^5JZZe0HLj|17j_Ni3C<_GJE#mi;zgP zAwy!;TC`RuD=0^aF;?XZd6my*H-95QM@Q=`At&_F=$hKwVx^^vBH?gDBvPW(P}k8q zL|c11dDkV^)g`v7Qb{r;1O5G~y<>kd{!#=8On~Qkcz&V1kT1O5+jsaWH=o;eTs!`z zZmF~$QyCv|PAD9z4~HUCv{rE|5}SM8xuL_G-!B;+3MtZ`vL`PO*#mI oy(S1clF9yU#sr-};p+tc16wtkWzAc!cK`qY07*qoM6N<$f*#2%0oP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L02IRj02IRk6>v>L00007bV*G`2iXY> z0T?-A|3K&f01kplL_t(|+U1xDkX2QB$A9PE`?l`akM3q~ppnJKM(GAIsDq$_xG*Tj zxMZTH%26|!n2M&#$z)QKs;SgyjiV;9vW!WYGBq`si6chAg(w3x6u zUCueV@6?qJRYpaNNLBvLSKoQ3ANT%$_k7AAg z5nFi*c#u;%*8o~kyqe0Srma1HEzR}K0PG*y&-%mbDP>D1QLN@+cAt9yPjEYNo?EqG zmHt-q?~Af3Q7GpCNGEGZSSg;~{}cV@?l%PRPZb?U?hy8I(d5>N#ci)|R0 z@d*M{2m$>8Or1DYbPRSh@Hor9dVqj6)Idj}9rsWd6CH<%aY66#60F8(=Z8n=8SZ4j z(;HKEZ)idTLU2kSeNThN=-|l%G;eB#S|CC5xd4#B z0W>6?B*KC*?-~q@I5nAwB{6aU8~dvU5R_;`qpj(PrsrldAqJBYFwz0XexLzp`U^qb zbm;S7Ab|KB@H{}$`F{#<&x!>TrPND6j}ws7TKwv#NB6wT9PU;MsxO4eRnQnl?Kn>9 zyo;cIE;vQ-!ssf2(FwMlRe)vlrn2Q=H>($&cdv!`VeepWN}wcKfk0q87As$wvEi+i z9iu>IG>7Q*!ScYBoYH`V{0Q`vV6X^SXe3#l=X0vq~!dHMcJM~(yh-IiJ&ST+KYhK5I53&pa2^jkNJwX2p9udbo2 z9TGKl#A+vFRaFXEL1~mFU%MRr$Y1e`E&I4?`BJs>mxq4FFR2IOfC5}#1UQKf1B##c zar&`0GJN-11IFWTjBBW$z)hj)HK`O|PgOxYu0aS5ptTmhD<~EzmP)*w9p>eOyTyhl zzB!Tum^X9EbE{g;yZwnD{wa1SKPPzvo85XE5*zVix;@B1+g<7>Xz zKA8JCkd6RE1W<^whA}y7AFXEnpA~rEC*zWV)HnXkdzm$&jRu#K#bc6ccJvy!FyQE_v|QyWV@LhtDMkpuH!!=!H$bo;5w0 zzhHL8N~MY^seDVr=OWN!OCuaB=?{#?f<;ZOaak6&RtiglMuCzDECZs2Kxl=fBqrMq zOP93L*f{-lW1cer@I8T4T6Fij>0Dt@G)|h~&Yn6=NwRid?nqoC%`N!^iHarRFf}vZ zE0iP$yF0Cc(f-tV(|h&&>P4WH2~i0l4JOJ$fSE`6paYZ;`ub~@jflpp4!{`#cwQwm zF-Hj3S9A@vCvt8lvnS8v@|pL!u8+Or*amyJ)GL(s0kkdRVsd7dYMHS@6}=&~v;993 z{i6dE%Zic*FCKnH+;H)7WDsD-C0berHuQO_tb{3{0J92COkA^c@%@~k1i-YrV!C>~ zq&g)?R|%?35WcpkskZfu3A4r3=l_9bg?W& z*@cp;DVM_>g4{THB@bV5Kk0F`Xe)*mHdq$gpa3X@3J`%uA(tid8@CD0P!2#awgR{w zIF2@_V=T;NPl~SL!))059cx`ZV(PrLTS8U&j}aWdMAPao5#&ekG{nXs$A*0zyyr2*-vt%Xbd_ z6GOR?$ULV^k7XVH4mw7&Jhyu@rF>pv%Ed>>FqDU7vX52)gu-e$Matd!1sxa zM~1yIh%pdt=7)>zYP6WA>=K#RpJ=`uj(rclx9MMY^>+3Mw^Tx#ZB!zZ1SDE%%EcmW zUEO;pEWfieETJ#B0up1=7!Sq_oBTiF!rzaS`gNfg7_*;ZKFnsGLRq?-w`|?k*?tnY zGGWRHl+u)n1^w#}KEz2R_wWVf03d}i8*{+%D)k>`M-Z#@g$=GF!a36;WJ^Q3=*q}E z|GW99^kN!&ZsUyMb+5g~jjOIG;vu{kXw3+2XMNoaT*`)TFD@Q*Rk$iEo@uI5^*u7X`YzX*l3qsf8mz{ z&={E=C>EOah(I*1U6~U&(JnQTAF(QXeFX8T=FxEf>iZT?SbPm5d*6{08m1~co>1{b zf~r)?N>^1|m8LGHXI{T+*RJ1gZEgM6FVq9ku1pa973BJrs5ET_s*=aXqq&@84y*EK zo3C@mv8?e*#y2h0>A9C!C}qmWwr$~rVQDG)Rfd|Wv-R7Xw?1>r&EJ>@aP6ua&j?^l zI%--sYTDCxCKI`0UX)yAOn;(z4H-Mll{H`E3bmY(fgBcyhSudGJ!gsImy6hzjbAE? zk=PVbJNJ_CwGjRNgH^8Q9k~6ryVuoZYNrFNS##@W12jM;CT%PwK!B3q8q@mpoyo^U zHeaGtQpWUY=EIm4pTerlRa`ArLRXsM!7{mg9>;MIXvWW8!1QI`NWAspCcC<2wVjzc zUkh|)MJROapOAR74J+Yout5%vbAel;u z$8Nua`0MXjTi^eHEAP5XC@G1>9M-RYmA<}yq>`dsE>p-C8;KGHAsjaWu z(cX4KUVq(MjvPHW1|VX%aZS7Im)nC*)mtr+4IxOqXGw&kBZx4Bz_LLHTAUnEq=Shx z+bvw^FGBRE$o9KKY5bc<;!Ug0xr1V0xE|8 z;pt}xO9%mI6WV~}a`}|&de@B0)c*Ox){8HUC*sHV?c3e8a>Z(nA3u!kd+4%DDHEsD z7J8=~l-q(%*_%?y1}7e?Q*ntEf!IQz0!4k_A{uiSQ0%cNWL>jW8b#kc2n0I%hPI)h zfhCtN=ER8;Tyn`JRL^W=+q3`79qZOHXZCCkA3h8MUVZi7DTRi$)+VG3Olb*WnQ^ID zCZEsG7l_}R*VLST{f(D5oz}$tMdVPP0ZZv^N%WKQX!)Mv7WYSTSK?^Uoy09!xPd0{ z;-q>ek{vFi0*SeqlAtl!HlH>tCX|Vh(GjLkpU(XG^GT&rbZ*^7Q&kmh+qaWWr)g?x zVp_vA1_y^wQbyn!D>NTS-&_MgnGbzZ^z?L5C=?(59%0`dzf%S2|GMm_MSg%e2&eJFaD| zF|8Cr81tsq!=W){WJ&>g`}+X!eIH-L@CP3-D;}qB#|}IxA&ma8c?HHi<{IX|OU#^7 zXg~leD$77h?I^Vrc+KH6G#r7{h9J2-|K-T)>y*+LYaN`bR{$w1Il8fBfj0Lt{n6Fc zMJAKsz|LJ{f&e>_ptNTX#j=Z|6&)u#v261|h*Y_*c_;wUgEDhrHlGoDXPk?|{g-iokVbRs&Igg;^WmVj(Yvh6Z*3_L&0sotKVF_Wz`}gfFf;xIRa<^!IzgUVzHWpWlcud4e@w!LZ-}3$bjkm}dq5uE@07*qoM6N<$ Eg2SmeH2?qr literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/WikiPoos/images/resource-group.png b/retroshare-gui/src/gui/WikiPoos/images/resource-group.png new file mode 100644 index 0000000000000000000000000000000000000000..2b37badddb88e4e72286482a858e90cbee5cd79e GIT binary patch literal 1823 zcmV+)2jKXLP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L0B*Vf0B*Vg*50uf00007bV*G`2iXY> z0ShpC%(>nG00y5)L_t(|+U-?oY*g17J>Oeq^LTf_INoB6jT?gk2?+=VDk_3PO^ZS) zQ0S5>Do9Zz)TUC@Dv?m7rj6QvP^qojG*z0WNKKUlHMmx2nyS#nVX+Ayu)#~>eH+i4 zx8M8q>W$40n%H#tRdF;&_tV_voOkZ`^l%4va0mYv*t4N|f&UhUf&T%#AYA_02bO;u zjLiTSN{O?!7d#1|7mI-KUt(=-`98zYUI_!qp!|76U|rMUg+bee!Rg;)0qFP-asA9& zn3*0cywNw*wDriN=Nv zkAkIkXewjjo~5PKP*s8Ex+*-rXD5F8!gKi1GhZc>LLQx%JaSt-@Pl`X@$@G%QGM($ zB`YhJ@s4y6+G25R(shA{r;B^s9NwIo;1d8&LE+rRD>dIgyq~}F_?Jk;(mTC%_)t+gxzh1{J!3J?WSM5O zpiGuA&zY=LWLOTv3$^NdjqTMB)UQIkuoz4_0LojIAvEDb^DOQi9v?b)`NmHcynIcdw3b>BAp=r?NQn{w zETRNR1h7M<&urWL%b&k?3JWGsaIgM^5$77iV7NgBv)&MW;_mfyU)3H^P>awn!TmLl zp&(X)3w>uWFgB)4hv*vX#UqsuV@X*Bm;izz3n=j@0hS?Fw;kHPXcKxK!FCw&7?6k& z#p8^w!9SwE_!PD@eGO~ShF3eEQKAA?4iU3ChMgn)>iu>cscV965}-+d2#`WCfbV)Q zVG(Hgred;PhV3FU;yC%*bu?Ta?ZDq}yspIMyl_Nojz>FBVq$n?95Mt+9}pgh1I$cM zV{B^X@bq6_UEF~0QQkl#oToEa&sZ5uWwVjkym(Yw`P#7w$KN>7KG4?(DFj$bo}QdW z*VP``{OLn8rR(?J#t`bt zM@YmQA6yqAkHr%p5cxjl5&#^RZ`L_msIJd`q_`A7I+5o4cOLw5>&hlsx4bc2(b5ub zT)!R;$6`I#`=5itu3cYP!~l~4V7><;MkXR7a|Wzi#6zGaS%s|y+oIZ=LdVIDBfCF$;Dt>OuG8~I_Wi4YDn&C#vj%GjL$G~Qcs>z{$r(F(`dP)C z12o1Pur2-w8pl>6GvvT9bSkWBM67m0?DX5`jiOasVVZ_Y&%(&?=r>QE`cwGW&V4^C zD=lk+!qW%8g?Xr*fb0q1O;{$IF{34jae{Pa!yqzrz%&ShBLOtG7!6@7R=I1Tj~2pL zW~7v`Z5w;`?m{R8z4GK!Bu=!G*tCi2Yin`*_-`@v;Rrn6LoSzFGc%KUYW3reu))tm7C%P*tt=uu2gjN|$5{t)LcbOQ_sDPZV2q-54~ozm%)+ur_0Qo|fZ zClFYSi!smthW}@Gll2GfSf(qMnavQ4fu-zvJ^%^H63m>Zlo4aG80zcmG1$=oK6@6) zL;}^-HR{@O(Y#~<0w6`SmxKs0JvEj1)RyggHQa)UDU~kJZTkM#r#jrt6Td6{g&zuH zmXORh4M>?cLqzyMeHTJzjGjKNk{ZJ3_&A_2GBN_5U(W&(s#cUzfHaLA*V(AyV=yrZ z-vPQROPBvziZF^$2}Z&|bYOHi>4brS0nA$J3a(y7K|GFu&QAEgkI~VwXwSTPo~wcU z7z9D3frX(C?;k8LtC&nBQ{|d5x113fA&sI0`uh4&SzeBWWUyK@(cO*y#ubtHd}2hT zYJdP%36N?`va;Ft7Brw~I>yI_FDo`KSyH(-l}hiACldFWrkPfAYM!EIyw-CKH3cbX zh7K3NU)&E+7;cKp6Vc^ZZ`NvENcn`eV;?E)o8HlqZv^dS#~BG>yAS)5{9d z1*v7lMR6V&Gz<{A1u22brGX01WhrLEPz-y%+pC`Vnv`M~K!6B@e*&Ez5>n5KMyCJ( N002ovPDHLkV1jgbSKj~t literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/WikiPoos/images/story-editor.png b/retroshare-gui/src/gui/WikiPoos/images/story-editor.png new file mode 100644 index 0000000000000000000000000000000000000000..296e08797ed3fc44834cf3d91b7381596c3a0e57 GIT binary patch literal 1646 zcmV-!29f!RP)Px#32;bRa{vGh*8l(w*8xH(n|J^K00(qQO+^RU2NnYhIvEL#Gynhq24YJ`L;(K) z{{a7>y{D4^00r(zL_t(|+Rc;;Op{j_h7S}_3vw$^ZX$&Og(9HboJ?7CZet9m&J3a( zS&SwlE=v}j&Lz8Q&@Dv~g>q9aDn(nMEiy%LPM9~$mbmDcHzw$C(>auJ5qf!d&TrGL zOuBkY_9jpMpTqgS_x;YvU&0CGU&_nNgG?qfLu?e?YrSsVPP55!l0f#88Dt*`AbX$( z`uqDi*gFxDJw!_OaYR{SUJoRDq5Hc|KcWZg#d@;doX5CIAa$;lE(qBhh>-FCT)%wX z*xA_$M$e@lPZhef>8|$&HXEio;twMHd2D&fynCrSP zbsHrWB1mdQ@T_tJ^RN~`#g{w6Yo{~FvjimtC1BUUC@v^w#aP@Hh1ZWxL-z6MSaCW5 zD?5_#)`=O&Iu?T^?bASJ63Dm7&2@#_inukOT`q7gb^`OT8ek#~;88LOlX7^7OOHlO zMik-}NRhNK4pUaUBE2O73tOeg{3Zs=+TyURJ&rS9d_;aM|tzft(NjvdIutcpzf87h-CB5wG;eGxb53qZMH;HG95E zjQJF1oJ!YH8iJ6h3Ph~J7m_{R2&wc$K)EZti}`TfF#)_n9#XUCcm3F&hX6mJ(azq^ zXm3Y8u?WE1VTVcE99aP^bmkg}D({Dgt`Q<`pC1xb0hn1gg$px_GLw?148-*P{+MPm z53TYuTcGXAW@R8$CDHZxI75^%Ab+!mVwi7sR<$+H_u&eMY z;Ul2T6~Ptm2&)nxk~U{Sm{Dvk!w)g^Jz60|cD?vs<7y!W_WXD_}=yD|EjK zOhcV(QInSfcW*Hc75L(pj`v|O4P|2hHpwU+Mn=9LEE|6w9}PrnP(FlKBHU@#bLx&nmeER>*=_h1+}cYjmqUF*R6>m040;X;}!J zfem3ao6{3zJm~;N-2L?ou4&vL7Kb7;Jq$l-lTFi(u;*B855Rs2RVo!b;&C~o*@?SH zd=MQa!V9UPIID=j;J|GRo6H_7!0_-eo01D+n%Ls++kJf)Y4=9*j9{cBhT+sMA^Pw1 zQuAS2J1({d7#bR4-z|ePHDUgiPqZ~7KQ{+bNeIrA*<;|3EA;YYA(dUz<@Pu4!}0E5N4P@Shp6#!$Zu7t&N4%uqmx!V}PeC>j4}b9AfBW s$vC_=4vQJ)cS{zHg~#JXlmDCk0vyc2W|M4Ci2wiq07*qoM6N<$f~1n)*#H0l literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/WikiPoos/images/view-refresh.png b/retroshare-gui/src/gui/WikiPoos/images/view-refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..afa2a9d77403a12cf6808fd4e551f8582e2599d6 GIT binary patch literal 2182 zcmV;12zmF3P)Dnz#_!jKNQq7A*Lpp`badk2@PWXqYX-|G^Br&q=F$>Qi+zP5MsM!mpA*k zuf20;?#!HXoIAVOWm%yVoA{l4@5#OM_&bhbJb6n1`H5BQ;7S*8aYsrg z(%8Ii3;uED#FnEM{<>~)`;y+z_k9UfuL=Wd3^^--)HY-9vi9Yh?_cu(n!Jfy$zTS8 zFo2)}vyvn?9M|-r={nrdg{hj@bLQ6=E!AfxklAj3tAllJUis0Fqv}*~qbQ*$kCrho zG=SmJ;ke;A=O|2uVNMJp+ zu;cEWP$ayjH}ek0J-mASRn(kXt0W9x0rd%pBpxKBqw^{10_ z%oVjGo>@EUS*iKf;$&9;O=?7MYMcQXV9*`JiNOiUq?uH19(+43b^r%Qh*N0-8PySL@{C>NTq zmAl*&&j?%;7m=-I(Us~#EHN?vgcGQQ0hk0J4Qw(qsrZhsSEW?J(B&a8Ns-d@z$hB4 z&i!^|7&j3whr5FWPw_8BZN)_edGBODPKjlmU)OlN& z4dJ>|3B=t!-WZQFVw^yzWIt}A)jJn2p(fkv>~xUJ=8+4c!VW>LUW;RQ#vRl~YN%eT z0!}M&0-I$B!U~}7K&Z}?pjDR^9 zW{w1fBn%*okZ2@|Mo`dfPy?U|ddU}J(~;eB;yI9g(5#EJY7>RVjYkxMPzh1xRX_*Q zgGN}L>lt#-?Jo$$M-mwReI4(mI02!^YNO`Zp&|eVz{136M>f%FB&97#EC=ugZbOBQ z1{xQHVXx5y)hVYs5kve(BsILL3O2L2eVrEoM3QY?Kgcb3@949XR>=y| zN9HIt>tOA)An!&l_%Kg4mvO7o?ddELGctBk@|Iqbzuk#2Bo z&hBJ8ZldsmjWTmA?MYAi&~*-)hk2IVeh$Mc&Y~^q*Rk^U(roGHs0>XDKJW)w2D&} zLr@aI9y*b6*=b_SODgY>+mHwoplwY`2+TZC2}AP}PN!W?UpF;VD9pM2G~W zv=zcESwU4AVsN?%Clyk$t6K5CULaO>RB3=w+Hwq`F$PVc@dDDMA*^l<0R@VEwgoBC zK!`SB>s*LjR9s;~MEqP3GO_+i2^oFJ_AnvesgxX9l+N^$J}LPp={csqlMPa&i2+9F zj44oKhzaYFr6Ez$U5wc-8i@dIWNt}C(P%E(pO2sm(K&6A^9rN6E-jV4e5RI?33*KZ zT*_Gq#1IGMUb2DoFS?k2bZmYj#*0&+QxLHOlOr$$LS29}0T6%)0v1HT&Bz{0YhaLo z5K{6CO^Wlcm!ukdMp#^1ui8avBL6 zumS>~gG4_FIunN4<@%g)A+7>w`9$QyDB!rsetHeaderImage(QPixmap(":/WikiPoos/images/resource-group-new_48.png")); + //ui.headerFrame->setHeaderText(tr("Create Wiki Group")); if (!ui.pubKeyShare_cb->isChecked()) { diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui index c349988a6..2fab209f0 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui @@ -1,560 +1,557 @@ - - - GxsGroupDialog - - - - 0 - 0 - 695 - 658 - - - - Create new Forum - - - - :/images/rstray3.png:/images/rstray3.png - - - - 0 - - - 0 - - - - - - 16777215 - 64 - - - - QFrame#frame_2{background-image: url(:/images/connect/connectFriendBanner.png);} - - - QFrame::NoFrame - - - QFrame::Raised - - - - 6 - - - - - - 48 - 48 - - - - - - - - - - :/images/konversation64.png - - - true - - - - - - - color: rgb(255, 255, 255); - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Arial'; font-size:24pt; font-weight:600; color:#ffffff;">New Group</span></p></body></html> - - - - - - - - - - QFrame::NoFrame - - - QFrame::Raised - - - - - - - - - - 0 - - - 4 - - - - - 0 - - - - - - 64 - 64 - - - - - 64 - 64 - - - - -border: 2px solid white; -border-radius: 10px; - - - - - - - - :/images/channels.png:/images/channels.png - - - - 64 - 64 - - - - - - - - - - Name - - - - - - - - - - - - 0 - - - - - Add Icon - - - - :/images/add_image24.png:/images/add_image24.png - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Key recipients can publish to restricted-type channels, and can view and publish for private-type channels - - - Share Publish Key - - - - - - - - - - - - - - true - - - - 0 - 0 - - - - - 300 - 524287 - - - - - 220 - 0 - - - - - 0 - 0 - - - - check peers you would like to share private publish key with - - - false - - - QDockWidget::NoDockWidgetFeatures - - - Share Key With - - - - - 0 - - - 0 - - - - - - 0 - 4 - - - - - 20 - 0 - - - - - 300 - 16777215 - - - - - 220 - 0 - - - - - 200 - 0 - - - - - - - - - - - - - - Description - - - - - - - - - - - - Message Distribution - - - - 0 - - - 4 - - - - - - - Public - - - - - - - Restricted to Group - - - - - - - Only For Your Friends - - - - - - - - - - - - Select Group of Friends - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Edit Groups - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - Publish Signatures - - - - 0 - - - 4 - - - - - Open - - - - - - - New Thread - - - - - - - Required - - - - - - - Encrypted Msgs - - - - - - - - - - Personal Signatures - - - - 0 - - - 4 - - - - - PGP Required - - - - - - - Signature Required - - - - - - - If No Publish Signature - - - - - - - - - - Comments - - - - 0 - - - 4 - - - - - Allow Comments - - - - - - - No Comments - - - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - Qt::Horizontal - - - - 238 - 20 - - - - - - - - Cancel - - - - - - - Create - - - true - - - - - - - - - - - FriendSelectionWidget - QWidget -
gui/common/FriendSelectionWidget.h
- 1 -
-
- - - - -
+ + + GxsGroupDialog + + + + 0 + 0 + 695 + 658 + + + + Create new Wiki Group + + + + :/images/rstray3.png:/images/rstray3.png + + + + 0 + + + 0 + + + + + + 16777215 + 64 + + + + + 11 + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 6 + + + + + + 48 + 48 + + + + + + + :/images/resource-group-new_48.png + + + + + + + Create Wiki Group + + + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + + + + + + + 0 + + + 4 + + + + + 0 + + + + + + 64 + 64 + + + + + 64 + 64 + + + + +border: 2px solid white; +border-radius: 10px; + + + + + + + + :/images/channels.png:/images/channels.png + + + + 64 + 64 + + + + + + + + + + Name + + + + + + + + + + + + 0 + + + + + Add Icon + + + + :/images/add_image24.png:/images/add_image24.png + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Key recipients can publish to restricted-type Wiki Group, and can view and publish for private-type channels</span></p></body></html> + + + Add Wiki Moderators + + + + + + + + + + + + + + true + + + + 0 + 0 + + + + + 300 + 524287 + + + + + 220 + 0 + + + + + 0 + 0 + + + + check peers you would like to share private publish key with + + + false + + + QDockWidget::NoDockWidgetFeatures + + + Select Wiki Moderators + + + + + 0 + + + 0 + + + + + + 0 + 4 + + + + + 20 + 0 + + + + + 300 + 16777215 + + + + + 220 + 0 + + + + + 200 + 0 + + + + + + + + + + + + + + Description + + + + + + + + + + + + Message Distribution + + + + 0 + + + 4 + + + + + + + Public + + + + + + + Restricted to Group + + + + + + + Only For Your Friends + + + + + + + + + + + + Select Group of Friends + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Edit Groups + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Publish Signatures + + + + 0 + + + 4 + + + + + Open + + + + + + + New Thread + + + + + + + Required + + + + + + + Encrypted Msgs + + + + + + + + + + Personal Signatures + + + + 0 + + + 4 + + + + + PGP Required + + + + + + + Signature Required + + + + + + + If No Publish Signature + + + + + + + + + + Comments + + + + 0 + + + 4 + + + + + Allow Comments + + + + + + + No Comments + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + Qt::Horizontal + + + + 238 + 20 + + + + + + + + Cancel + + + + + + + Create + + + true + + + + + + + + + + + FriendSelectionWidget + QWidget +
gui/common/FriendSelectionWidget.h
+ 1 +
+
+ + + + + +
From d591d795bd6b033263b7f6ac9b2d938c75ff34cf Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sat, 17 Nov 2012 14:35:21 +0000 Subject: [PATCH 150/222] Fix providing mask for setting group subscribeFlag, msgStatus and grpStatus Tests updated Also setting msg and grp Status to unprocessed and unread on receipt from a sync (see rsgxsflag.h). These are set on bits masked by 0xf00. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5834 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgds.h | 1 - libretroshare/src/gxs/rsgenexchange.cc | 104 +++++++++++++++++- libretroshare/src/gxs/rsgenexchange.h | 9 ++ libretroshare/src/gxs/rsgxsflags.h | 8 ++ libretroshare/src/serialiser/rsgxsitems.h | 2 + .../src/tests/gxs/genexchangetester.cpp | 27 +++-- .../src/tests/gxs/genexchangetestservice.cpp | 12 +- .../src/tests/gxs/genexchangetestservice.h | 6 +- .../src/tests/gxs/rsgenexchange_test.cc | 6 +- 9 files changed, 150 insertions(+), 25 deletions(-) diff --git a/libretroshare/src/gxs/rsgds.h b/libretroshare/src/gxs/rsgds.h index abe39f363..bfcee886c 100644 --- a/libretroshare/src/gxs/rsgds.h +++ b/libretroshare/src/gxs/rsgds.h @@ -105,7 +105,6 @@ class RsGeneralDataService public: - static const std::string MSG_META_SERV_STRING; static const std::string MSG_META_STATUS; diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 5712bf4f6..da2153171 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -47,6 +47,8 @@ #define PRIV_GRP_OFFSET 16 #define GRP_OPTIONS_OFFSET 24 +#define GXS_MASK "GXS_MASK_HACK" + #define GEN_EXCH_DEBUG 1 RsGenExchange::RsGenExchange(RsGeneralDataService *gds, RsNetworkExchangeService *ns, @@ -986,6 +988,7 @@ void RsGenExchange::setGroupSubscribeFlags(uint32_t& token, const RsGxsGroupId& GrpLocMetaData g; g.grpId = grpId; g.val.put(RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG, (int32_t)flag); + g.val.put(RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG+GXS_MASK, (int32_t)mask); // HACK, need to perform mask operation in a non-blocking location mGrpLocMetaMap.insert(std::make_pair(token, g)); } @@ -998,6 +1001,7 @@ void RsGenExchange::setGroupStatusFlags(uint32_t& token, const RsGxsGroupId& grp GrpLocMetaData g; g.grpId = grpId; g.val.put(RsGeneralDataService::GRP_META_STATUS, (int32_t)status); + g.val.put(RsGeneralDataService::GRP_META_STATUS+GXS_MASK, (int32_t)mask); // HACK, need to perform mask operation in a non-blocking location mGrpLocMetaMap.insert(std::make_pair(token, g)); } @@ -1021,6 +1025,7 @@ void RsGenExchange::setMsgStatusFlags(uint32_t& token, const RsGxsGrpMsgIdPair& MsgLocMetaData m; m.val.put(RsGeneralDataService::MSG_META_STATUS, (int32_t)status); + m.val.put(RsGeneralDataService::MSG_META_STATUS+GXS_MASK, (int32_t)mask); // HACK, need to perform mask operation in a non-blocking location m.msgId = msgId; mMsgLocMetaMap.insert(std::make_pair(token, m)); } @@ -1047,7 +1052,43 @@ void RsGenExchange::processMsgMetaChanges() for(; mit != mit_end; mit++) { MsgLocMetaData& m = mit->second; - bool ok = mDataStore->updateMessageMetaData(m) == 1; + + int32_t value, mask; + bool ok = true; + + // for meta flag changes get flag to apply mask + if(m.val.getAsInt32(RsGeneralDataService::MSG_META_STATUS, value)) + { + ok = false; + if(m.val.getAsInt32(RsGeneralDataService::MSG_META_STATUS+GXS_MASK, mask)) + { + GxsMsgReq req; + std::vector msgIdV; + msgIdV.push_back(m.msgId.second); + req.insert(std::make_pair(m.msgId.first, msgIdV)); + GxsMsgMetaResult result; + mDataStore->retrieveGxsMsgMetaData(req, result); + GxsMsgMetaResult::iterator mit = result.find(m.msgId.first); + + if(mit != result.end()) + { + std::vector& msgMetaV = mit->second; + + if(!msgMetaV.empty()) + { + RsGxsMsgMetaData* meta = *(msgMetaV.begin()); + value = (meta->mMsgStatus & ~mask) | (mask & value); + m.val.put(RsGeneralDataService::MSG_META_STATUS, value); + delete meta; + ok = true; + } + } + m.val.removeKeyValue(RsGeneralDataService::MSG_META_STATUS+GXS_MASK); + } + } + + + ok &= mDataStore->updateMessageMetaData(m) == 1; uint32_t token = mit->first; if(ok) @@ -1074,7 +1115,11 @@ void RsGenExchange::processGrpMetaChanges() { GrpLocMetaData& g = mit->second; uint32_t token = mit->first; - bool ok = mDataStore->updateGroupMetaData(g) == 1; + + // process mask + bool ok = processGrpMask(g.grpId, g.val); + + ok &= mDataStore->updateGroupMetaData(g) == 1; if(ok) { @@ -1089,6 +1134,59 @@ void RsGenExchange::processGrpMetaChanges() mGrpLocMetaMap.clear(); } +bool RsGenExchange::processGrpMask(const RsGxsGroupId& grpId, ContentValue &grpCv) +{ + // first find out which mask is involved + int32_t value, mask, currValue; + std::string key; + RsGxsGrpMetaData* grpMeta = NULL; + bool ok = false; + + + std::map grpMetaMap; + std::map::iterator mit; + grpMetaMap.insert(std::make_pair(grpId, (RsGxsGrpMetaData*)(NULL))); + + mDataStore->retrieveGxsGrpMetaData(grpMetaMap); + + if((mit = grpMetaMap.find(grpId)) != grpMetaMap.end()) + { + grpMeta = mit->second; + ok = true; + } + + if(grpCv.getAsInt32(RsGeneralDataService::GRP_META_STATUS, value)) + { + key = RsGeneralDataService::GRP_META_STATUS; + currValue = grpMeta->mGroupStatus; + } + else if(grpCv.getAsInt32(RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG, value)) + { + key = RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG; + currValue = grpMeta->mSubscribeFlags; + }else + { + if(grpMeta) + delete grpMeta; + return true; + } + + ok &= grpCv.getAsInt32(key+GXS_MASK, mask); + + // remove mask entry so it doesn't affect + grpCv.removeKeyValue(key+GXS_MASK); + + // apply mask to current value + value = (currValue & ~mask) | (value & mask); + + grpCv.put(key, value); + + if(grpMeta) + delete grpMeta; + + return ok; +} + void RsGenExchange::publishMsgs() { RsStackMutex stack(mGenMtx); @@ -1487,6 +1585,7 @@ void RsGenExchange::processRecvdMessages() if(ok) { + meta->mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_UNREAD; msgs.insert(std::make_pair(msg, meta)); msgIds[msg->grpId].push_back(msg->msgId); } @@ -1540,6 +1639,7 @@ void RsGenExchange::processRecvdGroups() if(ok) { + meta->mGroupStatus = GXS_SERV::GXS_GRP_STATUS_UNPROCESSED | GXS_SERV::GXS_GRP_STATUS_UNREAD; grps.insert(std::make_pair(grp, meta)); grpIds.push_back(grp->grpId); } diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 0efd32343..06df6ba9e 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -430,6 +430,8 @@ protected: * as it is called by the backend GXS system to \n * update client of changes which should \n * instigate client to retrieve new content from the system + * Note! For newly received message and groups, bit 0xf00 is set to + * GXS_SERV::GXS_MSG_STATUS_UNPROCESSED and GXS_SERV::GXS_MSG_STATUS_UNREAD * @param changes the changes that have occured to data held by this service */ virtual void notifyChanges(std::vector& changes) = 0; @@ -459,6 +461,13 @@ private: */ void processGrpMetaChanges(); + /*! + * Convenience function for properly applying masks for status and subscribe flag + * of a group. + * @warning mask entry is removed from grpCv + */ + bool processGrpMask(const RsGxsGroupId& grpId, ContentValue& grpCv); + /*! * This completes the creation of an instance on RsNxsGrp * by assigning it a groupId and signature via SHA1 and EVP_sign respectively \n diff --git a/libretroshare/src/gxs/rsgxsflags.h b/libretroshare/src/gxs/rsgxsflags.h index ba352171b..3b4d22897 100644 --- a/libretroshare/src/gxs/rsgxsflags.h +++ b/libretroshare/src/gxs/rsgxsflags.h @@ -93,6 +93,14 @@ namespace GXS_SERV { /** END GXS Msg status flags **/ + /** START GXS Grp status flags **/ + + static const uint32_t GXS_GRP_STATUS_UNPROCESSED = 0x000000100; + + static const uint32_t GXS_GRP_STATUS_UNREAD = 0x00000200; + + /** END GXS Grp status flags **/ + } diff --git a/libretroshare/src/serialiser/rsgxsitems.h b/libretroshare/src/serialiser/rsgxsitems.h index 151219c2c..2726e21b9 100644 --- a/libretroshare/src/serialiser/rsgxsitems.h +++ b/libretroshare/src/serialiser/rsgxsitems.h @@ -46,6 +46,7 @@ public: mPop = 0; mMsgCount = 0; mLastPost = 0; + mGroupStatus = 0; //mPublishTs = 0; @@ -86,6 +87,7 @@ public: { mPublishTs = 0; mMsgFlags = 0; + mMsgStatus = 0; mChildTs = 0; } diff --git a/libretroshare/src/tests/gxs/genexchangetester.cpp b/libretroshare/src/tests/gxs/genexchangetester.cpp index d02bab577..3a2e14e53 100644 --- a/libretroshare/src/tests/gxs/genexchangetester.cpp +++ b/libretroshare/src/tests/gxs/genexchangetester.cpp @@ -3,6 +3,9 @@ #include "gxs/rsdataservice.h" #include "gxs/rsgxsflags.h" +#define TEST_FLAG 0x00004; +#define TEST_MASK 0x0000f; + GenExchangeTester::GenExchangeTester() : mGenTestMutex("genTest") { @@ -277,7 +280,6 @@ bool GenExchangeTester::testGrpMetaRetrieval() opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; - std::list grpIds; mTokenService->requestGroupInfo(token, 0, opts); pollForToken(token, opts); @@ -372,6 +374,8 @@ bool GenExchangeTester::testGrpMetaModRequest() init(dgrp1); init(dgrp2); init(dgrp3); + dgrp1->meta.mSubscribeFlags = 0; + dgrp1->meta.mGroupStatus = 0; uint32_t token; RsTokReqOptions opts; @@ -397,8 +401,9 @@ bool GenExchangeTester::testGrpMetaModRequest() bool ok = true; std::string newServiceString; - uint32_t newGrpStatus = randNum(); - uint32_t newSubscribeGrpFlag = randNum(); + uint32_t newGrpStatus = TEST_FLAG; + uint32_t newSubscribeGrpFlag = TEST_FLAG; + uint32_t testMask = TEST_MASK; randString(SHORT_STR, newServiceString); // mod service flag for first grp @@ -406,11 +411,11 @@ bool GenExchangeTester::testGrpMetaModRequest() pollForToken(token, opts); ok = mTestService->acknowledgeTokenGrp(token, grpId); - mTestService->setGroupStatusFlagTS(token, grpIds[0], newGrpStatus); + mTestService->setGroupStatusFlagTS(token, grpIds[0], newGrpStatus, testMask); pollForToken(token, opts); ok = mTestService->acknowledgeTokenGrp(token, grpId); - mTestService->setGroupSubscribeFlagTS(token, grpIds[0], newSubscribeGrpFlag); + mTestService->setGroupSubscribeFlagTS(token, grpIds[0], newSubscribeGrpFlag, testMask); pollForToken(token, opts); ok = mTestService->acknowledgeTokenGrp(token, grpId); @@ -432,10 +437,10 @@ bool GenExchangeTester::testGrpMetaModRequest() if(meta.mServiceString != newServiceString) ok = false; - if(meta.mSubscribeFlags != newSubscribeGrpFlag) + if(!(meta.mSubscribeFlags & newSubscribeGrpFlag)) ok = false; - if(meta.mGroupStatus != newGrpStatus) + if(!(meta.mGroupStatus & newGrpStatus)) ok = false; @@ -475,6 +480,7 @@ bool GenExchangeTester::testMsgMetaModRequest() uint32_t token; RsDummyMsg* msgOut = new RsDummyMsg(); *msgOut = *msg; + msg->meta.mMsgStatus = 0; mTestService->publishDummyMsg(token, msg); // poll will block until found @@ -499,9 +505,10 @@ bool GenExchangeTester::testMsgMetaModRequest() mTestService->acknowledgeTokenMsg(token, msgId); - uint32_t newStatus = 2; + uint32_t newStatus = TEST_FLAG; + uint32_t testMask = TEST_MASK; // first modify service string - mTestService->setMsgStatusFlagTS(token, msgId, newStatus); + mTestService->setMsgStatusFlagTS(token, msgId, newStatus, testMask); pollForToken(token, opts); mTestService->acknowledgeTokenMsg(token, msgId); @@ -539,7 +546,7 @@ bool GenExchangeTester::testMsgMetaModRequest() if(meta.mServiceString != newServiceString) ok &= false; - if(meta.mMsgStatus != newStatus) + if(!(meta.mMsgStatus & newStatus)) ok &= false; diff --git a/libretroshare/src/tests/gxs/genexchangetestservice.cpp b/libretroshare/src/tests/gxs/genexchangetestservice.cpp index f8858bb64..7e8b69957 100644 --- a/libretroshare/src/tests/gxs/genexchangetestservice.cpp +++ b/libretroshare/src/tests/gxs/genexchangetestservice.cpp @@ -67,14 +67,14 @@ void GenExchangeTestService::setGroupServiceStringTS(uint32_t &token, const RsGx RsGenExchange::setGroupServiceString(token, grpId, servString); } -void GenExchangeTestService::setGroupStatusFlagTS(uint32_t &token, const RsGxsGroupId &grpId, const uint32_t &status) +void GenExchangeTestService::setGroupStatusFlagTS(uint32_t &token, const RsGxsGroupId &grpId, const uint32_t &status, const uint32_t& mask) { - RsGenExchange::setGroupStatusFlags(token, grpId, status, 0xff); + RsGenExchange::setGroupStatusFlags(token, grpId, status, mask); } -void GenExchangeTestService::setGroupSubscribeFlagTS(uint32_t &token, const RsGxsGroupId &grpId, const uint32_t &status) +void GenExchangeTestService::setGroupSubscribeFlagTS(uint32_t &token, const RsGxsGroupId &grpId, const uint32_t &status, const uint32_t& mask) { - RsGenExchange::setGroupSubscribeFlags(token, grpId, status, 0xff); + RsGenExchange::setGroupSubscribeFlags(token, grpId, status, mask); } void GenExchangeTestService::setMsgServiceStringTS(uint32_t &token, const RsGxsGrpMsgIdPair &msgId, const std::string &servString) @@ -82,9 +82,9 @@ void GenExchangeTestService::setMsgServiceStringTS(uint32_t &token, const RsGxsG RsGenExchange::setMsgServiceString(token, msgId, servString); } -void GenExchangeTestService::setMsgStatusFlagTS(uint32_t &token, const RsGxsGrpMsgIdPair &msgId, const uint32_t &status) +void GenExchangeTestService::setMsgStatusFlagTS(uint32_t &token, const RsGxsGrpMsgIdPair &msgId, const uint32_t &status, const uint32_t& mask) { - RsGenExchange::setMsgStatusFlags(token, msgId, status, 0xff); + RsGenExchange::setMsgStatusFlags(token, msgId, status, mask); } void GenExchangeTestService::service_tick() diff --git a/libretroshare/src/tests/gxs/genexchangetestservice.h b/libretroshare/src/tests/gxs/genexchangetestservice.h index 6cdb2e041..60fa0488b 100644 --- a/libretroshare/src/tests/gxs/genexchangetestservice.h +++ b/libretroshare/src/tests/gxs/genexchangetestservice.h @@ -76,13 +76,13 @@ public: bool getMsgRelatedDataTS(const uint32_t &token, GxsMsgRelatedDataMap& msgItems); - void setGroupSubscribeFlagTS(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status); + void setGroupSubscribeFlagTS(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status, const uint32_t& mask); - void setGroupStatusFlagTS(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status); + void setGroupStatusFlagTS(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status, const uint32_t& mask); void setGroupServiceStringTS(uint32_t& token, const RsGxsGroupId& grpId, const std::string& servString); - void setMsgStatusFlagTS(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const uint32_t& status); + void setMsgStatusFlagTS(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const uint32_t& status, const uint32_t& mask); void setMsgServiceStringTS(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const std::string& servString ); diff --git a/libretroshare/src/tests/gxs/rsgenexchange_test.cc b/libretroshare/src/tests/gxs/rsgenexchange_test.cc index 3f572d291..b275df062 100644 --- a/libretroshare/src/tests/gxs/rsgenexchange_test.cc +++ b/libretroshare/src/tests/gxs/rsgenexchange_test.cc @@ -21,13 +21,13 @@ int main() // CHECK(tester.testMsgIdRetrieval_OptOrigMsgId()); REPORT("tester.testRelatedMsgIdRetrieval_OrigMsgId()"); // CHECK(tester.testMsgIdRetrieval_OptLatest()); REPORT("tester.testRelatedMsgIdRetrieval_Latest()"); // CHECK(tester.testMsgMetaModRequest()); REPORT("tester.testMsgMetaModRequest()"); - CHECK(tester.testMsgRelatedChildDataRetrieval()); REPORT("tester.testMsgRelatedChildDataRetrieval()"); + //CHECK(tester.testMsgRelatedChildDataRetrieval()); REPORT("tester.testMsgRelatedChildDataRetrieval()"); // CHECK(tester.testMsgAllVersions()); REPORT("tester.testMsgAllVersions()"); // CHECK(tester.testGrpSubmissionRetrieval()); REPORT("tester.testGrpSubmissionRetrieval()"); -// CHECK(tester.testGrpMetaRetrieval()); REPORT("tester.testGrpMetaRetrieval()"); + // CHECK(tester.testGrpMetaRetrieval()); REPORT("tester.testGrpMetaRetrieval()"); // CHECK(tester.testGrpIdRetrieval()); REPORT("tester.testGrpIdRetrieval()"); -// CHECK(tester.testGrpMetaModRequest()); REPORT("tester.testGrpMetaModRequest()"); + CHECK(tester.testGrpMetaModRequest()); REPORT("tester.testGrpMetaModRequest()"); FINALREPORT("RsGenExchangeTest"); From ae5cbecaba4a2a81129f24f4487b129890d6d838 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sat, 17 Nov 2012 18:45:14 +0000 Subject: [PATCH 151/222] Fixed relatedMsgData bug (PARENT | LATEST), same issue as ALL_VERSION opt flags, was using origMsgId used for filtering (filtering worked as bugged request was actually requesting all msgs instead). Added test for (PARENT | LATEST) All tests passed git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5835 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgxsdataaccess.cc | 4 +- .../src/tests/gxs/genexchangetester.cpp | 194 +++++++++++++++++- .../src/tests/gxs/genexchangetester.h | 1 + .../src/tests/gxs/rsgenexchange_test.cc | 25 +-- 4 files changed, 204 insertions(+), 20 deletions(-) diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index fd5e828d4..af45bbdca 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -1221,7 +1221,7 @@ bool RsGxsDataAccess::getMsgRelatedInfo(MsgRelatedInfoReq *req) { // add as latest. (overwriting if necessary) origMsgTs[meta->mOrigMsgId] = std::make_pair(meta->mMsgId, meta->mPublishTs); - metaMap.insert(std::make_pair(meta->mOrigMsgId, meta)); + metaMap.insert(std::make_pair(meta->mMsgId, meta)); } } @@ -1275,7 +1275,7 @@ bool RsGxsDataAccess::getMsgRelatedInfo(MsgRelatedInfoReq *req) filteredOutMsgIds[grpId] = outMsgIds; filterMsgList(filteredOutMsgIds, opts, filterMap); - if(!outMsgIds.empty()) + if(!filteredOutMsgIds[grpId].empty()) { if(req->Options.mReqType == GXS_REQUEST_TYPE_MSG_RELATED_IDS) { diff --git a/libretroshare/src/tests/gxs/genexchangetester.cpp b/libretroshare/src/tests/gxs/genexchangetester.cpp index 3a2e14e53..15afd5135 100644 --- a/libretroshare/src/tests/gxs/genexchangetester.cpp +++ b/libretroshare/src/tests/gxs/genexchangetester.cpp @@ -979,6 +979,7 @@ bool GenExchangeTester::testMsgRelatedChildDataRetrieval() for(int i=0; i < nMsgs; i++) { RsDummyMsg* msg = msgs[i]; + RsDummyMsg* msgCopy = NULL; if(first){ msg->meta.mParentId = ""; @@ -989,8 +990,14 @@ bool GenExchangeTester::testMsgRelatedChildDataRetrieval() msg->meta.mParentId = firstMsgId.second; msg->meta.mGroupId = firstMsgId.first; msg->meta.mOrigMsgId = ""; + msgCopy = new RsDummyMsg(); } + + // make a copy of msg for store in data out + if(msgCopy) + *msgCopy = *msg; + mTestService->publishDummyMsg(token, msg); pollForToken(token, opts); RsGxsGrpMsgIdPair msgId; @@ -1007,7 +1014,8 @@ bool GenExchangeTester::testMsgRelatedChildDataRetrieval() // don't add the id to be related if(!first) { - mMsgRelatedDataMapOut[firstMsgId].push_back(msg); + msgCopy->meta.mMsgId = msgId.second; + mMsgRelatedDataMapOut[firstMsgId].push_back(msgCopy); } if(first){ @@ -1040,12 +1048,22 @@ bool GenExchangeTester::testMsgRelatedChildDataRetrieval() std::vector& msgDataIn = mMsgRelatedDataMapIn[mit->first]; vit_in = msgDataIn.begin(); - for(; vit_in != msgDataIn.end(); vit_in++) - { - if(*vit_in == *vit_out) - found = true; - } + RsGxsMsgItem* mItem = *vit_out; + RsDummyMsg* msgOut = dynamic_cast(*vit_out); + if(msgOut) + { + for(; vit_in != msgDataIn.end(); vit_in++) + { + RsDummyMsg* msgIn = dynamic_cast(*vit_in); + + if(msgIn) + { + if(msgIn->meta.mMsgId == msgOut->meta.mMsgId) + found = true; + } + } + } if(!found){ breakDown(); return false; @@ -1062,6 +1080,170 @@ bool GenExchangeTester::testMsgRelatedChildDataRetrieval() return true; } +bool GenExchangeTester::testMsgRelatedChildDataRetrieval_Multi() +{ + // start up + setUp(); + setUpGrps(GXS_SERV::FLAG_PRIVACY_PUBLIC); + + /********************/ + + + // create msgs + // then make all requests immediately then poll afterwards for each and run outbound test + // we want only latest for now + int nMsgs = 5; // test a large number of msgs + std::vector msgs; + createMsgs(msgs, nMsgs); + RsTokReqOptions opts; + opts.mReqType = 4000; + uint32_t token; + + bool first = true; + RsGxsGrpMsgIdPair firstMsgId; + + // everyone is parent of first msg +RsGxsMessageId msgIdVersion; + for(int i=0; i < nMsgs; i++) + { + RsDummyMsg* msg = msgs[i]; + RsDummyMsg* msgCopy = NULL; + + bool getMsgVersionId= false; + + + if(first){ + msg->meta.mParentId = ""; + msg->meta.mOrigMsgId = ""; + } + else + { + + + // every even numbered msg is a version of the one before + + msg->meta.mParentId = firstMsgId.second; + msg->meta.mGroupId = firstMsgId.first; + msg->meta.mOrigMsgId = ""; + + // every even numbered msg is version of the previous odd numbered msg + if((i%2)) + { + + getMsgVersionId = true; + } + else + { + /** just in case put it to sleep so publish time is sufficiently later **/ + + double timeDelta = 2.; + + #ifndef WINDOWS_SYS + usleep((int) (timeDelta * 1000000)); + #else + Sleep((int) (timeDelta * 1000)); + #endif + + + msg->meta.mOrigMsgId = msgIdVersion; + msgCopy = new RsDummyMsg(); + + } + } + + + // make a copy of msg for store in data out + if(msgCopy) + *msgCopy = *msg; + + mTestService->publishDummyMsg(token, msg); + pollForToken(token, opts); + RsGxsGrpMsgIdPair msgId; + mTestService->acknowledgeTokenMsg(token, msgId); + + + if(msgId.first.empty() || msgId.second.empty()) + { + breakDown(); + std::cerr << "serious error: Acknowledgement failed! " << std::endl; + return false; + } + + // don't add the id to be related + if(!first) + { + if(getMsgVersionId) + { + msgIdVersion = msgId.second; + }else + { + + msgCopy->meta.mMsgId = msgId.second; + mMsgRelatedDataMapOut[firstMsgId].push_back(msgCopy); + } + } + + if(first){ + firstMsgId.second = msgId.second; + firstMsgId.first = msgId.first; + first = false; + } + } + + + + opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; + opts.mOptions = RS_TOKREQOPT_MSG_PARENT | RS_TOKREQOPT_MSG_LATEST; + std::vector msgIdList; + msgIdList.push_back(firstMsgId); + mTokenService->requestMsgRelatedInfo(token, 0, opts, msgIdList); + + pollForToken(token, opts); + + GxsMsgRelatedDataMap::iterator mit = mMsgRelatedDataMapOut.begin(); + for(; mit != mMsgRelatedDataMapOut.end(); mit++) + { + std::vector& msgDataOut = mit->second; + + std::vector::iterator vit_out = msgDataOut.begin(), vit_in; + + for(; vit_out != msgDataOut.end(); vit_out++) + { + bool found = false; + std::vector& msgDataIn = mMsgRelatedDataMapIn[mit->first]; + vit_in = msgDataIn.begin(); + + RsGxsMsgItem* mItem = *vit_out; + RsDummyMsg* msgOut = dynamic_cast(*vit_out); + + if(msgOut) + { + for(; vit_in != msgDataIn.end(); vit_in++) + { + RsDummyMsg* msgIn = dynamic_cast(*vit_in); + + if(msgIn) + { + if(msgIn->meta.mMsgId == msgOut->meta.mMsgId) + found = true; + } + } + } + if(!found){ + breakDown(); + return false; + } + + } + } + + /********************/ + + // complete + breakDown(); + + return true; +} bool GenExchangeTester::testSpecificMsgMetaRetrieval() diff --git a/libretroshare/src/tests/gxs/genexchangetester.h b/libretroshare/src/tests/gxs/genexchangetester.h index adec76689..7dfc1d2e2 100644 --- a/libretroshare/src/tests/gxs/genexchangetester.h +++ b/libretroshare/src/tests/gxs/genexchangetester.h @@ -36,6 +36,7 @@ public: // request msg related tests bool testMsgRelatedChildIdRetrieval(); bool testMsgRelatedChildDataRetrieval(); + bool testMsgRelatedChildDataRetrieval_Multi(); bool testMsgAllVersions(); diff --git a/libretroshare/src/tests/gxs/rsgenexchange_test.cc b/libretroshare/src/tests/gxs/rsgenexchange_test.cc index b275df062..7932a6c41 100644 --- a/libretroshare/src/tests/gxs/rsgenexchange_test.cc +++ b/libretroshare/src/tests/gxs/rsgenexchange_test.cc @@ -14,19 +14,20 @@ int main() { GenExchangeTester tester; -// CHECK(tester.testMsgSubmissionRetrieval()); REPORT("testMsgSubmissionRetrieval()"); -// CHECK(tester.testSpecificMsgMetaRetrieval()); REPORT("testSpecificMsgMetaRetrieval()"); -// CHECK(tester.testMsgIdRetrieval()); REPORT("tester.testMsgIdRetrieval()"); -// CHECK(tester.testMsgIdRetrieval_OptParents()); REPORT("tester.testRelatedMsgIdRetrieval_Parents()"); -// CHECK(tester.testMsgIdRetrieval_OptOrigMsgId()); REPORT("tester.testRelatedMsgIdRetrieval_OrigMsgId()"); -// CHECK(tester.testMsgIdRetrieval_OptLatest()); REPORT("tester.testRelatedMsgIdRetrieval_Latest()"); -// CHECK(tester.testMsgMetaModRequest()); REPORT("tester.testMsgMetaModRequest()"); - //CHECK(tester.testMsgRelatedChildDataRetrieval()); REPORT("tester.testMsgRelatedChildDataRetrieval()"); -// CHECK(tester.testMsgAllVersions()); REPORT("tester.testMsgAllVersions()"); + CHECK(tester.testMsgSubmissionRetrieval()); REPORT("testMsgSubmissionRetrieval()"); + CHECK(tester.testSpecificMsgMetaRetrieval()); REPORT("testSpecificMsgMetaRetrieval()"); + CHECK(tester.testMsgIdRetrieval()); REPORT("tester.testMsgIdRetrieval()"); + CHECK(tester.testMsgIdRetrieval_OptParents()); REPORT("tester.testRelatedMsgIdRetrieval_Parents()"); + CHECK(tester.testMsgIdRetrieval_OptOrigMsgId()); REPORT("tester.testRelatedMsgIdRetrieval_OrigMsgId()"); + CHECK(tester.testMsgIdRetrieval_OptLatest()); REPORT("tester.testRelatedMsgIdRetrieval_Latest()"); + CHECK(tester.testMsgMetaModRequest()); REPORT("tester.testMsgMetaModRequest()"); + CHECK(tester.testMsgRelatedChildDataRetrieval()); REPORT("tester.testMsgRelatedChildDataRetrieval()"); + CHECK(tester.testMsgRelatedChildDataRetrieval_Multi()); REPORT("tester.testMsgRelatedChildDataRetrieval_Multi()"); + CHECK(tester.testMsgAllVersions()); REPORT("tester.testMsgAllVersions()"); -// CHECK(tester.testGrpSubmissionRetrieval()); REPORT("tester.testGrpSubmissionRetrieval()"); - // CHECK(tester.testGrpMetaRetrieval()); REPORT("tester.testGrpMetaRetrieval()"); -// CHECK(tester.testGrpIdRetrieval()); REPORT("tester.testGrpIdRetrieval()"); + CHECK(tester.testGrpSubmissionRetrieval()); REPORT("tester.testGrpSubmissionRetrieval()"); + CHECK(tester.testGrpMetaRetrieval()); REPORT("tester.testGrpMetaRetrieval()"); + CHECK(tester.testGrpIdRetrieval()); REPORT("tester.testGrpIdRetrieval()"); CHECK(tester.testGrpMetaModRequest()); REPORT("tester.testGrpMetaModRequest()"); FINALREPORT("RsGenExchangeTest"); From 92f1673729c728614fd54ca8e8505a67c44f8415 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sat, 17 Nov 2012 21:43:21 +0000 Subject: [PATCH 152/222] A stab at progressing posted, got post creation working and parameterised GxsGroupDialog for creating "create " header for all gxs services git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5837 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/retroshare/rsposted.h | 2 + libretroshare/src/services/p3posted.cc | 5 + libretroshare/src/services/p3posted.h | 2 +- .../src/gui/Posted/PostedCreatePostDialog.cpp | 13 +- .../src/gui/Posted/PostedCreatePostDialog.h | 5 +- .../src/gui/Posted/PostedCreatePostDialog.ui | 4 +- .../src/gui/Posted/PostedGroupDialog.cpp | 2 +- retroshare-gui/src/gui/Posted/PostedItem.h | 1 + .../src/gui/Posted/PostedListDialog.cpp | 301 ++++++------------ .../src/gui/Posted/PostedListDialog.h | 88 +++-- retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp | 11 +- retroshare-gui/src/gui/gxs/GxsGroupDialog.h | 2 +- retroshare-gui/src/gui/gxs/GxsGroupDialog.ui | 4 +- 13 files changed, 172 insertions(+), 268 deletions(-) diff --git a/libretroshare/src/retroshare/rsposted.h b/libretroshare/src/retroshare/rsposted.h index c5becb9ff..1f585fd94 100644 --- a/libretroshare/src/retroshare/rsposted.h +++ b/libretroshare/src/retroshare/rsposted.h @@ -68,6 +68,7 @@ class RsPostedVote; typedef std::map > PostedPostResult; typedef std::map > PostedCommentResult; typedef std::map > PostedVoteResult; +typedef std::pair GroupRank; std::ostream &operator<<(std::ostream &out, const RsPostedGroup &group); std::ostream &operator<<(std::ostream &out, const RsPostedPost &post); @@ -92,6 +93,7 @@ virtual ~RsPosted() { return; } virtual bool getGroup(const uint32_t &token, std::vector &group) = 0; virtual bool getPost(const uint32_t &token, PostedPostResult &post) = 0; virtual bool getComment(const uint32_t &token, PostedCommentResult &comment) = 0; +virtual bool getGroupRank(const uint32_t &token, GroupRank& grpRank) = 0; virtual bool submitGroup(uint32_t &token, RsPostedGroup &group) = 0; virtual bool submitPost(uint32_t &token, RsPostedPost &post) = 0; diff --git a/libretroshare/src/services/p3posted.cc b/libretroshare/src/services/p3posted.cc index ff16734f7..350a559bc 100644 --- a/libretroshare/src/services/p3posted.cc +++ b/libretroshare/src/services/p3posted.cc @@ -118,6 +118,11 @@ bool p3Posted::getComment(const uint32_t &token, PostedCommentResult &comments) return ok; } +bool p3Posted::getGroupRank(const uint32_t &token, GroupRank &grpRank) +{ + +} + bool p3Posted::submitGroup(uint32_t &token, RsPostedGroup &group) { RsGxsPostedGroupItem* grpItem = new RsGxsPostedGroupItem(); diff --git a/libretroshare/src/services/p3posted.h b/libretroshare/src/services/p3posted.h index cd198db1c..18be77e7b 100644 --- a/libretroshare/src/services/p3posted.h +++ b/libretroshare/src/services/p3posted.h @@ -29,12 +29,12 @@ public: bool getGroup(const uint32_t &token, std::vector &group); bool getPost(const uint32_t &token, PostedPostResult& posts) ; bool getComment(const uint32_t &token, PostedCommentResult& comments) ; + bool getGroupRank(const uint32_t& token, GroupRank& grpRank); bool submitGroup(uint32_t &token, RsPostedGroup &group); bool submitPost(uint32_t &token, RsPostedPost &post); bool submitVote(uint32_t &token, RsPostedVote &vote); bool submitComment(uint32_t &token, RsPostedComment &comment) ; - // Special Ranking Request. bool requestRanking(uint32_t &token, RsGxsGroupId groupId) ; diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp index f17fb2486..91d97f703 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp @@ -1,17 +1,24 @@ #include "PostedCreatePostDialog.h" #include "ui_PostedCreatePostDialog.h" -PostedCreatePostDialog::PostedCreatePostDialog(TokenQueue* tokenQ, RsPosted *posted, QWidget *parent): - QDialog(parent), mTokenQueue(tokenQ), mPosted(posted), +PostedCreatePostDialog::PostedCreatePostDialog(TokenQueue* tokenQ, RsPosted *posted, const RsGxsGroupId& grpId, QWidget *parent): + QDialog(parent), mTokenQueue(tokenQ), mPosted(posted), mGrpId(grpId), ui(new Ui::PostedCreatePostDialog) { ui->setupUi(this); + connect(this, SIGNAL(accepted()), this, SLOT(createPost())); } void PostedCreatePostDialog::createPost() { + RsPostedPost post; + post.mMeta.mGroupId = mGrpId; + post.mLink = ui->linkEdit->text().toStdString(); + post.mNotes = ui->notesTextEdit->toPlainText().toStdString(); - + uint32_t token; + mPosted->submitPost(token, post); + mTokenQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); close(); } diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h index d2fe3e45a..0c5ba887e 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h @@ -19,10 +19,10 @@ public: * @param tokenQ parent callee token * @param posted */ - explicit PostedCreatePostDialog(TokenQueue* tokenQ, RsPosted* posted, QWidget *parent = 0); + explicit PostedCreatePostDialog(TokenQueue* tokenQ, RsPosted* posted, const RsGxsGroupId& grpId, QWidget *parent = 0); ~PostedCreatePostDialog(); -private: +private slots: void createPost(); @@ -32,6 +32,7 @@ private: QString mLink; QString mNotes; RsPosted* mPosted; + RsGxsGroupId mGrpId; TokenQueue* mTokenQueue; }; diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui index cd9e01abf..2b0be21e8 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui @@ -28,7 +28,7 @@ p, li { white-space: pre-wrap; }
- +
@@ -42,7 +42,7 @@ p, li { white-space: pre-wrap; } - + diff --git a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp index 71381fb84..ef27fb73b 100644 --- a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp @@ -41,7 +41,7 @@ 0) PostedGroupDialog::PostedGroupDialog(TokenQueue* tokenQueue, RsPosted* posted, QWidget *parent) - :GxsGroupDialog(tokenQueue, POSTED_ENABLE_FLAG, POSTED_CREATE_DEFAULT_FLAG, parent), + :GxsGroupDialog(tokenQueue, POSTED_ENABLE_FLAG, POSTED_CREATE_DEFAULT_FLAG, parent, "Create New Posted Topic"), mPosted(posted) { } diff --git a/retroshare-gui/src/gui/Posted/PostedItem.h b/retroshare-gui/src/gui/Posted/PostedItem.h index b13925802..0a233457b 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.h +++ b/retroshare-gui/src/gui/Posted/PostedItem.h @@ -40,6 +40,7 @@ virtual void notifySelection(PostedItem *item, int ptype) = 0; virtual void requestComments(std::string threadId) = 0; }; + class PostedItem : public QWidget, private Ui::PostedItem { Q_OBJECT diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp index 3bcc144dc..63a6d3ad4 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp @@ -69,17 +69,14 @@ PostedListDialog::PostedListDialog(QWidget *parent) /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); - /* Setup Queue */ - mPostedQueue = new TokenQueue(rsPosted->getTokenService(), this); + /* Setup Queue */ + mPostedQueue = new TokenQueue(rsPosted->getTokenService(), this); connect( ui.groupTreeWidget, SIGNAL( treeCustomContextMenuRequested( QPoint ) ), this, SLOT( groupListCustomPopupMenu( QPoint ) ) ); connect( ui.groupTreeWidget, SIGNAL( treeCurrentItemChanged(QString) ), this, SLOT( changedTopic(QString) ) ); - /* Initialize group tree */ - //ui.groupTreeWidget->initDisplayMenu(ui.displayButton); - - /* create forum tree */ + /* create posted tree */ yourTopics = ui.groupTreeWidget->addCategoryItem(tr("Your Topics"), QIcon(IMAGE_FOLDER), true); subscribedTopics = ui.groupTreeWidget->addCategoryItem(tr("Subscribed Topics"), QIcon(IMAGE_FOLDERRED), true); popularTopics = ui.groupTreeWidget->addCategoryItem(tr("Popular Topics"), QIcon(IMAGE_FOLDERGREEN), false); @@ -88,19 +85,7 @@ PostedListDialog::PostedListDialog(QWidget *parent) ui.hotSortButton->setChecked(true); mSortButton = ui.hotSortButton; - connect( ui.newTopicButton, SIGNAL( clicked() ), this, SLOT( newGroup() ) ); - - connect( ui.hotSortButton, SIGNAL( released() ), this, SLOT( sortButtonPressed() ) ); - connect( ui.newSortButton, SIGNAL( released() ), this, SLOT( sortButtonPressed() ) ); - connect( ui.topSortButton, SIGNAL( released() ), this, SLOT( sortButtonPressed() ) ); - - connect( ui.sortGroup, SIGNAL( buttonClicked( QAbstractButton * ) ), this, SLOT( sortButtonClicked( QAbstractButton * ) ) ); - connect( ui.periodComboBox, SIGNAL( currentIndexChanged ( int index ) ), this, SLOT( periodChanged ( int ) ) ); - - /* Hide platform specific features */ -#ifdef Q_WS_WIN - -#endif + connect( ui.newTopicButton, SIGNAL( clicked() ), this, SLOT( newTopic() ) ); } @@ -108,15 +93,16 @@ void PostedListDialog::groupListCustomPopupMenu( QPoint /*point*/ ) { QMenu contextMnu( this ); - QAction *action = contextMnu.addAction(QIcon(IMAGE_MESSAGE), tr("Create Post"), this, SLOT(createPost())); + QAction *action = contextMnu.addAction(QIcon(IMAGE_MESSAGE), tr("Create Topic"), this, SLOT(newPost())); action->setDisabled (mCurrTopicId.empty()); contextMnu.exec(QCursor::pos()); } -void PostedListDialog::createPost() +void PostedListDialog::newPost() { - + PostedCreatePostDialog cp(mPostedQueue, rsPosted, mCurrTopicId, this); + cp.exec(); } void PostedListDialog::updateDisplay() @@ -126,22 +112,6 @@ void PostedListDialog::updateDisplay() if (!rsPosted) return; - // TODO groupsChanged... HACK XXX. -#if 0 - if ((rsPosted->groupsChanged(groupIds)) || (rsPosted->updated())) - { - /* update Forums List */ - insertGroups(); - - it = std::find(groupIds.begin(), groupIds.end(), mCurrTopicId); - if (it != groupIds.end()) - { - /* update threads as well */ - insertThreads(); - } - } -#endif - if (rsPosted->updated()) { /* update Forums List */ @@ -168,86 +138,12 @@ void PostedListDialog::changedTopic(const QString &id) insertThreads(); } -void PostedListDialog::sortButtonPressed() -{ - std::cerr << "PostedListDialog::sortButtonPressed()"; - std::cerr << std::endl; - - QAbstractButton *pressed = NULL; - if (ui.hotSortButton->isChecked()) { - std::cerr << "PostedListDialog::sortButtonPressed() Hot"; - std::cerr << std::endl; - pressed = ui.hotSortButton; - } else if (ui.newSortButton->isChecked()) { - std::cerr << "PostedListDialog::sortButtonPressed() New"; - std::cerr << std::endl; - pressed = ui.newSortButton; - } else if (ui.topSortButton->isChecked()) { - std::cerr << "PostedListDialog::sortButtonPressed() Top"; - std::cerr << std::endl; - pressed = ui.topSortButton; - } - - if ((pressed) && (pressed != mSortButton)) - { - mSortButton = pressed; - sortButtonClicked( mSortButton ); - insertThreads(); - } -} - -void PostedListDialog::sortButtonClicked( QAbstractButton *button ) -{ - std::cerr << "PostedListDialog::sortButtonClicked( From Button Group! )"; - std::cerr << std::endl; - - uint32_t sortMode = RSPOSTED_VIEWMODE_HOT; - - if (button == ui.hotSortButton) { - sortMode = RSPOSTED_VIEWMODE_HOT; - } else if (button == ui.newSortButton) { - sortMode = RSPOSTED_VIEWMODE_LATEST; - } else if (button == ui.topSortButton) { - sortMode = RSPOSTED_VIEWMODE_TOP; - } -} - - -void PostedListDialog::periodChanged( int index ) -{ - uint32_t periodMode = RSPOSTED_PERIOD_HOUR; - switch (index) - { - case 0: - periodMode = RSPOSTED_PERIOD_HOUR; - break; - - case 1: - periodMode = RSPOSTED_PERIOD_DAY; - break; - - default: - case 2: - periodMode = RSPOSTED_PERIOD_WEEK; - break; - - case 3: - periodMode = RSPOSTED_PERIOD_MONTH; - break; - - case 4: - periodMode = RSPOSTED_PERIOD_YEAR; - break; - } -} - - /*********************** **** **** **** ***********************/ /** New / Edit Groups ********************************/ /*********************** **** **** **** ***********************/ -void PostedListDialog::newGroup() +void PostedListDialog::newTopic() { PostedGroupDialog cf (mPostedQueue, rsPosted, this); cf.exec (); @@ -263,11 +159,6 @@ void PostedListDialog::showGroupDetails() PostedGroupDialog cf(mGroups[mCurrTopicId], GXS_GROUP_DIALOG_SHOW_MODE, this); cf.exec (); } - -void PostedListDialog::editGroupDetails() -{ - -} void PostedListDialog::insertGroups() @@ -303,6 +194,14 @@ void PostedListDialog::acknowledgeGroup(const uint32_t &token) } } +void PostedListDialog::acknowledgeMsg(const uint32_t &token) +{ + RsGxsGrpMsgIdPair msgId; + + // just acknowledge, don't load anything + rsPosted->acknowledgeMsg(token, msgId); +} + void PostedListDialog::loadGroupSummary(const uint32_t &token) { std::cerr << "PostedListDialog::loadGroupSummary()"; @@ -322,6 +221,11 @@ void PostedListDialog::loadGroupSummary(const uint32_t &token) } } +void PostedListDialog::loadPostData(const uint32_t &token) +{ + loadGroupThreadData_InsertThreads(token); +} + /*********************** **** **** **** ***********************/ /*********************** **** **** **** ***********************/ @@ -369,39 +273,26 @@ void PostedListDialog::loadGroupSummary_CurrentForum(const uint32_t &token) void PostedListDialog::insertThreads() { - loadCurrentForumThreads(mCurrTopicId); + loadCurrentTopicThreads(mCurrTopicId); } -void PostedListDialog::loadCurrentForumThreads(const std::string &forumId) +void PostedListDialog::loadCurrentTopicThreads(const std::string &topicId) { - std::cerr << "PostedListDialog::loadCurrentForumThreads(" << forumId << ")"; + std::cerr << "PostedListDialog::loadCurrentForumThreads(" << topicId << ")"; std::cerr << std::endl; - if (forumId.empty()) + if (topicId.empty()) { std::cerr << "PostedListDialog::loadCurrentForumThreads() Empty GroupId .. ignoring Req"; std::cerr << std::endl; return; - } - - /* if already active -> kill current loading */ - if (mThreadLoading) - { - /* Cleanup */ - std::cerr << "Already Loading -> must Clean ... TODO, retry in a moment"; - return; - } + } clearPosts(); - /* initiate loading */ - std::cerr << "PostedListDialog::loadCurrentForumThreads() Initiating Loading"; - std::cerr << std::endl; - - mThreadLoading = true; - - requestGroupThreadData_InsertThreads(forumId); + /* initiate loading */ + requestGroupThreadData_InsertThreads(topicId); } @@ -410,103 +301,86 @@ void PostedListDialog::requestGroupThreadData_InsertThreads(const std::string &g { RsTokReqOptions opts; - opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - std::list grpIds; + std::list grpIds; grpIds.push_back(groupId); std::cerr << "PostedListDialog::requestGroupThreadData_InsertThreads(" << groupId << ")"; std::cerr << std::endl; uint32_t token; - //mPostedQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, POSTEDDIALOG_INSERTTHREADS); - - // Do specific Posted Request.... - if (rsPosted->requestRanking(token, groupId)) - { - // get the Queue to handle response. - mPostedQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_DATA, POSTEDDIALOG_INSERTTHREADS); - } + mPostedQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, POSTEDDIALOG_INSERTTHREADS); } void PostedListDialog::loadGroupThreadData_InsertThreads(const uint32_t &token) { - std::cerr << "PostedListDialog::loadGroupThreadData_InsertThreads()"; - std::cerr << std::endl; - - bool moreData = true; - while(moreData) - { - RsPostedPost post; - // Old Format. - //if () + std::cerr << "PostedListDialog::loadGroupThreadData_InsertThreads()"; + std::cerr << std::endl; - if (/*rsPosted->getPost(token, post)*/false) - { - std::cerr << "PostedListDialog::loadGroupThreadData_InsertThreads() MsgId: " << post.mMeta.mMsgId; - std::cerr << std::endl; - - loadPost(post); - } - else - { - moreData = false; - } - } + clearPosts(); - mThreadLoading = false; + PostedPostResult result; + rsPosted->getPost(token, result); + std::vector& posts = result[mCurrTopicId]; + std::vector::iterator vit = posts.begin(); + for(; vit != posts.end(); vit++) + { + loadPost(*vit); + } } void PostedListDialog::loadPost(const RsPostedPost &post) { - PostedItem *item = new PostedItem(this, post); - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - alayout->addWidget(item); + PostedItem *item = new PostedItem(this, post); + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); + alayout->addWidget(item); } void PostedListDialog::clearPosts() { - std::cerr << "PostedListDialog::clearPosts()" << std::endl; + std::cerr << "PostedListDialog::clearPosts()" << std::endl; - std::list postedItems; - std::list::iterator pit; + std::list postedItems; + std::list::iterator pit; - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - int count = alayout->count(); - for(int i = 0; i < count; i++) - { - QLayoutItem *litem = alayout->itemAt(i); - if (!litem) - { - std::cerr << "PostedListDialog::clearPosts() missing litem"; - std::cerr << std::endl; - continue; - } + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); + int count = alayout->count(); + for(int i = 0; i < count; i++) + { + QLayoutItem *litem = alayout->itemAt(i); + if (!litem) + { + std::cerr << "PostedListDialog::clearPosts() missing litem"; + std::cerr << std::endl; + continue; + } - PostedItem *item = dynamic_cast(litem->widget()); - if (item) - { - std::cerr << "PostedListDialog::clearPosts() item: " << item; - std::cerr << std::endl; + PostedItem *item = dynamic_cast(litem->widget()); + if (item) + { + std::cerr << "PostedListDialog::clearPosts() item: " << item; + std::cerr << std::endl; - postedItems.push_back(item); - } - else - { - std::cerr << "PostedListDialog::clearPosts() Found Child, which is not a PostedItem???"; - std::cerr << std::endl; - } - } + postedItems.push_back(item); + } + else + { + std::cerr << "PostedListDialog::clearPosts() Found Child, which is not a PostedItem???"; + std::cerr << std::endl; + } + } - for(pit = postedItems.begin(); pit != postedItems.end(); pit++) - { - PostedItem *item = *pit; - alayout->removeWidget(item); - delete item; - } + for(pit = postedItems.begin(); pit != postedItems.end(); pit++) + { + PostedItem *item = *pit; + alayout->removeWidget(item); + delete item; + } } @@ -528,7 +402,6 @@ void PostedListDialog::loadRequest(const TokenQueue *queue, const TokenRequest & case TOKENREQ_GROUPINFO: switch(req.mAnsType) { - case RS_TOKREQ_ANSTYPE_ACK: acknowledgeGroup(req.mToken); break; @@ -539,6 +412,20 @@ void PostedListDialog::loadRequest(const TokenQueue *queue, const TokenRequest & break; } break; + case TOKENREQ_MSGINFO: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgeMsg(req.mToken); + break; + case RS_TOKREQ_ANSTYPE_DATA: + loadPostData(req.mToken); + break; + default: + std::cerr << "Error, unexpected anstype:" << req.mAnsType << std::endl; + break; + } + default: std::cerr << "PostedListDialog::loadRequest() ERROR: INVALID TYPE"; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.h b/retroshare-gui/src/gui/Posted/PostedListDialog.h index a0dc4cf25..8889babf4 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.h @@ -56,71 +56,69 @@ class PostedListDialog : public RsAutoUpdatePage, public PostedHolder, public To public: PostedListDialog(QWidget *parent = 0); -virtual void deletePostedItem(PostedItem *, uint32_t ptype) { return; } -virtual void notifySelection(PostedItem *item, int ptype) { return; } -virtual void requestComments(std::string threadId); + virtual void deletePostedItem(PostedItem *, uint32_t ptype) { return; } + virtual void notifySelection(PostedItem *item, int ptype) { return; } + virtual void requestComments(std::string threadId); signals: - void loadComments( std::string ); + void loadComments( std::string ); private slots: -void groupListCustomPopupMenu( QPoint /*point*/ ); -void changedTopic(const QString &id); + void groupListCustomPopupMenu( QPoint /*point*/ ); + void changedTopic(const QString &id); -void sortButtonClicked( QAbstractButton *button ); -void sortButtonPressed(); - -void periodChanged( int index ); - - void newGroup(); - void showGroupDetails(); - void editGroupDetails(); - void createPost(); + void newTopic(); + void showGroupDetails(); + void newPost(); private: -void clearPosts(); + void clearPosts(); -void updateDisplay(); -void loadPost(const RsPostedPost &post); + void updateDisplay(); + void loadPost(const RsPostedPost &post); -void insertGroups(); -void requestGroupSummary(); -void acknowledgeGroup(const uint32_t &token); -void loadGroupSummary(const uint32_t &token); + void insertGroups(); + void requestGroupSummary(); + void acknowledgeGroup(const uint32_t &token); + void loadGroupSummary(const uint32_t &token); -void requestGroupSummary_CurrentForum(const std::string &forumId); -void loadGroupSummary_CurrentForum(const uint32_t &token); - -void insertThreads(); -void loadCurrentForumThreads(const std::string &forumId); - -void requestGroupThreadData_InsertThreads(const std::string &forumId); -void loadGroupThreadData_InsertThreads(const uint32_t &token); + void requestGroupSummary_CurrentForum(const std::string &forumId); + void loadGroupSummary_CurrentForum(const uint32_t &token); -void insertGroupData(const std::list &groupList); -void groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo &groupItemInfo); - - void loadRequest(const TokenQueue *queue, const TokenRequest &req); + void acknowledgeMsg(const uint32_t &token); + void loadPostData(const uint32_t &token); + void insertThreads(); + void loadCurrentTopicThreads(const std::string &forumId); + void requestGroupThreadData_InsertThreads(const std::string &forumId); + void loadGroupThreadData_InsertThreads(const uint32_t &token); - QTreeWidgetItem *yourTopics; - QTreeWidgetItem *subscribedTopics; - QTreeWidgetItem *popularTopics; - QTreeWidgetItem *otherTopics; + void insertGroupData(const std::list &groupList); + void groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo &groupItemInfo); - QAbstractButton *mSortButton; + void loadRequest(const TokenQueue *queue, const TokenRequest &req); - bool mThreadLoading; - std::string mCurrTopicId; - QMap mGroups; - TokenQueue *mPostedQueue; +private: - /* UI - from Designer */ - Ui::PostedListDialog ui; + QTreeWidgetItem *yourTopics; + QTreeWidgetItem *subscribedTopics; + QTreeWidgetItem *popularTopics; + QTreeWidgetItem *otherTopics; + + QAbstractButton *mSortButton; + + bool mThreadLoading; + RsGxsGroupId mCurrTopicId; + + QMap mGroups; + TokenQueue *mPostedQueue; + + /* UI - from Designer */ + Ui::PostedListDialog ui; }; diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index f310035df..b3fc5d6bf 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -50,7 +50,7 @@ #define GXSGROUP_LOADGROUP 2 /** Constructor */ -GxsGroupDialog::GxsGroupDialog(TokenQueue *tokenQueue, uint32_t enableFlags, uint16_t defaultFlags, QWidget *parent) +GxsGroupDialog::GxsGroupDialog(TokenQueue *tokenQueue, uint32_t enableFlags, uint16_t defaultFlags, QWidget *parent, const QString &serviceHeader) : QDialog(parent), mTokenQueue(tokenQueue), mMode(GXS_GROUP_DIALOG_CREATE_MODE), mEnabledFlags(enableFlags), mDefaultsFlags(defaultFlags), mReadonlyFlags(0) { /* Invoke the Qt Designer generated object setup routine */ @@ -62,9 +62,12 @@ GxsGroupDialog::GxsGroupDialog(TokenQueue *tokenQueue, uint32_t enableFlags, uin connect( ui.pubKeyShare_cb, SIGNAL( clicked() ), this, SLOT( setShareList( ) )); connect( ui.groupLogo, SIGNAL(clicked() ), this , SLOT(addGroupLogo())); - connect( ui.addLogoButton, SIGNAL(clicked() ), this , SLOT(addGroupLogo())); - - //ui.headerFrame->setHeaderImage(QPixmap(":/WikiPoos/images/resource-group-new_48.png")); + connect( ui.addLogoButton, SIGNAL(clicked() ), this , SLOT(addGroupLogo())); + + if(!serviceHeader.isEmpty()) + ui.mServiceHeader->setText(serviceHeader); + + //ui.headerFrame->setHeaderImage(QPixmap(":/WikiPoos/images/resource-group-new_48.png")); //ui.headerFrame->setHeaderText(tr("Create Wiki Group")); if (!ui.pubKeyShare_cb->isChecked()) diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h index a417621e5..7cb5ed87a 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h @@ -125,7 +125,7 @@ public: * @param parent The parent dialog * @param mode */ - GxsGroupDialog(TokenQueue* tokenQueue, uint32_t enableFlags, uint16_t defaultFlags, QWidget *parent = NULL); + GxsGroupDialog(TokenQueue* tokenQueue, uint32_t enableFlags, uint16_t defaultFlags, QWidget *parent = NULL, const QString& serviceHeader = ""); /*! * Contructs a GxsGroupDialog for display a group or editing diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui index 2fab209f0..c16d9c4b8 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui @@ -11,7 +11,7 @@
- Create new Wiki Group + Create New Group @@ -67,7 +67,7 @@ - + Create Wiki Group From 3fe147d5eb4ebf63a31d82ca7479f4560378d26b Mon Sep 17 00:00:00 2001 From: defnax Date: Sat, 17 Nov 2012 22:37:48 +0000 Subject: [PATCH 153/222] Added some icons for Wiki Pages git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5838 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/WikiPoos/WikiDialog.ui | 14 +++++++------- retroshare-gui/src/gui/WikiPoos/Wiki_images.qrc | 15 ++++++++------- .../src/gui/WikiPoos/images/wikibook_128.png | Bin 0 -> 11798 bytes .../src/gui/WikiPoos/images/wikibook_32.png | Bin 0 -> 1880 bytes .../src/gui/WikiPoos/images/wikibook_48.png | Bin 0 -> 3154 bytes .../src/gui/WikiPoos/images/wikibook_64.png | Bin 0 -> 4588 bytes .../src/gui/unfinished/ApplicationWindow.cpp | 3 ++- 7 files changed, 17 insertions(+), 15 deletions(-) create mode 100644 retroshare-gui/src/gui/WikiPoos/images/wikibook_128.png create mode 100644 retroshare-gui/src/gui/WikiPoos/images/wikibook_32.png create mode 100644 retroshare-gui/src/gui/WikiPoos/images/wikibook_48.png create mode 100644 retroshare-gui/src/gui/WikiPoos/images/wikibook_64.png diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui index e526c49c3..5dd4b74a1 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui @@ -34,7 +34,7 @@ - 3 + 2 @@ -48,7 +48,7 @@ - :/images/book2_32.png + :/images/wikibook_32.png true @@ -106,8 +106,8 @@ 0 0 - 255 - 301 + 271 + 302 @@ -142,8 +142,8 @@ 0 0 - 255 - 301 + 271 + 302 @@ -397,7 +397,7 @@ 0 0 - 616 + 600 611 diff --git a/retroshare-gui/src/gui/WikiPoos/Wiki_images.qrc b/retroshare-gui/src/gui/WikiPoos/Wiki_images.qrc index 47a905426..76299597a 100644 --- a/retroshare-gui/src/gui/WikiPoos/Wiki_images.qrc +++ b/retroshare-gui/src/gui/WikiPoos/Wiki_images.qrc @@ -1,12 +1,13 @@ - images/arrow-left.png - images/arrow-right.png - images/resource-group-new.png - images/appointment-new.png - images/book2_32.png - images/story-editor.png - images/republish.png + images/arrow-left.png + images/arrow-right.png + images/resource-group-new.png + images/appointment-new.png + images/book2_32.png + images/story-editor.png + images/republish.png images/resource-group-new_48.png + images/wikibook_32.png diff --git a/retroshare-gui/src/gui/WikiPoos/images/wikibook_128.png b/retroshare-gui/src/gui/WikiPoos/images/wikibook_128.png new file mode 100644 index 0000000000000000000000000000000000000000..2c879d444968da11379cf9f133653653fac0c27f GIT binary patch literal 11798 zcmV+xF6q&UP)#&TSWyp~Fl96NF1ic@jLN<~$Q z%W>J2C{A3digQ&eszi~JC|cQ4bgZ<}9^&%8!D~SRBmofT%wX<&I`8Z5H+a+2GZ7lGMy$Kex@m8e5oIH?eM1J8oK;^#Z$p#SJ*8rj9eO z_lf;1G!<}@&@HUn4jnq=I(+zW=#^Jq$tGE2+tRFO*x?1X%t@P&lbRxvO?ckx+Ei}R z0&X1`7;t{F*XlKnluQNpVq~Fo^X%P+|LULr>%U~j{h0L#>v?t` zv+I1$D<9X)K|gNDDc!Ng z%#SH=$dJisCdX2D>D4b^dGOYE&i@DYz5h)L5oFlCEUn`;tk`~`0@S9_o=vcD>Kt>o`WXLT}!jbj?VY9Z}OmL(&wbd?~GbLjtpqtoak}sOj*_gWYd^ zhkluDxyJfs)&YKIqpwwLKeq&+qsL_qf9k2HJjYL++IQsek@p0Ld@qorI8?G^J&T5W zu5shIF=LKWx)f&^t5Ok=){~IiqTawZrz83>eT=Q$Vm*i7-AuN?&kX_S=y4fvrpFy0 z{NP8n9XWF7`Q9BpzhrSsJIPV-M~#o&x9OZYV+&KVv_vIt$QSjo)7{GM?$+Z$A0vRB zY|X=ZO#SV3_X_H@pIHLX(c@U!91e&5rI%jnKXB;Kv8_)Gz1J2rA7WxXm^Mbdla|xg zgmsZJs+SjLi?Bf>J=Sdmy7X;9WrqSaS!|g*K`e^9j z;eAJT?b-FbyWjqtWXt#DY)Rju`GzBInWc;|Mwvo_0apun4cJnHeL4s9?sfOtJZ4ue zQQX0{jFO@Ta+^g9ysHVIjvluiKYrYE;PBzS`wt#C8Q9`_-e50oDcQ5Wm}SEC*feR( zTavOKm&H1CcxiQ9UGD(BW6VyIVen~xVEiYG2iWQlNb$TNnaUe||K#)A=o45?tEb0@ zhlgD!PrfjG;J|@n-8;PRGrH*sa^?al>w@Qz>54gTPso7h%ZeMW8<%SccJ0oU_*W7R z8h%e#h!H?H``E*Jl$86P-{|{E^e!L(2D;WCw*`Yi`>9jE)OYaU{%87kcE4cjG9Q+l zxvrcw=8f2`o zmiguj+36KPTv>$c9^Jq&kaRXXf>vwy9=Ct~W@0~EJ;Qo>v$%sBP5?T3Tn7B`v(Net z?ccv=*RGw<`iGs*le4g`?8pTq_kz3NkqmaHoxDaT84WIFAbu-VAnzwenT{`0_0H;J z8Z}AhYud3S{mr$Tj0W0zA{bxfla7n%Q1=`@Y?gXHt$7R5o9(Nu&a%9Jzz5AZ( z+Ua}2>@Dq<-1(5vm-Ct3S);@4Ae)JSEx9VU7XRzgPiE-p(Y73`HIW{Dj;p1i3`7;6>bD{QJ6T<;j)Hb=nKWAmiubGt}!2eY_0 z8?6O8LI8r{ChBpxXQ7diJqNbz?myukupBda%Y*iSDP#{AZ4Q@}99AFmjY?Eh&GbTf z^$hYTb(eCbOnXJR?hdK(G5k>V0Hei7L&pOCyWgJO$5y|~dR)Cf>yjL**V;k=8o=?{ zP73H)4zT_N>&M^o8%KX_V5H0A>@wTH;SRe)_Qlb`H+dfaW*I$ccAbZSBu;#NiY zO2@6l$k@H@J)s^(09~ZGgAw)qzxxP4hr_Kxce8$w^^>eW>G61;={;LzW;^_qer-@TxEDVoP$n-DEbK>Cxy6Z9g#B)NidugafkK z^h4(NFV;D-{@|^EU2`T<F8rk|b?dRIq6RU?&Q0hYQos z`Uok2Kkah4Mpz%R+wJC5Dn%zwoS-vj&XB|5kiSV<#KX28jW%X=p1}3%jGf^qGgIKE>W;6(CGHo?1IXO z7XWrd20c-TvCZW=Lv&7r>z}dyMoDLf$!MT0$NYom40MN`gP0xMFn6$72>@~bB8)rxSv4bnb z0i1V82rO+j8!av_($LV5yaec?Bw%WSW^XUiu4k$TN0Mf#BF@9inonwO;N}tG4UcXR zVRYKf>^?|xRB-UQfS(b-UQ%qS4J{IBmH?di&tx*$!Oa|SEfJun(`jNBe+6{0qfK9p zQ2J9zN|d4%9gevDyFr9&SDOtdn@vWtnoSf-X62LLay-~K`ah?GY%el|$PR8;k;tmN z0H(*2qORwli-Z8<4<+&7cC8&C69N18#)a3&y;FI1Vne`Qg9u-JIC*)+a+PQu3W5uQn81$fkh(5CXbVi6n28iOeRCwY*tqVpfitvW@ct&DWFvWSmK!6 zgjt4Od%2QS+r`_dbV)Wm8R?PN5}+R2U}dL7I$c<)jLXN-9xX|==b*t=9Jg|g%O7e+ zwpkS(%Vdj{FPm&e8hFYFOZX5et~4(a*|Y?}0~SeukIuPY+W{~n09ON|D&XoPaa(Ev zY^ee^x{3V-EL}A0+DnInr|3k_N9Yh+7Ud|SU@9~XHtB+0MUXW_DK!LJvx}*FgRJ|L znL^dCqis16KtymWDYg|4sI7Zz_D5?7pph*Amk*KvOOg9|&&?XBn3l-wG}IO07NeDM zc#wS7klfv7pKM8s$3?Pp6wc1JtglxR;mz#U8{cWSP_Dq--$JS8xSl7yC=wZ!N|NXf zu6ty#Spwh&N&?`+2EY>fUe6A2I-Rtzus~j~S3Xv25Lzu(O5H1v_u%pm*i3fvF%I`y z70{h#Pwkx*J|i|T7QbHO9yVo|)gab@gjN+!UfyG7MxVuEq-ZRwYlGPQR$JE|cVIy& z5`jCoAw?pqkpMWcxES;S&{{75&0?`oB9Wj#AV5=7Q&qMAI`(Jpn`z|P!3u}lP0qSt z>)rCn4qmQH8D;*z}7p)s}<%tPLQk zCl&(%a3YY6F&znjbr_5F+(CSA>1Khpx<;tizJ=^Yr-n7P%Dh?^r;90il)6`Qg1Y*; z%6z1{`dT#jwE9{cnA;?^$1ES_uvz5onOspvwn$_#Gq=!UqJd+6Bu4Pe0PFz-+f3^T z{%Q#TYG8rs{xFvSViXV!z?)1ac^ymG09cCpzv2$2%rrMYzarRLD;({e_zmV#mFt2n ztpV)1K(7F{)_}x4fZLab;inx(KFC0BCLI##Jb8v30e7Fx%Qo&NMGBajeW-K22>^lj z6ze$#>U|Er=naU3z@vf)2g42!T|xdC`)BTiR|H$z=Ch9}nw`@JyO!x!2euB-D|-v- zd8lJJY$jRkgZpcbVyeMqrDRG`4Mwwp2A=i99Xv?OYG7TZKvM*u8YVo~Itt*q8W6$f zpZO9|L8ODZHz4K)aLj{qbE`VpqEw=LjQi_?O|5~wQVc)~Hs@+?4uE-`4$HFJr|}wX zOzdNsE0ijvJ9ymROG=#}iXD0B`?|H&{21gl43;Ylc!_m`HY%uHf=D0%v~~a|hWOnq zCG!b#TRk;D#&0~r#IanM86Odf<`*ef%+{9@D;Q?t&XrAVNgS@;FjXsX`y_CGwkVDw zFA)=f=numy5C#tJaSxd7CRZ_A8fL2tw9c;JY6t)|YEc zFpNQnd#w#1yMsm>J$^V#BO?j{;Km^H2e9QlK^}R6I+JQN19lTJfC@~j1Y6rU_d~bq zWiGuQ8^u$3S@es|;x?Olj(7r(&n}@zl!CzSaBiN) z6L%<_o2Ozq-&TFCXNBwM7xZlkMOEnh2|vicr&#v2;6wC#oK}h@^1}6qrYlkJQST5t zOmqj=%??;?0%BfWUM(oCLIhgQ=j#9&ssKw7_)30Y(MZK~xd!M;5NAazygt~~N2~xg z>4RNAzp#8B4!fH0kzK!K*AyLAe#-ntnH07@*Zp7$LNK9<_3p!gXCAjShkRe-Q? z_}IEYhAr@)!D^_4kqT34+kZ_-J#OY0G>L)QSHjssJaw?N2J@>THx#D}pQknXX`M5g> zPkqoM*%EU zfv5)1v@Ril7K=r-MDY0Lf*cMWi`{4pws z3-(H}2!lFldl~fv{kDL6z=p6eCYJ1Ykw`1G=$rs9GC(CgLr~j6Bp?7>yp{male0Ox zJ%5AprF>gNxTN`_v`Vn`L^!}NGEU9rN>$?_=(Ci_ttl1(;wh9Ab!TL1q~{r5h;2Sh z>rf=p3IXu+@GQD$2gn0!Lc(InIK;iSWL(Y}SnYK6)mt4G;mv}rC&HD$Po9&E{D*Ka zL^xc(=7_EOJfZ&~{`q))&-zd#f~SUfVyI(wKq~}*urSiYum|qxxr2J~0G8Tm^vj!opfLfOvo?`bB9_m^XG*gs(s)$O*{zNhJmlHRZWRhdxI5SpJD^npfE~cY!guT00cfH@$n5|<2>@Wy zBU*_*x%}OTX@;J`{*-qvbgm zHzffe_KBDP(!-DHWe2rg23oBZ)CPp09u_ZUbfadX7tq>GZX97;%Xsb9EAFlKUR%(D zT0z7GI#MLkG6AURVO}OSDo+O|WC-<)KyC7|Exxj34b8s_T2lC@JdyzEI@QfKjT9{s3S!p?KCKOJOJ@oNt6P-NJOt(92P$h4rz-; zZAAwyTuM|$0>zAAYd5*Q(M9g9w8f(k2VfsVhg_IR1O=n=YwM|v?qE9!0IncZ0Mf$? zq6%na4C1CC9v}vV#IW%EnPiQH-JYA=<|ZvK+UlaRbz8U9?;5fpDu`;Kwib!BlK^;F zSWXWESWybps}t0FXhgIH^0ShzzHWCMpe=g4&2fOrPzac8av<$ z{^JCI4$juI0}wCZvxx967L1y+Hp)f|)%vf;W@=-R zNV{{)+zz0j4%6#9K3AVgB%F>}KsOA?jCIJ5QFv7!ku|XRT(6a-u53`79jX+KWQqrWOuiHlfZOaC> zEfT0nR;d@={j>+}AnX8m0=!71rPfvg&^$d{6&BW$0%+VF#B+oAzLo&wuyDan;p+)a zHn7EWZIiwhF20>NvL^9`?%V6$!puKp2zhp}Wjmk~b!PnOVWfw%d|EiIJII&fXNY@k zKnUM=TAeh1I?;B0-3c$Cosq!Gx;m!WYj*l}IguH}1k-IP66pj1@bob3fk|x8lK|p* z^Qa)7MMR7Vl*`J~H<_tojbYU4O>VTlmI2$H4Xix-ppI%VN)$Tkfjii?nMB%70Gg+V zZ(*CL2ILU0PSaKkYs12(f|+t*Vfxh;Z?ln%RXW>hw6-*!sIOZct0qV-5JcdR8!7;X zAb@W&D*xr4vg(pYsv-|T~t z@q6f~n+JtjE)wa~BS$|bZSnCPMJ-%EIfSa+9nWJt; z@0w2VnZA?s)nEC3+b;M6+deAywls~Kt0ndzvjb*+Sb6;{FA`bP6tf+X0BTq`tghmr zk*e@6pH+-EZFZ3BWo=x*Qnpd#MxtT?#&gk5oc@NkNOrNR{G~z*f?DwGaBMMJjj#o5 z)MAlHC*M@Xrvir^An_PKe~YMI1L%BiL2XDF>(;WJ=FcQ5VsSb-*}>D_m^PD~u60qV zS_+t)CW~*s6Yp>yrWT7tI!ORxdKg|o1$=G?h;abE&Z~m8K_Pqwaiqp`6_@K)_(lg$ ze`DI6@XeL&8$%^K*m99bCka4I55pL&fUhS7I3e)aLi8knTq-7+V{~Ed&);p< zc5ddUHQNlNOd=uv`S-gK40?hT4A<-qc8mZt>0vo6tbK=|Ud$X|V;&)Oj9PCXZ=;3t zahXeQhOg5?dUY?I*vu`)Y?@26XKTQg;Wtz#&}>~6pKGff7I5Ve^0jDzPQR^Ed~8g9 zvQ;z&MHi4a4!X8jlrQl=g>t?IY~}tKsw4r_Vd$tA zb^xDOa7{%bohAUD9)`Itv#KZo_#4D{(@PKYP;ga#V5wXQk-jqaHTkV0@Ad}n|37#C z2T?WOSN|ERB>^JH@*Avw?aqIrx2NCe03ZS2v&qpa?Mo!}nr!e{tu>y2TwBOaJAON(hDa4> z`HxQj0bO6X+>r|aasB4EKS~ed6Kx;+jmaOR6P#>aR6^z1*Qe|P!Mm}o550b3*ZHN;^tT4=<- zhr;(`D468aldjqiZ0ZZG*0`|~hr4o&lu3~P1lu6qk@$hN&jUZ&S;Jrl#9}eoV*oKA zM2wE@=!M=4?f=47-QNs4y697TKT99m`8RdnOIWX6WPbR!m^-F$dhP8|JXXeeHa~rO z|KFh(x4+c%_}Nm1{@=ZC(pPW&7iRS@)xcn=K}6Wjn%QV3uhmBZdx%UK3!VASIcef@Q6958ubPxfWHuQ^&!0Tr4>NyU+ zNCatflAiqX4xI~HzAUTBMo;%WC-)};d#K+%NPVt>%Ko{`6om^@bZ+tj{c!vTG@W=P z09|{Fv}+juSpNxnhV@;+{qoo#4m5E3Z0a#Bl=>F~0SEH%Ye0cVZ#e+RA^17{bdpt_}b_Ch) zo9ODD#hNlRgYLIi22R|E7fFu{d*v5Kj*dmu-!SMNFV914aZ||NMImQ5NleSkPR`Ld z13Vo`Q@1ljd$$}QXFN++PQOO6r3fv=OK;zw%l}LE^=qU=Uei#!%@V-6yq^wXVRk}c zl>n}C0uaSM0M&e_k^tgwBIi<}@|01=MB$4G^6zuk0j~BYn9T<22|4M(bV8n^*U11% zrj;pP#qTxCr8V0%$9Dx4>6XecV^^vM9&30XQh;%Ix3iZVB{xOqBXsZL1A6<;MY5Gm zw7vTY`pk*X)Aqp;S!F_XUON2)8oP0c67ePSI;3IsevZ*{FsSL;fc1P)@w|GXZ?pbM zY|!d`E@?!G!yg{SBV=46Z~`#pO%%PFB*SNFVW}s=dxI`!Q~m>hKHn z`@j7K*$aYn1n7`@X!soJ?jw)aM~hYj%Q6EFtHGDaOGpkyRPZ+?0id7{*6NJ<*{Age z_|w875y%$5`tCt45vqv5VxnTAL>8}^R?^p)&b=q-psBf({9TV*0SDZvFEZN9dn^;*ZGV^2%xvAfuy! z_<090VAXPDT%=?gk`P0XfmQ*|(?saZwWlK>D(TT)N*0qcjgIe$KdoJa(` zNJI-fR|RI1nHDd^Y2f{#6@lvsIb>bD6wk>=cwCB`na-4!ztgmSuLhep1aREUaDzw> z_>5%F_{q#<-`%TY^y3?EG56IVi}g=E_i5VtksVclL)GCr0W#M45}nsof>CUCC%cXk z74kXq1-t3N?6me>gH5}G>qY>o9RM|e1jcz%=EJWp{Wh6u3{GA@h(%U5ntG7_hLUmu-3@Lu|@&;6bZCP3$0jmE)-$miQ3_4qWpypkH*=4K}8>V?yE z^V$XK8{9@SiwP;3F5Mv|>9*=Pz@wr@@EEMYAUy) z2=8X#qeWsl*+B5PIrkTFpm}ps9&R6tH;c z;P#{Rk3afFa=ScLTrS%I3`h>N2)^h6!RC>PzL2BQE9dCy`M2oSjf<3Ih9AU#sCOIP zz4xHB5KWv(=gP>BLj~}X>!v4_UT*?OsU2v-VCfQrKB5%RssinHE&%_hFd=ae2Zrr*(E2<&d$-TH*eB+um6CI zj0lIjN9YsBK1o}DdAkfI2OMC7csbCVyKxM^W;9+Ofo1jq>ny3#c2g1nPY*+9-6O>;tQh`rL!G z&9|L`)-H-g<8=4dUHV@azd^CZ2(#Av=)}SI(#xOztttbJbGZmMCj_p`x%A=$AB`+9 zvHlj_xOA4rZeNuRJDc4_(O80JBRT2Hog2w?CKt&SrKx15e2JMc4@jxC1mK8CBYKrp z*K@Rrwyp%AUOa*oa9L3N_8i~NC4sg&NL*^|0RFu~1O%`|yFW7|A1CT-=>BfT{m~fS z@}=y9b&i(JmY9B35-|>olX_kKw9UIi7VCv{ksdsFNI&}CoAl`3IC(8D*;@aHFa9AT z9#@6S`O{1y(4u(9x@gzPA#7&6-5$L}*Dm~&ZePDhv86Ei0$r5J6)7Cc($wSmTr?Js z=8Mu?DqkMW7bJ*xB+}qLl~qRKg*N;-OsIjZntR!t1faHg^&;e#OyC@}nLg1Q5Q%_q z*Ln-GH()hVDN`nk(?p^O2iSP0Pb8XG9-(1i`F)E1FXvqJ+`v<`m2tUEa?s4|3|;xj z75c`tZ&EQ+pzWdU^r5FdLfcO5sESx}<4rW&c%%}bb9;rKH$aCdhaMljdX{~@M{Xw8 z$!K9}DM6EuBc-{^cVoGHX_5K!_fxs@6%}yUOt1iPp&1qAqzZUW?OFAh{A$79C<5T= zVUv1+{TxKm9?%o@;%wu5$(zM#rTMc) z%-hLq@zc%G+w_%lU!m~)f*fjndiP0s@mF4wqi%Rw832nRXzs3w;+>0q-sDLx<8h|L zPt(5iY1v?Pt)Y}`$;C(!?}X=IGHV9VUEZHQp9>v1w1bRo)Uo0 zsY@7qkOU>Eg;@PY5CBgPBZqy96M$&livc0NkFRUFpSMD!NOR|+H1z&%1q95b(Cs7U z?a^M>ar*GVy;NXaJw7o`XV09YiLp1yVX)Ik{~r3)gTKL~f?oz5Q`7Mr1vlQfA;*b< zbG>*@2=b5JzD8G=i+1bUIZDLBG`O6Lcb=N&94%Vz z{5L9qvo=3F#Wl|zje36#9e6{zuspB?60-*89rSGX1YZD~^zkqsCLGCT^?EnaK3!FH1jP~W8 zrU#?r^zC!sqlL$_q0xC=0*HxoIkxfmJ14emHqCVSdAiO( zAG>u`J_oliD2w&S3u$_I`A#|>PcAT9ZkAc=SBquoAuWf#aUlf(@T3OpoO(|%k9GV8#uKNrUy6pA zwf-iJUOP`y560vmjK$`n@KTEIP0W-h-?|V>XLDgD)*mpjex02z0Eh7g5v~>MDFJBC z?Ofll8<#g~8zKSZA2t{e1cDSmP1j%W?Enox0I066E*Y#$CL;rmWXRy)pxgmC*WV%s zb0Xj!pmV?>HSihRxjHEn@^t&gMLE7cJ~j$>gnZ0+W1^hyjZe_{_(WzY7F*00>2V@c z9xaq)u@2DTgM-7hVqN5L7;;>X7uOT;O)UY`hRh&t5_BZE2M;&MT;AK;D|2}`9F~Cs z;D-+%mgf`}f#qUc6zyDp<1;uMpmS-!Q>>3C$LaDpCf09WqIfhy0f_ao#C-A$jolk7 z&P>mQbEWbE6YKA!b7ffT@&wqV0IC)1qI<@H7rA@`Z}G})BME@Ndl;yoo^3a%76h=c zupk2-3|eRldGIbF=ZcX((io~GMllhVT< zz8OnqvWvL_J&I>aHyCChN_504fFMBDigm5=wrRxrYTAYofF?bR?BH&2_{_`Lcf2fa1l@vXkUZi{X&St~m$O7}p zXA{}-Ew);v43IWLTQePb%a`Bt3QZgK8j^Zx66vPE+$k&u`UK-Hq0mAh_+!~fc)c% zrHTpqkjDGFtbYgu@TD((Nw)9-HaFlv5OZ^LboJ_0`sq)9O6SgXaPx866#^ zix)4_8*jWp^YioK*8$cvDIiagVo1&~SB)oBz~wwm%DEi6TLgYn`Q#hXHdF%0Ctxt3 zRtrxJA;wg2(3*!#Hzvj1*`v%xE!V(it@VSTpDz7@?fa~gU(x2A1(Ymz4wtAoI zZtEn`ZTOQxYPi>^cD>KyHY9}*4MZ&9cS)J`0u4ZMkhuQbR0nB@Y zNFl&Qzz7@;-3<-~sA*cRfh!1I48oLYWv&&sH3GC5fa`7RXs<^Z9U}l0a1OR!H)=jN zLl`&@)CY+3-tlweftU;}*Sv8;sQBY5;94$k1oBFtwF^w~oXSlcS8ifFy>${}5*;A` zHYf+ytXXP5YuB{|qem22N3kes1)S=IiScv}x(GPeB z?6z{fxtR6ZYQ2E6N;G;LMzqYiqIeexLQ6P$1jHX9GwT3p6pmXf0D9XDn$LP*@ZT5L zdE?&`*NLj7SSOlR!mZkUU9$}!7bUfCMi* z>`JU)7lhz}7bI@G((b~FRcVPzkxCIzE-kbnv}w~OB~6^9j^j8dwqyI)=fXe7$FAMP ziOX2OX6E051@p}tLg)07UZ@jcct%*Mx8k&y3^N)Z1h1Se2GbdmF z9suTK{;6l5ZV7Zc9#1)9e-i4H^{PMKnC2xbvR384kA3$-^kVW&y~4uR4S*(CcHh0% zySX>`2)yZCIbUL<5RjWwHp!vu8uGJs6qY&h_UOS=?~UJ2>*kgNAS_2~Q&W@e-Y56$ zcCE2I@XF!mx@%W^S{xp$Gc1o`JUNv&s=+j>!>o+D;YQCNsPdCcFSjw_8lzUK*4yp& z`)%NCx+I54k-sKhqfiu@eT3I0D7oqBU(OAAVIWQRrbbHs>Jp3KB=EuviE0h>- z>FVnGnwqV$EL)tM4^EF=)h#+Vn+ansJBxTOhGbTvO>1Sw3I<9U5M6?>wkNRTVqf?G zb=7JZ*w)d}v2Jp55|Ky*(wv0Pzc|9zZsnkn0S*?pMIW_c^mSaNzQ{z0j^}wabb7WC z06QrbssS)FHZ}&Q(}|jz8pPvqq(`0T>}iKjtb<3ag_NDanb?W4-IfNPZXysx9n%r>3TKQ53Ou?OG%f3Djp=5%g?AMv=?tFE?(sX^C7; zWk(8%q8R$XW^bc&m9?jm7cAHG&s@23CBgtO2AG6SMR0DWf03U{jTac<2!Oy_D1MaU z81QtV-BG)f*5<1L5TW23QdQMBMl29x5eXy5LyLB%(wEVGLuouEV{J z)^@EFgluq@sQNY>4)=JyUeHyHWHO1m*;->k_B*iqr{ef~`nDLMcku30McuwnZ!uia zx9@aOw{xN^$O&8*HNRbn0agwX0F}9cNh+0s{3}-sveHs;M`=-1ebG4H$J-jW*YvUn ztr`HM^Yil)bpNAp92285a!GZOv7(>LKrOBFZ*tv9OL6DtQF`!leB{tjr?x6k7Yj4G+ z7+~eISS*$`0U4(uab8|zY?Wg*+I$^lx&Y~dzKx54(l4;p%Z_7N;8#jWrpW&x+WC4G z2kbtW4t9)zECTnnIc}rMO)|F<0}{#L+}xaz zI@Q(HA)QXsWo*YsLm%LJ%DV$^(Otwtu<-D-yPE|ke{-o9mIPoXl84w^P)If?Nx}TN z3=R!{jF-QE5o7VuJW@(jJ{kTWo;dO#`Y!#S5|)IaA4?A7ug9OqvGLCg<2)z8p}8!A zOJMIp5kbYIlu$CB2b-Il9mb6qi=n2$hfS|F8FxMV)q3r)iWbbo(nde8htX~bIFOJy z2yqemw1zeIb;ypyaNwVZpNuB8w_(1a6_ZjbGbEGrAZ;id$F!6|=%ZP*J=_3?T{Mi# zGG#v&!7yy)ZSZq`WFuMF!cH`+E$Hd$McZu~kXnf2VCWqss~I-AY5*ijPE#OmU|A9? zEEwH&F2kp80${iDaOLVLOIIPr1k`c?bkuLgt=s=dnUw>hBZD~k)zRGh1Fue97`k|F zVp=*GPiY?#+uDk0IdcgO`VSf1&z@GzxQaDoMpU$0Z-gGEpp3gwBR8V=_Py}e`ib%= z2KrCv@4of-SpUzbE`%l`XQrm(2NmEvEg2Pj(S#z6~J7aAKI9WIv(!C(*@ z+Seo4z7Cx?bfc+p6^4h-;%xuP^uWOB%OjV^2QU2^KAOs@-_X3U$zpD)ucNBIjA#(M zyT9DOfB*LG?ryZUwi@H4$YtgH;6UW;FN5dKU%GrEDrNd;+&J>*JEK?eomcgz84Y}9 z$BrFu`2GIGv17*uW@l%AqL@5RDZ?2vP}3yJ^?uw|1YkayEb8p01W4FJvS1oyepHZ; zV$H18B}7?D$c|DC0GkPdiNh53*~Xi53de{E`}oY3h+^t;C58)t)Pj2o0Dc3A*B6Cy Si9EOf0000fti@Wa&5|s06Zdsydhg>5HKa&U zl#^#)b7mgr%{lj;d*6FQ1E`uLNuRl4)1n#fIeN_d;!D4K>e#V+57T)K_ZKxyDS=PB zX|Umku4B($^W#rH_JE;5cqC(r?bSF_O;LWy;Tuc`Uw-zjXGBqY6Q3_^V7$+kfcyZR z$z(GA=(!&sa<&*B9YjxtLB7hGf zz}y25K3sp`?v6+Gp6m&$$GFGZVDQF_K7J-SQUIrbRSzu{{{zdz5#O6nUiuy$o~kCJ zO-V@6@!oy=Y{$QT&rws0^oXO;a?tMOTZ|5!g*Tem_edHSgJ&QqBvfOnNUUN8)n$x| z2>*Dj|Ap{e@_EFNu7vo$U2E+FD_I8eUYoTt7P4@Jv zKFI6QTnNJH09;Q@S+}k*lwl|j)FW{Bz zW(nBQ0}i9n2pq=&dLMGR93$ZyiNQtxhY-uH;Pb>aUZr%BR!dA72}vc1y?Q@y&_PNP zIFwP(%$dMTwGhyjoabV(ScJf%jPe(dKq8TVXdnS|qe~b8k;#PDTA`8O2D|JB;h^g- zOc)NY=jBBviPGvZeTuMp%+B-2RL=zZE`Fh*)4m%Y*-)COwL~C`U}K?Bh(&;m22LiE zjD&sC3?1EF;Ly8((;5oCy&4{bw2&_Gyi{_ome6W`@c4{)GVk!u9dWnyy*S;2hqGu^ zXXSDcNC<*39S8(Kr_(V4Znqoo8Y964EZ{PDL8sBnYZHK#bO;vXGi5vv%!(o*<~`4@ zqj8)T(wQ6^OQ+LEp%~gHe!m|S8D%mVmJ1Yt&_oInsW`-QQCL9G zBcTDf96YxQR8&hw4Ys6DKG!4YbXH(hNvn|{n-jp>?KprKESr)Ll`quaU@#c;W96x* zD3B2edT=71gj4@I4NZ5N%T$!Y7@+DZI*?Ra((5sCGXjf*LC--lm1Vu2{k9$W(SbP5 zO6sbx!3a=WM)0FZqL2r5b#<(iQWP@RH3bPE-7<*@WhA4VL*d+j@=2w0=y@s>A_#OJ z_PaYQO}xu+2W)ViR*rxV?J^~@k_SpfA`+&s8+JPn!tI`;VA5JDRGs{yt(2V7$LSRB zOE|s`Wt1!2kJUlD_nXbf@NuTi5}>uf|1gnR6(AB+O0`-oOXToe0&HnFEGHHqnvLW= zz7E*ZL}uRC<5=i@CY^M)C_kvII@`>*LB5<;t*2`U$QquCL?Vky6v!wFM1Z33&TH?% zbY!fMsFG53#1gQg5*d(*B0&5jurEq%DVfU^%TAAuGHo?@HChdoQ{84FKGeX0JJ=7$!OLTl0T4c+!5h{3p7 z0+a{+D=RAuJdsGJ(`>Ov5y;Hws+LH#SBuD?*99S8k7$xCm0bS11ofY{Q8~3%Q&HJW zM<7|e@eC69Ni-TY5CM=MNCc9>G%UOyho-w6MJ4jo{TJ4Z^_Bk|V!fvy>|fLO&|BRs zTyH%*u%_?MYaMO)u@B7;>&(iPB0y~clXs3*q)Hy(N|g~Hi;QK~l*kIsV38`@CsyvW zZsR@HZKhtRQcl++KzVS5WTX%vqh$pVuxnj~R~-tGa!tvPihULCqlkJA*@%F7vjhTY zpI|j&$*Yu8YLpMDSrKw+brq@rQmoRq4!OGBmUcXBT(6u~Bp^@YAK>g8S7bzUf!%J; z=Rqt5qkmp3ETJoTd0lcPv)Nb#sGPdJZq-`9 z`~YIntCUi5mG5J`j9RYYcKcm;#NP^mL6Q+QB0w@C&_p6Tui21_5g_F6<1P)9C{Pm9+&~1Pvq`vlK2lXeyis4iZv**ZZ@28kQzB7TM(Yxg-ws^D zk1$0+k&(;gVoU6FDhp1qS@;z=s1}2gNv^(y7@2n{k!78uiSU4?Db?WQIs3b1J=VU zBXKIH$(kY{w`H^e+6z$PQWNBL5XmS!k}S*xL%x9x3|GBfTt3eheOg?alDT$S_TuGc z`ITnP1PJvzn7kt80yP3m<&>h3@TFkvj|=SDo8y1KW$=O|z+ZFZ>#=2CpD^ z9Rp7!c%4bxw6CEH%53&G`g)!6U;-yFw=x?O5t0%S5Q3|3pI;w)6|SvJ!Z+H#4V~UD zuy8i;C6?i%h4 zq`8!Z=x|8#58fQb;d7b9KcsyDd7lzkiHOBvhL)$D;Apon?NZ};9oWnU zW-|-X{8bGU`q`0uamQ9G%*@B3&gce+Y9P6g06uPlCjD0Ua_?8+?9$Tl3@n@uf~&(;0Oq!v*`__2$}uS@3{>#JW^{m? zb3k$`4(@3S@M$v~ZoeB2-FukL_{x5~xuq4H^TFHZ{5MRSBEa^l8qES82GH{jJkPVe zfg&T4Regt>>6QQ*jks#Xt)jzf06*>>XbnZzdCm-trY(@Zk%gQO7l=_@qC4B*c+bON z+iwSx$pkcZCY^+_p?(;-(hq$fe~_HIHaj;l>!X^x=GA*GKQU1rjG^WmsC-f*64Z!9 zU@!vPzUE<`b~||lo`HH74_gqhRy06nDFqPLfH7l+`?~Lk#*Qsuu~-;r^78eW3FtpN z0O!x06-I}Lm;I6W{QRPCD3TD~g?tg2DfRw_b3o1ms#w23`?>P=nt&^&*K^SDMJF78 z?hbI7EfBqi_e63KU&z9~mfN9ce=m^q$gEZ?M8iS2I(!KR2hPDj|M{@rAG$ubusrDt zCEm@7a9MU3?Z%?A=S5iwnd1?`(Q*W_D@urf+&~Db$xpiyz{+BvIOnhao@r2<3k0xYb`N z$tyk_q>;cm91hsNeLDl$+S&>pkB7YsZfAyZXH9NT!2%kx3;S%0^L-w*F3*lCOo351rCD9vBr}N&<&Q9ienhOR82jS$& zlbPVn#c{h?7apIU?~5gwEM{d7hafMDTrIzUZKT!wJ2A?Krt}xPyStB!kB{GoMx*0+ zPO~JvQz?}N{lcx5g`~F4klAn&%T7L@#`NCpbd@Lza7A4D)D3KDWM6x9nj-xt}Y$vJPGzE$#2+*{RTNFjw zqCt@YM%w&p`ltO-^heU91p*_9<1|*`1ZiBm2`!1TB#IJ6@gcs%$CA6;_v~|Kdd{7h zNDgLzxRAF|BZQ~EH7Akn};mo#Vp?Nh(_ zb|#+xDt;&0>{vf^3s3-)mQ82QKJEIuzkl_)mM1K~!?|-u@(#W;YPs!97&mkUF<1Of z5hHP6&zb{6?xPRi4*Bp%0!7&Em>w$uC4Su1W&iW9{Kd&YzwdJfSAIxvX7{CSi!F~V zD_l-Ws~7>*ErTt&l2km_J>1fX1f0a(#a~MTR6jNvjn+T-{1^KAhWGuh$tyl%_HlhW zce-^&f6bK9B@m1PQPhH!w0KJ?P!8-r@9%o|o702%y|?gVuHJYaI{{ih{=_FQb$s<3 zfAxa79iDf!S&mwLT)W;aSgaNY79^RZ+7?pOZum2=Ks?lUa``zdFewae(0>^7SfJLyZlw~<+aa5mT! zSgAs1+H?-Ody#-X+zq4bDjU=#K_E`1IK?KKt_7=X~AnZcD4dZF89Q)K7xS z$`GUi%qH$>v@Mn6t_rr~uyUa1ytnh#cb7hjyEh*T0Sagfij@dQxuDnU&$hI*oDT#7 z-QD{G#>3~kaX_MG%-c06AC+J(aUZfmx)h)0LpjunZlMVbt%n?KjtbI z3$_uUfbX{1Y+v*H{U0}(OkH>bv(;*abUF<#mkZ)^S;%IyU^E%GnK0$-WIhJ*To|JH zFm5-YKs8Gpt(IIx+7=cyWZ@VMItUEA4^O?Bp>!C9U1Wnw7GOg8()sh}zeHpt5(y@S zLV|0YNO(1zWDw60lNPpE3e$W+QZ;Zt0qO zGdP4F=l7ZbJDR&i5CpJTEMPDgfa5r(eIg-~$uPM$It{Uo1=Mha`FLHeHUqX&8dUxn z4SLAq*gA$?0nVZy5HjL_NA|8!Kp{J*ZX`e_ScfjHXc%Ek@I5(Y;3gyA-HGrA3fZON;m&pq*qZjN3 z7rW4AcAdoots1qOt(pe6S%%zfW&`kg+XZFE$q11^+9&Yj0%o(Bbx=u2%wU|*TQ%mam@f8NNK64= zNS2wnROSX1%$!7&H0NcpT8u^QlbB7Y6t}_QJ!n5c#-Xb;)!PXHN@*Fwpm(1L&{_Zq zrNbft^LdN`r2#mN`F=IM2#d+-GJh`h`z_$x`-o+I2pSy|1erhsr)QQxHqtieI*hmV zf?TXM-KtfB8z^@%{XI>QUj>iBk;MWv5awb6%+Ae%t;2{Z5c57tR>)K|;YyL6rOKLf z0XdmEtR{5FoDv9e(3lBQX}JLG{D`M>@&~JD$>>lD&}6F?J=al2W3iY-HGtLvC=inW zt0cVr{Slaoj=>uL2r`9qRTCDsX}+;OEWnGDn&kdgGY5P+Up((UVh@;IMl~BWZ2{E? zNTDoY99YxF0o4U49^~_RMu3@j)iq&J8y_mTgIJ-DnkwxU10>Q}cAg_HkPJaXu->TG zx1V-V9I(R<+@K->N*vfglb;|9Q0oCAfJJ`{hH56@HtnFxbI^)&;6CRu@R~a+YZa=4 zl`0a3+Gl?h`Q`o=lbi<22@ah0^kTQC_KX0H8{AP#VFFJkMnbWmm=gIMv@RWjN*U?ZeJ)?EKL^BS7N@H;DjkIwTSt4#$=oWU_GgwMS(EuYQ43u6dOV z4o$y+fXSU~77mhpzRa4ou3jP?0MB*2GI4F5OqOIm$zcgC);-9`UT&xg({KAc@{a*UXP;sT`CokQs+VAw} z!JhdyLu3U(XmF9FrUhu?z&)B7YHI>IXEK?J1f)YbSiKtGrqz1a7nS;;R?}*}R`VXU zcXMVvtrA%p0biE@rI7_(Cjv;wBvlf$>5ydgo%pu&RvTDj{j_dX6O2V?^q+DKLKBN5 zjdY?#$4NmD;_CW<8VA(EsOSdXwrvGYZD8`ep`m^f)a^%vdXGB~LKEq*E&-Cf_D#WX zngXGg1T`J1R-g--KqyE>jn&s|W3HkNfc38D9kBO+oDPk9LV(hUfN@$5BLY+xphj+> zS^yuyVA&KtqcpjS@g{;3`#pY8+5w0WFl$3bJYi zQi3aSgIY}+Flz&AydMSC)&a*cXfPc%N&rod=TSoB21JC`|Fv?rA6uiVdbW?P_v;LglUJsGVkq-Fry@O^+X; ztd&~Ab)uPL~h7T(jSW?u+bNmk<0_1BA+g1nfiTSZmi_Bx!i+ zs7y>K4ou?IIH1l2*n0tZj%J6kSd0;n4(4F`+fg|9g${^iqu@4sDqiy+&izY6_kQ)6 zf2!L@kc1LT;+&k#bHZ^tdMo+ET5pmx`%I18V3agY1ZW%03upcc=O*eUq zowbM2X|{f-Q~va*81FGhKOUmzbX66-BLYzJ>QiF1$xC5Uk$~2Kmucks>aRW!0^V8r zIa@*};CkHBD>~kOCoPuNOoz=9KvPW02Fp|ns03)!p=t&3$qdA%Q}E-N*C3foJXY`< zd=TE4{+M#B(tFtu=^e+BfJ%b9 z*Tvl6-KGD5zy9AZ!)7{E^TI^Z>r>x@-+tpF{A~Wsx&v8GF2PrR@rQ6PbX(E9s(lVx z%wF(BeNt>8u>!@{FSoa*-xXHo*_TkhkAcrZlOZ()5@=d9p+;|)c#b+?-=BJv#~T0+ zlM^oWeFn~TJqw4tPl3aT1(cYBh1eXtxAG2Lnf(#0rB;;QIylsF7@mLPB^YQMh91`w zVB$=W$j4wYF%3U|_%rzF{C`1Ske?CSjCSxCyudGKL5hfwTg||uU)_d<>Ex@MNs-b` zxDp9FdRZDtpy}p+pd9jeJZwUw20zk16-ty9EH(?+&Tw$x_u7lMl3h^;J)I8N*i6HL zZZ}NKMnG2_jZQNtUCD7`{>VW$EUctJ$Qi+BZ3i(XL1GT)C!s7j3J&=A@C$JK$&-+Z zhv6T;_Qx=@xc<|bwcMZKSLdL@!_%F}OerERBHEgBrST3`x0l z?H!o7a~%@Nj1W!;1bh>!#DJX=Ky@%xI4LB+P6W_ERNxd7)LR*un&D*m*5~WAAwXb4lAiucy{0t9C@an0j6uK+NSl0LLm<` zljAToaTD&|ybkv!?&VW_F0{50U5F$zHLZxEGm4;Z!|1j5q)0p&2}csE!Ej_M#*6Rb?PnFOQ{W?ar5{%ad;Nn6 zasyh-Kc>D#qFR8~6^Ic3VK)XaJ^H>0TowoP`36{!ir?g6b#@gt^9i_k`bFq@rk4RF zEt7^-jb}4FOpM=v*~u}uaeV}qmzUGAIKQ^E9Gr`%#p~&ucpKybEvA5`RKzP<7iuYW zHx@v1?a!k8JDQ@721+KW21F8d$!y@oBk;-3Uxd)&I&3U%Kzua@CwkAo;r&P1nj&Qq z(k_9fNflYm{LForzJD8m--7Y+u|gu54kO^D%_u(>OBdb)d1e|_G#ypkGN%BRs*HJ0 z382l#P=18sqCvaeZgyNXeQKSZozU6S0WQB4h7O-)?-~$*f7sRNsmp#83EkO8`aL zHI#eFWb)+T;2>KS8XFsfk&zJ?9UV<$7N8Pz#$wPPn# literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp index 1c7672295..5576080ba 100644 --- a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp +++ b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp @@ -54,6 +54,7 @@ #define IMAGE_LIBRARY ":/images/library.png" #define IMAGE_PLUGINS ":/images/extension_32.png" #define IMAGE_GXSFORUMS ":/images/konversation.png" +#define IMAGE_WIKI ":/images/wikibook_32.png" /** Constructor */ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) @@ -98,7 +99,7 @@ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) WikiDialog *wikiDialog = NULL; ui.stackPages->add(wikiDialog = new WikiDialog(ui.stackPages), - createPageAction(QIcon(IMAGE_LIBRARY), tr("Wiki Pages"), grp)); + createPageAction(QIcon(IMAGE_WIKI), tr("Wiki Pages"), grp)); GxsForumsDialog *gxsforumsDialog = NULL; ui.stackPages->add(gxsforumsDialog = new GxsForumsDialog(ui.stackPages), From 8da8f24683c33b91fa581a77901bb83d383548ef Mon Sep 17 00:00:00 2001 From: defnax Date: Sun, 18 Nov 2012 00:18:46 +0000 Subject: [PATCH 154/222] restored back some of my changes, added serviceheader text for Wiki and Forum git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5839 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/gui/gxs/GxsForumGroupDialog.cpp | 2 +- retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp | 3 ++- retroshare-gui/src/gui/gxs/GxsGroupDialog.ui | 22 ++++++++++++++----- .../src/gui/gxs/WikiGroupDialog.cpp | 2 +- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.cpp index 75232c960..66381d075 100644 --- a/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.cpp @@ -55,7 +55,7 @@ const uint32_t ForumCreateDefaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC GxsForumGroupDialog::GxsForumGroupDialog(TokenQueue *tokenQueue, QWidget *parent) - :GxsGroupDialog(tokenQueue, ForumCreateEnabledFlags, ForumCreateDefaultsFlags, parent) + :GxsGroupDialog(tokenQueue, ForumCreateEnabledFlags, ForumCreateDefaultsFlags, parent, "Create New Forum") { diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index b3fc5d6bf..7e6108d68 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -66,9 +66,10 @@ GxsGroupDialog::GxsGroupDialog(TokenQueue *tokenQueue, uint32_t enableFlags, uin if(!serviceHeader.isEmpty()) ui.mServiceHeader->setText(serviceHeader); + setWindowTitle(serviceHeader); //ui.headerFrame->setHeaderImage(QPixmap(":/WikiPoos/images/resource-group-new_48.png")); - //ui.headerFrame->setHeaderText(tr("Create Wiki Group")); + //ui.headerFrame->setHeaderText(tr("Create")); if (!ui.pubKeyShare_cb->isChecked()) { diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui index c16d9c4b8..197d001f3 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui @@ -11,7 +11,7 @@ - Create New Group + Create New @@ -69,7 +69,7 @@ - Create Wiki Group + Create New @@ -99,7 +99,10 @@ - + + 6 + + 0 @@ -139,6 +142,12 @@ border-radius: 10px; + + 6 + + + 6 + @@ -190,7 +199,7 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Key recipients can publish to restricted-type Wiki Group, and can view and publish for private-type channels</span></p></body></html> - Add Wiki Moderators + Share Publish Key @@ -240,7 +249,7 @@ p, li { white-space: pre-wrap; } QDockWidget::NoDockWidgetFeatures - Select Wiki Moderators + Share Key With @@ -552,6 +561,9 @@ p, li { white-space: pre-wrap; } + + + diff --git a/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp b/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp index 3485ea605..6a4026714 100644 --- a/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp @@ -52,7 +52,7 @@ uint32_t WikiCreateDefaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC | WikiGroupDialog::WikiGroupDialog(TokenQueue *tokenQueue, QWidget *parent) - :GxsGroupDialog(tokenQueue, WikiCreateEnabledFlags, WikiCreateDefaultsFlags, parent) + :GxsGroupDialog(tokenQueue, WikiCreateEnabledFlags, WikiCreateDefaultsFlags, parent, "Create New Wiki Group") { // To start with we only have open forums - with distribution controls. From e24ea713489916a82f2abb40ab9df732ab9cb94d Mon Sep 17 00:00:00 2001 From: defnax Date: Sun, 18 Nov 2012 01:36:22 +0000 Subject: [PATCH 155/222] Added Author and Timestamp Label's for GxsForums git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5840 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/GxsForumsDialog.cpp | 24 ++++++ retroshare-gui/src/gui/GxsForumsDialog.ui | 91 ++++++++++++++++------ 2 files changed, 93 insertions(+), 22 deletions(-) diff --git a/retroshare-gui/src/gui/GxsForumsDialog.cpp b/retroshare-gui/src/gui/GxsForumsDialog.cpp index 182626b98..8092cf79a 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/GxsForumsDialog.cpp @@ -1207,11 +1207,35 @@ void GxsForumsDialog::insertPostData(const RsGxsForumMsg &msg) { setMsgReadStatus(Row, true); } + + QString text; + { + QDateTime qtime; + qtime.setTime_t(msg.mMeta.mPublishTs); + + text = qtime.toString("yyyy-MM-dd hh:mm:ss"); + + ui.time_label->setText(text); + } + + std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); + text = QString::fromUtf8(authorName.c_str()); + + if (text.isEmpty()) + { + ui.by_label->setText( tr("By") + " " + tr("Anonymous")); + } + else + { + ui.by_label->setText( tr("By") + " " + text ); + } QString extraTxt = RsHtml().formatText(ui.postText->document(), messageFromInfo(msg), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS); ui.postText->setHtml(extraTxt); ui.threadTitle->setText(titleFromInfo(msg.mMeta)); + + } diff --git a/retroshare-gui/src/gui/GxsForumsDialog.ui b/retroshare-gui/src/gui/GxsForumsDialog.ui index 302f20ecb..c3228a940 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.ui +++ b/retroshare-gui/src/gui/GxsForumsDialog.ui @@ -837,6 +837,9 @@ p, li { white-space: pre-wrap; } :/images/back.png:/images/back.png + + true + @@ -875,9 +878,12 @@ p, li { white-space: pre-wrap; } :/images/forward.png:/images/forward.png + + true + - + @@ -903,27 +909,7 @@ p, li { white-space: pre-wrap; } - - - - - 24 - 24 - - - - Qt::NoFocus - - - Download all files - - - - :/images/down.png:/images/down.png - - - - + @@ -959,7 +945,68 @@ p, li { white-space: pre-wrap; } + + + + + 10 + + + + + + + + + + + + 10 + + + + + + + + + + + Qt::Vertical + + + + + + + 24 + 24 + + + + Qt::NoFocus + + + Download all files + + + + :/images/down.png:/images/down.png + + + true + + + + + + + Qt::Vertical + + + + Qt::Horizontal From ec6aef8d45e186834c7c66e4263c12f4f004246b Mon Sep 17 00:00:00 2001 From: defnax Date: Sun, 18 Nov 2012 14:42:54 +0000 Subject: [PATCH 156/222] Added some headerFrame's changed some button order git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5841 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/RetroShare.pro | 2 +- .../src/gui/PhotoShare/AlbumCreateDialog.ui | 597 ++++++++-------- .../src/gui/PhotoShare/AlbumDialog.ui | 636 +++++++++--------- .../src/gui/PhotoShare/PhotoShare.ui | 270 +++++--- .../src/gui/PhotoShare/Photo_images.qrc | 2 +- .../src/gui/PhotoShare/images/kuickshow.png | Bin 0 -> 1779 bytes retroshare-gui/src/gui/WikiPoos/WikiDialog.ui | 4 +- 7 files changed, 831 insertions(+), 680 deletions(-) create mode 100644 retroshare-gui/src/gui/PhotoShare/images/kuickshow.png diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index 8b1d1c05b..050914d3b 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -708,7 +708,7 @@ SOURCES += main.cpp \ -RESOURCES += gui/images.qrc lang/lang.qrc gui/help/content/content.qrc gui/WikiPoos/Wiki_images.qrc +RESOURCES += gui/images.qrc lang/lang.qrc gui/help/content/content.qrc gui/WikiPoos/Wiki_images.qrc gui/PhotoShare/Photo_images.qrc TRANSLATIONS += \ lang/retroshare_en.ts \ diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui index 4e0e3dcb4..71aa7f75c 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui @@ -6,8 +6,8 @@ 0 0 - 465 - 365 + 530 + 488 @@ -16,296 +16,333 @@ true - - - - - - - - - - 18 - 75 - true - - - - Album Details - - - - - - - Album Name: - - - - - - - - - - Category: - - - - - - - - Travel + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + + + 18 + 75 + true + + + + Album Details + + + + + + + Album Name: + + + + + + + + + + Category: + + + + + + + + Travel + + + + + Holiday + + + + + Friends + + + + + Family + + + + + Work + + + + + Random + + + + + + + + + + + 64 + 64 + - - - - Holiday + + + 64 + 64 + - - - - Friends - - - - - Family - - - - - Work - - - - - Random - - - - - - - - - - - 64 - 64 - - - - - 64 - 64 - - - - + + border: 2px solid white; border-radius: 10px; - - - - - - - :/images/channels.png:/images/channels.png - - - - 64 - 64 - - - - - - - - - - Qt::Horizontal - - - - - - - - - Caption: - - - - - - - - - - Photographer: - - - - - - - - - - Description - - - - - - - - - - Where: - - - - - - - - - - - - Qt::Horizontal - - - - - - - - - - 1 - 0 - - - - Share Options - - - - - - - 0 - 0 - - - - Public - - - - - Restricted - - - - - - - - - 0 - 0 - + + - - - Resize Images (< 1Mb) - - - - - Resize Images (< 10Mb) - - - - - Send Original Images - - - - - - - - - 0 - 0 - + + + :/images/channels.png:/images/channels.png - - - No Comments Allowed - - - - - Authenticated Comments - - - - - Any Comments Allowed - - - - - - - - - 0 - 0 - + + + 64 + 64 + - - - Publish with Identity - - - - - - - - Qt::Horizontal - - - - 598 - 20 - - - - - - - - Publish Album - - - - + + + + + Qt::Horizontal + + + + + + + + + Caption: + + + + + + + + + + Photographer: + + + + + + + + + + Description + + + + + + + + + + Where: + + + + + + + + + + + + Qt::Horizontal + + + + + + + + 1 + 0 + + + + Share Options + + + + + + + 0 + 0 + + + + + Public + + + + + Restricted + + + + + + + + + 0 + 0 + + + + + Resize Images (< 1Mb) + + + + + Resize Images (< 10Mb) + + + + + Send Original Images + + + + + + + + + 0 + 0 + + + + + No Comments Allowed + + + + + Authenticated Comments + + + + + Any Comments Allowed + + + + + + + + + 0 + 0 + + + + + Publish with Identity + + + + + + + + + + + Qt::Horizontal + + + + 168 + 20 + + + + + + + + Qt::Horizontal + + + + 419 + 18 + + + + + + + + Publish Album + + + + + diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui index 5d42b38cf..0acc5793d 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui @@ -20,337 +20,361 @@ true - - - - - Qt::Vertical + + + 0 + + + 0 + + + + + QFrame::StyledPanel - - - - - - - 0 - 1 - - - - Album Thumbnail - - - - - - TextLabel - - - - - - - - - - - 10 - 1 - - - - Summary - - - - - - false - + + QFrame::Raised + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Qt::Vertical + + + + + - + 0 - 0 + 1 + + Album Thumbnail + + + + + + TextLabel + + + + + + + + + + + 10 + 1 + + + + Summary + + + + + + false + + + + 0 + 0 + + + + + + + + Category: + + + + + + + Caption + + + + + + + false + + + + 0 + 0 + + + + + + + + Where: + + + + + + + false + + + + 0 + 0 + + + + + + + + false + + + + 0 + 0 + + + + + + + + Album Title: + + + + + + + When + + + + + + + false + + + + 0 + 0 + + + + + - - - Category: - - - - - - - Caption - - - - - - - false - - - - 0 - 0 - - - - - - - - Where: - - - - - - - false - - - - 0 - 0 - - - - - - - - false - - - - 0 - 0 - - - - - - - - Album Title: - - - - - - - When - - - - - - - false - - - - 0 - 0 - - - - - - - - - - - - - - 10 - 1 - - - - Share Options - - - - - - false - + + + - - 0 - 0 + + 10 + 1 - - - - - - Comments - - - - - - - Publish Identity - - - - - - - false - - - - 0 - 0 - - - - - - - - Visibility - - - - - - - false - - - - 0 - 0 - + + Share Options + + + + + false + + + + 0 + 0 + + + + + + + + Comments + + + + + + + Publish Identity + + + + + + + false + + + + 0 + 0 + + + + + + + + Visibility + + + + + + + false + + + + 0 + 0 + + + + + - - - - - - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;"> Drag &amp; Drop to insert pictures. Click on a picture to edit details below.</span></p></body></html> - + + + + + + + + 0 + 10 + + + + true + + + Qt::ScrollBarAsNeeded + + + true + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + 0 + 0 + 625 + 103 + + + + QWidget#scrollAreaWidgetContents{border: none;} + + + + + + - - - - - - 0 - 10 - - - - true - - - Qt::ScrollBarAsNeeded - - - true - - - Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - - - - - 0 - 0 - 627 - 116 - + + + + + + + + Add Photo - - QWidget#scrollAreaWidgetContents{border: none;} - - - - - - + + + + + Edit Photo + + + + + + + Delete Photo + + + + + + + Qt::Horizontal + + + + 68 + 17 + + + + + + + + Publish Photos + + + + + + - - - - - - Delete Photo - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Edit Photo - - - - - - - Qt::Horizontal - - - - 68 - 17 - - - - - - - - Publish Photos / Close - - - - - + frame + headerFrame diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui index 73592cef6..1842828f5 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui @@ -14,98 +14,179 @@ Form + + 0 + - - - - - false - - - - 6 + + + + 2 + + + + + Create Album - - 0 + + + :/images/add_image24.png:/images/add_image24.png - - - - Your Albums - - - true - - - true - - - - - - - Subscribed Albums - - - true - - - true - - - - - - - Shared Albums - - - true - - - false - - - true - - - - - - - + + + 24 + 24 + + + + Qt::ToolButtonTextBesideIcon + + + true + + + + + + + View Album + + + + :/images/lphoto.png:/images/lphoto.png + + + + 24 + 24 + + + + Qt::ToolButtonTextBesideIcon + + + true + + + + + + + Slide Show + + + + :/images/kuickshow.png:/images/kuickshow.png + + + + 24 + 24 + + + + Qt::ToolButtonTextBesideIcon + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Subscribe To Album + + + + :/images/konqsidebar_news24.png:/images/konqsidebar_news24.png + + + + 24 + 24 + + + + Qt::ToolButtonTextBesideIcon + + + true + + + + + - - - - - Slide Show - - - - - - - View Album / Add Photos - - - - - - - Subscribe To Album - - - - - - - Create Album - - - - + + + false + + + + 6 + + + 0 + + + + + Your Albums + + + true + + + true + + + + + + + Subscribed Albums + + + true + + + true + + + + + + + Shared Albums + + + true + + + false + + + true + + + + + @@ -125,7 +206,7 @@ 0 0 804 - 228 + 230 @@ -168,7 +249,7 @@ 0 0 804 - 227 + 230 @@ -195,6 +276,12 @@ + + 2 + + + 2 + @@ -206,6 +293,9 @@ - + + + + diff --git a/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc b/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc index 3ab091103..fcfc1f3fc 100644 --- a/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc +++ b/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc @@ -1,5 +1,5 @@ - images/dummy.png + images/kuickshow.png diff --git a/retroshare-gui/src/gui/PhotoShare/images/kuickshow.png b/retroshare-gui/src/gui/PhotoShare/images/kuickshow.png new file mode 100644 index 0000000000000000000000000000000000000000..e860920283a337eff3ba794f5ca46fb5d2376210 GIT binary patch literal 1779 zcmV4S7rLD%DX0W{QX$QZ@PfzV>1gNbnd{zrt-k%w z9-6e%%n|x$|FdS+T6_K9|NWQQV_dp)>3IMix|EYAPd;f`RWKFN5aRJb_Nj#3Ulng;w;-NT{xSI?@Kba6ER0)MLHCZ&!*W;kU`{P$P zV*Z_UjGGA_qUn*S9AcVcm>X$KCm?8$3=jwv42!S_6tWKLp+bMJhnY&fD+UBW%R}2V zCBA{uNzy@#*y1h3V@}In8s(aVL?-$(o`7&{*)Kp^#yNHbAk;dRMKz%!NX7?|mVB_| zL%GH)$#^YnSjl}U$3Qw|OFpDM85^;;f`3qyfv@DK7vBcXK5E_k0=qA7>2!m?dHXHy${XS-@A?i#F ziwtm8D!^ko)ho5Q1-DvrX8??tcqDag$RxeB(4!?Gr7BcBLi2Nk!MrcDU!JZ=ZmcS% zF*Z{}Z;E|D0L!_Z0dSKbHK^INBi=^hs)R(!&~BS|Yyz7O-k@8Y9z;bxP*g{aAXHATeyB$F!hq zue}d+ZpDwRTZ%7ET#yD6i%%^v;Bso%9Hc(DUY~GL&Ulrc>ufeb@NdroqV3d&VW?}h+DCkpi+DeA8H>X( z8t3}A#-2TU`g?nsx?M`OTHUv3(IVr(fdg;;G5!ZigQa%k|M)yMb`6Uc7cn_GflQ_s z1OeA`G0yvz-E}vJBsAov1<3B*yI~TrMwbets!O3(!%_ z3d~>zHWnaz_wF57zkdCr>2$jI&G6T9C?Ds*@3GQQ7Hik6Lr+f+W^c}7cD9C3KmQb) z9(WK>?bwA;ti_4~P|QLS{N~s%-2vFYf4^5QmtWqtZQBdO!^0=}cy0ag{f}@Q2V{cu zX3*EyhyMP4tXaDjlhc!MYzu>>5}x0+M|#W1#k0r^^&zS#gr-JRHjpv{m|b}N?9QD# zPxB!q$4B_h{2%d&>$*R+;v7X0+9e{j+1@M)eMRQSQZQWTW&G>a3T~VqMlkg|rfyt= zS*04${0z{`7q@QR`cA1-`tHb)BTrK=0@8+`T)lery7``f@4aU=PMtoD!GXbeuT;&@ z(A^jv9mT}Ngsivb>D2rHeBUpS?$1U>M)q-Y@8QFTO&U`GZg{>ogntp18DczR*T%4U z(`LMK@F0|*gISx#8?V2PFTeZ>fC10*1USoB&l`es=gz$y8&ABvNmWTrzxD7#4x`NTjrbd8AyaU}*V}u<+sg@8SG!=UJNX z;`;UL*sx)PfF^)eM^$$Oz;#?a{={SA0c&2A2H6L4$fPq+Da9^0hRc^PgIyD6&YZ!( zzyMaPSRpL608sTE0ifa0XSVNX<$x$Dm9d#*er!xa!PH?D3`xUcxFifM0Q^0f`U|#a V?9&@3Ik5l$002ovPDHLkV1mT$K1=`r literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui index 5dd4b74a1..7a28c7002 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui @@ -25,7 +25,7 @@ 0 - + QFrame::StyledPanel @@ -174,7 +174,7 @@ 0 - + QFrame::StyledPanel From 6e349749d010a19b317d6e1a96012d5cdd86cdc2 Mon Sep 17 00:00:00 2001 From: defnax Date: Mon, 19 Nov 2012 16:27:39 +0000 Subject: [PATCH 157/222] Added to hide logo label and logo button, when calling "Create Wiki Group" switch text for some labels, when "Create Wiki Group" is called. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5844 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp | 5 +++-- retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp | 12 +++++++++++- retroshare-gui/src/gui/gxs/GxsGroupDialog.h | 3 ++- retroshare-gui/src/gui/gxs/GxsGroupDialog.ui | 7 +++---- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp index db0253ec0..74624dee4 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp @@ -28,7 +28,7 @@ #include "gui/WikiPoos/WikiAddDialog.h" #include "gui/WikiPoos/WikiEditDialog.h" -#include "gui/gxs/WikiGroupDialog.h" +#include "gui/gxs/WikiGroupDialog.h" #include @@ -160,7 +160,8 @@ void WikiDialog::OpenOrShowAddGroupDialog() void WikiDialog::newGroup() { WikiGroupDialog cf(mWikiQueue, this); - //cf.newGroup(); + //cf.newGroup(); + cf.wikitype(); cf.exec (); } diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index 7e6108d68..97e2978b0 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -438,4 +438,14 @@ void GxsGroupDialog::setShareList() this->resize(this->size().width() - ui.contactsdockWidget->size().width(), this->size().height()); } } - + +void GxsGroupDialog::wikitype() +{ + // hide logo Button/Label + ui.groupLogo->hide(); + ui.addLogoButton->hide(); + + ui.headerImage->setPixmap(QPixmap(":/images/resource-group-new_48.png")) ; + ui.pubKeyShare_cb->setText(tr("Add Wiki Moderators")); + ui.contactsdockWidget->setWindowTitle(tr("Select Wiki Moderators")); +} diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h index 7cb5ed87a..b4186c898 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h @@ -134,10 +134,11 @@ public: * @param parent */ GxsGroupDialog(const RsGroupMetaData& grpMeta, uint32_t mode = GXS_GROUP_DIALOG_SHOW_MODE, QWidget *parent = NULL); + void wikitype(); private: void newGroup(); - void setMode(uint32_t mode); + void setMode(uint32_t mode); // Functions that can be overloaded for specific stuff. diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui index 197d001f3..777f80b11 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui @@ -51,7 +51,7 @@ 6 - + 48 @@ -61,9 +61,6 @@ - - :/images/resource-group-new_48.png - @@ -564,6 +561,8 @@ p, li { white-space: pre-wrap; } + + From c6e6d444bfa4d0f941428124d1b7025d8a2373d2 Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 19 Nov 2012 22:00:05 +0000 Subject: [PATCH 158/222] Added Identity Info retrieval to rsIdentities. This is now pretty much complete for Phase 1 of GXS. Still todo: - PGPHash signatures. - Reputations. - Added two helper classes GxsTokenQueue: similar to TokenQueue, but for libretroshare & RsTickEvent: schedule one shot events, and basic stats. - Reorganised/simplified p3IdService using these two classes. - Added fns to load/reload a list of Own Identities. - Improved the Cache to store all GUI required Info. - Updater retroshare/rsidentity.h with new Identity interface. - added fns to update Cache from internal background tasks. - Modified RsMemCache to support replace operation. - Found nasty Bug that caused PGPHASHes not to match & Patched same bug in GXS. - added generic CacheArbitration. - Added AuthorIds to dummy Forum messages. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5848 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/gxstokenqueue.cc | 95 ++ libretroshare/src/gxs/gxstokenqueue.h | 71 ++ libretroshare/src/gxs/rsgenexchange.cc | 6 +- libretroshare/src/libretroshare.pro | 8 +- libretroshare/src/retroshare/rsgxsforums.h | 2 - libretroshare/src/retroshare/rsidentity.h | 15 +- libretroshare/src/services/p3gxsforums.cc | 50 ++ libretroshare/src/services/p3gxsforums.h | 12 +- libretroshare/src/services/p3idservice.cc | 993 +++++++++++---------- libretroshare/src/services/p3idservice.h | 71 +- libretroshare/src/util/rsmemcache.h | 12 +- libretroshare/src/util/rstickevent.cc | 185 ++++ libretroshare/src/util/rstickevent.h | 67 ++ 13 files changed, 1096 insertions(+), 491 deletions(-) create mode 100644 libretroshare/src/gxs/gxstokenqueue.cc create mode 100644 libretroshare/src/gxs/gxstokenqueue.h create mode 100644 libretroshare/src/util/rstickevent.cc create mode 100644 libretroshare/src/util/rstickevent.h diff --git a/libretroshare/src/gxs/gxstokenqueue.cc b/libretroshare/src/gxs/gxstokenqueue.cc new file mode 100644 index 000000000..95284dfd4 --- /dev/null +++ b/libretroshare/src/gxs/gxstokenqueue.cc @@ -0,0 +1,95 @@ +/* + * libretroshare/src/gxs gxstokenqueue.cc + * + * Gxs Support for RetroShare. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "gxs/gxstokenqueue.h" + +bool GxsTokenQueue::queueRequest(uint32_t token, uint32_t req_type) +{ + RsStackMutex stack(mQueueMtx); /********** STACK LOCKED MTX ******/ + mQueue.push_back(GxsTokenQueueItem(token, req_type)); + return true; +} + + +void GxsTokenQueue::checkRequests() +{ + { + RsStackMutex stack(mQueueMtx); /********** STACK LOCKED MTX ******/ + if (mQueue.empty()) + { + return; + } + } + + // Must check all, and move to a different list - for reentrant / good mutex behaviour. + std::list toload; + std::list::iterator it; + + bool stuffToLoad = false; + { + RsStackMutex stack(mQueueMtx); /********** STACK LOCKED MTX ******/ + for(it = mQueue.begin(); it != mQueue.end();) + { + uint32_t token = it->mToken; + uint32_t status = mGenExchange->getTokenService()->requestStatus(token); + + if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + { + toload.push_back(*it); + it = mQueue.erase(it); + stuffToLoad = true; + } + else if (status == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED) + { + // maybe we should do alternative callback? + std::cerr << "GxsTokenQueue::checkRequests() ERROR Request Failed: " << token; + std::cerr << std::endl; + + it = mQueue.erase(it); + } + else + { + it++; + } + } + } + + if (stuffToLoad) + { + for(it = toload.begin(); it != toload.end(); it++) + { + handleResponse(it->mToken, it->mReqType); + } + } +} + + // This must be overloaded to complete the functionality. +void GxsTokenQueue::handleResponse(uint32_t token, uint32_t req_type) +{ + std::cerr << "GxsTokenQueue::handleResponse(" << token << "," << req_type << ") ERROR: NOT HANDLED"; + std::cerr << std::endl; +} + + diff --git a/libretroshare/src/gxs/gxstokenqueue.h b/libretroshare/src/gxs/gxstokenqueue.h new file mode 100644 index 000000000..b77f9247f --- /dev/null +++ b/libretroshare/src/gxs/gxstokenqueue.h @@ -0,0 +1,71 @@ +#ifndef R_GXS_TOKEN_QUEUE_H +#define R_GXS_TOKEN_QUEUE_H +/* + * libretroshare/src/gxs gxstokenqueue.h + * + * Gxs Support for RetroShare. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "gxs/rsgenexchange.h" +#include "util/rsthreads.h" + + +/* + * + * A little helper class, to manage callbacks from requests + * + */ + +class GxsTokenQueueItem +{ + public: + GxsTokenQueueItem(const uint32_t token, const uint32_t req_type) + :mToken(token),mReqType(req_type) { return; } + + GxsTokenQueueItem(): mToken(0), mReqType(0) { return; } + + uint32_t mToken; + uint32_t mReqType; +}; + + +class GxsTokenQueue +{ + public: + + GxsTokenQueue(RsGenExchange *gxs) + :mGenExchange(gxs), mQueueMtx("GxsTokenQueueMtx") { return; } +bool queueRequest(uint32_t token, uint32_t req_type); + +void checkRequests(); // must be called by + + // This must be overloaded to complete the functionality. +virtual void handleResponse(uint32_t token, uint32_t req_type); + + private: + RsGenExchange *mGenExchange; + RsMutex mQueueMtx; + std::list mQueue; +}; + + +#endif //R_GXS_TOKEN_QUEUE_H diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index da2153171..6a662cc72 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -396,7 +396,7 @@ bool RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBina for(; mit != mit_end; mit++) { - pub_key_found = mit->second.keyFlags & (RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL); + pub_key_found = mit->second.keyFlags == (RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL); if(pub_key_found) break; } @@ -1342,7 +1342,7 @@ void RsGenExchange::publishGrps() { RsTlvSecurityKey& key = mit_keys->second; - if(key.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL)) + if(key.keyFlags == (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL)) { privAdminKey = key; privKeyFound = true; @@ -1493,7 +1493,7 @@ void RsGenExchange::createDummyGroup(RsGxsGrpItem *grpItem) { RsTlvSecurityKey& key = mit_keys->second; - if(key.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL)) + if(key.keyFlags == (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL)) { privAdminKey = key; privKeyFound = true; diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 7a84059c1..4c3ed995e 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -430,7 +430,8 @@ HEADERS += retroshare/rsgame.h \ util/rsrandom.h \ util/radix64.h \ util/pugiconfig.h \ - util/rsmemcache.h + util/rsmemcache.h \ + util/rstickevent.h SOURCES += dbase/cachestrapper.cc \ dbase/fimonitor.cc \ @@ -564,7 +565,8 @@ HEADERS += retroshare/rsgame.h \ util/rsthreads.cc \ util/rsversion.cc \ util/rswin.cc \ - util/rsrandom.cc + util/rsrandom.cc \ + util/rstickevent.cc upnp_miniupnpc { HEADERS += upnp/upnputil.h upnp/upnphandler_miniupnp.h @@ -614,6 +616,7 @@ HEADERS += retroshare/rsgame.h \ gxs/gxscoreserver.h \ gxs/gxssecurity.h \ gxs/rsgxsifaceimpl.h \ + gxs/gxstokenqueue.h \ services/p3posted.h \ retroshare/rsposted.h \ serialiser/rsposteditems.h @@ -633,6 +636,7 @@ HEADERS += retroshare/rsgame.h \ gxs/gxscoreserver.cc \ gxs/gxssecurity.cc \ gxs/rsgxsifaceimpl.cc \ + gxs/gxstokenqueue.cc \ services/p3posted.cc \ serialiser/rsposteditems.cc diff --git a/libretroshare/src/retroshare/rsgxsforums.h b/libretroshare/src/retroshare/rsgxsforums.h index 8c18509e5..bab7f9556 100644 --- a/libretroshare/src/retroshare/rsgxsforums.h +++ b/libretroshare/src/retroshare/rsgxsforums.h @@ -89,8 +89,6 @@ virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgI virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group) = 0; virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg) = 0; -virtual bool generateDummyData() = 0; - }; diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index cc7f8fa3d..ca1ada8a6 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -160,13 +160,24 @@ typedef std::string RsGxsId; // TMP. => class RsIdentityDetails { public: + RsIdentityDetails() + :mIsOwnId(false), mPgpLinked(false), mPgpKnown(false), + mOpinion(0), mReputation(0) { return; } - RsGxsId id; + RsGxsId mId; // identity details. + std::string mNickname; + bool mIsOwnId; + // PGP Stuff. + bool mPgpLinked; + bool mPgpKnown; + std::string mPgpId; // reputation details. + double mOpinion; + double mReputation; }; @@ -261,7 +272,7 @@ public: // We cache all identities, and provide alternative (instantaneous) // functions to extract info, rather than the standard Token system. -virtual bool getNickname(const RsGxsId &id, std::string &nickname) = 0; +//virtual bool getNickname(const RsGxsId &id, std::string &nickname) = 0; virtual bool getIdDetails(const RsGxsId &id, RsIdentityDetails &details) = 0; virtual bool getOwnIds(std::list &ownIds) = 0; diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index 6c539cd97..6d301e9b1 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -26,6 +26,8 @@ #include "services/p3gxsforums.h" #include "serialiser/rsgxsforumitems.h" +#include + #include "gxs/rsgxsflags.h" #include @@ -41,6 +43,8 @@ RsGxsForums *rsGxsForums = NULL; +#define FORUM_TESTEVENT_DUMMYDATA 0x0001 +#define DUMMYDATA_PERIOD 60 // long enough for some RsIdentities to be generated. /********************************************************************************/ /******************* Startup / Tick ******************************************/ @@ -51,6 +55,7 @@ p3GxsForums::p3GxsForums(RsGeneralDataService *gds, RsNetworkExchangeService *ne { // For Dummy Msgs. mGenActive = false; + RsTickEvent::schedule_in(FORUM_TESTEVENT_DUMMYDATA, DUMMYDATA_PERIOD); } void p3GxsForums::notifyChanges(std::vector &changes) @@ -61,6 +66,7 @@ void p3GxsForums::notifyChanges(std::vector &changes) void p3GxsForums::service_tick() { dummy_tick(); + RsTickEvent::tick_events(); return; } @@ -400,6 +406,28 @@ bool p3GxsForums::generateMessage(uint32_t &token, const RsGxsGroupId &grpId, co msg.mMeta.mThreadId = threadId; msg.mMeta.mParentId = parentId; + /* chose a random Id to sign with */ + std::list ownIds; + std::list::iterator it; + + rsIdentity->getOwnIds(ownIds); + + uint32_t idx = (uint32_t) (ownIds.size() * RSRandom::random_f32()); + int i = 0; + for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); it++, i++); + + if (it != ownIds.end()) + { + std::cerr << "p3GxsForums::generateMessage() Author: " << *it; + std::cerr << std::endl; + msg.mMeta.mAuthorId = *it; + } + else + { + std::cerr << "p3GxsForums::generateMessage() No Author!"; + std::cerr << std::endl; + } + createMsg(token, msg); return true; @@ -417,3 +445,25 @@ bool p3GxsForums::generateGroup(uint32_t &token, std::string groupName) return true; } + + // Overloaded from RsTickEvent for Event callbacks. +void p3GxsForums::handle_event(uint32_t event_type) +{ + std::cerr << "p3GxsForums::handle_event(" << event_type << ")"; + std::cerr << std::endl; + + // stuff. + switch(event_type) + { + case FORUM_TESTEVENT_DUMMYDATA: + generateDummyData(); + break; + + default: + /* error */ + std::cerr << "p3GxsForums::handle_event() Unknown Event Type: " << event_type; + std::cerr << std::endl; + break; + } +} + diff --git a/libretroshare/src/services/p3gxsforums.h b/libretroshare/src/services/p3gxsforums.h index a8a45358f..3b0a2f8d6 100644 --- a/libretroshare/src/services/p3gxsforums.h +++ b/libretroshare/src/services/p3gxsforums.h @@ -30,6 +30,8 @@ #include "retroshare/rsgxsforums.h" #include "gxs/rsgenexchange.h" +#include "util/rstickevent.h" + #include #include @@ -37,7 +39,8 @@ * */ -class p3GxsForums: public RsGenExchange, public RsGxsForums +class p3GxsForums: public RsGenExchange, public RsGxsForums, + public RsTickEvent /* only needed for testing - remove after */ { public: @@ -66,9 +69,14 @@ virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgI virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group); virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg); -virtual bool generateDummyData(); + + // Overloaded from RsTickEvent. +virtual void handle_event(uint32_t event_type); + private: +virtual bool generateDummyData(); + std::string genRandomId(); void dummy_tick(); diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 784bacb7d..d8ec68db1 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -25,7 +25,7 @@ #include "services/p3idservice.h" #include "serialiser/rsgxsiditems.h" - +#include "gxs/rsgxsflags.h" #include "util/rsrandom.h" #include "util/rsstring.h" @@ -71,43 +71,62 @@ RsIdentity *rsIdentity = NULL; #define BG_PGPHASH 1 #define BG_REPUTATION 2 + +#define GXSIDREQ_CACHELOAD 0x0001 +#define GXSIDREQ_CACHEOWNIDS 0x0002 + +#define GXSIDREQ_PGPHASH 0x0010 +#define GXSIDREQ_REPUTATION 0x0020 + +#define GXSIDREQ_CACHETEST 0x1000 + +// Events. +#define GXSID_EVENT_CACHEOWNIDS 0x0001 +#define GXSID_EVENT_CACHELOAD 0x0002 + +#define GXSID_EVENT_PGPHASH 0x0010 +#define GXSID_EVENT_PGPHASH_PROC 0x0011 + +#define GXSID_EVENT_REPUTATION 0x0020 + +#define GXSID_EVENT_CACHETEST 0x1000 + +#define CACHETEST_PERIOD 60 + +#define OWNID_RELOAD_DELAY 10 + +#define PGPHASH_PERIOD 60 +#define PGPHASH_RETRY_PERIOD 11 +#define PGPHASH_PROC_PERIOD 1 + +#define REPUTATION_PERIOD 60 +#define REPUTATION_RETRY_PERIOD 13 +#define REPUTATION_PROC_PERIOD 1 + /********************************************************************************/ /******************* Startup / Tick ******************************************/ /********************************************************************************/ p3IdService::p3IdService(RsGeneralDataService *gds, RsNetworkExchangeService *nes) - : RsGxsIdExchange(gds, nes, new RsGxsIdSerialiser(), RS_SERVICE_GXSV1_TYPE_GXSID), RsIdentity(this), - mIdMtx("p3IdService") + : RsGxsIdExchange(gds, nes, new RsGxsIdSerialiser(), RS_SERVICE_GXSV1_TYPE_GXSID), + RsIdentity(this), GxsTokenQueue(this), RsTickEvent(), mIdMtx("p3IdService") { - mCacheTest_LastTs = 0; - mCacheTest_Active = false; - - mCacheLoad_LastCycle = 0; - mCacheLoad_Status = 0; - - mHashPgp_SearchActive = false; - mHashPgp_LastTs = 0; - mBgSchedule_Mode = 0; mBgSchedule_Active = false; + + // Kick off Cache Testing, + Others. + RsTickEvent::schedule_in(GXSID_EVENT_CACHETEST, CACHETEST_PERIOD); + RsTickEvent::schedule_in(GXSID_EVENT_PGPHASH, PGPHASH_PERIOD); + RsTickEvent::schedule_in(GXSID_EVENT_REPUTATION, REPUTATION_PERIOD); + RsTickEvent::schedule_now(GXSID_EVENT_CACHEOWNIDS); } + + void p3IdService::service_tick() { - //std::cerr << "p3IdService::service_tick()"; - //std::cerr << std::endl; - - // Disable for now. - // background_tick(); - - cache_tick(); - - // internal testing - request keys. (NOT FINISHED YET) - cachetest_tick(); - - // background stuff. - scheduling_tick(); - + RsTickEvent::tick_events(); + GxsTokenQueue::checkRequests(); // GxsTokenQueue handles all requests. return; } @@ -123,19 +142,48 @@ void p3IdService::notifyChanges(std::vector &changes) /******************* RsIdentity Interface ***************************************/ /********************************************************************************/ +#if 0 bool p3IdService:: getNickname(const RsGxsId &id, std::string &nickname) { return false; } +#endif bool p3IdService:: getIdDetails(const RsGxsId &id, RsIdentityDetails &details) { + std::cerr << "p3IdService::getIdDetails(" << id << ")"; + std::cerr << std::endl; + + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + RsGxsIdCache data; + if (mPublicKeyCache.fetch(id, data)) + { + details = data.details; + return true; + } + + /* try private cache too */ + if (mPrivateKeyCache.fetch(id, data)) + { + details = data.details; + return true; + } + } + + /* it isn't there - add to public requests */ + cache_request_load(id); + return false; } + bool p3IdService:: getOwnIds(std::list &ownIds) { - return false; + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + ownIds = mOwnIds; + + return true; } @@ -161,6 +209,7 @@ bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) } createGroup(token, id); + return true; } @@ -532,31 +581,73 @@ std::string SSGxsIdGroup::save() const */ RsGxsIdCache::RsGxsIdCache() - :reputation(0), lastUsedTs(0) { return; } RsGxsIdCache::RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvSecurityKey &in_pkey) { - id = item->meta.mGroupId; - name = item->meta.mGroupName; + // Save Keys. pubkey = in_pkey; - std::cerr << "RsGxsIdCache::RsGxsIdCache() for: " << id; + // Fill in Details. + details.mNickname = item->meta.mGroupName; + details.mId = item->meta.mGroupId; + + std::cerr << "RsGxsIdCache::RsGxsIdCache() for: " << details.mId; std::cerr << std::endl; - reputation = 0; /* TODO: extract from string - This will need to be refreshed!!! */ - lastUsedTs = 0; + details.mIsOwnId = (item->meta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN); + details.mPgpLinked = (item->meta.mGroupFlags & RSGXSID_GROUPFLAG_REALID); + + /* rest must be retrived from ServiceString */ + updateServiceString(item->meta.mServiceString); } +void RsGxsIdCache::updateServiceString(std::string serviceString) +{ + SSGxsIdGroup ssdata; + if (ssdata.load(serviceString)) + { + if (details.mPgpLinked) + { + details.mPgpKnown = ssdata.pgp.idKnown; + if (details.mPgpKnown) + { + details.mPgpId = ssdata.pgp.pgpId; + } + else + { + details.mPgpId = ""; + } + } + + details.mOpinion = 0; + details.mReputation = ssdata.score.score; + } + else + { + details.mPgpKnown = false; + details.mPgpId = ""; + + details.mOpinion = 0; + details.mReputation = 0; + } +} + + + + + + + bool p3IdService::cache_store(const RsGxsIdGroupItem *item) { - std::cerr << "p3IdService::cache_store() Item: "; + std::cerr << "p3IdService::cache_store() Item: " << item->meta.mGroupId; std::cerr << std::endl; //item->print(std::cerr, 0); NEEDS CONST!!!! TODO - std::cerr << std::endl; + //std::cerr << std::endl; /* extract key from keys */ RsTlvSecurityKeySet keySet; @@ -627,54 +718,33 @@ bool p3IdService::cache_store(const RsGxsIdGroupItem *item) #define MIN_CYCLE_GAP 2 -int p3IdService::cache_tick() -{ - //std::cerr << "p3IdService::cache_tick()"; - //std::cerr << std::endl; - - /* every minute - run a background check */ - time_t now = time(NULL); - bool doCycle = false; - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - if (now - mCacheLoad_LastCycle > MIN_CYCLE_GAP) - { - doCycle = true; - mCacheLoad_LastCycle = now; - } - } - - if (doCycle) - { - cache_start_load(); - } - - cache_check_loading(); - - - return 0; -} - bool p3IdService::cache_request_load(const RsGxsId &id) { std::cerr << "p3IdService::cache_request_load(" << id << ")"; std::cerr << std::endl; - bool start = false; { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mCacheLoad_ToCache.push_back(id); + } - if (time(NULL) - mCacheLoad_LastCycle > MIN_CYCLE_GAP) + if (RsTickEvent::event_count(GXSID_EVENT_CACHELOAD) > 0) + { + /* its already scheduled */ + return true; + } + + int32_t age = 0; + if (RsTickEvent::prev_event_ago(GXSID_EVENT_CACHELOAD, age)) + { + if (age < MIN_CYCLE_GAP) { - start = true; + RsTickEvent::schedule_in(GXSID_EVENT_CACHELOAD, MIN_CYCLE_GAP - age); + return true; } } - if (start) - cache_start_load(); - + RsTickEvent::schedule_now(GXSID_EVENT_CACHELOAD); return true; } @@ -690,6 +760,8 @@ bool p3IdService::cache_start_load() std::list::iterator it; for(it = mCacheLoad_ToCache.begin(); it != mCacheLoad_ToCache.end(); it++) { + std::cerr << "p3IdService::cache_start_load() GroupId: " << *it; + std::cerr << std::endl; groupIds.push_back(*it); // might need conversion? } @@ -701,69 +773,17 @@ bool p3IdService::cache_start_load() std::cerr << "p3IdService::cache_start_load() #Groups: " << groupIds.size(); std::cerr << std::endl; - mCacheLoad_LastCycle = time(NULL); - mCacheLoad_Status = 1; - uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; uint32_t token = 0; RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts, groupIds); - - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mCacheLoad_Tokens.push_back(token); - } + GxsTokenQueue::queueRequest(token, GXSIDREQ_CACHELOAD); } return 1; } -bool p3IdService::cache_check_loading() -{ - /* check the status of all active tokens */ - std::list toload; - std::list::iterator it; - - bool stuffToLoad = false; - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - for(it = mCacheLoad_Tokens.begin(); it != mCacheLoad_Tokens.end();) - { - std::cerr << "p3IdService::cache_check_loading() token: " << *it; - std::cerr << std::endl; - - uint32_t token = *it; - uint32_t status = RsGenExchange::getTokenService()->requestStatus(token); - //checkRequestStatus(token, status, reqtype, anstype, ts); - - if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) - { - it = mCacheLoad_Tokens.erase(it); - toload.push_back(token); - stuffToLoad = true; - } - else - { - it++; - } - } - } - - if (stuffToLoad) - { - for(it = toload.begin(); it != toload.end(); it++) - { - cache_load_for_token(*it); - } - - // cleanup. - mPrivateKeyCache.resize(); - mPublicKeyCache.resize(); - } - return 1; - -} bool p3IdService::cache_load_for_token(uint32_t token) { @@ -789,6 +809,10 @@ bool p3IdService::cache_load_for_token(uint32_t token) cache_store(item); delete item; } + + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + mPrivateKeyCache.resize(); + mPublicKeyCache.resize(); } else { @@ -801,49 +825,126 @@ bool p3IdService::cache_load_for_token(uint32_t token) } -/************************************************************************************/ -/************************************************************************************/ -#define TEST_PERIOD 60 - -bool p3IdService::cachetest_tick() +bool p3IdService::cache_update_if_cached(const RsGxsId &id, std::string serviceString) { - /* every minute - run a background check */ - time_t now = time(NULL); - bool doTest = false; - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - if (now - mCacheTest_LastTs > TEST_PERIOD) - { - doTest = true; - mCacheTest_LastTs = now; - } - } + /* if these entries are cached - update with new info */ + std::cerr << "p3IdService::cache_update_if_cached(" << id << ")"; + std::cerr << std::endl; - if (doTest) + /* retrieve - update, save */ + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + RsGxsIdCache pub_data; + if (mPublicKeyCache.fetch(id, pub_data)) { - std::cerr << "p3IdService::cachetest_tick() starting"; + std::cerr << "p3IdService::cache_update_if_cached() Updating Public Cache"; std::cerr << std::endl; - cachetest_getlist(); + + pub_data.updateServiceString(serviceString); + mPublicKeyCache.store(id, pub_data); + } + + + RsGxsIdCache priv_data; + if (mPrivateKeyCache.fetch(id, priv_data)) + { + std::cerr << "p3IdService::cache_update_if_cached() Updating Private Cache"; + std::cerr << std::endl; + + priv_data.updateServiceString(serviceString); + mPrivateKeyCache.store(id, priv_data); } - cachetest_request(); return true; } +/************************************************************************************/ +/************************************************************************************/ + +bool p3IdService::cache_request_ownids() +{ + /* trigger request to load missing ids into cache */ + std::list groupIds; + std::cerr << "p3IdService::cache_request_ownids()"; + std::cerr << std::endl; + + uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + //opts.mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; + + uint32_t token = 0; + + RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts); + GxsTokenQueue::queueRequest(token, GXSIDREQ_CACHEOWNIDS); + return 1; +} + + +bool p3IdService::cache_load_ownids(uint32_t token) +{ + std::cerr << "p3IdService::cache_load_ownids() : " << token; + std::cerr << std::endl; + + std::vector grpData; + bool ok = RsGenExchange::getGroupData(token, grpData); + + if(ok) + { + std::vector::iterator vit = grpData.begin(); + + // Save List + { + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + mOwnIds.clear(); + for(vit = grpData.begin(); vit != grpData.end(); vit++) + { + RsGxsIdGroupItem* item = dynamic_cast(*vit); + + + if (item->meta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) + { + mOwnIds.push_back(item->meta.mGroupId); + } + } + } + + // Cache Items too. + for(vit = grpData.begin(); vit != grpData.end(); vit++) + { + RsGxsIdGroupItem* item = dynamic_cast(*vit); + if (item->meta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) + { + + std::cerr << "p3IdService::cache_load_ownids() Loaded Id with Meta: "; + std::cerr << item->meta; + std::cerr << std::endl; + + /* cache the data */ + cache_store(item); + } + delete item; + } + + } + else + { + std::cerr << "p3IdService::cache_load_ownids() ERROR no data"; + std::cerr << std::endl; + + return false; + } + return true; +} + + +/************************************************************************************/ +/************************************************************************************/ + bool p3IdService::cachetest_getlist() { - - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - if (mCacheTest_Active) - { - std::cerr << "p3IdService::cachetest_getlist() Already active"; - std::cerr << std::endl; - return false; - } - } - std::cerr << "p3IdService::cachetest_getlist() making request"; std::cerr << std::endl; @@ -853,119 +954,93 @@ bool p3IdService::cachetest_getlist() uint32_t token = 0; RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts); - - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mCacheTest_Token = token; - mCacheTest_Active = true; - } + GxsTokenQueue::queueRequest(token, GXSIDREQ_CACHETEST); + + // Schedule Next Event. + RsTickEvent::schedule_in(GXSID_EVENT_CACHETEST, CACHETEST_PERIOD); return true; } - -bool p3IdService::cachetest_request() +bool p3IdService::cachetest_handlerequest(uint32_t token) { - uint32_t token = 0; - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - if (!mCacheTest_Active) - { - return false; - } - token = mCacheTest_Token; - } - - std::cerr << "p3IdService::cachetest_request() checking request"; + std::cerr << "p3IdService::cachetest_handlerequest() token: " << token; std::cerr << std::endl; - uint32_t status = RsGenExchange::getTokenService()->requestStatus(token); - - if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) - { - std::cerr << "p3IdService::cachetest_request() token ready: " << token; - std::cerr << std::endl; - std::list grpIds; bool ok = RsGenExchange::getGroupList(token, grpIds); - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mCacheTest_Active = false; - } + if(ok) + { + std::list::iterator vit = grpIds.begin(); + for(; vit != grpIds.end(); vit++) + { + /* 5% chance of checking it! */ + if (RSRandom::random_f32() < 0.25) + { + std::cerr << "p3IdService::cachetest_request() Testing Id: " << *vit; + std::cerr << std::endl; - if(ok) - { - std::list::iterator vit = grpIds.begin(); - for(; vit != grpIds.end(); vit++) - { - /* 5% chance of checking it! */ - if (RSRandom::random_f32() < 0.25) + /* try the cache! */ + if (!haveKey(*vit)) { - std::cerr << "p3IdService::cachetest_request() Testing Id: " << *vit; + std::list nullpeers; + requestKey(*vit, nullpeers); + + std::cerr << "p3IdService::cachetest_request() Requested Key Id: " << *vit; std::cerr << std::endl; - - /* try the cache! */ - if (!haveKey(*vit)) + } + else + { + RsTlvSecurityKey seckey; + if (getKey(*vit, seckey)) { - std::list nullpeers; - requestKey(*vit, nullpeers); - - std::cerr << "p3IdService::cachetest_request() Requested Key Id: " << *vit; + std::cerr << "p3IdService::cachetest_request() Got Key OK Id: " << *vit; std::cerr << std::endl; - } - else - { - RsTlvSecurityKey seckey; - if (getKey(*vit, seckey)) - { - std::cerr << "p3IdService::cachetest_request() Got Key OK Id: " << *vit; - std::cerr << std::endl; - // success! + // success! seckey.print(std::cerr, 10); - std::cerr << std::endl; + std::cerr << std::endl; - } - else - { - std::cerr << "p3IdService::cachetest_request() ERROR no Key for Id: " << *vit; - std::cerr << std::endl; - } } - - /* try private key too! */ - if (!havePrivateKey(*vit)) + else { - requestPrivateKey(*vit); - std::cerr << "p3IdService::cachetest_request() Requested PrivateKey Id: " << *vit; + std::cerr << "p3IdService::cachetest_request() ERROR no Key for Id: " << *vit; + std::cerr << std::endl; + } + } + + /* try private key too! */ + if (!havePrivateKey(*vit)) + { + requestPrivateKey(*vit); + std::cerr << "p3IdService::cachetest_request() Requested PrivateKey Id: " << *vit; + std::cerr << std::endl; + } + else + { + RsTlvSecurityKey seckey; + if (getPrivateKey(*vit, seckey)) + { + // success! + std::cerr << "p3IdService::cachetest_request() Got PrivateKey OK Id: " << *vit; std::cerr << std::endl; } else { - RsTlvSecurityKey seckey; - if (getPrivateKey(*vit, seckey)) - { - // success! - std::cerr << "p3IdService::cachetest_request() Got PrivateKey OK Id: " << *vit; - std::cerr << std::endl; - } - else - { - std::cerr << "p3IdService::cachetest_request() ERROR no PrivateKey for Id: " << *vit; - std::cerr << std::endl; - } + std::cerr << "p3IdService::cachetest_request() ERROR no PrivateKey for Id: " << *vit; + std::cerr << std::endl; } } } - } - else - { - std::cerr << "p3IdService::cache_load_for_token() ERROR no data"; - std::cerr << std::endl; - - return false; } + } + else + { + std::cerr << "p3IdService::cache_load_for_token() ERROR no data"; + std::cerr << std::endl; + + return false; } return true; } @@ -985,59 +1060,44 @@ bool p3IdService::cachetest_request() * */ -#define ID_BACKGROUND_PERIOD 60 -int p3IdService::scheduling_tick() +bool p3IdService::CacheArbitration(uint32_t mode) { - //std::cerr << "p3IdService::scheduling_tick()"; - //std::cerr << std::endl; + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - /*** MUTEX TODO ***/ - bool active; - uint32_t mode; + if (!mBgSchedule_Active) { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - active = mBgSchedule_Active; - mode = mBgSchedule_Mode; + std::cerr << "p3IdService::CacheArbitration() Okay"; + std::cerr << std::endl; + + mBgSchedule_Active = true; + mBgSchedule_Mode = mode; + return true; } - if (active) - { - bool done = false; - if (mode == BG_PGPHASH) - { - done = pgphash_continue(); - } - else - { - done = reputation_continue(); - } + std::cerr << "p3IdService::CacheArbitration() Is busy..."; + std::cerr << std::endl; - if (done) - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mBgSchedule_Active = false; - } - } - else - { - if (pgphash_start()) - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mBgSchedule_Mode = BG_PGPHASH; - mBgSchedule_Active = true; - } - else if (reputation_start()) - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mBgSchedule_Mode = BG_REPUTATION; - mBgSchedule_Active = true; - } - } - - return 1; + return false; } +void p3IdService::CacheArbitrationDone(uint32_t mode) +{ + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + if (mBgSchedule_Mode != mode) + { + /* issues */ + std::cerr << "p3IdService::CacheArbitrationDone() ERROR Wrong Current Mode"; + std::cerr << std::endl; + return; + } + + std::cerr << "p3IdService::CacheArbitrationDone()"; + std::cerr << std::endl; + + mBgSchedule_Active = false; +} /************************************************************************************/ /************************************************************************************/ @@ -1079,7 +1139,6 @@ void p3IdService::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet return; } - /********************* TEMP HACK UNTIL GXS FILLS IN GROUP_ID *****************/ // find private admin key std::map::iterator mit = keySet.keys.begin(); @@ -1087,7 +1146,7 @@ void p3IdService::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet { RsTlvSecurityKey& pk = mit->second; - if(pk.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL)) + if(pk.keyFlags == (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL)) { item->group.mMeta.mGroupId = pk.keyId; break; @@ -1106,6 +1165,8 @@ void p3IdService::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet std::cerr << "p3IdService::service_CreateGroup() for : " << item->group.mMeta.mGroupId; std::cerr << std::endl; + std::cerr << "p3IdService::service_CreateGroup() Alt GroupId : " << item->meta.mGroupId; + std::cerr << std::endl; if (item->group.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID) { @@ -1153,6 +1214,10 @@ void p3IdService::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet #endif } + + // Reload in a little bit. + // HACK to get it to work. + RsTickEvent::schedule_in(GXSID_EVENT_CACHEOWNIDS, OWNID_RELOAD_DELAY); } @@ -1161,66 +1226,20 @@ void p3IdService::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet bool p3IdService::pgphash_start() { - /* every minute - run a background check */ - time_t now = time(NULL); - bool doHash = false; + if (!CacheArbitration(BG_PGPHASH)) { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - if (now - mHashPgp_LastTs > HASHPGP_PERIOD) - { - doHash = true; - mHashPgp_LastTs = now; - } - } - - if (doHash) - { - std::cerr << "p3IdService::pgphash_tick() starting"; + std::cerr << "p3IdService::pgphash_start() Other Events running... Rescheduling"; std::cerr << std::endl; - pgphash_getlist(); - return true; - } - return false; -} - -bool p3IdService::pgphash_continue() -{ - std::cerr << "p3IdService::pgphash_continue()"; - std::cerr << std::endl; - bool active; - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - active = mHashPgp_SearchActive; + /* reschedule in a bit */ + RsTickEvent::schedule_in(GXSID_EVENT_PGPHASH, PGPHASH_RETRY_PERIOD); + return false; } - if (active) - { - pgphash_request(); - } - else - { - return pgphash_process(); - } - return false; -} + // SCHEDULE NEXT ONE. + RsTickEvent::schedule_in(GXSID_EVENT_PGPHASH, PGPHASH_PERIOD); - - -bool p3IdService::pgphash_getlist() -{ - - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - if (mHashPgp_SearchActive) - { - std::cerr << "p3IdService::pgphash_getlist() Already active"; - std::cerr << std::endl; - return false; - } - } - - std::cerr << "p3IdService::pgphash_getlist() making request"; + std::cerr << "p3IdService::pgphash_start() making request"; std::cerr << std::endl; getPgpIdList(); @@ -1237,127 +1256,98 @@ bool p3IdService::pgphash_getlist() uint32_t token = 0; RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts); - - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mHashPgp_Token = token; - mHashPgp_SearchActive = true; - } + GxsTokenQueue::queueRequest(token, GXSIDREQ_PGPHASH); return true; } -bool p3IdService::pgphash_request() +bool p3IdService::pgphash_handlerequest(uint32_t token) { - uint32_t token = 0; - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - if (!mHashPgp_SearchActive) - { - std::cerr << "p3IdService::pgphash_request() Search Not Active returning false"; - std::cerr << std::endl; - - return false; - } - token = mHashPgp_Token; - } - - std::cerr << "p3IdService::pgphash_request() checking request"; + std::cerr << "p3IdService::pgphash_handlerequest(" << token << ")"; std::cerr << std::endl; - uint32_t status = RsGenExchange::getTokenService()->requestStatus(token); + // We need full data - for access to Hash & Signature. + // Perhaps we will change this to an initial pass through Meta, + // and use this to discard lots of things. - if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) - { - std::cerr << "p3IdService::pgphash_request() token ready: " << token; + // Even better - we can set flags in the Meta Data, (IdType), + // And use GXS to filter out all the AnonIds, and only have to process + // Proper Ids. + + // We Will do this later! + + std::vector groups; + std::vector groupsToProcess; + bool ok = getGroupData(token, groups); + + if(ok) + { + std::cerr << "p3IdService::pgphash_request() Have " << groups.size() << " Groups"; std::cerr << std::endl; - // We need full data - for access to Hash & Signature. - // Perhaps we will change this to an initial pass through Meta, - // and use this to discard lots of things. - - // Even better - we can set flags in the Meta Data, (IdType), - // And use GXS to filter out all the AnonIds, and only have to process - // Proper Ids. - - // We Will do this later! - - std::vector groups; - std::vector groupsToProcess; - bool ok = getGroupData(token, groups); - - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mHashPgp_SearchActive = false; - } - - if(ok) - { - std::cerr << "p3IdService::pgphash_request() Have " << groups.size() << " Groups"; + std::vector::iterator vit; + for(vit = groups.begin(); vit != groups.end(); vit++) + { + std::cerr << "p3IdService::pgphash_request() Group Id: " << vit->mMeta.mGroupId; std::cerr << std::endl; - std::vector::iterator vit; - for(vit = groups.begin(); vit != groups.end(); vit++) - { - std::cerr << "p3IdService::pgphash_request() Group Id: " << vit->mMeta.mGroupId; + /* Filter based on IdType */ + if (!(vit->mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)) + { + std::cerr << "p3IdService::pgphash_request() discarding AnonID"; std::cerr << std::endl; + continue; + } - /* Filter based on IdType */ - if (!(vit->mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)) + /* now we need to decode the Service String - see what is saved there */ + SSGxsIdGroup ssdata; + if (ssdata.load(vit->mMeta.mServiceString)) + { + if (ssdata.pgp.idKnown) { - std::cerr << "p3IdService::pgphash_request() discarding AnonID"; + std::cerr << "p3IdService::pgphash_request() discarding Already Known"; std::cerr << std::endl; continue; } - /* now we need to decode the Service String - see what is saved there */ - SSGxsIdGroup ssdata; - if (ssdata.load(vit->mMeta.mServiceString)) - { - if (ssdata.pgp.idKnown) - { - std::cerr << "p3IdService::pgphash_request() discarding Already Known"; - std::cerr << std::endl; - continue; - } - - /* Have a linear attempt policy - - * if zero checks - try now. - * if 1 check, at least a day. - * if 2 checks: 2days, etc. - */ + /* Have a linear attempt policy - + * if zero checks - try now. + * if 1 check, at least a day. + * if 2 checks: 2days, etc. + */ #define SECS_PER_DAY (3600 * 24) - time_t age = time(NULL) - ssdata.pgp.lastCheckTs; - time_t wait_period = ssdata.pgp.checkAttempts * SECS_PER_DAY; - if (wait_period > 30 * SECS_PER_DAY) - { - wait_period = 30 * SECS_PER_DAY; - } - - if (age < wait_period) - { - std::cerr << "p3IdService::pgphash_request() discarding Recent Check"; - std::cerr << std::endl; - continue; - } + time_t age = time(NULL) - ssdata.pgp.lastCheckTs; + time_t wait_period = ssdata.pgp.checkAttempts * SECS_PER_DAY; + if (wait_period > 30 * SECS_PER_DAY) + { + wait_period = 30 * SECS_PER_DAY; } - /* if we get here -> then its to be processed */ - std::cerr << "p3IdService::pgphash_request() ToProcess Group: " << vit->mMeta.mGroupId; - std::cerr << std::endl; - - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mGroupsToProcess.push_back(*vit); + if (age < wait_period) + { + std::cerr << "p3IdService::pgphash_request() discarding Recent Check"; + std::cerr << std::endl; + continue; + } } - } - else - { - std::cerr << "p3IdService::pgphash_request() getGroupData ERROR"; - std::cerr << std::endl; - } + /* if we get here -> then its to be processed */ + std::cerr << "p3IdService::pgphash_request() ToProcess Group: " << vit->mMeta.mGroupId; + std::cerr << std::endl; + + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + mGroupsToProcess.push_back(*vit); + } } + else + { + std::cerr << "p3IdService::pgphash_request() getGroupData ERROR"; + std::cerr << std::endl; + } + + // Schedule Processing. + RsTickEvent::schedule_in(GXSID_EVENT_PGPHASH_PROC, PGPHASH_PROC_PERIOD); return true; } @@ -1365,22 +1355,33 @@ bool p3IdService::pgphash_process() { /* each time this is called - process one Id from mGroupsToProcess */ RsGxsIdGroup pg; + bool isDone = false; { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - if (mGroupsToProcess.empty()) + if (!mGroupsToProcess.empty()) { - std::cerr << "p3IdService::pgphash_process() List Empty... Done"; + pg = mGroupsToProcess.front(); + mGroupsToProcess.pop_front(); + + std::cerr << "p3IdService::pgphash_process() Popped Group: " << pg.mMeta.mGroupId; std::cerr << std::endl; - return true; } - - pg = mGroupsToProcess.front(); - mGroupsToProcess.pop_front(); - - std::cerr << "p3IdService::pgphash_process() Popped Group: " << pg.mMeta.mGroupId; - std::cerr << std::endl; + else + { + isDone = true; + } } + if (isDone) + { + std::cerr << "p3IdService::pgphash_process() List Empty... Done"; + std::cerr << std::endl; + // FINISHED. + CacheArbitrationDone(BG_PGPHASH); + return true; + } + + SSGxsIdGroup ssdata; ssdata.load(pg.mMeta.mServiceString); // attempt load - okay if fails. @@ -1437,6 +1438,10 @@ bool p3IdService::pgphash_process() std::string serviceString = ssdata.save(); setGroupServiceString(dummyToken, pg.mMeta.mGroupId, serviceString); + cache_update_if_cached(pg.mMeta.mGroupId, serviceString); + + // Schedule Next Processing. + RsTickEvent::schedule_in(GXSID_EVENT_PGPHASH_PROC, PGPHASH_PROC_PERIOD); return false; // as there are more items on the queue to process. } @@ -1793,16 +1798,24 @@ std::string rsIdTypeToString(uint32_t idtype) bool p3IdService::reputation_start() { - return false; -} + if (!CacheArbitration(BG_REPUTATION)) + { + std::cerr << "p3IdService::reputation_start() Other Events running... Rescheduling"; + std::cerr << std::endl; + /* reschedule in a bit */ + RsTickEvent::schedule_in(GXSID_EVENT_REPUTATION, REPUTATION_RETRY_PERIOD); + return false; + } -bool p3IdService::reputation_continue() -{ + CacheArbitrationDone(BG_REPUTATION); + // SCHEDULE NEXT ONE. + RsTickEvent::schedule_in(GXSID_EVENT_REPUTATION, REPUTATION_PERIOD); return true; } + #define ID_BACKGROUND_PERIOD 60 int p3IdService::background_tick() @@ -2373,3 +2386,89 @@ std::ostream &operator<<(std::ostream &out, const RsGxsIdOpinion &opinion) return out; } + + + + + + + + + + // Overloaded from GxsTokenQueue for Request callbacks. +void p3IdService::handleResponse(uint32_t token, uint32_t req_type) +{ + std::cerr << "p3IdService::handleResponse(" << token << "," << req_type << ")"; + std::cerr << std::endl; + + // stuff. + switch(req_type) + { + case GXSIDREQ_CACHEOWNIDS: + cache_load_ownids(token); + break; + case GXSIDREQ_CACHELOAD: + cache_load_for_token(token); + break; + case GXSIDREQ_PGPHASH: + pgphash_handlerequest(token); + break; + case GXSIDREQ_CACHETEST: + cachetest_handlerequest(token); + break; + + case GXSIDREQ_REPUTATION: + + break; + default: + /* error */ + std::cerr << "p3IdService::handleResponse() Unknown Request Type: " << req_type; + std::cerr << std::endl; + break; + } +} + + + // Overloaded from RsTickEvent for Event callbacks. +void p3IdService::handle_event(uint32_t event_type) +{ + std::cerr << "p3IdService::handle_event(" << event_type << ")"; + std::cerr << std::endl; + + // stuff. + switch(event_type) + { + case GXSID_EVENT_CACHEOWNIDS: + cache_request_ownids(); + break; + + case GXSID_EVENT_CACHELOAD: + cache_start_load(); + break; + + case GXSID_EVENT_CACHETEST: + cachetest_getlist(); + break; + + case GXSID_EVENT_REPUTATION: + reputation_start(); + break; + + case GXSID_EVENT_PGPHASH: + pgphash_start(); + break; + + case GXSID_EVENT_PGPHASH_PROC: + pgphash_process(); + break; + + default: + /* error */ + std::cerr << "p3IdService::handle_event() Unknown Event Type: " << event_type; + std::cerr << std::endl; + break; + } +} + + + diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index 72e752740..1a21e6d16 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -31,10 +31,13 @@ #include "gxs/rsgenexchange.h" // GXS service. #include "gxs/rsgixs.h" // Internal Interfaces. +#include "gxs/gxstokenqueue.h" + #include #include #include "util/rsmemcache.h" +#include "util/rstickevent.h" #include "pqi/authgpg.h" @@ -132,31 +135,33 @@ class RsGxsIdCache RsGxsIdCache(); RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvSecurityKey &in_pkey); - RsGxsId id; - std::string name; - RsTlvSecurityKey pubkey; - double reputation; - time_t lastUsedTs; +void updateServiceString(std::string serviceString); + RsIdentityDetails details; + RsTlvSecurityKey pubkey; }; +#if 0 class LruData { public: RsGxsId key; }; +#endif // Not sure exactly what should be inherited here? // Chris - please correct as necessary. -class p3IdService: public RsGxsIdExchange, public RsIdentity +class p3IdService: public RsGxsIdExchange, public RsIdentity, + public GxsTokenQueue, public RsTickEvent { public: p3IdService(RsGeneralDataService* gds, RsNetworkExchangeService* nes); + virtual void service_tick(); // needed for background processing. @@ -174,12 +179,20 @@ virtual bool createMsg(uint32_t& token, RsGxsIdOpinion &opinion); /**************** RsIdentity External Interface. * Notes: + * + * All the data is cached together for the moment - We should probably + * seperate and sort this out. + * + * Also need to handle Cache updates / invalidation from internal changes. + * */ -virtual bool getNickname(const RsGxsId &id, std::string &nickname); +//virtual bool getNickname(const RsGxsId &id, std::string &nickname); virtual bool getIdDetails(const RsGxsId &id, RsIdentityDetails &details); virtual bool getOwnIds(std::list &ownIds); + + // virtual bool submitOpinion(uint32_t& token, RsIdOpinion &opinion); virtual bool createIdentity(uint32_t& token, RsIdentityParameters ¶ms); @@ -208,6 +221,13 @@ virtual int getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key); virtual bool getReputation(const RsGxsId &id, const GixsReputation &rep); + + // Overloaded from GxsTokenQueue for Request callbacks. +virtual void handleResponse(uint32_t token, uint32_t req_type); + + // Overloaded from RsTickEvent. +virtual void handle_event(uint32_t event_type); + protected: /** Notifications **/ @@ -226,20 +246,27 @@ virtual void service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& key bool cache_request_load(const RsGxsId &id); bool cache_start_load(); - bool cache_check_loading(); bool cache_load_for_token(uint32_t token); bool cache_store(const RsGxsIdGroupItem *item); + bool cache_update_if_cached(const RsGxsId &id, std::string serviceString); + + // Mutex protected. - time_t mCacheLoad_LastCycle; - int mCacheLoad_Status; std::list mCacheLoad_ToCache; - std::list mCacheLoad_Tokens; // Switching to RsMemCache for Key Caching. RsMemCache mPublicKeyCache; RsMemCache mPrivateKeyCache; +/************************************************************************ + * Refreshing own Ids. + * + */ + bool cache_request_ownids(); + bool cache_load_ownids(uint32_t token); + + std::list mOwnIds; /************************************************************************ * Test fns for Caching. @@ -247,20 +274,14 @@ virtual void service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& key */ bool cachetest_tick(); bool cachetest_getlist(); - bool cachetest_request(); - - /* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */ - - time_t mCacheTest_LastTs; - bool mCacheTest_Active; - uint32_t mCacheTest_Token; - + bool cachetest_handlerequest(uint32_t token); /************************************************************************ * for processing background tasks that use the serviceString. * - must be mutually exclusive to avoid clashes. */ - int scheduling_tick(); + bool CacheArbitration(uint32_t mode); + void CacheArbitrationDone(uint32_t mode); bool mBgSchedule_Active; uint32_t mBgSchedule_Mode; @@ -270,19 +291,13 @@ virtual void service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& key * */ bool pgphash_start(); - bool pgphash_continue(); - - bool pgphash_getlist(); - bool pgphash_request(); + bool pgphash_handlerequest(uint32_t token); bool pgphash_process(); bool checkId(const RsGxsIdGroup &grp, PGPIdType &pgp_id); void getPgpIdList(); - /* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */ - time_t mHashPgp_LastTs; - bool mHashPgp_SearchActive; - uint32_t mHashPgp_Token; + /* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */ std::map mPgpFingerprintMap; std::list mGroupsToProcess; diff --git a/libretroshare/src/util/rsmemcache.h b/libretroshare/src/util/rsmemcache.h index 66087ce34..cd7e96d21 100644 --- a/libretroshare/src/util/rsmemcache.h +++ b/libretroshare/src/util/rsmemcache.h @@ -133,20 +133,22 @@ template bool RsMemCache::store(const Key &k std::cerr << "RsMemCache::store()"; std::cerr << std::endl; + /* update lrumap entry */ + time_t old_ts = 0; + time_t new_ts = time(NULL); + // For consistency typename std::map::const_iterator it; it = mDataMap.find(key); if (it != mDataMap.end()) { // ERROR. - std::cerr << "RsMemCache::store() ERROR entry exists already"; + std::cerr << "RsMemCache::store() WARNING overriding existing entry"; std::cerr << std::endl; - return false; + + old_ts = it->second.ts; } - /* add new lrumap entry */ - time_t old_ts = 0; - time_t new_ts = time(NULL); mDataMap[key] = cache_data(key, data, new_ts); mDataCount++; diff --git a/libretroshare/src/util/rstickevent.cc b/libretroshare/src/util/rstickevent.cc new file mode 100644 index 000000000..d0d39e9b0 --- /dev/null +++ b/libretroshare/src/util/rstickevent.cc @@ -0,0 +1,185 @@ +/* + * libretroshare/src/util: rstickevent.cc + * + * Identity interface for RetroShare. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "util/rstickevent.h" + +#include +#include + +//#define DEBUG_EVENTS 1 + +void RsTickEvent::tick_events() +{ +#ifdef DEBUG_EVENTS + std::cerr << "RsTickEvent::tick_events() Event List:"; + std::cerr << std::endl; +#endif + + time_t now = time(NULL); + { + RsStackMutex stack(mEventMtx); /********** STACK LOCKED MTX ******/ + +#ifdef DEBUG_EVENTS + if (!mEvents.empty()) + { + std::multimap::iterator it; + + for(it = mEvents.begin(); it != mEvents.end(); it++) + { + std::cerr << "\tEvent type: "; + std::cerr << it->second << " in " << it->first - now << " secs"; + std::cerr << std::endl; + } + } +#endif + + if (mEvents.empty()) + { + return; + } + + /* all events in the future */ + if (mEvents.begin()->first > now) + { + return; + } + } + + std::list toProcess; + std::list::iterator it; + + { + RsStackMutex stack(mEventMtx); /********** STACK LOCKED MTX ******/ + while((!mEvents.empty()) && (mEvents.begin()->first <= now)) + { + std::multimap::iterator it = mEvents.begin(); + uint32_t event_type = it->second; + toProcess.push_back(event_type); + mEvents.erase(it); + + count_adjust_locked(event_type, -1); + } + } + + for(it = toProcess.begin(); it != toProcess.end(); it++) + { + std::cerr << "RsTickEvent::tick_events() calling handle_event("; + std::cerr << *it << ")"; + std::cerr << std::endl; + handle_event(*it); + } +} + +void RsTickEvent::schedule_now(uint32_t event_type) +{ + RsTickEvent::schedule_in(event_type, 0); +} + +void RsTickEvent::schedule_event(uint32_t event_type, time_t when) +{ + RsStackMutex stack(mEventMtx); /********** STACK LOCKED MTX ******/ + mEvents.insert(std::make_pair(when, event_type)); + + count_adjust_locked(event_type, 1); +} + +void RsTickEvent::schedule_in(uint32_t event_type, uint32_t in_secs) +{ + std::cerr << "RsTickEvent::schedule_in(" << event_type << ") in " << in_secs << " secs"; + std::cerr << std::endl; + + RsStackMutex stack(mEventMtx); /********** STACK LOCKED MTX ******/ + time_t event_time = time(NULL) + in_secs; + mEvents.insert(std::make_pair(event_time, event_type)); + + count_adjust_locked(event_type, 1); +} + +void RsTickEvent::handle_event(uint32_t event_type) +{ + std::cerr << "RsTickEvent::handle_event(" << event_type << ") ERROR Not Handled"; + std::cerr << std::endl; +} + + +int32_t RsTickEvent::event_count(uint32_t event_type) +{ + RsStackMutex stack(mEventMtx); /********** STACK LOCKED MTX ******/ + std::map::iterator it; + + it = mEventCount.find(event_type); + if (it == mEventCount.end()) + { + return 0; + } + + return it->second; +} + + +bool RsTickEvent::prev_event_ago(uint32_t event_type, int32_t &age) +{ + RsStackMutex stack(mEventMtx); /********** STACK LOCKED MTX ******/ + std::map::iterator it; + + it = mPreviousEvent.find(event_type); + if (it == mPreviousEvent.end()) + { + return false; + } + + age = time(NULL) - it->second; + return true; +} + + +void RsTickEvent::count_adjust_locked(uint32_t event_type, int32_t change) +{ + std::map::iterator it; + + it = mEventCount.find(event_type); + if (it == mEventCount.end()) + { + mEventCount[event_type] = 0; + it = mEventCount.find(event_type); + } + + it->second += change; + if (it->second < 0) + { + std::cerr << "RsTickEvent::count_adjust() ERROR: COUNT < 0"; + std::cerr << std::endl; + + it->second = 0; + } +} + + +void RsTickEvent::note_event_locked(uint32_t event_type) +{ + mPreviousEvent[event_type] = time(NULL); +} + + diff --git a/libretroshare/src/util/rstickevent.h b/libretroshare/src/util/rstickevent.h new file mode 100644 index 000000000..73786fe77 --- /dev/null +++ b/libretroshare/src/util/rstickevent.h @@ -0,0 +1,67 @@ +/* + * libretroshare/src/util: rstickevent.h + * + * Identity interface for RetroShare. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ +#ifndef RS_UTIL_TICK_EVENT +#define RS_UTIL_TICK_EVENT + + +/* + * + * A simple event queue... to avoid having to continually write separate one. + */ + +#include +#include + +#include "util/rsthreads.h" + +class RsTickEvent +{ + public: + RsTickEvent():mEventMtx("TickEventMtx") { return; } + +void tick_events(); + +void schedule_now(uint32_t event_type); +void schedule_event(uint32_t event_type, time_t when); +void schedule_in(uint32_t event_type, uint32_t in_secs); + +int32_t event_count(uint32_t event_type); +bool prev_event_ago(uint32_t event_type, int32_t &age); + + // Overloaded to handle the events. +virtual void handle_event(uint32_t event_type); + + private: + +void count_adjust_locked(uint32_t event_type, int32_t change); +void note_event_locked(uint32_t event_type); + + RsMutex mEventMtx; + std::map mEventCount; + std::map mPreviousEvent; + std::multimap mEvents; +}; + +#endif // RS_UTIL_TICK_EVENT From c90d0d6abd04f10a80d4d4a83820ee91d94f8726 Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 19 Nov 2012 22:14:45 +0000 Subject: [PATCH 159/222] Added Identity stuff into the GUI. - Generic Classes: - GxsIdChooser: gets a list of current OwnIds for user to select AuthorId. - GxsIdLabel: retrieves and displays Author Information. - GxsIdTreeWidgetItem: retrieves and displays Author Information, in specified column. - Added GxsIdChooser into GxsGroupDialog & CreateGxsForumMsg. - Added GxsIdTreeWidgetItem into Forum Thread listings. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5849 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/RetroShare.pro | 7 + retroshare-gui/src/gui/GxsForumsDialog.cpp | 31 ++-- retroshare-gui/src/gui/GxsForumsDialog.h | 8 +- .../src/gui/gxs/GxsForumGroupDialog.cpp | 1 - retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp | 2 + retroshare-gui/src/gui/gxs/GxsGroupDialog.ui | 8 + retroshare-gui/src/gui/gxs/GxsIdChooser.cpp | 143 ++++++++++++++++++ retroshare-gui/src/gui/gxs/GxsIdChooser.h | 50 ++++++ retroshare-gui/src/gui/gxs/GxsIdLabel.cpp | 124 +++++++++++++++ retroshare-gui/src/gui/gxs/GxsIdLabel.h | 51 +++++++ .../src/gui/gxs/GxsIdTreeWidgetItem.cpp | 141 +++++++++++++++++ .../src/gui/gxs/GxsIdTreeWidgetItem.h | 53 +++++++ .../src/gui/gxsforums/CreateGxsForumMsg.cpp | 28 +++- .../src/gui/gxsforums/CreateGxsForumMsg.ui | 14 +- 14 files changed, 639 insertions(+), 22 deletions(-) create mode 100644 retroshare-gui/src/gui/gxs/GxsIdChooser.cpp create mode 100644 retroshare-gui/src/gui/gxs/GxsIdChooser.h create mode 100644 retroshare-gui/src/gui/gxs/GxsIdLabel.cpp create mode 100644 retroshare-gui/src/gui/gxs/GxsIdLabel.h create mode 100644 retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp create mode 100644 retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.h diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index 050914d3b..e7ebd96db 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -1017,10 +1017,14 @@ gxsgui { gui/gxs/GxsCommentTreeWidget.h \ gui/gxs/WikiGroupDialog.h \ gui/gxs/GxsForumGroupDialog.h \ + gui/gxs/GxsIdChooser.h \ + gui/gxs/GxsIdLabel.h \ + gui/gxs/GxsIdTreeWidgetItem.h \ # gui/gxs/GxsMsgDialog.h \ FORMS += gui/gxs/GxsGroupDialog.ui \ + # gui/gxs/GxsMsgDialog.ui \ # gui/gxs/GxsCommentTreeWidget.ui \ @@ -1028,6 +1032,9 @@ gxsgui { gui/gxs/GxsCommentTreeWidget.cpp \ gui/gxs/WikiGroupDialog.cpp \ gui/gxs/GxsForumGroupDialog.cpp \ + gui/gxs/GxsIdChooser.cpp \ + gui/gxs/GxsIdLabel.cpp \ + gui/gxs/GxsIdTreeWidgetItem.cpp \ # gui/gxs/GxsMsgDialog.cpp \ diff --git a/retroshare-gui/src/gui/GxsForumsDialog.cpp b/retroshare-gui/src/gui/GxsForumsDialog.cpp index 8092cf79a..a0abfb71b 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/GxsForumsDialog.cpp @@ -241,10 +241,6 @@ GxsForumsDialog::GxsForumsDialog(QWidget *parent) ui.threadTreeWidget->installEventFilter(this); - - - rsGxsForums->generateDummyData(); - /* Hide platform specific features */ #ifdef Q_WS_WIN @@ -2094,8 +2090,8 @@ void GxsForumsDialog::loadGroupThreadData_InsertThreads(const uint32_t &token) } } -bool GxsForumsDialog::convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, std::string authorName, - bool useChildTS, uint32_t filterColumn, QTreeWidgetItem *item) +bool GxsForumsDialog::convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, + bool useChildTS, uint32_t filterColumn, GxsIdTreeWidgetItem *item) { QString text; @@ -2120,6 +2116,8 @@ bool GxsForumsDialog::convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, std item->setText(COLUMN_THREAD_TITLE, GxsForumsDialog::titleFromInfo(msgInfo.mMeta)); + item->setId(msgInfo.mMeta.mAuthorId, COLUMN_THREAD_AUTHOR); +#if 0 text = QString::fromUtf8(authorName.c_str()); if (text.isEmpty()) @@ -2130,6 +2128,7 @@ bool GxsForumsDialog::convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, std { item->setText(COLUMN_THREAD_AUTHOR, text); } +#endif #ifdef TOGXS if (msgInfo.mMeta.mMsgFlags & RS_DISTRIB_AUTHEN_REQ) @@ -2173,11 +2172,13 @@ bool GxsForumsDialog::convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, std void GxsForumsDialog::loadForumBaseThread(const RsGxsForumMsg &msg) { - std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); + //std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); - QTreeWidgetItem *item = new QTreeWidgetItem(); // no Parent. + //QTreeWidgetItem *item = new QTreeWidgetItem(); // no Parent. + GxsIdTreeWidgetItem *item = new GxsIdTreeWidgetItem(); // no Parent. - convertMsgToThreadWidget(msg, authorName, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, item); + //convertMsgToThreadWidget(msg, authorName, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, item); + convertMsgToThreadWidget(msg, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, item); /* request Children Data */ uint32_t token; @@ -2262,21 +2263,23 @@ void GxsForumsDialog::loadChildData_InsertThreads(const uint32_t &token) void GxsForumsDialog::loadForumChildMsg(const RsGxsForumMsg &msg, QTreeWidgetItem *parent) { - std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); + //std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); - QTreeWidgetItem *child = NULL; + //QTreeWidgetItem *child = NULL; + GxsIdTreeWidgetItem *child = NULL; if (mThreadLoad.FlatView) { - child = new QTreeWidgetItem(); // no Parent. + child = new GxsIdTreeWidgetItem(); // no Parent. } else { - child = new QTreeWidgetItem(parent); + child = new GxsIdTreeWidgetItem(parent); } - convertMsgToThreadWidget(msg, authorName, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, child); + convertMsgToThreadWidget(msg, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, child); + //convertMsgToThreadWidget(msg, authorName, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, child); /* request Children Data */ uint32_t token; diff --git a/retroshare-gui/src/gui/GxsForumsDialog.h b/retroshare-gui/src/gui/GxsForumsDialog.h index 37d803830..f80769575 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.h +++ b/retroshare-gui/src/gui/GxsForumsDialog.h @@ -34,6 +34,8 @@ #include +#include "gui/gxs/GxsIdTreeWidgetItem.h" + class ForumInfo; @@ -202,8 +204,10 @@ private: void requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId); void loadMsgData_ReplyMessage(const uint32_t &token); - bool convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, std::string authorName, - bool useChildTS, uint32_t filterColumn, QTreeWidgetItem *item); + bool convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, + bool useChildTS, uint32_t filterColumn, GxsIdTreeWidgetItem *item); + //bool convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, std::string authorName, + // bool useChildTS, uint32_t filterColumn, QTreeWidgetItem *item); TokenQueue *mForumQueue; diff --git a/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.cpp index 66381d075..7f8773671 100644 --- a/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.cpp @@ -58,7 +58,6 @@ GxsForumGroupDialog::GxsForumGroupDialog(TokenQueue *tokenQueue, QWidget *parent :GxsGroupDialog(tokenQueue, ForumCreateEnabledFlags, ForumCreateDefaultsFlags, parent, "Create New Forum") { - } GxsForumGroupDialog::GxsForumGroupDialog(const RsGxsForumGroup &group, QWidget *parent) diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index 97e2978b0..402fd3cde 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -84,11 +84,13 @@ GxsGroupDialog::GxsGroupDialog(TokenQueue *tokenQueue, uint32_t enableFlags, uin /* Setup Reasonable Defaults */ + ui.idChooser->loadIds(0,""); } GxsGroupDialog::GxsGroupDialog(const RsGroupMetaData &grpMeta, uint32_t mode, QWidget *parent) : QDialog(parent), mMode(mode), mGrpMeta(grpMeta) { + ui.idChooser->loadIds(0,""); } void GxsGroupDialog::setMode(uint32_t mode) diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui index 777f80b11..c0a9160c0 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui @@ -186,6 +186,9 @@ border-radius: 10px; + + + @@ -554,6 +557,11 @@ p, li { white-space: pre-wrap; }
gui/common/FriendSelectionWidget.h
1
+ + GxsIdChooser + QComboBox +
gui/gxs/GxsIdChooser.h
+
diff --git a/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp b/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp new file mode 100644 index 000000000..0b1fadb48 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp @@ -0,0 +1,143 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include "GxsIdChooser.h" + +#include + +#include + +#include + +/** Constructor */ +GxsIdChooser::GxsIdChooser(QWidget *parent) +: QComboBox(parent), mFlags(IDCHOOSER_ANON_DEFAULT), mDefaultId("") +{ + return; +} + +void GxsIdChooser::loadIds(uint32_t chooserFlags, RsGxsId defId) +{ + mFlags = chooserFlags; + mDefaultId = defId; + loadPrivateIds(); +} + + +bool MakeIdDesc(const RsGxsId &id, QString &desc) +{ + RsIdentityDetails details; + + if (!rsIdentity->getIdDetails(id, details)) + { + return false; + } + + desc = QString::fromUtf8(details.mNickname.c_str()); + if (details.mPgpLinked) + { + desc += " (PGP) ["; + } + else + { + desc += " (Anon) ["; + } + desc += QString::fromStdString(id.substr(0,5)); + desc += "...]"; + + return true; +} + + +void GxsIdChooser::loadPrivateIds() +{ + std::list ids; + rsIdentity->getOwnIds(ids); + + + if (ids.empty()) + { + std::cerr << "GxsIdChooser::loadPrivateIds() ERROR no ids"; + std::cerr << std::endl; + return; + } + + //rsIdentity->getDefaultId(defId); + // Prefer to use an application specific default??? + int def = -1; + + if (!(mFlags & IDCHOOSER_ID_REQUIRED)) + { + /* add No Signature option */ + QString str = "No Signature"; + QString id = ""; + + addItem(str, id); + if (mFlags & IDCHOOSER_ANON_DEFAULT) + { + def = 0; + } + } + + int i = 1; + std::list::iterator it; + for(it = ids.begin(); it != ids.end(); it++, i++) + { + /* add to Chooser */ + QString str; + if (!MakeIdDesc(*it, str)) + { + std::cerr << "GxsIdChooser::loadPrivateIds() ERROR Desc for Id: " << *it; + std::cerr << std::endl; + continue; + } + QString id = QString::fromStdString(*it); + + addItem(str, id); + + if (mDefaultId == *it) + { + def = i; + } + } + + if (def >= 0) + { + setCurrentIndex(def); + //ui.comboBox->setCurrentIndex(def); + } +} + +bool GxsIdChooser::getChosenId(RsGxsId &id) +{ + if (count() < 1) + { + return false; + } + + int idx = currentIndex(); + + QVariant var = itemData(idx); + id = var.toString().toStdString(); + + return true; +} + diff --git a/retroshare-gui/src/gui/gxs/GxsIdChooser.h b/retroshare-gui/src/gui/gxs/GxsIdChooser.h new file mode 100644 index 000000000..39606442a --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsIdChooser.h @@ -0,0 +1,50 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + + +#ifndef _GXS_ID_CHOOSER_H +#define _GXS_ID_CHOOSER_H + +#include +#include + +#define IDCHOOSER_ID_REQUIRED 0x0001 +#define IDCHOOSER_ANON_DEFAULT 0x0002 + +class GxsIdChooser : public QComboBox +{ + Q_OBJECT + +public: + GxsIdChooser(QWidget *parent = NULL); + + void loadIds(uint32_t chooserFlags, RsGxsId defId); + bool getChosenId(RsGxsId &id); + +private: + void loadPrivateIds(); + + uint32_t mFlags; + RsGxsId mDefaultId; +}; + +#endif + diff --git a/retroshare-gui/src/gui/gxs/GxsIdLabel.cpp b/retroshare-gui/src/gui/gxs/GxsIdLabel.cpp new file mode 100644 index 000000000..26189b803 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsIdLabel.cpp @@ -0,0 +1,124 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include "GxsIdLabel.h" + +#include + +#include + +#include + +/** Constructor */ +GxsIdLabel::GxsIdLabel(QWidget *parent) +:QLabel(parent), mTimer(NULL), mCount(0) +{ + mTimer = new QTimer(this); + mTimer->setSingleShot(true); + connect(mTimer, SIGNAL(timeout()), this, SLOT(loadId())); + + return; +} + +void GxsIdLabel::setId(const RsGxsId &id) +{ + mId = id; + if (mId == "") + { + setText("No Signature"); + } + else + { + loadId(); + } +} + +bool GxsIdLabel::getId(RsGxsId &id) +{ + id = mId; + return true; +} + +static bool MakeIdDesc(const RsGxsId &id, QString &str) +{ + RsIdentityDetails details; + + if (!rsIdentity->getIdDetails(id, details)) + { + str = "Loading... " + QString::fromStdString(id.substr(0,5)); + return false; + } + + str = QString::fromUtf8(details.mNickname.c_str()); + + bool addCode = true; + if (details.mPgpLinked) + { + str += " (PGP) ["; + if (details.mPgpKnown) + { + /* look up real name */ + std::string authorName = rsPeers->getPeerName(details.mPgpId); + str += QString::fromUtf8(authorName.c_str()); + str += "]"; + + addCode = false; + } + } + else + { + str += " (Anon) ["; + } + + if (addCode) + { + str += QString::fromStdString(id.substr(0,5)); + str += "...]"; + } + + return true; +} + +#define MAX_ATTEMPTS 3 + +void GxsIdLabel::loadId() +{ + mCount++; + + /* try and get details - if not there ... set callback */ + QString desc; + bool loaded = MakeIdDesc(mId, desc); + + setText(desc); + + if (loaded) + { + return; + } + + if (mCount < MAX_ATTEMPTS) + { + /* timer event to try again */ + mTimer->setInterval(mCount * 1000); + mTimer->start(); + } +} + diff --git a/retroshare-gui/src/gui/gxs/GxsIdLabel.h b/retroshare-gui/src/gui/gxs/GxsIdLabel.h new file mode 100644 index 000000000..e0e7c4992 --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsIdLabel.h @@ -0,0 +1,51 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + + +#ifndef _GXS_ID_LABEL_H +#define _GXS_ID_LABEL_H + +#include +#include +#include + +class GxsIdLabel : public QLabel +{ + Q_OBJECT + +public: + GxsIdLabel(QWidget *parent = NULL); + + void setId(const RsGxsId &id); + bool getId(RsGxsId &id); + +private slots: + void loadId(); + +private: + + QTimer *mTimer; + RsGxsId mId; + int mCount; +}; + +#endif + diff --git a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp new file mode 100644 index 000000000..bee6c95cd --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp @@ -0,0 +1,141 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2008 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include "GxsIdTreeWidgetItem.h" + +#include + +#include + +#include + +/** Constructor */ +GxsIdTreeWidgetItem::GxsIdTreeWidgetItem(QTreeWidget *parent) +:QTreeWidgetItem(parent), QObject(NULL), mTimer(NULL), mCount(0), mColumn(0) +{ + mTimer = new QTimer(this); + mTimer->setSingleShot(true); + connect(mTimer, SIGNAL(timeout()), this, SLOT(loadId())); + + return; +} + +GxsIdTreeWidgetItem::GxsIdTreeWidgetItem(QTreeWidgetItem *parent) +:QTreeWidgetItem(parent), QObject(NULL), mTimer(NULL), mCount(0), mColumn(0) +{ + mTimer = new QTimer(this); + mTimer->setSingleShot(true); + connect(mTimer, SIGNAL(timeout()), this, SLOT(loadId())); + + return; +} + +void GxsIdTreeWidgetItem::setId(const RsGxsId &id, int column) +{ + std::cerr << " GxsIdTreeWidgetItem::setId(" << id << "," << column << ")"; + std::cerr << std::endl; + + mId = id; + mColumn = column; + if (mId == "") + { + setText(mColumn, "No Signature"); + } + else + { + loadId(); + } +} + +bool GxsIdTreeWidgetItem::getId(RsGxsId &id) +{ + id = mId; + return true; +} + +static bool MakeIdDesc(const RsGxsId &id, QString &str) +{ + RsIdentityDetails details; + + if (!rsIdentity->getIdDetails(id, details)) + { + str = "Loading... " + QString::fromStdString(id.substr(0,5)); + return false; + } + + str = QString::fromUtf8(details.mNickname.c_str()); + + bool addCode = true; + if (details.mPgpLinked) + { + str += " (PGP) ["; + if (details.mPgpKnown) + { + /* look up real name */ + std::string authorName = rsPeers->getPeerName(details.mPgpId); + str += QString::fromUtf8(authorName.c_str()); + str += "]"; + + addCode = false; + } + } + else + { + str += " (Anon) ["; + } + + if (addCode) + { + str += QString::fromStdString(id.substr(0,5)); + str += "...]"; + } + + return true; +} + +#define MAX_ATTEMPTS 5 + +void GxsIdTreeWidgetItem::loadId() +{ + std::cerr << " GxsIdTreeWidgetItem::loadId() Id: " << mId << ", mCount: " << mCount; + std::cerr << std::endl; + + mCount++; + + /* try and get details - if not there ... set callback */ + QString desc; + bool loaded = MakeIdDesc(mId, desc); + + setText(mColumn, desc); + + if (loaded) + { + return; + } + + if (mCount < MAX_ATTEMPTS) + { + /* timer event to try again */ + mTimer->setInterval(mCount * 1000); + mTimer->start(); + } +} + diff --git a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.h b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.h new file mode 100644 index 000000000..0db4b346e --- /dev/null +++ b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.h @@ -0,0 +1,53 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2012 Robert Fernie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + + +#ifndef _GXS_ID_TREEWIDGETITEM_H +#define _GXS_ID_TREEWIDGETITEM_H + +#include +#include +#include + +class GxsIdTreeWidgetItem : public QObject, public QTreeWidgetItem +{ + Q_OBJECT + +public: + GxsIdTreeWidgetItem(QTreeWidget *parent = NULL); + GxsIdTreeWidgetItem(QTreeWidgetItem *parent); + + void setId(const RsGxsId &id, int column); + bool getId(RsGxsId &id); + +private slots: + void loadId(); + +private: + + QTimer *mTimer; + RsGxsId mId; + int mCount; + int mColumn; +}; + +#endif + diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp index 82fe2ce4e..eb8df4a9c 100644 --- a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp @@ -104,6 +104,9 @@ void CreateGxsForumMsg::newMsg() mParentMsgLoaded = false; mForumMetaLoaded = false; + /* fill in the available OwnIds for signing */ + ui.idChooser->loadIds(IDCHOOSER_ID_REQUIRED, ""); + /* request Data */ { RsTokReqOptions opts; @@ -259,8 +262,29 @@ void CreateGxsForumMsg::createMsg() #endif if ((msg.mMsg == "") && (msg.mMeta.mMsgName == "")) - return; /* do nothing */ - + return; /* do nothing */ + + if (ui.signBox->isChecked()) + { + RsGxsId authorId; + if (ui.idChooser->getChosenId(authorId)) + { + msg.mMeta.mAuthorId = authorId; + std::cerr << "CreateGxsForumMsg::createMsg() AuthorId: " << authorId; + std::cerr << std::endl; + } + else + { + std::cerr << "CreateGxsForumMsg::createMsg() ERROR GETTING AuthorId!"; + std::cerr << std::endl; + } + } + else + { + std::cerr << "CreateGxsForumMsg::createMsg() No Signature (for now :)"; + std::cerr << std::endl; + } + uint32_t token; rsGxsForums->createMsg(token, msg); close(); diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.ui b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.ui index d71364f87..40d8dcb15 100644 --- a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.ui +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.ui @@ -10,7 +10,7 @@ 0 0 482 - 448 + 497 @@ -180,6 +180,9 @@ border: 1px solid #CCCCCC;} + + + @@ -246,8 +249,8 @@ border: 1px solid #CCCCCC;} <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></p></body></html> +</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"></p></body></html> @@ -319,6 +322,11 @@ p, li { white-space: pre-wrap; } + + GxsIdChooser + QComboBox +
gui/gxs/GxsIdChooser.h
+
HashBox QScrollArea From 163cec0eda0df12ec4fd24bbac2eab88585bc4f5 Mon Sep 17 00:00:00 2001 From: defnax Date: Mon, 19 Nov 2012 23:56:54 +0000 Subject: [PATCH 160/222] Added icons for Posted git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5851 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/Posted/Posted_images.qrc | 8 ++++++++ .../src/gui/Posted/images/posted_128.png | Bin 0 -> 21793 bytes .../src/gui/Posted/images/posted_16.png | Bin 0 -> 3681 bytes .../src/gui/Posted/images/posted_24.png | Bin 0 -> 1723 bytes .../src/gui/Posted/images/posted_256.png | Bin 0 -> 44670 bytes .../src/gui/Posted/images/posted_32.png | Bin 0 -> 2676 bytes .../src/gui/Posted/images/posted_48.png | Bin 0 -> 5032 bytes .../src/gui/Posted/images/posted_64.png | Bin 0 -> 7719 bytes .../src/gui/Posted/images/posted_add_128.png | Bin 0 -> 19191 bytes .../src/gui/Posted/images/posted_add_256.png | Bin 0 -> 37063 bytes .../src/gui/Posted/images/posted_add_32.png | Bin 0 -> 2465 bytes .../src/gui/Posted/images/posted_add_48.png | Bin 0 -> 3658 bytes .../src/gui/Posted/images/posted_add_64.png | Bin 0 -> 6423 bytes 13 files changed, 8 insertions(+) create mode 100644 retroshare-gui/src/gui/Posted/Posted_images.qrc create mode 100644 retroshare-gui/src/gui/Posted/images/posted_128.png create mode 100644 retroshare-gui/src/gui/Posted/images/posted_16.png create mode 100644 retroshare-gui/src/gui/Posted/images/posted_24.png create mode 100644 retroshare-gui/src/gui/Posted/images/posted_256.png create mode 100644 retroshare-gui/src/gui/Posted/images/posted_32.png create mode 100644 retroshare-gui/src/gui/Posted/images/posted_48.png create mode 100644 retroshare-gui/src/gui/Posted/images/posted_64.png create mode 100644 retroshare-gui/src/gui/Posted/images/posted_add_128.png create mode 100644 retroshare-gui/src/gui/Posted/images/posted_add_256.png create mode 100644 retroshare-gui/src/gui/Posted/images/posted_add_32.png create mode 100644 retroshare-gui/src/gui/Posted/images/posted_add_48.png create mode 100644 retroshare-gui/src/gui/Posted/images/posted_add_64.png diff --git a/retroshare-gui/src/gui/Posted/Posted_images.qrc b/retroshare-gui/src/gui/Posted/Posted_images.qrc new file mode 100644 index 000000000..b2686ad8b --- /dev/null +++ b/retroshare-gui/src/gui/Posted/Posted_images.qrc @@ -0,0 +1,8 @@ + + + images/posted_24.png + images/posted_32.png + images/posted_48.png + images/posted_64.png + + diff --git a/retroshare-gui/src/gui/Posted/images/posted_128.png b/retroshare-gui/src/gui/Posted/images/posted_128.png new file mode 100644 index 0000000000000000000000000000000000000000..1781430570bf0b5f57bdfd0cfc0b1d98cb40becd GIT binary patch literal 21793 zcmV)4K+3;~P)S}h5Qhdi7g z@lL&}%B;%DjC12FKB?Ef znN2p!1>An{_DwlXl%${%MS#|VLZZ+VLUd z5mW&U22qVqc#+De8gBxs>Jc$Y(4avTQ4`Q09t91-2en2BB31)F`-6}D;YZHcviDPe z@MC|tN!S16woS7DA%x936j2Fi#^`Wc^G-uR1qcCSnwo2CFh_{}=hqc*MotAasnBCU%aTz-%%?!JPSZDBBA1%qO6hzLeatq2A+g00QF z5r>#);jK6VN@8uaFe(@W5)5J>{sUvch|ryw=6xS~Up{~P{AZT-t~@E%{;g=6rT~>z zn{}wiY_+E*ATx>hvyLtwMNyI@X*@SpEMiPO<^_vEM6hCN|85WggGB(bLJ|yWKvXbB zqKmPLNIV8WP-UXk zVocDClmKBUctMzGO>+PI{ak(hHQ>0M4rEFCq+I*AqJ7(0fS?foT8xO1mmXU`M&IXT zE+e3*@n}#~bSU_sQQ$+tBheyAJ?h8YL<|v|5U>_}tpJFSxfY+e>K~|<%L?IgRB$$X zQm*}5(Z2mGKojeWOs0}O^XS@9az7w(30|u@MAV_sjl_r6ra$1Z>PDtt$NamP4Z^m4>^DICegl%{=zAq3-8ms1lK|bglSv`U=79RpC zQOJ$3RTNbn3cDHg5YM%71I=H96B>n(P`{Q4Iy>D7K5_LwP%PyD|AOLCNbGl907WPs z_je+iAAdF4GTORvo2l6xHRgrhdluG?M&d|4p%#Ag*ZBV-0IXerMrS|#3<{A!Utpc(%mC>TXBsiMz6vVMfV<~X8HH(G~)4FJ?JWvB(-2)Xh7L!$Y_ z_l<1|;GCnV`uzR1pM(tX^a<>XA5n~a2Ln)rZw(PNE|frk0D^g1SyeMf*N%c#1XUo$ z>>mFxzaJ!Q6uQLY4M)3PkO zNikv)5q;6o)dhSg2*y%S4t;;nIPyn1J{ekrp(Pl@1LLp9&3_<}h{Iap(>HxKj{XGb zQDC?Mp$-pY{lK?t+cX8}X>U`G(+K>;V2}VRkV>*wg6ufnU!baEf@bVD!r!0>HOe0f zzBd1`(e!V4Uk9IQl5+R_Jv{ip{m`jT#d8-4{pRc>fhU>=)1X{-*IHEVCjIRLFMGz! z6FcA&Xq(3al#ibW08R}3H|$ViMNW*i1ZNB-JkN*9Evy|yFjOJb`tfk#kMjZJR-kbQ zC%T29RZsyHTsz})w|+kUe$!K)FATAOg|ZSpcx|7*`prA)8ir`M40Z7e9v=+Wg!)`O2bUk@ z?)&bBHnAcs2OM8!9P~M%)i$IPt{%p<3WOS4gczi5M2gL88NYggU=m}%5W|{i^x_)@ zE5by!xtzo1MFHkp7X>ucMuFgrnv0M1k1+5#sS}*a1_0Qwf8$ZWc>Eti7!pJ$CVd(Z zhziy?F1zCjf)A1TgQ$s)FOfqN`H2Q7JWUl75Jzoe+9W&@@M$FJ0Ec3uLTCU=BEnQVQ!b#Y^+7f7h%w-(wALI6iZi~KOh~f$yz_Ch?m`>0-0;uvhRvTeA7dAq$ zCpNEhrxH2MFbh|MtMYyQT4e4_;DMzAL;!;x<^KBq~_6?a@omHQ}$#voUG zk&JREx=`mTY<==gJz-O58#R~_kcmG-v?(dj6=56DHHLMAOjp7)@p=`?by_Qm7`#?W zYK58f|40j*6IQ2Q5~`W z8)ARPeE%2#Z1Mpc*gg$IplFR@xwp(s58V_+WQn6a0G6*Z01AdKK&?fqa^$U*n4Cf( zgcIESP<18|wu-Xd2-{jBp~Sp+;KOhFN+%5D4qj#8GLN=Ua#anfg~`_DR`PGs(S)CV z`CIt(?SIGq<^81Q8!M0ysZp*FO?)H#So@6xkPz@ObLTY33s(n=_`38<2}7|D2_M<$ z`!^_oj#0ldGX3Mq&^D9YaNs8LwLF5qQ1{Y+fN(j6@rVFPd>p5BUSRk?)~q#e1i=9* z!lb}9V7Iff(>ckipfB&|;fI3vX39B^^#@sE-9NM~XNq!Ml{6Ug38zeKa@t|j)M?M; zQ+VY$Kgyro@;>^NVzfT=$-=zxkv>e?)ZtFOO#v(fQy}6AMVL|RpT1lyQ&N(WB6y+^ zZeVjjRY6qUSW948Pht{Be*sR4}^Y_wU zAH<#s#B;BJf~ye*tU#@I(c+sxXjg1NI5Gq=Mg*fU0Za?*uy96dq^pLlYo-3|>Ol8y z?Jr|b6!;<&`Vf}7@Vi6h=I20%HvaeY9 z$Yjg3SA)yH_ut4%8^|CSI>? zWL>UZSNp_SA0%m<;E`q+W6TSCp+{kJEH)~Dm?-! zftKxZ|KfgDmX@P{8>LjDNeO&~f{md}0Bk_)SS~=3nr%vnCV#7eQ>>BQ&M`sYg{%GW zBVKXm?Mf(1xcz8Ol2}?cl17z{u{adz}4vBI8KrX_@Gt>jeat+pY@lcZb%L6@X@!2c1k5oCYa~0 zmn+mcShPXf^{ChSxlnL5rcjNPt2x2kH!R?|H83`C_pw`}*rHCvb9I1c6~}F)43$Ex zC7F9I;sb;dj5JDPiT=K;!ggoakQh;YH~i+J`~7xC3YU!rBxAzF|8NF4&2I)Wb-Xegp!8#f@3 zRpm=H1gXk35K}8bJ<5TGNs4YbK8K-Yh`ZxN;f;kKLw8^@?mKeb(DmSHn7>HM8m=ZI z=L;Z*GSc(E7krKn6*E8f!T6(sLumn9jIhfD_GFH^#MnJ6MfKCm>tV;)+Y+{S9XA}z z8I+#MBqqB8f)NGdAb7mQ{@dEMTzT6nr(Uv!xBcK=-v5#NU(|of)c@5n{QgwSa_#ZL zJntv33D^9^69R@X9c(YZM{?Xh76$zyyMjTF2^Ok)taMBi64G zenLzD318z7uq~r?{%Z+kAF7I(SAC!f5*^T1VXFwcjFG(^$E3ouj+g$&`?ndKu**4iw~(n)iYn9@u?XLdEk!y zYqYK4>e=gf$eH-7NBPe^8)>jF-qhgKZV+I=x+?>nFWe9eC(ov3pr4Qtv^s-fQQAWMa_rgyTl zvkh^RyTs>Hc^DAzQFtPav#7z~xHV`Z32NmC!y?hfA{dPfoh4~w~?GVpy1>;8o^ZOeH(6ZReV>|d>z z$V_BBn||^ELO|LMl2BX5cqx$wQB;JvPQw1xoOj)j@u$D~9Nzrvm$@TH(?dJA+c{?2 z{&nY)%?Z}zu|5dj#@ztGbT-AWzv$=Kb>@9sf9wWQ6HT!(V2nhzq}Kc* z7nT;F3eaCuifa93B5DfFamL^^j0t>{J!%vo)&Vq2#x%gRs`p2F-V-n?v{U8Yg@*{< z$DSBZMm2}`Tth-pRyRX$!0b7HZ&ke^X7Q#C?68JCiDg?VoVs4>8&>;z?yhOa8FP-C z4i~H!flg!->yBb%VS)i;kzgYMHe@9jD&ar^yQUlm4zKW@ozwiMU;ZwB;rB0}I+AYx ztDRlm6t=kH)`RQzmiyQIGftm;Tr%5q7qIcgsBL#=@dE!_{L$xL&LH%$#u5T?BBwUh zGvG4E>04*$*p!*>q)^KX-WX38_St<0#*9*3s zy)|K~ZMg1WNl{j0&O}S6qu)_#?ZhKlC!W-Z%Nn^ONfGZ+3#Uw4uD)T7XT7q^FTeRb z-t*_TzH#}yZC}is`ExUqB^UhM)xP@7_dG6{ZTccnMjj!yH1OQB&f=rL@bCHChkh3= z)-krucUmy@2wCqXEF8%h@H| zl)QqkA1KJI(n>AblywY^R>O=1Vg|Zql|)7}ksCW8C5R=6AO^Nf34i`C1K#zT(|Fas z<9y~T%O6P2>3(`<(jGiM?ONx*^{T;5|MmIbu)H=`0TjeOGP#g2!))=x+;qb&+<5o@ zz?z!*4bdHn5jtHsV>`@tEXZIo;HLuRs5VL%317!7z)%^0+Jpv13K8l7=R;g6C@*>( zUOQNu9T?WLj03@(RY~oE_LjFeJ&MAK*}t(iW%u&xy>H^er`}3`+jWs| zsUcOhma=qk1|I^0o*@kM)dD6MhlYSiiE4BMMxh#a0gMB`7+b4G!AIdoK;?miHcNwr zsC?tvI_~=wP`NIhdD$S{a`6NVy2i+E1G`cyI}&00pwjPO&h@!-ZOd76j{6oXj;;Hl z@JAgp{<;AsRb&v;Ry6;?40TUyOAxQhZXj5^5w=Xi{?&q?x;f)RzjHA^_A{SN56@?J z@7&%xb7o7sy77UPv_J4gyY<+a!_8#^H6r;(lD`5~VM*_OCFv)B6aL{W_&Dg_g8nt= z7ld%c;+I>5fJrQ`wob4Dsl+-x5eO9I(y)IaBK`W&uzji(fs&wA1c3xX?jwohN*0R6 zQF+EV>nFsKSPE3`vZ>SGYt@7~fm4lX~&e;NOw|IvvV0n#xGFme$AVb=s)b+dBAQ)l?)pM479j)h+=2E4SpwG)`m z+86))m5(X5&2s^D_~*4=So4vZkDu}OG!`a)hO2fhaL?rbL`#^-m9rAVv`y)#Z&@)j z-Y7y**T+{#sK`aAd_iTDvZ@H)Q&gVDRg^`Eh@%X3Tv`c1Kr5k@wm3XkCRmV4N3<{0 zpur+(24%?GJAeLw(bm(fS>Ka7nNoPsYA<}hDCyH?6M9~`alw|E0H$-zgB8nv!uh-Nk@Gh1gwLd0w4M+yyx{#;Wc+I%csA5{Bt{=H9IG> z?bWLm2FZ(m@tX4T_dPOIys0iA_!`ka%26A9V1VgEr!oD%FQoW)ry;-J=Jb6#u!}-s z6I#Z;I8Cih6Gz%IbW%r_39e;HTuEYM^)D%Sr+8=RSDy9CvsPJ_E2W=9uT=WMlMCc7 zu%zoqB_zgR6T!A>f13!B8b}gEGQ@3rpgr^I*-ZMoTUMt_l^_Fn|0Z4z90oc=-@Vmlj#5!c_`l!zVt)Ls|2#E+B>njI9h0wP%Rn#Nw{)U28n#VS043(K z#XY(U(E9wNIqXV8`qjE1Kck0dG0Le@h85B)#2GSpKD zM8Qa{AGLd_l|>b1J8Br>7j z(=o|TF$7nMlu6~aOoBBgsAS?w7YJDZO@Pt_tHBy;O1vj727r<;Nvgqs zJQNbjwNMpeD{qWvGNH4#t;zX2vi7;tSu!KZmhYRWH2aCXD&6jm!H6)w9%~UrBoY@| z$N5T(fg1&AV*e0otfxalBJK~U_qgdU(uxHLVg<1#`cG@>_i?pTtkl~KV&XGakfbSI zsH@il94O)EFM-a-?&eQEbeo@j&dz6pzj=8+PhWHPRPl*-UAValkoPKZ(C?QVIJm@h zH#&Ad!?N1~28!UZDyXkwK0Z+%S_)K01HpQ%cziB|B0>6H9$35|)jt2Nc%7C1sX zRK%5W{-mmUD$%S&`a!JSO1k0*2|-Y?l2WAuWHHgyS5hSz`T7z;a~b5N`c>7QHO5SK zj8478*vXf7Wa8P|CEImsYTKtcA;Y#`*(<{9RR?Bg$5903SYJsbL>JeP3-wH*I@LI) z5F@ZRQi%B6>=(dHcWPla!j&3C3C2ZbX!bKy2-)zR@p%W9Sd4QF_`Qn)SHAlyK6&j@ zfBQLGx8{SQzrIwM@7vY!AN#WrQ}|6Qz|!&nC2-(iVfP(cIDNL|wub`sE)&Gp)Vo*F zvI>Q9fX}RYO%$J_LDUm+JLroqD=kCMRQnJ0^~ljx)Usv#p}i5|P46V&fPvMvborj4y(i z;PJtj5DH&;Yw+OlI*}%F>z&7Ct>-lnN4`=?VKo%%BITe@QIxW@9?IVS>FzCSU(fG& z{o5graer-H2_;AlvJS>Rjp>U%gVk*~=ZyCv)~~jaFztiiA;OskCKAKkdZoWwlwtQ& zYM5(T<_Ahq`3RKsWD2lR;M#r)-2-*v3m=foVkbHe6a4UXGwO{UjeaXbt02}u zW=56EW6c1^2C(x~_>E+ZxBv2GlrydO&rP@AvAEc`uRnXH{F^_z@S9VBD!{&dYq&(X z{IW&KlZA8dx@+y)Yp&lvF_E?qQ&;T@*xK~jP!ZH(6mktXN_=S$Ezn??Xd50pxXex0 z?*mC=mav|G7t{g;8ayPE#RV5WV>Y>GPyecyy+HL$g;WqTOV+-GiHRR2$({>Z-y48k zgmNu09)qQYu+50s9Rj;smR2zOw4%^=^eb9h+Ctk}juf6MD9Mnz)sX--hB0ya*9poI zpx!yA9OK`QpvO$4n2A_{+W7vVV8_jTZ5_nfG5>Fd%J67yegH3dCcNy9L;U(5f0gu% zZEv1P?MIgv2KGnJn5;hXAD{okqW}%cdQp&8%F&f|G~)$#+_N~buu!r#;n6CZC^d@n z8o7J%I0O?s8i>y#;45rUf~MSX-C@e2$>WU^DFu7O3{CJ*V{M2HPjGiBc{u?|n_Hk1ufW|6-8k#sp1TtK#x?b1* zg!U*27vjfvX7I&ZVeW!m{QM6+l@I*wJs(cb+H&<&H@oj|ZeElR4J!Sn!oambiA{vH z!J4I%=N?}6q*HC2bx0DxdhmjAF-4Q&P>Ix=tpKqYuTpqLDm9b{ zbJ~atS1cVpUJ))3?z>(k`wH3Qt#qGyE|Zfl#0MySz>wptYEVs0UAbc|d!1)TrP!l= z-p~)cqMHPEw^G)yEcGf9qo9Hx59u~a^n~YHY$saN6F=H0htXl~VLbEK@cm-Ogxll? zbUZZVvE<)Owqm=$$8LjPd&ASYbl>sh^Ea+tJ$pvyH0iqD%xgdY1QbAFeXZiE>yOh) z9HD>}U$$LoU);|Jq*)fHW{DudBJ~ZKK;q&IY7wuf1SFU^!OJL>vD|(CL1J~riTrHS zDiEXU%w@0>II8sCh~A-;X`8k7(;4jgA{tiMy7iOdwJ+ea#G0-R?8$^v@;+PpB{Oc) z{Op;tdhTp0EUqWa2Tz_?W0QV#^i+@b4eqijJlr7j(VGo?K-^FtCm_}#F4jQ~1z!tn zDA_UAZ$okj>Y9N^(0~&tADh6|65h8@_}yQ+m?M99`RpwV)!)p`WUpEDB9C7IL@7eW z(O!>M=D7B&iy|#Mb9k{leJv!+7>5^)wYzE&JZQb@iK$oSupy>DC4d^*nPF+MV0p2C zG>HMNKiR5d0n)6ZEWd`7;Ew@+2uV(D6y{#}LUh|9QiA&EF*_!(EveY6eWudD z>94%V{bGC4%-*)IU|$awgQvsK#u-K=@6#QtfPr)@xBoWQctUDY*?i376=e|pUEJ_nUem>ueY1Z(ZYuo;gj*8GQV@ zBftI8uN-;*<5GYkz@00e%kNVvH;WBQGVP5N`rQvMmy#tJrHwWIP}liOvlv65snaoP zK|;g@iJ{jEEX?S|q=$~iZ&;03)bB{{_ z5{1rDa9=NJXDR<&DBYvEt+s^kS?UG4S&Em~adFmnJ?bTzuDJewh&Or+ARdw##~rsE zLyd*hK;<89LK}A=28>(<-HQA}z}I7!DQLbQ8C-zLbIPEC#}Kdtj1~kfwO8blR(Bd& zdzI`wka7jd9Qo}El@jk47}ppJ#A~1lMNN!Kyn^^Jv}$FRvUF!jakub_*G+QjQ!Q8R z%Q>{<@xGCK!w=MX93!AI1beXpXv`fLL$6=Zz3%{@_|>QJrE8Dy8=t`L1k#{_RK8xXLct>%G_E;PA+`$ER5lZ(w0!S6Hmj1!xyyBcLnJQbSvs5TUV7T&i2@9rwqbhf zHj4H%ixv)b4{2JNa~@jiWx-^WVq!M17J6I&v00TPuC`!m;1>|4ItlkYcpM6W$xf7f zUXK`Q{I15L$-;wkE7lUzHYV8(elt&_>l>9geQFrojZ+@`JW7GY`4GpM4_ zH~RFb1(ClehIV6!Um9Ov48aOrN(O0*SHAa-PaRw?-&Ua^bH;>HKz)ei%pwqc71W@3 zP{kvP1gL_d#)@K5FHjh-W!swSEw4KxeE5okeE9SG&0{NoLg54VKCsN+{nG(Hf7M~K z9c`?IU1vPk43-vNfB)hdEti6+)3c_Y|F5)H!~bsttiUc9wr(cnuz`_|W~#FD$Bj?$V5NOc+U2|;snFzVT-0oA5>%jQvQl)gH6ml=~K{J5*$$(greb2t}*W_2`CUY&?0uAbH_=>x*}*3?eT0v)_n| zOMF8L;7rBDy3hh9rgrL7MyXiDxEL z_U8rU6->H_{B2#Hs~YX0W%ODUtgK=Dovh~ddUB_Y_3W4geIUQ)4wCbphFH(>KYgR3 z{TL9JN(hzieaV@ed+AfSc<#Gcecpn8^aCH^&<78|DFJ*f~?Jz7J z?_Ft~jcF%AE3Z&_{^w7fLtc6YWuPd7mZc{z1HK|Ydrzp8qJj`S!3Pb4z3&YOoW!Pam~NHVq0Q_ z?On@}_2~bl7W&5fXi2=DF)m+fyRTzhKnT#rBQ~W!sIE1!ph-*!npxqJr_S<&FWUBK zVtZWeQ5C>inA{3;vxd(0gyQQNy?eUMABWj93)6p)H!m($OwKv_J~~dN7P<(c^*SAa z7&iy#WXjPVXx~6LgEAi*?OH2DbNhFqWk?iExDG$HNVqe=v&K$+jH$yCXLR0AbP*44 z0f(X zN4aZ0CVTn;(j!~Mg~3xp+o7o?6t!Q|5TSOB{1K_wK?npfWD^PZK6n_qZEzlf9SOP_ z{f3w>wY3Y-0GO+BLFiuroNU6wNdeu%TBt&tVy=o*8mn&}r58j!8gGbY0Vjr*h_sCn zS9rFUUXwl37B$LB9^&Mfao^t@$4Jc)k0{^)_jw z`0+Xx>eYg`W@HVtE|L@mIC~@cdWrr%!@7WBCgdpakHFt>(h`~RR&z=aGnT0{ac1(# zS~gKr(F(N-5NL_eb_Taz==L(ej;rZ05%I#jDAy`sgZwkGwad&*w=Oa#A=V$ zgysGNz1tFJ`a>gvfOvAVx%X&(Om&hr6x%b7@5-15Yzp05Dp^_2-_$DuI@6+O6vbdA zAeErjL^nV~n;OJtv?f#b?Oy@sVy!^1F*j~ay-lpTM6i!PB{I9 zX!h$RvjWd?^+i7p1dJ| zU<}iY;hE;RjDtaj;9aedRTXLCSXnK;R#U}Iz6VuHnLoCbdpzwC6(D$JWwGS0eSIE0 zP!X2FN{Xq3`LlLmmTvsH-r@|l4HW@na?c(O^u(V_s!5PT%GHYmbsS^lVboU z&=R!mL{fptywcgs30o#C_bo;Rh(EHC{v8&1Ho_ho_zFWy;44qNDk;SIDzENH5`#8C zLIDZn)sut)j1_35JXknxoiABh9x%uUEcGj9_oQZhW%fcci_hZd4*`r(9G+m6)EUI) z*h(3Mloo*%9l(wxn*Q9x^dc$9pw@8{pM%7aZ<;KfUc>6nocwNuUm=cqPvm`<9^VzK z#%x+$uo>?ze)5k7rKY5Z^N2GHEo(@8V6O5yG26Bz7M4!{fa3&EQ|hh6-`hX{4XuEn zg|amjme>5DpnA)Olc^(x;+w4EKCwNj3vfw}om}RyUE*L_qB05Iu(G&leAaSUg+7Fp z01WV}fpTR417)yY!Jr4E&|jyg74#Kc32hTY1E(=H>dLrCl9)POR=a>Cg>t0?xt`2; z1_R)=z;(clPw0Y8P}E1JGGdg`okTZYyn|5HOlBPc2$_SnGh$1x+Y68E=thjwE5-;Q z-AE$E(La_R9>G3_Fwh89uTQt*IJA=Qv&hkh$vPM+{|MUp1lyyBfhHqOw&T+6l&K;q zP|f3W`%21ygo@Lq9eZ{=w#~LUD>ZE0)@9p-VeeE<<|eQ$XcIV^4_NM{tgaM1w9x11 zYR*IR0~QYtIB=}P!J{h-)_hb9Q(J-(K>JvCCwbrF-$$hDp5PtI03RZ6;Oih=XeMEv z(5hJ3vE>i%mb#x3fwmDcD9x7*sc$%q=Nncahqp_LxyXwlZMi-eb52t5}5d%)Ri1ug!7W0hpemD*7N9 zT9(i&pfq?hsMltx;w|#lLL_r+0Bu3Gu1H3;E`n4_Sw*G@9|?qjp;D#n2deb)*7QX0 zFFy8GooT&-Ucb+v=yUVn7JB`4@`rNDennY%@Sd^=m=e5?NvT2$?q?q%_+e*necCoc zp%kH@Wm;nt`iX6*9!_co&>9kjsnY9oClMxF!h0p<*ph)~m9*HA^hIk6kGIZ9okZhoDJ09__LlOsYyT?;=YNff znPXCl$C5!|GK2Wct0|JiNLA)l)oQ2hqEO>Pkylo2kS;!7H6lmzWprVmadt_tIZoQf zCe9dZur@QI)=b*Lo~O?I{TqJhtnB%hwv(Ceh1O#g4d#OKnLKd(fLUE$l7a7qTtX65 zg?{j%^fpM$lCFg{&g1D+Qh|q{fnu#7@8#jzqu1tJ@7&rO6oW^IABPH%BD9RqNer$E zy1l40J9WlkO$`9+2?U{;E>=Gzu|vh%um*q`p?{3v^NKAU$7-+IFDiGR6zd6Sc+y;e zK&M0dxzD7tayFf7j?-INhkyDq?8!gG-b?-)oi(Fn@Du^2G8rt^^R=y4yoJo_dSwN- zCKP?Vq;O2&{uQy4-SFps_k+)S<0Vi3T+pzfLGutQ=M_SzDjy3p#JTF_VxXe(E35sW zUcHD36Jau}Ev&Qd`-EV<29Nhe2*I1uRH3RWO7As13Wf3!n;vl5o!f(#vmT>Z*f;2{_{%%f2hm4Xk`Z;rzhU zT9M-X(*43ywkwY4sx5HevP4xUuGrYFl!0e@_Z{;7kH1!4^Q_MAd~W_PC;B}*VZ`E6 ziwTwlgW4410|Z;I@n`F5TT9n<`Rc(d_{`n^NMc>w@8dm$L-2T2LQs4d(Y_j#5W?^| zgurw*ecvv>D;-=k5Z-bkkF0Ec*S)6hqf~^<7|9H@%SyKk%C0HP(!i6KTBi#(rhmnN zI61+^$WZppe>Fl{m9(b}E33uTW{dzjQ6|k=hnv+NSph_F?UeJMe+KQ@8QjDz{KKan zzyvBKPh;oxc+ z0U$MQ9M=HrBE<_J2Cca*>I|T1;{Tvzc}Yc!d{EtH%?2)UgG|DcW&uXO$vNlF@<)Gi z34in_&EkV^0xAw3xQ_RK;Q!?#ANeeV`!{~E#$0Ed4zKwB=kTJ}y_}g{Jq82AtyzcT zcg{~&q-~hYCi(h-YdEq#&+J4SklOFYQ6Fj{ zX#Lu2h%<&Y#_7WpZJ=1I)^1-ux}1l0P#&HthfxYRtpT9(sv@U4I!Yf0<)>IHt@%S*IVo(F;j3dwfLsm6HYC8Z&+KMB}-3XqTSiB zPl%{#r)zV;DQ9u+>Ca=Pa}FK1i*6SV-+T{~Q`=wp(8@mBmV}}T80jG-fW>35Ayzg? zGcQ0a28;IvUpe?MxC9bwqu^BtAr_(pC7O6?GLnWMN(crK#YHBmCTu0GcQqsg%$~PPfVR^hSmTO&cer z68`o6zZW}S^8fpaKI}IMqDtIZusI1_n|9Bua^cPHyYr(m0dH|sg`>xgaO%_@tgWx@ z`Gxj3rCd9hXztXpye~MJ&oVouVuIdik zSGH*c?m2c`wsxK$>Cw%P&wS2Cy+)q9Ly?l63G(s2ZZ3i3#fBJT>KIWI9+|fIM4%AJ@=){Qmtot45VL~@i_J?c%Zf{E1+K~w-PM+fE z(PIF3GtMuk)T**!?(bH~e_} z5>GR{zQ_)RnTYmdE)sT5>i$GVMZa+xXooqmvGs z&Nn@`#Q>^-6UUEn{MaVr@rZlxzlTqM_A~skq`15du?P5*zz2?VHA**vnw@uSCRnwICEdx=ZG@o)J0Z+<-^xg5@(y_+w5 z@$;lE^1yq~@$eVVh3Uoilk@JHRG|V-1s5+%CRmBpTp)y+t@$OM+xZ^j(HJ3=)hpS# z%TReK>fZ-ONFqi3_Z`Vb6sU}6lyJc(F*e`y8%jC5+fY8KI% zHZ~xDd<6kC%=-}vBdicV`vmT89<(ysop(n@I=OJQ`CS#cdOP&Em2+DR-~>kNCpdG@ z`}xH${W3rQ3!mfeyWTOhNheQ8eVK6fC1Tg`gO?|A_0sF(5l24KlKTY)4X|%xLtkAA z2u@Jp{IzcpX&8k`W(}uEzLZFyclvr0ke$BL1VmDhl)F<5c{WyQYxZ4?2Zs+c_yNTM z?2|x2MMMPa5*tC7-MOLd)p=skmIP3r{w?zbhVgC1@e?KE0VMA#AP)vLM`G2*W^JQt zukY?YAu>2Xe=tly2ypHl%2)ovF1y$MDfhqY>!jG`ekB1xncJOQ?0!5??>_UOT-rKy zI{MY4bdbj%H%b3H$m zt|SrlB%BZH-JBQQ`CkVd*cgD$(jj>*@g825_ zh-qaVF6E-H^V7q<`VcVdep#x!*d~! z{wsO?bM9EOQbs@8orO*3Tz8H~FP`iVe{3s4d<;AKB7p~7e+TUt2wxpzp-|^Tx`Px@M%U{1p zAopr&5$Gm5Ybkkm$3~brFkOLw=g(VA{-FM4VC(?`kY8>hmSe$_<=)UfSNT<@h&#_Sh*EKzz4N=Z#YF~Ewj!ANt3Ed?@vtwbO;98J80SFQ=B!( z%O9TKeu{az%D9>=vwj}XGKV*N|6pR63(1P4lNlmOb{51S1`yL{f~U*lGjro>X&4P zi>Eq^kGLd~ce(dN`j9UVjp`?0i7HKMxG;N)T1VOTv$Xjxx-Si!M0@<+0Osk@Q({6A zfnb>PeZ8aJ>;4ln}fBLDyt&`Cr=RDXu*NX@7I>QC^o&;10+13&u@|5R`P zRRlubHDS?wEeO|7tVugvIPD4qe86p}4jn$L`HTS%0KIbT++-2jc5ifi#C#T?)i=xk z_s8L;2-aIXx6J^Gawli_5FaMc@9R?xL&e#cY$7^maq)t9ko%1Ij^r&y%0v|(QovI3 z0iXn}czymNGuvidkML4a&cwGN?CYCR#BwfP`Y53IAR>@@=h9>@LB7{ct=S$K^`9Q` z8(q_Q=t)VB6IVp^8{d)3_&KMTApzsfrn&miHn zZZ=;}X*!R-XqxVo@D@`)mw(vdIsv!eXXKDx>-gWl`a2+bUXKDDk>J9qdr$MnKmIY| zL+e#&7a#DH#>rcd4wdmh^gb8RZvu82F3p}Lh!Rv+oIl51_Z5Az{m-^uO7bVGU(LfF zr9>I%%ZR+Zac!qt|93Ty|Er(p;Sao*>+BL4lRLl)fUD2i3Y|enMz=neYn8a~E{v3? z$P{uMlz3JcfTcYE1WzDMw}`XTV_nQz+jir!>p`S&p9_(dr~J^vfJ13C8|ymvUVUhg zhHOBc6K5vaMbImPPZ&!hkGi+Cz5q!j49r;h-tLPCK`M6I*O}Q>CUu=9zj*vQIDek) zzcIx8ga1$xioG+KNok0rXX`4wdh+zy_>tdyjQ4!{VP>{q#E3ODTCMP0I1abN1MWcvE~a7*;BQxe@pa~n<)4UNyHvm+yEE?;jhh=y5^X-OxS z%!QQ7->_sVGm%+l{6V95?_}N@W86Li2;6yconQXi{fPR~9=g+ofG3zu)@6I%opiNF z%#6sC5OR^G&wb=@$#RxYoGZ=C#iv>+`IhXT7l}8Q;^gIbh{nbrq^gw>*h|A7P2$nq1)@q2oMOL&-a~(ah=3#M1Ns_Gy0E?0RXLL zJoxTkE01~|;52>$r{nEb5l!-A4H9vmuXFqdx{hbeOgrjZP3Nq1J$6=j`j=Z)b)H?D{ z+!yrY_nCUq+B{SmM)J&M-Dpy+_Z+RIGhusf-n3DYCEC={Sc`d-hR$P`h;-grC!Lvh z)<}#lU1~g~)>CRcrMda$cAC)G#vRY@iiJ)Wl}{EEcX2lA4Q4iD*3L*x@=;q$l<03T z|1}PL%irn0=I*mw(E^9mYkZWe{9TNyjBCi9Hz~nL)~Kh8+JZfVbF{T7iIz%6^p(IY z`Niu}=UR6uH=1fyrnrQh`STJ)_voLMJbx+eHRqD{o;xJTNQFf)=_j)0QUx|Qc5F&SR2 zEk>+sh^avqdth^#*-NB2BX*J4MY^ub*D=zij%fM2_f00NCjlKD4HLar=YH{r?;AT5 z2H0cHpWttx!;V`x#wK1le~zE#v-)H8Mc@5!w1(Dq5ivsON5*8ySMj{B(e{|z6-HG( zxIxRDe*t`0QTKg~pKNwhQ9dHMJGl=?#{{|<`Q0l|5Mv_7Or&H+?3`HOVr`poAt_aO zJ0>y$KZ2#xD2aL5~|tZmI~SnZZAnHDgxkaq)=BA0<%%FU+9u(+U#4HoBg^Vf#` zL%?$0?~4C7d|xH6kXs|2=Wued`WDWiFu)pX{0hH1WW5tk@a)yz)z{%G_$ z3)>+CN3;x*AP3z2{NUa0HB=KptHJZnVPAHTa)_6cs!I)0TD?{ng0jG_2kBI*9MLtR z8mV$7$w|qHA$#=EjII(=5>g7JdW0vzeN30yQtj&y5>$ql9+qX{GHaEgo5OPcVL%AQ zyfITkf;fjNk!%X1K5QYw(t5}Btt`3%Egcn4GN(z;-5Oy0P#9prg1^bHtUTjvvdK}~ z;GfLDs(ZwHqNn#YzDvh-f@W2ZJF3~9t2oK$Ol^xg`AGNghK0gaXxdcia<61*}6QVHjP?`-zcUi0VP0GI;7N znW3PQdtypaUG532C1JQX%doMR__u4u4d}Q8JP)+`HuDGv&!I5Dgfai%+CR#@_d)?^ z8XIfM&SED-Z_Xjz$+=y{i6}Lpq=2>5MwGx_+(tA~)7ySo#{b!oM!Wz%OX4RLv6qqu z0L?eL3>wS7M431zD+9>NZtg-n^*rf34_eM0!x`i`&l)I|$;Xl@n&<&683{BDeXs*s zp;zfKGrFgUOI~;D{b>1v4DfcCAOXg+R9xcHO8WJOJcq&n^W8aL{pgp5aP0WW+#m4x zS3bc{edP;bcdPqYWUj4Whoau4WB>&SB8WG%w#6vaAX4@$`4ZwiIDeY80EOU^ha)Fh z>P+`Mtt3-8kA7AI4@z0pOz@1c51QA^t4d}Naa1ki`-d)`RK~hEL9Api6FxW{j<0qY z`|6kFsi}og`fO8C3pbYhRi?Pn$sr&ZPaWA`+72m_K;44cS(vo0hMt?65`RT$D z{ZzXfN&BkP_f`zh-~`UIV9~yG>vLlcg#o6O^BbSa*AA?EqBh~Na7xnd-rXkgy`9a8 z%rh~xsQnTFh;+2FLtQC?7Q5e9`vfc1ydE^%gGUBND91goj;Ab^cC|cctnAzI;+%RR zcqojf{iqlv=NBX=bHpKNDokXk8!CoM%JcclAYu-F^@FeaM4rRGv0*;^FQ2zd_|@N! zTn1hs(A1+_3;{T_JV49w_1_-;whcQ@a^d>!-C-;z?@cVuwp>TFL$oR$f3H#@+6*Kz z3e}3;?=yft*ncxyf;%bBpDSpu)*W1i3A0GC`NiJr3h`C)s2KI!kI-ug6Di|~1TCZO zvIg*#`pzFfMhx{G5z341dCNMunbnW7R2n)mQZ$pk7!@;ycY(10gj4)9*d{N;pC4zq+6$#-xo zHeYjzIG91muoCsG_SL=E`z67pWa_0v1KBT;3?KIro|ZyV{^}Wbc|B0*W<)~w(fG!pIDgAHzcgUwYhAtW{eTSZF)uTxRk8_?K1f)Rdd&qVmEsfh z&$Dt}7)8lA!+pIhZ-=Nia`9~sX z6b*~D$>fJ8*vdJaFp!pi%M$>ct4}g=Jia zKeToWdGS)|@}W54X(huKG?#g^{nw?_N9hncAkm>{0qG^Xm81xbI!UJs-c1`orUp z_PP%_c0{Bj6vC^dJQ7tvNK|>dPH~jAWZ|-hZI;u@l%dnn$uYMIp{QL~DTy6laq@a~ z&WdES^gARwdjnxvO7yZmA;mQG3{qZ0?+=i*$;~YAjhNx>s{Vt&?<>z`%sGr^hXn}H5 zHjI|V%P7GdLXrHUHG2E)E(7tibn6hdY5y~krF0|voWNBi*YG?m8le9ftIro2-AKZ3 zM8ws{z4^G&;~TwK3kcsKG23}&=eF!W91;U;oL2tQ-}yKjDOC-~CNTQ8aJ`)u{nb6>IltT=TnL8(h^ zz+m%Xcf(*HFvx400<#u`>RsSfUZhXJ`R|NlJ@nI@KK_9F6gM1#7$-rMKCY# zv#RzBVc%f8S0#5~idD6q(Mcj<8T!#<`+fLZ1<9c+kf(nhppvp2Ht}YJUA=xYrdU1M z{=bZHfp~DD!L6M`VSuy1-{(4FH4_`tG!`1S_ezir4cS=>Dnkw+lo4tD_`Gb|ohSiM zF)wG7ys;!_>L45ZQp73hTn1Gy#ilb5b{VqegidMJS|PsgBXZv1mvn2R8XpV zNkFwiya=PSTzuY#h56$x>(;BzUFm+`NAMdlNKfkg@xFsI-TL0vZ99N)NDOcf@K;Yeh06UN4yO#p+*{VO}UcIlPd?L$&&`KilhLXQ3;~4xpOudc_`8W?HKNGd8quC*g56}efuF5i3d=fKca5v}N| zh#^=~l4L@FWCD_%z7#FryQs7VYS6es%G<{m$q`R9E_j=WV#Jh430h0EDIwnFjbAAd ziNw^>G)9XPQ%6%UdW+O$ri?9(Ic*o2cQY1k!c*QC>|LVsh&7R9PV72TN~CC{Cg%Bt z#0(?vcVqY3;ou7RmG7SXBF-!5;n;sTBnB{GzSA*_9ZyVO)4O!?z}lK0pNyQfYQi{- z7}pgetq~^FQc*FcmI+ElkTq&X1Zrv~j2U4vV&r3-iXbD*#{?VUssw6u9B|1~#dMU> z!=O14B>Azd>QCzjPidCo0;x$3<}C{Yr^PKYvj(${nMJy^%cAROt!3WKnZ=fQoH1+j z%;LRf#5Z|BTnL)$jYn>q8@f@wRYZ5x_q#$eU7Id~2S7XB(M{&j~coPYOg^2Buh=u@w3qm^c4l#~!InV8^ilI^IK zNY8Ru=jO|s5VI#}8Gz$r;4Lz!&@RuQbSr^i!iki@LAWH(aFgUt0&y3QXM#x1xmDgzgJ+X}8$;cjD0+6H!hlywKfM{^61F3=J`37itmAXhqwB+CG zKQAnOf>r;aX9&Rmg<86< zGqDOMCluTfiz?zBW_iDNiowNAEIA%J^B4p-PszkccxSjHQOrHMOHwg0JgSxQlvbSI+ff~FWZ?(r7%H4*ur^&mc@ya zhhzWYuo&RAz~r9`QYo*ztBFTH>E9W({(QJzVT=?_h)DtuSPt`DH0AzLEn^lmNlNO7 zNbr=j1PFUB3wLuwQiX6#+{U;}lHwxLRZ&Ec4tF*6GC{;Eggrx}y17YEF-tC5iKHY* z5ZB#SEC6$eji`xx6~wK}RUUPa;O9(N$|NXQ+yfoDLg8^w7FhTz77tf%?a8-_e@9J zMmX9!4TO7hAA&s}r4+0B)(xjc{9I;W5y7`SOM1?F_bJV+*qy$^r*{HnxRxRLDeS`K z=U#V}o9(!}wIlw+Hh- z9!ZirV4_8m7?H%olZQDUe;+r)D)9gA$lS3V$G@40Ba)TGD2y^f*m9y=p!5(58|xc% zDbY6bf(I_@!{a~wvutl)XWq9P}MbOPM4kAG~vG-2{Jl{=Yf@2T6{g U*r%)u=>Px#07*qoM6N<$f_{#5egFUf literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/Posted/images/posted_16.png b/retroshare-gui/src/gui/Posted/images/posted_16.png new file mode 100644 index 0000000000000000000000000000000000000000..6c07665a42225e31f2ff159a4c55aaa185338109 GIT binary patch literal 3681 zcmV-n4xaIeP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=00004XF*Lt006O$eEU(80000WV@Og>004R=004l4008;_004mL004C` z008P>0026e000+nl3&F}000AgNkl{9nbEz}uo3XoVrDiSrp@qy78ocryE;?T$ES4KwGzz_p02Q)SL*98m!P(rb4NKiBhQ|iPkNi6}% zkPumpU`dgpcIX-C9v(&&i>IECJvwqxzW2bU2F}L^;bH{<9Ol(u8_TF5p%?L2<}N^S zEBxKz*!u+es6Tsz`R310IFO;L05rQ zd~@_xvroU0od~vW36Tu~jLgmB-(Qg1TlUw0iz#j_TpH@%9DMAsf9!-kHaT2Yc7C<1 z^ibXb6_t%0X|woqK2hD|7j3^2OpO!b?%LKD--?F^J?2?*>XS(fTq_i^i;_1znL=4s z%e}q(gfk602ufDFGMXExu6M9jtqa)h0|)`*V^I2RQD2k)3~_Iso_<(tY4%v07v&^? z)x~SNRsgk$XZcjNk9&|rMCHpP8)_ifK??LOFLyngb9t2F4XN2!9;<;>*|j&5ypDF&P!evso| zN+1@Gxok(^;Ncc&sgxz}j=c}H45%L!?k9KV>NX$Hhq#v;>WoAl>Gu};%-P3#);kDy zOd@<}8m+JH=}O2eCS!y!0*nP6Qb3LS(7=uYE zn8NY{9*=~2!3#k#Fki_tUtB#KNbrN8@f{#0$I?_BP^kk&%&!Y>_F7ne?bD5&!Da`= zCgcnQ^I{2Zj|h$z;dbXRn~cE7Sg@TIU_(b4KduX&d_zRb(~2?Pb78>Z`7D)K&&El^5NFSN9r_MFpm>pACl`F{PwL}4r;KL0)c zd|r8;DBqvV|O(nKZ36ZD_!;tH;;$j$F~|>{@hX(okKCkI$udyUW;pxA@NhpeVRmMzSLq znxNWF#2ET-dnfJCr6QpLXh089Glb&@Z-H=Aw$+y`nO^kp8JjJ{UZVJVv4ANw-4% zW7zQ@G(~(UgI!;N*49Xi<#F!uw^p}3&~~!#!216HFaEg`7md>32hpEwf9i~vFQhJ< z368zh`ODdv<9cOB(<@8-FZlKDh)T*ToW?n6+e+o*#db${Ie|AiNwBpZtvrafvYJ`v zC*;{ZX9DvL&AWW~VT`!mfRch~?mw_-)xMUXmB)5jF*snMXjL1MPTtE9>-j{9vatGI z@zCVn;&L57??c8#7#ga~1YzI}LUK)mwyHfIoE)B3!y)=Q(I^ASVE$8g%4zc{kERYYr= zNDe1p5a`K)I``VQzFkZG>Bqc*UH_^)`0F=7D&)bPR%6G7(&?nYuC%Fc);Rt37q`_l zwC&Li69b=sK1iTFjA7I^BgaqNC-xjDO~!JXNVsy@hNeI<5>l@`@$^Ic&+c7y>!11V*P@}IdtmhYzqrwzz_)D7c@ZK(1uA}IV&o5Z+=1A%Wk0#9T4sg|6!Hf5 zJ^3^1nMbyiG*Qnrzr>^O{TNK}qZ0KaBGzs%Q~5?ue#zqv_R)`%)U0gco|R#FcK#Ae z`Mv%fzv!>~z5xtyMRg#h!I=Alo$sBAv9!9L7tTCK`4rUK<=hMuRBGDER+?ya(V@Ut zvYKE(qT2yx{_f=5lb!Xu z1~qXOBjAO__<&mwcBC+42de2VZ8Nua(K5FM!!o(r*Z02__2+vzp4yKt3>;aY*`4L~ zIVX+l*?vZ51_*dnOk^f$EBlh%@zt$Yv-$P+ynnUaIu|R%GgU|-jJoDi8;1{N4o4F~ z8RTVtrHX3Tec zC8nx0#xorx>@;cyG^wBoC;&PNpWojGSXvpHYoaTYx{%yHH|XMPVH_zLcXN~_O589@ zSXvR>G)|dAvE-vn2^RP^pa31XgtuITw6jh#QA59KQVyJeA^tyN|FLWa;*8kBKjf zT0HW~(loB1ZtQXp}|}1f-Gf z8e(Q%p5Onv-Vf*6`+PZPueH~`&b{unPpqN7CK;R=4gdhz11+_O006p~f&duN&0y_Y z;(Rj@duu)N0{{}5|1J>lF^drZ;08}sRSgYYz5KoWT)n(G9;m8vc>8)eKYiu|0D&{v z#x5qtoAe6j^Cv1gF{lqZUJvPD91m6EQMAc?f}F&Z+A*B@f9Q-lsMOUVEd6;g1aIG> z66lPCN#o$t&{fWYx8a{+;(lH&z5e9>yXE}f5Uy@YalPU=`|Ai44I@p}k~F%9A}v+9 zMYR~-*WJ6cdIu2-=kW$8VPBtc`eC_20479UUWf|~Z394ozer#JS}zkV#u|;M*iy-` z2B9KAX#Zpx9TXPxf*z_bV;_Q2d(3#e%T(8H7@UjP^>AZ8R3 zDF8rT19tt~+<`zu20*KEWG;UwR7JTic;l&zFY--1_titKU?M(HbMrg5ZVx|T5Tcc` z2it!{-06Io!6XrSmtygF5CHO$>29n&#s&_PR}BwKy{#v=71?Sh!gDz|tl-v0%DoW) zu;d>yh7%V3%8ZgDLV4f{c=sT#HY9n^&*PoHP$24nyv-T&WAFcbqn@AC^ykmo>gu$1 zw~CehPxD}$OQ$W`9Q*7dME?5xbg^xjCsg8bs3run*g1HjTgW={jyS?$?q8zjbpr|h zn(Y@?_XCF}3qjfyBWjRo)5o@Q&l3EH4OO5hyO)18Uq9L9dfVN*+5B zoayjWTKJ=v&jH}*yI04=Z5RQ{HGF9#0Kcz<)y(4sP|gqD`2c{88qXb*pI?>wU;v<& z7b;kz%yQDfD2ygz?I4`%Ai1`aicsO{?o^>vfj>d9`q~LpgsI$)8meIvv=f~`u-!!) zxkkPBCco2Z+DNY8O>t=t%jvk?5=snF?uXIXbI!zo9O5jv-@+I&A~BpDS`g}Z9*!R| zv_@Py$@jFxAI6z*m};>dDfoi#M_X$&C(HE%5@FX-Et=vVLcbU(Opw;8HkC*-M`#p~ zj6U%f|CmUhmpSVDjaeZn+?8S`QBk!|486e!mF#{dcBi*XrB+6m_`TymEms9; zc`tK~Sp~uO*i*-m+5iZ3s5+Wh3KF2gVSh_m%R<*ee_E@AgO%ql)eNyTF+qe;CqLKw z5}j{+%~TiNj1Cgw(H2_5+`p+4X+$Ys$EbEo^H9gCO7J%&fgjX{!lpm1D(Rkf|Os(t_-f{Ppdcl zo2mY$+|o}QH6I_?)Z9qhAUFviC5xg9?~8G{&6LRqWprT*V60BpEn@l=&(vokCM~|5 zzMesm;bm$eST7hvm;4i+qMgE*!XhYYQd(A2HeW_!dTcsil2~eE99*SgDrvk@N<5KT zZd#UYxNXd0>{2RM5?$s};$@=rIph&GmgrHJZkK`TXQRAY+m)7H4iZPEuYtmx?quar z&qMEZ^VJUh33?&;Jsr#TJzk-#H2=P;q_(8_*N4X+oRy#}={}e&e|_Th+r??eA#wAx z`vS`XEJb&9o5Y>0-OEzbQZ350%8kl3w_ByEc8jx%TGhWlx(X#%?$hSC=GSyd945?O zH~wS%w-{bbucsh;T6L$)y^tmUyIMfIXYpQoPMZxXN7t)({$=a>C2O!K)&%QuS$wKV zYC-gsl!s`RbeK`T=bn$3Jez3W?4gnB<1U11p?!*d+EPSv)0q6HNsTue6bVmztyg$f zJbFEPKk*Uqaq{WtZRzcOe5lt{Bv2%$E2rBxG&oc+^gH8Trh@pC#Cqm>=2YfFgPmod zrEq;oeWTNZFRPYCkM`ddKPt2^wS4?lqcXda_xJb8@5NNbP5STk%X5Cabk!Wz z|EMo*V5(W0CYr6P_oxrHcX42FY3Qly+I!#nKDasf4ORh47X633oXwIg#P6Fgt*n{s z{Kw&}J*D8DlhjR77mE?fk!i`5dYS=&?x)$tnZGn$7+jkC!jEI(V|Bs??xZQ+$zb8I z<=93ps3N)XPw=nsV?Z&A7vw?^8>$>?1-`<(3gT>kt0X(?boS-Xu5v#UXS#?R+^-hVz9*S_|INKhhG^d-ZN7x#iwVo*v0U;kBj+{?eotT{7LjnX)uk_qQZ90C2b<}~}w@FOlYmvd*b5pyI z4Jg&zSr0t+c$m>B)%mxbx<}d666| z^3<}le`(~NWPfJ9ku8{g+dVx~pA}6Tx;^_nyk52GQ@ea)i&OEB;UPIClg}n6CYL5s zd*grW?58lEV|y>h8w8OwL-hoMRP#w9T4=O!X$6C!MYyTzx%Ps){Y!#H3z%Jg(ID z@Y(Gn7$?9&xykFNnkFXM#uZE+CjJ)M)+Fy^Z^LEp2Z)eKk(s{9>RsmcR(rX+c}~1= zev3?Y=0(EmiY4eT_7`j}Y@%)|ACEq2WEy|GvU0F$HW*YK`@J>)>RNM_og(Y5{G*rJ z$0k3X&TNMLdhc>Hl8~K}9UOA!V$N>1p#Jr`H#faMhjc>+ zQ%---#h>NnGG62-R4Z1RVe{;{_sP#|}0ABF| z04f{+F7P+wCICDa1Ar|%0FX@w00ysjwmljE@G0YgnzBjY%ntTx4bN1{Em+99^|{5u zMbfM4PthJ2ucQ$`P;S9nidO@2n`}v z(};-fJL0;|dOaM_cFgwBbjRyz7Wcx>vjtE0-?WWjdf}`AyURCM;C{%Z=Km|m-XQno zWe6YyIcLAl)z7RfXqr9JO*VD)o zb{rM%5WmK*RPQBqMZQ?{*W~mZn0q|^+BG1esaHo^GD_O9zixfVkLbCkm}8^g*$^X+ zT%QA}i$wz7d&^B^K>3wRM;k$-Km&UYZYi#8o~>%eBnpt!Sa4mWLn^qwOnSIe+ynm#FW=fcr@A6_?YCBcrQ4% z1k6l7!Y^2D6jF43dUT+Ol)rnlTs!0bZ?^sVs2w7KXwSbQ|If5RCe%CyA$6vm<2NH_ zAJ>ifMMmq0g?wfD^Ezg#K^d^u>P2ln_ie6l4#C^LXCEbR=a~D!mTI5t=CxfS523b@ zFWAZdR@Obc!hZ|NVY?))!P4V4(p_k8{M7o*7*N(%LiCmcP2pUC8s&6dWDGJfv?C-d z4{=&xjjs8%g)d|eBGv){3$scjXKd&pHr(s3fiC3jr0}qOaWj=;4(5`If1%v4PZ9EZ z>Fy^c8ibLYLe5#rK08@-O1i}VDsi7SVaNjvJHQ0ku>*4fz!ks&RFM5Hd;Y@9LU*ol zJYKtYT>22Y)ypg!#^ z%daoV{!ahT4!x$}wTtSx>M|jC&)SkxNtxssWdw=p1;7FeZ9NFV*c#Is?vRLuX~QXH zL6t=`&(UHP>E4qw!Z4_!}&Z;QatGVSMt#d&~zy_=NCL=euoS zz>Q#o;RD67X)|~_|Gq@}I^-kJ5q6ta<}32_6uIWPvyT7Y{x)9c#?(kz2qnmg;^|_L zB574q*T?G-FN5E6rwg!ZVBm@+6rJQL z4~107MS!uIb<&GRXHN2m<229zd(-|6P6NKW?T?J%;=AGtYeyWhlLN>SH>e4#vd3B# z5bAe?lf^J-!2PmOzmM=Ws|+&X$g4`E6?R4P*@m>g65;fX=hn}>LNH!t5MLz$&aX@w zKl+)Hq?=iH+;>2(9G4TvR~d9l5R&!Nz3Be7)MxG5F$;?j6_rt4X-?Yh@aI9t8D3`d z&=>!=2>}>9B1Fy_OAuto$L#8WjeL$3lXbN`6e7Cgs>mljIs;cSfA+-Y9)|_C{cupa z40-*3=ATuT;Jc#nNgB%|q+h+>O5Whta;C=Eax@)ptePpd%LWlXd+8$ifUj!X>o@3s z5%YhcUw+lI)YBRGLIraihlt#vaR9W3SaFN(S$>942njUrtFOJE6)F>f$n9MXXvcJk zI%Fkm-^41=f0Jr|umRS@l<;Q>(#~#IdKWDvHzI)@$IutB5Z9+>)s0-aa1Mp^ANV@X z>``V|2`?dLb_Ds_Y~t?h2>zT6t=AHK_B~ewg1D0yL|~Y6JYsc0z@1A%RFHAXz#QPX zv0ob{OI~B#Xe<6Aua@}$bDZcHTw_zj-^`A?**7d%!4aa3+LqZy@Z@lP^KwWM180n3 zmPYD-GI)&PmY#2Z=>6V$x{4b5RtbBi z)M{&D2H1(QAvoyT+Ig+sp^n6CTu!gHHEaXO)jbp4LTv4^g!179VR_BmS6)RsQwXrE z&k{u6T1H%Mc(8dgHzZ-BUo?AsPN1o#ggLQsUzNq_Cu_fj7Tt*AEk%QXz*Yyhv7NS~ z%Sr5fS!7xT)}#6?#Wr{M2!Grb4E3(8$8TohX=3{m*P6}>lLzo!thpZqk8JhI13ryO z*IjN^yia!#mW#s47SBb$6K9l-tX8@@6+FsS;w402sORU7ZJy$Aqa-_bcYTz=fqqfA zC!ije&I6^aN``S1i)k?G;>w-F!D2u6(diiKa!Tbw14S`Z*k`!o=hqlpZ2R)n*~uLc zx^KQas#;D4{L!za?a|12FqHCH`|+EFd|io}qbon|mb=X+n`bvUQ-W-Ih{~?MNU34I z+GLa1b#R}~PZh@$ZMcpTIw&k|Gs&5G&YxsY5HEAVC%<;w{-G;a@w$4-VQlgC>d*%4 zj15ua^br)-VDaT9FBScvE&Yts%`o0BR;ar68xLcmw+kO#_bkC%!@bdG1KAzFT}c*{ zF0hX>e2y;Km*Wj7cQSn^2j2XJoHGH+F4p-IRp;C&>EpA75NtcI5vS=*>~>DFm*`)C zoD0z(e@1+_2id#YLWxuf{)(JkQge$oRKVe+F<>Fq(gPeZ*iD*PHFY0)3kGMTg0QMa6UtChEuXZ$>RXGHI$iUur zH*>i2G4p32IEWq05zNk6^frW&b#{0RXJ292}008=`f)8I7NcK{21&z zFS?J#G=JI%0&l3pVmThAu|nlD__<(zM4(~&{b^^viv>~-KV*;Jy|-UYdNgN$x)8f3 z_iLYBCeo|r;LSxjau`oRjJPI}49*5!Iv}6EhK>@9LPxpt42G%vV<@lqpYmbe(_@Tz z2aDTz;&M607x+dg0JSaeu))3u)_J^TUj5#SMFD`-FOl?qbQv!=SXOhmp~$KbfPF4# zO=Ge7W_@= zF?<#m$A$|`iuNEhnCg^xLp)!7Z`#J~&>eh%2&Y4`#*fwZ~K#{4Q@&7=oi{1JSIpH81n*Hq>5lL3ZyE-Zl$b5H(Ds%#pn^ zk=&K`hX}MKRw4h8pY)I9j!P#Tnjd5Pt1*uO5AZ7vVd_!-0w*wi`Y6B30Hu0C<8!w) zgYspm_9WH9RWQ@}anM6kWM(XmsA*E^#XI3eX<2gbUvj7)XAvA6HS&vUzA&p_l@ifr zF8aE2@&k#kW`rfTsH~Oem1y?1g8;Fh>bQOv!*iwYA@nZ4M|N5+`2iSmRcIk@iRH;! zfbE?rGhBW9N&o#&b>B2zBKq{FV`8%1w2#X7bDkXWw|+$l+A+GSM@)+m(I~rx_UGOB z#N_lP*EJGgEU7m%BRXPqy8%{meKh{SURxLJm|}V%x%$T4@5`RCoFMfe6SZM5rr3Aj5@mC z>=@a=&#A`}`7*9)K_ALLJ?HNI8$ByiKdvFq``#oT@cWi$2IgnWflpTFEh3c528f0ve+6MhLKOOD3 zTY3HF6q&sSBIP5<`YZGOcq>;9#b^t@(kzyK)n<@?mvHpH5xWCW00`7fII~(l<@V?ad}TGZ4eZO!b-6TC;jrg-xF3i(s5Zb4q%#iS zpapYvcIJxf`%-ydZq^9Pv{y}r^Zx#F@1OC@Mnzrds38ajH~P3j1h%Xhe=8KM;F~VK zH6xF1K0_*~l&oK$!j|Ot+rM6I?ZXhoH7LCiq;bU@D%BvTc#8Dwc~ILzv~P@90MF ztVzsHe0I;5{I=Mn0FXUv7n{g^06H_IDq&|Z1EPL$=E&i#C08iwCKn>{TRJT0CKkz6 ze!j-NQR@-3i9SA3VFZGGd z2j?jx-G5LgX?%^z4z`}xKS*(rvXkNBy8cqurlyO(Cjc4khthDS1m4h$(b*-Me(&^( zI?{22_fSBZKeK1c!23guihC~XK&WaD1--kQ>2i`EK23a@`+)FcH-doj;D)jcl_S3b z{pPHzySEgMSVXrI8otk8C{n3TLWGdFj?NW2`k0jLGeVtSkaO~NhSAL_)m^R_`sWX0 z7%UU4(nu=^Z7dCvs5$qDDzPHx{DtOa=V08%QH% z9i1b89G4fYXmMy8APNYV+x{H&sJl&6x@woF1X$JKTf3+y!WfrMbkW9y2X;N1X~-Pg zcRlcv!AtHanSPe)A#oSIfwQ|INDSjkh5kwAHy(A-MsgAB+|edK0!;-8OE_lG#p~LE zQy=yu7MUSG0QGPSD%L%9nR?e61=FkG;KU_Rb?9eR%P=XkHdo`XK-CejMy79O`ft3e?F-1@~exe5q|QwU_@S2 z%X}`WVO5@H5)_2te-#Cn?WGc>9ZVNtFH_YG#rXUn1rtsXyK+V@0ewXOa;zpiL9hA zM*}mnP(OG4))nYm%nlooLkF!n_wl-u{o5M3Ui7HN@*ej4r<5~fR7c^;VmRvXQKEbj z4Tc0lt_sTgUHqMJno8z^$QS|of&g7Yq&!_qv{teOhr{A7)T+@*ytA~DwECF~VIE*) zxCby#fUTm$v}kSbOZIfADqOF=rcj~Nsszx*>IddA-YAqfZLL93Tv`BsLfeZpEbWaQ zXOU78@2M>;Oq5na0(v?A2yWrke_A_(I(TyAD~dZ`7_u~qQ(zZ#1Z%9A#S(A2y!@g$ z!shta5BUC@^adyCnK_jT0hbN7nI-K9{HVl{=vr{vWe_WH2{Wl=hQ25Y#G9N*7RVrg zq6~+8kAr#ws&wKJ8{OLbbgLG&ZEeVMh<44)fecnu-04 zoydYRQHe2Rby-HER-QFKt?wsi0_j46^cewAC%ooei?no!@)t4)7T&t zqon9xD-RIA%y`Fc??r1j$pm;uF;}1uzxJ&Ygp@=k5Cgpw9EP8(3W8VDY}@o*+{W%w z{l*+q+d>fx5qC;eF&Q;aP)?MulH(~aOMCc>%oK|d1|Xh{iD!feCeO# z((9~KK!)9gW5%c4oZi(@p~ZKKWu_%DtFOuJ{L&Xo)1o)N=_VqO#1Zc~E|p+2M#`j! zFha{4!G^3xp@ib$S+(T1H@u))LB$Mw_sTQc3A~QbcnjbD^X>93saE5D9iq`?^IVsc zH>RM!1cZ(AY$cO>?Z#;a_UWVnQkULHB0DPEs7SO*a?9R;$!&e9YGnHWI*htm&EiQX zT<*mJmt-oV9T#i5g?y4l5DMT1TadIk-RrH?p&EW>)zY$5P~aNXT8)a08@K(7(dk>9 zAu+f-PD zm^fT=ngD)vE0W_E?fYle|E`m`)<;qbv`IOjgxFdhLJbaF?JJx8TNGk|7U7`#4ebt# zn7L-=7tNhxI>=-LAKhdBdHaN?hWcsBMFL(@q-rjc99vWv6}#k z<=Yr8-e$jNhXbXHs%m1f&y}WHH7y%G1UhxL1@t{-J}=zWBS^XieT)Z1*ghJJ@F5C1 zOcCJAmI^rwkFJ@C7fXKvc(=z~)6)is+wWvEs&kVAWa3Wl4dZ*WMm*>%R* z3->0}6YgbNVAo6zq=0niFnu))x>7_qfXTo{*XM;?I448f$XB|5GaM-yZiu%8O`5Y* z_8zw}bEUK-n)HXi&e;+1#J_a&wcAU|@X}n5?T8p%UovN`i0znzs`l%}EI8bukQl1| z*CN7@Fng)nZDZ6k$5Fb}GK7#ZRJF+3SeUj?>V1f<^B6X2HpTQ7*#@p<3*kK{$&mBs z??zYf9XwtTM$bgcM0?)i2}6bq1b)jU`Mfap@=DDDVxPeTjqyPPLQ%EM;`9y$W_+0G z{;d(K9ubJ$I|1@jQpF%E2JHlPYpojb`j|J|kPk}P!yyHfC*|(MQ9EG6u%~g`Ed*twTR`$S_4t zVC%z5*`RDFUUv;4Qs$u%fHp%pP3^Nc?;lykrQZ!oZJHgrJbM1^%C6eY^&ye9pA(8<{qDu)wseuD4!RHL8;@} zjq-%Rx|Pd&Yp{J8+Lgijp7?EnhvhLZ-;P1A`fCD!$x9`-Bn0+K67r2~=|{W(`L|h2 z_Z9hn`HP0XzIOVJ83N#` zn)TK>uT;fJd*ETN5cKj+2Y@*?zWevNGLr`Cw{+UIwiwlf!&gEGhJwI}_> zLM3VX;)4o10s)9e%PlyF9^Anji6+{i8&tQ zpe28}q9w|9`T~F&+OE(#8DY?k!IC2=nhpI^?C-u<41rUHA zQ*|@UHmFLVz^%TVG}3s-aiFMxgPYzct!zRGu&|T)c{MVx3gGB~Ozn@6GF~nOZO2WXR?|bSI?=uD3etRqx z&%b7535Os9g9w)X<@NeLjWieo?rJYwrU}-%_&5J-X2eQJ9nlk24Z2BuA zUBO@47+dRK&s=khAI#lN%tL2%&qk@NoTg=j(ByhSL4$j1L@h~%6gI*HwV zGPMbBlc2bRhqe(%azy5BAK|(2f1kE$XiyaAYe%IYxvT1mIBba-r)AK;$#?R-z{QQ6 zo4?8LnKn$zNYyk$20NSv1C|8{zPQ(k-wx)jW-w46iTF) zEVqd2i-b!VjjlpWNlfEQ6T;__E*Q(zOZ&I`<}b)}{3dvuT!?Pw#267U;h~c|S`VeCj0_DpOo@|DjR+iSyz){zH!JG#lYZj@25NVmmE#u2V)wA5~B$C7q@je zLYTfsR`Zuhr38SB6>67!skAj?h{`1Lsc$(9`0;!<(xU|$B(z_~DXgjHQ{<25m{fA4 zgA#KXO+}t>ewT~k?qtvYXqOIm@T1H1G#eokZ92!R-tOB>R{Y2_ITBdy^P#!2i8-xOni$|8g=Akc{A<0Bl%ox+nC{ zZLTy6A&qYcuPJ}~Wi{ku7Vi;XZ8KxVvkYCJ`Z?tkc2p7S1j6FKs6ixDpS)<(ErXn& zoUW)%Lwx#De(t*Zmz<%J1%nHt* zTvA~>o?|;whh&I?NA?)|oWvv&%7g3eI(&=p1{d&wS51TkWe6ahGAL7ga|Un2?p0pC z#I#FU&%XX4I=63vY$uG0JXHJ8g-)I|2i+Il`PZ+tcg|Ds#`++>kG3tY z5a@bv--Wr+i?A2mofLN-1qIA?js#tjw_q(OehbpdI2&KcLFV*y3lOUiHTY21P0L{y z07eG_o)x4#tDT&%m_C>D`^kD~Q0V#IEss!(b6*LDCHeF_&ml<~uk}Y=E4>38H{6k@ zf#HJq`dBCXzwJma7JP80GmtAiHR(ZHEgI1y$?X6|*p7cA4rSUtDGci5bS{1c5G zh^ie-;FbEuNL5GdZOFVS2C3&)OlhXCt;rgp_QVF zg%S>wg~!9)bd@KYcH3R*N31WlY=`iV^8z=}$P|2SO7O@E82M zA<-`?Ckctwc>O+iRpp)F=4YA8N zCVQa;~n#=xFR?j+(r~esA`wjxL-CxA719I`SwIK@Z}yIkr_}C_--VQ z^MqT4-}G|vMOix++E-D(m_bs}&zzw& zyH+?Fx-6Eg+2EAi^K_v9fNgb$pQMK}F1p%#Euf?AFb$T#XwwqT7~gHd74GC*LA_zu z{f$}k8@0FyV*ze@nLj!M2Nr0)9}`^Dg&C8Z33N(Y+AgM{+%(Nfe_etl6oA~wU2|l+ zpP5}5rC>&;Qi?&fZJaINJPzA)9|j$KYFJ)5ui_XIuCNmySZxn0Ol0QMxv7_^k~ONK zTKIoeV0ltmiN8Fb7ZdclkB4bd9i239l zgY*9PtDp5^W#3{_z+aqhPO(d5+B<%!l`gF=O7VuH4m|)SSQu%TshucHEz98Qvkqy<~(WyX-FbW_oL>h7l_n?2V&?6fum)6-E3DTsgS(Ow3mS+CCqlT3j zoIKT?k^;JPDuZjZb=QF1*Y-n#nCOKG8e?Y_)$ zN;h8#@b*V9*P>YRKQLv*aq`T^MTksXGu=Ln(er+vu3SWKPrZoe|*-B3hac7n$=D>zo?V z^?5Zr%-Fuy7`Jajo}~lCX=lB0g^E*tq*<6s3CnT`2(SpKkQc5;Rp-#ivpql5Q3{bG z7g0+uf}3IkQ-9dH6wnha7cswd`OczrbMR(x03Rxqnlae@gsax=j4CqHl%$-=dA96x z0fd$uC=~=YNuM{~^))euM+|lX6tLV+rjNvpN*f7<=w~<2Qo=({VR@14VgLK`wy~vQ zU$xmX>~G{fIj=e`7yDS+HaDiZba~!B%C;`fN-O&?z$$`*ExvYK67zFYK&m({ z^$%xk`)>v9qI@votC_(x?}#W@Tv16bvzYM_Ex2dDo%BgV#bO8hcLI?Yl0<5!BbGwQ z9P4fGTlwoU10fLawF{-&o#|?JCZ7vODb`vqQ-a!j*;euD4@U2U1-S@`OFB&T5leUD z-f;*G|!E3WS4`NaMAGAUd}q4 z@^f{@AfjL*1qG3T>;#SPuJJjOS2d}Xl76h>vj$PZ!DTwlrphI3K(Ei zn`#V=k^~9WC%nTX`e>@jl!9@Z7QEc-URJ%}vEg0(tsdS`*&FC&7w>%Q*XOxU<}1Wu+u5?K zCN9JX6CLP3DikxnNaRbzr1)r7zc%O_skbxidi!3dXz&(!g_r(ec~fF&?YbVFJysaAzsQt%~HpRFD9i?FDy>@rdN@-+CTVEVb z5B!$e6+Za_O_g`K*|ZP*Tg6wV^<{;TSvc|qO{;$cx&K;NFR0Wle}!)n>emU+AA?2- z3(_fzp2~*`(ijSDArM+5RRS==H_BGOhTQI7YIov-bU@z@K9~b9M1vNpIF-Un)1q*H!R3CEw0V!^fXs1lW$+YpNN}?%wkCfR$a6%A=0J1u$V1kOJ^Qkuvy8gJY9|a| zbn*L99lc4B1*U2aSFeEYUhdJ#|3hwbWR93LYd5& zC;|&u)>EW0qx8m5uRR3_?o7H8#M#S6n9gQZ@AYuz_2WlAg&P|_v4eflc2=!B<`g}w z!)`5{7PhU)PuxiFlBw6aZR9lc)IHI?^zG@yo}scUwr-Mp3as1`3H-k$Dhw*zSIEr0 z|MH$qDg48~j%78ObLE(KgmTE}U`|W&Pmf+!iGD_7=Jti`lhs zrQ(ZCiovZ*{ZevAa4YS}bM@TYWeEHwi|TSePd z0#Z)$$T^}W!SI9@ebR!5v^*b3h&AKZ^&LKtQ)!5pvw~K4lonr8el~n!fm$Tr7z?ky zO|=#p5-edbYx^pM+%`8`122(mymQ)uBZuk4juRMn7zov@;>Z^_R3aMKpV`lXl^W9> z-bHHR>*hXc(bnzrC$KgW0rcGH7ieSWgVvT+^L@zb#nVo5{h3WD7{5igc+jeOuvqLF zYI#%Jx~d}w;&3u7GcTT^G)CR|xsHnb0e#?!ma~uqBsSxsm6h@3Ut$w+P}yH{-VQhJ zEUhfv!qMoWGOcTcjmK}t^N0aaiB*M3}`~Cl@-9E;@)JF+08mBozB>Ot$ z!lQ!P4KIc|Isx@j%PzymOeLL!w?9P~Nx>`p^=VNGY9Ik$upvD34gGxVngM=gE?12C z?v?yv1FU+EV37k<4v;fSr$|#TR>m$ST6MgJ#SLmsc|D5t&SO~VPF*}n6-mZDR(+m5 zgs%hrSrEY&XQTi#zwg5r<@hY z?W~RMX}7N_wo3n0x9#lToEFysN?H6HrEQ!vVhML79@z6%%5YhG(2Dg?K9+wlUOOjy z`$HYwz{^pcovU*zWd_?s1c^7W07pPcT_cr+2EX;IJtn!<;=&M?H?lyUfc-NLQd1ar zV-7ntqI9^oUtu1&JiQz(7d{{QfoCCW>+mtm0q+3g_v&HMPMt-TO6G5ZZ3JuMXDDeX zX%0?x&?H#i>t4|o!Uo|!#y1l6Wyqh-N13{SWTBl$IHjs>Hd(s>8(J<0%TdAfwKm4$ zf|AO!vT$m%BSwjWiJ$tBUP$dQTj#ywvt&mbV zA$W|g71K!q?khCEYTN(#GIc3EsJvSSeP>EZE1}Ka|6xxtb&o;(G7R_(7Oo=>s8+lA z$}Si6aL`DnmX{6|zrMY0`xMt+?1th84sB>rI=}Lo^gHp4@2_KzgR2&EonBH?nKBFq+PJncs-20{nk zddElkzIW_uwC&2}e%oNMaY)B_<8P7AUWc`_uMw&6M_% z##y(XXz`~1XkeIarT889yd6SPyt~eZ7KN0QOW> za}67>FBur^Oj(C%m0ak&272UZ(9Id;K75ShXyJEY4$ z@v{Kjj9G85n8hFSf6e?08a>ohMoYYTcUL0$o5M1NAgp5RIU6xNY6%u~bF8V2ZS6{? zoz2u!la_m#G3wLeAuNhZtf`C{)!8puTeED2nJCiYQFk-`ET!yV%p=uto6Yf~Uh*`p zac1M}qp+u`c5cP#pZ8vUNkg#E>h@$-CX6Uc2=fKEA0;| zb(Iid+=b}C8UFe~(@QoK*ga7J<+@ADU1!8I^M$E>va)TM@^5U9n66m2Sa(c}y#-}* zq|)c^0`&~T z(PX9Qw`7PnuYlv7ko~u)A3h^(&xvJTJOfeSb{;p@i1+*$c;H^kfG=h`A#}vBgB;ZE znwdVjHo&_!V-1uFrQIQ@U6+PZC+fEj>8C@hjw?R@Kv#w*@0|~V1rhAzTL3QAfG$X~ zc;JW8-oTjsLqRX|@i@y8QR)cn^1eIOa{TmSU_cgGj$;q~$mHUwNf12gyjb(!)#&iV zfd}=u61CB50kFCVm%pKQz$u*tm)+Q#)gp3`57Bk{^RT7I=zAw8WZot0_O8S%G$iF@ z*+I<&2Kak7>c|}! z+a`PC_g5OR!|6l5YB91LzCRUgI--e#eP@EjQITqg#|44XbCfzUfRKk>9nF$&*|h%J zBxk=l7_bQiALuiN5&%!V;OG)f*j;{n?lH4v7f}@eJe!#zvd9JSdt56W0SjSD7o}7o z=YGZFS<50MY}fQOxef*VDWe3X!nh_;`zz#y|EuHssOT&jMlXtQb(D|zE*As}ib0Qo zd@{=Nu-4jD_}<%8TN6yFh4R2HPWWdV9h)5Z%O+u@ZMd!FkASOGZnd5`_y<;Lt(H6; zCQu2y0%f9(bu%a^D^pQaF$@r%^UE_d@)c4NK<`DS7$-6LY>x(f+LQZIg7qv4EYvHS za)|rR!9S<$scXIviM`2NKWN*9<7ShO>FH#~xlgQ!)_c+2ZcNJ3Z`KORDfR=N)V0D1 z?P^@OjoyRBcISX^jwkbZf}d|&>2I&0%TGX@w=vPXFs0+z+1h%kUiP4Mt|GomMpQeq zIG%yjno=6oa|icF^v^Ex>}gXID}d^fsc_d}*ztFGuXUI}oz1)4R`M+-z1$3*)(tf^ zI{%*Xgo+PH4Sz3^&OfrVw|4U7pe~Gk=G9kkb!FfnMiInA{{*IC?M|u8(aBNAL63l_ z5IxD}hz<2wQ}_K5NBKVKxv}RrJ;R4_^pbDQijDAX4_;rqk71bqD{<%+-$7DUP9Zc8 z5~dyv7}nVzqE!-#3-9SHM^`Ekyk&CHpf7c6+Sv3oYcvOs(k&Cn8AbYi_~N_3!gD(6c)gXm9D zj1$cC4_GL*iniCao4hU#K)q2t@<_Q7KlJJ%dH>IqZO0#dlu~8SX{B9PxRW=h406g~CW3;w*gclZC=ys#mZK??XoH$XvzrOx0oUs$$vd8)C ztwiwC zqPQQbZNSlb`>{j%HxtFy)I}|%wE-yw?hsS}By<3Q^ic>7hFyELNTE0v!&SUCKM@i* z0G*X5aydRMpW`J`xAC=Dm3Mnxv1tr|$#$ztI)pPD} z>aRhs+7S?diN|FA#8HL);mi0Z|K=rJo(L8?{Ip^7mx%CXE7BFwOcley?|#O<77l(FnLW z+@v(yq$!3pNK>*ltr_}+0H`;5e|t)7QXNfFG2N-1#%tL+ow4iLwzh7)30WI$AzQ8$J&JaJL0& zN1h0Ts!W!WqU6}F}-{c1GpA+29dkgZ{X>$JxC&E|1>#sNx3LRuBA- z3;;U?0P#k$fMbQuxI)s^3z5owtHW~VKo-2(j)RGy8SMEbK~9}*rPVD?z=%B1O`*ys!L#U13cY62fwlBz9nc3HH{P%{#ba8u|;|mwseEj&mbOS8@ZvA2+W@08XhNxwTdhUXy zn6TUeR%2i_0uC6^ssSx9sGEX5Jq3PI1k2)^d17_~9w{>}j4f=~Zq&%+)7{H>dzshw zssTWq4*-Un307WhK=yYc05ux%4n|+`FgZX-ui2Q-e4Ox?&jF`bSMUozb{B42jxm~8 zlV$ps)yhvqtnhtq?S)@|%)IIdfC%*2&w_xF8BVg+B-6#Ee*4}3#1OSDtS(L zRUrJHZC7z^6@bHFGVDe003aDthW@m-6MW`2QPJ=>gX&W~qPTVhpuK#ZZ3e~}@CR$a zuf6ps{^SEA{Ih?53L8^kl(UB#L;-+hc@qc*O4XFs7XgOe`cwDQIQy|doodWqG z9_2Txp+m^?SOV79C)dRI0f4&g>Bij8NCTjk+8^Zk=%MSSkis~@Y*C}!AGw|F7@cYuj&%gU1UO2stuf8}y zX7!gD`m8bZ_X!w_g8RSr1vC8TKW?uY1kAEE8UoR1MC~{>A3Sk-;7po#{{5)I^Apjm zBgj1}l~Zy6^-VeID7%D8xk(jx@x}FP^KG``v836H+v7<_oxUBf4;6Uy8mx7D-#GZT zvQT6I-;9o*z7}7VHbfsgj0LaI7HbVVJFU!h@H!7|m6{E|5*283r{Qb8U=Xm} z2EKV_jOg4Z?mE=L@pBVg-b$g0zZxt3kcs{`s{M$3Wp6@s@4cX{_LS|^wkBED<%r*Q z;_MJg3`eskD1{ex{5x_9fFSS5caIDCeMH4b?ff}P`F=;V$R8KVHFru;uI<4T8ynYV z^+&g}Z8x`Guqh|wR4iIh;J)h?{*&u8BvLW}8B)Yhw8~y< z`%Dy>vb;Aho|*>$Vuz{0b3b#rXzfk1`P%wM?gHKM1fxqMtoCCZ?za%DB1t8hCi2&; z#qH#TE2;lyzCc$V0jT10zwzLmaP8(nH`CLUGOg1r1hh4CxOvXqwL z6a~>j?sc`q4}4z_PQS7peEF|(i=%Tg9&Sq9N-zwrB6a8J>?&G$CxRT%Wu zC;S1ZPQ`FFD8MXGAy@mQYCyPS=Ag|0psNdWBYU^`c9YTP0ARVQlOc$bD@#XyvQ&i} z@R4_K;>*vhV{IeB*Ph;d@1^bJy+m{( z_@?xV9KgemJObcBY%jn}?YMpC?F%0}d1i>J1JIh6t?wd~&AI-Q)WZ6FpXLg@ULQ|U z%@uN|G8v~hcVXmy0J#RMRun%4p($*dBJSA|op}AWpzL2PBPw3PTQow3h!kyDv?xWa z85E?;Q{dfeC#0RO38GDc*#xpJKn8$VfMQ3NP0uRKK?cXWr}kF_0P39lJZM|Cs_4dq zLw$p3A{cKf(g`7n6zI6}Bx%+AU3m^gpopp+fM}2a$KC-zVi&chiABF<(CZp(W$tXI zu)G+)ooY4GqAPH)v^U?YR$$WvG0_edN1ODv^a%h{AlU-!)U8OSuV}3TW(6>d3bO#{#MTCB z?!vayIy$cnXnmCe95Ouf$H_Z*n+V!lK>Kn8T{pNiZsCqkrWi#QgOOk`b(|2jwaGn= zPNzB{hzwPYai`UPw@JZy(G|e(>=t61;YUAo7>i`_xu-U9aXUj~ayl^r{fS!DL9YhW z2!EPp@2ryq$?0`u7dCOGZSc4MM5rP@@o*R9jp#%S~+*i4X2GpyVyz>}|g{%^IGedfT46!rtMfLJFtNY;}k zx6n&p1T+Rr8;B1BW)(08fM^-uMSyyK5`e19!f$1P^iT`K17o~=QE*{kacL+R44t(4Ooy@V(2C5axwRMbF@d=y zJ5T2wo?L@HxrX2P<+tM3?``4pUq6S1SJrU;>=+XfCx}`MhtlfTQ{%88MR;ewVhh+4#wGC)6|b#*@+>BV0`*arl3VEpO^EBa$s2gE7F0ge>rn*fPxRq z>{TnJ8Vy`g{%Q?+EfctLr2b37`K4k)qg=Bhy=KVYHp# zfB285F&JAs`^xaCPK*B^5z&@hH4ot7M+kV3V;PtPQS0CVe(#yJNmpkml{%a5XbJcf zKwpmWDM871ol%WT5O@w!4XHxTNUY%Od7t~|t3Cjzj|K##bJ%+d@C=B@;3z?4GN*_6 zo7V;XM-2weeLftUIaR_KfKdWzgf^_cV3zPN7Jd{zts|^Z45bc0Z2-oVU^J^G?`5RU z0HQ(?N#}&1+OPtb2@)0IK7nA1fy=o$8cm=wL_a-^MSH>F6443}A2QHmDHab3)m|Wb(fu6ySedJcGok_5;$oQ%I zRhYX_}qrm z+Ye4r%0qmu6&tky2&tgA<pivkj1L{PADJ_AUnDu9mkF?98N+{Z%xGCBcOCfI}sTY17U zfL8u~mF_#Lh4n>98s_~(uMe*zE3xIh5O@8GkSTIr*Oo*UrV2LnQr%o0DAkDA= zg24E%lC@a^M^TRgwDPX?+YKpbIT>AYjKZiDLmAo-bi``k2rUBWGh@LhR=RCmKVF(T$G+)2?D^*(oh=j0LH<5m~AD!gb}l(Pn%nr;3LPKt*&)&EGHcOmq;Qhh!K^ zf_ON_(RUrilV`_x`upqIw_e)*{5M~j{x|Ex?0m1qF%c=8fMW?+)j(Bk4DIJ(1TzjU zm_}J#iv@(B83{5drJ_0&(TP}$FaEO!(v@HT!+7yO`NOWdPCx;G;lKECy`mI=2=ws7 zhv_+-GA52%*~IoTi@PpvrDYh!l>&Vw^mkx~Th5fKvF&WCP*w`60YfS14FWD+9%Gt` zU;VXe=qjbb7yZI}NC)C*gu(cEFi$Y$6qlmwviet207j5IK_E!;TC)Ncgj5+5KQrFp z)m#z@11YT6kd0oLCHpcEfuZ6GI4(gUw3W535yw{0>K)*<&OO;gVsuR(;0!pnV31f~ zn1~;wqOcY-gn%4}q`3efH`dU|%%S*VCkb%CW)>}*;pnZ4IC*Y@@0=XIw6qZaJu7%= zIi>@d*im6Y76;VRR~B$S)q|Cbwrexe(eua zby1*2wHAXb!vGXG^E->wIh&YK(r)$p(LLwZlY@EwUvydKMoSvx@1Yfk^}ZbZ3qZh1 zpb&roK}MXv_L=iJ@~<_6hff7+PN2X9Xnu9T@be&3%0O`db-Okw=t>c3|P@bDv`O9z(uVsa@GO1lfa-iJ<{8&<>r#u_V?l)t)bRV}cB z+z(W>LI^}sE&X{Xu(378G}A)LY1ZI(asuqetu&#@?f5B7rXv_6h}i;XZv+LPob7DY zV`0ADES?yYdWf&AX5}I_#e|S@jNz_|yn6-yYbUs>vQu3_42w40Jk=H$7SIe#mLh;6 zg^6gKGVWAH3%***1l+P@Fqm3j-gO*+O2DS22Pn$JHRExK@-9sdd#V5D!DJ@LE)URO zYy*aI@zQ9k6VW#_E0T!}R2->B1)@!Py;dWaX21_~XxO<&0P46*SU@CbF{56cyq5L8 z$mYk?4gZR(0MpBxti-Lvnobn+`!8;1p5qS$G`(4jk5GpHHHL2y(rYOJq!bW|l!DhP zF@p1#rzP?~*Wghadyxj@$22eo+wlmKi+kcLGpT1vU68MG0X$rSZ49 zOj@7R2cr_j6~lgh#6y=Ww;Cl?t||F#C3K8;XOeqTB{!WtPqE(?f`VBc^$g@DnGMJQ9Tva z{Xpb9GuV}*h`o9_ks$^%gUBHi@l^Fde*TF7w=Oxva%&>U1YX@~_Ji%j{c#d;#{cf& z$rb$mm?a0zMFRXO8jmNq^|o7ZX=92s&0aCB_!$wks+g*(sCRO+tAB$+Qd872FDyPt*)!0N@QG_EGx6|9ylYf+JcB;Y3j)2eK&<{{w*$cu0 zmCmE&|9Ry9;-psg3+nxiPM{Y07x$@}zA(Q6JKcccDU5j9$wPV_8i4i`fEQn^?x9VA z(44md;Ru8!GEs0GE;vS0tAfxH+r_#1SBbekyuU1APAW6_>>%nTuaD3uK}* zlm*cp96?e4=dy9EsT4TR=&9xyRADD6VknLrS-|5jZK)xgRMqoV(NZ9Vmc_n`)Kue_ zyF)Z{rA?2exwF<-(2md-nl`w_>~GS zYq9v}9ae!ltWt@97H%N`2a`-Nm}JhIYt7(yasu_xpQsu^hyam!8cZV?N*u!;@_IJ_ zU7;hW!K2q3rBDI|=M#ZR5tGB>I3L1nm@*4p%tU+P$$Z;NjHz{zbn3xB+ratPUBcC( z0zf-0>~k7`>i4Z8y*$8T+n~G9!iBZbFk*U2N*8Dwil(pkW&zNZ7=4BMvb+5Q3vcQ0 zm^scsy*Q5Ee_=C&1U>&k3@Li}gG)^tz#Ze3hvIQi<+U1L!yj}0a=!X=`D1f#%v2e~ z;Mzc`oC-_fzS{AvcnX!5Ks-hoCy4tNxEI&mu&yRWc-`N<(DcrY!T9sa5FsWYB7$K; zOoWy(NK%V~B8UM;_GuZy(FKFc6G5gZ@_*ad20W)ik&DY126hqv+KU2kkzWzy@&Ky` zJ4meJ;@W7-5IyMwZY_J)ukSYe=RbbcpMiIFs6@x_1z~H8)ut_*QI8D0Wn*liOi=bB zATy4@3xhD1LLW7e5O-|N_(2fl!XhZeL&$}O8-uJg=y^^c-(PnG#p9u_yML@550ToJ z!Da&H4CjZ}r2*)Tw^ax^6cimJ?+79yw0s1>L=+LgiPb{{vHe=yOvB@(FiaA4?#ar@OC)qM(hgGV(w@J()l{22JxXLlQf z3mem_#@jq6(0IQo3J5NdxroeOfanA!O3VCzf7@y0S39FF#f9NJ)~*3j%!HT$LkuXP zn}{A1C)f=raNAM@!@wXBh-Uy=JKOv!&}Ox<{Jxa)OYYzR{Un(I#m5+nwrU+7dPA(mm zM*x`sgR!j|eBBAmivTK7z?^*%KL_F=IGQ4gvKu)6zk!Tj>Ode@oB$yPV3>+1z!-vx zXg{-92}tv}W5r;aIn+PR=Q}j?Ea^^y8oq2-hVnF9fvQjXor4kNA|}b!2uy_4gFT$R zFiIoBi*U1AqdF8y`81$6lLL4d4`B^Gwn;CRH0wo?x&P9@7OOMrjsQHX2Uz6zWojTk ztQV@bxfjtws2K>t@pqoxMOu){tgATk*UFMxFdBe?*`8zujL{S800&iI?p zrJREs5zz9Wpdms;KpZipnP4>&H;7a`5PWReU~?)^(SiUp^A@@TqOP9)Yj_W+f35u2 zI3UEUCSBad;$jON8=Su|+BQtbtI%gL3d=d5eEis(!2#s?e`~O1Qkk|ApaCURl^LYr}*7va(H4|hu!^M-bZ|x1`x5VyZLIwIC!O52!FttF4m|)z{ zShN$1L#nOX(V!Cn8xuk5BY?D$UF2iG_W}S?AwE*g?Q1&UyC?wXQ+|0k!R@yn z#l_7jvZ+1Cz35p_v%5wkQEuoI;1OEGlVrFbWmDVfblUG(A4w<7%@x$n#nhH4i?~PGbTm5NH=+E=Rd~Qe+@{6GtT>U?r!k7#=hU?Y$yamLc)m_M*SQ3$g` z{kg0F6pnzyu%2hYz@o$#0ERmOfZJn73oYyXdkp<|0{kkEvw-P2C=U_S6miR5F9DDn zb(2Z5hXA??0FoO!7!eRLp+$f(jLa%6WETC9sD9gWgmLQ7|J?ZN`TuU-nAnHx8jS0r z1^{rc3cvznmxpMz8NJ0e&aI6`hVT@s!s9zTfz}(t3C#V34<3J%w$Wx`v@Dq}nC=-S zGAGxctqO?G|8r-686z(Nz{({64>yL{4t4%Hb$#9e@S~bDFf@hISs09wwG*_b_Vu0s zbi*3{D1nTVy&Ot441hfd7*QUW6JjPxGtq;p+93o4phbhr6YJQ2s>teEuJtCFFbv42 zx>oA{yCM7ysQ}d!dZ#3E{+C<@k6aPLhOo}Q2WNm19)CVW$nJhH0W-b zQA{l>Sg_!?57Pk6ub26P>k1jjgMsz1zu*QmMghPiQ!n>558Rtm*QY&Rn1G0f$n<$2 z8X=AnbRxNq6M$}rtLpcc9NOm2yF1RzDk{`bCh zB|>C?LE={a)HeXl0DwCw5QoN3yM*_R`y0xDnE=xSx81pjGnXfT=viiZNnG#cUNe*3 zKgSL003HTyPM>G(P;95%?ML(@TN79R&o#T%kMXW{_La&&8chG8!Wl@}AXL*1Ex&(8 zlDd*mW7AH>p!0o!E~X+zfD9qg6mgo}AOaxQ&G_vgxzg;1Y5<^t%lRWJ zX~2;oh^Y2ci&gatfU4s5<=C(MK&qYqB(vtV)0je+|5Fv%(;&936M!gqu)$%FDw54H z3@HvA>f<{vT}Wfb^IlvdMk%s!Wl?~pu8jIdi2z2IH@P=jj+Lb+6uotnp>P02i!Ny) z?OiJT1nsJ zpnCiKjIu`F90oKf05|!oT31kmP-?oig~f#qC^9&AemG*P4Af{6BH#5p=1vTmC^WmV zFlKJZrwI3g7Do$a+Cn>3(--D#W{X`M*DfWthNjkFVD4QOyD5eE^OIj2r_Xq*f2A zqRZskeHYq<)gEJgY%$4v6kr2Ayh;?Xg94Dr8Gu^J|K}q7^C|-#C!jcju5aVkTl*MJ z1ncXQ%_!pIR|Ejga{}FVAWU+@f`Ez-e(rIe_Sz;*(NX53qZGFYS6hCCIcV77()f9n z`Wpg$A^o=k9(rcrAdx-P_4&#GzorO)a0Wz|5t}hulH$Zo)Br>-N|M3E34mTbhdnob z^3kNpQGXu+7(XPpomw0e&0BzhTbCnrW5VWCitsXRP3?JRdK##x((Bba0lMKGz{8KwW_y_@(=1Mjdm#E?9{!g#|2mS- z4VS>^!@hrn&LH>OZeON^Nvh2T&O8U{=c{uBzzZN90y4$uCTaj80z@Fgu{Zu#^=bwo z0Vr$(c4)t0Ca7vBwYs8;LPz@cWdj9}cmhxs5`ZdpzLNqFs^R}U0#L4WWTOO{ z3T`>JfOBhOF@%>vblE$&R~Nslg1aqHY;NQT;2}(+4yPJ$UKl2Z-DDVCE9E8eP9QQjo&z8v!g0`axot99Zb?La3x3yBsJ7|{H~@3A zkJ3Wce7sUFo~c;9qecbE1H7zg&We&Viy4Qq9nR6X*X# zP!R|8Wp+Me?$tYhybCb)5r7i}0Y!=E0afi1Ilccwea2$jV0~ya_XYv}*Aa{}Ggbq_jgXTu|e zTR%uycM^-BD=;5UG?eh-ikw%)(7Aq0-WO1!{iQNc9s!j3e_~Ok`OY(Vx&{~37oj`= zWQum2;rJPSQ|A9nP*KR%#Fd|}tzbpS0f;>S=qdn2F$fVmq3}-T06+t{BKob%jFtgL zsq6g9#1Vn&7~8x7P7udIA!C~VrlKE!s*=?^Nq_^;%t9wq+fpf(45&)w$ zx$SGR`JRC*qZhuG4&dR30Dx^0$BAYOmiYY{e3>Q4{j1^sY-hTRPKNx_>b|M#n-T7hhh9RcOqtJQE=24pInfD-@( zA||qc_EM`$MT4IxZd;C#ihAas%rkEH3@J6U^holRUA6p z$C(Sm%n&^bAo0=7Yf`}HP8-yUubUHyD*69|O1SI1kx1K!qP``*Qv@hROP6Dy{ER-W zO!=yQ-T6RUb~*umc0wr!o=?6MBsMVoy%KqL2l|@#tDS=5lOP%)ixR{a1=xDi7(X#V zt%Xi9Xqq|WzxJi4u>U{5j>!{%7>J1x8A6r`7BfYkP|j$*WyxTe3erqn7hppN;I8i; zg>xMm=)4*NfHc1~xcuUftZjJ(pa^F#3{yk;z2Mben{&ih21Ef(vg;WEC~zMLW*AMP zsI8y{OMH*AXIh1qdPG2T!vBiwcPR%hREGblA1%LkBF_#E05m`UFLdIvEpT)Sj1g=r z!Sd}EZyM_-x9Shakii(5X0H|Tglfjm0AdDW1tJibftVRc1qVdXXE*}TVux|C$Jm$% z#+d^Evuw`jtfq2+IQAb!wenvR!XJ{9Lnpzr1R!ol$S!W-_G1eePAxXpC)>vG4*~%2 zwaXE`6Sy8xKvc>9@gRejBShM@65UHo?R-p;bNTA)J?ejbEkwNCSrFXU@;0fs1zCO6 zpyIAYkfa7`1u6oy3K4N9ad1&9u$e%tg=Btz23QXqX};p;6JQ%1N6s~tlZbd5NXBSQ zGj#CgXaLIV`-72N^D;`MCT{~du)RuQ%?J>l=g##APfbVW)*;f)?i|W-5lfYA320en+a@UFL2u&S17$E z`TwjJ0C!^8aq?QEYkP124?hIp1f$)G!KO=u_p1-p35t#Zx-rm;fUY5QBcL1k{SnYH zKs&rJ&|)AqE?P5OItfzO51;~MR*+dmmI=~KkfwrZDo7HGNn$abT1=)EFY)rE*-#e5bkR;QWGOK zT^PM9ocfyp$Wp~9b4F}-UG?34@(}>ftp4g&cfazhxZ7^kSE#jR6p)qIHje@_>!Skq zgKH%gtZ_E-6v3twnAQn!G=NMJw6iz90EjANF!YMOuZ!{50YGNo0K{%eaSK2kxwejO zYOz!fc>#_s8B8sZSU^OYM}VQu38;=ChA|EKKgtqt1q9%R6`y9Jr|H@@S`nka*umNJ zYnFi@&MgX-KgTH zdjXI~-*|@anSCzgPlN8s*TwiN9e@BL_B3E77-qywu!+U8K>O?!fLjJQvS6^CSWHrZ zRdOT1rKSLkIX*cz_@e)xW^?@fsXX6wsoon98>DMnIC7|q48Zxd@q`S0S5;sCxr+*L zCkCL9(QBU$RNH|^YXnLdDvUHyWZ4u7Q^e7^1amIMlwa}@QTZyLJAoO8P<0LzItMKs z1PTW+$BBfGNt3gw9IFl}5DS~WfH>X&XJd5xDddm>mtVD)e=P<=9Q!91b+?t@ZVz6s zkbkENfKve?w1_D35OG8x%B&s`K`$QxcDQe_(lK~>dy26q097Txb{_#&^#3Veg@++W~+o;{9idzpyOl#HU=UU5J#(xwjL8xl=bww$^ulX61 zMe^pFw=xBQdKicDa)2CpT`znA>q0f0{Y)A%xAp#ThMD-}H;QYZrB*pfjj z21bb||5!n48x(+>Mu7X@ws0}wDz9i3w`)-QEqMY|TxllA22KjJ}964&sOEge{)jZ%75LAKQ}!?LH$2h17;=>&_ZHmNqm2oC~)gi z1W_$ifSeFW<5|JBTxi#aP%AiisE;Rqcv%>D7Qocw8QFEg zh=?2>pz56fzm^UFz@twpe(oa{+h-@R(FX3i{cpkI7O*Zs(1J3npU;xd)o?fM9N1O@ z>{M#UNO0S_-yy#*#SO3$#RjI`=D6SCcBez_R!nis%u4EchWT^D_b6axB~TVcI_|`L zdG$d1>>amtqj$Y?b@5&ATs23JA#1f;vp?Q=|q!Gho|k9NliqSK}y0ie-E{QK6>bC2i9cRm|TLwB2tFN9duNo zupX}Hq6dX^T_rechcvwfvXQ0mwuDQW01(ixm-FWO7447F&cv zJ%i1u#VE<=06JiK2IrgiS8>1=ZD{dza(^}cKjyRmssaEZW|zSPT(3xeNp9`dF)}qeMm4lybY@fY`lRai_jV~(AoKwCRh5_J3K*C zirNt!UG2v2e9uDvUGL}}{>cXpz4!2;?oX6*&n_Pbf8r2~qrmgi+;h2kdCQ;A#ITZK zbGqpz2^q>cCP5H(kp}tFrsTSXN=~>`gAO+qpOKJr0vyagW0V+2@Uet)EQF9r_QX(! zeKwr@;E^9#C@lWo>mQib0YIPsw+NIE0$~uD%*v`&v~vpZ(G`P*Hskz8hQtD?_z~c> z^ik%be*i@WRR5uL)~KtMfH41`r3@1>vduB>e%~=%-b#@r_EIP2$!QG(Z0*@&ur1f?ID}!qXQfYDixOaK_t) z#f`ub@#DtKVh7nZjsl|U`*4=(6 zOBRN9>urDZ@*jeU;1(Ho&E!_<0yzbPhzsYCujJ$hnwCz(&6DTiwY=FEw+Z8Hg1`Nx zzll*g3W^wtvgn`%ZmB^PBfss88@1b74RgcmIs00sb^fDwe6&kK5hqM9_FlYB>(Gn< zh?@gI1sE7JkrhQJwO9y4`dbzwq^d|#XZYeZ02|Kr25;bF4K~#!zhcyNO)#1h8dPeE zNY=Iy8%BSzjq^WPR|uX6GTR%7Af}*R8wP}IYjn-D1*6#?Aph1MQa8}y^(Vv?v-+yM0wkdI?o+Ker ckcZN&ht2mUtSxosah4=wQ~E} z+uaxNcdttXzySalk*5KB{r?sdBo!=K(G`XR`dS7!ybxiSC>(EFcqC ziE+CEfU}QRMt}j}R)l123r7!iAjCL-ag;IB6RH~HMr4PoQxb}x$hOAU#0f+@zu(?q zkZVnZdFY{s=&=)z(UdO7qv^C4#|PfOIam);w`wk=u2$&Jf!stJ)Me_U${QZjpoH}J z*>8Y-XCne5&$GkApeu%*4?Nk)5qJy%J50T)ZZBLKUz#vDk+I10_db6;PR=?2m?Qsf zKM0il6d;qSu8N}P6o4E7Xtm3@G)Xbe#Fqj?067oUxO6jM)?yT#iO*`T{h$Oq@9Ufh=}jH zIKEK*`SRf-l$)=()Sy@jnpS-A!%b#e$MfU!=Rbb#o7kLQhEuggp?i=UG74wlBLP%z zQ{fbPCRwm`!3{PcYJJ69wFGQwvoUhjExTPj5y{rkx;N$i%*7ln&f)LfVips}H@kR_f82 za8YZ~LABFUirZf}@dscpZ0D59D7f!%1P(8Z%55T#LHJ{x)B)woWbr!1Yx-j_dl@81 zE?Bjr@o=2rrR#QLh5#V>Ro_rf19lyN3Q#)}T`nA+I{rTxh5p}e0N{)nn=k?hDn3-} z`N)$vqMacC|68Q%BdApzJkrJai(`=L(*U-DghFpvC(v&rTIxcrzPTL0Bab{nYfr9m z)Q_U6O}i`Y#d|ML*V;s-p;Be_58FLmPLB$GJGk$UcR-x)L8q!SP*r^Q{5P?gtd~Yw zxyG!~GgXbc(J9Px7$}V2Ig1$wa9UIbsiq?+GE5m|UYf!Vs$Z zZB>o%M%V%;@TPJA4?P4N?hQGUEVeT3bxi;LTa%5zlWP_1s~LCoI$!ZiCqVO@LvVTG z!sCIlIs-L38vnf8&Bk7N9Um#w9Yo*&UI1YmEleQD@RQdi0%%qMX0-AsfISY736?U| z#asb+vCTNtHyBI>!$cqoWR~`>0L%n3#&wVu%Xed-KQ94js1^X+j*(m(;ErQGOftp# z`gmxVet`Kx<2R-gSZKewFn~vKFLm2phKyT0MK5M^_oc}ND7hTJXzi^4LRzW+Yk=ny zQ2_GQ*<&seAmSo#Ke_oLPHnyDjj%-e5q3cns<;4VfxtT8SAT9EiwF@|^JB^x%A8{Z zf+xWkBE=LvT(A7Ut^k~?0L36`ao!L_6s4l8B7O#dKo2i47CMZx+nM74cpg9<0Gtaq z*Fmqj);oMV3a6QKMAM+07C^JZFU3{nIKN3*-1b1^Z>)$ zjy!Iw09cg-u!FJMX(G4WvZyayob+M!1sFQxU*V0T5+!dU3_zh+eBfC!qd_E;bh=UZ z?#;>N1CYWK2e79Gx>k@n(Ej92Wi8c zbbyNI&0+vydf@M$AvW7FV~iG3T!vnU{67Q$^YA#zKX!qSf>J2hW?1y{j443b!Jf%7 z)oheXW(8SlHOmB_Yi|x_biz9*PH&KX;D@4~Rl}bie_6qyWD9%40>@uNndDT=t`CEn;r{U!X3!&}v#B!K$B& zEO|?N5sU#@jQz=fy;i1toy`eAj&$i4ZC|BJtRl`tdxnr?qFI}PgFS;$D%hSn;!~EP zu>%lw#}1c*k*TYGHm)4rMb(%^BYoh==g<=F3KP+7d;t6Ls&~NG=8Fc)n^&B^A(6e8jK%I#VW;TIo=rT7rOE$vU38 z^h7hd-&pnwR`o`-AI0-%4$#MWX)uTes1g;>(*zn&gem&4IDXyg|Dgjg{<}8Bj{9!_ zAtJI?`vQ%bF;=B)rDyDNm+aP9>?pC;TD6&lRaFbX`XMb=6t20+^@dx3EL1HSvLIL@ zzn|TGr%?e5_K&gOr~WuXMnDEFqJR_%xB5dT6w@@_98T}JeQ~-yvXjv;J;%(?z>yPg zj0T{aE&@Z{M6=c7UAv96q4sa?b4Y`F-94P$35e{Lvgpq(C?# z$B3R-`zF{g!v)4Y^j=2+3|1cv$UamB`YHfmi9}S$K_Ge-R)@q$FoeZ@*ERev zrU6p{tr7d7Pbq+QD!QOf0Vq*b9PF{SB4BN#eiD!$0Tu{26~6*G^@fV=8H3qketqt=TV3dQd{{yTi+V9Sh0 z)QL>%$ROQ1%Dy>ANCF8m@`A;As840SKQjO_Bm+?pEtJ)SNjAYVmw!-{-^vtV2l_8| zxdeDc z?>~>=6b)fMf!Lsq_RZ@647)r_e2A1t#ixH31Obsv*M}*rX3GbA_Qez1ky?G44UN?a zUEdfTfH#{1cm$8oN0txpAd6!%((Oh4dpDEI1&a>i2tbvUJSgW;f#?@vASFhS(|?N- zgDWQYgNxrrDpRMrq%>RRtK$HuItJA_j-WWMVbz~k_9Is#XQdNhY?ERfvCsb>hF+%z zpwQIvAt1znFad^WDxk$wq)&vYC=vo_rOQav6M)pm`nd#H$j(&Ef&%%Z=kQpr2Lky# zfSGdOYyhWfRVd?@vD1s|*>XQhTOE^KSR1h_ez0>l(!K+DUGo1&JCAZ(x8uP8y>`@n z@7nmR&x;uulAy&m?*$0dUn--a!#;p!-ar{45{_Sbyn*wt6=zU#0cvGG)K~gi$gh=E zy|U_8R{pZ|=kBXM3!(vKG;PJma4)V`15m{gctAEE;4WUE$BJmj3OY;}rB<_Ui)p!M zFib)M5UPC-I^WvJkBX~z@P#*Li9QwMhf|m39O%gawcKf?$>m}8mLuIX6{MS+(+Lqh zuX^(!|2Luophxim7%k`0C}C^OOiin8jPzTk^^Wai-Kp>trWTg|nw+&(LVXU-5-rY; zLRAzX;JNiDkxAl}rmCwt!iJvw9UI9%JJkR4v8bfrItBm&=beH64ND9F-zTPlY4J2R zkn2bQ0;)tHH;{`-K@bKkfs7UH!_5a6LrGRUObac-##AxQ#7zLQfd*hm^__Xsh8YJT z-M4P|RH70-hVy|Qi3fEAL=G5)Cdt+~yYuab(v4xJX=*o_=_H`p4ch_uW_JLpF8{x0 zH8R^4onb1AnN05%SP&7cW<~gqq7Q&-`F(ZeFVECE7u=P4)eD3?aq;V5E&(V-&EPBH zz9$3K^ZXe{P!IX57(gW&sFeMRl;AQ&v<2AF6mfEK3)gFaDOXYe-{<5roqV2a0zxNK z^hH1sW1>)9?J~s%n55$Q|9;ksxBa@M6%N{0^2jta|2L%qGk6cHI`B2%R*?me0!U>z zNwZ0s96qv;o!OjrAaV-8rQqb)j{six{Qr?h=-vnKrAf9PCoJ97&gzG@l8r*CN5vwP zXIH;cQa$&pL;(mY0d4`KU@0L8Ufg^Jqinmz{HxJ_8+!g}9^e=3uL6D5RX>ads>pxg z3{Hw*AVgy`*v@bair>6$`G1&k7ijARtjE_DD-z=dy>1mjD-q6rt6e zSR)?`&kdrVxu8cl05&)#kO9-6#Z%m{d9?si;wVcl50bV)(pzX}7fx>&$>dpM*!n-o z?mK|%k^esgJa%HpmkBXX(Tn2v?HlPu6cqqi6y1PCl{AlnwS;ORe^nE*RuTm8(&kez zzK%5u`pqxTvWlr8=H)hHnh6Gp_z~dF5rm>FIp*O5yUL_qa4-adsOp9)l^&{2t5F3}9_D$z z0g;7j%IzpkFAdYfEA510PA^>=SpY8rDmPyN@CI@KkK$fh?oLc+WLg7G`)$*H=P=oH zD>D?LwxrR{g#BgduVnmbIoC8V92L@FZr|GY4Av%RYRtbqmi>rI)gKU~R{yVt{N*v+ zi2R3aK(|V&;y5u4qK-~6#`P2c3DbZa0%3OMD(q3zOtd44hzLVfNWTT@w;01zFv$c~ z^ATV&fAtUlI_BB7XfA_53J?jZVFL_=8gTC796^GJlj-Itz4x|$HcllSkCFi~ovy9? z`&EF~H~$AchQlC-jiwqB0?sK%l~uZp9%XLDgadN4Wx#A@yW~IF17xy zr0f^q1o^7N4N-v3mh~FTeql=BD*yumE?BXnEH%kObY1Dcg(5 zbfD}iRgAJBE=|sQ=3mvI!*IU<1$RXIo9h4N<3(8y&1F9nKw#k%PK(j)$nuyYlRa-B zcnEr(W&qTu?-2lT!&ab%DFwh*wdb9|RF$yYWyA&;rLOBDAM{)gvl~4dhfDpOdPI{t z2+hm~w!Q+8fjA?kG}{^_uy(q%+RdI_o3yQ!Q$#eG)h60^0Iw$mNQZlO@mhvfWYbb+wtT`vGYtC|13!yMm512gADK?g2>&+t^qNkUJrf45QVuio`w{B<0`^~xD5M_5tE&A50HD?lzH}5m z1xOV7EI~(ElqId!y5LDD+SldRX(HV!5vlJ3umF)2jlIL0h(h`?QNP7HNfk+^5DQ4& z1AwOdpJp(C+3=of4xv#XFkHojeD>i}lN6vN*`6fF-nE=Z|7ciU#$lVD(QW#o5t|zPd1r z^f#6L>QOMfYDrG|*7?s{?^PA~*x#Z4gHNHYGTDUGx9Y{&KU^;F1z)Y^`?G zr34dIrGAIei3sasf!H$tuY-QGlfQg@VNQxaR|kN~vY;n#`x8VJLar5<$lBp#noiQ> zz~NrDzCC4|*)=8%f>+vi0Iz%Y?*%|&x)^KQc3awc*VqmUbUxFhwhjdof4uRRWkCuA zL+U4uyK!ppG_0m&=`RoinZW=W_ce9?W3IWSoUj50mOaAmxOe{B9mz+&TjvV z-+g`a|AO>aG~p4HnKFRbsIdO{L(cCUK@k}cP7s*^F-_VM+sD?fOa5OE|Fwt$d_ZIz24Dq1W;JGD zs6fgDUT6`lx)EUNX8_vz`q~7#6U}A-v|9)eMurYT0g(pOQ42-Nag=16vLf<#4L$Oh^ zWxMt|<^N3$F}|aYgj}{`;kue5fRuruRkiJicp)ZC62T->4*-^IKMg?HLi{5S;FxAG zfCBujh`>@Yz_sF{dGFyr*#W4^jhy;{5m&QeRof zyUt4EZ*T^vm;LI-K06~|M$rcqdGE%uAF7eTNvqg4tmB?UDb~FL@ZY^o{yD7wy9HXk z+`f`)0fvaSh>#GFDu7N4)QW(Ov1|Jkb!kB3DqET6<46Ss0LYE5sB{Rk1)kvNBw
$G^C++AcAP?cF}L13%C?*VGmyxn z5O<*p4LBe05t4r9rHKwGyf}F|DE*bWe!c96I;*c9=FchnAyo9KssHX$_A9Ry&%_aL z+k_{ROzgdfA&+0*2p|AiAl~rB378@Sz#?EKj1;g0pw}W&RSc)j0c2qXpdkRL%ll!s zgq-H?3`iepy|1+n0OTyWII&CZXc~7~*`=2^ILmY+V#>>ZvhM({!%6li9woG4bQHJA zqKK4x-FH;S|FrgYm4Tj>)GlxewFyDKYMYAy<&6eP(6R{#NGakh+aBAa%W*19 z>GswXq}ZnXbl8sou0wp83xM3SYJh1c6I~RwcLM-3W10$7f+0NV`AylMrKBda4JgEOr6TP0mp{4MW9q+CQcG;VxefY2;CM@ zVg*(O;*)TYdM8*~ZrQ%8!Ox`?q1Jli*DSmfjCzB3sUe?miEjfID=L~MzR*5~#njsI{pcv<;N-`0HxaJBjWBahI758X>=x1%V7>9(Wx zhccZOdVdo;s5OXJ>Ah5o3c?eD@}2-N5*cHdtykv!HEaF_H~@BH`jv=wO~JQ90@}Ik zSFQc~BIoIdTa$L&$__5B(p#2~MIYz4V)XGQ23g z?m@eLDPxS!rpfrTlpcR91{6s52n7Bd6c->^gyJ#C#{cU>SozCud?#>S96&Ark}X6n zCGACQ-afKJuQmasnpXhInm<(xe6|EgMLNgDDtm7HLK*sF9`}E?=bsdFLjKuRUp1U1 z&|LNtlsG}X_AekrCO+La3%uGr)HxF0zIZUYJ)&sYViYT|2B2SjcYXAV+oN8-e*^&j z5%+Ju?~Yyz{sn+u55UkLgZ!8^0KjeCE=3|{#V8%@P3iVgCmN+{E{u~X$q?BDCee(P zz%Osb^?h3NZ;y_z4G8wv1B-WOW(n`>)D#HdsLYiqa}Q(=Pe6<*&fytd(5LVuCU_XS@$iRm zBg^^fn@Cn)Cc4qfm8jN*zGy>|B~EO#{j4yJy@H(1Vc0ZyWcRiQPUjAQ*rMRxDC$(Tg)A)?KElK`I8Rq)0N0g|%Pou4X8vMf#oe~n8E$4XWRm&Y?(r-)Xt78ogUye(7MWzoU}4oFgMXg5 z$1|J3X65l&mVo_z*eNtiz{vzaipkJIk_kvRp_;iOfnx7SAORQyu=uNJ;S@T^aNJRj z-^fhD>kt7b)}DNXmzM60TD09o6yGhHwsVGFB15kLRBAkiQeYHt{>x^cJTmZV|C(W7 zFPCb+b9(+!;r7qz@z>dqzd^;y8)Mwxlv#mc z@%4X&vbbqntRO#?%cz3~-G28Th6F?wLK%$5@02VA85kB!S#evCfz?7Z18D|Q3(^db z)DHzt0ZrXLn*fpmltCneN{Uyd`#A!1K~KPNZ;Es115m`s%DAE1GW!nTN(xn*XMe}U?YK2fr5};GH`9sN|4%WM zLD}3xrNC!7{tIRK2sD!th+1r`eC2CJFC7l>O?tev=cR8BTyZ znYomNf?C$F7p4pi`=X~c5LhWvH#cro1 z4GdsI^iRMYT8zrV=+UIa>HuWku6PLr!c0H%>86bzxXlLTAXqG)I7T?pKLVt!sZf-m z=dSSIsPRV#`CF+Uxc;Ibpq$&!WC**NXKn~FUTbr2sofV$As}u5#I{nWLFg@MRfslw zvL$}c7(}a07T+~HyNPVC$J+i?1Q4u&PDjyCEQvT&RMzX(rbEi-7zKo9*z52O1M(=q zG-^*<9SqI(OiW-7puo28*P z^6DYtQ`4fjPuL|)Ab^I@+r{L={?0R&0H*j8fEfrY`~(_z!2kSjpA2rmjkSN=ruRR4 zSsngtR4yM?`;*D!_bW4VZM`*S`caYq)Yf~as4k>e4caO}C-sleSVc)cJ>kEx9Uv&` zDWra41L&^svk4O*v=HB~Y0yAa*u)YyJ4xS4?D)7<1th$08A0n#ZP8TA3|NHKN)*sC z0Exkf<6gSlFX6igo=>TcN6dt!8Xy|JdOe2Ob%o;CaBwCDaEyKY1qL%Htnj@BhR=IP zk)1LCUjSsj{9#;_*k{JOm60YeaazVB|Bvj@n(H;yDNkbMwSK+}`ppt^BeOXvXi))_quG(U$v0+TuH@`6rQq zlNu^%_nk}iO;v!khCdJS!PawtZap6fvA1eY0{x|ZBq3_?UCHA>J&+8eWrzf63kaL; zSz{U^rm&$z?>kSYQxTfD5N;Vh1QQ@6l?cvm04(u2G>%YWfhlT??2Z5K`gC9bo9h1` z-2Fhk`pT-DOp7U#Ijnf`Glm9;F*lDvibcksbN2T0rZu||}aqJd2$f37X?rc%E{1xSnz{`Y71)UY`}0~q1YAe^AW5;Zjb6a4T0^}~=0 za2oypU*5YxUwnts@X_9=EZ?hn;oM7%l{psBA89tAbPGamftnYncxJQy5K4RL0chQR z{iVHqXmBX`eXH-#5NMPw2x?t>JvzT<2psGA)F7Wm4M_C-mOw+7Uuz?PaOuScz{abx z4h1kb2+T8$&`&2Rk+vemdu;^gUd!h<{sF)WD;(exR5*dc3J)y&pRb<(QUW_;05<{L z`R1Eq!qvE#(moi!t$6N8g|RSC90K4_f(ZtI2on3>c~(C}(Ex_bm`(yfBCLkex#1N>}`5}lo(DO6Leg6GCD)7Y50^Ub!Sf~*>WWbSpryf|3r$yxF zv+b=NwrYIYh7v0rG>*%G0c<$v4sOuZ(N}7T)x>CZ2pavm;yFM-#S4Jy7V=9= zwO|5m{67U@ze|1+*87t&0FiqSafctIb^c^%ZDvdNKipe&*$bl$-;lhG?Kue9;)A!)PEYx!0P{h254D*keJ4gXHVA7ym@9zEZx1YuB4&c)Y8>v0z9BWwK+rFp|lrJFCuG@`lICHR!3 z{#n-X78t-7e*)te8VjtT@dq&T<)|mTlPreYw{Ot{K+(*U#?*UI^loM5wq^`#tG~+@ zV9GHAANuO|U8j0~j$u&4mJw4#u=VN)1re08lGSc0-THlZjSoEX$BNpX*vb{fZ?_QJ z_IiIl-uI18UF}OZPpzus*CD!2oL4{_B`MV-(Xm5TPm=GMog?W&rJQfI+3zgH7r)jq zgtM&OWZik!tYZLEd}R!}@q!j*5MS^0yV{0BHaUD?S3q zmGU4F#3G?DWCWmP3=6i2LyB6wA7uPRi9j9+P-OX!TXx3=z-inf zKZ59pP(lvsb7RaC2GmWEK{J=Xp6P<6{(0A36#Ta~zVD!Mgc>sxjR6n?131OFgL|~N z|3>l3crsq0Iv^Cksdxc^p|OI&3W}5Ed<|wXzQ$2qjLtyaf2>c@SciPgL zO~(vCi7x>hfiZ_}^#1_?Y;FJmUBkOHAE8*7bdVrhVbO9e(~yk`EyY+-cTz=>4&t9~c0`(A{p`-Pb|j zz-vd`x*Vn7Kb^~X2XYyHr!oHRTHTf(XVaVU0@d=w$i`R*S$U;+5&p@e`zO>Hh^B8 zpElC@TRq>aHF>>0IhMM5r03g;NRdvD$W_{-=Tn$S5xP~9_-aZCiD-NJ`!;O>7ikBW z1K7iV!{8W8=l;8Mc?^I%K>)XLi{8KS16ALfQC*rnrqS;-uK==0s>X>k@*xZa3W9*b zXSL!5NTmD%*gX6<)8Qwm@RRA=*F^l~bbjyR<5bU=e*bLxE=LkR$-Bx(@efo?T`(}o_q)Zb~t`)rFe4FHYr033l_0?-p^T(WWD2;e4wufJOsTvlTP zbHJ=`)Vu&(2`G)F$oqF8z{Cy}_`XzV_X*IjQGZ2j(U127B!CntNU87UJ0-nJkwEu8 znhM8KqATi<($eVJg$f`VXn2O$To)q)^vtb64bl6__0NSgKd;r_k0pQ-|LX#Pto}a* z1A_{1D*Ye0N9Cw4RvHs7%mK)}t+4{bpn_`vl7ao?s#r+quZY34vIRdP=wAdbybRor z8G&^Bso1sG4fj<-(9{_9^6gOPP2h`8F`4S(UP!;5y%pgqMeK{9khZ;b;a^G!( zS!~1oH^TqG;1~uARH*URFtet$YlOC6@D^qzdjeAjLmQ3_M^a^xb#-+^2=1?vGp`^ zusjF#TdzUu=8IH?$hz+XqO$J3b!tHLS%RRTU0CeT3;oZk8q5G3;3E)@0W5t1kjte1 zUpNA|ja&5kXJ4z)%ac-bwGX1-8(zX!ebv4Jh%^3K32vaAQBVcQz*dzFq(3<|Kp6Ro z$mmCuf&7uw@00Y+JUR@1QaUFAK#}yOoB>ee^HX22k3b7pH|H75dRX7Jz858I+u*kg z=zm&7u);$q+((TW7MIWezY_*<6TtEGP+_UZ3TB^4ziX&+V#Pqyvi13U{oi{6l- zq)H_B0?uy>*cKx=&-u;a|6jn)|6il_1waM{a0>nZ4(<^qC@Nh~P~w1KerZqvWMJUB z|9I(7Q3`Mq{_7Ef0aI-yd?u7v^@aZiOd@srolfT$*F`QpwV_LI6Fna}JwI@XWTbL- zE@UbpF?XSa5S4`Yq^B>fccK3m_!^93Fy>fYPW}JFZ2&*seMybq{=OV7Fx6BXD&jY+ zm7i?wK4GnH0)2eCta~DrGrSs9D5Cbzx$s})I{b*_p4jczAME3Ub5cDYnXEj>W7*DJ zhVpKz=QBm&ygflXITv8>`u6^48!x#n1$F*f+d$+Fd=~WgP0pW1W-kFu@G%TdP-2P0 z%c=igCQx^f}7)Yh%*jn7}h5E6r(DCB{Vz=Ng-$PhTSWwQdQ zA2E@H+GC>H6(d-8|7{upZ2{1)U~qyNR+wEr|Njnb0JreXHz;U%GB(Wnq|D!QqyICQ z>d;r;813Nnb~MI7kZuik3W*J%$VU7ja{Eyj>F4gVR_BlO_(bpTb?Jqr&8erc0SWhA z7yxw^HJ~5X%X9LYoI8+ms>9RJ-?yO_Y%2X_0Z?uWfDS6a=7VnF9xX;wg|ZsM=mQ4* zEkifZJJ!M5UU>0C%4orNWM&ZDy|?AJm+H!fz2U$9zR`R1NBl`<)Z@a-K>Y@KQ`^iCmP`-I5V#8mQn-2l)liqnj z^NbYgw`B%IK5`C<$I=$UFh}dW0b${eM7ojqBDN{@&uR#KR;7JBd;w5g&H|u2V*odB zkM?jy-LFn2C6xyZ{HBRtkNoX{VJ(S?=f`jtt?|zS6YvEvy zUA_XKJFx*UfKTyjT9l?lfhh=Y65(naE04tWCK-Y(${D!zqD;Qt@ZXHvFRSw-PT%d& z^K&k_HHA4u9B)RKrpVRSA9@>v@n-A*ErG}GJ!JLyJhV?gXErxrV?WT2&z<*L&j4%z zkV{zrbSDhpHbAfAYqh_qM+MWq0e;s=dUX5UWfh(*6Nswprp7;EG?WY_*hi#(M9DeS zWw^`7;-fbuHzndMfnz;^BPMY46L>25^8_Bp3-nP;78%ep$OO(hd;w773V;-sHv#BE z8Nf~4!q?xG#iA_6YOMAF+>nx=ddh4C3_+3Tdb`FLOh^-ZR2avfX5#f^?O{!^4V<>H zMk@7Vi+r}qHg#L%*AsXL%IKk_&=Y`8PeAay&{H7vi#TTsfPMwW5muMC0LaBMfTjS* z!(vp@L^B@}@Qc9Mhcv1#C$Y~mZ1tcP4UpQz#V2eH3GsKi*N}(&eFUD7`ke_kgdV1_ zp1{|!&Bi_0rJnRg{n758&RsGAUjP&?0B8YySrdRRi~-mJAYZ8Ih)PyGC04Hz(QAD^ z^wc28=YD2#3?(hol}c=^f%O}O-Xb4*+i3?#t^xY|@KW;kJ>hXnwVcXungTv+DeGB- z^rs!R0f;RCTD1j0&WZqt=*43Iw*h+nvscxqxKb*k_CV&ntVE6AxRlUa6CNFCV`DuZ zYYJ;b#=o4@&%$egIPy9_tszVb5f9>+{%*S-*02piSG|BPX7ZfE{oJ`44?%dctpcFW zi{oIc4B#ei;duH;&5PxjO??2ScT=NNrWy_b+h&+a`R%x{2KwfZ1|;POobvi}x73d$ zG}h?lw8j&VgY|1*f2XZ4N<`{K7MBeNTloJKY8+!r1wfw{1hBn009OFy!DLeG9jOT` z9F!ycQW2q~F$xqYsA#r|3KUSyzK!?~UkHwij`^NBQjUrgz{< zZH(J$Xx7l~oZT82qfr|TZ8T~>Z)()q9cz2OHnrPod(O>O+ReMI(eAzcON*`8uXUZB z?|Rj`b_rWRr#61pbMn!hvn>E>D*)L7pzpxo?&U`STMY#IkGo%}w_bXwSQV?usKmib zZPBTxLc^}(nLw?9H1xvI91tvk*^(R0l{M6<9qV97EA7X1rsXtQw)f&6|G$zp^wr}pWVU6CQ~?Rp6?MYRz~*@CFV zHdLAzhLo+t$ZTsJ5JUO7rd+%I-fSB;2D$U>yE!#B6$*cIc+ZcrpUJ%pOu9CD?Szo# z0QT__fD_EOr~f|>Okk@F;OBb_`uhK#lvgHZIvLY@KOE1Yl)_j|Q7DH1qODQ|6jZ|u z6pHTsW}Uny+_!7PV}L;1q6Dyt=3RRargn{EOwE?%u@UE6rsJ>g1l=s^?1)AiP1-VZ zP`SwN+t6g6#%x@}6622zntkn#wE+w>w2^ZR&4AW`W^Rs+cGqiyF$6XQHn1=4j|tEO z7y@Ym8G_OTWfY7tcFxU{U!!~Wn|ml29bI3yTcs6PTV@zmdD+5CjwK#q5BHk@pmX~F zpQpgV?Jw0#ktd7YpLKn zRCo-H8R+~4Kwek`Fuz~Z!^w;eN`)Vfmhbq`bdyUTCkb7{`1LapyrbOgwHz$TFpB7W z^x$yjy*XYJ6SMq0+|A4wcy>Zfa#?bfd$g@{JPq?A&&*{A)lfdMLTN>JjcP=UjO5+?@b&a+r! z+`REbC+7he1+cIg8PR4~NOR*piD^`F)t(o*#*Ny2T@{0xk-Yna`>yN;a>VpzO~`{Rs*KOBQ30z%XYU_eD^8otdimZaKOY>M=(IN3_qBhA?)V&;dBKHD@cDG|Hqb^e zM?lM)YroN%&t#H0t#$f6G+Zva-zMKr?lLd10W*Y0{!Y`jDVLXm0lc}LhlnslajdL0)!fb@oDcoI{$}Tb<9^CODX^uhqEg` z*L{!XaD(^TXui4Es`I+lY5(Tr{p>-t@%nIXm3yO8-m7YFcDm1Sn)j9WA(t(#QG>9= z7$>MOLy0Bsp?*=M|5h1*WCFO3;uj|<7Zu8%FqD~q%;GBH>Qnw}9|xN=U5i~`yN&C6 z@A>$AZ*ifY?E=RU7z&I%Xq=$NE6})W(|=zS>A!Ub5HNvzAow`I>(5c}*xeW4SHFv4 z0KgS6K5Uc+S7YYIA^r7#P4XhB1tR0Ssdp!x$LAForRVfdLF-7{jZ zYmA-6dB=Y<^SlH_!X(vJ4Ivc6l{H`O*!cFM$|R{tlSEr5Hi;>_ zIm)HJ%3WW$`@wyWzV+Hw54?hjD*;#_NJ46z8d1_kNrkH%rfTzg|M(uYrnm}W6|Um| zQ1D8uUOmM2>u-1@oC*Hsg8(>Jq{4#HL`gt9>;Qs+V!wKOVxKxaeVU}wMUWxuDr_RS ze#18Y?#0g&HN(IEAmUdAz(SP7)Y=PF{W+|)n)@i8bi4i2q8GKII^x4E|M@nL&r!X@Nfyem~Zd<4#2l2m*CM? zrZ`>=S?b0pAgc}UJaX+-0p#U7g4k2c=R2IvTx3*DkR)1;&Ye_oF`=3I__|9w_Q~aY zIdEz}X)^`*%-2WYjatA`QQ@^6re-bgY0LJ{T|F|F16YF%yXg8n{>&ud%p@l>lh@3( zPT>kkBW_UDb(Ycw%BH+@^hJoV13jMw)h53N_2}%Q#XWL3cG6%+@EZ)j=JVS4=HMZu(Yq zx^i!6U1|La^3R`NI$~Qz!2H|@q&8)8@dR(4`64G~|A}?k)2#ANG8JFkp)wB01glbt zD#0Q-F!>Xx0P{>cS#WcT`L51o4g}r7yL#8PYcZ4a36%#n<;0lWef{?RKR*RR2pVXP zwPFs;2wtC&%=%M8dQB&`3(SUNoNOQCc32Rn&%%41JHfrDjX!BRaUskpG| zl*rxwD^6F2E(6JSR;yuT?D1apEC}LmB_a-~YrVfYCE8b{#km!eQ@s|585l()T{^D%)xL*3P}_ zB(J;QOisSL^W({x4dZ*&mmX~kw%7@4la$mJ?6`0;!3q;RHu&fEkE-L-gmVTNrX-z^ zOr?nG%OkT2)7MA;brSJ~vH0ZCW5x8HdlLY0_*jh}9GD{OdCZ@?xNZO8_|WX+1ikr~ z%>%vc-V@N(F4o>`hM)Mj$`8-bUjY=H_l;^l#pJU4Syj6*MO+6@8Avs8J)}6?k11ww zGcM$cFrZjI1SfuD@44+2@0z{4Zo(-J_G2p$SXi*NKW?io1Dl2@JBACbfKGA>2!Xf# zjUS#NoK88hxF`l!d8>mL&rVc6Go%)0Q!*um^aSx@gbZS&XV6Nb9EYH%L~%$U9jFP| z_QP9;e|qz-=kK`h%}+WH|JiGpf+7hut@YR5(=5a|jzl^sCngr4umVyA(Q6OSr4XiV zmdA3f`3~d3Ouy=UYYA0Pv8GG1et`9T4ijBVK`2DV!Ou8seYeK3Jp#{_Xi`Qhc|P^X z=3jgE;kR8!Y+OzzpW*d?{)rqK{^h*R7Kx=~UU!Lu0t_Tzmc#V%C)Y^mx`Jbgy%1~( zZ}RT+#ysoVIM8W4tK`6B^2RNk>cfdE%OcR$jG59a zBW@cU?XY|cN!CHHJG<^&>Z#BzU~Nisse|p$LbnVT9E0tNPDc=n9x`1_Zk;|{G#zxe z2}&^?$8z;8xf>?i7TY#BgBc>PK#z{>v)`{iw00<`y-@pESCH>_=e%Z0ZgUAIcl-^~ zLWb_fkNtzXroggQWy)bfbf!#jcn;1^Lohk>^sakscj~X1sZFx>+6<@SUA!i6>Wbn3j@bVyMk#*(wvRk+5+09RDPaV^{ui$mHeMHW zW=x08uD9WtnLQgGZ$AM80;>&X7VL9&&C33jb#W)sY4BT4YH2rO`UdkDS5e4W!qM8Z zXZC*V>Hy#Pm;2tgoMY5Kj7c0W6mERz&4WkCk|nb;=DD|?rQ}&kL5@Hg{Bmf!$2saO zSCsEDPS(wAYbO>+aSItjA#u?#(R%Kx>b&nYv_LHpRHGD!lrYuDl8LjU@iY)Vk%|ESOIQ)+>A@%qobKUbuiga~C z)Jdp@5$z?P@!1aDmPPB82=5~#jRwjsVKaHK4(ajlAvz&egY5m8QGzZ+ zSP4Wx9!UAzWi^mm&8hY&UcT@YISRyRu3H;y%67X5C!)tKA+(|uMF=5~NQ?nvAW5K< zONi_gSsf6iDQOHKNVNsUC3k@kP0WA%PXMWe!=`dCcWmwFuB`(cYWy%~op~=`N+|Yd zDm@;VoW}JGN`+_}BGQORcZt#tQQ9UBV@zrh8b|hqLaKh3xmKG6KcL$7x!CXt z{SdQc(Qbli*-QOxfI0`h^5j=8Z$n`P?uzt!F+?aF5|+5)+~^>nutBln zeurMKz}N1sKd!#qc)=#bq$FgpHjCwDVL5CO2&}OJBZUw)LLq5dWttY@3P`O4AuU#5 ikq9ITmx!?|0sJQ;oKpk=l!K=L0000usR8?Q^o|!i@n$e7Agl=@i+Q{ONI3y5j6pLX^U~Jirwap$V!e|M+Ylqjn z$Y6{Y$L_)kV_0J&3B&|CkN^pE-$EClkwzNLeZDvIu6}(~RaaGJ{`^PJ3TZ8k1SrB8 z@$2m9uFC#?@~Hgf@7GF1_+^Xp6$|MC2oz zs`0URf9#k3%~vbxcmM);UoqcXWU;q^07@y82o)X#Mw_j-7lZQu#F0IyMJpAwpupob zA%rrBR{f>}QW~WV0%#P7fYJ>6LV;3*5NJkq-gE9H{Lx4L z-79Le$E71s1xH?{^ol-8E40%1;K-{!K{Q6&E3SX|+nXb$H`n3@F$Sz5CP5pEQJPq3 zlBiC-mGIgBd{s0!T7YI~>LoRRIrd(LwH-B_*xdN48jlMAntD`c)2hvETD2K~tjgK9 zxQ{VCiB*cjONV|V^?jxqE5U+C5h;yQ0un%ApaRq5!T#acDIudr|ET* zGe@?P*g9G%X1jYnaI`$is(2-t^s!j1vXmICSP)p%s`JGDCrIaW@O=3VRsZ?{6e=iO zRZ_T=;43m;*caNnE-1wOM}o7_XYbN=$41!|*~*l2Fq)>T@gyLlA(DIb`eK6$$F@Qpiq&42k{xBvP8Ru6|*>jK9TMOb7$oip>*!E-D*PC2|3hz!U= zPUIFk{`CR8_jFyKqoK_a)#oT(GJn+e`%Bi;AV`6yAW#rwK;|gnbB^froXoe;THzT`NpZ{u1PYuk*|oF>0cZk_yZ-T2;%l{p`*x@5 zzCA^)5vxlht8X5ynR6HOKw5ZeHBDqSaS(RJH7>ej^S`=#U+)&ly{oVSAnVw5Mr4Lx|!6+~mqoM3o%$&G_3*WZ>wtM#UR=wwnpS*Gh9}mFQ zDh{mZaPLB&r@MiOl=tTu(;Ln>V{y@w=6&W}o4)f@rNS4A2u13`(5p1Z8mf3~+uG~2 zP343r=ub7`=o5rs7dnn0f(1MpWeo%mDk8FQXrW^4t()vw^Zh;dKRZ8u(d7@i`>%b+ zD+BZknD0Rn!FUZC35>G}_xX==Me=dJ_>L2qGHbamf5N`C|1%p!g~nbEEbV1^DJ>#(aoc)z0^!J4S~mH>zy}snj}<{{zzaSEY!rb~ zD6LRRF(QubOEGWx(3_j{2Oj+1!v~AY7&_W778QJ8VXniWL-Pm@QHtB|og<1y7-B*Cp!{Jn*g+rM!4e>{I> z<8u#QfAKE>M1%uJ3U0f5mRsS&jqgX;cRoWRur;gjh16ot#gfZ)kzE=altNW_lnCO7 z!bJiya1a7^-8foDLx3bk*CI@kP#UPMfis>yEVqC4i8sA%cZ}Bt_kRDq*wyPdu<^|+2%`m2Yc9{G7$Ci!-Uih=m?Sxw&TVk@QsX4`yOO+lUH521w`iqNQeR*)k zq}_^02_g`NFMu#Sj|&nUBnGcN%0wuoQCg#o2CYCt;^DvnNIrO0ym5cJ?SVV@pA3lY zEYEXvZjPDufGE~%I`abi{ip8Jc5IZncAzK&bz^y9zRSY?6h_A&?Sh{K_TJt|0HyIx zu_N~Updsl5Cz_ho~YjtcLC2@tSW;@XiOXuLJm{Z>UPH7~# zS_7{##+7B?Tn1xxXgHYnpfxOQ-SVy7kMpHFbCy#_uT+c|NR&|OdO!~ZjiDZSOx!gZ@^;ouB&|e+K=?9)k18pI&o=?PW|i4Xv8cTnV-hM|RKB|M6jAc`hJx2DSXKghT%J zg&R0Bmm!0Se%@yxTE?~&Kkwa2t5$JF^QT~!(OLtjMx>@X6=%nhW2RGKr9?+DA-0&{ zaNe+P8lGQN&%ZA9fQ>)%r|4~@@~cm5vm@eLO`s>jBDD5x}H2MUN^wW&`|^kT3Zq?YnsCI*wut?{DD>#BgV>-PAWIt;Va%EUw*X-Zde(-gxe>p%v>5O{g0P7ojm|ojP zuvip#K41S&Q8UM@44h)THO`HXewmHygmJ5BYfDW9v>m(Vk>1VgLT_U)1fXR8Q?kje6Q+L9eK( zku_6^I@&H%U%6B@6Q!)N80DSSAsP7br5$1asV8lG)yMO30Tj>_SXF9V&oYrlXfgaC zN=%&WF-eHgCNP~$a_gSIV#8|9gih${l1f_=9mt%b6SWE7lKFqT^-jLQI{}aR(0)BT zS=bYrw)gW{zgLdAq23se!UU~CJP2!Qrun(@{C~!IpR}l^A$~Bz>WGuppTxD-Uh|3o ze<#Hh$mz1^50m>I7R{j-=FZ$!`_Z#A=?v@Z8yIh{<$phY6_bs%NJuDLO6dZH^W=k! z(n|6E<_B9JzT{8BcKs86OZ~RG?nz^=e=eMEjQ_)<^I`jejx&s4lV(Jen8-)LPuH|< z?O6EIu6+GMR*mR(r!7nZcL7gQiF@Uw$p4cg%jt3`-^P5t7p(%T8*je#8@oPr*|a2NZ25lnWY01kZJ=Lel!d2ofifuC%gc;4*UC9l7csx*u;h8B^kgorcoL`Ht5&br zB+u?Ss>(bSg;o8kFNH4Y=eepnvvhWD5m|E5u8=hEDIzopJ9&uHr1Q$jycegC6GuBe z%AUoiIMjWPSj7Z!sCD+;PI`EoJ9XY_d<}~614Y3#$T6;|Ck&%SC&QA69`Df^L zMHQtG_A3>Z71}>Th-*r9mO+gwu{AV7iLQfa^uioIZL4956KDZ3u#0;>^8Sy!YEJ4! z0HZ98R*msSOs6V|RK?sji5BesTC3)%Czb{G98>j}M7PK*hcOm?EP?_V zwj5be&{?4=s)!=1)2gNmxYJQPv_?ihpzX86{YXSTeW{+BLd z!8$`!LL)EHI-&Na&Z)EALuRzuB1A$^3yhly#A}oW69-g2ykA5J!Q&$cp`w(EQas)} zs-i>J&yy7eY7p>2feTP5#Dnw0`(Mml4h4atqGIc-s^?|ui?EzDNF1~)8<$Xqp+Ez8 z83uaPON?V66>U8I*97ngZ5DV&?&2Y?BThzeQt}UK6Tdkg3^fx_TCg&P3Xp|}mQiG3 zz-aIc^VEuvL4ib*w`?Lg_4Re=~$FNCKUtkS@w=aU(oGUbOwETJlo$*%(l(NEnjCq!Qj%IK~hkp6$6)( z7bQWL6rm&-Pjyp;oA-zjf)k_y9fqBu3xkOi##l^ZiI*%ksgcwpA`?@O5|Ua>QmfNQ y5^D82Nv%%3(V&sks3&!jM$8}l!6#lzKmQl$*pot}gE}?<0000% zd9>wMRp&qZoZoQoefQos)I6msmC78*AVk8HkQO5qw%4iajR6>%fN~PxU)vGtZJN<@p&h9^cuQCB4mX-de&s%4m z``)|v{`U8~_u1#1z4sAS<^Sgvy&PYfl><}-2q=rALI?_~)n8Q!fQCSj0KuRH1SLsQ zb{yORqFj3BkG~uuKGR+n0#HRnI52f^xwX-|jYQsv2EiH$1O-74Pyi&5k|mZ z5j9|hNQEGZh($%Q7*>od<`aN$wz8AJrPCy6&k-+w2PfM2d zUO$)56WbUOFd`se5UdD@K~XS(DlP_ZWr)0~imhXk_loQ}Wj#`Uz<=A+4 zVq>@L(Ts;c3|>8vL>O7L02~H`2?m1!6-LrFPmOP9`y-Eaf!R|n-wWF*C!h=gf+yF( ztB!S!rKOgXTB0acEnYkk5neoIaVi)!2!a8UbQ%A6`#<5Q^v+-ZnO_a3TD}*yQ%*qU z2B-*wa`2|33*)#@QUv!5a4Qy%$6_n(%cAxJG}0Ca=Z>*;>sHA4=I1{Dg;Oow_q9_- zK+wS6nY~!5^?YV9{~xCMlNhRL;l(@y+)4%h1PP*o1Yy;1gU{dlWkTOW&Noh#Y%kVM zodpPsrf#@r?|rSwZ2G(fKgUqiMnksf@uLc~7_2T@z#;)@Qsa1ck_Wfm2P5Rj%Rm3& z6cS)iT*%3TW#IZ}k1rf)6d@-KIbLiv|M8Xc3(tZ#YLF0E(pt`Up12v8c}UoG`NdcG z=RF_$y*Od?M$T9bN9)-Qj`# z8K_491v*)fpKT?2!!>9BnoLw* z2Bj8w_0K|IocmTQ5+YKZFW9nkO9fu=4A^(cFC6Ca-P@3*HCS0gm(+<;OJX6m28^*m z)ezLTYEk&s?#>B5{@)N_jIest^1&;c{MMDrxn;K{sAcof&W6eUWLv!>L=IKKtEW^` zxxhu>RxO~6rYYNxZ>Q{)&;)Wi6u7PbycSr?SDsklukV>AHGm3F9v+AW>NaAj5jnqC z6xSNDpLyLmjlVq^94AeHbFk~U@|8ylKD~FG3zi*2T+9W_`&TU#(}bwRQ&71_LDk^Y zV4tIX6AS^kfA77J0uA5*H=MupT&4%`sXLBxD~MWD zEgA$3La9QemFKs?(oX73=^5_GH^P@B6$Yr%SyZ6%QO39qe3182^9$q-{A4Xk3dXi0Xa&K`!2jras8vz8VS}2 zyC*Xfj9Jz&Tu`e1d9y9Au8ZaHY)+_q?m1?-^3v1NZ*SiF#DmAPa{&Kh@;|qklOaHW zRt>J)Wcm1&@Q#fIZ#yevp;ip{ve~vuAm9j;1WLRXcs(%|WZK6|V7zyXLBCs>z5x~} zXplFoqmkA)ve1`((}j&=NDzCl2>%Ub=}3&yH`rZ=yeTAQ$02gBV#^9QD?(5aqI=;pD#9p2d z5aTH*>G%%4FvmhUPdA@pzL;UIKSQ4NI5;@??5b^m0pPfyc;gN+BEyZEy~s=XshTyv zy>?{CY#aA1WPzbbtKg~+NNf-sVgxLVS;y@Ml}$f)v0XkA9lZN+Ke_4y54DugP=t)kN3>?U^lZTUfXAZ~ zxTt+juk6ZLU5{RxtNrVdq1qWWiFsn8M=g}pBU8DzLeV6JC;}Cbsv9HJe9k@D5O4m) z3x{s}-;dnB3cSvweNklHzZaQ(%KRoiH3EF zUBZwVlSVQuL+Ox~E|1F<}BAK<-bYG#JLd-pRpeT)!L-6qY3<@6hd zBuadfNHoesf`+TO5NGwPkA&JGr7D-|xHgwX2^UoCGuRf{w-g)G* zw_P&&;Me}_(ibNnD9p?Tp5C1^GwJXO?fPcfc)^?R95&MPb?e1>6LKwyj46vgopQiP ze?@-JeKSR8A)B3@?#skfcj=DD7Ov~Q?@u?ISwmd6G<`&HkcE{DU;H_82lvnB#)>3T z$mv?}As-grzswfq*dS13fk*-pLZ$hjs1K+KFxMwqG7Q5hA`vFB&yXN-Oqy6+5;L2? z<;w#HK6`(*ZGU(9yU$+)|LJ`IkIlnZpMt$}U`$~1zAjSs zB1~8wAs2@bt~ORLYezAY{eaUz8kFD{wZ91d#OV7u$;zde1SGadasqsW#1STmFtH_w zFlfS6I5vO!?p?=c{CV!yH@oK&@Vr%^7AvXEA!KBl(e(ok%}iW2GgGquytS-9YZpZGAp++YC=n%wTnnE&HcX z9mFO!rzc5tdBFa!S{z@NCMm}XgApYG!gIIiCtk-2PKhu`ooAdMB0%K>#8khlse-KW z3~Wgv-t@~Cof&Cy-3R~Vk>^=}0SEym=aiei>-gN38h0LC#rC6yoktUT+Pj7&ZH8Bk zB8`~laE+mnVI++iTiIf=R}ew~Sq9ieK}S5+?YU(JZroom(lWFfmMw=0L8P8obCv}2 z(^)CkHB&jwC&FwINYpBJapF^L)@kakcXI31131U z3)EY6w%ol3bO>4k-4fJ6ZL~-CsdB6aCRo~5*nBu6Nu(Kv==^p&yaSQ{ywLYizkoq6 zkO<&I)fFf!tf*pvQUEdFOC)WAmS9W;UKJyXI3N-zg0jkh112bNkN&?+chZq>1$;`LLgQ=}*QVO^z#sm+}&{|UC=pc|! zcVStpIv>}8zCd^4<_ljrrk}VEQj{zxHDibBPA?j&^SklB`L`XIULnP+ln@Jv1(TNe z%pj$Q2y8MSAj}-@V!MGxVu(VZ$iNOS0!I)5Z6+M6)sZp7x~7uUh2Q`MFCY$54?8Wq z{mMST~;k?(2q)jdW;BV z6j;%;-1pEFG}=%%P-GBdsJ9`X_~OUDdlR3!bwG@A|F{<|S(0~HwR4+ZRX*7kS$C9H zHUoV{B%r}pW}BA;D-@w1Jai#%|IjdZMe}5Hinj`>K;1$aAdX05!+|-+ukN~=;|qaX z;+2e!T3lJB+EpypdrBkp7E1QE`n>as)$zUe9yb6{Ucjz>!Z+@)+E>g^h{_CbfUpqdV`v`sX(E z0iq;vjIPaC`eReHnPKu+iAe%s^Cj|hXWvy}tc@SBlrut5L#ctK^(Idqn1Nay;t0G# zqR=iO8THIPK6uyled>V_o(zSmA9qSwn9AV?(K3Jrik?c;b7wTx zre^3jVQwxkK2g$a81NpV1g{_>SQF@r;f%D;TR*-3Q>U$H-WrWq!5B3X#3Z0TD5~N^ zkjaHYfBB*%+7$TsM=z?Jpf4l(Gj)2iOBf6q1XmIwL0|PKPaj@qYs-{Qza))4rE^FP zoVVojz|uCj9DH>wB~74UCz|OeuWWGRqd9Z4B^NZI7Ho)32ohC!z~F>XZEX+}6sP2> zJg{ew4y}kb9{2tyRy!ld7aSo3jIorZCvKZ+H)sU4hCGj0pE&l-6`!A{!;OK$t{@|0>aOFtO2j4l$i!}uvIF#{;yQisHiwglUj5da(d2k{> z`=U)P_D&QSV~AY9i$&73a(+g@8hq?XixPh@f9mi*UH+oa`#~*wWCv{C2KV+Yos9-w zFQ~$vZ>;_l4?c+|Z3gpQ806q$#&r%IbihXy@H9YOzzL+WqRE&3;&*=jB|TgNh>wUx zNUU(z{#?{BoC>4PnROdiMclDHC$fetl-Sr{Q;%u{PSIM8W~s;^D|MpxlEYxnBVf1< z^kLyHWiW9N35UrC1$^a-_YM8zD>-vDoR`7|lu?1SgoAzM@Qmm2hkI=Q?iB1j2EGG3 zX9NDOg}=FJHQ#w`JD0R#k~E3n^}wzmMj}(#p{<5w8Mq=1Jp4jK>Sc0>w z#k!;s!GVq^iWQS9Br$=i*n$LH-LeGF15b6ft!~FB72S=BU4Kb_@6EXTp2nSaHsLq_ z7?M}ONB-6KzP-gfHhLP5%}ptJfH0>>L-3{IcPr95B*yL*m`CJ%(e@X9@elr3E^8mK zjdM5Y&cpj{etceMqmD^3BR+EBsq%p6_RNg!S)uFR(Q>a&#oGu%EU3dqDfQgB)0Wo7 z1n(*ORRqWfkJRhc`QLyELPsMu`33gw?|i0w>}O8~KaqXy?_rYPLthDUB*3>1!sHeh z3?~dGq1ORZgHpk^AS$5T&Bz6pn&XfD+HJx3H%Tx@y_PG3_)l0#KW^p6I4fl4Z})$) zNRv_N4l?Ek3+e`CST19s?DUwKJFc@g@A%y}U7??A)T=#tAq)>&8J)|+=^Mr(j&uUf z3ss2KP>U@DkJyOF8dMx@b?CnCKb;hMAiDQ6f5^Sxypuya4lpFVF(qE`XNN> z1fL+*(QMD~{`bBGS1jY&Prf^R$$#`sU-_5Y%^AZNt&2=dYU_|k_VTrtbIqMs^XPYX z)$KAc)fom@+}fAbi>Q@8edb!BnM8c?(FI~dBZ*COqT@Dg9JB13E=eNL(qm(T8dKF7 z8NnwO>y=twdJ5^DGy(7Z&|mQ0553g4AEf8znaVn-3GpreGGSi7G$c4{OxVN7A!$cW{^Lpf0d zl!8rT#F*-kgpfy;wgw*EJ<~sJG(9N?2tObs=1~@W!M@HB9-i94gA-43Xl@GcJT;Rt zWG$t0{O#*TuI_MzCCv-S+!T?C$O`5Bb?5NK@BIzV1y&6WQw9%2q$XgzAaTGTn1<{t z4*5ZnKv5bLjD_J~Sk!Dv8?U=v%F z--;o|Fc&O!JmFCPizki#2N7_hIpgRKJ7$Ix2D$|An>4JUPRvK{$ar{aUm_+YCc~M4 zXvW$lui&l&H_){uo7yYL%RnlY$Sb8^1n(*WoR(WgR(y=08P*sgXxFR^_e#ITp`TDnQVfOe^69zujb>=s zzpKRMc?1Mi`bEb0)FitP?q%=({mjhGQg0=!*|d!HXRahj$$2aN-%mV!kTcBr zmSia9{v-d$sOlCHI&8;+AVyzD+)!|Fg`-^BR_@b{FQ2&ZE2w z;YO4@Uc7AP`2`XRE+|D&FhA(hDZ4ldlGxI!H4$LYxY;~*be+HH(68~TC2yr)^f`Ov z72LY-A2=E&Sdk1fC<878oL5R0D7~j}fnMps3vXEQmg6fL8(k>8T^iRz;g{fSEqZEh zVDP-9S4>+r#uQcEr4te6ig`x7#=@KM5&8$T*Cn16rcN(ROcNJv(zPjWk6ShQ<;m ziX%*MkTtE91Six)D7|2fR+=|e00SV$am$f^SU#O8VW7r33Jc8ts8We%2nazb@-E}Yce8u{ z!|d7fD6^9j1Rt45uVCC`^GnvE)fu zbgGMCYE@KY+B!bqthuvetN& zQZE;Ku}H#+@@fYh=DLf|zvM-yz%v9GBh>0GPG5g9YuB&ktjo{fC_9+vI2nDc3frzd zBF9ZbH0XW3uB^1A`bKQt)1s5LVhR#0Hu1m$^9%tF|16N62+GO?+@gusoPDQTAH>-A}uDvE=Hp|^~6#*!I?_?r4dpQC_y8w zE=_5b+mAyvM#17dBsQSFhYuN!0vkEJ210PCH&wXJ3E~8CCBgLxEGAE$+ub4}4+sv& zwiiYJLIPs3j3z4?O;&Pt>muMG3J&Ac5wxTk&WUd7+`+2RHZAKBO6K%9BX$W&gpn%z ze8THjnqLGTs%aL2;)CKtAo4mAmX*buNbV12-vfH6h2 zlv)<&^&+D`Nb}}7|2B&cKEO9FIO~ERxk*|~j0o+t&1+V@me;I0mk+-F^*qf39OVG2 zB{hlpl|Q{ff}Q!rrDQadHjX}tl%$g2gCPn+=>sA{E|5HkE$Yw?-cb6COse`os~JTINKk~VDwIsXd&OIW z!(f9DFK(?(WU#(UF^Kn+0+A_bNW^?pR)8$k96w7H@B$m6Me9#(vl8a7|~pR z-#)4%q@cj4J{Km)Lv33ee9VJ4koFLQ*6c9CV zQHQ({$VUdu6X=CNDJ5B{%#}i(7Yss9&nsoWPrp<;Mb4ls>6U?hKA@isn9B>Ye#V>| zu+Vc9F2`jh&Uwm#BNQcN-&J$H05TSH;fq%A7`L3e@tl`*;VMEQ&SN$_bs86ct6F88)n7ien@z11M9ncwkrKOM(#R5(by6!>H$5;*r{TGXf6!fs(w!O3CrQm;_`1K{k5D(IMGp6%W8YD8Ny#Ozdm&eQFWq&{d`m}Y_)^g4+N0x2m{V1zo3<0D5aM5flg%LL%+Qf zcYbwzZk#88|J-X~pU*8!eE$pp-M<)NM*rfH9!~RNKmh8L(FHOcgFgcB{YUSIzrFX~ zPmGKX+ppsF@I1lSkmeZvf?QsBFWXo)1jtl&rk=qIyx_Wna|hv}9S4G>9(ne8?$((f%18%Z31{PS4actV0fc$y93!GW-jW?P{SNN9T!l z?;TGU2CNJNg?}CboIfMP(DWTc<-TN;G4S#{X64FLNaYGvjf}zb`<{h8kM5a*)zF19 z7{EH_;n<3Irl#fi##zq+keYAqCB4dYdzvRa(-~7c4U*;_%U`1x(0d2`oEvC|3}#;u z)oUXdlomP1VEjO2p?!td87dFKhraevKwS6=Sp0#aYNSu$iYc+5kKUJe{ZQXDsW@ zpR~d|M*wY=N7DY4;Q+(cLHMs<|NlU>@IV>9dnO)yxyISf0Y(w%S4?-Np{IIK5+&9H zgfrDF(47+KSih0`-U8O|tOHga3&1xVf)L0U2ZQAr?4RBT_dWaoKo#a8hQ`@S{WQ*M z4uIgfHcFyVmj7VnzXNjqN?bte9N3QP-Ed;S{W(1$Hyf2bPH(dmh6gvm-G6sCq%(-{ z0eqWf!dX0)4FO^mpZ1$a`F~xCK$+>xFtyW0Ll^#>{C9wLBEV?thuK?8XgC>0QCtb@w)>uAAkUss6AOzS=1pIE=Wgs~Ykm~_ps6FQZ z*34t^07mZ9tK$On3{DSlpXYi2KHk9aFx>mty^zcxvJa9RK?FF<$MWd_*=g4SstB~} zNd8Az1SPLz*giXPWM2W)1!S-QcR+TsKlcwTes4Jd5xcso<#F97w0h2tDtn_J}Yy8aK?XleZ zmpge>ejbh77f`ea7&*|?C-V`n@#P2a0VsiS^JegO?EO27fW6c>Yt29e>J80a6WVE; z-xEOfqCW?8C+CYY-f;#RMYdn`1JL)#pHLeZgC}2n3}*Js01V-WDWC9dr~ts3i-9f6 zSUxjQpGIp)KnVeQBisL34+0q=OwwHTGj-d)qU_HBzepb_?iblV`4mDGfbaS6#YgS| z_W04(M)~ialDH(9xaKcGH0lwjhu<&30#*^^?EfQN08H0z|M{ehzrc{%I6h z|AO}p0ZK#g+{8{exN9Gp0r@RFi!(QWHamdaSUx{M^3wYO2!KTG2_)CW5Qj6-3?Cx} zlmME``~vWc{(vGEaN=OGSjf48^$pa*GW@Rx{sy#fXNy>V2KV9qKLGGABLW1>8(-SN zz)n*Tp13JWBAAco%`waVmjb?{_9EbO>euox5zsdU6%2#}uy5`F?AWmrSl-hh`R^eD zNa$<)XE7=)pA{fagB74@{!`!A{&htCk&3_<-3T@ZkZV$5rsM4&Vl|<(K|$$swn*jrjlNbI~kY9>@(A1bHaj z%jTWZxxJsWe%+7!(Rqu#eSOVeLB+4aY;yv(?cRoR0Q!j?3iczjn?*GcI12DG0+`Y5 zbj_p-dFmHC((nk-`i4}AYNI#DnLEb)>p(1Xlh6GXWxPWI_WQ%asGp;J&IrO2s?`Db z`yYQ3R5vr8KVtI)@C402A7Vxbm+IxlStt&cPY0L|L4*o=Ne4pfmR;6?liM4Nk)p-* z2`YUZw*LwAnMuT4%Jv7jK)G}KE*`MJ+ee6^D4w7o@O@~s8}P&nj~Urdvy|D*hlea8 zoOQrnYAhcDyb!>z{N^vhSGIit_BHlFC`-$Fqa=qBh?MYmL$lX_G>bWh&tzgbwXKl! zQIP!$kU$q)zoO6j-FxCHL*)T@?8V0+?PP}iD?3x<{nv0m?=PnQvve$9EC9{G4fXTk z^%wpU{QuAV7wD!Gm|3RF6I=qc%DeGuCFB+Jag#NF4{u*sLCnGdAO|k_1|0AgMEP_< z?klmt4?y1!QNSlz3J>po7;;yylk*Cu@Z;V5egw`+mcMu`8v=k$ve-~M2L_(|Wq9t@ z9|yk@Bf$wP&tC<#()BPmc^`y9eaT9q6Bz`Y zOmQ~u4JuQ}UFIoOhm&!%wg|wPyJnw6LTXWixr75WQM@Q{0bLCKP>lfYc^N#m|8WC+ zr_c6r>p{l3r4+!kbSygp&>$1}?SsDwKiWPE-#_peRD;?P&OAB~?awM?@Eg zA1w&~p5-PWjh6%gs7kC>_2HdYy#s!{?;+694EXXSbEnDqQz=6#U{q*%O($(3u+aV& zo&jF5)b(haz4(0z=-uL_WcD9d~ z1OaGtkVrR;UJ4(4-5x^)5?5uI;8B*7ps-A!qx*N?`x` zT*RpiCm^?;f<>~wAO`3hUzUN&%Nor&!~Qk&IRO1!3QyqsSw;@`lMVsSVnle!5WtOV z*53p-Zn+h{ci`(#7Ue?1jG006zA&41*O_)S;WbYJT75U5E+Jw>01(bAW2v0Ks2LfI zx?x^b&KbG|nz>8Et-geLm4CkLOG906$j*44iO z-3R^?bUQ65`M&kUEg~ROlbzS)5!Gqw!~W4RXskKk3$?mFRtd`g*nUUmEZ@90sHCkG z0M@K?2%+q66cNCQfdB>mOgsZP@h0QP6?r;ezj=Ka=%)v9J7As+ID{ z15bRPfjK!h39WX-&n1+7CKFBMjdEy)YXh)xY$Iez2Jg7*T~Mx8^#}gT2d;#3^fRXe zHm3yvD&Y{kckiL(}XsB|aokyHlP^-uv+6pj

7r+N+}0biGZpSf3yRH)djA6w4}tru>(7~XQ{Tj9?? z^FMkzRv!Gq>43~>LI4_9t-l4X*>fv=?EC);N&~PkmC8|?1scyg?hltLaLwoz1WI)i zsOX$nMJ)eKe}%pmP;0S>8(0g#iV{^w5_KGbeg5S3^+ITOnlMGhB`)IU?#)>M32evx z2}S^7%u8hg`=FoL`IzqB+kv;g@m&z065Q#`Lz*Nx!n>lBV)aqET!GP5s{qil{m6g# zU3loRA88Q^t(&Juu{doAKo9-?8{Y#X8=iyv_umhp40FOaJ5E|tqzYcYaezuUqqIjEwt_3<&7@z z6mD}U9t0wTh9l&@$WXxUsU6TpXb#m@;4}1~r@E|qQr)7-L$Kzj?O))bNDPKTn4Fn_ zC$>Eb+5>}l-O~e?(}n;v>i!74W#EtCV-H*goot*#0mAGr+c9M3^Llh3^cNO>MX)B3TcZ_tcNnoQb-Z`;o`Qulxf<02=E@hT)6v{y6;k&iA5b-=?lBB+{7^NMSRsaKc)1KCzClUA#!(5Y20{>Cyh`cp91i<3 zhwySP(3k(P2pP;TIdM)1!Frb!2TBK?{oATuTgi8jhn)S!!LX8`M7 zTEM&U(ushhjKn%xMtj%6VDk=$>pP)@@)G9=nm7qD%2Em_^<)@&rSzxhxF?N}Mpl4G zKv3`)5i-jWn1H#NgX;)FNZ=!@Cv6YqFm?AzL*z7czJzu<4+)xRM5W5fh9Uyc7W36GD=fcXSZS4aGyOCy?##q&)})s*!0^AM=b*r zZZ-)Cs97We-otzGNah=%11iA#Qx*wQdKh6i0GqXHVLQ2fXDI?4=KDUT8=Y@M<)+FUi0g4Z#cjS4$7c7y--^NfAJt#02+!vda?1p4%YH7$K5S zGx20S#pV}XA60$Gtm{=<^B~48@B`#3NP*N7G{y7rH!^L-gHlfZ6U|RCV7>=O5Bgkf zsGq{fMEM?Xp5X+xxRl!s`if0L5)Sb3Wa7mLfngrgKybpvk~3L_l1= z?q^|g%|ozvX?nFkb#Ug+URUVMvU-u4IG`qN zF*Ej3iUL(@Pq1K(rAV1|laj?*M4AA}0wXn;i3%5SVES>x5R^$2<1j=*oC7~dt;tY= z$0%d~2aXMVGUJE?kRIUsUakZZrAuXd4rWG)RUY1vwC16yL|_g9{}2!$@F@%maI}0- z`Y1w{+->88AKE+d_7N6=vF3rU+8`C z@3icY@Rux7gqBKw3B z7h^;KlMEt-m&7tjGvd&AH;7dU1ClyUr0^_mJCFVR%=jz^Fd{%0z*FyG3wRR~GEFQM z+r7Z%p<+Q`OqrLmuI430fB@Ov)7xgfz2oikFFG$;tM?0d(f2gu?YR+BG zl}h-DZVzr{IZtKVkY|jO8&?o9BDIT%03WjrFBG!jB=v0-pAtb8SvS&S$s2-zB7>;> zm%JEa)b4wT5S=8^QCD~C^BcF!U$%8T+UkM2B;_;#a__bg%Tn2eFtootkN<^2M~2FD zB304s)4Bw%w7}Tl^h#`>B67#u`bZcrpbIGr$Ie;dwb?GVag}zpOH|sHYXSOwBzx~YoFXY>6b&V;8Hh+HY2!=&$3cS<{PJ6W$Ym%Tb(k74vjbA$tMnh zN#T*~PE|IR&lNzVL07BEg_~AYvTxiedgJ$M)xr;Ngar{|u2-i0y6y*iT((cq_AdaD zi$PlUvlQSsrN8+)aR3hIioP$w0p5B8ERus&P3>lnSVi)5BEhmDz;v^V8hCo$vpXAu z`==r_?_{2@Bkd~znKo&YGbFooO>UpejMJ7PWsg645L)x|(D#iljQg|WH!N>`ai$r! zX7+<>;CT-sbcb-e8qZtYtfZgUXNFqzS#h6kw%F?6IDtW5t)iJ42T?IKmGvHF!QKbH zV!%^I66pY(nS@9)GE`%6F*z}Rd_Q_A7;oh%cny~g0a{TT^{wp6sa6U>$v9bToer1` zoPOe#;Iu4l95rBFqqLj~Qp@a27lBVt6&~f+*k$%~W3JtT-X`4tE5ty&^0#**6g~;C z`6)Q5YIVmIT;?yp@l#_2O@eSOsNi#W++HRJx$R=g)Nc1P>jI`?RPqB*ox`p$D!Zulf(w_s#8TRS1h)sxagFyV z&$q4aH`(SEL5Sis}jb&v1WQcy#$pz{Bh4{ zysix^D4Pk)nVu#$j$^x&7-2H@J(QD;W&|^{D7nJ`tiis-uTgNvYvE_x0J=zIV|eT? z`x*Y|BtqpY_|coci2zCukKU!Q_LB22`rTjn*&QC!`tUt7} z+`j6^M$yfNSj5z-tPD07%x7Tn_qiRQIe z{tPWR<=57Q?=Hm>#;3=T8Cc*GQ%s_o-c6h?5$~kXzFbtLJn^N$U$`yjmD_7Fjd2 z2DwUytBk3IE?FjNX10V=z-T{Z-v`Gq@Lt!9u7&B|A(-pT!q43L2F_aU_PTukrdP4Z zQ_E?ekCS_hUNckMz&5vSeo?Q~po-h((Jk;l{^GyGgO5GXU8<4OvLJx2DnE|()zkAC zWjO+cx^vB6_j~pVn+FHX89c-KX&)!B9mS|f#>SOcT!D<(c##vB6+E6tY?>kO4^?FJ zdA+rx==(p$>ug12ziR)&1WTN=s2Azaf8&3{1-EPg`3eoaas(@?qcB_++omnaVuJvM%^?AKABmzf z@>eE^2;~&UHm-uza;;f*j#K2k!YXK#RBDP~Ij2|@w&HuYQW@S@rBa4(-2Dx>=S%mH z7&F@FawEXoJ~=K1nlRk+;EMT}T%3m5O?fuh-_(3e*a8X8+qDURd<;)KG#zmTFh%d2 z<7B~bNWjS)0_A_H4e>X$NyS-0Q$t*Y&-IL1cOjVKPKzT%aYS8njTz{TcOWgtaIm}| zsiuxdFajgh5vZ33pp1x63PT7P5lS4mq9~&81zhXsSuKYndP*@+$<0ii%rex4=#|>% zCAh`uLL^X>6oJo4eHHfZ-U)m4jsgHhzQ~0GaJ~u}r<5CHkisB_D7;GOBTB7WgGOtP z8Y@C4TDp(pDI>th?pU;ZZ%wnKE{za?foGC243ITz_|l~Pa!5_E;^!H?fNmJsXs4IJ zbR#jqSC)!RJGKIw(MBA2K0V1cP+dIZ3Ou;#$Tvrkp>N}NHhmkvHO>KA;|Rt& zW6+wJg{XwwaUcL{JTcpwhKZ;OgVkZ=3M*i+JOq`j0%00*$8bgf-?0CDK}c**M8Z58GVQFzoHxj~=(2xIT0|*+E(?g@ z_DT1c>&(H<{ktIzGgH;HTnOOm@g`MMdQxtg=_G4YoD?$uj5%$9E~Rz)m|9%^L~?Sc zNdhEfooXQ!avK)k0NMS5uyz?|^>`+b?|b|3q&+M|NkgN2>;+>{$@z=8|LJuA|7a?= z|Ao0VPBZJaB1DKTDxqDxd=DzB%o;hhplhacP)`P6I2nea@-S4=s>vguWDi0BXW1}r z>OL1p5CM{uw6>>_^Lm>4iE64y{f?L$WIISp@#a5Ch4Ix>NqVXhJ0&^+# z_Pem?IE`-7MOs4rBwRY1?W7REC410IP#^K5?)Wt`U4vqqMFB=As1>*v5V%4rCMdF5mhZMlFnSxdYOo_SW%r%b;iqhwRUjCs}US0Qo4`G!<; zKm-|D7xQv*07}xh=;BpkE{fOoQhixZQ3{lqaH0EJKbtAU%18&`gidR|;ISUg$80+@ z>|GUrm?su$@pAa-BJJl>QZHh;P^|(sQ9ms2^%RQ!K0zM&u13nje+8RG6CNeb- zQ`rQ2H);LCny9l^kaN`VRx}|%S2OTASFnWND-rPV*-M7~dz4Fn^TM5biI*SLV5;idCn=@2!T&Im3h_k5=E^ig#ane(&cwH#PDshk~EF{R|H7w?ltMw z$~I!O0U%{7W7yQ!(2meVB8+i4WKaaUEdg_-y`D`V^z_r9O4E=&hi@)}ehyVJw(GVR zaoc}n1W2t<-Qf>SV8`g8#GoiuEvq19Rbn)uQd**%J%OC=B@6<%VamG{Q#~0cv*`?5 z7-3R^A>>kndKgMc8S#~pLNf#KlIXt%Bno^+42NW10SWpDAaWmo1AKn(q$jXwwHZe^ z;R^3t(_H#TR*_E*0T5ubuk1p(LWx)PYMAjFMlYS^SWMX zeMgCNQv|H%xT4>h|EVQq_ss3d)%gB-S z$x2xuxYjTD^A)cQwb>Ogz4s8Bf*H(}8qn-Epc+!y`!EdqBe-9MdbI{CYHQf^3=r@h z0iP(}Gr)J|s9W;@M8BzJj<7Dt##S70k}19hK?t?#IILf_5@x5HFyA=5rT@tx0JmBn zM)@CI(^XK81M-p^V3U)FwS1ci%ea~;tGu8ljT1UI&jPDY{nFaJG_&kKw#PVelFMz0 zCr{w4?1DxMpYG@Foj5I@phN<$4abwi6(E%ng$BbR)NibTj3hUSJj|NZ{h!D~z@m`i zX1Rv40AR%rksFOf*qmMs4n2o9=4FdI$7h!}yO?!o%{dPIoz z9Crv90SZVU7At_}hjaf!jsV&!uE0r_lw;td*xFUv&LQuifkBu*G`Tzo5Op$`uMdPe zO0McEQ`KrZZUD<6mi=V<#YXPC%2>*gk6A00#z*g*KDn%Sa^E@&T+;xy0Q5E};jC4+ zpeg@Nd+RUa_66L&ird_A-#^s~+;siTuyVypP+!cT8+9OxBM!|vKnsUk{VsHUWGEnj z@Qu%%keOlz8%8$3>gz9pom0EvK(@=sUvk9YCh(cjNIRiZ@_RAFO%Gu(7V0^j-Jcb1%slR|(C z-nUPbuNWB3lz)x#4IiSkT9Q2^A3ZitB-kWt{t=4rl#zXQNJduphvMR#R#1<&X zLY$iK^=RkMwGwZ~%8_RjpKX6Khy%5T}1h-!JQ*h@k zZ-M7_Y%d*pcIGf$@Z>y!t7~4Ir0bRRH?z}%OTGh@atia`1(W?r`P$Pbe(xUW{mldS|KVT$ z;m$*o2NX#U&dD2C$mZRqU0~9AkZtiOACnZG(1<*9xoJ0_p4UvuN@Og|uL z5unuHi1JzC3xXUG2nopMf1$MpWru zWkKJw{j2bU`yP><`Oc(`UY|Mw=%KF6{DI36@O9D#2Js;W5oQBrqz1G-N6@rE!hqHI zT-8bjWz=qKe#Xw8Hex5m%4a%g3N~Yyn2Dg#h+zBx%EqY&YTRH1a z{~7d~_ngEKaB#9Y@v%v(hUCEZ78SHQN-IqMQlqDtlTrTrrfs{n-Y831Jzsn>FhD0H zU_Ah3auN7J7~~d!z-^*)5GESqY3u3UAEHUR4KEWcasNkpuEkKwm+{%Z{~#kiZnMjR z0N{_HmLjf!l1bd0M>$B?HiNf&P#dBSkn&UNzd#L=yo9-QN_H}J$jAaTwNj*>5d01~ zS?XvOp%$@v9`(4y_-5xKTSJb*G4uDr&bSHPFN=jfFA_hv1L@^&i9D-`jig*S!*Ih}c?N*RddR=2;}5YN1f%p=7u5d*TSBlp?an+LXZK zcc%0^Vd9v-NiA)^hTC_c9}N`Zm|r_}1ZXz}>^>-wd{GS`y+1?X;xBVWEmvh4uS67^ zwtnR3p|&7BlIvYWO+jmaQZ$BY@+f9$5;$x}28ca_1XL^1q$JVcUg?+8y@&op2jV|* z0tSU_w`R{mE1H7VYzyWiw7FXm^pJ~mr@Iifdl0o^=yp2LL0P&h-o?EFl(m<~E*|4{ zEiwL12;p+%;(HxhHz}~daLmh93l*F^41C80Y=Q|n*ScBcoKvT5P4bgNfbDw}9NO_c zn47KRlLct+TVGQuJfs1wxu!obA)z?X%1?Zy$^vW5qRpauDFDr(+mNz7D0K2hi3FxD7wqEuN1SmQ2~s zl2rCePc)d|Q|p*0AB{k+2qk{^{HzLxN7Mgy_nU8i$LlWns+Mw!-9^fDXwW48w1^QK zs-7o*op=W#5X>~XL@Q~kD`HJ$L;U>A4(Y3MToWZ7WO1+8Yo|Sh*0`tA823^x38pOZ znn-n|k_7QnC7L2>rE&>+QSbW`KOX;AYcESDgatvi2ck&=-NQ&(A@}cwK zo^5{%cR%r`u)4aAe_koDwf11Ek)fY|Z(OIx1lxwDfB?A{Q7k}!A|gl^UF5|s?KOYWYXjGLsvlJ@wl642&rmgS2pMLk!9^WHnp> zY_*Q=Pqcz~KAqpzm~8Y^1wXj#1SbOZR0_6y{zIRKyFPkXzp_{tJc)8q3ipD|hIegf zIUlEy3oJujfPmql(W9PGMF3uM@p`!7H5bFV8#l7gd*X%tP!3nTZYp`f50UkgupO^|5M@ltsba@dP)fJf2DtN8cf#F&a5s#t8tZ?Sy3lMsHA}MdoZ1%!mChO+ z;4m1M2bVlvDwW{6*Iy6+_`UxK)?Bn6+GzE4(C%I@$HYW$U+7ipuYxFspc0rmLg7Mf z3zy~Ac5MJDjotk97ry{yR542QJ!<{JrDrY}WdSctPhf5-#mAFY1`{4|6&wtof&vNDvD8+8f9NEUZDL}3aQS#0yH3cSy_}H z_q`X&Xv(Fn3{nvz#p1-H%$_+gE<-VN?NqiuEU}Z?q&jo0pk2S$aRJUE0$24Czytfg ziwI{riKJHR=T4id$o8$=wfmf^ZkY>n0gf@~3B2r16+HwT*NL1GURdkVv=cb)2>sfvYAQ8BL-Xwq}`YD#WHckKIRs8p)()VH37 zU%mdHLfTVYWcj8yzX3|+3S4}}g>d=X*30&u__o%3Qv`vL{}fj@vfd&=fg=z*FUu-S z#s^?q>v0$f2e`+8pHHkbt=G8wwxxInd?76RcNNKsL({&3?I;BH=}MaR9@I`R~M7}#${Ek_^Bl8AT_24Fps-~EHs2|i8v{SIE!Vp zmw#~Rdl29`RHSLs;4J0$`|ca1&xrt|^tlKxS(zd;d4q^%+fzTA?rg=~Erp+T1A*c9 zB)svL-U6Tfm!GkfK*tyb_OA;FkOMo*76PB%XIY+5%2vejDuD$gpbVljiU3Kk3vc~- z1@C>&Jlt~2Cm~D!*s}GMYXG`>CG1Sz0MvT(ywyW`&!N$Jrjtv_YfKFQC5Qi&?W1RF z00{WJ;4|fkRADxqh8LR8Ksl)L8nUeQD{U#?P&>C{b;_P_naKTmQ+m%xAf!h9;AyXx zM6esb{LtagG%zp-AO7Hn;r;LXt>XheKz~WN0taAC7U)s#PKU^+QZ0OW zE=jzuemCCpuk`^&qTt-xM)_|QLp8{B@ui2mO63oZ8$Ir$jww$Qy>B9Kwrw0*;Ff#OB)7 zTJ6~9zH|s6kZ4MXzt^)RWpp6l^!>qYB@Dym{$|M5rVvnHfSnyb9h9$2se=acyeh?u zY)27cWjVkzv3o8I z>M{aKa}~0W_Z(ya1W5pXWZKYFBLrTI$J!M(GpU?=sRZQ(!$umpGY;PSP<`;Y?(Zc* zfC%s61^6*M2|ut10Zjc|la9i7OLr}-o10-af5FPz#CUMf_p{3NlX;XHkEhqD}T|tz!e`fj8RwCO#5ZL$=n1WQY2*7v^pYT?P z^T{*wN_;}VhFjLdtKRc!xZuVuh{)u1aBIh(z(6i?)n(U+x4-or@TE_G5q9i;o|lcA zXib>9Kbsih@&jm}0$2m}8r17`xZ&cP;a7j^-SAi6{R^=xJ9O;dQ|33R9&p9z$eBX` z)ZbwQR={iUPq5^s&N*hS9{M*@9fWE&%IQwgo~J+srO{ZWrHt0rQ(c^dz!s1?yI#d6;8NuFaG?BkuiAW(MRC9=eBVX$!v2L+Q{j=k^y)z zLrD0xB3UWsl#gut5o}p=AzZlnQvE}CeBreh*StEjrj3`1eHc4;)$!fqaw7maF%BI( z2tWMF_u<<=_cj+TZ|Od)t*T^wR@S8>m5h1tLSIaeGf^GNXxFgxm?93zrR?VVJbTl~Id)YK zwAIa(Tj9pn+yv!wsxXIt1a>Ov3^~$yf=>AmdS89=tDow{yN z=>&y-Me_pZ>d-7c%QSrKiI02bQiW1qTX{O@VkfHuK1wLr5l|}+ER08-P6S921+7C0 z;+>-~y89Z|2k0TmEM2v#2G?FU0vp#=AUTvm*lK~gXbk*W`Oa3U16|pKkPp_&eJvW6a^S_cV(sLxQY8k(>$Cz_0qc!Qjy zh-18)b^nB-*SRxrG4OO@E6$_!{^0dQGT%z@dxuu-UCHx8oRd~M$>!6AMJlx3B8rw- zZwCJK&;ArHy69r~!292S!Z1837gEu$t&wutoo&#ICeXa$1szbS%b+d0Fy(cj5%d^P z;kGPU#6m93k0@Kyfa=7Dqn{Vkhbn`}D&Vm&(<+g}8++V}CB ztD&kXO{=2ozAuL3Q6c?6tJOjWnS?R1T2PBP3QG z-HTlQL%!lBJAu%o%A`w^mYk@Jq8|c8&|kjnH{Nkh?fl!y=|CvA@qt^?_7A7@s09yLO;DIbB@pw=l4E3Z~EQK?>?t;wP|mQmD& zZrp`))~$zm-4XM>c^!2l5%t=-8Ae$&G$+g5x*qHeh~|7tcGk=TzE{u{BJB9OUFyh{ zYK89fQr+y#cv-uv!nmBJlq}m{2GMljBbF4ykMtG#gZKQ+Jtv&ldI|_Ym`1sH{{pvn zp=fK_$ek$#ulUojxjF|M{g`e1AMM*Cq11eZCu)-V?9i&(T3U6{DuJ%>(Z@;O(|a5$ z9wL$~G4)ebgG=dVnQtS0s^I6(tO97nf$CTA@MkEdvl8rXyl~;JnIB&mgKbqyrm63l zwkpgC0`@g%YSzddM0{=}!7gcGx}cJELo1cgy1+5&B{~`;kW(YDGRV8$ zan}h!@RSgMZfghreHQ<|0bheB;4#|-&V;I739p7%s7v6I&Pu2wMc+PjwZ2ar`gPq7 zA<}yx)D@)2)JE>W>H(DbS7RM$M(u%GP~*Cme>-M;{btBID=t9<; zfUasm8)Y4JK#!((d%e=gTuI6L!*icO`#yldO3liD(*%L2xb6?b-p;ddu)7P&DEp1f zFM9s0iKndmcbq_J+j_nKx!I^|huu%jx`2edT&YCmQ>kfa5htdje?-?HeG4hFN8iZ| zlJ*q&EsRe;rV6K2Ed;D%zAh=G(6~82$2ENh=r^Uv3Y)8q$rhb+B#;skO)wMvMO4MU z{7+x`PtrgCI%=z52aZQx+Ll_neON6;lK+mqKTXfP~6`% z9y7MTbNpo1=`XAwz%0k5@Q{VKFDZDGha z!8wR_Ulq+VC;;4%mNP*YA1|hj7tbvoFTOw0Fn)#Sp$Z3(4WCrC>?yR0)zF#m!Tk?D z44?VbC*iYS_@Aaj4?gS-w^rco@4BADykje?aQf6+tH(9{!L_2rXGmfD(0 z(=j|mJ%Jo2-E15xVbwHH%piCDve}m_f6_$yzyjR1P02)`WXMtExy7M8vwknX^^C>A zhqXy3gJ&1eJ z?KBffHUR@+87awR0h?~3fI2-DA|&!-|w4!ChiZ5!o14n;7bz#vQ45GxTddQ z-c-Q>mpOs7{q^v7jZr6<3%Ps(L-~damRnOJOSngY;I=xq%5S`BLR6SWPv5V zb2Rx+_if@;55XiPU;N82on8b0dvB9|4Ze24Al!Ry#u_-ahFO_3;38z>G&h%DaX!G* zbX^DWc^R5L9d8cp|3O1lYyyIb{o~Vg1%Bq4NTLh*YFjR-Y&6d$4ZGx#91+|-Im-8? z&HYz~swux*8jivgYys}^(lrj?+ETk%K>403(X^=h$k01sz4Nt@J6fPMabx$hNHy`)X`R{i8ou*Am@bZp%?qFjerI@$FmW*$)h zJ~v)wR&PvD$0d}db_ZxKFrl@6^`asVFz+>gumr&MqRCo{LmW#FSPB`OVu{m^(|-WE zC!b7y%F)0K$|#D?g-78=(+U9Zc7V0nDx9Z>V6`5UbFy_uCL)oE7AH)2IGNH`%+Lgr zJ19bA4vF8=(iU9Og5%Qv|;r z+e|bQjg-PHD{s1<3ESvO^qXDf)joQmW9CReKN7`jSQ_xfbB;Xm^l(pe*N^temy?__ z0)z;V^C_7EQGgNw!wNk0ylEYcwdw-MDqX1SmC%~0hM7oTnIM{Gq6=OqSUz*FTwYa( z>Patr!}#0?=yn{=6*(DCtPopRt03xGO9NIM<9%@$xAZQYvOOp}Q&~RAhFQyn0HuZxH+&d! zkKN{rGuUwR8VIi{`B^Kz4wa;e5D6;g!UA5|l4#@d^6e8F;7eOXVLX3a-v>6Q54aOL zm?hYGt@qrlGmafyQ1T#m=JYAMuXh-et^iml$a zed{KVasgfPry0^}|4sx*o62oNykJ%$q4PZU;8@DH^4`hsg`PZZTdih`%sA1fZu%=I zfjMvm^p8VP`GW$2^v~Bz0rhBr)%jyD3@CYp_lvJZpSAh*DP)3eiXGGk>t_}L$^#PK z_j|8kg{ewaJ2>g92TG!q&JJcWyUJ%)tIS$F&dZiha&e(v>+ffR7kOBh&P(|e;~F+t z=Nvf>;C(r-avNSRkkw0R@ur7^rE(C9G5an z%w6bM1U-b@Q`FZ$ATkV(oWZ0}8g0J^U*58f@AiB&{U}NNGPo4fY_uM=!Odjak*)7Z z>s_-*(5IySTu{2Vwq~Dk_(%@Cc-okFo?Ua;bYc^n7-}fB!1gU*50l+R%FU5t5nBhn z#JK>FiwbKofDJVZvo!7kHT-DQUIc7$|7b{29HuSoA!Pr%*>{ffI5xWS%pw3~(tRAw zQ4U|H2!4c4FU@?^`!C1)8B z2KrfdAbZkUKegxV{lOvc+-Azy=OIV-?l}e z{XiPwD(zFdmGEdr$(JBK9};C+!$4uNDXyTVwFx|V zc>N`}?3$0q*tVzjcrwF90!h_5l+BrOEP|FUq;~CQrJ9UOTzrZy3bRHqO}b(qhB9dY zLRe9-2(VCi?|cP|yN9@zwMBq0g&;1}(P0F57?1U6vO-#aV8t000qf8h{jcn?TglT> zN3xv~y)sVB4GdsmsaVhg%>hofU0T*ObpsO>DArX=R^|u+c-3v4axz9tuXtWUaeA`b zDdmc|1}AMuh_W6xB&EzAO8zj*wWf?r6uXaUOHAeuT{qSyz8}XD&r!UbE9U|vrkIDg z4>ze5iR=~r#(ghjmIMVL0UkH5QK8|XzkxPNjTS! zQnq`%o?r&ugi75~MkwG)-^?r$olw$A!YhZ-n#EiW9@`3GX*!oK;10#Kafc)s7%o9# zGuB<)-wAc2cu=#;a;1D`5uitYNu+?*I4!K$h3}WgVWS^jR7un7U>HD!iX~~K1X@~N zl#oT^rp@L{v#cehVhUa5x*S@M&*LI3s+kEnlf%;?e%I$>5zPx!g&^>{BB1j^6;897Nd581#uMa7-oPJlivY>pUR9^3+?G1a}h#_2+xT!T3Dis zpGDBYxp z1(}Xh#0wP-%}e44(+WXymYiz~BeYrLmEDXcWnG&FC<%2|*8GgZIWfH)xFWBrj|+Uj zh!3MG4ZstKKS|&4FxAm#3;_tZunO<(7J$Z+89OO<4gR zkNy2T@4|GI6^JkRpE9c>D;Wr0ag3ckA=mP%tfWGSMJmfmW~oRbuD-|9JTeuy(*t3Z z(1GHdkR&AxkeWz4u&P_kv0y>#9V#lePzV835*RTl&rhIjqI-B5j}StuG^IOKS)9`C zDUH9I8t~J?j25E0jr_{C%i(Id5Dv=s#4;qSn3oXP9@5$se^}=hes6u zD1Mf)ddeYGu%T2Z4l={Q?5oLh5h(RN_y&XD_BA4r5=GI;g74H3fSoN*BXa+WfYF~u zd%r5-#pmK|=#BcBQk1>W*c&3eOT=z@{n*UJ?hyc*yMD`*Wi>Mco>@h+r>bM|$)!}95w4^ooJWl3UDVv69RCavL0R`YD<{Tnj>crS@-b41E$Ny;k<5qkA z%pm~XrjLrAp3*RRf67<%H-nz}MjVF|5QqOPhQ@Ufv%KH{K0iLZ-}NBu1~7Mh!>%C; z!k-t+LS>Bh&1%IQqPEr7s)KXT@}Ye}0v=L-@0t|KpG7@kn}qH*l;PVF82aTw=E1Xn zIV*U=0!uZfQXN$U!Hi00wwJfjHfb>@mJj7EC2r^tA4JQl8bGo$7XBqZ;R^&6G)ecT z?7xVgO+Z%htCMJeZbq&}g`dwSf&*11LI<$cI1mJx<{_T@D57yGGi<)6MQ#$(xm5O0 zhW_$&O)%BNq!vwCl&D*W#2grXpt*4R=Vlwwm~EUg7+)SQkC(^G}W_uyl7VozfCYEFleo(jg!cqNJ46E**k|AgCZMDWG&OjY@a7q;$vb zzWo00hjX3hIv?hlXYRRX?wMy!jJ}>a2_YjP001PK8mdnK0Ccwm0Z_cVm!)Ts!`%zt zOH=m|{yY&C4Yk0VGF05%Cjxg3vo`=hMD^bT0zPNZ-+hEQD(NZ#z>fr?TU%TJNHo?| zRWkIO{nuhr!L9xocK+xEtFINqPp8l2eGW`N`*^;58_*e&q;uXI1UHR_p{$f}G|2qv zw-lkz4ctz$y9tN)RaDG{U{G>X!8o;trF$dQ#ZqHq1N+ZEyfz-8`&0Svdn2Y^l7jH! zQD749P)l9k?q*=!PjQLSjQ+mMW&$LEjt!V99R=YL4f$`0NI(WHGHLKnVL|5&h*cCS zz+@@F_&cdYC1U!f?3f`};e*Z4hw_%ug(v8hvt-sXSvSisWz5-2DbJ!dCs@)}@{34@ z&{No@w#Wml?~-E6+>%Y9ZN-{;V`&@af_U8KlBnjv{!!+8k_V&$c9EKqQ&UT6uq6!( ztERHHNlrgqi?fR*r(0?;(O-{zPvsbH5(d0o=0Di}Bp zCXZ|OM&DYn*UE6rlAF~#gQep8-)lQ)l)4Z9?m;Og$a9VA^0cSWZQlX=IGdFRVp9n3 z&<2N7T)9@vM_yF4xYZ7@m1mm6V^q$V$BeD2KA-;%+Vb$%9UpW)=T^O7CMs+EBL})P zK^#>qcU~ymZo48v3F11!fq&#s{?>OI9^Tsm^X4ry?81(6YM#o}a-i(+4lDHo19d1L zsF<~LDQ5D%YVJoMSrw9fFtvtQNVek?7%}vEYSQS(O~=Jr1WGF9@&@s zUcGNW9=HFQx;2g)?Ek%`;FP0Y8b;Zb z0F7^|Xv1g6!!!~qWp5^5R9%$2W3w=r!p}g);vOaoF0TVck)l2kIX+V+tw>_4tC@C# zb4n5Q83~fW1K%sbf2sY$=X?TiLzBtzcxn7Blt`u$W_!pXH&kcySjRRj1Kd@L7Y`** zNCmFMvFSoY`SD?P5l+JP*5tRzApW{Qy~pp)+FvYava1y{rks8;2UV( ze4F&YcCx`+R4f*t!dYgGxH}*Sj*}gERdY2xv`_v=1LuCmq6W_Uv8iq{!=zM7u*msT zH%np=;wx9AqO$~j=aKq2(1AuA&au&REOQ~pn$RRX`egswbvX~|Eck3<9h@!bkSD?Reyh46?cl4^)Hm-O9E1zGB4Vg6mQVN{-wc7<=;z&Xzj?748B2;6gS6 z8lG#k3;~dU@Hg!J-X1P1I)c5BxpO=z@B}vg=JD^5qBh2hC4c7-n~n@cWoXYf zT5>fJ6|D;Yjurh%J}ytyk+5{@aS0N{JU+$BlitA_pH05r6fL=kwWd3h9z^r@zQfFZ zgm+)WpJL2aU?kG4c91ekh#NXeM%u>K8?<=6{{0ZRvxGJ34hGJYpMkXB(RGb=;GYTa zu1g!SuyPi1icrGM_rxJ~r@ z6()+{>!(7nx;90nc|P3wjsH2OmF;f~M&zalSL}o-LInF>@dLG&b4S0g8Jt68g| zk|Yd?e1zA<)^e6tKZ#uY$_4BR{-*$72Y5x+TnTFeqxxy*O(AEB;*^vlaQ2DDNW{$?;-*abU#EY7 zOT9zAV*G`O8AB*iKdul@$vENE;0sryeAjgl^_luAaWj5SPo-%*b=O%vESpGLB%M1~ zQR-5?^QE6Ai>wuIl#Wfse+FT{{W66mp;ErZ8Lzp2F{Pp69T*>7eM{HTI1!xvRmQM_ z0o0&5V*TFZBFCTIF88pMESSaubCf*)8e6t+z*8x0d*_MdlD;MyM^*xuv4%4zdUqEi zHssMB4JXIhMS?pz)(}bFjWf=0*>^B@Gx|L1&w{<*!S8^)c}05Q@xi%oI%?xT8PHbj z?m?9@HHsU7m!wYxeBO()@x-v7pCxcZ*4NY6b#^gXP&c`TVSN1rh$8rZ%z%4? zg02;QatO79SK($`BA1YC0ms6Rfh4>3mlGv`_{Ns^JVHKpzggDwXU%&5tru7UD#|AMD(CeNUT}f>I@|HnZO|so5 z{y9(#cy}uwnR@FUyxF*AP=U<11AHV-G&YQjQhiI)dllj#19vPXP|s;YmyZ!wFk7Yr z5}?MZ!>_%yiKa+m`Q!J<1Nbs=)4O$p2{bD{)SeIU?vo#!-kiYY$k{rV$jT@tyZs^Z zjQ};&|LUc({=ajRPbh~w^b~kcsUo%_IvOF*Mx$9`u&VQg(Rv9lFNMSaMvl7W2lH(L zVr8$Wiqx>h=qi)J_nwFnu&Kr7knR^AFcpo>(p`iNB)z0-yQM3eIuKi2)+q*tZ2In#UAV!kR3ze{{K=;8Oq_w zJm%|D&FF*?&+@q-5IMQQo;=C5={?(`@Ojswiv*>0b1Os~s8UZL+b86rycJ&%oobL@ z$7?$L9Gk%bT=SUUTF>o?Nc_LCNS%gi*$+0#glIs^hrP5v${^(1=W+4Wz|lEUjJrc; z?mQIZ-sbq0~4S(c^?u434)SfN`4WI}>)@BE9w_MSyp^{1VfMpJ?A zsn^5IVFfGVHqcBi)okZQoFZvr4t9DaPew6Qs-ee5;b$_4@7OkF`u-b|$>rJ6nzM#B zJY9gX2iGZq)c59(&a&QJhEm|p?n1NFGH^s?xTl!vC5&&H!B5Upslu$jPNl^A|oXr3vwL($! zHR_e_i^fjjK)u5znrQ5W@8jyQXUE3gJAHoA!u0s7F(npE8pf?HMVbW!BmXB>_ z-XJ>VMh+dL0SS`i?1sojfwqZS4-L1$h42ZsgsV3@u_2V4%QK~pyA6mSP-5GCbxPmU z{w|!#tpCnVRK|k8`0R!Fie>cit7ywoh9dy>=S7hlClPm&&mhSb#Ui_d)ts6}n{bCp zP(R{~F-Y&(#^KRz@9rCfs>dEkBLxEMpY;dvR94)H+b6F+Yn$2iE^ESf%5sXm zI4+k)M_>y!F+g5;_TZNED393--t6AVDx&eX5Vd2hAVlQ`T_sK=BKQ906<^A}A_?7u z`86z?;NO3#>|uCmmC1^eVn{3h4rhX(m%nM2p{L zjY{^5-8aFi$An4rVwiTPA`uc&e{9dqmo?1n7VmP}{zyR*-iFW3?j7uR!C;@>ApnFjfznTKgW~57gzAxm|45afJdpS|JCD|A|AU{ryvR zi6C_1=B7f`ca$D%`NZp>bJcILs+H!mMB)2hh`T1SdG&o#F7f1>MehwbYt5Nz7-GE_KP1(}nX27fW{OpQ+zrbifr z_{sU<4+|onKUBRa;<(aaAO7uSy9Vu!#)#}ezTGj`e`KzaH*=8eHXIA=%g2_0GhDn8|fvszZhVRB*YktEuamKBhnX12q6W}GWyNlYFSXEMVdd!a@5C_ za=57qy(_0bm;WCB;H2FP1S8zXGw<>&SM%-cABX7sUr;Ay>z2P2$8SF4lKxQ$Cq|(L zxM%Rz&-pOwQdJ zO!6R|y{y?M`NL!Ze$M6SB`yMlS2_ut&JvaK@`PSl*?4_rWUJx^a~5ir->NaYaZcrZ zpdu0Vx=HY*@yFQfL&(0YPu9o&#sjN>3xx4NTJ52{FUuXb_~8EHNKQ!MoSuo4DB@P` zo>Cx_tdHVB1Xau5rME>(j>NfU#TSWfslGj8b^0AvGm>uFiC_nnl zx}Fr>j>?CrYTSdt8sp|}Wv}bM+XBi*XH8^m5%>rGaCD@k%OeBj(wWeM=0o+v@ee~C zUp5!RFE9tbSY`CIJu(JzctJ{=AcwbYlWhf)nZ}dJgpbVV1EMyjeOX$G$`@Mk?AZg$BBrXt1H6MGvRGZ$i~%rT&y2E|$nG}Z*@K|3DWTM#3)4y;XE2+(EtL&4j-?iV>t16}!U%@<53 z!3F;K136?vtdU=|iHye!HS|KFuZ{TOZ?K$EjyV&qg33?m*QcVs2JAe#T=d1V2mU>( zK>Za=v&Ec~Xl0TS-(@Kt_%7DIwqI3tIhVSa(FuVJt@g$m^*l0aRu6;O1Ouh%I4nJ4 z4AIEm0LLd@HP|jSyfzO5B+V|u?4!HOU-R33=xzhZyZQ~`0ewlY74`Du4wg2>5)p7F zb$i%PhV;O@U~Z*zaB$2SaqSRgOV2I&3?3+!k{7I^oncVOQ}K!K-^k<#!HwYIZw?-K zrcvThPnle|?zc5j|Bwy772|eEIb2jf=&(kgS$BM@vsO%;_5`e7?%HCe<>ZDBDx1mW zQpJ;W0*Q=}mQHa{8f2n0KDISt`PdF(QE7}k^}%U=M)?aE>V&a3#o9r3;zGU!=_C#p z6lnV>j}53{Yy&_hHiPsX;S|`Z+mY|w;A`&`4a`Ulnay8E!NUUlR>C1ZtJ}w|7YVka z%tftyG@(ShVo9ezvq@8PiNh0DJ_n2zwfC>1WF;9%ocLmtD-!xyB2Er6qS~&mtUCkP znsMA((UAu7q|bj<-T4KC`Ae4L%zT)0#tTjU840O>5ucQ7@p5H}k{CiS-#a7melbTC zx+*c;qPb+EBk`K@l*C~IsxH8A`ipD1 zIyC(7B54e}?{^$SHJtt>bdE?ncFi$yQ>AbGNwzdnENu9k&3EWPr$*Qqe1j)X*z+}! zOLXFE#I_zd{*zRGlzHX2H8KmkA!*s*Ka>C9B!#VyA>l5R;K;nCoZj9SyFVCZng98w zQzH7A%1FXQM_!*Dc6NzEayQ&|Q5p-;y zzL()ReBj=m`i-x>3G12kmJI%S#*v1lwPY>o1-s@vVw4IOh>h>Lr<)%--7Uj&T35mf zhe6D5qeikAhR{dpAAu(_L=Pl+e0k#R=B6$pM)zuhhn~d$p!C$O_FAE^2!!N6d-`Mk zp^hjNuw#!_ja(VhN&b`1Tf{d=|4Vs&__fpknz&sKdDl&1LQY~gjc0WZGl-HT$EUAo zca|Su6(N99+;VaeATD+Owllkq!l{c!)xWZL&!#INjEpe(*%VTvx}xfIO^o^S!MbnJ zF715rnY9XDsVL3?{cf9DyOH2XhP=B5IodqOuvlu=#xfbr8Rt_gICP#iJxCFpSoNs|T7uakJ9Y3CS!C{52Fdat zwz8jsWM1?ievH!Qfu8U!|)@jcV1URx; zE*MuL*dY#@1wjg%*eP^J0SyVHc*Mz7b4U2PHD&S(f1*s$Q@k0VTtuj7X)GKUN+D}{ zXUyG@QLKn!HSwO(;G0Q96(xnvdA>iXe$a0^bUV9U)B)LzJ5|V2bSM)G9Tr4exh>r6y((}pXV6g z((yCs%-6f-`HwtVt+m;s^a<<`15UQ67*Lsc z-3AI3~0@v}#lR!=b1%nN@eXl9R# z#!gKMNcgZ@!^V2?aPBoc%PQmg}uLhqo%0+ z!U~(##e)hzpjwJb%72s_V=ysYs}Z$u*X5+g*TS|r*7v7u{UQ3AAG;zKreT`fw@>10 zbdeQD5Y}W5z0Sewa2FE4e!B{vf9hn@b#ocrE~-`_&4Fi^O=@b+D75hDPeSMH6i31IHC|rsnAEp|VX}P)~1#kCyr^WkxwPt`KNp$HNAFI)h=< zlbOOht2DxG zIQ~Z2z$8h{Lm9epJfW&b$e+InKt(tOSVf<8NI%^>=fL|<2LBukyBqYp2v1~{qkM{P zeGWav+`1EsDbNEdG%!L9QE(`ciVoK&FUe{0l(O=ow6B%aTaQ6;3YY%9Wmv55;I(x} z^$50ZNoZsB?#dM&D+V(DC*4AE3k?Z&u2# zM=8Q=5>tise;b1d(X7Ql3Y0}Oy$HB3iXb*ERQz*kE|S_jVraLG`%tcIurCv9C6kmH zR=N;|8gIWoJ(#C?`atFFp6m35Z7X2lBntVF_4C=vT=Ab_;g)7c;*T$$chF0D zqE}=Y=8>K5zqYXR^?1Q|@BfO4zP#@D=gALEntQ%Ud^(qXk6?(E9|q z4r=}si`!_+`kERdKO+>H?6O9b&L&S`c2hJ75O6=&M9%1aQ}BIgu-2M`H~enY9dTH7 zeOz*RAcQsM0NnKy0faCd?nl{5#C|(9vYG^(I#UAAJg8~${}FlDGS3fd(I8S zBqLQ`bAfD0@sDrt=SlqF*1J_Iwk1MT0}|?7&b?< z#xkyo{uQghh+9gYRKrN0Z{(GvQcQc@4`dk-(kq+9+-_21MdFA==ag`=@zO|{<2(lY z9J>%49t}Rrl6uIii!@;bydJ`l_fd>u^c}uO-v@=qS{e=O zzNH{9>oRbh0lu6Vy^CF{)SLI4YwUZ{YW{PyayUl!mE$PE#f5(uyLJe=hJL)f$RfE! z%Wu7o9-qeIdfCoVAvsVQa)n@bY4&J!*G({Fl>~+{qdR&0EOq7uEaod<2%=Xrh-AHU zW>!~U^1GH8Uxp+ue45(L^P|%R+f5jKjCu@;Pps&naT2w_=1cg+SL^g5SX+^GG-)Z? ztAS7G*rGonW;jy=gfpDC#>t7<1(sW{lc*L=e@MXB084WH+@g@bhg~euB3t?3`PzsO z2E#{h86VpgfRd?}gC7t=9-t`i(hVGr4`j;UUmpH6iXJtz`}b%~>UmsIo>XVtjqGhY z+r8xROB{v+d=nNNFWl=BfxUJdKzLN7t9b26Y~qygeC^;>mR6zeEn?ewW7j*U4tK^U z*lodKU(ks%8OH)xC#fnp!`41n5o(<$r2t6+luUqnSD`RmN?>0?n&cr-1k&>2PahHN zQ#|DK2SYyP)9_0wu={dIrhI|o3H#)qV@b_NRqdB2J%H1@ec7B$m5!&~F^sOoOL{-z z*L)aVcD;WyZ9H4?bDq??J+v>S_(c>p{;_k@p7hh`$=Pg5&*Y8s!k?Q+=oUI>R(dYt znd3L|Em+;FmaGY(S!Guiicx>y+lu!Z_%$PXNeh@0BO0zJ1Ji~Sa6<4_a&n(Hkn2*_ zN8M+zqPFJCLWY>T4zWz_AZr*#A%ca$VsDp|tUJR2SkZwz;+k7yQ^X^}=%v7mDxpg{ zl{h~Q3hnxdM`y`9HOd(&sm_^2H6Q6Mw~8giLFEktoRxU|O0 zeGZ%YmGg-5keA;|r8Zu-6{&l^fwHQ`e5KNdud-z(V^qKMni|Dds z&sYDe##DePte+s{NFZQAnl1jZjHJYv=}C5jf9gN~lCv3!P|?D;fBYb40>W>Y4H@r9 zJ;Yei)P8_#t@wH0yFW8^*XWL+Q>xsH(6{%>7PzPe&mSj9@TQ47{ytZ5p6Z!*x{vcY z>Bhe%mt*H4#bPYFV^3RTmB=9ZWbZ9^gIX!R-*>KyPHHp7b1FY=iuWN>g7gH-eZqm{ z#1P8mG0z~fH(!Rs9<(JiEene$|4Mg)_f;RNq8NzthF#)*!)sQMO(0$fuwvwL!3g)P zdtskcB_wF=Zr2+y;sMqR>B&u!v}8P!Zrm$9GYq^q3YxDinh#UEeslrt`ZYL zyDACp+vdS1fg!mGHW zmk~6&-_Uv#A482+<(G*i=Ox&wKAU@rBPkKJtyZC%CI^r3+_xiPA4^3i4yx;ih>b+A z-9zsm^^3V^>+j9$ePyqn(|L+_MoutoCLI1nm8ulaHa#y#XnqU*AVr^!a!a|h3lz;V zg>7#T9)b3?+xft+36H;og;(A9FvuXN9bDKAEkmQ_RJ+!ZTA(I9AYY}##M+yr!qnl` zY{dw>l-WM>v~Ze01|K2MEb!Xw7v9f0Lgj6+khP|&ipdv8QYv|Bj3N6Auz{Ar+gPWXsd zob%LCH2l8zwX|-L)NxiZ-^%DgN4|G0mRBGO z?CJK{>tGBkCf-dlXH1hJ0}p*5(dmmuFm*-{+1@1WzpIqNKaBco7g!)CSWY5rZ)TVC z?~lUc92*Xb*P_gbigr}FnYf`}3Q>fL=kONJ(6s}X{Xig9C|CQuTKUxhR8<#`-G8K@ zrE%`tZ1MCN{=1|A)r9PvM_nF@%N#EWsR4AfnbP zld;&INbOQ8HqmJsaCQr%QrI4qI-e?1e@=P| z#&5seh@*mP5NvYUq;-+%)3&A#oy~tHk26y3;X3cOa5#x&@_px2dOld5;}Kpx?DU*Y z7a{biu@o}4KOw4HsBd(4WHB1UA4|2EUtyVw`e^=!Og?kRr4G__?m)U@Ij1r&8bd!$%hRPwVPcf_G_T6VH(gFkpjeus<*p;eMk0#@K7$ zh0ss$s1NVeHy-6LCm{r?3=}7o7xu7T(|@3#>B(j87JGT!1)ZPeR?v;_E1DcZT$Z1u zY@G#+ZWtt|2=DJdNaQ=Jw=$hF%b9XUn5&N!yBK^N=J)>M;zqN9$^EV;9KhjLAgGw! zdEYzRTA{(uIOBnb^Q*|gBNxnrYYgwg`L-4F{!W@jyp)$YiK*aJ%BAZEDq@+^V4*&B zBbr>pS8O}GbDh<%VVbSDHl%p;&pT4#v#$KVBwbX#(uk%k5P&Y5vmavmKS>aVk=>_$ znECws;GdGmSh=oWCwv~<#x3rT@yubFxS1B=o2G6mjWN%|OK)Ia9nqNjdH=UwI&5{U zYy)P=U6@+gC%L{^vMotp46U~1iw8;7?w#*F^V;9yP@8ogL{!ZUIMT$>mzCE>Iu0o?49VXQ(Zy-paYzZD z)G<$r7UA$D=al2QfQDX;LAxc4M%6HNJKgr0@1*ZSQqTCmz+#p@3SrK=|$* zdIV6wlUU_x#rC+yd6#)sbi!M+3PkL^fFUcGd1e$B;2GlO8eh`y}MlS(f->FvyX z_Vg|BgbTm+v{lu>Om(M4rNGA^Rc^i2mC~zg7fmQA*OMV1P-GHKBDC!0wwBPx`(==2 z@RRb}oQvOWNCm3nn4>u@Fc9)JB%t7IQ#?1(SgNm7zOx7Mb^$Yvx8&OL>Sf!^Z9I8x zMhD#Gu9Wkpe|YYb0ytS?NAjZl5cQu=tD1u@^*84ZvaD-=iS9=@L2HMWY(g%ym7!dF z5Qg#}1H!ILh5-aCImwg|U$P)XS_XD@ijn1k!{J`^bYQVg$I{7lf1?Jq}rNZiLl7_jx0IYb=<=X`@nUv<(%1QxRc1Cs{yzu8Z_hX)%~l3L#L4cF#}F4t!z z2jNkG4maton~>F?OsBFKtAc9r__bG(W_oQRhfvAN)lVQS&op8WJEo-gGGCDMprPSN z9^(>>2#BE1Sd0lIO6ss^O zE0#0qhRU_vL>%TDO;6y7Y~b#cUH+8yoar``tL!_8?aP<1>J`0aOaC7K?uGe%bG8+DA0xdvUICXzro;cE4atH%^cGH+q)a& zLgQjhXI)=uDUY-YROoc6b9iC#MzYO13C#8VB#JU@a8Yn7`$P4BZ|l9ym9SN-bnOkB z2cIJBzTc3Hruus-QzT9}D8^P^{_9C(;E#ZrrP%&prr)$Ct_90yb)+a?N9_mGd!BJf zr@5i#(w4%nYTi=mxx}aw5G~-+3#_lbF!nHi+RZ6r)-fMW+hG4l3-A;va!0&i&(!;) z!B?Q{6SOe)SdnPyMjZi8U`0?12l*2Wehna^rFHWjH&M*jvrenpV+QHFU3VU2tvqGm z`l~N>tm8v#a?JaJd6mZh{j=ZCYv9Q!k?m30Pi|>N5|?u;s)>dbHjC4p%VUD2&z@h- z4{KDs3-&dW{LDZ+4s9-0%p`SHXt1-gn!0&#syHNZ)YCAvg0Z{kj1f`5C7VAHoyRWY zxVv1HaNxx#O&90m{8~{h#wo2m^@%O0`~KPHiIc}e+u&9OLr%Zdd|7dOy6;oHRx7GP z2amMfUhOZ5IRlp+87DI&^`&o!Tis7VGEzYm+(7xLL6N^{3;?4gZamCzh+ z&!E@7l+LpL?^7AwgK?mgAW9Q1$GKK&;jzzENYIK;FN|KH3mf?GEzbA?pA(PWTd=m};r#t~7*?kCkMv7qP2fPx z4e75(4AB5Lp5C~0cn2&N8gK z@{2B)_$$Kp%x;ahGCO}`%j3%vg8At?87?j+cB_*@Eoly`5LoT{z!l2ot4St(hlVG+ zQk#LZN;JzfreAL!e%;K?ss468Zg>(Qy=V~!MRGlVTd6$8zUq1W1IOUEdilN=Pg?C7 zabP>t>0nc6VHC62{il@lsv(|(a?qaoYGGniB175|JQaQI|N47z zdv%I1%FB+?!TineOE014g|stCfZuBN-2GglsN0UchsxR95DS5OXMGh|p<@#QBw9j) ztUx``x6PV@q|c=SnKDWH$t1-OQEKwi)pVfE)&m0{KN)Yhaa?Lk{8{t zp{JZq1{UaDmGTtXXbYA9&6oVa`3dpFq{dhJhOGU~pVk8W=byJ_*CzNw2+4OlNGSk< z&B06u!MzzsT!pH-70tPDF4S?gNw`BWNhzQnOlr$6NyPnsVl-u-y+VA*%ztw}{i zNCLjps~D<&{Flpm*-1i52=}KHNaEz?a3VTi-gqBN>jz?VZ`}~n(i-AhWYi#lNoryJ z+i=lWD<@g&(Cv+Ca|c_se!dpdm?Pz!N<%&&W-*`_ZDhgm-8^xp=4Q>`!n2gay^vMr zDC+~iuZlqVp|SsVu5inb$J5P3f7)GasnEC22w{{;;kP}kuna4>X}<4+Cif3v&I_$= zjo??>+VqkjcH)U7frMsw;s**Yo;e{k&)A;Ydj6J3EqpI=y8VQRbdrsVk-1qPiBw$+ z3*Fzu?Ihd7Or3+|cXNp)y+NO(yFPcsRll7wz?@E8DfPa=YH2*0D8)BY$+`ecOBLQR z@{hPnA&VB9TB=wzrd(wfmTufm3G^66Y2AYzRbje|Cf0Riaz+)O?gp5*(KGM8jv`Uj zT~ATpQ|Gj%+*GO-LXC;yh>DjEW*RP-pGZoYJZ6d{C;km8TNl)#bm}ZihB`1x3@5t? zf;71Biq!+-5AUv}AnoieJYatX#a|2a(3r6-oQmpm8LvOHMe^Ibtd!cVO8zTd{w72Q zEos5h+waYC$%(`It_*UAA3cqbYLs1S!o;U`KQa|?4V&7N=XkRe!kWYodl&-1MxYu) zE#(JiKFF;=_q{lBhPa4A)xPxt@?Y%z;r(S^1y&zo$+y->GQ{x- z2Qmz=vA8k=)CF2MvegHfuB~@tQQQ`8OBOpxB|S<0aNKaMbiufgnf4n z+gtrprF<=4>Pfzj{QR(cOvcS7eVL`)f>FcwCbK7;_+xDF9KIOKJ8A6FNvp!myQW4# zB{)5NMM+t2q)QVx!4%g~(<_d zTf2~3?N#u_oIfb@Hc@)9bL%~}jq?u*lDS#um-%_gqR@P*S(Tz$IHJ)i)s`W+KVa~d zECeo`4aQdyou^=dDF?4^ys?7n;H9Fz1;})eFJA{Pc_4tS(>)_lV{O(O6^>z7Z+4M# z0SL$P@2{Y^SaI(XjQ)!P!*oI8<}%5je&Fe z@I(#^HfhP58bWM-Yv7J)2@Egd1Z6yY7-CElN1-nRUY5g&-1OLQ$i%u%YnRiPxNm1T z;qbADiS}8=I=OHGsy->;`QUW{A+4vZnMpr)xEq(`mTaB{_UI_hlRD?WN;|r0f4|A~ z6n>CGe9@CFDJ@=laky!7ONjZFb%M%N>8T3dEG06rZJ09(Dpz}z_vE`P%QOfKn;|H` zBA{u>s{Bda*%?okR+20P-)5J|c@9T`R=!`ATbPDl+%Hi+q=tJjw-BD=)zO|p7=?d! zzX>{lu}i+A1m$tRhC>)%l1*N-g$O%{uFKBrUC>@6C=ft=KQP|Tz&+r)04xx^7yc?5 zFGY)xkHkcTIL)mulH%t6lfUB9UD*?cJ0Tq4v3RqszV{xjL&6dHDO({A)Qf=_M)P~#tH0#C z(Yix@!!?q|R?mf+Cf|7zz826Ck5hXVFXu!1tjVP@1=srYZu-nDrYV-*Ym`6TARN9q zB26ur{CT%jVWNuEOcVK#Y zjVpM4$akl5&l`sFs(A?DbEJNffcHeZ%{D-*D7jrxR}8iUt83%y&!#HO>%eJaBk|`F z^-Ep{<%qG8?hYahWw)Jr2Fl7&IG25rT<1Acdo9&nJO(!foszeu@_+0*9_$|sk35+;t6 zf2v=V6E$5UA9ZWs#1D^t_D18N)AuZSH?$`fNTId8Pw64f?r1>0{|d67`KzCP_Bt1T zAQxAnIGJ#KRLi^vYAP-XW~|*NM03pL4{12d%CNPZ_P}>BOa}Ob;$no1Sgq{>pcCyK z;h@6T5vSp=R^Y+BG|gYH5=gh_bk_$RGDA7yeTA9QAc^gWpZl6>#t_OtE^_vHhENm` zrNOj}K*C^w?6^MMa8QT*D}h}zn~jG0&(pze-85QnUSXk zRACy)wR4hb_vSxr)Dq=ukBsFj0?*)Z}hh?8%c59taDI!@qUI z1I+PK7A0uAM3%sfy38M3q;)rtRaFapT!2%0qfNEdMJR~tq|94Q)VRDsWg@G<(OO=o zM`8W=AhL?Umh!{f*Xrab_EtB1%{briFr1Gbj;+}GQZ8gvy(sgT^QqZs2;sI+(=fye=$XdgA5BhIEGvwzeNBGw-=L{F!n2I5idGjFA*t z033olO22@*R%>dpEZ)Xda>$U>8>a%P`bg3esx{-0N5h*M@XS02RCD8raD~z#u<5^$ zY=i8Ktgv6qOk3G$qa+IbJAc}Tern&bu5V(midBMJoOY{~R3}Vk=dxA&YI59TA9osx zljttS9X#R!Gz)+oN=YS!Wg}qQDs+?yTb(mRg%_l^avB_Vy3-m#i*E1+(FQ+Yk18WQ zy5Bn`OA@n(uL~7RYkw(Ru3ud368DzTp^&W?UTu)cA`pE*5L(?8`D=JE<9e+yRwb;? zM$amd=iQTB3YKmJcB!Xwj}n#CEfE<1C%<1+LU-k>Md=mJC@xmxS^HB>nWoJ-aSrP7 zHadI!&v@0XqXD?$e(1^U)pJe^#+*Z+0*zMS%%8MG;Qn4oPJWY$5g`m174%G_Lhj_` zV(pZSB-qQxI4Q0?^l60LgTI(DTvIO?P+a&zqxThCoPk3OT>x`st`Bx~o^(ko{+ka-CTCx}a=*gkq5n<6JVhqM#xXD~Nty8! zblWUZMC%5wO#?C@K3AD4few*{1$?tn8=plMO$XyJZv4Vs{t5;gIJzj!x@bn2ffwVX;2 zmiuql{YGTIhE;?Ni65>C*%?!!Oh)HfKz01bOyP7=g{<*We2?f=a<7?wvI|w&uSI68 zJ{>mDR^gp|=pn5EqNjt&iJ=mhX!smC%$9RC%|2aI*z=zK9XyB3mZlaI8a5Ek1&p#ef<8Y`k zul;AF^snZDIi~9P-xOQ`WfkPhJyL50~3^xT4)!Ovnf&Y+DA&m}yd0sqm9 zcx7*oN;OK3S+Mda(XqivrTd2dEYCBd!l2Ly)Z_1?Xd~Mpr4hmrVi?@B(gh z_gn%H>7p<&kO@&^rtZTmbhqgi&l1^$1`akEbRF<~`x1bJ^FKVpX1|c6in_NlQB1E5`Ab&sHxU&d@dG7(^~ zkh3v3-|Ee!q2ul~(S2j}{Pm;&Vwp^nTae{9)%F0AG>5&e{|A-R^m`*|#0V(}5n%SU zt3hSj)kgz%svMuLDfdTv!8js-_tRy`R>ZOq(Y0zYZEOW?Q$qlge9$mx5Z|n=8erXf z%pkt0vuBKe+^RILmYFq2<;A0suo`Dh9rp<4# z80dqBIp*?{P+lDV9GpcFB4oFLsWK)8PCE7RK*BOc<2B$i5HB|@nXRn0p(eV01mNVW z>@j$m%|k!QSfhRDQ1XrWwE{u_5E1>U?~iPHLQv<|B(Xk`>rkS*#a^!m$6CK!Kg74H z)1xW?R0L0L!+NI_?gH)$L)>2ZxP>e ze`oa5zpW8JvB)g7?ynHvdp{J%7rxSwG+f>g2xt8_h!5^Kgrp%G6M)qXxX<>hX8IxL z$C?#XmGuKy67DXoq1+TN;g%RkI(ddBd{hM>1YrCGv@vWO0niCRr{MxG750m~Kb20m zp1pm0Xaj%%`8pB(Y4jhyg+z`XdZeqi<6!t)r$HK@txRj zi2^go&%Hf>n_*&~JFy&}vk=Nm-peF8A?NqTK&*BUkl(&>s38P0?uUptqwx=%nC}gL z!SHBm8aNezInke%SlbM23jsj=zxnz~vXY9X>i;SAgpaNagsb5fxVv}nlQ!A{Ksb+4 z0fcXeoPem{`t(9Oqs!u2PAdM~fr}53p0;`F>y9UUpbmekMt%>JmIIx`&{ls2A#!P~{b&a;)_%vyHR5XnpGJJHM}BJEe2Dnqqyt;~Fd)3IYv{8X zkqEG$3IOxIer)rIPg95ec&@}iP*WEgXCt1f-{>Tqpfy2!q;k~lhep9LO3d}rNdw+{MzU5^H{|JQa=EoMiO8_ z)OVxCOIVC-d&_OW8chTYPbyuA8%~Jn+`A(Mbk>1wA^@){-T!4a&8O3BShhRu)>Df; z(UuSfTV(ae&|NmF8U(guUrwTi9T>g0Ck9o(+5wh&MTPrAg~J0x(S3DdJ~jANC4q!} ztlD~Nqz!>})Q{b-4*uERlmHMg@DXfZVsg*AAS@9;(cdQy>7@ZS(k`|8dfTW3sY{$m z2$w_)HsOx+u>f$k9vI>NTC~UC^x1q)-`9j;DO-W%Vg*`SDo})AwlN2tR>u~{)I`8= zduQBp20xJ^@`J5_%$>yIto$7Jkr0r229&sAaudz*r+;SjFpByR+^-V+oB*DCZEC^! z4ucm!68^Ni1mNT=a7^j{-J;hhxR~ON^y{})3WbL;_qRH`MS8|i$ESi4{?A^$2KAQBXZXn{361j)7#jGs`tA}79E1oboN*QkSZ9%nbuqw9GaSj znVA{LSO#p48ARUHph0(8gKSe58makj0%W)iSH*q{L;xy3C_TpuQ+2sPjdKfB-bEj4 zHrr4v<%&R+h8PTTB^4Am;Z|ebyx-y3!!SED2RaNDjKR-|%c*qg0Ef1^hc0)R5kPrgk4T9j>%tLa=+kkk}Ri@bcMH?EH!EsNU)|OO|w0&pg)6s`@{D`#RA-wiS4*z!;}M z=u?~1ztk;0V|3pbgCA7|EP>D#&1-5f^`X%EzaD|RJ_FDOpb&q02IgjGq0wxbcS~l} zJ2jQ~OX{Pn2VTlD5p)n{2TCEHDhx$ZYLsHGRvnAtkK&tG7A#X1O|Vf~&%~kDU63p` zV5vV3a$wud?X`cuAz`Ilh1KpVv_w*wJt2B{<>jx&`hLREj5qlss zF}Qc;L6}{=3vPF>TjbBf?=dHx7=OQ7w3IVHyafwz8>YoH9G*S`bIn80PTI}|s-=M( z=GsS%F2g7hAhwLE2Y?foAE$%>k)6d3K+5$aCrtF-A+W{gX&?cRK>`4*m!R=w$V_&j zwqYDQd<>?P>T|7o%SLW)0NWw~tls|;YkqPm&5C}9rR>qwp*(CtCj9^kD2u^8Owuk1 zgdnVe)B&L;(?B$tyWeuJj0<^;Gw#)j`IT)>t!8+>zE)mPJ6*LqfPS}x>qq5YEC3RL zv}v^{eVGimDYbP>^;>TYS6=^ifS=Q+$6_R!=lbB0U(#+|53oLKMH(=^e|7Bm+?U~= z;c>Wq?|A0KDT55r4$i!93UZeK<}90Pu-E!mGT}`u+()FpMzEO|X)5UV-V( zG_)EkkjagwyW4sKa1z+^@FOnUtWgemXF6ritqe-Q3_z;}NkRySH^7Tal5lt27oOYu zVnEofzK1zvc>zP5yqT>d`i~RyktpD2^HM?OJb(|?!7hk&2o3e4d$9mW4KSxmYODIu zxuY<3*Az@W)KSVaBWgAqi>K?oB%_RuY*!+=$ATo{Fa1I3sxTF~fcx5y!sF}(SiE%8 zx8o(&wHFpfY!s9r=$eHkD_|kN4Xa`W4vE7`6#|%H9Vil|GO#8zl4)r0#JK_!&*AAB z2}0HC?}LA$&|mWMROlt|E4|)N>|Ab&G%EVj$xVeUK&W?`o|=I{zi(ZUXf)phY>NcY zTUh2(y+aM9TTKa;eo-6aeF`vGPHp}8;PaZ1z58@tz;>*FVht)b87L3~+i{^k*M@TQ zqW_4CkJ<#P;y+aZ%-ri2)wNyKgF}$o|NmRh5cez?BcSE{#~*qO9(wR$=+7^~*QQ^9 zVpwlr-fFa=QFh=f4?PK&l272u&C90x z(ykBy9RLKcNjCf2nWWc*R+%T$g7dHRObrfV2$9ss@1p%iIKM??QzEHi^2aK_I0!H^ zSc|sLe<4L#^OJ+uLyu(mqF?bKvBSy=KgzF|94=l#;Tvc{?v2u%@@9H z=9T;X@7{*9|L5CqbK!gP8!l)6*ST%c{D2onN0y z2J0F8>h`_u;i_6MD0ZThtUQMcdpH580-E!`@a#9>(T5*}rIkgvdHn`l{q(9Kd^}Yu zRGGoBmxX-yF^0V;>@>3U$IDn^fS=D1_UT5;%ot=+c?~fy;qc56c;?~f;E`j;;ri{X zkQbSm#b*SF3zDS)=~3)A2Emj^$nWPW@Pr^tcB(nOCO&sh-D~UwH+$FMc_k4W<%)h?F1kXs%tv!DfZ~Y zUo<-H&6_vj_vhY(v*+G6BMrq{?MwF6fzY^$0~3o*l6yu8E!Ay^x2py)e^^OlGo4wR zQtZNAr`jEO=Q3zqfL+LwXLODh`cLNUe0?efyPJj(K8dEei7( zax>Yfo@cLLbm8&oFT-I)1aw8C3o9R)Sqo9eKioP5%SufsP1YmSa(Y?A`6+RTA}nR# z@)Yr@G@yf@bn#V@>Un4yh6r3+{S*p2Gzt-3P z899Em=w6jqAW5|waJcto0Imi7W;#A^_{p{NS3bV_q0m!EUA}S=vV3T`BUT6Q=YtSc zhJqOC>nNrYPL36=7-{prSlN$k2j+?FI!PIHSNhOpeJ{=rTSE5d2FDiH7CN8Ie++MY z@N4+PFaD!Z^CS&EqM|vN_pBLGJKe_68OiB?h+jiyWo(pTD~WCQA>LzibTHiv&40Wd{EHsJVlUvqtye4>8556x5&gT=j@02Dyad(~gf zSAX}DcYksTTp?M{C4qExYZG_dVse*jQChCWjpf?ZOlRu97QA@$;`}GD)LXR1Eea&? z$gk;QLVUShDtf;s1gH`u&e~51#9For=jPuwm5rCzmh)?Wx%huT2DgFlzPLBkSz3@q z-(*poM+DMk7H_HlhhQTl#=;g#0P2^IoZ&_Pv7~Ga+6q}_hLRmG8Ae3~U%uT7nSYij z$Y@a6Orm) z#l!nT|5xe?Tv6{)s6o+zy(p~&lrkPY_4inB(9N&iz5>H+VC(}UPwm8hx=_QP7yVh# z`%U^TRRNF)upj{>WCD|Z*@LTVm!Qmy)%hd!wcmkF#n|lv1aV(Kn+^iF0ruOEg)Jli zuQK?;D@sMV)=)yS8f3|frGy~n-hWvAg;OoQb_d-; zDdH9xYpg8Z5J^Lji6nrWf7IX?Y87}jfICB=LHxu;_<`~F4@3{L%%t93R*i3}WfQe_ zb{&WkF&?�Gxb9|If>;(a2Lm|$00s~Oh8@>8 zGMGJ9lp?N@LIZg=MEHu1599QH*KW-*Y7huTRf_?14=LH>d+JxdzxOyQh2NX*!~DIy z4^OG*RI0T#kl7KEEaOiAm`8$}lq#<@|I`JhJaA_z-SiB?26$DmVMwy8tyo(9w3QSq3E+W)c$@qjCo^ zcKZXiNCMDtFxt%2O$X^*D}iE0F#Z@8H?*gqj_)J@8N~je77+2@B>-WOPgClPf&UCz z{4bm_&|3dDj;52c^50do0otqnXqhTaOB<+K0UYF-|*mpL$N_N2r&j_ z%{fHur#1j^MLn=GQC*p`5w(EX#U%eQdz~J8I?l@wp8X*^-7#zt0Z{rsysUcePztH+ zlp=jnQQsCKyp__VCDKf~?l5(ml~}PCTtA>F#7)m4y|TG^YAIk)koY@`0ZSzD2Rd*nfkNDVK zZNLGY$tA&5=u-R1hFst7GbaJ?5$fa(hrND<$%KHCIBWh`en7Tc0YsmjZ|S(3mUC2Vi36I*2es-*0~62jzBV={7k#T z#X<@z;`;<}zc0)TDc}&^xBJEIm!iHMmlA&qUjizjY!#b;KC#St>b*XMLUe%*GibN= zb^(xs0B$%`!)&QphUO<&qQJ&-{&8)gJ*52x1_l!eU{lbWS3Q?01}>B&kZHMmXqY|9 z(aspie3>H>59w;1F-inR2trI87$pue5D4%DVhj`#6 zLuWb%akn~Y!MxILf5aL%7(5HJ-~j54fYck{wrK&vzZK!NBY>;#fafXGHCj4bCVvrH< zgQOk^eN6aiS)HFY+=tv7D=*|~>G5Xs-F7Ngre_+1hmL^wr{6gN-~C^X@t0nzcl4gB zN(NgbD4e>(8=W|JLca3KE7DC#wXcS;^!4w-+Who1&kX zys%*?&HjchAOO1eUjw+@5zv^)fr~X*S)GD3>8Tzq4FT|<%%ijeGCOKr_Cyr@HA)~n z;=AqWnB8P9#Mlb+J|RJn(+JYX_jVRX9Y-$)Q&Y)>`|eA74?i*`UwrP~^y|+it)q`0 z6>s0D&%OSN`n#_FbTH-({ohych}o-$buu{dsz>b1!|Q`Ob>+y4obFG{3y)loe|F~2 z%9qc-EMAkZ3ELt21Q7Wcgrpb*s{6ZbhL-y~AOyY)IKvwM4*97HaDZWJB!E-rB>dxV zl(2ej0A;!ak39H4D2ja_a5<+wTvN}&C^2^rqjSxsBkv;=RuGX-RL&7(y9`-sX6-lB zPczm?AZfLDW4g^-?KW#Q8?4b#UtBU1pv=O3>2Dx$Fp&sFn#z8=!55AkZC!ilflm6> zuN;|GOLFi1P&8Z3(IGO>|Lk9L(1fMt5|o3|?889+pOQ{Dtu|0sLsS1ZG#MPxEeG*c zyX?W+K?D< zPXw^W|A^u70K(@c0E$uC`9AxnOPK#;0PS=UhFsSzT2Vu-t+;3kp)5oM0q-j_8Lm6A zVX?t^xe_@NXf;@JXpT4UJ=U83C;#xir=EZ2@N?<|>#1-Ph7NxhW~?EWDotHCQ^i~j zl(O02dApqs+HF2;HIqC^S*f!Wn258}46{;5JPlLOk!>iG0+t51L7PESoxId&L)!=y zr88G_)R_t+J7kV~J;{}jcJfVqPql8h+O`%P2wxArqyGH#*e$EAv_;#_pfe?;EYz8) zEYyCcUgvbD+4<|)nOS)fPUa_V;?mwH0+=iBB!H18uG(wIU}+uV({}D_{l!FMAN0`Y zhApxIs17@QQosqwU~p_zjou8(#u8*j3eCR4lJ@$S4>tEJo4P$ovh0oKv;qwiaH+}(&l7#opBc|eK5mJk3d1*k4Nd$NF+<^_CuG>1W# zgP3NprbqO~<%zcp?jEuSAD-ra^z2mYt6x9N9=tDMbBEF==X*DuZii%m4hmAr8LDj+ z*}z*fs0T=f2110Xid4RRTcHzs}|3#Q%{AN?G`}%vG<7gw_L!{2I2* z3*d>sX`M0ms`^}Kb$GBka%4we=%pvlvE$#IP5He+AOpEhX_{ z;5Jr)jkm+~0G0Kawr0}2@y&<6*2n`nktRcM7lLG7dg&zl#-H9ROI@p}%-YlK&NpuLbSgYX zk+`@&7DCK|$nUTwuz8=BTsJwLwWnG6lU6s>@Uu%lhGE&amSyl|Pwa7K)c{)&-R2`; zJ$T$UPlCq*&&77?J*oQ;;E|${HZIS1=cO#AC_ANi@Y;hC_JjDZ!NmZW&r-npNO%YD zRFw?sZoyn;sn1rO5P&-aBnCU3@BGRuudve>PO~9fX!M4|sYc`IGs|m>M52q8Wm}C1 zkrz=k{@T+0U-u^Tn7!T-iZj=KZIEBOJZ6vBj!Jlhju0FC1gGN(fwLh1)>zsQKEB<* zJy6n0Ci+5r^yEkTXDFAXkEsMu2OA8tI$Hp}HmWl~ft33`h_G!0V3&ZMf>Z2J=TOpL z%vyygXHv!=xz)cJo#ZDUVTis0a9XDj{ZZxk!cA^crygRF5_|ob>#xJ|aKS{B;e77_ z*t#kezi9=WGG2S%5*46>W0 zEPMTKKZ8&9S4`W;h#QinbFCY{%TaOcO@K%WYwM0M?bqX~^G7RK| z0PGKVYVhRv?ZHh`NR;{ctjOSS`_%tWXDc#g zpSk~^Oo#V@cg+o-VkL~3We1$x!kc32$6ttjZ(2|3q zmLWU5A^FiCus`A-An^nK06zJh5xe0RN7&(wz&<#3W_jGqv zWjgP9GApa6=Yl~u+-Fdzs=QToRh|3ElXJv=e2$5M56fmob>djp^4^H25S|(W@Q(Pq z@#sdz`Lx62;<9=Fjh)$jWF5C$+suY_?q2;tSkHjd0ZnbF41zo7XmR)5*+cm3{-4s; z{iNFuA#l>#53U~}X+s}%>94#rKmw_N{8{`zB)QQ42SSMbWVQ5vY?Ke|t#KQyr?=?+ zZBhZAOMz3>b35f6Ey~HC3I(bOPX__uIsho&%(D_$muGCy$%;!V7{^WM36b8eLtwc& zMD9Tzt@y21B(iP5s}y4Yr|th6itUjXV7}$w>hw+jf79|0A@Y+n@*4v31?4aj$1@lS z0`SHPA-{jGi%9@>72U%kKEo;l^DbT^5jfZ5Q|twJDhPmlaSuOuNY8a?#%83Klg5FSbrn$U4Ars;5e(*>$OhLf^+W%^vLZ)eZ7UBSXM)DR0xNU?)@H0Hcg8D2U`B= z96}Hq0}~>DU;wmggRZ|Oj`uQ7_H%0V|5Y;p0yyr@50U~7Py<3v-z=BOSM-!>rU`*5 zS1|~d`>$1i^OLqRZxS%*%G4A`m#0O41{jnHND_ND6GV%-K&C1T6e zUopZ~_PvzxoCE4<3zw$bgu*)v=4%vKLFlDR0ofcs-zy$+>-l+KUK z14+S%|Fv3og1~eA=ir6Sm!KepCIU|(tULjb6M)Y4&yq<6#f-52+1}Y-?ap=_VsMVb zxU`l}tPKE11)|8n&=X*-|Jabo;Oj@9!noR7O!Q9$|IC^26B_zLOFyA)mVZYKt_un^ z6rb>ZHr%V=!U_fenOCvV?Zeq;o`qhgr=+hSkPFdm&O%+?BC-$gLHfR29xjp!YF0Zb zKobwYxa=Swz=h2pz-BR6!H0M-th@>!Cjec&Hlhy*6f*ulFN#Y$>uO4LgpjTI5F)dc0xK5(JLcgdl<2&{_bt_rHhj z$@ebd$AMXY0D|;iF6)o{po#6E?+YV2ZbOq3eh@Jr^0%t%e07#q7RX9)fi|?`uNKd?= zO~LUmmVBlVUK;4Ms853EKLvJXpv?%Y3hhdier_Nk(M84irw@J)F4tdd^oz6p#6~{w ziiksa2&Dj*>4#_oA8ncKhYf`C`xG+DP?X#iBJH>;v)N|8%G}?G@`B61^21l*#TPEX z&NugA=O4a<-UIO@#v9Pve+kY_w_r9K>on_z`x6=bELWotA{xoef*+Y(50L0`w1}vz z%fvPl?IeNN>+MS!3V!t5kKxwNO|_Er>RM9f!%7nXi8|Y#zE7Wdrjt{c_BJ{jm&fH^ z*CJ=lOK?U#@GD7$$S*-6J`Kjj>VTC3SvHT z%YUS89EnrGFQ(gX00vH`3fs2|MXm%sQG{N^|R322eQ=U;vf|M*}3 z7u>#gOOZcX2qG``cXn>8br48q9#Cdpr`&RIYYPxlC)Z~nnSQwP`S*KWc=pVeBEnmn z&%%!{{1sgK;m_dG&;Jd4b@vPS{nx*PQ8j+jPvo({iW7h<tygh|L{MaN)=$Gy#P}GA9kOoeU^1NrGtWWE?djI6#Z*H3nKnB;J_dJ zRRDOzN5VSt3dpg)8+|#)@(<1OxJ}#q|F(%kk@o<*{ldvVYF)gqX-pDma{%}0>36T7&#jja8a&W50xJ@l2jp=MA zR4KLK8{FT$2Y>kTU*N{}b-AtrTzc`RaDMZ}RasH-P_ViZfJp#S{M+5^;eOpElnum( z@e>)iArWH6rtU3UL!Xue2zcMWG3yb`D6Jg;f$4v3?=!HezGF*&VDvM4Yh1*(0XN$q z3KZhTh!9~4S49=u(%?AT;FfsIbzEiv}} zz3s z#@}x`I4^)r0Uql8974ReACfI9SqZnsUmNd2)6$=E`vJ222ReRa@U!W@vA*wY013BW zYzWl-`1io*o;V#3x?~2|S6Kg-Pp$*-#m*Q1@a@&>-;5@sn$?vu=&7kq@_7mRUWqa; zaMrESYDEDwL(m!T2!uLabUq|gnBKh~5Rcn``4{-tfBF#my#cN2@{SmHVjlNXV-j3h z0w5;^8i-mUu`-uu~pJ#^OjN{IiVqR$bAYvlKCLAx#>Vwfa6_;&bbWmI&o zKNnJzumL2?5(YnqwGV+xBH|Y%Spq^5&$^?=%0G; z(;YJHu!;@xyz|EXY};7pr3$bQdfh+0T91tb&=!5mCj4>W9ndvqr|WKx{^BkFiFp6O z3*h1bbYl`3{H*&fH1svOJ`(T4U>~FcILUy(HA1o>p=8o!MSXR9h4p`pwztLhk@%_C z%wtHyqQCGUVmQBEKI%QO-GQfw`%73&0-$j6eX>2;%ZrVoOUP_c(9Wf4JyJUUj8B}~ z&LcYyBm&RiLqoY<0MuPXZMVnQ#1~kCO}TB699#P1NWdVYpbhphA1h6|{hBraY~lBa z?qdU7jDRv^kqrtA&AUOVu)CBQJ?vM3<%<(a{H_L6b0KOK$^^rIJ;fTM68!+Yei)Q!f zzM@0Z{t? z);YRg6-Cy~`UNR2mu#Y_g*mY;lfsBxU>H)l*Y5bbt8oQ z31R?<5F~v3p)t?~@+1O&Y#ndv{5a6aNCwwy4ts(K>~FBVgom)26M)um>adb=05$np-i0fZ6465)2sd$3p8Reo`NKL7yI@!O1m$j2YA z@Dqpm#xwp>Za)S#0uX{Sak($WZj^1-(?QmIs*F@?c)YN31VAE~)c-GDJevVbdllnn z7_VQGby5YGR-=&n0|Z7r1%VNep=rUcv1UcjBEp=lZ^N4m!X91^S>qU^50_ZW+8Y7{eRjZ)Vf6*o+!Ngm;)uq6$0iG zP9@`uEmM3duyO=ICII={cP^7#dwE_#*6-%sUsZf+basGAJv1V`*YhFJ?ae@r`%B=+ z`mfPT8WKmw>RGWE6AmT<& zvrFT8WOQMGl3Nde_xY0m!J95X-P7_~jeNKFzw)9#kcOqd>Gs1?KuY9qa(!+(&vW}R zqoUA+?_bvCS#fiaZPK&-=X);{FQ0iXe>o@lRt@7q46`j-4&1XFz=k^>Z`g7@%WVVw zKN#rN+vtB)E2~GQ4cIo@rY9O({0&Ttkxim8(B-ylFbeBcotbc_>cvfrPy&we$j`=8 z*BblrD7kX(2 zX7GkMy9~AXF4-~=ft4cwHUUUc($0(!q5l^@t;(qq|7CjaQb+@KGLQs~_#UOaN&t~c z;B5iYj_|O&ja+{acmUFFzi?iF1`~bAQ34NS-3Lfp_^}FLMhSF&iX?&`4qiF)gUwg| z`kBtTSI%^{h8@~1bMb>GGk{D*JC-0Q0%SCU8L7l^Ci-PCnaa3^LYz<4T=-IyQE@EW zPA0k7Pee%p6PY}N%v92h$-XR~sl*x+*_Vp(Xs(`p1$ySCOx__U)W|U1id8@vRbkW> zuhjg0S+45kpPa2(gHF&X+NnOKzLa;wGd1}~ZgOmOEb8TtS7X~SLZ5y zm~1Pbr_Cmu1pE3b^{PtoD5r26KIfbKGx!uH(n~{Js;VakD@6co0+4?3T{dJ@HwPlf zF}o#$jX)j}iTb*K+UtFRfw$--5ra4CXrukvMi&yIXC4rH^jk|1?Ra!Zn@cVf1K&M ztk7j@yi6xyRatdwg-jAj<))BMBA`H4d4Czp6hg_ml9cLLBC8xjCFrR2RA1STfIMBKA z#JI&_%sX1h$|Bpyh=v;ei;x1og`T*u z==L;r0TOt&cTP=Ll@Lod#F+rG`_r7;MqrJL9Kzag1_Q)PXq!Ka?2_wSWS3j*^6N8) zh;HRxJceDU6aD%7@b$P2J`cYP9-tFPzmq3_GiqxQnammIxFEC*!TqlZwBHc4Ift*8 z1NT-+0+0zn-n{%axqf%2Ae{CyQoJd}bvprQTt701PrRR>7|oh!UP~;uFabe6q((~u z4`<&4Hxfl?`A2TR79-%iV4v8v*KqrBKtVn&hCdog0&?wxzyI>Tnf`{e$zz6&T~=Iu z9Jga;S!`9;a_+{#=k7QhKk#cVy0IhlIjM2l`kXXK1z@1YE|iygNnk0c(Bkk8Ji2uw zEAmN4Xnq4ivdfi<`;X41O)jYAlXiiu~Xhkr0Z_3^OstwCl&0I zOyP~VeYm`rmk=0b#q~+{Zq|=WZN)4&bFJV#VcV8ij>{EU+DQ zoWu5c93aL20&Xg*UK;Xp=E;ly5>`h7FcW|#MV_&`5c>aYAh`Qal+jOAjq9C2#0TO< z;UEQAp#S4Nfl>WX>}s>1sMY&p-+$!xLsCJI)DwmIN^q{fCx ztwnx!Z2A(er5)T(8rmdraOVWsLeRMyNB$0b&h0Zagn;{iD(e9`;hkl#hEkuxU@|nJ?CCwk0hqQpcRIJ*4+z zeP8zu>;eFRgrM6p!TrBGT!`=7u-_)v*D1eZseq(8eVZgeL(WbSC#KMp3_^Q?=h*Ri zAT1z{?u=mxslcAQd`C_^;x(f@@0&Af5nZU#{io{(V~&z-I}PK|eLjqDen`^lZRq^0G0^mar98nPw4#(sQ`{91)L=3KgsqdDH%xaPlf(3 z6N;3A0LcHhmS?Tu)sO&;{y*(*XS^oeSv}j_$U2v1D(a64LifjA!`zuxrxd+Z(r^|B@BFZnpk*`HXox4ByHJhxw*-`^m5WC&b@2m}NH zBIHb}0ao;f27=NUVGnTWC6T<*CSB$$;dlnU!?b@KZI25x@z;gVrI|_T|M!xRA;CZkX@SG;GBCtFG7% zfP!U-&-3SyKQZ^eY1NO207g`#|D(hoK-{n3PRw_{e25d8dc9uXer(A{?GM!RxqBug zX)i!T1C<>p=pILRKTO*vK@7D1{|!h3AX94!RB(QIJOBVIKmg1_a4uDnaOC2ova&REqKM{md^oe~W= zueJVextP+Yk?s%39cWjGHRn3;cidRN&$h&fPTX zg*rNo&Yb}fVm&`J=D|EYKUIdtcNl~9D&otMlK*Mx`irzXZku@^2|y3NPzFG$|DRiq z8Gsm;UII`FK*YEGpc;1aBHN&l|3b!6%8*@&(KEiMUXuREQ4k9jeceXD&I_1uJ#k1) zB#M)M05m27SxJCE=mLzF><-Fcj<}yt2Q-KG(|w^)9_#rnqJJc!LnI}nM15|h0PbxA zWD&{0m8JW0i$ITy>mRq>;}ZY1pnps0|B};Wf&gqUm-sJX=?TF5@CljRc{O{k)9uWl z90(r$Go|+{AHYmJ(V3bf?h!u>_q7&jZw!=}DthsuiTdM?V+Ha4$QBSx6f=au&LFf) zcDogS;1D`LL^?n5#{d?An|gjj?{}hq(|8xe1{{FUc3NzTh|JUT4gko^L(37d9-u}#7GFEX|4H&sY%zc!8V zDEP-&w@uU^5=Uh~mU9V0XyNx<-`>K(6MpavQfnA&59e(X0VTdCCiz$u#s%)Ub}f2; ztmg*?KyS=T8vFvoonhbh2U)`(L~WC03GV<;eD#Mh{+%|*KMAQo`~N>z`hOwx|FI$f zONIOrmf8j&pVs!LpU`3cD2M5^FVN<-lJ9qA@Q+jhDj5kVGrAZZKM4FG8hMo7kL?0t zQ`|rH^&b@U(=y>F9qOCX`O{&)&13M#(A4vf61uBUG7+?crKE#={DD4fjjN3^@cMsT zc2fHLN!kJ)ryW2NfIfUEDDx1e#{IV>6M!%*wFGbl-X(8ezE8@#tf+F<=cIVER;&JM zNve{zl_1hD^l!U&hmK2?Kfq7Witi1ceewyXVw96dFC7hCchT$@B39-KG;5cG>B1DI2GfYcCO z54TUkvT^gHa{CzM1fU#ln*boK|Mvn-acN+A34mfypOCz$vRMsXo-vgGL>m6MTC3MA z0Fn^Z}XJW6pJq;uSrY8|`S-M1Hlpsq0%__303T4MWg>lXnn{(mbzOYQ%cixezT0+1M%lK^lz z0q7I80&rPZU7@H9gb@6S)chs#%iN0ExMsM&`(SZS0AmB7Mgky}=J0|3e{lBSkVrJ$ zeuvZfQ9lSddOGWF3V9FK^C6|@I|Lyf69dFemHGCeB#=PxMjeFLwg*p|Tc3vhpTP~~ z|Ca<{w!Hekgr&6sJpAA+?fm3!UQD1@lWbFP@>jK$pXl6u;6-p3=wpZgHD4q(hF3{A zGQ@s#AYU{57pz`SklW9eCER}VgMDmpPE*f^#H>8P=T59{=G$9H&*wfE>cF5Ki`;zC z_I`XY&(7}&iju^(0ei39J!k(STHtZ(?~BwQg=b4GwF{rB`Tw~%+gx7#U&2xnfOo~? zKl|20QtkC~o>zVG+5Ae0|DXu~@Jj3GNpThB{I|wI6QqmZDmMfHhyNP%48ne~|G&9f z?>xhwB}OQQU$&L80nw~HAMFRw48bLiV6`GGz#JdH9WyrAd87=>%n!%mdohBWIxM-n zv4U}IXZt=NM5@yw1P6_Ol14zC0Q9;d0As?sdx3HWlfFJ=kZwjV89d#Jz8-%i- zbEp4vCC;ZZ_b5@?>i)(Us0@GBa7UqG14t(Tg~;va#dxcF1etx>bpA+>Z|MC1(RnHg zFVdgA!jJ50-hGEfaX6A1Fkh_4b+}J3mOV|W4yo7uxb^pwPzx4;H~}bMt^}YdSVjqe zT$U4niXMf$>;S6=g0K8kE!PDmF?XbcyAQJQk!qoxB;FvNr8alTZ!lb)5Wj?%o!}yF zKrWGG#r;$QPitjY=a_rDXhnm#2hO&OB?Dh(*RvzUN;J`!hY;%<96S>1^}yhB2*fTw zx7kJzsR^*WV*Nq)b`Tmbc>>TBEFS^ja{2Xb@5%HU{XeOvoj ztjCZN>ph~k*#W?*5KW?>pIR`{CI);BHkkdTnE;7!s|80Y=g%owx5*9AH$L-08PR2 zNdWJ>E1up}3Us4jjBGGc{X1{KlRM@RAyfefLIjIgc1?i9bzEc`3B-Qclo^&x<2-++ zYhd^z;oN*cqP^zyXpTLQxuU*LGhk(TK%5mdh`Fu#t$?|7i&!5g?r=b&YdbOjgt$IL z_l~a%uzK7+2AcpBmNx-t3YLxlNd3PLXXu@B)XhmQ^ndu7MR*7}Zpek3G4cA#B-ZE! z(K|&rrgeSq_OnZNr`&!xly|H#zm z91;jlz}Gd2L(@)>gyY%1VAMK*(TpT=;s9^U6S)nQTPK@ zXRy0{K7Er21kz|C4uBi3>QjBE-F|`24@l=fNY5u$CTJS&4ou9!(eIfvCAVo<3yp6n zuI~^xmM$WK;faFpmqKvhyg?L#dx>ui5#InF7owjA5zqwSn)ncgg7+_F0?-sJl?^~X zsW0GlGRavE8ORAhuZfRk%OZ7{NHdJg3w8J?qA!}sH#ht@;r2`F{D|1h)%zjT^Rb#7 zs0ye|H)zwPLp{Htx1(!@HU?;p2N=Qe_0hGWK55aud7sI-0gJ+Mbo-;!9k;Ipp8#ZO z6M&{*sR+Oo@u+_UH|WNsDl#tge}FgrLYM7+_h2QS6cIquLa<^_YN;lMfgoGiyzr=ku5QH?&8j``|LdfGH@=?Gh z0A(ft$dV=iO~FzTfOp_sxN$4bCVAGO9l9ZkE@RH$woYDh?Y-FIoB;drHYWB2v;9aD z*ý=B%U09o>uLhfY`GJF#IQUBz$E~AkQF)U)|_vOf|mnhA3(sxF-OJ-d=yaQBKIPRBK^{$ zKC(45kRO`JOc1ihB0t(S5In*4TPNID?hKG13V2*dBKSdM)42!R)RX95ep3X+BR{0? z#SPFd);Gj-)P5dK|{0;8@bbv zlcy0J&~@9NN5Wpv_)QT0-bBMiB!-m(E&g9u{{JOU0Gfj3hyySQK(@QxtiMOQoWdY4 z;1$VvbJBrK{*lb>sXC_aSV#Pa8wBTBOZl8KwU{8$dvQZLWal*G+Ed$s2}q>0&M&eXBq7~0S|V^H&29oLMR zeXYuBQ>XW`t@y%ao!r}URzX#p^IF$evdpxtP+3`S{HS&K)7|Gf0jSOZq!WN%5tAfEmJ8r!TTz)6%FLEOJe zh^i(@aeYly#?7ilHVZRFxfz*xcNFw8Zd|=TovE3J?-uXTvFyi9d;L3Evu(7UN(_#a z05;%b@&8C1uay2TVQC1!5Bd{w1N)?AqZz;jwNTo-35$UP_P%9hPfCK@7L|5(V*lj?WpY_e96`*N_mpU63BpQH-|O zPFv~uuCCr{PaL2VduT>dWdtb)Yv0$uX&)vCT!n%Jgr$q~dQyb{5 zw&&u0#j%W;CSp&-o{BwXR7oDH%#;(`rk-=`#-K`i2-;MBFY9@&iD8)K|UO;?j`Vg$8PEkTF|QJa>6 zB*Lo`p6<(oCSkv5t_@Fo+>LLG`*B(c0=^$q7T+IF6+S7j@1*VgX$308e74FS5^YwFr+Q@&@Od7I%sjuh0ozvTG zmJ&vSb_`vcF`npe&zb$_{&TO3@t~ZU_F9_pb<7N4-?J3kIqqY|k;X>bUfq-W$CL^o z+bCls>c@=^qIUKg=EpH30&z2ryk>A8Oqc1O;md6qN6*BTrJl0`{0TFd-(K5TDe7N&`ui6|vOLB5PXZd-a zku6GiPavpN$dz4QTH)tIHm7dEz9}y*Lv2t!tK)jvADNJu&S4}+u5H`8ZERgv$K`cc z@2Xk4JUC}jb&WdV!#WxyxQ|3RqCzaVzq)Z5dE$wq?2iVo?XFJT6Kj;!bshB6)vWQX z)Od?LpVT{OYsU;ZkooBdOvL#kvELSg|6TEdAHfCKhpW;|vN%$#34neG1l|QAr2v3) z-LjqxSXOTkD7rb}8JFlUX>RARBNxYiLbI0gvZaYC?}Vi@Th=~?J6+&<3zfUEX082Z zbNelFJ$+Ix+&(Our7m>Hu}VMK;qKuu*TvM$;MegaeRT1P4Ys7wL=2~>yS{u0&% zz&{8@1Oye$ULHX{DItG`17$K9*kp^q))ReBAm}^Z9jWheuKUFL&mHs8@hEPtd?Gd*2Y6wHg2z@Q_+$MWPXNvc0&rCw zIjjFsl7FlTK3dcLR)(tYHmnSi>6Du!c3PVGV0o z!y4AGhBd5V4Qp7#8rHCeHLPI`Ygoe?*645875?sh+q_vkp4f?(-~^mFAtXUf-Lxe%WtX5($`5Ekg?}J*Q4yf36)K=g z6%rDtPz6d0ZADR0fRcnjiP};SO^Dqn1hUwPgB@?w_ISqQ@horNes9lnLWl`Yjl_L= zdb8Yj&v(!H&UembIAcgD@mZthS{TZYAP@mEX5Hg<=v@)xy2lxpp&v+>OQB0OOea(6 zA3S;2{V(6Y?G2n`FvdRld`asJLaCpdqemfTQ5zmFux( z=MyMT%sh$DG0q73*aVb>O-Rh5ip95Ko%$c!2F&cLv|R z=H}uT2Eda(CTm$7neKrrJ$#wr_a7EcVD*v?RGe}YA@EQ|Q)3IZz5gbhY5^(5rS*ne#T`xwAdiHZ!KNkR> zc04J^(WiU}$plt7D_BqN5LY!a&MlZhh%f}&7qz3ie-Hek9|3sk3j^Rf7D|P2)UyAD z2nG7i3zv@BhnW$Jqgc&jCX~>mK_Dbv>D>mzDIz*XzAyj*F+3Mq7egZ$d_a3Z{t-~+ZJcYY0 zhD;1teuV4ST-S|`b`8sd%g|O?i9$u-y?hV$+r6mpvY_a{d)kXCgQxo_@jQXGX-^Cb z0?@qrdfa*IZT#66|MEblF|hP2IV&Gw)+1LvQ#|qJ>)Q$kzSjHaMGrk1rgnF-0zyw! z;zIFb7-7Nf*WO{BGVkhKK}t!W94{kKJTSrC`2fs;_L~>`F>rY3lI{b3*YNQHXo`c4 z%QN`rzg@T?(VT6T4UcW&+A$78kKsJy{C4;(E?p^n=95+kconaG0buc7tg3y?C1kTWivuxmCi zfY;rr`|_vfZ~Dchf5S?DO>#{POVEZzVMD|L$PG>~Y=6k73neO04dVQb&9BEy11i^` zD>@3<8B9+VkI@nr%>giW;3x`e^Nn^YpoxHDN*o@bqNBAEIWr^<`+t7se23X$GBE;w z)if?_Sxv=iE$ZkR_r}$U!8}C2Bnc1I_?L)CaX|ni5{d!q0|iQni?cZJ+$;S`+bv5? zPmLppNsQGjxHXDWa~=6^2{1nJ%$$^s(tpB5Whcv*mpjSrt z8A4r0z^SsTB{=;KLNz>_gu(Jf>xX$t^Aa}Pz=u_JfW{QiHOzqZL|U+|XEPi8tlW6H#f5NTzve z`_%gE&VlxW(Ap?!hXbDfN9o(b3WiD&+z()-x$KbzZXk`4i7yJMrMy@W)GB_LD1J&-A$3 z2qaofn1gX1#@Mm0r}v(g;(0rwXMc9Zmh7avB{x(?Zpz2iKmL2-!p@*F6%^S@ExzKp zp*<@e4W0l?({2^&kqYF}7i2pg#AyJOi3TWQEI}bMVo}N=kW{r6B1Ct7e@&E(=y&$Q zcO?eQwGX`WpB|>GNlJn;cI^EF(gZ%`o3Nr-CR}Odi_yt%BBc6OLB9;pioFv^G%*_F?)GqoL<)UblIU&I?s=GapCH%)op* zgi|HZq-f=Xg;|PNo z9M28sTNfoA51Z3p-K@QTBv!Y zxj{fx(5Lq_ff9L$4h$!aMK?e7j4Zj78}=uC15W*Ydej*@^?7kT)c3t6C05GBlRi?U z#PvxXNmE6_U{DDVr$dM&o=E9N<)6IaQHSJ`XMzaYCo8j4&yPQsk$>;)_iFQcz>e4* z1lZK6-IVrJZtC?kL5Y}wD!I}!JTxQ&l#(GTHFCM-AaB_ykn2-r8>Ur7ex?T7@(@-+ z5};s~*a&g*F5}(KuXN6zhSHA6qvDU-N6nUo;v|Pgs;LvVbpocdpu(eGi^)*o)M-iK zDJ<|zx>e@cbVRXrR_DZ^Rcq3=YN%Dnyeq`)`7OF~`0ZJmb>^2Moq9C-sqXqrlX@>- zPS_=j3LIl0$u|q$M5y#c1m{wczDB2GN(M;>7lA4*P$JgzD4l5$F`EYTqyWg-n?we^ flFoZ))`I^5HMp-(*hQEy00000NkvXXu0mjfoH>WX literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/Posted/images/posted_add_48.png b/retroshare-gui/src/gui/Posted/images/posted_add_48.png new file mode 100644 index 0000000000000000000000000000000000000000..0c2418a5311c1189b3bf5a95846eb33e2a8ea8b0 GIT binary patch literal 3658 zcmV-Q4z=-#P)>?9aM76%8%^`68_GM@2_XP)17_vM^^=e;p@Y|q4T zCX%^V=iTdh@80|Se&@G*-?;{U%QvwUH`zaR;D#hizGh3|OW2kW0vyuZTquZ47aH0; zOY4!rk9T?tSV;s0^+w!Q$=+n-)8;B_O54zesqV z2kA)s>o@=9zn9{ClR5vy?{?xjWU4@_Qe;SBJ`2H5ogpt$Br3*0sf=Ij+y;Nj z-?~%)-u4Xq?B%D1_D$`7caWv9WD3Q-P&SlQ$hn)@kRpf2S!hLVJn-lP9h7kJk^$f+ z{`%wH$>BuCh-kQ@ZCJwMY}h^H&AHiz23O%{dwz~!GTetfM0TkFXl3p9&&5roI%k+f zw9JOh_;-7^mh&@UGn681d~PG?{im18_$2{wymS2exo{RGyM$0HV}1_+0}3{0Lui4q zfidhjyc5B+ZvfnX$pEQ_1n8U7L*Y5fU7_ zWB_#2_6JWUv%?8udS5dBozuo^8czU2_5fZw_7WPiGeDKbKe}}B|F!}6dGq%h(JZTv z>Xk`TI!zM)27r>Ndo^s`{}i-mF2FCB()hOx;6yU>p&)Cr(ztB2179eaQg$_e6oV84T{EL{J-^2(QUQ50WrqF;Oth~O4O77F8avQKj~hGz_eLJ359f~odQ{|Sbc z7H4^se-l*#sbq*M0c6WYC9I;5`CDRW7X{#!2kUlN^{z+6*v|@tS;*Koowz_u=FEnG zM#7->bpHaACKh(S;U+ZFsao*Lt|_lb(}dSE9A)v&1K3w2<16EKT`CtV+)+JPS}g|a z%UCj(A*TWDZVN{{Q#d*|iHXJp+NvF48n2uUz^;;V5P;=bNXi6I#AL9=TT&^D0@$&y z5ZArO(n*{MujJ_m?or~_+oZly-O%p7I<-D$3^l?+G`;8CJQ0qSFtix~VVJ6J#>`H0 zorq$9Pif*Oy?Hpj(MYRG`QzHu2n<78Ar*-!#!Ca>N1OM4V#}5n{_CIq?OFfse}B=s z`>tPzlXxQg*4;bA_Dx-tPqkZ-pN$X1^&h{u|6{jZ#6+f+Cwmt3s5faysuQBp20-?< z0c?9d{L%yeyLWtO&>5GEO+(76toM0x5C`@iWW_1LbS7cFZ|(W6U-bv8J`o82&-|oI z1F0tst3Ea8;re?AvYJ(A&O{VJ2`4LtP6bvhTZ#8xebv~0`;|?~6w@;YvDJr$vAnwC zdj}pn@X&$){_x9BI>(CmleINtSUJM(TJY*DC#!Vu!gCWeez<=(b|>wXe|);SpWghu zbH{ymeq%#1RG?C-qFgG$^;~$4N4Dy~u)m$juQBV-AV_?KX#lHRU`_o>eEPGW`Pg69 zuE6CS#&Pt3(blk7nj0q?`0Cg1FhRC3fYFs#m7hMet7273=o&*a*;7<=d_dy_XLpF5 z$&YwrN5h)=;rZ^-4gK^h58ej3zQC$wt8w|VE3jr{Ek?Xilq?TKGNOOr3aBiQ4OW7y$rhhy12z-AaHOuuph2PO{w#%1RP&`js9J>IHfS=~a+tSmSK z)d7tohkSaRWv|58%}lIX0g@zGFvw?F;}7#E*DLZhSzP7N*a;@Cvqsj>LfHvsGb0EL0{@2kfA#zp-9kI!m1v)G$ zGsiiP^=dDiP^I10ik+DGVsT#UP0vjPG?_$9QQwFgi2WFiQiJTZPxfpYLGsy_O->~lK8C8~8Izp0RawluH%a1`mGf~yg_Tt)3>kwZr;M2f4X%0p zBy7^UnDo*b`pH7xH)O7~+C%cL(69|;HbchlAT;YN?A%$FA!ii2hdnqg7o(StFo9QK z`PfWC>NO^==q0gXsyboU=Zuc(5nQ?UO84Nrusa7pYr`E^sc}z~ zE9)@GtS_fA5QS*0j9^7RI?ae)XaUd8DRdtS7Xpwa+23s2_Uv6ssndTv-JsO0736FF z;_4giVa7PE7_1GTI#k7Ecmz+}^ZfRBF5lIYbU?r0%@4{`QPGwETrh;xO80)-4=_3? zu-s+x+7u{J8Pl)MA=omZb!&QKxL}TU?hiZnk^@tEpSA7S{S7&G^~^0loqfg{FRy?X zW~;YOy?*WHJ&)nLTfYy%oHlwuahf%|j!8PNR9^VW=67Tch6mZU-5ZX{EioT17Y$&6 zZTZ#f>i0ge*|OP$Is+*NtO`~R58#ElCs8JusM1(PX&A8FWlZ$MDU#$^^y@bRa1L=( z?+}2e4^4c^Vx<_Vj)Q5zc2L7JbKCG5sleLdVG0?=h+w{04v%bpL&ap{Z_{Y8duldA zO$leZa(}S28Zo9W)T+0l2bBJ->oA3=m;{r~)&+JowqQ-o!2n!@MGl*+(y|OKX5&Nt zgGKLWlqSKNdlgi6W)<78QOV|Jc+Z7S!UbucUDX>0?Vpn za7q>`o{h2@uEi$gLL_?gV)tY$idBte$Tm@oZmXcXCBe~$r%;(>6LTxplFq>18Ci!l zTVi7*fC4T{&k=t+hNz}W+!IoT%o1?S4AA?b+s%^~)$YaaSxQTP{^--2|2a&e-n$#f zE+*t04p*k7Q@HmmDS&z;*S~HDw#9gLEVHE2M2n?*tTN1M!)}vXNX;53<)Gq_sy6ed zH{YD!c<-M$kvw7DgioSue9%i+Q>m1qbld%++IiCne^Ry{?P@=5i9Cef6YRqy!6qR; zAWBW24YS5ewlKP=eY1#5E{PF2 zwvvg_eB`J9!MZNR53P+_NFgm*W|fr)f-bsbpms!(62-dX`lR2KKTTig4nyiBxm%bE zvu37Ahj1AV<7KR4S5g-Rpqouzr=2b;a*(2()YodDR_1w6=k&uy%3{7EdT50+^6|q5 zWjia-Arnd1UGpw04mFE5b;#+unn=rfLaZ}n{7MFX&l_@>-FiHaqe zqyb8NxF}qtMc?xlLG-$+?psrsSHc__nXF?gUN3t_+p_ltnUsO|VbfCbEMw0eavoTW zcJK3I0pwoy_eylPsXo$30bPPNiA%dJnK6MSsQ64}VNOtGxeP1b*5Pk#k~EiUCNs+> z%#noU*Y3@l!jBRZB!5Lv^pD(?HSg$Cgf8p(e%D0<_@8Hw{!Z@e!nHl~e;|a370M4Ol}+w% zOPw-aJVyvk@vkhQS-M%4G`|xnD=Ss>Nm>+FwBn4oX)H@|s_J^YJZxzGNjn=5DnAh*LvF97}GQ<44$NiOlo@1_` z$2}5e7V-E6^{gpHLTet`#H3k!Zxfq&amH)OLWPl6qF2MT*2eHtkzVxPcWAUIz2+7N c@LRwAKas!w<%8zq4gdfE07*qoM6N<$f-DCZNdN!< literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/Posted/images/posted_add_64.png b/retroshare-gui/src/gui/Posted/images/posted_add_64.png new file mode 100644 index 0000000000000000000000000000000000000000..d87421a52072905769ab2a6a854c7da4cb6c1d83 GIT binary patch literal 6423 zcmV+y8R+JTP)eNxE){HZ)t+hq1 z{-btAr_hgoYFn$F(W!Mn5v15ssgxKJ0)&JlB!Pr%5|Z7`?&kfx@BO~#^!J?mzMCcP zCLtffjJ-Q&@B4Z0dA@$n?|II7iT?li)jq_0Z)mO0`Xc+r_MPtS#kOVro<)|HmQ<2# zEd=f>@K|Yum$gVGB~mGgnv`1xH)vWBdxA zC1kP$e-*DtLG5q}{p0=r^j~{k-2HvKSb(meH`%=(c3o9T>fWkUfeT-u^E%R@p6X>3oKpuy?_+I@Hz?R@Te#0^c)dD9t%sMlWsK^n|4 zKg=-J@0jq$OED!>(204Ch0X+&fImL7*p`42wCo}>yaT}Yz>_~D6=WOX0U6DQ$M}Mf z=jQ?!!2<;5t4tQrLftav9b+7z$Vwo5E;tLE;m@Mk)<=Lt3DrV{UYQ)FXJ6RH==kVN z%y$JoMa!hs*=MVZq5u}QlXhmkpbWyZK%I{NuIb=}QAwQ1R|#&c&ercLK>*=!C!+CI92Lf;3!HJ5tAD4<7rPCdV26ab56)tn0F zfCLtp$#OktUK0Tv9a*3V!1yW!bYtI~bq<7S9MG1-PvzE6$iv%vfCCrR{V#|DG6;8Q z@kGw$;jYjJEto1@(TFC8l#C6pN4Y}@6cFp2_Ra{dnfocK+Jp4M)QiX(?cDk?jY0`E z=J zkl=y-mZ2GbtmzF7f;b%AF{w{yn#(`(Rd#EjTS#>ZAb8RXcw}be$ZvrL+m1zt>PM*M zHIWC2OxzRV{~-QH`Sq7ww)A&>(fLxd-6Yk+1(lysZ_tw4m(WOQNKcITEaZU;I0%QSAMb$7d&4{05{<>I&+`FJ& zXFx%ctZRKfbEKqP$KpG$bdDG@HH+|UrGP?uq5B#i{X}iqqK@6BmTZz0f>We9n{0b+ zst5IRp8t6(fNT4{Qe>>h%?y>qwm0>8j3dsO8=SuaAkk_c#Sh|fqEIS&F0FME z20df|#D1ii6=v`ZSRJ3uFjUGdF_$=|jnP>FIk0ieY^UW!GZ}!7XK|mBAjd@#Er2s1 zywVK86-!fTYD>R<3P@nd|9GYf1aH&Yn<~ruENgiRCYUIf%0PL@Zme$7B_vfS^5Rre zkfiu-MA`nK+E%WtP#L2l`bEhappsqHj#UzwmFafkQ6sI3N-{+C@Pw*) zP0{jOB2CjB)S@Xme9BF(;1GZUT*SVMP)Gr+wxZPK$^#0J7s&$*QnU5CEoFo09L!t* z@M}t$zTSr}-9W3{Ds7+m`hNy#dwr%voThP>sj*^g?=Py@0RzG;6_R3_>NpW1NirQp z+JQAyoF!7FfWiVYz|lE+T(~92KXV4@;=U0E+&;As3L@pk%Xt{^G>7gs9Up#pOR+Mr z>EXsYTIl_)nr_#Uz*E%mBD)i+NA@qg=aK14MsX*` z3AjIlKPDW)ZB;=TC37Y*X>bR|t~n;c7*}AXDJX9op|-#^QjwTq%G4ki!voSZ@9vD( z7Or~yC%eB?t3_0_^1zhr9f&{En#N00Cp_A@9W?>Ry)j5eeZ!YEyl~`^&do=NuJ4dx z#V*mDZ7wb-x&1kZF);;Ia0@U76lOXKnE}Fthl;7vS0ZVjn;V=~0db~`w;!5nUw?2c zrUYQcZFm;mg8K^&0gM7HxO3+ewc6YoJK4kX+qF&9dMDA-i-;CINwi{|sM|YPx@qZM zZ(qIoQ=9i~ULNTv&jceF@1y*2cYs~${{Ft9A-#~oECh>;F)z%eI|5XZD=&R3UHYaS zR~CNFK8Vl~J*KD`NYk!TuL4fnE`9i>505^vcjLESe(dFcJFNnyK&&KOj>Dklr#A(d ziCZq1s|l6Ey3X=W?sUVaR)7y$FmKi+>5kLDXLpm>Of(Kp*;pZzeMG}4rvvhR@2W9x z?ACX0SWm@Dkp`**RIOI1R4G%rT*OEFOe+mE!dSeF=k2g<1P+tHbfKaM%CKWv{^k|5 z;ZuLuA4EYvuq5v=WqE3*F74)-4)!ge?|<+9x74R=PoL2P;y5*yy!%_nijA7TCXz1P zj10Hu_>;f^4qX9ncx4*-2ncPg7C|}=4a<3%)C6MUMZ@^$FjTb_>GHh|^SNfL6<0%- zM$-uw#ZF`jmx=#!tLLwXsQf zX1?mgiz*f-YVo2A(`7e*&aM;`JCw9TYP6d185Ph7;N}2sog_=g0(p6cNv38|62f=; z`L-pg>EVJMSRGcQs7uE~1_o;zzJMFuk>3W_qXS@lmqH=e?#nw#orJ=}ZAyX&*Qn9B zca()t-iNg#KcdhN$q#&rJt(<_f%s$;mv<*5@;O_c3=@?s*-=6yt!gL@^g9eDnj1BUDHiJ=`jB_Rh zOrNlbo3ker-O_|DtLmq{flUW9%5H3E!2_m5;-cRDhSlM$uc`-{g#DY#*T9Fl*x5MQ@Jte@AJ9!jk_nAY9ZHoHKw8 zi%9Vdbu<#*`*Ecc7<;?I=dmYYDHotRvUr5*w~a%o-M1KH;L@m*Nbt-oowwR>pOP+9 zb!;Jx?>$1b{yJ3#OSH&dNLLPDO_%nsf&z+Egfa5v_mitltU%2Qz~BuQOPB1S{l&xZ zx9s!^m_poz&cL-zKPqUOEdlq>QlmT@;8@SNEJZLmM#Z`CT=~F-QL#Kq3HP&j9AbZ> zUayM}2SC*~(C1vYY%M+fjfcpOyKX6IhDI=?Fze<5sK3%jcYNYb+BLA3CW=Q$4k4r~ z5h9^R)Akru>wUEGfi2{#j%m`0ZYDNshuyUW<^)Aiq&wE$PP>O*bS6-8oK^wBsGwS9 z;Py0a7~+$ldb4p>0K+WG-BJ`W>&Qi%^%Q`+lwr2x;wKbycdAXi!f`6S<4LyC)}s$? z{P9$y-c(G7XZX`8L&_vd7G|HDczI%#97gN|N9BN^GWbGYwU5fB3LUMF(y;?$2mPt| zuOLw&2V*+fJDfHC{pI^**on8FF$C`YAFziTtq(foMKlC-9RddQ!&i$?ubspc0+Bl) zK;y?cGB`>{1! zman>;KCp=-7oq$8ltWS~diT z4O@fdqtt!(1rDJcU_Ut;~Rto(CW)~RzU7;ep ztZx#_6>*jeUrK4)Q0r{z@aqZz(YHn2wP>CvL<)4?rE2TbA zf;R20@1&6x;O9VJUK@;K?un#e%m7uSO$^WT{T&97ov!fR>TPg%kpAGVkJINr^OrPq z+YoV5?a67j8H$smr_2kgfKv~)Un}=Bjda!GvmF#Y>x#sT_AMV0~9sX-{n% z5=NT_N>$JUW%>#>1mIqU5uTO6n<(w{NqSBjvdHD{9k=~Def91y)0L~Q`h|Nl(6JY$ z36oG@QraC^i0fSh5S;HoQE4bu0$K zE8E$g9anjWEam&^#!P-W6?g;@th9X`r0&6EVFW~ zW+?!rkZK-{dc;UTuo!YrSez98{K_${`h3^XA&2%cFCDzC@*I&2BS+({iD+>c{i9X%1YN99?fa!5H@35!n z1a(Gjb8XvRxp({X;SNeXCBmO~RM1R>pS3APncR#T`myjaT6fP4MaG9t(9w$f60ie3 z1$21Hu!uQP;x+wVAV~vKAcQ;GKYGVldur=`?Y9>gvS3CR8U}RBG@5&{5z3TRuQ}S^+;tc}E$q4`#yj6^-TP$$~_Qlr~NLWSJj; z9z!vmNae~weUb2E5T<&W8_gXpG;@1fFNy} z*v~RVzN+8Y(G!TR3<73GKrfx3GOv)pbxrJNJ-1gT=8f<=_bjd9-Y#c?0u|s6MLTDS z0nSMwCO^)Q;xg0@SuS*sKKEdvryQp%e3vHEsf36>8_^S6?%$HGU%&qR6u{jXR_voM z+*2&Sd2n44)J!MbkzB9>k*y|`3+1ko;Pz7FKa3E0?$5)jTc(2+D=m#Oc)yUtX8@^V zno8Wxh615PAR915<-(=Z+dq(7xYs<%W?8-WoMtJ+qs{Bqt(#Y@v!}vJnO&ZRw`6bX z1QRQi9hkNjXWszs@7m1mY(sp~9_UFios72HVYmyjjs;HiIQa}u)YHTL{8E^Rlp9F$@{`s zzlZv-65ce7bHOt+6nK;{6xlLAp@Gn>1nvYgt!72?!l2Oe3oPe&e)1R!lyfw)MqF7?3~7-(x#vP^`GB!+RamE)kU#wW`H*R{r->GS-HL5wo*I?(Qvp+ zqo`bT3`Zye6bg=o*O0{#5*!u|>UD=}0UlBqf|3g=b3uhTDX=(+8Pa4Aem;-&=``n_ z7qsYqKl|A~JH2dYqkvu;ebrm~7lm2#ZQPnFSWaH#u<>~ll*Rjiv|)sdM5d$7KXYS? zH9Q(f67vOt-zC;eiinQAn>urX}F#Wpzgx;^eH6!ReKb<|J z0zyoX+rbMr^vnJ$?KQaBWr&GX<*Y_&vtZ7vPs*Hm37LOLYPwZqCS{^Rn@MWZ-37_# zFY#psTm&T#o*{Rdp96yu3mhbe9LaXF?e lounu9v~HbA0l)Ic{{hkNAaFi(B_IF*002ovPDHLkV1oSWHVXg% literal 0 HcmV?d00001 From fd981f453cedbfbe2c9cbc2be6f596baa459010f Mon Sep 17 00:00:00 2001 From: defnax Date: Tue, 20 Nov 2012 10:29:40 +0000 Subject: [PATCH 161/222] Added the default Posted icon git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5853 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/RetroShare.pro | 2 +- retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index e7ebd96db..04cf3ae83 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -708,7 +708,7 @@ SOURCES += main.cpp \ -RESOURCES += gui/images.qrc lang/lang.qrc gui/help/content/content.qrc gui/WikiPoos/Wiki_images.qrc gui/PhotoShare/Photo_images.qrc +RESOURCES += gui/images.qrc lang/lang.qrc gui/help/content/content.qrc gui/WikiPoos/Wiki_images.qrc gui/PhotoShare/Photo_images.qrc gui/Posted/Posted_images.qrc TRANSLATIONS += \ lang/retroshare_en.ts \ diff --git a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp index 5576080ba..972b383c4 100644 --- a/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp +++ b/retroshare-gui/src/gui/unfinished/ApplicationWindow.cpp @@ -54,7 +54,9 @@ #define IMAGE_LIBRARY ":/images/library.png" #define IMAGE_PLUGINS ":/images/extension_32.png" #define IMAGE_GXSFORUMS ":/images/konversation.png" -#define IMAGE_WIKI ":/images/wikibook_32.png" +#define IMAGE_WIKI ":/images/wikibook_32.png" +#define IMAGE_POSTED ":/images/posted_32.png" + /** Constructor */ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) @@ -95,7 +97,7 @@ ApplicationWindow::ApplicationWindow(QWidget* parent, Qt::WFlags flags) PostedDialog *postedDialog = NULL; ui.stackPages->add(postedDialog = new PostedDialog(ui.stackPages), - createPageAction(QIcon(IMAGE_LIBRARY), tr("Posted Links"), grp)); + createPageAction(QIcon(IMAGE_POSTED), tr("Posted Links"), grp)); WikiDialog *wikiDialog = NULL; ui.stackPages->add(wikiDialog = new WikiDialog(ui.stackPages), From 03a3499a1b22b70a69d4cc857e438b52a5a43520 Mon Sep 17 00:00:00 2001 From: defnax Date: Tue, 20 Nov 2012 11:27:15 +0000 Subject: [PATCH 162/222] changed view icon for PhotoShare git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5854 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/PhotoShare/PhotoShare.ui | 4 ++-- .../src/gui/PhotoShare/Photo_images.qrc | 3 ++- .../src/gui/PhotoShare/images/kview_24.png | Bin 0 -> 4036 bytes .../src/gui/PhotoShare/images/kview_32.png | Bin 0 -> 2166 bytes .../src/gui/PhotoShare/images/kview_48.png | Bin 0 -> 4467 bytes .../src/gui/PhotoShare/images/kview_64.png | Bin 0 -> 10139 bytes 6 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 retroshare-gui/src/gui/PhotoShare/images/kview_24.png create mode 100644 retroshare-gui/src/gui/PhotoShare/images/kview_32.png create mode 100644 retroshare-gui/src/gui/PhotoShare/images/kview_48.png create mode 100644 retroshare-gui/src/gui/PhotoShare/images/kview_64.png diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui index 1842828f5..0cd71e64c 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui @@ -52,8 +52,8 @@ View Album - - :/images/lphoto.png:/images/lphoto.png + + :/images/kview_24.png:/images/kview_24.png diff --git a/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc b/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc index fcfc1f3fc..86cbd58ef 100644 --- a/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc +++ b/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc @@ -1,5 +1,6 @@ - images/kuickshow.png + images/kuickshow.png + images/kview_24.png diff --git a/retroshare-gui/src/gui/PhotoShare/images/kview_24.png b/retroshare-gui/src/gui/PhotoShare/images/kview_24.png new file mode 100644 index 0000000000000000000000000000000000000000..094b6f5fdf7e7b0715515d3ccf411acfffff775f GIT binary patch literal 4036 zcmV;#4?FOQP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=00004XF*Lt006O$eEU(80000WV@Og>004R=004l4008;_004mL004C` z008P>0026e000+nl3&F}000EvNklIVs(ozh2%+f4nTOA!8 zp-*>w9N|7g96o&b9wFF2Ku>po?m#z#LxUJ@Hz|{nNlZ+{>y5iFKnEx)Dh41F8l|$b zlH*5@k(-xG_QTo4CnRCpHnla?R99W#spTsuo>z>=?f%!zD=Nyz0f59;8(CXW$AKed z_@*!7=>^NMEXBpHFjv}!sp*@7^hP-J!FEms3WP)og^)U$R8+T&(YeES z=L7)DGwV73dkrtGSp(T2cl>J;Zhg915y8?~i7DK1PTlJpoTP*Na; zLeAPEaajiaA;mxlhQiP}B=DF9Qh=?-NB)v^sOE1G@w3o9 zF(5z+ff52uYUmz&B2Zpljw^LGtLCTE&>0~NBPQaEDArw+*NC_U3@zmW0>MqxjUO1opG$%s|4ysxs=$gWC>7*Jqc%sk+SR;dk zg#(vUA?SJIejAlbraw1*r8m7yM6bf5t2umP!fj8DM5r~V6CDCIuguv9mG$09`QI|vy z+{6esP}e*}%;XpFI-HCIZ88!J>SL2J3My}I0AiyCI zE9O!+PbE4t1Jbhq9e>Rbx!wq+<>yGtNujOwI)_R&QL}Y5 z;>d^O25WE|cb&lDaF93eS$^F2H8ZBbmCN97f{tO69?PUH=%S(7O>ZEE=N>n?boLZG zw`^p?+$lu%y-Q4+pMtDh3Lcq9bnGEY;_~Mwr^wA9LV%SZ#%R#!Jh%h zOM~Z&VC!2YT)A3L>G2b6F4;uc)mCETeC$1ajK&)+MCc~Zopvwq*}C-{-F=XwKm0;g z#xxG?-j3OSo`>9RxcVyD|H=D2xnMCl3Dep4#eN#ET|+uNytiuy1Db=R)GYR%tt2yN zIqiPW#A;epRLshkr!x1^Cs3g zSeDJgMMa!A`8o9$n(5afT=bu&{JXx1#qP|(9?sMrfZ_4EDZrzFupnSTeln;iXd4DA z1PM`oelDNHvL(;(+qp|DUbKO-Q!A-7%y z?D-X??0fq`MMXLPHB7gg>PuBTv0x#coi~Y3OrW}|if}kQzCbDUzXve)?alABG&K2D zUofcpg29XDFI1%{r5+4$3(4PDvZ=W%(4&-6YGicurw0n$Lh{zHf1|0Zr$-eQ7QX(# qfm_H7r_;IN_FVkax8*^_UjqR5OUi#+fY)yT0000v3-7@@8R8@{&B_uLMyct_(`js zot@p^N8jIXelsJq)_k2NzgF*n@tJBdIh!Bcc^4j!hpa#Vuh)y^u^1g4W%uqT*1z%+ zx7~gxrKM%enN$5=JAdn~tr-9}Z47RoIRu+McF+ zI88_25J#d3M#rnLXa9oxo?ORI>tfvf;xQ7Q>9|sYmPo0QNTdKqW}bzXpauQoibJa^ zPb&a$Zbc54=e4rsFRyX-bq`T@Wf_;8RZK^Jn&?m(uVvu3G^XiNIn6*zkc1GmKVfbC zYHq*I&)&o=v>8B30f4JPNR1Qf!{Llc|CYcgR>Xk!`643$WDKVX(*&HkV;_~3Z=}cwp0oX zg_Ngrf2x(2{(!wF!W7q55w{gR!!}79Y!|c^#NsZ>G|9F=XwZ}V8jWR{q-(BanmS6G zo51u20f7_}tu;~#w2(-lv9&;^<);BUJ3E*+!_RomdEC9Yh}P~D+giq$U*ZQLiBCA# zLXnfL&`w4-0cZiX2Fn3iHWxS6fsA)!X6H^0(g-2YQX{oON{O&F9`9#n!QsP)DJ+OE zl3PeYwn1J%(a@UYqy7mZ0mTH8?4X6f!PXfClp$~d1fvTu!O;RK z1VTtOAcaI48VmJlfM~RvobYtaoNP2O;lP3ti?*1c!bRvaqh|EvYFfE*&aqKmaTBA`g2_UpU8UowV_@xOM{W9Mc7Z=ld z@)U(L6t)%^O5o8N4fuTmVQ5f3k^;=54Ggp$$GKny;Q}x5xPu*sfKL$iIjF2$EYn2D zOp-_;aJ58`$p?=i5m`(DNPw!UDt0yRXI7!)_y8D2CdSGV_`HHpwn0_^B7N@@_FK%H zTSM%_on!^UL}8~SGzB>`Wo?m;w~Iv0jY4FypQy9I&X)86`0SLV!mI&M$)}Hh)C;qJ>Be zRzMJnfbc=rad>C#>l|uoplknj`j5A8Uuxphb>M=9yDL*Ct4wg1j(f1trR|0B{{hjX{6EVsr?uz7Vn| z#<}-_A5pVtIeVMBNDcOocy}|VJ<3H3&u7Vv->3QDKCEdzJY5|)Cy$*8U``Bh<<-~l z+J@&zr_wB2zKlKXaIg*1E+|hXVH_KzhLQ*@TLeds9;2aYH_tr%6w%Iho?r7U*UzmW zUR6#kZIeuUY3pt$;0==K1k>yCL9}fOU}{26%P*v~u$YxA?_|q+tt?+rN0HIXEtkXc z%VE(1xNJULa}nHn1za@`o_Xds%s*!V_da+Z;oMxhd;3_wegmRx0ewRbhAY_ExRt@- zaYp*aXw&;i4>>%sV&$0%YBXRKdkyKufDN?-@m$!%Bor(e)N|-_`v-fh~%-azJdH1VOIZn9Y4GM zHWpUgz&jh?rFB=^nE=s$9-_Kz0W-f-MOo2w60XL*a*)zs4puNs^!PB1&5gKrnwcdP zEV`tafsqK?Te=t=&*pFS?{n7!HPqJD^1@4Nx#`Abgo{fl*wx7HeK9ue>ZQw_%YnEi zJ5+EcK)mENeAU$mZ7`6uk%miNu1k_U2FB8)oFV317(&Pdj%*>?-o@~krsvoo(@S&7 zEpmABg`GV5(8~xZY52!>F1+A;mVWOl{E=pw_Z}rHvX*&QBp8XGJQH9?qh>U51YZD5 z1$GkRNyxH}Qji6VgSO$&7?cKJM!7-Ave6M3w+Ar=)XsySKT^l)$KT}mi4&YS*@04J zEV}B)oM^k5md;~{31~g-{}a37ZfFzW&4JM_P<|-%Lr)rF3I>5-Huyb|9EPEGn}ZUD z1=uMFN(h(1sGH)BA1>q7SL*5PjFLAW`k%P_-g{7n$?WoS9PN@y zCOFvA!qkaOYyG8NK%kQ{+=2ci|fZ$t=a<=eq{iY5N0qKeEQ-` sFWmr4`?z0xmB(`-gnu&c#y{@+7sQQvVI0uAl>h($07*qoM6N<$g0lAtJpcdz literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/PhotoShare/images/kview_48.png b/retroshare-gui/src/gui/PhotoShare/images/kview_48.png new file mode 100644 index 0000000000000000000000000000000000000000..9c1b75c3396263f89805e155939539d5ad0f49af GIT binary patch literal 4467 zcmV-(5sdDMP)Nkl=+Nf9Kq;TkpMk_xJtn z_jg-ZYxzee`L|}^FD3nM9=>4t#YiNHs#tvH%vn{&GZpc8JeBJv7|+WW3Il@!gZrZu zk+r*b?RlbqU|@@s0;S&V67P=0JMn=FmR}rQv}o~X&pGRi&$(`P_Ub=B?LGbU(+4(f zdZ~9TJ2nc4X)P^@Q%^aqY1y)K>yDbgknKBnt^VU5{`B2}f#eh6Na(M^?3-yoJo3mR zZ;PO>e}J~uR){@C&NTpJAb#<|8*Dg*!^;9nT z=%uWE;d$z7YY2zKe-#iDslB~jYk>34JMT>&cwyZJX12}bhd;WFy83!*p?UPt zM{yh{R5s9LGKG}7{OpE}8=2P9#89Nx<Yx+}29l;8LC^9GkE5vwA7nJWy0TzKoASB#= zSxuQ=W6b0z6b&lK4ROU;Reba2Tbcd7FA)ev`QC~XXsQlyXfV&vm`BdF6g-PDzWZcy zhTb6;5JW;6;R_fnL_>ANPi*J@Rlnu?*L;9&otw$ly>}7-F^;%66GhFG?;wRh3Nevg zJkOh)$dr_Xk{c-u4=_-%h-j>i@2pr%YkiRZVV6walJ_im7hF$Z5sYLFhlf0*l7xba zaB&0!icnAz3@E~}YT6dH^Oc+L<`d`4#T!0|RuU-{S}C-WC?%0fp_D=?iP8!!C0a?e zmgQ%Tq)8gcr@Ogw*#f?E_aA6H?lPt{)>0pHNM{V$f+g=-3LbdIVu7p+J!ua|OM;G| zB-4`J7TpAE!D*aM`lxf*-O)jvXBbhfW!YOm2vOEXNzkIC0pZUldP9jOLF(VV8ZBHz z?eR3$#HolV?s+!JNY-EsxCT7q+oVM>Fzlg}q$2DP4QV1FMI@w&hBTp&CLGd)g8qnx zG}Gsu%##~CIb}gLHkbCLsuf!Ml6SO1>&e%oRw$*5L%p>IthF3fXIQtTlg8HLIscSe z7ETHB!zTxMe9JIPW=1f8u>v6kqd7~#3M#@5LX=X;xP&ZVuvi412d)d1@hUR43y6jS zc&UAaV()>n#Krg<%1$&<1JYOJTLI|q?q!f!lu`A z%xQ3t(wBb56;woY*#RdSPiYxb1mb#7a6u_cb@N=OP zHUK(1J87s*uze^*RlJf|Sdq>crX(EBo*U)G19|ohcr?Zp1uKwRQsKz5%qQxg#JCmU z6#?j+&sZ!`3r;Ul*^SYvZ0}5rFeQl>ugfAFt0%5>1c08NZl<@i5Uz-mhy_9T3+Fwk zi#se5lD&g2eWL~?1eFoxCq~Adb%MZ(CIp^uE1?9cG%rOX;pd%F*g6tGWo0EJqodTuf@Gz{ zlqD)q(hr^CfTT_ck~xbkNw^r9jI|g9N=l?KAjeHe2rvbUBPEq#s7Zv$6bw~bmDrqQ zMxsUG5 zvf-s2%xDM_bR=DAP)eYsz)^yLmISmw2PBc8Bpj3k1Cl^U5(qh{v4cbgwjg@9;gBa3 z)&zq7@0FAYBMB%$TZ5wK@BsqV)6iPt1T@-F{?Ho7(SAN~6pofS+W+ooKPOn>Yrh1d z44}Tgo>w}$(RP%n)q(>(0#|^i1x5?376?b81A<^s5DExF!D9JP=p*6wQ&}0oaU`k3 z`%#WTInu9RJV8DqsEG@jD+L=iZl$gE+#EUD;#ISTuc9+`2*gmvVuVC$Ng`Ci zSV2(8LT(g>2BED9nkxkV`HNrEbixO402aS0qy#4nP7tzrk8PWG zu=>G!+5O^Ej16?51jMSskds(peBnv^Mh%35iW5#-#zS}A#G*g{nX}J68*5?99;l2% zxDrAYJ_t0RBt{k)@g$}Iwjd~EU^oqf{SXhqhfW6Ld3^nbTR8U%H&GcaCO!$ufn3IL zV8>3ju6vyHt_`FQ>;X5&7tTJ5>`0big=XFU9SjVm{0Jp1!th27XbRNT)p72{S8&aZ zH*sGq#^MuCBoT#YUxB_PR8&AH>YJ1hJ`+-aF<|oG7MagxVAfPP=NSLpKfe7A7A&00 z>Id%Tm@}3kgB1uZN%eGcc-=D$cf3kG5@y!adRmt(Wn^fWp@BoJKe&^l=gp?IF2SAy z9mOP8%Kt}fDYZ9-l!DfoGgyB4Rb26<>$&N=tGICaaxOa)*6;OAs;?J31zLkD7Kxq( zn+He2lv=ppRH$|!H8{xCU%ifReC>MX&YsDu+qW^TrJ0}H^)vqCzkbP*mg!8Xj8oMx z73Dx>G{Wnhhp>fF`UcV@;!#F2BSfk~%&1L(Ddr$q68glDWb-H^kP_xDJeH5F_$s&E z{{T-uvzC9o{yLV-tYgVc=*htTgV2+NY}S8EO$eqp>5@(EBX9YUt}Pa=DGiV zj`eHT^33XIi6vs(aNU&7MueEZ&qd zV`Hpb`2^qk&iCm#ypvc%Jz14tWF*bOLkFp;tKpA-e3YHLc5~B>H_%u&g`eMcCpkAs zOh@P$=pk!!wAD7?Z z?K=w0OgIdOB$r(J5!OAomd>s&c5K_ub=QA`f4=%lTy^u;`Qgp~PV%+aIG8%j=KlSh zK6Wg+V3D;R^BSj+>MBrO6$N9F2)}qd62R);-AA4gwr$$U{*Dd^C}zx_!u+-woVoNg zUfQ;q88s2=s-rxzY8@}GAEa~NVHPhumcxZK|Fq)coYL4zpUkrIg-2L^$~k=W!?SpP z)$?@p?%`1PAwGZQ3jXcZTez$`jR$C)7Nv8via9f5 zWR2y%pZ}c8F8w(7Kkxu`HMKmlauvyBicep26%Rf1E1r4j6}IksjkUWw=@`lpt!%4SWkg3xf$&9&Jsp#nJV`_6V7hc%T z<13$}t#vxvckW;`o8h91K1MvA;Qo8>qrb0!BLvlnJYH0@;J6uJCl#ZU0qp6!m&!^9 zsV#@o1%#1=v_uL^)EI_Riu&40vH_Q>8YtwmY)(FiCP=O^&8<&9hKy=-Q=Wbq;?zqV z#zu3<5kn}_kF_4Dtc#md{Pb5F`IoQ!j8jiq%FA1}Fn9JGhK7dt{lkCaL(9)csa}5i zi*MpoO0r%K&#_d5OmW}+76AGN2N)Su1i}I@ZzxF63T)2cLN6@HJX)W<1q4UK0JLi$|vuIQ7)1FzVbTIchnzlrI-mUH zr})|Z_cL$a96ZbK?20s6nBPLt?D-hNccS87^eDIqp zLg1$sg~0PQ;(=8PVGLHtV*lUYlox;arqtct%@a>N!8dNWk*=;zs;jCw<>aNL(`owp z`k67KjWuhYVQg#^fcExw=WP!8YC<4$5tl044i(ee*PerS$6D&D#5o2RnlBpEUO^t>1>o>M9S#sj4 z;ydg+8lLOEajE}1nht#Px#!lVpIW`fzPRZnYpt~d$)vT`+I1T?-8_D*^$r324gMve z8Tk6j$5-{QUh`ZT#F{nFZU^fB5dZ*80j~btgAaATyk)DsF*o>Kt1r; z*>jG%1DJCpPw(iYzC`0q*Z+4)09k8o_Q)IW3c%kZ{SR2)>rwdP$}<1}002ovPDHLk FV1iqoW*`6n literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/PhotoShare/images/kview_64.png b/retroshare-gui/src/gui/PhotoShare/images/kview_64.png new file mode 100644 index 0000000000000000000000000000000000000000..323ab96f8d4c2b786fb119b2562f4c598705b678 GIT binary patch literal 10139 zcmV;MCuG=(P)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=00004XF*Lt006O$eEU(80000WV@Og>004R=004l4008;_004mL004C` z008P>0026e000+nl3&F}0011eNklB4HN{O9*5k3)$CBC*4Up z-RbVzeb=fwXa1aQ^FX-f9K8mQ!l*o%4@~> z^UoK(y}haR>o?AtI&I2yTgj2BRK@UAGFj{^`Gr0E)%ptlr+P zfe&4I?b+{Jc0<>NRU_udb=y`jim>&2P>A(1)+E-*{t9-@W(U z_oGAY9d`h^zlZ<;v258g{Z1zxKHNb~Z7uW9KaZc>bvF+!eVCauXEJ8Y80zcmsi>$R z8jYg0#`k@Mlt>|wQUV6w_sL{3bai#n+1bhd{rlP9(#ki#{&gnLn89xrEn-CDaH^^* z|4ZS&aN$B>Nh#w1mtK0Q=X)Mff-xWjc%ILjZ>|@^8=F)r9^;y8t~PT|JI&nry*o^E zbF-uE}w}+N}En>%xojmc(Q{v^8Pkmr!A*vuv;6&J$I5N!{xQE1eEPm28jbS83olpzmJq@|5h41%&ztKu z5KpGa^=J5(o4?54fBI8m-n@CDuC9(FM>HeR)QY8S^$x45<9LV<$4as_Gifn0FSHRn?>`D!KXQ zTlnD*zt4k9mQY(;OMQJk#+U&>{pkn@26(dGSY@~c_8Qv8Ee~_m>~Rm?r}gqpQpL9#MPHw%ED{@fm0TKfx1yM$oI7I%EXY9%IAce6e1A35N{(WhTfwLoptNhbJIu9<<}1`MKqmF zdpX0lqeGemRB6MavO0L264X$T!eem^Q6GBk(;b4zTUtZ%_633Rb9Y$-;n-WLokD{bR$-tv1DT4jb!-%kzJJ$OUo3fzhViEniA1^nl4d3jkJ6j-DR`QaZ}5C@wLxox zuSK9;A@DSGWIVD(h&dK9N8vb%h%JfOiii^o-m!vXjxDh)MKoejJ7NmMo9A)MH}B%w zD;84RzXB;mIEZjSN+Q%yp-7|>$Z)V$*vi7PltfB_kn-I_;nk~GbLpiE`1J#iF?_}a zII%Rbc#;E0UHbAq25>!t=No*Vpc#QSW$F_g&H7{uhIm8;&@*NG9E!9+^1c9J0y98^ zic0FooWk}MTiM^*!kLpQ*i_75#j1|+C}mGmHVG*NMg)6hP8;9|5paz-2?-8}MQhE< zm2c2cU&rrPw@^_#j_QguV}?grwX47rZ)PaD1|bBl51uw?BM8V=Acdg6sLA9t5nB=u zH6M+H%~8a{7L7=p@R(yOqPD`e6}D|rSu>2fv9tNj(r1}}?&)OruSJD$Rzozdl)|<` z4IlsefElO(6Aa7`1#A-yuQ0YJR+GkB8m_K zKh&H?Af%z>LtkDal_X{h%E~`p@@9y7$}UQ40yEO!OU=mfGugRjGnMH$aeX-OP{JHX za6{E923&$LVu0^N`A-}do191ht5>h)^wZB^>((7q4j)G{ndbDdQR>nbA38P7;x!pw z+mlBd7+V)XN`Vm|LLe60z#QUH6~NAzfqv;Bf-uJkLjyV_Qtbm%YZxc6XF8MxZ1}De!c_{FbeVITjH|5^)p}y9{wFAV6CYbu6N`6%eBn zenu=Jj)m<=Y}>+#L>M+=B0CQpX57do3P<-LtpMgiNu(uEN(B3sL|Q8R44V=tOQMtt zNK*!VeMbbe>}$ogEu!%_F+W9R+9DB=WQ&G^YZz5yb8d5-)vX2g9Q80lP?Jz7C2)<8 z7J>GqIC<7JG$I?&e%L$@lox1H0O^_rO5Q=z=>%TB1Es>SMwAgHj){&0f@6Y)ke7f! z2MK-`5NU(21ApI8WiuPWjw3FIbHNZ2QHeGJ$B`%@1_mgO z4~-EB5g2_ry3@j-0UuBjJP}4X+TbLUSostY+d}w7q*4PxkQgG-GRqJ0L)ipOC;;(x z+dGi}gb*0*6N@KtvJQz@!1g*MJKun(p*E$EQqZ39>2nQUL4$-?L?PcsduE`=27xHY z29k~i(C^7>`rUw%oMWT&W3DN8&V(H?VO-#s1)zfxk^!`5@Fhee zipqEjuhb40EH$W2Q)YNkjs?VVCJ{m(F|-%&EPzs}gc1s+6cO9PATj1xVwECvF&JWY z5N+87L*6%7;&^K>cOkIZ6S99;JM**&0wN!LCGZ3!B2b-3(6!G+S`I2?v7v!Zxnn~I zF9^Jo3kAfIPI`+^_^@n3dJC<4`L938e-o;h#A078HgQ|t_~tVhmUZ558?IW zYk`a=0gWkVX(2qc0uO`G0>^^tG^Ap1p#3oE+PNr8BFu3y?J)viFaa)qA7J8>$HD^w zm@r`in>KFd{P`D<&S;JnEV^8%a|FIHl>M6!fl!nVVtFSdB6Uol6P)WK$@d?Ho;Dnv zBj-i1M$Z5#(HMjjK@{i(*GmN2Kt&ver3JF!(c0F*h>Ip;4K0!$=k~->jfB2>joL~X&ogTY{p6k%4zKod%!EJ4JEs4cL==GcJ=S&l-v z8REHisvLvuMCt3x(6Mg^%9dERL|K6bq!3^PS__0PXs8xcMg<4j+UP6U#FJ?(74VZ~ zsqnkRvSb+W1UZ2f<_MMwvq2@WlnC<$@y-YsJ$e*-TlUbC>1TK{fv4bLr=WK<*b-b5 zR9wo$XiR_tEg2v{Il$5aRmftOx^NvE-x!Rqsc)=dPuo#4M~_fFydHdmACiIb!7W0} zHjJ(pR73@DtX)Ud=;z5La8hv+RY@90 z*JJz~TAR?-3XB$%3IeYr7}X%CjtKg?4zcRZt&EvHAEgv3%>2rl51JTgLI^~7KPM(g zR|{%}3o0rhQ3<-x_s$4Nr_;=vcRD}4=a*c5+52cnJLDTJw(N$=G*qSqE(XgAt`eq9 zIcC6qg#e>9!sIcr2qv5-Fi2#~!83-G6QeJ0@I4Kl!Y@Iw0J$urB5=xBLCS_jPd!Vd zzL{iY^$7@Uh{cCNT09ALqaYoHzN}{FmOc*c+0Kfm9wyh*PJibC{%P&f{MLxa47O`s`;=wjk37+jhZ}31CG9o)4A=Wd$e@QVbwZU@*poNHi>17=+eH zZNQR2(BgrkHKnYJ5sG3K`g%e5Fnc1wE} z0M9q9c%_>MzWYV?ZF&-X9}9(yDw=94iK)o3A{56}g#m^SZ{WOh&*j!{{e<_-JB!(K zW-)gn{GlIq?1m8|!Er#@gUzx**nu#N0pZvKfsPBfIzUU&2U7r}!(ym!$mgJ^H$cFt z%`mAx`0bv1eo4jHxm4B;ds}2J6-1)oB%tJLHm=&kAD;LXs}|pdSIm=0M3_Ep3`HTa zgpF%FQYy;9&fd2rXUCX;F@{Ja!j#FAnRfO9ZvWnoxa&uE(AZGVd9z{p8ra(c_4N>q zf{K9c1kLxrQUq)$1U}#yC<49<#tVtA1lkSAF53^iy->))^l@1=s@6Rz?|RVtoY zvyx7~$a|*Gc;|V6a%rofp@GRW&)|*2t=#e5AMn+$-9k-eH5bo=CW@NCbk2 zM4{vaCLvWA;h8}51p!_$3`I*IJn)N9C_tt+@FH_3!<=yN|FL)pFTeaMUddy}#v7X(p{GQC#byUY=oLN1BSkrheeE)f@U$v8{W7xL#4PMx^j(BB~ z@qQ!IM~~(4^{>)$l7h$p2b3{kJ2oRmj-oj4d|rG0QNH)RA8_**{+XJZ8WzrhRXbtx z9_Z_XcnlKB5D}pOgbW7nx=`{5t3CMO6#}?>MX0HSIg?>rP4L_$OP8{HPYa*^^rv`z z)$2U+?_Z&5+&K2P9U<>&@C!^zMQMtsscUE?kxUVbDPk$XmQCB(-@2P|qleMbafn_g zhn?^_B4fBBPt;NL`-k2|07D|BSj=Wj^JKi@#jJk$8E(Dp>-_7@pJ&2^@yu(6aU)^F zHrRJKfU+HhSTq>C6hVUHx`8145|lzSkOFE`Fkvj5Hh%DVKfm`rwr<(Z*T4BSQt>Di z6_s3b^)=MhRIy>>7Vh}Y?F>uQF|lzZ`TiUoJvs9Ee!7nKF=AvRJzW`u6m)d;U|R_; z7&(_>wn$7{n7B*TgeZq|o$u@h%`uAxJW|Od8^9ncq^<@t_j99!Q_TP0y?n2oqO-QkDuQ2GcuVB zO-;l3;umhBzNVTdpLv!U)2DLg8FTsBJ^zO#zqlVi-%Ve}N0&VElxV20A=l^P6|y9f zHja$qM*C69rRQLlyouANyV=mY8DYOmHaL_YmFI&Hq!MW+G*2a&h_PqeX1@B3AMng` zFY>W#uHu|?=24|&pvm!p)_Y3Op9ilLpuu*aA^{c0J)*a}hld_{gryHZ#+tRSVOOR| z$_l=9$G4a@YbLpTfvwxNu;$G*Y}>VyPkij7eEf6&z>^OxWzX(cP{N?>C?!wRd$g0D zQXh?01IEgM>(PDGBOA@o=I_I{Y{sUV7~WX*&LpVKV71P&ER?dSPbvC4`#9pluwe~M zJaslNzV-@BmMmuBrSIdC1q(R)%(;vnH3mycY8|L`PO_$`;Id)EI$nHf1rk;8Vv!={s($r?^>uRtp2V;DS z`8=(y?QGt(jSbs3aB%NF@O|orC0KAlBl+GKxkNQ8TO^wMG4BjI zj&!kq{{dQB5AZMldMp3*`OmZP>dQ&hRPpNX9;bD83%;Ah_B1cIZloiYp(dI{)cQ0> z#-j3?&4=1ZrXy4yv`;30K=rmg7%9E}>>~0i9bOTjs#iNhhPuI`-h{YWW`4UEZB;!f?i$!W1D*43K*U@*dgT`s&S^Uhy zjGJ^OH@xrt^heX|-msljtJbiudoSJXN4WOGSMkWQCpqWb_wdw{PvN>Q_<}p{{65!R z_fgKh@LWcZZsOj%e#V3eb?jS`V_#=0M>xb8Gv_mX{CJ#n1s&~OSO>a@*cRD*;bZ~` zi(Eq@uB57A$|=*?8rh3-J>ENODm4{Jbk1kb?tS!h_i@JD(`cxyW$wfoocZ2!IRC8k zX&N(;VWXOOqFTcv8k3Yxf{>Ke$czp}I+Pk@I!YKa!>T8%hb~cM%+|015 z9H);PLEESVNBmmiDvDz}-1xa0`RUz1p|_`(KP>+PPBcO~l49|LOE}uq&4P!;$S?55+TC0@e!)92>)tMUbqU{FO+0B+C1NN?@ah}; zsj6(k(Ic2OCBmc6Kg6Dv7nn9qv1tzN!#>(}`1 zcm5ZdOgC??e~XHWCYsVImM?#a?w%g5z3NKdx8Nh}*mjt#A7|g54vZgV$JTz*b_Loi zk+9N4WgW6IesT^lh#|`?VD`EFpd_}FpfB6Su*xi#Ts#(Odl)~(fv&@h9FbwhoH3kw z+Z7l;&Vd7+q$?sEJ={)5KEqjOM!D|#tJ%En1sa=nGi+oXQ_nt|J?*X3rt7(~dmJt8 zN64EzJGYmJD2KUI#;~jH5C^*Yi8&2y-1#bt9=wmMulfl6*&MC=_A_qm7@C`#*|mEY z_uapUPkj73zI5v?y#Ct5EPwSW`g)2)92+MV$JJY?tS&KfN&?G%hk}Rz)DU<0+vo2m zoeCx^G8(!LK_m%oFC^noQzMAlkna=3tota~5Q!UXEwF(Ot-1RNL7`|!r6F5GQ5&*WNdIddn~AGkqk}f%gBa&&Vu(5<<3Q68mQGx1|>m!ZEy zlaG5$8m~|i@@*wX79Em0%J58z8aIvTHB@vvD9@s=*PyaNncd(MiGc4KN)bav15`J{ z-+ksnJe_0V`!B`Qn)X9MY(I6{RP1Pk#f$#~Ap{F9|2$`3@M(l?Q!KgoxgtqNoOI68 zVo3dbAQ!MCM_W9E3(0!evm%S%FEGAA`d}=;E7Fiu9LZ`To+O_tkynDlJ(`M?k8FcP zLy-Jr`y{<_5B8g&V$)h+Tfa}LDo?)zp#^=$P|86v4QVM!#U(LElj%03qEM_heC)dO zdHj*pEO_sHUVQN-+S=Qgm}q9^)G6%Q)54NR9^%kjIN$MzJj86 z(#g?aO`Yqx0~x{U=ljA!qYS;IMueqib6kZ&n!&j~VMJimCR{KX7E&c9sN$dzQh*j9 zO;8#);Y@-F!f#{B=bFJu4Ff&BJ*?lbfnWXNH~jO>U%>S=D^|Ql>;C;rojj2lr%Y$} z&OJQ-#FJcp*+M>Z{heI({x4%$LA}aob21JPCs@T12t{iT-}msfkJdiE@1gx7+IPd| z;c6G(^)R}K#>MzPMtk^P3GJ56g>%$zZUxu?zM$3OhvOr6xsS!d0otE-DWEiL$-X4dRkR8*#U>X~N&K}~fvuIs&R z?a&EGFw|zKa3zCWz_M*@%f?m?O4(SJg{7ic%0^k?zU83o2+E3LDF-QSq_k011Z6o$ z%Rx#jIHoL=a!{5PG-U<%Q8r51#~io9J}6}k^rxn#mbr6IW6qq}{N(PtnK)rQr=2#J zBZrQ#d-rbKVu{(aW>Z~N&9l$H00?Sp>L?Ukq&zVRT9##Lfajin{Sj35ahFJw>$442H9Fzgh{VEk}~R||~PV8ZJM5OCtH zr>6&BYrgiiukz*FzKQ_edTSF-#9`K~S)6{x95$|hi{&r9!ujW&LuF+pD_&bkF5Cb1 z)F&2;DWz20vaCoMd?M_wD9?`uwG8cRjrRP(DF_kN(KN;gEsPdOp|$q3mLgorE5wi~ z-&DKF=qOC=b!hHU*EszlKuPkN4IR-#>D1k z=FXWzA|7Si_U-g#^PDz&7Fz3$#~y#;OV?g=)$eq$<%}`KV-^|@HjUOA?R$8xhg&M) zx-O++kz%ok>$((61&W0Ng+l(gI;%MDZG_{8AWpzKf6^v_VZeg<^Dlg`^}vDrt1DkO zzq)UcS+VkUx?nRlsv!X^;K&Y9<#Xm!~*!^oA3L7(N})LH&HI0 zKmWo94;*MKu3WXoEP7zES+#17DQ~-W?=_n@Z#Bjklg;M0y}DxM*?%?x{1v=*Cx9B@ zqIvV?E!wnsYv0OMYt7<^9v;wqSqM9J?J~v~(|Vw7?ca<5hV-EtnBUwy@t$?-H)htZ zTW=m-`lwmEZvB7|Hf`E$eB&EqjQh7J01*n|+~$cB|9#!MjlFBut~ZZ9_B*p~{YEo% z`?r7l#&`ba1TaJhmB6{_RQd;hSpIV7`i+~+W4~KwHgDZ#j4|fRx83%n9d#Q2CIv90 zKb624z;~7{d-CAE)&pkU#*OCkE3SA9nDl4$0)LGH2>X-*P6NL2na|w#YF%C3-N5+c z&l7)+0h}z({;v|iJM=3FOa>}|jmDTG|Ie?^{;h42|K{6&4ge+uu$xWN=nVh>002ov JPDHLkV1oMrZDIfb literal 0 HcmV?d00001 From 96b0d4a372feb07b3ddbde443b02bb417892bb9f Mon Sep 17 00:00:00 2001 From: defnax Date: Tue, 20 Nov 2012 14:08:28 +0000 Subject: [PATCH 163/222] Added subscribe/unsubscribe to album icons Fixed layout spaces for GxsGroupDialog.ui, when some labels/buttons is hided. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5859 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/Identity/IdDialog.ui | 533 ++++++++++-------- .../src/gui/PhotoShare/PhotoShare.cpp | 2 + .../src/gui/PhotoShare/PhotoShare.ui | 4 +- .../src/gui/PhotoShare/Photo_images.qrc | 4 +- .../gui/PhotoShare/images/album_subscribe.png | Bin 0 -> 1813 bytes .../PhotoShare/images/album_unsubscribe.png | Bin 0 -> 1761 bytes retroshare-gui/src/gui/gxs/GxsGroupDialog.ui | 7 +- 7 files changed, 319 insertions(+), 231 deletions(-) create mode 100644 retroshare-gui/src/gui/PhotoShare/images/album_subscribe.png create mode 100644 retroshare-gui/src/gui/PhotoShare/images/album_unsubscribe.png diff --git a/retroshare-gui/src/gui/Identity/IdDialog.ui b/retroshare-gui/src/gui/Identity/IdDialog.ui index ecc942f00..a124df4ca 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.ui +++ b/retroshare-gui/src/gui/Identity/IdDialog.ui @@ -13,10 +13,73 @@ - - - - + + + + + 6 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 1 + + + + + + + + :/images/groupchat.png + + + + + + + + 11 + + + + Identities + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + New ID + + + + + + + Showing: @@ -84,7 +147,7 @@ - + @@ -106,260 +169,278 @@ - - - - - Delete ID - - - - - - - Edit Reputation - - - - - - - Edit ID - - - - - - - New ID - - - - - - - - - Identity Type + + + 0 - - - - - Nickname + + + + + 3 - - - - - - true - - - true - - - - - - - - false - + - Yourself - - - true + Delete ID - - - false - + - Friend - - - true + Edit Reputation - - - false - + - Friend of Friend - - - true + Edit ID - - - false - - - Other - - - true - - - - - + Qt::Horizontal + + + 40 + 20 + + + + + + + + + + + Identity Type + + + + + + Nickname + - - + + - false - - - Pseudonym - - true + + true + + + + + + + + + false + + + Yourself + + + true + + + + + + + false + + + Friend + + + true + + + + + + + false + + + Friend of Friend + + + true + + + + + + + false + + + Other + + + true + + + + + + + Qt::Horizontal + + + + + + + false + + + Pseudonym + + + true + + + + + + + + + Key ID + + + + + + + true + + + true + + + + + + + GPG Name + + + + + + + true + + + true + + + + + + + GPG Email + + + + + + + true + + + true + + + + + + + true + + + true + + + + + + + true + + + true + + + + + + + GPG Id + + + + + + + GPG Hash + - - - - - Key ID - - - - - - - true - - - true - - - - - - - GPG Name - - - - - - - true - - - true - - - - - - - GPG Email - - - - - - - true - - - true - - - - - - - true - - - true - - - - - - - true - - - true - - - - - - - GPG Id - - - - - - - GPG Hash - - - - - - - - - - Reputation - - - - - - Your Rating - - - - - - - - - - Overall Rating - - - - - - - - - - - + + + + + + Reputation + + + + + + Your Rating + + + + + + + + + + Overall Rating + + + + + + + + + + + + + - + diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp index 010990d4b..b2ea8a63a 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp @@ -330,6 +330,7 @@ void PhotoShare::updateAlbums() ui.toolButton_subscribe->setEnabled(true); ui.toolButton_subscribe->setText("Unsubscribe From Album"); + ui.toolButton_subscribe->setIcon(QIcon(":/images/album_unsubscribe.png")); ui.toolButton_NewAlbum->setEnabled(false); ui.toolButton_SlideShow->setEnabled(true); @@ -347,6 +348,7 @@ void PhotoShare::updateAlbums() ui.toolButton_subscribe->setEnabled(true); ui.toolButton_subscribe->setText("Subscribe To Album"); + ui.toolButton_subscribe->setIcon(QIcon(":/images/album_subscribe.png")); ui.toolButton_NewAlbum->setEnabled(false); ui.toolButton_SlideShow->setEnabled(false); diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui index 0cd71e64c..0662f0f7e 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui @@ -111,8 +111,8 @@ Subscribe To Album - - :/images/konqsidebar_news24.png:/images/konqsidebar_news24.png + + :/images/album_subscribe.png:/images/album_subscribe.png diff --git a/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc b/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc index 86cbd58ef..0b1667402 100644 --- a/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc +++ b/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc @@ -1,6 +1,8 @@ images/kuickshow.png - images/kview_24.png + images/kview_24.png + images/album_subscribe.png + images/album_unsubscribe.png diff --git a/retroshare-gui/src/gui/PhotoShare/images/album_subscribe.png b/retroshare-gui/src/gui/PhotoShare/images/album_subscribe.png new file mode 100644 index 0000000000000000000000000000000000000000..3ba182fe52e8c9695325fb6dab004874d4f519e7 GIT binary patch literal 1813 zcmV+w2kQ8VP)(>D0LMKL?uzU^a7L!D%7VUQK&#D zT!f$nwIx!CKvmNRNO&kA5tk^Tr7e!2Zo$+o1ruy1v76M6?ZmZrZST(R?9R+N{Qs;i znm*x&yl{4P=FH`M-+%uP(^|vz9Q?YX|6dRoy}iBHm%#J9-Fx<^N^m{U`}+QD*tU)6 ziThsLyw>In7>nL0P)y-cg}?+;O6ka&7;zj2gc=wJt#GOFUUPiRAf$Ji;hko)MKSdF zdeWdu_5SwshK#A15D)?|BESo$X-OCb1cSUdX<7?lp^kv@B@t?lvd{vzv$>L5GEwy+ zg<%LYbx^Edy=Za1DWN*}~+4qYH#Wv8nDMM9>^9td|m} zs!7#6k<*EawjmoTVQ7owdItgFo6%l_M;>KlxCAU_B~WTLXYIfZyC)9ZqZjX zs;A1Xq*C{S;>mUouF*hCEaYE8N|XP8m6nxA+uGTOinOZ z5Ne0Zs*#rn9Lpf9VI-qw81_7ha;+elsz_MX`}o*Pz2d%Kt>2J#vmRm52bvrcWduYf zQs@*4B4(lxHSlhNn5o0a;^+p7QpgD{y`gsP z=GjRRKKEE=>}6T2Sv}*DNt0<`d!sNjJ#~3{E;pO)zp(h_8UMcoahux?CaZ|7OZYMa zxj**R&Y$fY2{Vo2#%&vJ?Hv8tPkvCB{KA$O?%&-t!s=!rk%CwQIQ3w}DVDb^K(PS% zqF(Szlg9B+bz~lVYT3!)T9lTQFVv>ZQWfh^M$L-%Yg^5_eaotH~4d~_$o{ugG|0Y)r%#+Y^Sft;-x#2x2^DlkV?)yeAMZA` zd3Ja>!Dqq>!(3%o1|Ys35}Tp^4*Ivg4ljKU&Y!2USOmWWegIZf5@?+I`J*F)1O2_f zZ)j_7s$cc?%;LxH=n=MzGs6NqC;SbaTLveFyE|^}P#gWZV;DEase{}+2#x_8cfxIl zAlU_b&O)#w{OfB0gNg@%0^uw>dFth%j@GT~_HArkv$lj`Xy-OHHnnuTFK)-5ec`md zn0fN|GR_mPk0W_3OQ-ndNgO25vRMq+Vn3=nwWdQfAHuEuOEf(~G) z05`;;rOilLK?2p!La7M+@B^_Me(3DjZ*Bhu``{tmRyy)6`@46FH9bM+_QG&Kq~4Ke zFbx+O*lEa5lHoEAT&cjEfE+*~362Tg0?dyG|K^aW$B>{RQ5jzlUOxEefts;i=icY} z&Zo*R9#f~k6yN`1eCPe*WPhNe#!|&Em;L{-kI$SuRQT=Jz=zabd(xji5=`_K9{Y^k z{9}33SDg=k(f!R&;j?9{tw+`}RnZg+)!x5?lfvj&3zjqkYP!F|%zD{=k6gV!{QFTP zFxvLA@*(A35y^G&rUaW@#O`JE^z^I%9boM0pu7Mg4&~<$h`o>M^Ct{95QS-&ILWfZ zb_~?$FLm8}V=)MAXkORKR(klI9(=ugczc}@V#k*b;4y?MGaUk!I(X<(m}nEG^QL$A z=@lOx*KF+?Nq_#zBKI8@)NsF61aTQA%ph%6lG3vb&lW|=FT2)o-6uBh`pAkkSaS70 z1{Th}DzTkm+Z5613A;-`#YF`gbGT;xP0hFLz%Ty;iR|K}N?DzQ00000NkvXXu0mjf Dap`W@ literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/PhotoShare/images/album_unsubscribe.png b/retroshare-gui/src/gui/PhotoShare/images/album_unsubscribe.png new file mode 100644 index 0000000000000000000000000000000000000000..0f4348d4bdbe7c6b27f0033bac3f8baab744344f GIT binary patch literal 1761 zcmV<71|Io|P)K`%TkF&|#xpQZ} z@0{`Z)QiwP8m$}|OioB2S=+cDS5sjJdaorRH_M3F4irXeC994T8q$TA2DF)iVwYF^|5 zfm2tcYM9CB8Kyn8vs`d+mt|F`?0Nm-;U2bS$KoZPWH>FcZ}fGUNu3LhxhA7vX91ec?Rs#Q zg2xYr0kH&3jKSYxKnzN`of@Fo$wO3D1<{@FyVBwFabw-8`t}7QgZ;dH6Ah2EXb8+) zA$fHdDf0nw!1xFp_~^629}bP5K0Grr@Kh%ECxOeLh7*gG+3HGswHhMbz2&n5z2~fI zKf8YAlABsCeDuyMUiTv+skXJ(WIDGw0}Z+M_OU5Awzp^O=$8ZE?+xfB8_Z0MC%OXO z;vhp(mt`rdoC{0!l;%dmH52=MEvvZi&>)}6iEdXG2Osc(0@Hx{3+oZs^6p@VR) z|IruUN`1FaHREeshWw+T%Hb}`r*KV-JL`Iee%$REC$2xtGlng zO%vL9cIcZEBf)pS(ta6+J-e(DFI%&EXx9hZm#;lM+_#mhD{p@wJ8)V96B?JE9h>R9 zZDoPr@#kMXcc$-n&tBicKwU-U_;jpoMI$p*7g2ODA}n`n%XMe247E0S1FqE%z3{@R zhT3JrKL>MZ(4CdOipV|prY9$BPMiqFVvtH!YU*W=XTelx|JS<<5=|T#Y?{BK;qJ!y zHMMh?hDM~>UsvC>+-11BzTIQQ!od(Tpzh3&Z^SWv^Rl%!p6WhpsI{rs@m!W9W>W?i*qj=-En zweaY8G$E!gMr!Ak-&n&p>`!!-y5jM~6u`yvLtvkZK7d1%Jz37~xIa@A*cAWM;Fj+A%b~*R^9l4;= zzr)9u-w+%cC@wUZgi8br55&iTIicDKQ&|Wxhyawj!Kpzy3bUi;PZXjA%nX!L@Xm+F zujDeBEUr;)^HTt^O!}U<=h1!`yHZS$$^2o&zis{V8ZyC&^8%UxDs6&EfN(6jIGOr1 z>t7QpoE0*Qt`=HwPBw3Lr&2*7$^j}cgsrQHuDOmK!+1mi0*W?U=E!XCWV)_w+_>?o z&~vj<*tYG*WD=EWKrDbRkEf+&36zxd4G-QGj$Q-^nps~cJMY8o#=CFg@o?4cu+M!4 z-~tK@&{|HtcZBM+qlEP3`_00000NkvXXu0mjf Db>vMJ literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui index c0a9160c0..b67f9eee4 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui @@ -159,8 +159,11 @@ border-radius: 10px; - - 0 + + 9 + + + 3 From b18a95ac9b1842b5048c4d0dce93b8c0bfdcc855 Mon Sep 17 00:00:00 2001 From: defnax Date: Wed, 21 Nov 2012 13:41:10 +0000 Subject: [PATCH 164/222] Added a headerframee icon for Create Album Added a close button git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5865 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/RetroShare.pro | 3 + .../src/gui/PhotoShare/AlbumCreateDialog.cpp | 4 + .../src/gui/PhotoShare/AlbumCreateDialog.ui | 51 ++++----- .../src/gui/PhotoShare/Photo_images.qrc | 3 +- .../gui/PhotoShare/images/album_create_64.png | Bin 0 -> 4554 bytes retroshare-gui/src/gui/common/HeaderFrame.cpp | 24 +++++ retroshare-gui/src/gui/common/HeaderFrame.h | 25 +++++ retroshare-gui/src/gui/common/HeaderFrame.ui | 98 ++++++++++++++++++ 8 files changed, 182 insertions(+), 26 deletions(-) create mode 100644 retroshare-gui/src/gui/PhotoShare/images/album_create_64.png create mode 100644 retroshare-gui/src/gui/common/HeaderFrame.cpp create mode 100644 retroshare-gui/src/gui/common/HeaderFrame.h create mode 100644 retroshare-gui/src/gui/common/HeaderFrame.ui diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index 04cf3ae83..e8e1dc8ed 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -383,6 +383,7 @@ HEADERS += rshare.h \ gui/common/LineEditClear.h \ gui/common/DropLineEdit.h \ gui/common/LinkTextBrowser.h \ + gui/common/HeaderFrame.h \ gui/style/RSStyle.h \ gui/style/StyleDialog.h \ gui/MessagesDialog.h \ @@ -521,6 +522,7 @@ FORMS += gui/StartDialog.ui \ gui/common/FriendSelectionWidget.ui \ gui/common/HashBox.ui \ gui/common/RsCollectionDialog.ui \ + gui/common/HeaderFrame.ui \ gui/style/StyleDialog.ui \ gui/dht/DhtWindow.ui \ gui/bwctrl/BwCtrlWindow.ui \ @@ -641,6 +643,7 @@ SOURCES += main.cpp \ gui/common/LineEditClear.cpp \ gui/common/DropLineEdit.cpp \ gui/common/LinkTextBrowser.cpp \ + gui/common/HeaderFrame.cpp \ gui/style/RSStyle.cpp \ gui/style/StyleDialog.cpp \ gui/settings/rsharesettings.cpp \ diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp index a8712322b..7356747e1 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp @@ -11,9 +11,13 @@ AlbumCreateDialog::AlbumCreateDialog(TokenQueue *photoQueue, RsPhotoV2 *rs_photo ui(new Ui::AlbumCreateDialog), mPhotoQueue(photoQueue), mRsPhoto(rs_photo) { ui->setupUi(this); + + ui->headerFrame->setHeaderImage(QPixmap(":/images/album_create_64.png")); + ui->headerFrame->setHeaderText(tr("Create Album")); connect(ui->publishButton, SIGNAL(clicked()), this, SLOT(publishAlbum())); connect(ui->AlbumThumbNail, SIGNAL(clicked()), this, SLOT(addAlbumThumbnail())); + } AlbumCreateDialog::~AlbumCreateDialog() diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui index 71aa7f75c..68b88a61b 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui @@ -24,7 +24,7 @@ 0 - + QFrame::StyledPanel @@ -42,42 +42,28 @@ QFrame::Raised - + - - - - - 18 - 75 - true - - - - Album Details - - - - + Album Name: - + - + Category: - + @@ -150,14 +136,14 @@ border-radius: 10px; - + Qt::Horizontal - + @@ -201,7 +187,7 @@ border-radius: 10px; - + Qt::Horizontal @@ -308,7 +294,7 @@ border-radius: 10px; - + Qt::Horizontal @@ -334,18 +320,33 @@ border-radius: 10px; - + Publish Album + + + + QDialogButtonBox::Cancel + + + + + + HeaderFrame + QFrame +

gui/common/HeaderFrame.h
+ 1 + + diff --git a/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc b/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc index 0b1667402..5851b35e0 100644 --- a/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc +++ b/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc @@ -3,6 +3,7 @@ images/kuickshow.png images/kview_24.png images/album_subscribe.png - images/album_unsubscribe.png + images/album_unsubscribe.png + images/album_create_64.png diff --git a/retroshare-gui/src/gui/PhotoShare/images/album_create_64.png b/retroshare-gui/src/gui/PhotoShare/images/album_create_64.png new file mode 100644 index 0000000000000000000000000000000000000000..f19ea20eeb7eafbba0188572a56b6ee56eb8efb0 GIT binary patch literal 4554 zcmV;*5jF0KP)00007bV*G`2iyx4 z4Gbd4GJW#^000SaNLh0L08StP08StQ7JZrC00004XF*Lt006O%3;baP000qLNkl{fRLhLkXR&y1ma~L zc!UQ)2!xPE0}%p+S(pLOOu}RwI}3@&Ax=DF$L_>iyY242-Phf>?^=7E!(V&#VtYsw zc_QU>tM9FQ>s0;A_kaI)PBrG7qfhc6ciVtZ9k|;DeCoj6HsDhS?zRCRbx`O7FTVKV z-8SPxjw45oP}4Nw-QmNB1K%eEL0iKZKET;Y7~@;bU-Q+f!_^mw21jYn%(`d%X8mD2 zviJFi(Q6QJMNy6)KMtQ$&-3nf9RGhq6lGD&4`~)Qfl~Mzc;4EG7wLNX6W=Y-daLQ9f+hwtM6eeW-SZ373gF}!6ri#&jn1&qV{g$75aa1Iuy zx6d3(4pD46id_irj#IzLDlfy&dBL}==<+jh?osYM1T=91-_8LzO9+jO?i3oqqgkQZ z@GkrcC%3@Somu1sL2+Qi8^!M8{F5+~JhnbcDoNZf@I+)2!&yRb67$r{$Z9Zc13p>n zfIx)Mb_jMlEejjwaoWT1CV36Bl*BxYePlC_*(eTj0u!9l8%F6t2DR8w_&~_ugcC+1 zahf9>5L|%UZ5*J4u+R#e=Dl#MC^Ml^IaYWQ;l!;l7uh@#1(hV1z`Q^QoD`}fjWSO; zoP^Mg(ulKSiac6JCmT3Ggb+e3#s`n#pC&p%M1qGXQE{xplL$(amDnGJExkQQg^(vX zT|;3p&eMEHF2vA9D0Kx#>An+$NWoSfWg;ouj0R)W2x)>y!ERh|1LqZ*zh)&~z)t2$ z7U2}W$%%1A#QxmL0U`iG!_rI*O>D#o>!eT*FP35`MfYl2T$S#$sCiNbDW=kcl*6(* z&Jdq6QivwBb)%Oz%Hv;BKC;m zl!dZWa8d${vGv+Bb0Dz-(~RjN6GH15ju|zSN(nY{DB`Tjc|uR&w{Zkh#3hIz>GzS_ z$>)i|4CPkmGg22~3IcTCJJ*0fIM34$Y|2yS$9YFy<#f#aak&Hc5X`fhjTtLWK}KH* zl@@9SrNBx!IB#JwggD9i*E%h+0Sh6N@-&ZHc~qrw@x|Pf7H6&-ILacL5C>23gECwt zE~Jc*1~~%@&)||f6d#ZrRJV43r!^q(w4&0_A}l2iWM!43DdWk!HdBLBJBx?ez_^f- z7)dcRq>Vf|3q>S?H!yyq42S|qwCpacjNz+Oh?ABa8$s~u?~0^^lBA)O%rl0~X}&NM z7fLuO{8(9XzJU*GGeCr7RfATWi;5+gyOe0hMDxMD2n`RJmlr{%L~u-kc(v3`0H0Dp zMzXnF!706E(Yl=jRKQu(Q!$HB?h?wIQd**Mgoz;eo-LSjo{y!zQN)6*YO{%HU^79O z^pyPCxdRC0K+2Tu25N4d77_%63;U&61s0)`>xDD}g4~`vD_nlHj2g9GS$*>Nuqd)1 zAgKaQA(zg@IVTiQmvT~;kVwE5I`H}gWDcZO3KXM4xhIs8;W@f(;RX>*McJEsZ}9R9 zeG;|<_43&tx%IC+@jHJcg!yBu;+h6C(Q4_Pb1i{$%@?s;qM!>raLYbWfKc9=GR)yT z=y}GYYf}-;pVP0rrXkhmqsmH`4r)iBcB%lU+mT> zt@zlvM1kEV1CawUw!`#gi?MbU>Z z=cqul%SR1_r^|#w(=BE*Ls%L&pcJ?U;F<;DWUJLesB+sHAQ^ses^j?@wUq>m3Vypm zre1;*+yMEewY1#Xve{T^_I6Khx_WZHxwJeoJ{vqxWk^)EWT4iBOa zqct9IVSiu$lTZHX#EvIxGc(P_8}FSu(T4hJ%>VJp?{Am^zTSZ};yIaQZ3`0;coskR z9qL<*3uQ%Y+3rBUuE~O5R{VhP=%;V~=Qn@z&;HOhaS;nyMQ4)xl{f$PbB`Zrnyp5w z5n3N0%*fc_*v|gRzxua7(K|cLmAY@kUEBdf)kJM=#Mdwr6;f)!>EbY}5{%QeL6{ix zo$u4uoTMwR>E4)Mxp=v@f8Q2emm!X>8%%7joO$WB>lut@qx0|AAk)cmKiB?URxyDw=9{d%bQ;PzQ;ESt($Iu^uHJ z37C&X5c9$8(ma;Qh*;e@Hg4_4hgh@K>e{^B zF-rr~7d+o1Wl4usUaL0iF}`)A`p~Xj$2uxeNx0!DQ^o>U^^gUH;c)>LQe?6^5qQ2B z2t-wl3EJ@5w}4Q3Ot>ExYU~YXNn3{E5*4*~bGCc+>`+y8J-b$4xp1v^>G}c~ZP||F zdWI%VZ0aj(x+I|cCMqDz9k(}E>$ytLF&$2#&1DpnR0V{F6?i))#;S^rO(cK=5)~wY z_?T1XOM#C(9xdQR5w%(l^~E0VoNr&ivT%zGWDfX1V>sYkhz5#Q2(TD!H5;?%&Rl-? zwYf`Y9N)iLZ!R^urfsW+q(~w`0f1}RDF4j1ZCf@E%`DC8L3O%5M@ybsV$||E79^Q4 zkGl>Oc~Djq(HB0Lxqelsxq|@|02KuyVdR9ne_^gLOo8Pr@3bt3b{2RWWYvT|wt2j7 zV+UB)2Pha!4OK9g=PzEE#}b*Z&0W28_VU!3oAWh@G)M+jmUX-)o7SRm&&XEZ zb%SQNO}n*5XV>T$RHjG`(+bN}lA&?=vLrJM9U=%26t4%A?=e>|sSGhsadv3q#A5H) z=XFC~S&%n&04gYc^Y-ztnM=)}Z7nV=LcAZ{wofbTn};_`m}vd|$A0kNkL;Oz_~G4G zr?0&Ke*N)B_FtR6)@-%+KKRfpr%(Uv&aGcK^2~cD|JU!6&(+RP3?KNdrw+b(?b7+V zskhF)YcUg#pmSm!>WOjR4+2g>EHb^S_VYnIuw4cX5E2~zTCTNo%jA#8-+R4t`o#3x z%wvw{;$=kY_^XGHLnTR6eCEJ2zT&4voYJU4`VQ^h@d3R~JpZxDZDm8}F21?2?6~d( z7b=QY5>;L9-#U&TKJeLrkrCT_WA8rY_!~cb_we9(1lzZEUPEW>j=Vhl-GBxK##h95l?ucBk93d+=-8W?-}0@{PuP zU8K+*L|9`9Bq~jKmBRO+Q7xtCb!?#QtPdn9*z-u&a&5SB*IcZq;(dFhDBZN{cB|!u z(JgrNmv;$VZFPFGB=oGd<2T30`tIMmeSZG(Q2$lET>9;iO0BUBs%!LKV{a3kxwc&E zdG<`lvz%tHQR~hQbOwh@!~I&nN;Rn5zzW6*Y1I(z^$SHE<`>6 zCkg_m0)xMTt{E$C0|-BHKu8}k9ev}UWhvC(Hb-U$DGEq4q)Nyr5lWy*5QrNRfvm#q z7f7YW9RECXTrNr>arh3RFdh82I90=^2Nom?m3R{e6q%wKlXBPYEXoVIWEi9*aVY?Z z16C}{>AJXqahFnwQ%wjogk?@d!~`Dg!GO|22=uwf1MFipB(8N@2o{Kh+P-Um?=pxJ zu9iSKL%RiGf|wKNz(gvlsv>YC*rqVKjL4;$-y(L8_PWpgm?$K5jV*u~)$neT%Y9xqO zTM$NxgLVQBQM?K0VU=sf{9tYBdZWCe_o+j4aL>TLE#+N`1RYy}Iu^oRe-b|QfEnOG zzywT2H(wA$k~jd1@%YVa-)R^3Z$I2)`g9XI9Dn^!fAjvOsqg;dQPT|<3gOlkNq6Fb z*<`V-mk$5#)8{Hv3(9rUk38L3!Hp$4Z>*GF|Mm|})&t037C#6=;j$CNnvWE$96tD~ zP~LQ%UANeSTx)%{las84(sdADvjO`J`w!V8BU zJVfJX^glRu?9O5Tc*fGwlJ4k|h=__rDI5w6S%HYGw3;VgdG+?wDY*N@6Hhpf^Wkp) z(f@0+^sN%eY+w`Md%!d}Ad0X)gEfU<7{;&BuI4k@U4k$1v(ZRvN+fV-~_>V0R{&xO2CL8e%*B!@ChXWCZ^N?d$GT^QENpS#$ z$`({L_jwQv9|lM~C-}rTAVfXc_YhFN<43=NO?=@eae&_Wl#h8p)sCnm&P}_oQ>C&X za+&zlQM~~)yolO&oPPHmc>2)O&wcN?&ar08b&$pzS`W!+zFHs9HhN4oV3b-aIa{~f3QACI2VuYxU(=>Px#07*qoM6N<$f?A}Xga7~l literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/common/HeaderFrame.cpp b/retroshare-gui/src/gui/common/HeaderFrame.cpp new file mode 100644 index 000000000..499076b80 --- /dev/null +++ b/retroshare-gui/src/gui/common/HeaderFrame.cpp @@ -0,0 +1,24 @@ +#include "HeaderFrame.h" +#include "ui_HeaderFrame.h" + +HeaderFrame::HeaderFrame(QWidget *parent) : + QFrame(parent), + ui(new Ui::HeaderFrame) +{ + ui->setupUi(this); +} + +HeaderFrame::~HeaderFrame() +{ + delete ui; +} + +void HeaderFrame::setHeaderText(const QString &headerText) +{ + ui->headerLabel->setText(headerText); +} + +void HeaderFrame::setHeaderImage(const QPixmap &headerImage) +{ + ui->headerImage->setPixmap(headerImage); +} diff --git a/retroshare-gui/src/gui/common/HeaderFrame.h b/retroshare-gui/src/gui/common/HeaderFrame.h new file mode 100644 index 000000000..833da3df2 --- /dev/null +++ b/retroshare-gui/src/gui/common/HeaderFrame.h @@ -0,0 +1,25 @@ +#ifndef HEADERFRAME_H +#define HEADERFRAME_H + +#include + +namespace Ui { +class HeaderFrame; +} + +class HeaderFrame : public QFrame +{ + Q_OBJECT + +public: + HeaderFrame(QWidget *parent = 0); + ~HeaderFrame(); + + void setHeaderText(const QString &headerText); + void setHeaderImage(const QPixmap &headerImage); + +private: + Ui::HeaderFrame *ui; +}; + +#endif // HEADERFRAME_H diff --git a/retroshare-gui/src/gui/common/HeaderFrame.ui b/retroshare-gui/src/gui/common/HeaderFrame.ui new file mode 100644 index 000000000..2257060cd --- /dev/null +++ b/retroshare-gui/src/gui/common/HeaderFrame.ui @@ -0,0 +1,98 @@ + + + HeaderFrame + + + + 0 + 0 + 400 + 86 + + + + + 0 + 76 + + + + + 0 + + + 0 + + + + + + 0 + 76 + + + + + 16777215 + 76 + + + + + 12 + + + 6 + + + 6 + + + + + + 64 + 64 + + + + + 64 + 64 + + + + true + + + + + + + + 18 + + + + Header text + + + + + + + + + + QFrame::HLine + + + QFrame::Sunken + + + + + + + + From 9e30148c63c854bc22f2a6e5d284d8c4ab09e5c3 Mon Sep 17 00:00:00 2001 From: defnax Date: Wed, 21 Nov 2012 15:46:08 +0000 Subject: [PATCH 165/222] Added Header Images and Text for Albums Dialogs Enabled always "Create Album" functionality, not only when own Album is selected. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5866 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/gui/PhotoShare/AlbumCreateDialog.ui | 19 +++++- .../src/gui/PhotoShare/AlbumDialog.cpp | 3 + .../src/gui/PhotoShare/AlbumDialog.ui | 56 +++++++++++++----- .../src/gui/PhotoShare/PhotoShare.cpp | 4 +- .../src/gui/PhotoShare/PhotoShare.ui | 24 +++++--- .../src/gui/PhotoShare/Photo_images.qrc | 2 + .../src/gui/PhotoShare/images/album_64.png | Bin 0 -> 4596 bytes 7 files changed, 82 insertions(+), 26 deletions(-) create mode 100644 retroshare-gui/src/gui/PhotoShare/images/album_64.png diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui index 68b88a61b..978b6e4d1 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui @@ -350,5 +350,22 @@ border-radius: 10px; - + + + buttonBox + rejected() + AlbumCreateDialog + close() + + + 398 + 466 + + + 264 + 243 + + + + diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp index 4d9234ee8..fefe8b261 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp @@ -9,6 +9,9 @@ AlbumDialog::AlbumDialog(const RsPhotoAlbum& album, TokenQueue* photoQueue, RsPh ui(new Ui::AlbumDialog), mRsPhoto(rs_Photo), mPhotoQueue(photoQueue), mAlbum(album), mPhotoSelected(NULL) { ui->setupUi(this); + + ui->headerFrame->setHeaderImage(QPixmap(":/images/kview_64.png")); + ui->headerFrame->setHeaderText(tr("Album")); connect(ui->pushButton_PublishPhotos, SIGNAL(clicked()), this, SLOT(updateAlbumPhotos())); connect(ui->pushButton_DeletePhoto, SIGNAL(clicked()), this, SLOT(deletePhoto())); diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui index 0acc5793d..c0b45cb68 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui @@ -27,16 +27,6 @@ 0 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - @@ -310,7 +300,7 @@ p, li { white-space: pre-wrap; } 0 0 625 - 103 + 112 @@ -360,6 +350,13 @@ p, li { white-space: pre-wrap; } + + + + QDialogButtonBox::Cancel + + + @@ -372,9 +369,17 @@ p, li { white-space: pre-wrap; } + + + + QFrame::StyledPanel + + + QFrame::Raised + + + - frame - headerFrame @@ -383,9 +388,32 @@ p, li { white-space: pre-wrap; }
gui/PhotoShare/PhotoDrop.h
1
+ + HeaderFrame + QFrame +
gui/common/headerframe.h
+ 1 +
- + + + buttonBox + rejected() + AlbumDialog + close() + + + 481 + 413 + + + 324 + 217 + + + + diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp index b2ea8a63a..dcef37533 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp @@ -331,7 +331,7 @@ void PhotoShare::updateAlbums() ui.toolButton_subscribe->setEnabled(true); ui.toolButton_subscribe->setText("Unsubscribe From Album"); ui.toolButton_subscribe->setIcon(QIcon(":/images/album_unsubscribe.png")); - ui.toolButton_NewAlbum->setEnabled(false); + //ui.toolButton_NewAlbum->setEnabled(false); ui.toolButton_SlideShow->setEnabled(true); while(sit.hasNext()){ @@ -349,7 +349,7 @@ void PhotoShare::updateAlbums() ui.toolButton_subscribe->setEnabled(true); ui.toolButton_subscribe->setText("Subscribe To Album"); ui.toolButton_subscribe->setIcon(QIcon(":/images/album_subscribe.png")); - ui.toolButton_NewAlbum->setEnabled(false); + //ui.toolButton_NewAlbum->setEnabled(false); ui.toolButton_SlideShow->setEnabled(false); while(sit.hasNext()){ diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui index 0662f0f7e..ba24bf785 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui @@ -206,20 +206,13 @@ 0 0 804 - 230 + 225 QWidget#scrollAreaWidgetContents{border: none;} - - - - - - - @@ -249,7 +242,7 @@ 0 0 804 - 230 + 224 @@ -287,6 +280,19 @@ View Photo + + + :/images/kview_24.png:/images/kview_24.png + + + + 24 + 24 + + + + Qt::ToolButtonTextBesideIcon + diff --git a/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc b/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc index 5851b35e0..bf435030e 100644 --- a/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc +++ b/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc @@ -2,6 +2,8 @@ images/kuickshow.png images/kview_24.png + images/kview_64.png + images/album_64.png images/album_subscribe.png images/album_unsubscribe.png images/album_create_64.png diff --git a/retroshare-gui/src/gui/PhotoShare/images/album_64.png b/retroshare-gui/src/gui/PhotoShare/images/album_64.png new file mode 100644 index 0000000000000000000000000000000000000000..12207ba89f3096827cdb39debbc65188b348374f GIT binary patch literal 4596 zcmV5+1<85pkReOzcdYcw##<9*<}7%(SQX>Aro}y0sr3YP~(TdjdibkvBj=-%P$#m z!2^A}66rw(h{AdCxU+9}2E8{p-?`qc*k7=_C0;U|fd z${wr<5etP%qyv;9LKOr}#7d1QGTjSs2|ytdK~sE&Q&B26uU}Q$mTH0x@IADUZr1 ztq`%0iUJ5C0U?JcHbOi{(Qi@(6`*Cxr&A>KPoFAOrhMVbp9}z9N+J={J*Q{xi80kh zCUWM3Ditp?B&Y_a;1W{riArLYiRjOd6Oqk(}~A+l$th@}}oYBFZ$-T>rH(_|q9CGbQdv39JnD5Sn( z%d&n_GvyvFkr^}6d6KcjqQ#67>yX>5G5_cF|6AVd*XGQSt1SX&N7M1T~6-E`jxK;8^Z z5DkfuDxS-km99ggrd44ouzXN}VlXSrUkq@WM;B;b%Av(j|u7(04)WaffHkT0N+AoaK}^0RB9u-+gIdWF(yXeFAmys$bH=`1M_!!Ab_ zP*oON9suA$l|a`7MT^IlRM~aIBrQ}kfKUZ~2#}gd;5%scGJYU1C*~mvhXP)4uH4Ua z+NTN#m0Owz07%aY=b8Nk;^6=kIyDW1+L7ACXda27!!QFhi_Y?8v|Im9ohGaOI^|#b zLxf=vg&|T7g|>_}*?g(H3}gI2+7m@qpg_ntU1!wa8COODP*6_O^T`X z;|sWspPM}M^W2YfN*4+%k*DWj>JMo=v``WXgvQ7=k^wOQiI1w7QhAMD%mq7tgD`ZQ z53f?X@)Cw2v1%5Z%|0`eC8irD&wuhbx868U@P%JN*M=V-C)gy$?DY9z9Euq2&^#_u zH61h!qA*rr&~5|cdjL@EltudIG|Os(tVD>V$Y`i*1f3@G+AAm&UI>9bU~{X>;e$1{ zTYa89bAa0yS7>c+F?VQ|FxXK}CKgMJoC3CmmOQaQMoofl#pia%Wp#0p*7`l(ed9ZH znyd7iEBxujZ;sG4O@oDqw-bQe*u#;#Snvob3H<@;%Gc3@0g=+EmkipD$JAt%ilq_M zO9Y|fC?l9G=MF@Ca$kBu2yz%-4+V_8#xkFU~KiSERAn+iHb|_qEQi5j0K5h3rZocyl zH{QCyweNqM_Qn#E^(qHyC7daPNNM=Wry@x3D-v+iPIE(RV=BkFFTZok1;wS?3p&cJ1Q+~OmrrwBqt zZM;Spg|zw(cURZ=!3Q^}%myr8{4!fxJ(`;ij^pv_-~SCq9(#-@p8X7uJ@ZNCPn^Lt z3`&(UPOs1V*Wcmp#q;z&xJILFaWQmo&-%DroE^PR7im^(C2 z7)p#v83LEb#!Adr#+htPU{xxVEJ3+y(AsKa_d1MKbei1`eQe5xq$^E4Wm7gay3yK0 z04Oj(C~r6l7i)-gfhPn)8f;#^fZSR_pPE2KAvH^}PCIiRC^?Yg-lcNVFs8_0(8a#e<9H}W> zug~&oAFtHMwOy1{$;vHctXx7E27}P&&?@y(jlh@yygtI5)px4HG! z1(t8VjT;2q-)OPf>|r|&<(f&!G?0WyEo8P<=cC7tarod2iE&!&^4r{Q!8uOTPxgnZv|mWR#um}ee*K6uD#9u zl~o3gi|2=wEt7uNqdr!mFa{YF>oRZ$TwHyRbM6U_ z)Mjve4?A!%4k!*A4a{~8qoQ+sdS-7ID7NLrYkd3Lud;b>5x2R;;_@nbL*Y1mWGFC9 z4QU8;DX2syQYlK)6)IyUL=iP4CW1q=GlU2>o9i5zp2PEP7S5btdE+Kl)n>4+aeVFw zs^<~5dUW(2tIaN_=NE{=K89Yy9t0>&VOp^1ZBpy&xS`MV#3b9zHc{vz0-sB(*V!)h zn6B2*Cln_uhmeDa_cvCk)-1Nyti1s+jQoN(&;JAVW{a>hV0~?!f#dSC$IelyS2;L) z5K~Ahlasvqt$*bcPo3ep=bq&Doey~b{S7|-iD$Tb=Ps>whqF(AjDNdyiI1N;!f(F# z>%4pMhXfNAS5~ibboN<(`wO4MGsjr^V2LYNuCm@=<>^o`H8F!K*JysYLjV1ButIu) zOD9@me5}OL1G6lxY*MaOdH%DXVd?8OckbU~Bi!KJ$x}Re@&uLf2AgZ!$mJ~zL&vu5 zy#XkexHUP!r=C2?b^Sx6AMo>Mj!~~wQJ&!b+7_BapKGk4+ z%3ys^L1>Bt^K&?*IxoENIo^Ejbyn`L@NE4oPds^=x>@D5i{ItS-4B_RRi4m~apYiw zdz-7QuQz$=wI9$TvMW{#s%)Ib~tco8fR;Zt~UTAt^?E4%hakmw?Do_$+W0V%<(5*`~!|2KgP=4 zyG%|V!-DzGokmk-+TA{usnH*FaDx_y7AAP& z>U-0bN<2ZvhE2}L&_xv1XOAtmH(^F%hTozXZgIR6>RL3EAAgva40 zs_4e(J)sN$t&k31di`&)%y>QRD6qRwDghppO{k4YbSY7R#MA{Cpz9J%#k+@t$R)TM z;d%FQq3VH*DUQWIv2%*}D7eViDfT=;X20agOq2q!tKtyo)2J}Oy*9C3} zdZ@4isFXFveG@Ix=ng!5BcfUtIF3&wC7u^Od{cC2Euai6spAA5HO)Y?LL#Xsk4Zv5 z!uAwV2$367)g__~jk1C7`1mMFkwqQJ&D8cb1=9pC1Yat;9fj*asGw33IDx{@1->h&nstuMjt-PZA_^&&blUw8Gmxm7pie-n7a}SiZX1ko7}o>@;9COSfeA`D?Eue-FscF~ z#h4Y(>DdaSB&eGj)iH^$N3^#iv=Hn-VfccHszFtP@N@>IL)ntJUW7desThKRGaw3e zq^U!o*lGoY8o0YLAU*K|FYCPU^$t6CBL2I+5*1>%P3qy-H>&Wv`2AnH3%Tbvg6U>> zlzbtILPZbV6)sB2-Y?Wf-IDARq#LJcOcB|j+Vd6F-jg%@{-wB$xN}Ppk#Fv#8>_I> zo>?0LApK5Q3jKjQ{?~pdEFNTlNWRG0`JM2nrt7*M0etJ#SNBxz|7#QFa#_}@Ae-|m`5GGG}sOR0000 Date: Wed, 21 Nov 2012 16:51:23 +0000 Subject: [PATCH 166/222] set default Album Thumbnail picture git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5867 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui index 978b6e4d1..b45df4373 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui @@ -123,8 +123,8 @@ border-radius: 10px; - - :/images/channels.png:/images/channels.png + + :/images/album_64.png:/images/album_64.png @@ -349,6 +349,7 @@ border-radius: 10px; + From 55d562238ed17f0d059d8ec38ab5e3dcc2fbbd10 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Wed, 21 Nov 2012 18:55:52 +0000 Subject: [PATCH 167/222] Applied changes from the trunk to the GXS forums. Cleaned old and unused files. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5868 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/RetroShare.pro | 3 - retroshare-gui/src/gui/ForumsV2Dialog.cpp | 2404 --------------- retroshare-gui/src/gui/ForumsV2Dialog.h | 271 -- retroshare-gui/src/gui/ForumsV2Dialog.ui | 1251 -------- retroshare-gui/src/gui/GxsForumsDialog.cpp | 2624 ++++++++--------- retroshare-gui/src/gui/GxsForumsDialog.h | 271 +- retroshare-gui/src/gui/GxsForumsDialog.ui | 775 +---- .../src/gui/Posted/PostedGroupDialog.cpp | 11 +- .../src/gui/Posted/PostedGroupDialog.h | 3 +- .../src/gui/forumsv2/CreateForumV2.cpp | 230 -- .../src/gui/forumsv2/CreateForumV2.h | 67 - .../src/gui/forumsv2/CreateForumV2.ui | 374 --- .../src/gui/forumsv2/CreateForumV2Msg.cpp | 424 --- .../src/gui/forumsv2/CreateForumV2Msg.h | 86 - .../src/gui/forumsv2/CreateForumV2Msg.ui | 333 --- .../src/gui/forumsv2/EditForumV2Details.cpp | 89 - .../src/gui/forumsv2/EditForumV2Details.h | 53 - .../src/gui/forumsv2/EditForumV2Details.ui | 130 - .../src/gui/forumsv2/ForumV2Details.cpp | 146 - .../src/gui/forumsv2/ForumV2Details.h | 67 - .../src/gui/forumsv2/ForumV2Details.ui | 201 -- .../src/gui/gxs/ForumV2GroupDialog.cpp | 100 - .../src/gui/gxs/ForumV2GroupDialog.h | 44 - .../src/gui/gxs/GxsForumGroupDialog.cpp | 14 +- .../src/gui/gxs/GxsForumGroupDialog.h | 4 +- retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp | 54 +- retroshare-gui/src/gui/gxs/GxsGroupDialog.h | 10 +- retroshare-gui/src/gui/gxs/GxsGroupDialog.ui | 130 +- .../src/gui/gxs/GxsIdTreeWidgetItem.cpp | 26 +- .../src/gui/gxs/GxsIdTreeWidgetItem.h | 12 +- .../src/gui/gxs/WikiGroupDialog.cpp | 14 +- retroshare-gui/src/gui/gxs/WikiGroupDialog.h | 4 +- .../src/gui/gxsforums/CreateGxsForum.cpp | 234 -- .../src/gui/gxsforums/CreateGxsForum.h | 67 - .../src/gui/gxsforums/CreateGxsForum.ui | 374 --- .../src/gui/gxsforums/CreateGxsForumMsg.cpp | 29 +- .../src/gui/gxsforums/CreateGxsForumMsg.h | 13 +- .../src/gui/gxsforums/CreateGxsForumMsg.ui | 257 +- .../src/gui/gxsforums/EditGxsForumDetails.cpp | 7 +- .../src/gui/gxsforums/EditGxsForumDetails.h | 2 +- .../src/gui/gxsforums/EditGxsForumDetails.ui | 51 +- .../src/gui/gxsforums/GxsForumDetails.cpp | 36 +- .../src/gui/gxsforums/GxsForumDetails.h | 11 +- .../src/gui/gxsforums/GxsForumDetails.ui | 32 +- 44 files changed, 1744 insertions(+), 9594 deletions(-) delete mode 100644 retroshare-gui/src/gui/ForumsV2Dialog.cpp delete mode 100644 retroshare-gui/src/gui/ForumsV2Dialog.h delete mode 100644 retroshare-gui/src/gui/ForumsV2Dialog.ui delete mode 100644 retroshare-gui/src/gui/forumsv2/CreateForumV2.cpp delete mode 100644 retroshare-gui/src/gui/forumsv2/CreateForumV2.h delete mode 100644 retroshare-gui/src/gui/forumsv2/CreateForumV2.ui delete mode 100644 retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.cpp delete mode 100644 retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.h delete mode 100644 retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.ui delete mode 100644 retroshare-gui/src/gui/forumsv2/EditForumV2Details.cpp delete mode 100644 retroshare-gui/src/gui/forumsv2/EditForumV2Details.h delete mode 100644 retroshare-gui/src/gui/forumsv2/EditForumV2Details.ui delete mode 100644 retroshare-gui/src/gui/forumsv2/ForumV2Details.cpp delete mode 100644 retroshare-gui/src/gui/forumsv2/ForumV2Details.h delete mode 100644 retroshare-gui/src/gui/forumsv2/ForumV2Details.ui delete mode 100644 retroshare-gui/src/gui/gxs/ForumV2GroupDialog.cpp delete mode 100644 retroshare-gui/src/gui/gxs/ForumV2GroupDialog.h delete mode 100644 retroshare-gui/src/gui/gxsforums/CreateGxsForum.cpp delete mode 100644 retroshare-gui/src/gui/gxsforums/CreateGxsForum.h delete mode 100644 retroshare-gui/src/gui/gxsforums/CreateGxsForum.ui diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index e8e1dc8ed..9af9bfef8 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -967,19 +967,16 @@ gxsforums { HEADERS += gui/GxsForumsDialog.h \ gui/gxsforums/GxsForumDetails.h \ gui/gxsforums/EditGxsForumDetails.h \ - gui/gxsforums/CreateGxsForum.h \ gui/gxsforums/CreateGxsForumMsg.h \ FORMS += gui/GxsForumsDialog.ui \ gui/gxsforums/GxsForumDetails.ui \ gui/gxsforums/EditGxsForumDetails.ui \ - gui/gxsforums/CreateGxsForum.ui \ gui/gxsforums/CreateGxsForumMsg.ui \ SOURCES += gui/GxsForumsDialog.cpp \ gui/gxsforums/GxsForumDetails.cpp \ gui/gxsforums/EditGxsForumDetails.cpp \ - gui/gxsforums/CreateGxsForum.cpp \ gui/gxsforums/CreateGxsForumMsg.cpp \ } diff --git a/retroshare-gui/src/gui/ForumsV2Dialog.cpp b/retroshare-gui/src/gui/ForumsV2Dialog.cpp deleted file mode 100644 index 62ec6061c..000000000 --- a/retroshare-gui/src/gui/ForumsV2Dialog.cpp +++ /dev/null @@ -1,2404 +0,0 @@ -/**************************************************************** - * RetroShare is distributed under the following license: - * - * Copyright (C) 2008 Robert Fernie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - ****************************************************************/ - -#include -#include -#include -#include -#include -#include - -#include "ForumsV2Dialog.h" - -#include "gxs/ForumV2GroupDialog.h" - -#include "forumsv2/CreateForumV2Msg.h" - -#include "msgs/MessageComposer.h" -#include "settings/rsharesettings.h" -#include "common/Emoticons.h" -#include "common/RSItemDelegate.h" -#include "common/PopularityDefs.h" -#include "RetroShareLink.h" -#include "channels/ShareKey.h" -#include "notifyqt.h" -#include "util/HandleRichText.h" - -#include -#include - -#include - -//#define DEBUG_FORUMS - -/* Images for context menu icons */ -#define IMAGE_MESSAGE ":/images/folder-draft.png" -#define IMAGE_MESSAGEREPLY ":/images/mail_reply.png" -#define IMAGE_MESSAGEREMOVE ":/images/mail_delete.png" -#define IMAGE_DOWNLOAD ":/images/start.png" -#define IMAGE_DOWNLOADALL ":/images/startall.png" - -/* Images for TreeWidget */ -#define IMAGE_FOLDER ":/images/folder16.png" -#define IMAGE_FOLDERGREEN ":/images/folder_green.png" -#define IMAGE_FOLDERRED ":/images/folder_red.png" -#define IMAGE_FOLDERYELLOW ":/images/folder_yellow.png" -#define IMAGE_FORUM ":/images/konversation.png" -#define IMAGE_SUBSCRIBE ":/images/edit_add24.png" -#define IMAGE_UNSUBSCRIBE ":/images/cancel.png" -#define IMAGE_INFO ":/images/info16.png" -#define IMAGE_NEWFORUM ":/images/new_forum16.png" -#define IMAGE_FORUMAUTHD ":/images/konv_message2.png" -#define IMAGE_COPYLINK ":/images/copyrslink.png" - -#define VIEW_LAST_POST 0 -#define VIEW_THREADED 1 -#define VIEW_FLAT 2 - -/* Thread constants */ -#define COLUMN_THREAD_COUNT 6 -#define COLUMN_THREAD_TITLE 0 -#define COLUMN_THREAD_READ 1 -#define COLUMN_THREAD_DATE 2 -#define COLUMN_THREAD_AUTHOR 3 -#define COLUMN_THREAD_SIGNED 4 -#define COLUMN_THREAD_CONTENT 5 - -#define COLUMN_THREAD_DATA 0 // column for storing the userdata like msgid and parentid - -#define ROLE_THREAD_MSGID Qt::UserRole -#define ROLE_THREAD_STATUS Qt::UserRole + 1 -#define ROLE_THREAD_MISSING Qt::UserRole + 2 -// no need to copy, don't count in ROLE_THREAD_COUNT -#define ROLE_THREAD_READCHILDREN Qt::UserRole + 3 -#define ROLE_THREAD_UNREADCHILDREN Qt::UserRole + 4 - -#define ROLE_THREAD_COUNT 3 - - -static int FilterColumnFromComboBox(int nIndex) -{ - switch (nIndex) { - case 0: - return COLUMN_THREAD_DATE; - case 1: - return COLUMN_THREAD_TITLE; - case 2: - return COLUMN_THREAD_AUTHOR; - case 3: - return COLUMN_THREAD_CONTENT; - } - - return COLUMN_THREAD_TITLE; -} - -static int FilterColumnToComboBox(int nIndex) -{ - switch (nIndex) { - case COLUMN_THREAD_DATE: - return 0; - case COLUMN_THREAD_TITLE: - return 1; - case COLUMN_THREAD_AUTHOR: - return 2; - case COLUMN_THREAD_CONTENT: - return 3; - } - - return FilterColumnToComboBox(COLUMN_THREAD_TITLE); -} - - -/* - * Transformation Notes: - * there are still a couple of things that the new forums differ from Old version. - * these will need to be addressed in the future. - * -> Missing Messages are not handled yet. - * -> Child TS (for sorting) is not handled by GXS, this will probably have to be done in the GUI. - * -> Need to handle IDs properly. - * -> Popularity not handled in GXS yet. - * -> Much more to do. - */ - -/** Constructor */ -ForumsV2Dialog::ForumsV2Dialog(QWidget *parent) -: RsAutoUpdatePage(1000,parent) -{ - /* Invoke the Qt Designer generated object setup routine */ - ui.setupUi(this); - - m_bProcessSettings = false; - subscribeFlags = 0; - inMsgAsReadUnread = false; - - - /* Setup Queue */ - mForumQueue = new TokenQueue(rsForumsV2, this); - - - - connect( ui.forumTreeWidget, SIGNAL( treeCustomContextMenuRequested( QPoint ) ), this, SLOT( forumListCustomPopupMenu( QPoint ) ) ); - connect( ui.threadTreeWidget, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( threadListCustomPopupMenu( QPoint ) ) ); - - connect(ui.newForumButton, SIGNAL(clicked()), this, SLOT(newforum())); - connect(ui.newmessageButton, SIGNAL(clicked()), this, SLOT(createmessage())); - connect(ui.newthreadButton, SIGNAL(clicked()), this, SLOT(createthread())); - - connect( ui.forumTreeWidget, SIGNAL( treeCurrentItemChanged(QString) ), this, SLOT( changedForum(QString) ) ); - - connect( ui.threadTreeWidget, SIGNAL( itemSelectionChanged() ), this, SLOT( changedThread () ) ); - connect( ui.threadTreeWidget, SIGNAL( itemClicked(QTreeWidgetItem*,int)), this, SLOT( clickedThread (QTreeWidgetItem*,int) ) ); - connect( ui.viewBox, SIGNAL( currentIndexChanged ( int ) ), this, SLOT( changedViewBox () ) ); - - connect(ui.expandButton, SIGNAL(clicked()), this, SLOT(togglethreadview())); - connect(ui.previousButton, SIGNAL(clicked()), this, SLOT(previousMessage())); - connect(ui.nextButton, SIGNAL(clicked()), this, SLOT(nextMessage())); - connect(ui.nextUnreadButton, SIGNAL(clicked()), this, SLOT(nextUnreadMessage())); - - connect(ui.downloadButton, SIGNAL(clicked()), this, SLOT(downloadAllFiles())); - - connect(ui.filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterItems(QString))); - connect(ui.filterColumnComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterColumnChanged())); - - connect(NotifyQt::getInstance(), SIGNAL(forumMsgReadSatusChanged(QString,QString,int)), this, SLOT(forumMsgReadSatusChanged(QString,QString,int))); - - /* Set initial size the splitter */ - QList sizes; - sizes << 300 << width(); // Qt calculates the right sizes - //ui.splitter->setSizes(sizes); - - /* Set own item delegate */ - RSItemDelegate *itemDelegate = new RSItemDelegate(this); - itemDelegate->setSpacing(QSize(0, 2)); - ui.threadTreeWidget->setItemDelegate(itemDelegate); - - /* Set header resize modes and initial section sizes */ - QHeaderView * ttheader = ui.threadTreeWidget->header () ; - ttheader->setResizeMode (COLUMN_THREAD_TITLE, QHeaderView::Interactive); - ttheader->resizeSection (COLUMN_THREAD_DATE, 140); - ttheader->resizeSection (COLUMN_THREAD_TITLE, 290); - - ui.threadTreeWidget->sortItems( COLUMN_THREAD_DATE, Qt::DescendingOrder ); - - /* Set text of column "Read" to empty - without this the column has a number as header text */ - QTreeWidgetItem *headerItem = ui.threadTreeWidget->headerItem(); - headerItem->setText(COLUMN_THREAD_READ, ""); - - m_ForumNameFont = QFont("Times", 12, QFont::Bold); - ui.forumName->setFont(m_ForumNameFont); - ui.threadTitle->setFont(m_ForumNameFont); - - /* Initialize group tree */ - ui.forumTreeWidget->initDisplayMenu(ui.displayButton); - - /* create forum tree */ - yourForums = ui.forumTreeWidget->addCategoryItem(tr("Your Forums"), QIcon(IMAGE_FOLDER), true); - subscribedForums = ui.forumTreeWidget->addCategoryItem(tr("Subscribed Forums"), QIcon(IMAGE_FOLDERRED), true); - popularForums = ui.forumTreeWidget->addCategoryItem(tr("Popular Forums"), QIcon(IMAGE_FOLDERGREEN), false); - otherForums = ui.forumTreeWidget->addCategoryItem(tr("Other Forums"), QIcon(IMAGE_FOLDERYELLOW), false); - - lastViewType = -1; - - // load settings - processSettings(true); - - /* Set header sizes for the fixed columns and resize modes, must be set after processSettings */ - ttheader->resizeSection (COLUMN_THREAD_READ, 24); - ttheader->setResizeMode (COLUMN_THREAD_READ, QHeaderView::Fixed); - ttheader->hideSection (COLUMN_THREAD_CONTENT); - - ui.progressBar->hide(); - ui.progLayOutTxt->hide(); - ui.progressBarLayOut->setEnabled(false); - - mThreadLoading = false; - - insertThreads(); - - ui.threadTreeWidget->installEventFilter(this); - - /* Hide platform specific features */ -#ifdef Q_WS_WIN - -#endif -} - -ForumsV2Dialog::~ForumsV2Dialog() -{ - // save settings - processSettings(false); -} - -void ForumsV2Dialog::processSettings(bool bLoad) -{ - m_bProcessSettings = true; - - QHeaderView *pHeader = ui.threadTreeWidget->header () ; - - Settings->beginGroup(QString("ForumsV2Dialog")); - - if (bLoad) { - // load settings - - // expandFiles - bool bValue = Settings->value("expandButton", true).toBool(); - ui.expandButton->setChecked(bValue); - togglethreadview_internal(); - - // filterColumn - int nValue = FilterColumnToComboBox(Settings->value("filterColumn", COLUMN_THREAD_TITLE).toInt()); - ui.filterColumnComboBox->setCurrentIndex(nValue); - - // index of viewBox - ui.viewBox->setCurrentIndex(Settings->value("viewBox", VIEW_THREADED).toInt()); - - // state of thread tree - pHeader->restoreState(Settings->value("ThreadTree").toByteArray()); - - // state of splitter - ui.splitter->restoreState(Settings->value("Splitter").toByteArray()); - ui.threadSplitter->restoreState(Settings->value("threadSplitter").toByteArray()); - } else { - // save settings - - // state of thread tree - Settings->setValue("ThreadTree", pHeader->saveState()); - - // state of splitter - Settings->setValue("Splitter", ui.splitter->saveState()); - Settings->setValue("threadSplitter", ui.threadSplitter->saveState()); - } - - ui.forumTreeWidget->processSettings(Settings, bLoad); - - Settings->endGroup(); - m_bProcessSettings = false; -} - -void ForumsV2Dialog::forumListCustomPopupMenu( QPoint /*point*/ ) -{ - QMenu contextMnu( this ); - - QAction *action = contextMnu.addAction(QIcon(IMAGE_SUBSCRIBE), tr("Subscribe to Forum"), this, SLOT(subscribeToForum())); - action->setDisabled (mCurrForumId.empty() || IS_GROUP_SUBSCRIBED(subscribeFlags)); - - action = contextMnu.addAction(QIcon(IMAGE_UNSUBSCRIBE), tr("Unsubscribe to Forum"), this, SLOT(unsubscribeToForum())); - action->setEnabled (!mCurrForumId.empty() && IS_GROUP_SUBSCRIBED(subscribeFlags)); - - contextMnu.addSeparator(); - - contextMnu.addAction(QIcon(IMAGE_NEWFORUM), tr("New Forum"), this, SLOT(newforum())); - - action = contextMnu.addAction(QIcon(IMAGE_INFO), tr("Show Forum Details"), this, SLOT(showForumDetails())); - action->setEnabled (!mCurrForumId.empty ()); - - action = contextMnu.addAction(QIcon(":/images/settings16.png"), tr("Edit Forum Details"), this, SLOT(editForumDetails())); - action->setEnabled (!mCurrForumId.empty () && IS_GROUP_ADMIN(subscribeFlags)); - - QAction *shareKeyAct = new QAction(QIcon(":/images/gpgp_key_generate.png"), tr("Share Forum"), &contextMnu); - connect( shareKeyAct, SIGNAL( triggered() ), this, SLOT( shareKey() ) ); - shareKeyAct->setEnabled(!mCurrForumId.empty() && IS_GROUP_ADMIN(subscribeFlags)); - contextMnu.addAction( shareKeyAct); - - QAction *restoreKeysAct = new QAction(QIcon(":/images/settings16.png"), tr("Restore Publish Rights for Forum" ), &contextMnu); - connect( restoreKeysAct , SIGNAL( triggered() ), this, SLOT( restoreForumKeys() ) ); - restoreKeysAct->setEnabled(!mCurrForumId.empty() && !IS_GROUP_ADMIN(subscribeFlags)); - contextMnu.addAction( restoreKeysAct); - - action = contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyForumLink())); - action->setEnabled(!mCurrForumId.empty()); - - contextMnu.addSeparator(); - - action = contextMnu.addAction(QIcon(":/images/message-mail-read.png"), tr("Mark all as read"), this, SLOT(markMsgAsReadAll())); - action->setEnabled (!mCurrForumId.empty () && IS_GROUP_SUBSCRIBED(subscribeFlags)); - - action = contextMnu.addAction(QIcon(":/images/message-mail.png"), tr("Mark all as unread"), this, SLOT(markMsgAsUnreadAll())); - action->setEnabled (!mCurrForumId.empty () && IS_GROUP_SUBSCRIBED(subscribeFlags)); - -#ifdef DEBUG_FORUMS - contextMnu.addSeparator(); - action = contextMnu.addAction("Generate mass data", this, SLOT(generateMassData())); - action->setEnabled (!mCurrForumId.empty() && IS_GROUP_SUBSCRIBED(subscribeFlags)); -#endif - - contextMnu.exec(QCursor::pos()); -} - -void ForumsV2Dialog::threadListCustomPopupMenu( QPoint /*point*/ ) -{ - if (mThreadLoading) { - return; - } - - QMenu contextMnu( this ); - - QAction *replyAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr( "Reply" ), &contextMnu ); - connect( replyAct , SIGNAL( triggered() ), this, SLOT( createmessage() ) ); - - QAction *newthreadAct = new QAction(QIcon(IMAGE_DOWNLOADALL), tr( "Start New Thread" ), &contextMnu ); - newthreadAct->setEnabled (IS_GROUP_SUBSCRIBED(subscribeFlags)); - connect( newthreadAct , SIGNAL( triggered() ), this, SLOT( createthread() ) ); - - QAction *replyauthorAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr( "Reply to Author" ), &contextMnu ); - connect( replyauthorAct , SIGNAL( triggered() ), this, SLOT( replytomessage() ) ); - - QAction* expandAll = new QAction(tr( "Expand all" ), &contextMnu ); - connect( expandAll , SIGNAL( triggered() ), ui.threadTreeWidget, SLOT (expandAll()) ); - - QAction* collapseAll = new QAction(tr( "Collapse all" ), &contextMnu ); - connect( collapseAll , SIGNAL( triggered() ), ui.threadTreeWidget, SLOT(collapseAll()) ); - - QAction *markMsgAsRead = new QAction(QIcon(":/images/message-mail-read.png"), tr("Mark as read"), &contextMnu); - connect(markMsgAsRead , SIGNAL(triggered()), this, SLOT(markMsgAsRead())); - - QAction *markMsgAsReadChildren = new QAction(QIcon(":/images/message-mail-read.png"), tr("Mark as read") + " (" + tr ("with children") + ")", &contextMnu); - connect(markMsgAsReadChildren, SIGNAL(triggered()), this, SLOT(markMsgAsReadChildren())); - - QAction *markMsgAsUnread = new QAction(QIcon(":/images/message-mail.png"), tr("Mark as unread"), &contextMnu); - connect(markMsgAsUnread , SIGNAL(triggered()), this, SLOT(markMsgAsUnread())); - - QAction *markMsgAsUnreadChildren = new QAction(QIcon(":/images/message-mail.png"), tr("Mark as unread") + " (" + tr ("with children") + ")", &contextMnu); - connect(markMsgAsUnreadChildren , SIGNAL(triggered()), this, SLOT(markMsgAsUnreadChildren())); - - if (IS_GROUP_SUBSCRIBED(subscribeFlags)) { - QList Rows; - QList RowsRead; - QList RowsUnread; - int nCount = getSelectedMsgCount (&Rows, &RowsRead, &RowsUnread); - - if (RowsUnread.size() == 0) { - - markMsgAsRead->setDisabled(true); - } - if (RowsRead.size() == 0) { - markMsgAsUnread->setDisabled(true); - } - - bool bHasUnreadChildren = false; - bool bHasReadChildren = false; - int nRowCount = Rows.count(); - for (int i = 0; i < nRowCount; i++) { - if (bHasUnreadChildren || Rows[i]->data(COLUMN_THREAD_DATA, ROLE_THREAD_UNREADCHILDREN).toBool()) { - bHasUnreadChildren = true; - } - if (bHasReadChildren || Rows[i]->data(COLUMN_THREAD_DATA, ROLE_THREAD_READCHILDREN).toBool()) { - bHasReadChildren = true; - } - } - markMsgAsReadChildren->setEnabled(bHasUnreadChildren); - markMsgAsUnreadChildren->setEnabled(bHasReadChildren); - - if (nCount == 1) { - replyAct->setEnabled (true); - replyauthorAct->setEnabled (true); - } else { - replyAct->setDisabled (true); - replyauthorAct->setDisabled (true); - } - } else { - markMsgAsRead->setDisabled(true); - markMsgAsReadChildren->setDisabled(true); - markMsgAsUnread->setDisabled(true); - markMsgAsUnreadChildren->setDisabled(true); - replyAct->setDisabled (true); - replyauthorAct->setDisabled (true); - } - - contextMnu.addAction( replyAct); - contextMnu.addAction( newthreadAct); - contextMnu.addAction( replyauthorAct); - QAction* action = contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr( "Copy RetroShare Link"), this, SLOT(copyMessageLink())); - action->setEnabled(!mCurrForumId.empty() && !mCurrThreadId.empty()); - contextMnu.addSeparator(); - contextMnu.addAction(markMsgAsRead); - contextMnu.addAction(markMsgAsReadChildren); - contextMnu.addAction(markMsgAsUnread); - contextMnu.addAction(markMsgAsUnreadChildren); - contextMnu.addSeparator(); - contextMnu.addAction( expandAll); - contextMnu.addAction( collapseAll); - - contextMnu.exec(QCursor::pos()); -} - -bool ForumsV2Dialog::eventFilter(QObject *obj, QEvent *event) -{ - if (obj == ui.threadTreeWidget) { - if (event->type() == QEvent::KeyPress) { - QKeyEvent *keyEvent = static_cast(event); - if (keyEvent && keyEvent->key() == Qt::Key_Space) { - // Space pressed - QTreeWidgetItem *item = ui.threadTreeWidget->currentItem (); - clickedThread (item, COLUMN_THREAD_READ); - return true; // eat event - } - } - } - // pass the event on to the parent class - return RsAutoUpdatePage::eventFilter(obj, event); -} - -void ForumsV2Dialog::restoreForumKeys(void) -{ - rsForumsV2->groupRestoreKeys(mCurrForumId); -} - -void ForumsV2Dialog::togglethreadview() -{ - // save state of button - Settings->setValueToGroup("ForumsV2Dialog", "expandButton", ui.expandButton->isChecked()); - - togglethreadview_internal(); -} - -void ForumsV2Dialog::togglethreadview_internal() -{ - if (ui.expandButton->isChecked()) { - ui.postText->setVisible(true); - ui.expandButton->setIcon(QIcon(QString(":/images/edit_remove24.png"))); - ui.expandButton->setToolTip(tr("Hide")); - } else { - ui.postText->setVisible(false); - ui.expandButton->setIcon(QIcon(QString(":/images/edit_add24.png"))); - ui.expandButton->setToolTip(tr("Expand")); - } -} - -void ForumsV2Dialog::updateDisplay() -{ - std::list forumIds; - std::list::iterator it; - if (!rsForumsV2) - return; - -#if 0 - // TODO groupsChanged... HACK XXX. - if ((rsForumsV2->groupsChanged(forumIds)) || (rsForumsV2->updated())) - { - /* update Forums List */ - insertForums(); - - it = std::find(forumIds.begin(), forumIds.end(), mCurrForumId); - if (it != forumIds.end()) - { - /* update threads as well */ - insertThreads(); - } - } -#endif - - /* The proper version (above) can be done with a data request -> TODO */ - if (rsForumsV2->updated()) - { - /* update Forums List */ - insertForums(); - /* update threads as well */ - insertThreads(); - } -} - -static void CleanupItems (QList &items) -{ - QList::iterator item; - for (item = items.begin (); item != items.end (); item++) { - if (*item) { - delete (*item); - } - } - items.clear(); -} - -void ForumsV2Dialog::forumInfoToGroupItemInfo(const RsGroupMetaData &forumInfo, GroupItemInfo &groupItemInfo) -//void ForumsV2Dialog::forumInfoToGroupItemInfo(const ForumInfo &forumInfo, GroupItemInfo &groupItemInfo) -{ - - groupItemInfo.id = QString::fromStdString(forumInfo.mGroupId); - groupItemInfo.name = QString::fromUtf8(forumInfo.mGroupName.c_str()); - //groupItemInfo.description = QString::fromUtf8(forumInfo.forumDesc); - groupItemInfo.popularity = forumInfo.mPop; - groupItemInfo.lastpost = QDateTime::fromTime_t(forumInfo.mLastPost); - - if (forumInfo.mGroupFlags & RS_DISTRIB_AUTHEN_REQ) { - groupItemInfo.name += " (" + tr("AUTHD") + ")"; - groupItemInfo.icon = QIcon(IMAGE_FORUMAUTHD); - } else { - groupItemInfo.icon = QIcon(IMAGE_FORUM); - } - -// groupItemInfo.id = QString::fromStdString(forumInfo.forumId); -// groupItemInfo.name = QString::fromStdWString(forumInfo.forumName); -// groupItemInfo.description = QString::fromStdWString(forumInfo.forumDesc); -// groupItemInfo.popularity = forumInfo.pop; -// groupItemInfo.lastpost = QDateTime::fromTime_t(forumInfo.lastPost); -// -// if (forumInfo.forumFlags & RS_DISTRIB_AUTHEN_REQ) { -// groupItemInfo.name += " (" + tr("AUTHD") + ")"; -// groupItemInfo.icon = QIcon(IMAGE_FORUMAUTHD); -// } else { -// groupItemInfo.icon = QIcon(IMAGE_FORUM); -// } -} - - -/***** INSERT FORUM LISTS *****/ -void ForumsV2Dialog::insertForumsData(const std::list &forumList) -{ - std::list::const_iterator it; - - QList adminList; - QList subList; - QList popList; - QList otherList; - std::multimap popMap; - - for (it = forumList.begin(); it != forumList.end(); it++) { - /* sort it into Publish (Own), Subscribed, Popular and Other */ - uint32_t flags = it->mSubscribeFlags; - - GroupItemInfo groupItemInfo; - forumInfoToGroupItemInfo(*it, groupItemInfo); - - if (flags & RSGXS_GROUP_SUBSCRIBE_ADMIN) { - adminList.push_back(groupItemInfo); - } else if (flags & RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED) { - /* subscribed forum */ - subList.push_back(groupItemInfo); - } else { - /* rate the others by popularity */ - popMap.insert(std::make_pair(it->mPop, groupItemInfo)); - } - } - - /* iterate backwards through popMap - take the top 5 or 10% of list */ - uint32_t popCount = 5; - if (popCount < popMap.size() / 10) - { - popCount = popMap.size() / 10; - } - - uint32_t i = 0; - uint32_t popLimit = 0; - std::multimap::reverse_iterator rit; - for(rit = popMap.rbegin(); ((rit != popMap.rend()) && (i < popCount)); rit++, i++) ; - if (rit != popMap.rend()) { - popLimit = rit->first; - } - - for (rit = popMap.rbegin(); rit != popMap.rend(); rit++) { - if (rit->second.popularity < (int) popLimit) { - otherList.append(rit->second); - } else { - popList.append(rit->second); - } - } - - /* now we can add them in as a tree! */ - ui.forumTreeWidget->fillGroupItems(yourForums, adminList); - ui.forumTreeWidget->fillGroupItems(subscribedForums, subList); - ui.forumTreeWidget->fillGroupItems(popularForums, popList); - ui.forumTreeWidget->fillGroupItems(otherForums, otherList); - - updateMessageSummaryList(""); -} - -void ForumsV2Dialog::changedForum(const QString &id) -{ - mCurrForumId = id.toStdString(); - - insertThreads(); -} - -void ForumsV2Dialog::changedThread () -{ - if (mThreadLoading) { - return; - } - - /* just grab the ids of the current item */ - QTreeWidgetItem *curr = ui.threadTreeWidget->currentItem(); - - if ((!curr) || (!curr->isSelected())) { - mCurrThreadId = ""; - } else { - mCurrThreadId = curr->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString(); - } - insertPost(); -} - -void ForumsV2Dialog::clickedThread (QTreeWidgetItem *item, int column) -{ - if (mCurrForumId.empty() || !IS_GROUP_SUBSCRIBED(subscribeFlags)) { - return; - } - - if (item == NULL) { - return; - } - - if (column == COLUMN_THREAD_READ) { - QList Rows; - Rows.append(item); - uint32_t status = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - setMsgAsReadUnread(Rows, IS_MSG_UNREAD(status)); - return; - } -} - -void ForumsV2Dialog::forumMsgReadStatusChanged(const QString &forumId, const QString &msgId, int status) -{ - if (inMsgAsReadUnread) { - return; - } - - if (forumId.toStdString() == mCurrForumId) { - /* Search exisiting item */ - QTreeWidgetItemIterator itemIterator(ui.threadTreeWidget); - QTreeWidgetItem *item = NULL; - while ((item = *itemIterator) != NULL) { - itemIterator++; - - if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString() == msgId) { - // update status - item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, status); - - QTreeWidgetItem *parentItem = item; - while (parentItem->parent()) { - parentItem = parentItem->parent(); - } - CalculateIconsAndFonts(parentItem); - break; - } - } - } - updateMessageSummaryList(forumId.toStdString()); -} - -void ForumsV2Dialog::CalculateIconsAndFonts(QTreeWidgetItem *pItem, bool &bHasReadChilddren, bool &bHasUnreadChilddren) -{ - uint32_t status = pItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - - bool bUnread = IS_MSG_UNREAD(status); - bool missing = pItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING).toBool(); - - // set icon - if (missing) { - pItem->setIcon(COLUMN_THREAD_READ, QIcon()); - pItem->setIcon(COLUMN_THREAD_TITLE, QIcon()); - } else { - if (bUnread) { - pItem->setIcon(COLUMN_THREAD_READ, QIcon(":/images/message-state-unread.png")); - } else { - pItem->setIcon(COLUMN_THREAD_READ, QIcon(":/images/message-state-read.png")); - } - if (status & RSGXS_MSG_STATUS_READ) { - pItem->setIcon(COLUMN_THREAD_TITLE, QIcon()); - } else { - pItem->setIcon(COLUMN_THREAD_TITLE, QIcon(":/images/message-state-new.png")); - } - } - - int nItem; - int nItemCount = pItem->childCount(); - - bool bMyReadChilddren = false; - bool bMyUnreadChilddren = false; - - for (nItem = 0; nItem < nItemCount; nItem++) { - CalculateIconsAndFonts(pItem->child(nItem), bMyReadChilddren, bMyUnreadChilddren); - } - - // set font - for (int i = 0; i < COLUMN_THREAD_COUNT; i++) { - QFont qf = pItem->font(i); - - if (!IS_GROUP_SUBSCRIBED(subscribeFlags)) { - qf.setBold(false); - pItem->setTextColor(i, Qt::black); - } else if (bUnread) { - qf.setBold(true); - pItem->setTextColor(i, Qt::black); - } else if (bMyUnreadChilddren) { - qf.setBold(true); - pItem->setTextColor(i, Qt::gray); - } else { - qf.setBold(false); - pItem->setTextColor(i, Qt::gray); - } - if (missing) { - /* Missing message */ - pItem->setTextColor(i, Qt::darkRed); - } - pItem->setFont(i, qf); - } - - pItem->setData(COLUMN_THREAD_DATA, ROLE_THREAD_READCHILDREN, bHasReadChilddren || bMyReadChilddren); - pItem->setData(COLUMN_THREAD_DATA, ROLE_THREAD_UNREADCHILDREN, bHasUnreadChilddren || bMyUnreadChilddren); - - bHasReadChilddren = bHasReadChilddren || bMyReadChilddren || !bUnread; - bHasUnreadChilddren = bHasUnreadChilddren || bMyUnreadChilddren || bUnread; -} - -void ForumsV2Dialog::CalculateIconsAndFonts(QTreeWidgetItem *pItem /*= NULL*/) -{ - bool bDummy1 = false; - bool bDummy2 = false; - - if (pItem) { - CalculateIconsAndFonts(pItem, bDummy1, bDummy2); - return; - } - - int nItem; - int nItemCount = ui.threadTreeWidget->topLevelItemCount(); - - for (nItem = 0; nItem < nItemCount; nItem++) { - bDummy1 = false; - bDummy2 = false; - CalculateIconsAndFonts(ui.threadTreeWidget->topLevelItem(nItem), bDummy1, bDummy2); - } -} - -void ForumsV2Dialog::fillThreadFinished() -{ -#ifdef DEBUG_FORUMS - std::cerr << "ForumsV2Dialog::fillThreadFinished" << std::endl; -#endif - - // This is now only called with a successful Load. - // cleanup of incomplete is handled elsewhere. - - // current thread has finished, hide progressbar and release thread - ui.progressBar->hide(); - ui.progLayOutTxt->hide(); - ui.progressBarLayOut->setEnabled(false); - -#ifdef DEBUG_FORUMS - std::cerr << "ForumsV2Dialog::fillThreadFinished Add messages" << std::endl; -#endif - ui.threadTreeWidget->setSortingEnabled(false); - - /* add all messages in! */ - if (lastViewType != mThreadLoad.ViewType || lastForumID != mCurrForumId) - { - ui.threadTreeWidget->clear(); - lastViewType = mThreadLoad.ViewType; - lastForumID = mCurrForumId; - ui.threadTreeWidget->insertTopLevelItems(0, mThreadLoad.Items); - - // clear list - mThreadLoad.Items.clear(); - } - else - { - FillThreads (mThreadLoad.Items, mThreadLoad.ExpandNewMessages, mThreadLoad.ItemToExpand); - - // cleanup list - CleanupItems (mThreadLoad.Items); - } - - ui.threadTreeWidget->setSortingEnabled(true); - - if (mThreadLoad.FocusMsgId.empty() == false) - { - /* Search exisiting item */ - QTreeWidgetItemIterator itemIterator(ui.threadTreeWidget); - QTreeWidgetItem *item = NULL; - while ((item = *itemIterator) != NULL) - { - itemIterator++; - - if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString() == mThreadLoad.FocusMsgId) - { - ui.threadTreeWidget->setCurrentItem(item); - ui.threadTreeWidget->setFocus(); - break; - } - } - } - - QList::iterator Item; - for (Item = mThreadLoad.ItemToExpand.begin(); Item != mThreadLoad.ItemToExpand.end(); Item++) - { - if ((*Item)->isHidden() == false) - { - (*Item)->setExpanded(true); - } - } - mThreadLoad.ItemToExpand.clear(); - - if (ui.filterLineEdit->text().isEmpty() == false) { - filterItems(ui.filterLineEdit->text()); - } - - insertPost (); - CalculateIconsAndFonts(); - - ui.newthreadButton->setEnabled (IS_GROUP_SUBSCRIBED(subscribeFlags)); - - mThreadLoading = false; - -#ifdef DEBUG_FORUMS - std::cerr << "ForumsV2Dialog::fillThreadFinished done" << std::endl; -#endif -} - -void ForumsV2Dialog::fillThreadProgress(int current, int count) -{ - // show fill progress - if (count) { - ui.progressBar->setValue(current * ui.progressBar->maximum() / count); - } - -} - -void ForumsV2Dialog::insertThreads() -{ -#ifdef DEBUG_FORUMS - /* get the current Forum */ - std::cerr << "ForumsV2Dialog::insertThreads()" << std::endl; -#endif - - subscribeFlags = 0; - - ui.newmessageButton->setEnabled (false); - ui.newthreadButton->setEnabled (false); - - ui.postText->clear(); - ui.threadTitle->clear(); - - if (mCurrForumId.empty()) - { - /* not an actual forum - clear */ - ui.threadTreeWidget->clear(); - /* when no Thread selected - clear */ - ui.forumName->clear(); - /* clear last stored forumID */ - mCurrForumId.erase(); - lastForumID.erase(); - -#ifdef DEBUG_FORUMS - std::cerr << "ForumsV2Dialog::insertThreads() Current Thread Invalid" << std::endl; -#endif - - return; - } - - // Get Current Forum Info... then complete insertForumThreads(). - requestGroupSummary_CurrentForum(mCurrForumId); -} - - -void ForumsV2Dialog::insertForumThreads(const RsGroupMetaData &fi) -{ - subscribeFlags = fi.mSubscribeFlags; - ui.forumName->setText(QString::fromUtf8(fi.mGroupName.c_str())); - - ui.progressBarLayOut->setEnabled(true); - - ui.progLayOutTxt->show(); - ui.progressBar->reset(); - ui.progressBar->show(); - -#ifdef DEBUG_FORUMS - std::cerr << "ForumsV2Dialog::insertThreads() Start filling Forum threads" << std::endl; -#endif - - loadCurrentForumThreads(fi.mGroupId); -} - - - - -void ForumsV2Dialog::FillThreads(QList &ThreadList, bool expandNewMessages, QList &itemToExpand) -{ -#ifdef DEBUG_FORUMS - std::cerr << "ForumsV2Dialog::FillThreads()" << std::endl; -#endif - - int Index = 0; - QTreeWidgetItem *Thread; - QList::iterator NewThread; - - // delete not existing - while (Index < ui.threadTreeWidget->topLevelItemCount ()) { - Thread = ui.threadTreeWidget->topLevelItem (Index); - - // search existing new thread - int Found = -1; - for (NewThread = ThreadList.begin (); NewThread != ThreadList.end (); NewThread++) { - if (Thread->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == (*NewThread)->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { - // found it - Found = Index; - break; - } - } - if (Found >= 0) { - Index++; - } else { - delete (ui.threadTreeWidget->takeTopLevelItem (Index)); - } - } - - // iterate all new threads - for (NewThread = ThreadList.begin (); NewThread != ThreadList.end (); NewThread++) { - // search existing thread - int Found = -1; - int Count = ui.threadTreeWidget->topLevelItemCount (); - for (Index = 0; Index < Count; Index++) { - Thread = ui.threadTreeWidget->topLevelItem (Index); - if (Thread->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == (*NewThread)->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { - // found it - Found = Index; - break; - } - } - - if (Found >= 0) { - // set child data - int i; - for (i = 0; i < COLUMN_THREAD_COUNT; i++) { - Thread->setText (i, (*NewThread)->text (i)); - } - for (i = 0; i < ROLE_THREAD_COUNT; i++) { - Thread->setData (COLUMN_THREAD_DATA, Qt::UserRole + i, (*NewThread)->data (COLUMN_THREAD_DATA, Qt::UserRole + i)); - } - - // fill recursive - FillChildren (Thread, *NewThread, expandNewMessages, itemToExpand); - } else { - // add new thread - ui.threadTreeWidget->addTopLevelItem (*NewThread); - Thread = *NewThread; - *NewThread = NULL; - } - - uint32_t status = Thread->data (COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - if (expandNewMessages && IS_MSG_UNREAD(status)) { - QTreeWidgetItem *pParent = Thread; - while ((pParent = pParent->parent()) != NULL) { - if (std::find(itemToExpand.begin(), itemToExpand.end(), pParent) == itemToExpand.end()) { - itemToExpand.push_back(pParent); - } - } - } - } - -#ifdef DEBUG_FORUMS - std::cerr << "ForumsV2Dialog::FillThreads() done" << std::endl; -#endif -} - -void ForumsV2Dialog::FillChildren(QTreeWidgetItem *Parent, QTreeWidgetItem *NewParent, bool expandNewMessages, QList &itemToExpand) -{ - int Index = 0; - int NewIndex; - int NewCount = NewParent->childCount(); - - QTreeWidgetItem *Child; - QTreeWidgetItem *NewChild; - - // delete not existing - while (Index < Parent->childCount ()) { - Child = Parent->child (Index); - - // search existing new child - int Found = -1; - int Count = NewParent->childCount(); - for (NewIndex = 0; NewIndex < Count; NewIndex++) { - NewChild = NewParent->child (NewIndex); - if (NewChild->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == Child->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { - // found it - Found = Index; - break; - } - } - if (Found >= 0) { - Index++; - } else { - delete (Parent->takeChild (Index)); - } - } - - // iterate all new children - for (NewIndex = 0; NewIndex < NewCount; NewIndex++) { - NewChild = NewParent->child (NewIndex); - - // search existing child - int Found = -1; - int Count = Parent->childCount(); - for (Index = 0; Index < Count; Index++) { - Child = Parent->child (Index); - if (Child->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == NewChild->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { - // found it - Found = Index; - break; - } - } - - if (Found >= 0) { - // set child data - int i; - for (i = 0; i < COLUMN_THREAD_COUNT; i++) { - Child->setText (i, NewChild->text (i)); - } - for (i = 0; i < ROLE_THREAD_COUNT; i++) { - Child->setData (COLUMN_THREAD_DATA, Qt::UserRole + i, NewChild->data (COLUMN_THREAD_DATA, Qt::UserRole + i)); - } - - // fill recursive - FillChildren (Child, NewChild, expandNewMessages, itemToExpand); - } else { - // add new child - Child = NewParent->takeChild(NewIndex); - Parent->addChild (Child); - NewIndex--; - NewCount--; - } - - uint32_t status = Child->data (COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - if (expandNewMessages && IS_MSG_UNREAD(status)) { - QTreeWidgetItem *pParent = Child; - while ((pParent = pParent->parent()) != NULL) { - if (std::find(itemToExpand.begin(), itemToExpand.end(), pParent) == itemToExpand.end()) { - itemToExpand.push_back(pParent); - } - } - } - } -} - -QString ForumsV2Dialog::titleFromInfo(const RsMsgMetaData &meta) -{ - // NOTE - NOTE SURE HOW THIS WILL WORK! - if (meta.mMsgStatus & RS_DISTRIB_MISSING_MSG) { - return QApplication::translate("ForumsV2Dialog", "[ ... Missing Message ... ]"); - } - - return QString::fromUtf8(meta.mMsgName.c_str()); -} - -QString ForumsV2Dialog::messageFromInfo(const RsForumV2Msg &msg) -{ - if (msg.mMeta.mMsgStatus & RS_DISTRIB_MISSING_MSG) { - return QApplication::translate("ForumsV2Dialog", "Placeholder for missing Message"); - } - - return QString::fromUtf8(msg.mMsg.c_str()); -} - -void ForumsV2Dialog::insertPost() -{ - if ((mCurrForumId == "") || (mCurrThreadId == "")) - { - ui.postText->setText(""); - ui.threadTitle->setText(""); - ui.previousButton->setEnabled(false); - ui.nextButton->setEnabled(false); - ui.newmessageButton->setEnabled (false); - return; - } - - QTreeWidgetItem *curr = ui.threadTreeWidget->currentItem(); - if (curr) { - QTreeWidgetItem *Parent = curr->parent (); - int Index = Parent ? Parent->indexOfChild (curr) : ui.threadTreeWidget->indexOfTopLevelItem (curr); - int Count = Parent ? Parent->childCount () : ui.threadTreeWidget->topLevelItemCount (); - ui.previousButton->setEnabled (Index > 0); - ui.nextButton->setEnabled (Index < Count - 1); - } else { - // there is something wrong - ui.previousButton->setEnabled(false); - ui.nextButton->setEnabled(false); - return; - } - - ui.newmessageButton->setEnabled (IS_GROUP_SUBSCRIBED(subscribeFlags) && mCurrThreadId.empty() == false); - - /* blank text, incase we get nothing */ - ui.postText->setText(""); - /* request Post */ - - requestMsgData_InsertPost(mCurrThreadId); - -} - - - -void ForumsV2Dialog::insertPostData(const RsForumV2Msg &msg) -{ - /* As some time has elapsed since request - check that this is still the current msg. - * otherwise, another request will fill the data - */ - - if ((msg.mMeta.mGroupId != mCurrForumId) || (msg.mMeta.mMsgId != mCurrThreadId)) - { - std::cerr << "ForumsV2Dialog::insertPostData() Ignoring Invalid Data...."; - std::cerr << std::endl; - std::cerr << "\t CurrForumId: " << mCurrForumId << " != msg.GroupId: " << msg.mMeta.mGroupId; - std::cerr << std::endl; - std::cerr << "\t or CurrThdId: " << mCurrThreadId << " != msg.MsgId: " << msg.mMeta.mMsgId; - std::cerr << std::endl; - std::cerr << std::endl; - return; - } - - QTreeWidgetItem *curr = ui.threadTreeWidget->currentItem(); - - bool bSetToReadOnActive = Settings->getForumMsgSetToReadOnActivate(); - uint32_t status = curr->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - - QList Row; - Row.append(curr); - if (status & RSGXS_MSG_STATUS_READ) { - if (bSetToReadOnActive && (status & RSGXS_MSG_STATUS_UNREAD_BY_USER)) { - /* set to read */ - setMsgAsReadUnread(Row, true); - } - } else { - /* set to read */ - if (bSetToReadOnActive) { - setMsgAsReadUnread(Row, true); - } else { - /* set to unread by user */ - setMsgAsReadUnread(Row, false); - } - } - - QString extraTxt = RsHtml().formatText(ui.postText->document(), messageFromInfo(msg), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS); - - ui.postText->setHtml(extraTxt); - ui.threadTitle->setText(titleFromInfo(msg.mMeta)); -} - - -void ForumsV2Dialog::previousMessage () -{ - QTreeWidgetItem *Item = ui.threadTreeWidget->currentItem (); - if (Item == NULL) { - return; - } - - QTreeWidgetItem *Parent = Item->parent (); - int Index = Parent ? Parent->indexOfChild (Item) : ui.threadTreeWidget->indexOfTopLevelItem (Item); - if (Index > 0) { - QTreeWidgetItem *Previous = Parent ? Parent->child (Index - 1) : ui.threadTreeWidget->topLevelItem (Index - 1); - if (Previous) { - ui.threadTreeWidget->setCurrentItem (Previous); - } - } -} - -void ForumsV2Dialog::nextMessage () -{ - QTreeWidgetItem *Item = ui.threadTreeWidget->currentItem (); - if (Item == NULL) { - return; - } - - QTreeWidgetItem *Parent = Item->parent (); - int Index = Parent ? Parent->indexOfChild (Item) : ui.threadTreeWidget->indexOfTopLevelItem (Item); - int Count = Parent ? Parent->childCount () : ui.threadTreeWidget->topLevelItemCount (); - if (Index < Count - 1) { - QTreeWidgetItem *Next = Parent ? Parent->child (Index + 1) : ui.threadTreeWidget->topLevelItem (Index + 1); - if (Next) { - ui.threadTreeWidget->setCurrentItem (Next); - } - } -} - -void ForumsV2Dialog::downloadAllFiles() -{ - QStringList urls; - if (RsHtml::findAnchors(ui.postText->toHtml(), urls) == false) { - return; - } - - if (urls.count() == 0) { - return; - } - - RetroShareLink::process(urls, RetroShareLink::TYPE_FILE/*, true*/); -} - -void ForumsV2Dialog::nextUnreadMessage() -{ - QTreeWidgetItem* currentItem = ui.threadTreeWidget->currentItem(); - if( !currentItem ) - { - currentItem = ui.threadTreeWidget->topLevelItem(0); - if( !currentItem ) - return; - } - - do - { - uint32_t status = currentItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - if( IS_MSG_UNREAD(status) ) - { - ui.threadTreeWidget->setCurrentItem(currentItem); - return; - } - } while( (currentItem = ui.threadTreeWidget->itemBelow(currentItem)) != NULL ); -} - -// TODO -#if 0 -void ForumsV2Dialog::removemessage() -{ - //std::cerr << "ForumsV2Dialog::removemessage()" << std::endl; - std::string cid, mid; - if (!getCurrentMsg(cid, mid)) - { - //std::cerr << "ForumsV2Dialog::removemessage()"; - //std::cerr << " No Message selected" << std::endl; - return; - } - - rsMsgs -> MessageDelete(mid); -} -#endif - -/* get selected messages - the messages tree is single selected, but who knows ... */ -int ForumsV2Dialog::getSelectedMsgCount(QList *pRows, QList *pRowsRead, QList *pRowsUnread) -{ - if (pRowsRead) pRowsRead->clear(); - if (pRowsUnread) pRowsUnread->clear(); - - QList selectedItems = ui.threadTreeWidget->selectedItems(); - for(QList::iterator it = selectedItems.begin(); it != selectedItems.end(); it++) { - if (pRows) pRows->append(*it); - if (pRowsRead || pRowsUnread) { - uint32_t status = (*it)->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - if (IS_MSG_UNREAD(status)) { - if (pRowsUnread) pRowsUnread->append(*it); - } else { - if (pRowsRead) pRowsRead->append(*it); - } - } - } - - return selectedItems.size(); -} - -void ForumsV2Dialog::setMsgAsReadUnread(QList &Rows, bool bRead) -{ - QList::iterator Row; - std::list changedItems; - - inMsgAsReadUnread = true; - - for (Row = Rows.begin(); Row != Rows.end(); Row++) { - if ((*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING).toBool()) { - /* Missing message */ - continue; - } - - uint32_t status = (*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - - /* set always as read ... */ - uint32_t statusNew = status | RSGXS_MSG_STATUS_READ; - if (bRead) { - /* ... and as read by user */ - statusNew &= ~RSGXS_MSG_STATUS_UNREAD_BY_USER; - } else { - /* ... and as unread by user */ - statusNew |= RSGXS_MSG_STATUS_UNREAD_BY_USER; - } - if (status != statusNew) { - std::string msgId = (*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString(); - rsForumsV2->setMessageStatus(msgId, statusNew, RSGXS_MSG_STATUS_READ | RSGXS_MSG_STATUS_UNREAD_BY_USER); - - (*Row)->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, statusNew); - - QTreeWidgetItem *parentItem = *Row; - while (parentItem->parent()) { - parentItem = parentItem->parent(); - } - if (std::find(changedItems.begin(), changedItems.end(), parentItem) == changedItems.end()) { - changedItems.push_back(parentItem); - } - } - } - - inMsgAsReadUnread = false; - - if (changedItems.size()) { - for (std::list::iterator it = changedItems.begin(); it != changedItems.end(); it++) { - CalculateIconsAndFonts(*it); - } - updateMessageSummaryList(mCurrForumId); - } -} - -void ForumsV2Dialog::markMsgAsReadUnread (bool bRead, bool bChildren, bool bForum) -{ - if (mCurrForumId.empty() || !IS_GROUP_SUBSCRIBED(subscribeFlags)) { - return; - } - - /* get selected messages */ - QList Rows; - if (bForum) { - int itemCount = ui.threadTreeWidget->topLevelItemCount(); - for (int item = 0; item < itemCount; item++) { - Rows.push_back(ui.threadTreeWidget->topLevelItem(item)); - } - } else { - getSelectedMsgCount (&Rows, NULL, NULL); - } - - if (bChildren) { - /* add children */ - QList AllRows; - - while (Rows.isEmpty() == false) { - QTreeWidgetItem *pRow = Rows.takeFirst(); - - /* add only items with the right state or with not RSGXS_MSG_STATUS_READ */ - uint32_t status = pRow->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - if (IS_MSG_UNREAD(status) == bRead || (status & RSGXS_MSG_STATUS_READ) == 0) { - AllRows.append(pRow); - } - - for (int i = 0; i < pRow->childCount(); i++) { - /* add child to main list and let the main loop do the work */ - Rows.append(pRow->child(i)); - } - } - - if (AllRows.isEmpty()) { - /* nothing to do */ - return; - } - - setMsgAsReadUnread (AllRows, bRead); - - return; - } - - setMsgAsReadUnread (Rows, bRead); -} - -void ForumsV2Dialog::markMsgAsRead() -{ - markMsgAsReadUnread(true, false, false); -} - -void ForumsV2Dialog::markMsgAsReadChildren() -{ - markMsgAsReadUnread(true, true, false); -} - -void ForumsV2Dialog::markMsgAsReadAll() -{ - markMsgAsReadUnread(true, true, true); -} - -void ForumsV2Dialog::markMsgAsUnread() -{ - markMsgAsReadUnread(false, false, false); -} - -void ForumsV2Dialog::markMsgAsUnreadChildren() -{ - markMsgAsReadUnread(false, true, false); -} - -void ForumsV2Dialog::markMsgAsUnreadAll() -{ - markMsgAsReadUnread(false, true, true); -} - -void ForumsV2Dialog::copyForumLink() -{ - if (mCurrForumId.empty()) { - return; - } - -// THIS CODE CALLS getForumInfo() to verify that the Ids are valid. -// As we are switching to Request/Response this is now harder to do... -// So not bothering any more - shouldn't be necessary. -// IF we get errors - fix them, rather than patching here. -#if 0 - ForumInfo fi; - if (rsForumsV2->getForumInfo(mCurrForumId, fi)) { - RetroShareLink link; - if (link.createForum(fi.forumId, "")) { - QList urls; - urls.push_back(link); - RSLinkClipboard::copyLinks(urls); - } - } -#endif - - { - RetroShareLink link; - if (link.createForum(mCurrForumId, "")) - { - QList urls; - urls.push_back(link); - RSLinkClipboard::copyLinks(urls); - } - } -} - - - - -void ForumsV2Dialog::copyMessageLink() -{ - if (mCurrForumId.empty() || mCurrThreadId.empty()) { - return; - } - -// SEE NOTE In fn above. -#if 0 - ForumInfo fi; - if (rsForumsV2->getForumInfo(mCurrForumId, fi)) { - RetroShareLink link; - if (link.createForum(mCurrForumId, mCurrThreadId)) { - QList urls; - urls.push_back(link); - RSLinkClipboard::copyLinks(urls); - } - } -#endif - - { - RetroShareLink link; - if (link.createForum(mCurrForumId, mCurrThreadId)) - { - QList urls; - urls.push_back(link); - RSLinkClipboard::copyLinks(urls); - } - } -} - - -void ForumsV2Dialog::newforum() -{ - ForumV2GroupDialog cf (this); - cf.newGroup(); - - cf.exec (); -} - -void ForumsV2Dialog::createmessage() -{ - if (mCurrForumId.empty () || !IS_GROUP_SUBSCRIBED(subscribeFlags)) { - return; - } - - CreateForumV2Msg *cfm = new CreateForumV2Msg(mCurrForumId, mCurrThreadId); - cfm->show(); - - /* window will destroy itself! */ -} - -void ForumsV2Dialog::createthread() -{ - if (mCurrForumId.empty ()) { - QMessageBox::information(this, tr("RetroShare"), tr("No Forum Selected!")); - return; - } - - CreateForumV2Msg *cfm = new CreateForumV2Msg(mCurrForumId, ""); - cfm->setWindowTitle(tr("Start New Thread")); - cfm->show(); - - /* window will destroy itself! */ -} - -void ForumsV2Dialog::subscribeToForum() -{ - forumSubscribe(true); -} - -void ForumsV2Dialog::unsubscribeToForum() -{ - forumSubscribe(false); -} - -void ForumsV2Dialog::forumSubscribe(bool subscribe) -{ - if (mCurrForumId.empty()) { - return; - } - - uint32_t flags = RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED; - if (!subscribe) - { - flags = 0; - } - - rsForumsV2->setGroupSubscribeFlags(mCurrForumId, flags, RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED); - -} - -void ForumsV2Dialog::showForumDetails() -{ - if (mCurrForumId.empty()) { - return; - } - - ForumV2GroupDialog cf (this); - cf.existingGroup(mCurrForumId, GXS_GROUP_DIALOG_SHOW_MODE); - - cf.exec (); -} - -void ForumsV2Dialog::editForumDetails() -{ - if (mCurrForumId.empty()) { - return; - } - - ForumV2GroupDialog cf (this); - cf.existingGroup(mCurrForumId, GXS_GROUP_DIALOG_EDIT_MODE); - - cf.exec (); -} - -static QString buildReplyHeader(const RsMsgMetaData &meta) -{ - RetroShareLink link; - link.createMessage(meta.mAuthorId, ""); - QString from = link.toHtml(); - - QDateTime qtime; - qtime.setTime_t(meta.mPublishTs); - - QString header = QString("-----%1-----").arg(QApplication::translate("ForumsV2Dialog", "Original Message")); - header += QString("
%1: %2
").arg(QApplication::translate("ForumsV2Dialog", "From"), from); - - header += QString("
%1: %2
").arg(QApplication::translate("ForumsV2Dialog", "Sent"), qtime.toString(Qt::SystemLocaleLongDate)); - header += QString("%1: %2

").arg(QApplication::translate("ForumsV2Dialog", "Subject"), QString::fromUtf8(meta.mMsgName.c_str())); - header += "
"; - - header += QApplication::translate("ForumsV2Dialog", "On %1, %2 wrote:").arg(qtime.toString(Qt::SystemLocaleShortDate), from); - - return header; -} - -void ForumsV2Dialog::replytomessage() -{ - if (mCurrForumId.empty() || mCurrThreadId.empty()) { - QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to a non-existant Message")); - return; - } - - - requestMsgData_ReplyMessage(mCurrThreadId); -} - -void ForumsV2Dialog::replyMessageData(const RsForumV2Msg &msg) -{ - if ((msg.mMeta.mGroupId != mCurrForumId) || (msg.mMeta.mMsgId != mCurrThreadId)) - { - std::cerr << "ForumsV2Dialog::replyMessageData() ERROR Message Ids have changed!"; - std::cerr << std::endl; - return; - } - - // NB: TODO REMOVE rsPeers references. - if (rsPeers->getPeerName(msg.mMeta.mAuthorId) !="") - { - MessageComposer *nMsgDialog = MessageComposer::newMsg(); - nMsgDialog->setTitleText(QString::fromUtf8(msg.mMeta.mMsgName.c_str()), MessageComposer::REPLY); - - nMsgDialog->setQuotedMsg(QString::fromUtf8(msg.mMsg.c_str()), buildReplyHeader(msg.mMeta)); - - nMsgDialog->addRecipient(MessageComposer::TO, msg.mMeta.mAuthorId, false); - nMsgDialog->show(); - nMsgDialog->activateWindow(); - - /* window will destroy itself! */ - } - else - { - QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to an Anonymous Author")); - } -} - -void ForumsV2Dialog::changedViewBox() -{ - if (m_bProcessSettings) { - return; - } - - // save index - Settings->setValueToGroup("ForumsV2Dialog", "viewBox", ui.viewBox->currentIndex()); - - insertThreads(); -} - -void ForumsV2Dialog::filterColumnChanged() -{ - if (m_bProcessSettings) { - return; - } - - int filterColumn = FilterColumnFromComboBox(ui.filterColumnComboBox->currentIndex()); - if (filterColumn == COLUMN_THREAD_CONTENT) { - // need content ... refill - insertThreads(); - } else { - filterItems(ui.filterLineEdit->text()); - } - - // save index - Settings->setValueToGroup("ForumsV2Dialog", "filterColumn", filterColumn); -} - -void ForumsV2Dialog::filterItems(const QString& text) -{ - int filterColumn = FilterColumnFromComboBox(ui.filterColumnComboBox->currentIndex()); - - int nCount = ui.threadTreeWidget->topLevelItemCount (); - for (int nIndex = 0; nIndex < nCount; nIndex++) { - filterItem(ui.threadTreeWidget->topLevelItem(nIndex), text, filterColumn); - } -} - -void ForumsV2Dialog::shareKey() -{ - ShareKey shareUi(this, 0, mCurrForumId, FORUM_KEY_SHARE); - shareUi.exec(); -} - -bool ForumsV2Dialog::filterItem(QTreeWidgetItem *pItem, const QString &text, int filterColumn) -{ - bool bVisible = true; - - if (text.isEmpty() == false) { - if (pItem->text(filterColumn).contains(text, Qt::CaseInsensitive) == false) { - bVisible = false; - } - } - - int nVisibleChildCount = 0; - int nCount = pItem->childCount(); - for (int nIndex = 0; nIndex < nCount; nIndex++) { - if (filterItem(pItem->child(nIndex), text, filterColumn)) { - nVisibleChildCount++; - } - } - - if (bVisible || nVisibleChildCount) { - pItem->setHidden(false); - } else { - pItem->setHidden(true); - } - - return (bVisible || nVisibleChildCount); -} - -void ForumsV2Dialog::updateMessageSummaryList(std::string forumId) -{ - QTreeWidgetItem *items[2] = { yourForums, subscribedForums }; - - for (int item = 0; item < 2; item++) { - int child; - int childCount = items[item]->childCount(); - for (child = 0; child < childCount; child++) { - QTreeWidgetItem *childItem = items[item]->child(child); - std::string childId = ui.forumTreeWidget->itemId(childItem).toStdString(); - if (childId.empty()) { - continue; - } - - if (forumId.empty() || childId == forumId) { - /* calculate unread messages */ - unsigned int newMessageCount = 0; - unsigned int unreadMessageCount = 0; - //rsForumsV2->getMessageCount(childId, newMessageCount, unreadMessageCount); - std::cerr << "IMPLEMENT rsForumsV2->getMessageCount()"; - std::cerr << std::endl; - - ui.forumTreeWidget->setUnreadCount(childItem, unreadMessageCount); - - if (forumId.empty() == false) { - /* Calculate only this forum */ - break; - } - } - } - } -} - -bool ForumsV2Dialog::navigate(const std::string& forumId, const std::string& msgId) -{ - if (forumId.empty()) { - return false; - } - - if (ui.forumTreeWidget->activateId(QString::fromStdString(forumId), msgId.empty()) == NULL) { - return false; - } - - /* Threads are filled in changedForum */ - if (mCurrForumId != forumId) { - return false; - } - - if (msgId.empty()) { - return true; - } - - if (mThreadLoading) { - mThreadLoad.FocusMsgId = msgId; - return true; - } - - /* Search exisiting item */ - QTreeWidgetItemIterator itemIterator(ui.threadTreeWidget); - QTreeWidgetItem *item = NULL; - while ((item = *itemIterator) != NULL) { - itemIterator++; - - if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString() == msgId) { - ui.threadTreeWidget->setCurrentItem(item); - ui.threadTreeWidget->setFocus(); - return true; - } - } - - return false; -} - -void ForumsV2Dialog::generateMassData() -{ -#ifdef DEBUG_FORUMS - if (mCurrForumId.empty ()) { - return; - } - - if (QMessageBox::question(this, "Generate mass data", "Do you really want to generate mass data ?", QMessageBox::Yes|QMessageBox::No, QMessageBox::No) == QMessageBox::No) { - return; - } - - for (int thread = 1; thread < 1000; thread++) { - ForumMsgInfo threadInfo; - threadInfo.forumId = mCurrForumId; - threadInfo.title = QString("Test %1").arg(thread, 3, 10, QChar('0')).toStdWString(); - threadInfo.msg = QString("That is only a test").toStdWString(); - - if (rsForumsV2->ForumMessageSend(threadInfo) == false) { - return; - } - - for (int msg = 1; msg < 3; msg++) { - ForumMsgInfo msgInfo; - msgInfo.forumId = mCurrForumId; - msgInfo.threadId = threadInfo.msgId; - msgInfo.parentId = threadInfo.msgId; - msgInfo.title = threadInfo.title; - msgInfo.msg = threadInfo.msg; - - if (rsForumsV2->ForumMessageSend(msgInfo) == false) { - return; - } - } - } -#endif -} - - - -/*********************** **** **** **** ***********************/ -/** Request / Response of Data ********************************/ -/*********************** **** **** **** ***********************/ - -#define FORUMSV2DIALOG_LISTING 1 -#define FORUMSV2DIALOG_CURRENTFORUM 2 -#define FORUMSV2DIALOG_INSERTTHREADS 3 -#define FORUMSV2DIALOG_INSERTCHILD 4 -#define FORUMV2DIALOG_INSERT_POST 5 -#define FORUMV2DIALOG_REPLY_MESSAGE 6 - - -void ForumsV2Dialog::insertForums() -{ - requestGroupSummary(); -} - -void ForumsV2Dialog::requestGroupSummary() -{ - std::cerr << "ForumsV2Dialog::requestGroupSummary()"; - std::cerr << std::endl; - - std::list ids; - RsTokReqOptions opts; - uint32_t token; - mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, ids, FORUMSV2DIALOG_LISTING); -} - -void ForumsV2Dialog::loadGroupSummary(const uint32_t &token) -{ - std::cerr << "ForumsV2Dialog::loadGroupSummary()"; - std::cerr << std::endl; - - std::list groupInfo; - rsForumsV2->getGroupSummary(token, groupInfo); - - if (groupInfo.size() > 0) - { - insertForumsData(groupInfo); - } - else - { - std::cerr << "ForumsV2Dialog::loadGroupSummary() ERROR No Groups..."; - std::cerr << std::endl; - } -} - -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ - - - -void ForumsV2Dialog::requestGroupSummary_CurrentForum(const std::string &forumId) -{ - RsTokReqOptions opts; - - std::list grpIds; - grpIds.push_back(forumId); - - std::cerr << "ForumsV2Dialog::requestGroupSummary_CurrentForum(" << forumId << ")"; - std::cerr << std::endl; - - uint32_t token; - mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, FORUMSV2DIALOG_CURRENTFORUM); -} - -void ForumsV2Dialog::loadGroupSummary_CurrentForum(const uint32_t &token) -{ - std::cerr << "ForumsV2Dialog::loadGroupSummary_CurrentForum()"; - std::cerr << std::endl; - - std::list groupInfo; - rsForumsV2->getGroupSummary(token, groupInfo); - - if (groupInfo.size() == 1) - { - RsGroupMetaData fi = groupInfo.front(); - insertForumThreads(fi); - } - else - { - std::cerr << "ForumsV2Dialog::loadGroupSummary_CurrentForum() ERROR Invalid Number of Groups..."; - std::cerr << std::endl; - } -} - -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ - - - -void ForumsV2Dialog::loadCurrentForumThreads(const std::string &forumId) -{ - - std::cerr << "ForumsV2Dialog::loadCurrentForumThreads(" << forumId << ")"; - std::cerr << std::endl; - - /* if already active -> kill current loading */ - if (mThreadLoading) - { - /* Cleanup */ - std::cerr << "ForumsV2Dialog::loadCurrentForumThreads() Cleanup old Threads"; - std::cerr << std::endl; - - /* Wipe Widget Tree */ - mThreadLoad.Items.clear(); - - /* Stop all active requests */ - std::map::iterator it; - for(it = mThreadLoad.MsgTokens.begin(); it != mThreadLoad.MsgTokens.end(); it++) - { - std::cerr << "ForumsV2Dialog::loadCurrentForumThreads() Canceling Request: " << it->first; - std::cerr << std::endl; - - mForumQueue->cancelRequest(it->first); - } - - mThreadLoad.MsgTokens.clear(); - mThreadLoad.ItemToExpand.clear(); - } - - /* initiate loading */ - std::cerr << "ForumsV2Dialog::loadCurrentForumThreads() Initiating Loading"; - std::cerr << std::endl; - - mThreadLoading = true; - - mThreadLoad.ForumId = mCurrForumId; - mThreadLoad.FilterColumn = FilterColumnFromComboBox(ui.filterColumnComboBox->currentIndex()); - mThreadLoad.ViewType = ui.viewBox->currentIndex(); - mThreadLoad.FillComplete = false; - - if (lastViewType != mThreadLoad.ViewType || lastForumID != mCurrForumId) { - mThreadLoad.FillComplete = true; - } - - mThreadLoad.FlatView = false; - mThreadLoad.UseChildTS = false; - mThreadLoad.ExpandNewMessages = Settings->getExpandNewMessages(); - mThreadLoad.SubscribeFlags = subscribeFlags; - - if (mThreadLoad.ViewType == VIEW_FLAT) { - ui.threadTreeWidget->setRootIsDecorated(false); - } else { - ui.threadTreeWidget->setRootIsDecorated(true); - } - - switch(mThreadLoad.ViewType) - { - case VIEW_LAST_POST: - mThreadLoad.UseChildTS = true; - break; - case VIEW_FLAT: - mThreadLoad.FlatView = true; - break; - case VIEW_THREADED: - break; - } - - requestGroupThreadData_InsertThreads(forumId); -} - - - -void ForumsV2Dialog::requestGroupThreadData_InsertThreads(const std::string &forumId) -{ - RsTokReqOptions opts; - - opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; - - std::list grpIds; - grpIds.push_back(forumId); - - std::cerr << "ForumsV2Dialog::requestGroupThreadData_InsertThreads(" << forumId << ")"; - std::cerr << std::endl; - - uint32_t token; - mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, FORUMSV2DIALOG_INSERTTHREADS); -} - - -void ForumsV2Dialog::loadGroupThreadData_InsertThreads(const uint32_t &token) -{ - std::cerr << "ForumsV2Dialog::loadGroupThreadData_InsertThreads()"; - std::cerr << std::endl; - - bool moreData = true; - bool someData = false; - while(moreData) - { - RsForumV2Msg msg; - if (rsForumsV2->getMsgData(token, msg)) - { - std::cerr << "ForumsV2Dialog::loadGroupThreadData_InsertThreads() MsgId: " << msg.mMeta.mMsgId; - std::cerr << std::endl; - - loadForumBaseThread(msg); - someData = true; - } - else - { - moreData = false; - } - } - - /* completed with no data */ - if (!someData) - { - fillThreadFinished(); - } -} - -bool ForumsV2Dialog::convertMsgToThreadWidget(const RsForumV2Msg &msgInfo, std::string authorName, - bool useChildTS, uint32_t filterColumn, QTreeWidgetItem *item) -{ - QString text; - - { - QDateTime qtime; - if (useChildTS) - qtime.setTime_t(msgInfo.mMeta.mChildTs); - else - qtime.setTime_t(msgInfo.mMeta.mPublishTs); - - text = qtime.toString("yyyy-MM-dd hh:mm:ss"); - if (useChildTS) - { - QDateTime qtime2; - qtime2.setTime_t(msgInfo.mMeta.mPublishTs); - QString timestamp2 = qtime2.toString("yyyy-MM-dd hh:mm:ss"); - text += " / "; - text += timestamp2; - } - item->setText(COLUMN_THREAD_DATE, text); - } - - item->setText(COLUMN_THREAD_TITLE, ForumsV2Dialog::titleFromInfo(msgInfo.mMeta)); - - text = QString::fromUtf8(authorName.c_str()); - - if (text.isEmpty()) - { - item->setText(COLUMN_THREAD_AUTHOR, tr("Anonymous")); - } - else - { - item->setText(COLUMN_THREAD_AUTHOR, text); - } - - if (msgInfo.mMeta.mMsgFlags & RS_DISTRIB_AUTHEN_REQ) - { - item->setText(COLUMN_THREAD_SIGNED, tr("signed")); - item->setIcon(COLUMN_THREAD_SIGNED, QIcon(":/images/mail-signed.png")); - } - else - { - item->setText(COLUMN_THREAD_SIGNED, tr("none")); - item->setIcon(COLUMN_THREAD_SIGNED, QIcon(":/images/mail-signature-unknown.png")); - } - - if (filterColumn == COLUMN_THREAD_CONTENT) { - // need content for filter - QTextDocument doc; - doc.setHtml(QString::fromUtf8(msgInfo.mMsg.c_str())); - item->setText(COLUMN_THREAD_CONTENT, doc.toPlainText().replace(QString("\n"), QString(" "))); - } - - item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID, QString::fromStdString(msgInfo.mMeta.mMsgId)); - -#if 0 - if (IS_GROUP_SUBSCRIBED(subscribeFlags) && !(msginfo.mMsgFlags & RS_DISTRIB_MISSING_MSG)) { - rsForumsV2->getMessageStatus(msginfo.forumId, msginfo.msgId, status); - } else { - // show message as read - status = RSGXS_MSG_STATUS_READ; - } -#endif - item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, msgInfo.mMeta.mMsgStatus); - - item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING, (msgInfo.mMeta.mMsgFlags & RS_DISTRIB_MISSING_MSG) ? true : false); - - return true; -} - - -void ForumsV2Dialog::loadForumBaseThread(const RsForumV2Msg &msg) -{ - std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); - - QTreeWidgetItem *item = new QTreeWidgetItem(); // no Parent. - - convertMsgToThreadWidget(msg, authorName, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, item); - - /* request Children Data */ - uint32_t token; - requestChildData_InsertThreads(token, msg.mMeta.mMsgId); - - /* store pair of (token, item) */ - mThreadLoad.MsgTokens[token] = item; - - /* add item to final tree */ - mThreadLoad.Items.append(item); -} - - - -/*********************** **** **** **** ***********************/ - -void ForumsV2Dialog::requestChildData_InsertThreads(uint32_t &token, const std::string &parentId) -{ - RsTokReqOptions opts; - - opts.mOptions = RS_TOKREQOPT_MSG_PARENT | RS_TOKREQOPT_MSG_LATEST; - - std::list msgIds; - msgIds.push_back(parentId); - - std::cerr << "ForumsV2Dialog::requestChildData_InsertThreads(" << parentId << ")"; - std::cerr << std::endl; - - //mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMSV2DIALOG_INSERTCHILD); -} - - -void ForumsV2Dialog::loadChildData_InsertThreads(const uint32_t &token) -{ - std::cerr << "ForumsV2Dialog::loadChildData_InsertThreads()"; - std::cerr << std::endl; - - /* find the matching *item */ - std::map::iterator it; - it = mThreadLoad.MsgTokens.find(token); - if (it == mThreadLoad.MsgTokens.end()) - { - std::cerr << "ForumsV2Dialog::loadGroupThreadData_InsertThreads() ERROR Missing Token->Parent in Map"; - std::cerr << std::endl; - /* finished with this one */ - return; - } - - QTreeWidgetItem *parent = it->second; - // cleanup map. - mThreadLoad.MsgTokens.erase(it); - - std::cerr << "ForumsV2Dialog::loadGroupThreadData_InsertThreads()"; - std::cerr << std::endl; - - bool moreData = true; - while(moreData) - { - RsForumV2Msg msg; - if (rsForumsV2->getMsgData(token, msg)) - { - std::cerr << "ForumsV2Dialog::loadGroupThreadData_InsertThreads() MsgId: " << msg.mMeta.mMsgId; - std::cerr << std::endl; - - loadForumChildMsg(msg, parent); - } - else - { - moreData = false; - } - } - - - /* check for completion */ - if (mThreadLoad.MsgTokens.size() == 0) - { - /* finished */ - /* push data into GUI */ - fillThreadFinished(); - } -} - -void ForumsV2Dialog::loadForumChildMsg(const RsForumV2Msg &msg, QTreeWidgetItem *parent) -{ - std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); - - QTreeWidgetItem *child = NULL; - - if (mThreadLoad.FlatView) - { - child = new QTreeWidgetItem(); // no Parent. - } - else - { - child = new QTreeWidgetItem(parent); - } - - - convertMsgToThreadWidget(msg, authorName, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, child); - - /* request Children Data */ - uint32_t token; - requestChildData_InsertThreads(token, msg.mMeta.mMsgId); - - /* store pair of (token, item) */ - mThreadLoad.MsgTokens[token] = child; - - // Leave this here... BUT IT WILL NEED TO BE FIXED. - if (mThreadLoad.FillComplete && mThreadLoad.ExpandNewMessages && IS_MSG_UNREAD(msg.mMeta.mMsgStatus)) - { - QTreeWidgetItem *pParent = child; - while ((pParent = pParent->parent()) != NULL) - { - if (std::find(mThreadLoad.ItemToExpand.begin(), mThreadLoad.ItemToExpand.end(), pParent) == mThreadLoad.ItemToExpand.end()) - { - mThreadLoad.ItemToExpand.push_back(pParent); - } - } - } - - if (mThreadLoad.FlatView) - { - /* add item to final tree */ - mThreadLoad.Items.append(child); - } -} - - - -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ - -void ForumsV2Dialog::requestMsgData_InsertPost(const std::string &msgId) -{ - RsTokReqOptions opts; - - std::list msgIds; - msgIds.push_back(msgId); - - std::cerr << "ForumsV2Dialog::requestMsgData_InsertPost(" << msgId << ")"; - std::cerr << std::endl; - - - uint32_t token; - //mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_INSERT_POST); -} - - -void ForumsV2Dialog::loadMsgData_InsertPost(const uint32_t &token) -{ - std::cerr << "ForumsV2Dialog::loadMsgData_InsertPost()"; - std::cerr << std::endl; - - RsForumV2Msg msg; - if (rsForumsV2->getMsgData(token, msg)) - { - insertPostData(msg); - } - else - { - std::cerr << "ForumsV2Dialog::loadMsgData_InsertPost() ERROR Missing Message Data..."; - std::cerr << std::endl; - } -} - - -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ - -void ForumsV2Dialog::requestMsgData_ReplyMessage(const std::string &msgId) -{ - RsTokReqOptions opts; - - std::list msgIds; - msgIds.push_back(msgId); - - std::cerr << "ForumsV2Dialog::requestMsgData_ReplyMessage(" << msgId << ")"; - std::cerr << std::endl; - - uint32_t token; - mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_REPLY_MESSAGE); -} - - -void ForumsV2Dialog::loadMsgData_ReplyMessage(const uint32_t &token) -{ - std::cerr << "ForumsV2Dialog::loadMsgData_ReplyMessage()"; - std::cerr << std::endl; - - RsForumV2Msg msg; - if (rsForumsV2->getMsgData(token, msg)) - { - replyMessageData(msg); - } - else - { - std::cerr << "ForumsV2Dialog::loadMsgData_ReplyMessage() ERROR Missing Message Data..."; - std::cerr << std::endl; - } -} - - -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ - - - -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ - -void ForumsV2Dialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) -{ - std::cerr << "ForumsV2Dialog::loadRequest() UserType: " << req.mUserType; - std::cerr << std::endl; - - if (queue == mForumQueue) - { - /* now switch on req */ - switch(req.mUserType) - { - case FORUMSV2DIALOG_LISTING: - loadGroupSummary(req.mToken); - break; - - case FORUMSV2DIALOG_CURRENTFORUM: - loadGroupSummary_CurrentForum(req.mToken); - break; - - case FORUMSV2DIALOG_INSERTTHREADS: - loadGroupThreadData_InsertThreads(req.mToken); - break; - - case FORUMSV2DIALOG_INSERTCHILD: - loadChildData_InsertThreads(req.mToken); - break; - - case FORUMV2DIALOG_INSERT_POST: - loadMsgData_InsertPost(req.mToken); - break; - - case FORUMV2DIALOG_REPLY_MESSAGE: - loadMsgData_ReplyMessage(req.mToken); - break; - - default: - std::cerr << "ForumsV2Dialog::loadRequest() ERROR: INVALID TYPE"; - std::cerr << std::endl; - break; - } - } -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/retroshare-gui/src/gui/ForumsV2Dialog.h b/retroshare-gui/src/gui/ForumsV2Dialog.h deleted file mode 100644 index 39c831d57..000000000 --- a/retroshare-gui/src/gui/ForumsV2Dialog.h +++ /dev/null @@ -1,271 +0,0 @@ -/**************************************************************** - * RetroShare is distributed under the following license: - * - * Copyright (C) 2008 Robert Fernie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - ****************************************************************/ - -#ifndef _FORUMSV2DIALOG_H -#define _FORUMSV2DIALOG_H - -#include - -#include "mainpage.h" -#include "RsAutoUpdatePage.h" -#include "ui_ForumsV2Dialog.h" - -#include - -#include "util/TokenQueue.h" - -#include - -class ForumInfo; - - -/* These are all the parameters that are required for thread loading. - * They are kept static for the load duration. - */ - -class ForumsV2ThreadLoadParameters -{ - public: - - std::string ForumId; - std::string FocusMsgId; - - uint32_t SubscribeFlags; - int ViewType; - uint32_t FilterColumn; - - std::map MsgTokens; - QList Items; - QList ItemToExpand; - - bool FillComplete; - bool FlatView; - bool UseChildTS; - bool ExpandNewMessages; -}; - - - - - - -class ForumsV2Dialog : public RsAutoUpdatePage, public TokenResponse -{ - Q_OBJECT - -public: - ForumsV2Dialog(QWidget *parent = 0); - ~ForumsV2Dialog(); - - bool navigate(const std::string& forumId, const std::string& msgId); - - /* overloaded from RsAuthUpdatePage */ - virtual void updateDisplay(); - - // Callback for all Loads. -virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); - -protected: - bool eventFilter(QObject *obj, QEvent *ev); - -private slots: - /** Create the context popup menu and it's submenus */ - void forumListCustomPopupMenu( QPoint point ); - void threadListCustomPopupMenu( QPoint point ); - void restoreForumKeys(); - void newforum(); - - void changedForum(const QString &id); - void changedThread(); - void clickedThread (QTreeWidgetItem *item, int column); - - void replytomessage(); - void replyMessageData(const RsForumV2Msg &msg); - - //void print(); - //void printpreview(); - - //void removemessage(); - void markMsgAsRead(); - void markMsgAsReadChildren(); - void markMsgAsReadAll(); - void markMsgAsUnread(); - void markMsgAsUnreadAll(); - void markMsgAsUnreadChildren(); - void copyForumLink(); - void copyMessageLink(); - - /* handle splitter */ - void togglethreadview(); - - void createthread(); - void createmessage(); - - void subscribeToForum(); - void unsubscribeToForum(); - - void showForumDetails(); - void editForumDetails(); - - void previousMessage (); - void nextMessage (); - void nextUnreadMessage(); - void downloadAllFiles(); - - void changedViewBox(); - - void filterColumnChanged(); - //void filterRegExpChanged(); - ///void clearFilter(); - - void generateMassData(); - - void fillThreadFinished(); - void fillThreadProgress(int current, int count); - - void shareKey(); - -private: - void insertForums(); - void insertThreads(); - void insertPost(); - void insertPostData(const RsForumV2Msg &msg); // Second Half. - - // Utility Fns. - QString titleFromInfo(const RsMsgMetaData &meta); - QString messageFromInfo(const RsForumV2Msg &msg); - - void forumMsgReadStatusChanged(const QString &forumId, const QString &msgId, int status); - - void updateMessageSummaryList(std::string forumId); - //void forumInfoToGroupItemInfo(const ForumInfo &forumInfo, GroupItemInfo &groupItemInfo); - void forumInfoToGroupItemInfo(const RsGroupMetaData &forumInfo, GroupItemInfo &groupItemInfo); - - void forumSubscribe(bool subscribe); - void FillThreads(QList &ThreadList, bool bExpandNewMessages, QList &itemToExpand); - void FillChildren(QTreeWidgetItem *Parent, QTreeWidgetItem *NewParent, bool bExpandNewMessages, QList &itemToExpand); - - int getSelectedMsgCount(QList *pRows, QList *pRowsRead, QList *pRowsUnread); - void setMsgAsReadUnread(QList &Rows, bool bRead); - void markMsgAsReadUnread(bool bRead, bool bChildren, bool bForum); - void CalculateIconsAndFonts(QTreeWidgetItem *pItem = NULL); - void CalculateIconsAndFonts(QTreeWidgetItem *pItem, bool &bHasReadChilddren, bool &bHasUnreadChilddren); - - void processSettings(bool bLoad); - void togglethreadview_internal(); - - void filterItems(const QString& text); - bool filterItem(QTreeWidgetItem *pItem, const QString &text, int filterColumn); - - // New Request/Response Loading Functions. - void insertForumsData(const std::list &forumList); - void insertForumThreads(const RsGroupMetaData &fi); - - void requestGroupSummary(); - void loadGroupSummary(const uint32_t &token); - - void requestGroupSummary_CurrentForum(const std::string &forumId); - void loadGroupSummary_CurrentForum(const uint32_t &token); - - void loadCurrentForumThreads(const std::string &forumId); - void requestGroupThreadData_InsertThreads(const std::string &forumId); - void loadGroupThreadData_InsertThreads(const uint32_t &token); - void loadForumBaseThread(const RsForumV2Msg &msg); - - void requestChildData_InsertThreads(uint32_t &token, const std::string &parentId); - void loadChildData_InsertThreads(const uint32_t &token); - void loadForumChildMsg(const RsForumV2Msg &msg, QTreeWidgetItem *parent); - - void requestMsgData_InsertPost(const std::string &msgId); - void loadMsgData_InsertPost(const uint32_t &token); - void requestMsgData_ReplyMessage(const std::string &msgId); - void loadMsgData_ReplyMessage(const uint32_t &token); - - bool convertMsgToThreadWidget(const RsForumV2Msg &msgInfo, std::string authorName, - bool useChildTS, uint32_t filterColumn, QTreeWidgetItem *item); - - TokenQueue *mForumQueue; - - - bool m_bProcessSettings; - - QTreeWidgetItem *yourForums; - QTreeWidgetItem *subscribedForums; - QTreeWidgetItem *popularForums; - QTreeWidgetItem *otherForums; - - std::string mCurrForumId; - std::string mCurrThreadId; - int subscribeFlags; - - QFont m_ForumNameFont; - int lastViewType; - std::string lastForumID; - - bool inMsgAsReadUnread; - //ForumsV2FillThread *fillThread; - - // New Datatypes to replace the FillThread. - bool mThreadLoading; - ForumsV2ThreadLoadParameters mThreadLoad; - - - /** Qt Designer generated object */ - Ui::ForumsV2Dialog ui; -}; - -#if 0 -class ForumsV2FillThread : public QThread -{ - Q_OBJECT - -public: - ForumsV2FillThread(ForumsV2Dialog *parent); - ~ForumsV2FillThread(); - - void run(); - void stop(); - bool wasStopped() { return stopped; } - -signals: - void progress(int current, int count); - -public: - std::string forumId; - int filterColumn; - int subscribeFlags; - bool fillComplete; - int viewType; - bool expandNewMessages; - std::string focusMsgId; - - QList Items; - QList ItemToExpand; - -private: - volatile bool stopped; -}; - -#endif - - -#endif - diff --git a/retroshare-gui/src/gui/ForumsV2Dialog.ui b/retroshare-gui/src/gui/ForumsV2Dialog.ui deleted file mode 100644 index 988837ac8..000000000 --- a/retroshare-gui/src/gui/ForumsV2Dialog.ui +++ /dev/null @@ -1,1251 +0,0 @@ - - - ForumsV2Dialog - - - - 0 - 0 - 732 - 420 - - - - - 0 - 2 - - - - - 60 - 0 - - - - - - - - - 0 - 0 - 0 - - - - - - - 208 - 208 - 208 - - - - - - - 255 - 255 - 255 - - - - - - - 247 - 247 - 247 - - - - - - - 104 - 104 - 104 - - - - - - - 139 - 139 - 139 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 240 - 240 - 240 - - - - - - - 0 - 0 - 0 - - - - - - - 0 - 0 - 128 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 255 - - - - - - - 255 - 0 - 255 - - - - - - - 231 - 231 - 231 - - - - - - - - - 0 - 0 - 0 - - - - - - - 208 - 208 - 208 - - - - - - - 255 - 255 - 255 - - - - - - - 247 - 247 - 247 - - - - - - - 104 - 104 - 104 - - - - - - - 139 - 139 - 139 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 240 - 240 - 240 - - - - - - - 0 - 0 - 0 - - - - - - - 192 - 192 - 192 - - - - - - - 0 - 0 - 0 - - - - - - - 0 - 0 - 255 - - - - - - - 255 - 0 - 255 - - - - - - - 231 - 231 - 231 - - - - - - - - - 104 - 104 - 104 - - - - - - - 208 - 208 - 208 - - - - - - - 255 - 255 - 255 - - - - - - - 247 - 247 - 247 - - - - - - - 104 - 104 - 104 - - - - - - - 139 - 139 - 139 - - - - - - - 104 - 104 - 104 - - - - - - - 255 - 255 - 255 - - - - - - - 104 - 104 - 104 - - - - - - - 240 - 240 - 240 - - - - - - - 240 - 240 - 240 - - - - - - - 0 - 0 - 0 - - - - - - - 0 - 0 - 128 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 255 - - - - - - - 255 - 0 - 255 - - - - - - - 231 - 231 - 231 - - - - - - - - - Arial - 8 - 50 - false - false - false - false - - - - Qt::DefaultContextMenu - - - - 9 - - - 9 - - - - - Qt::Horizontal - - - - - 300 - 300 - - - - QFrame#frame{border: none;} - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - - - QFrame#chheaderframe{ -background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #FEFEFE, stop:1 #E8E8E8); - -border: 1px solid #CCCCCC;} - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 2 - - - - - 0 - - - - - - 24 - 24 - - - - - - - :/images/konversation.png - - - true - - - - - - - - Arial - 10 - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Arial'; font-weight:600;">Forums</span></p></body></html> - - - - - - - - - Qt::Horizontal - - - - 123 - 13 - - - - - - - - Qt::NoFocus - - - Display - - - QPushButton::menu-indicator { - subcontrol-origin: padding; - subcontrol-position: bottom right; - } - - QPushButton::menu-indicator:pressed, QPushButton::menu-indicator:open { - position: relative; - top: 2px; left: 2px; /* shift the arrow by 2 px */ - } - - QPushButton:hover { - border: 1px solid #CCCCCC; - } - - - - :/images/looknfeel.png:/images/looknfeel.png - - - true - - - - - - - Qt::NoFocus - - - Create Forum - - - - :/images/new_forum16.png:/images/new_forum16.png - - - true - - - - - - - - - - - 0 - 0 - - - - - 9 - - - - - -1 - -1 - - - - - - - - - Qt::Vertical - - - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - - 10 - 75 - true - - - - Forum: - - - - - - - - 2 - 0 - - - - - 0 - 0 - - - - - 16777215 - 1677215 - - - - -border: 2px solid #CCCCCC; -border-radius:6px; -background: white; - - - - - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse - - - - - - - - Last Post - - - - - Threaded View - - - - - Flat View - - - - - - - - - - - 9 - - - - Qt::CustomContextMenu - - - true - - - true - - - - Title - - - - - - - - - :/images/message-state-header.png:/images/message-state-header.png - - - - - Date - - - - - Author - - - - - Signed - - - - - - - - - - - 0 - 0 - - - - - 10 - 75 - true - - - - Thread: - - - - - - - QLabel#threadTitle{ -border: 2px solid #CCCCCC; -border-radius: 6px; -background: white;} - - - true - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse - - - - - - - false - - - - 0 - 0 - - - - - 24 - 24 - - - - - 24 - 24 - - - - Qt::NoFocus - - - Previous Thread - - - - - - - :/images/back.png:/images/back.png - - - - - - - false - - - - 0 - 0 - - - - - 24 - 24 - - - - - 24 - 24 - - - - Qt::NoFocus - - - Next Thread - - - - - - - :/images/forward.png:/images/forward.png - - - - - - - - 24 - 24 - - - - Qt::NoFocus - - - - - - - :/images/edit_remove24.png:/images/edit_remove24.png - - - true - - - true - - - - - - - - 24 - 24 - - - - Qt::NoFocus - - - Download all files - - - - :/images/down.png:/images/down.png - - - - - - - - 0 - 0 - - - - Next unread - - - - - - - - - - 0 - 32 - - - - QFrame#frame_2{ -background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #FEFEFE, stop:1 #E8E8E8); - -border: 1px solid #CCCCCC;} - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 2 - - - - - 2 - - - - - - - - :/images/find-16.png - - - - - - - Search forums - - - - - - - - - - 0 - 0 - - - - - MS Shell Dlg 2 - - - - 1 - - - - Date - - - - - Title - - - - - Author - - - - - Content - - - - - - - - - 24 - 24 - - - - Qt::NoFocus - - - Reply Message - - - - :/images/mail_reply.png:/images/mail_reply.png - - - true - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 40 - 20 - - - - - - - - - 24 - 24 - - - - Qt::NoFocus - - - Start new Thread for Selected Forum - - - - :/images/mail_new.png:/images/mail_new.png - - - true - - - - - - - - - - - - - 10 - 75 - true - - - - Loading - - - - - - - - 16777215 - 25 - - - - 1000 - - - 0 - - - - - - - - - - - 0 - 10 - - - - - 9 - - - - - - - - - - Print - - - - - PrintPreview - - - - - - GroupTreeWidget - QWidget -
gui/common/GroupTreeWidget.h
- 1 -
- - LineEditClear - QLineEdit -
gui/common/LineEditClear.h
-
- - LinkTextBrowser - QTextBrowser -
gui/common/LinkTextBrowser.h
-
-
- - - - -
diff --git a/retroshare-gui/src/gui/GxsForumsDialog.cpp b/retroshare-gui/src/gui/GxsForumsDialog.cpp index a0abfb71b..19d1aff46 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/GxsForumsDialog.cpp @@ -27,9 +27,7 @@ #include #include "GxsForumsDialog.h" - #include "gxs/GxsForumGroupDialog.h" - #include "gxsforums/CreateGxsForumMsg.h" #include "msgs/MessageComposer.h" @@ -37,10 +35,12 @@ #include "common/Emoticons.h" #include "common/RSItemDelegate.h" #include "common/PopularityDefs.h" +#include "common/RSTreeWidgetItem.h" #include "RetroShareLink.h" #include "channels/ShareKey.h" #include "notifyqt.h" #include "util/HandleRichText.h" +//#AFTER MERGE #include "util/DateTime.h" #include #include @@ -93,43 +93,10 @@ // no need to copy, don't count in ROLE_THREAD_COUNT #define ROLE_THREAD_READCHILDREN Qt::UserRole + 3 #define ROLE_THREAD_UNREADCHILDREN Qt::UserRole + 4 +#define ROLE_THREAD_SORT Qt::UserRole + 5 #define ROLE_THREAD_COUNT 3 - -static int FilterColumnFromComboBox(int nIndex) -{ - switch (nIndex) { - case 0: - return COLUMN_THREAD_DATE; - case 1: - return COLUMN_THREAD_TITLE; - case 2: - return COLUMN_THREAD_AUTHOR; - case 3: - return COLUMN_THREAD_CONTENT; - } - - return COLUMN_THREAD_TITLE; -} - -static int FilterColumnToComboBox(int nIndex) -{ - switch (nIndex) { - case COLUMN_THREAD_DATE: - return 0; - case COLUMN_THREAD_TITLE: - return 1; - case COLUMN_THREAD_AUTHOR: - return 2; - case COLUMN_THREAD_CONTENT: - return 3; - } - - return FilterColumnToComboBox(COLUMN_THREAD_TITLE); -} - - /* * Transformation Notes: * there are still a couple of things that the new forums differ from Old version. @@ -145,103 +112,113 @@ static int FilterColumnToComboBox(int nIndex) GxsForumsDialog::GxsForumsDialog(QWidget *parent) : RsAutoUpdatePage(1000,parent) { - /* Invoke the Qt Designer generated object setup routine */ - ui.setupUi(this); + /* Invoke the Qt Designer generated object setup routine */ + ui.setupUi(this); - m_bProcessSettings = false; - subscribeFlags = 0; - inMsgAsReadUnread = false; + m_bProcessSettings = false; + subscribeFlags = 0; + inMsgAsReadUnread = false; + threadCompareRole = new RSTreeWidgetItemCompareRole; + threadCompareRole->setRole(COLUMN_THREAD_DATE, ROLE_THREAD_SORT); /* Setup Queue */ - mForumQueue = new TokenQueue(rsGxsForums->getTokenService(), this); + mForumQueue = new TokenQueue(rsGxsForums->getTokenService(), this); - - - connect( ui.forumTreeWidget, SIGNAL( treeCustomContextMenuRequested( QPoint ) ), this, SLOT( forumListCustomPopupMenu( QPoint ) ) ); - connect( ui.threadTreeWidget, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( threadListCustomPopupMenu( QPoint ) ) ); + connect( ui.forumTreeWidget, SIGNAL( treeCustomContextMenuRequested( QPoint ) ), this, SLOT( forumListCustomPopupMenu( QPoint ) ) ); + connect( ui.threadTreeWidget, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( threadListCustomPopupMenu( QPoint ) ) ); connect(ui.newForumButton, SIGNAL(clicked()), this, SLOT(newforum())); - connect(ui.newmessageButton, SIGNAL(clicked()), this, SLOT(createmessage())); - connect(ui.newthreadButton, SIGNAL(clicked()), this, SLOT(createthread())); + connect(ui.newmessageButton, SIGNAL(clicked()), this, SLOT(createmessage())); + connect(ui.newthreadButton, SIGNAL(clicked()), this, SLOT(createthread())); - connect( ui.forumTreeWidget, SIGNAL( treeCurrentItemChanged(QString) ), this, SLOT( changedForum(QString) ) ); + connect( ui.forumTreeWidget, SIGNAL( treeCurrentItemChanged(QString) ), this, SLOT( changedForum(QString) ) ); - connect( ui.threadTreeWidget, SIGNAL( itemSelectionChanged() ), this, SLOT( changedThread () ) ); - connect( ui.threadTreeWidget, SIGNAL( itemClicked(QTreeWidgetItem*,int)), this, SLOT( clickedThread (QTreeWidgetItem*,int) ) ); - connect( ui.viewBox, SIGNAL( currentIndexChanged ( int ) ), this, SLOT( changedViewBox () ) ); + connect( ui.threadTreeWidget, SIGNAL( itemSelectionChanged() ), this, SLOT( changedThread () ) ); + connect( ui.threadTreeWidget, SIGNAL( itemClicked(QTreeWidgetItem*,int)), this, SLOT( clickedThread (QTreeWidgetItem*,int) ) ); + connect( ui.viewBox, SIGNAL( currentIndexChanged ( int ) ), this, SLOT( changedViewBox () ) ); - connect(ui.expandButton, SIGNAL(clicked()), this, SLOT(togglethreadview())); - connect(ui.previousButton, SIGNAL(clicked()), this, SLOT(previousMessage())); - connect(ui.nextButton, SIGNAL(clicked()), this, SLOT(nextMessage())); + connect(ui.expandButton, SIGNAL(clicked()), this, SLOT(togglethreadview())); + connect(ui.previousButton, SIGNAL(clicked()), this, SLOT(previousMessage())); + connect(ui.nextButton, SIGNAL(clicked()), this, SLOT(nextMessage())); + connect(ui.nextUnreadButton, SIGNAL(clicked()), this, SLOT(nextUnreadMessage())); - // HACK - TEMPORARY HIJACKING THIS BUTTON FOR REFRESH. - //connect(ui.nextUnreadButton, SIGNAL(clicked()), this, SLOT(nextUnreadMessage())); - connect(ui.nextUnreadButton, SIGNAL(clicked()), this, SLOT(forceUpdateDisplay())); + // HACK - TEMPORARY HIJACKING THIS BUTTON FOR REFRESH. + //connect(ui.nextUnreadButton, SIGNAL(clicked()), this, SLOT(nextUnreadMessage())); + connect(ui.nextUnreadButton, SIGNAL(clicked()), this, SLOT(forceUpdateDisplay())); - connect(ui.downloadButton, SIGNAL(clicked()), this, SLOT(downloadAllFiles())); + connect(ui.downloadButton, SIGNAL(clicked()), this, SLOT(downloadAllFiles())); - connect(ui.filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterItems(QString))); - connect(ui.filterColumnComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterColumnChanged())); + connect(ui.filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterItems(QString))); + connect(ui.filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterColumnChanged(int))); - connect(NotifyQt::getInstance(), SIGNAL(forumMsgReadSatusChanged(QString,QString,int)), this, SLOT(forumMsgReadSatusChanged(QString,QString,int))); + connect(NotifyQt::getInstance(), SIGNAL(forumMsgReadSatusChanged(QString,QString,int)), this, SLOT(forumMsgReadSatusChanged(QString,QString,int))); - /* Set initial size the splitter */ - QList sizes; - sizes << 300 << width(); // Qt calculates the right sizes - //ui.splitter->setSizes(sizes); + /* Set initial size the splitter */ + QList sizes; + sizes << 300 << width(); // Qt calculates the right sizes + //ui.splitter->setSizes(sizes); - /* Set own item delegate */ - RSItemDelegate *itemDelegate = new RSItemDelegate(this); - itemDelegate->setSpacing(QSize(0, 2)); - ui.threadTreeWidget->setItemDelegate(itemDelegate); + /* Set own item delegate */ + RSItemDelegate *itemDelegate = new RSItemDelegate(this); + itemDelegate->setSpacing(QSize(0, 2)); + ui.threadTreeWidget->setItemDelegate(itemDelegate); - /* Set header resize modes and initial section sizes */ - QHeaderView * ttheader = ui.threadTreeWidget->header () ; - ttheader->setResizeMode (COLUMN_THREAD_TITLE, QHeaderView::Interactive); - ttheader->resizeSection (COLUMN_THREAD_DATE, 140); - ttheader->resizeSection (COLUMN_THREAD_TITLE, 290); + /* Set header resize modes and initial section sizes */ + QHeaderView * ttheader = ui.threadTreeWidget->header () ; + ttheader->setResizeMode (COLUMN_THREAD_TITLE, QHeaderView::Interactive); + ttheader->resizeSection (COLUMN_THREAD_DATE, 140); + ttheader->resizeSection (COLUMN_THREAD_TITLE, 290); - ui.threadTreeWidget->sortItems( COLUMN_THREAD_DATE, Qt::DescendingOrder ); + ui.threadTreeWidget->sortItems( COLUMN_THREAD_DATE, Qt::DescendingOrder ); - /* Set text of column "Read" to empty - without this the column has a number as header text */ - QTreeWidgetItem *headerItem = ui.threadTreeWidget->headerItem(); - headerItem->setText(COLUMN_THREAD_READ, ""); + /* Set text of column "Read" to empty - without this the column has a number as header text */ + QTreeWidgetItem *headerItem = ui.threadTreeWidget->headerItem(); + headerItem->setText(COLUMN_THREAD_READ, ""); - m_ForumNameFont = QFont("Times", 12, QFont::Bold); - ui.forumName->setFont(m_ForumNameFont); - ui.threadTitle->setFont(m_ForumNameFont); +//#AFTER MERGE setTextColorNotSubscribed(Qt::black); +//#AFTER MERGE setTextColorUnread(Qt::black); +//#AFTER MERGE setTextColorUnreadChildren(Qt::gray); +//#AFTER MERGE setTextColorRead(Qt::gray); +//#AFTER MERGE setTextColorMissing(Qt::darkRed); - /* Initialize group tree */ - ui.forumTreeWidget->initDisplayMenu(ui.displayButton); + /* Initialize group tree */ +//#AFTER MERGE ui.forumTreeWidget->initDisplayMenu(ui.displayButton); - /* create forum tree */ - yourForums = ui.forumTreeWidget->addCategoryItem(tr("Your Forums"), QIcon(IMAGE_FOLDER), true); - subscribedForums = ui.forumTreeWidget->addCategoryItem(tr("Subscribed Forums"), QIcon(IMAGE_FOLDERRED), true); - popularForums = ui.forumTreeWidget->addCategoryItem(tr("Popular Forums"), QIcon(IMAGE_FOLDERGREEN), false); - otherForums = ui.forumTreeWidget->addCategoryItem(tr("Other Forums"), QIcon(IMAGE_FOLDERYELLOW), false); + /* create forum tree */ + yourForums = ui.forumTreeWidget->addCategoryItem(tr("Your Forums"), QIcon(IMAGE_FOLDER), true); + subscribedForums = ui.forumTreeWidget->addCategoryItem(tr("Subscribed Forums"), QIcon(IMAGE_FOLDERRED), true); + popularForums = ui.forumTreeWidget->addCategoryItem(tr("Popular Forums"), QIcon(IMAGE_FOLDERGREEN), false); + otherForums = ui.forumTreeWidget->addCategoryItem(tr("Other Forums"), QIcon(IMAGE_FOLDERYELLOW), false); - lastViewType = -1; + lastViewType = -1; - // load settings - processSettings(true); + /* add filter actions */ +//#AFTER MERGE ui.filterLineEdit->addFilter(QIcon(), tr("Title"), COLUMN_THREAD_TITLE, tr("Search Title")); +//#AFTER MERGE ui.filterLineEdit->addFilter(QIcon(), tr("Date"), COLUMN_THREAD_DATE, tr("Search Date")); +//#AFTER MERGE ui.filterLineEdit->addFilter(QIcon(), tr("Author"), COLUMN_THREAD_AUTHOR, tr("Search Author")); +//#AFTER MERGE ui.filterLineEdit->addFilter(QIcon(), tr("Content"), COLUMN_THREAD_CONTENT, tr("Search Content")); +//#AFTER MERGE ui.filterLineEdit->setCurrentFilter(COLUMN_THREAD_TITLE); - /* Set header sizes for the fixed columns and resize modes, must be set after processSettings */ - ttheader->resizeSection (COLUMN_THREAD_READ, 24); - ttheader->setResizeMode (COLUMN_THREAD_READ, QHeaderView::Fixed); - ttheader->hideSection (COLUMN_THREAD_CONTENT); + // load settings + processSettings(true); - ui.progressBar->hide(); - ui.progLayOutTxt->hide(); - ui.progressBarLayOut->setEnabled(false); + /* Set header sizes for the fixed columns and resize modes, must be set after processSettings */ + ttheader->resizeSection (COLUMN_THREAD_READ, 24); + ttheader->setResizeMode (COLUMN_THREAD_READ, QHeaderView::Fixed); + ttheader->hideSection (COLUMN_THREAD_CONTENT); - mThreadLoading = false; + ui.progressBar->hide(); + ui.progLayOutTxt->hide(); + ui.progressBarLayOut->setEnabled(false); - insertThreads(); + mThreadLoading = false; - ui.threadTreeWidget->installEventFilter(this); + insertThreads(); - /* Hide platform specific features */ + ui.threadTreeWidget->installEventFilter(this); + +/* Hide platform specific features */ #ifdef Q_WS_WIN #endif @@ -249,218 +226,237 @@ GxsForumsDialog::GxsForumsDialog(QWidget *parent) GxsForumsDialog::~GxsForumsDialog() { - // save settings - processSettings(false); + delete(threadCompareRole); + + // save settings + processSettings(false); } +//#AFTER MERGE UserNotify *GxsForumsDialog::getUserNotify(QObject *parent) +//{ +// return new GxsForumUserNotify(parent); +//} + void GxsForumsDialog::processSettings(bool bLoad) { - m_bProcessSettings = true; + m_bProcessSettings = true; - QHeaderView *pHeader = ui.threadTreeWidget->header () ; + QHeaderView *pHeader = ui.threadTreeWidget->header () ; - Settings->beginGroup(QString("GxsForumsDialog")); + Settings->beginGroup(QString("GxsForumsDialog")); - if (bLoad) { - // load settings + if (bLoad) { + // load settings - // expandFiles - bool bValue = Settings->value("expandButton", true).toBool(); - ui.expandButton->setChecked(bValue); - togglethreadview_internal(); + // expandFiles + bool bValue = Settings->value("expandButton", true).toBool(); + ui.expandButton->setChecked(bValue); + togglethreadview_internal(); - // filterColumn - int nValue = FilterColumnToComboBox(Settings->value("filterColumn", COLUMN_THREAD_TITLE).toInt()); - ui.filterColumnComboBox->setCurrentIndex(nValue); + // filterColumn +//#AFTER MERGE ui.filterLineEdit->setCurrentFilter(Settings->value("filterColumn", COLUMN_THREAD_TITLE).toInt()); - // index of viewBox - ui.viewBox->setCurrentIndex(Settings->value("viewBox", VIEW_THREADED).toInt()); + // index of viewBox + ui.viewBox->setCurrentIndex(Settings->value("viewBox", VIEW_THREADED).toInt()); - // state of thread tree - pHeader->restoreState(Settings->value("ThreadTree").toByteArray()); + // state of thread tree + pHeader->restoreState(Settings->value("ThreadTree").toByteArray()); - // state of splitter - ui.splitter->restoreState(Settings->value("Splitter").toByteArray()); - ui.threadSplitter->restoreState(Settings->value("threadSplitter").toByteArray()); - } else { - // save settings + // state of splitter + ui.splitter->restoreState(Settings->value("Splitter").toByteArray()); + ui.threadSplitter->restoreState(Settings->value("threadSplitter").toByteArray()); + } else { + // save settings - // state of thread tree - Settings->setValue("ThreadTree", pHeader->saveState()); + // state of thread tree + Settings->setValue("ThreadTree", pHeader->saveState()); - // state of splitter - Settings->setValue("Splitter", ui.splitter->saveState()); - Settings->setValue("threadSplitter", ui.threadSplitter->saveState()); - } + // state of splitter + Settings->setValue("Splitter", ui.splitter->saveState()); + Settings->setValue("threadSplitter", ui.threadSplitter->saveState()); + } - ui.forumTreeWidget->processSettings(Settings, bLoad); + ui.forumTreeWidget->processSettings(Settings, bLoad); - Settings->endGroup(); - m_bProcessSettings = false; + Settings->endGroup(); + m_bProcessSettings = false; +} + +void GxsForumsDialog::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + switch (e->type()) { + case QEvent::StyleChange: + CalculateIconsAndFonts(); + break; + default: + // remove compiler warnings + break; + } } void GxsForumsDialog::forumListCustomPopupMenu( QPoint /*point*/ ) { - QMenu contextMnu( this ); + QMenu contextMnu( this ); - QAction *action = contextMnu.addAction(QIcon(IMAGE_SUBSCRIBE), tr("Subscribe to Forum"), this, SLOT(subscribeToForum())); - action->setDisabled (mCurrForumId.empty() || IS_GROUP_SUBSCRIBED(subscribeFlags)); + QAction *action = contextMnu.addAction(QIcon(IMAGE_SUBSCRIBE), tr("Subscribe to Forum"), this, SLOT(subscribeToForum())); + action->setDisabled (mCurrForumId.empty() || IS_GROUP_SUBSCRIBED(subscribeFlags)); - action = contextMnu.addAction(QIcon(IMAGE_UNSUBSCRIBE), tr("Unsubscribe to Forum"), this, SLOT(unsubscribeToForum())); - action->setEnabled (!mCurrForumId.empty() && IS_GROUP_SUBSCRIBED(subscribeFlags)); + action = contextMnu.addAction(QIcon(IMAGE_UNSUBSCRIBE), tr("Unsubscribe to Forum"), this, SLOT(unsubscribeToForum())); + action->setEnabled (!mCurrForumId.empty() && IS_GROUP_SUBSCRIBED(subscribeFlags)); - contextMnu.addSeparator(); + contextMnu.addSeparator(); - contextMnu.addAction(QIcon(IMAGE_NEWFORUM), tr("New Forum"), this, SLOT(newforum())); + contextMnu.addAction(QIcon(IMAGE_NEWFORUM), tr("New Forum"), this, SLOT(newforum())); - action = contextMnu.addAction(QIcon(IMAGE_INFO), tr("Show Forum Details"), this, SLOT(showForumDetails())); - action->setEnabled (!mCurrForumId.empty ()); + action = contextMnu.addAction(QIcon(IMAGE_INFO), tr("Show Forum Details"), this, SLOT(showForumDetails())); + action->setEnabled (!mCurrForumId.empty ()); - action = contextMnu.addAction(QIcon(":/images/settings16.png"), tr("Edit Forum Details"), this, SLOT(editForumDetails())); - action->setEnabled (!mCurrForumId.empty () && IS_GROUP_ADMIN(subscribeFlags)); + action = contextMnu.addAction(QIcon(":/images/settings16.png"), tr("Edit Forum Details"), this, SLOT(editForumDetails())); + action->setEnabled (!mCurrForumId.empty () && IS_GROUP_ADMIN(subscribeFlags)); - QAction *shareKeyAct = new QAction(QIcon(":/images/gpgp_key_generate.png"), tr("Share Forum"), &contextMnu); - connect( shareKeyAct, SIGNAL( triggered() ), this, SLOT( shareKey() ) ); - shareKeyAct->setEnabled(!mCurrForumId.empty() && IS_GROUP_ADMIN(subscribeFlags)); - contextMnu.addAction( shareKeyAct); + QAction *shareKeyAct = new QAction(QIcon(":/images/gpgp_key_generate.png"), tr("Share Forum"), &contextMnu); + connect( shareKeyAct, SIGNAL( triggered() ), this, SLOT( shareKey() ) ); + shareKeyAct->setEnabled(!mCurrForumId.empty() && IS_GROUP_ADMIN(subscribeFlags)); + contextMnu.addAction( shareKeyAct); - QAction *restoreKeysAct = new QAction(QIcon(":/images/settings16.png"), tr("Restore Publish Rights for Forum" ), &contextMnu); - connect( restoreKeysAct , SIGNAL( triggered() ), this, SLOT( restoreForumKeys() ) ); - restoreKeysAct->setEnabled(!mCurrForumId.empty() && !IS_GROUP_ADMIN(subscribeFlags)); - contextMnu.addAction( restoreKeysAct); + QAction *restoreKeysAct = new QAction(QIcon(":/images/settings16.png"), tr("Restore Publish Rights for Forum" ), &contextMnu); + connect( restoreKeysAct , SIGNAL( triggered() ), this, SLOT( restoreForumKeys() ) ); + restoreKeysAct->setEnabled(!mCurrForumId.empty() && !IS_GROUP_ADMIN(subscribeFlags)); + contextMnu.addAction( restoreKeysAct); - action = contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyForumLink())); - action->setEnabled(!mCurrForumId.empty()); + action = contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyForumLink())); + action->setEnabled(!mCurrForumId.empty()); - contextMnu.addSeparator(); + contextMnu.addSeparator(); - action = contextMnu.addAction(QIcon(":/images/message-mail-read.png"), tr("Mark all as read"), this, SLOT(markMsgAsReadAll())); - action->setEnabled (!mCurrForumId.empty () && IS_GROUP_SUBSCRIBED(subscribeFlags)); + action = contextMnu.addAction(QIcon(":/images/message-mail-read.png"), tr("Mark all as read"), this, SLOT(markMsgAsReadAll())); + action->setEnabled (!mCurrForumId.empty () && IS_GROUP_SUBSCRIBED(subscribeFlags)); - action = contextMnu.addAction(QIcon(":/images/message-mail.png"), tr("Mark all as unread"), this, SLOT(markMsgAsUnreadAll())); - action->setEnabled (!mCurrForumId.empty () && IS_GROUP_SUBSCRIBED(subscribeFlags)); + action = contextMnu.addAction(QIcon(":/images/message-mail.png"), tr("Mark all as unread"), this, SLOT(markMsgAsUnreadAll())); + action->setEnabled (!mCurrForumId.empty () && IS_GROUP_SUBSCRIBED(subscribeFlags)); #ifdef DEBUG_FORUMS - contextMnu.addSeparator(); - action = contextMnu.addAction("Generate mass data", this, SLOT(generateMassData())); - action->setEnabled (!mCurrForumId.empty() && IS_GROUP_SUBSCRIBED(subscribeFlags)); + contextMnu.addSeparator(); + action = contextMnu.addAction("Generate mass data", this, SLOT(generateMassData())); + action->setEnabled (!mCurrForumId.empty() && IS_GROUP_SUBSCRIBED(subscribeFlags)); #endif - contextMnu.exec(QCursor::pos()); + contextMnu.exec(QCursor::pos()); } void GxsForumsDialog::threadListCustomPopupMenu( QPoint /*point*/ ) { - if (mThreadLoading) { - return; - } + if (mThreadLoading) { + return; + } - QMenu contextMnu( this ); + QMenu contextMnu( this ); - QAction *replyAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr( "Reply" ), &contextMnu ); - connect( replyAct , SIGNAL( triggered() ), this, SLOT( createmessage() ) ); + QAction *replyAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr( "Reply" ), &contextMnu ); + connect( replyAct , SIGNAL( triggered() ), this, SLOT( createmessage() ) ); - QAction *newthreadAct = new QAction(QIcon(IMAGE_DOWNLOADALL), tr( "Start New Thread" ), &contextMnu ); - newthreadAct->setEnabled (IS_GROUP_SUBSCRIBED(subscribeFlags)); - connect( newthreadAct , SIGNAL( triggered() ), this, SLOT( createthread() ) ); + QAction *newthreadAct = new QAction(QIcon(IMAGE_DOWNLOADALL), tr( "Start New Thread" ), &contextMnu ); + newthreadAct->setEnabled (IS_GROUP_SUBSCRIBED(subscribeFlags)); + connect( newthreadAct , SIGNAL( triggered() ), this, SLOT( createthread() ) ); - QAction *replyauthorAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr( "Reply to Author" ), &contextMnu ); - connect( replyauthorAct , SIGNAL( triggered() ), this, SLOT( replytomessage() ) ); + QAction *replyauthorAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr( "Reply to Author" ), &contextMnu ); + connect( replyauthorAct , SIGNAL( triggered() ), this, SLOT( replytomessage() ) ); - QAction* expandAll = new QAction(tr( "Expand all" ), &contextMnu ); - connect( expandAll , SIGNAL( triggered() ), ui.threadTreeWidget, SLOT (expandAll()) ); + QAction* expandAll = new QAction(tr( "Expand all" ), &contextMnu ); + connect( expandAll , SIGNAL( triggered() ), ui.threadTreeWidget, SLOT (expandAll()) ); - QAction* collapseAll = new QAction(tr( "Collapse all" ), &contextMnu ); - connect( collapseAll , SIGNAL( triggered() ), ui.threadTreeWidget, SLOT(collapseAll()) ); + QAction* collapseAll = new QAction(tr( "Collapse all" ), &contextMnu ); + connect( collapseAll , SIGNAL( triggered() ), ui.threadTreeWidget, SLOT(collapseAll()) ); - QAction *markMsgAsRead = new QAction(QIcon(":/images/message-mail-read.png"), tr("Mark as read"), &contextMnu); - connect(markMsgAsRead , SIGNAL(triggered()), this, SLOT(markMsgAsRead())); + QAction *markMsgAsRead = new QAction(QIcon(":/images/message-mail-read.png"), tr("Mark as read"), &contextMnu); + connect(markMsgAsRead , SIGNAL(triggered()), this, SLOT(markMsgAsRead())); - QAction *markMsgAsReadChildren = new QAction(QIcon(":/images/message-mail-read.png"), tr("Mark as read") + " (" + tr ("with children") + ")", &contextMnu); - connect(markMsgAsReadChildren, SIGNAL(triggered()), this, SLOT(markMsgAsReadChildren())); + QAction *markMsgAsReadChildren = new QAction(QIcon(":/images/message-mail-read.png"), tr("Mark as read") + " (" + tr ("with children") + ")", &contextMnu); + connect(markMsgAsReadChildren, SIGNAL(triggered()), this, SLOT(markMsgAsReadChildren())); - QAction *markMsgAsUnread = new QAction(QIcon(":/images/message-mail.png"), tr("Mark as unread"), &contextMnu); - connect(markMsgAsUnread , SIGNAL(triggered()), this, SLOT(markMsgAsUnread())); + QAction *markMsgAsUnread = new QAction(QIcon(":/images/message-mail.png"), tr("Mark as unread"), &contextMnu); + connect(markMsgAsUnread , SIGNAL(triggered()), this, SLOT(markMsgAsUnread())); - QAction *markMsgAsUnreadChildren = new QAction(QIcon(":/images/message-mail.png"), tr("Mark as unread") + " (" + tr ("with children") + ")", &contextMnu); - connect(markMsgAsUnreadChildren , SIGNAL(triggered()), this, SLOT(markMsgAsUnreadChildren())); + QAction *markMsgAsUnreadChildren = new QAction(QIcon(":/images/message-mail.png"), tr("Mark as unread") + " (" + tr ("with children") + ")", &contextMnu); + connect(markMsgAsUnreadChildren , SIGNAL(triggered()), this, SLOT(markMsgAsUnreadChildren())); - if (IS_GROUP_SUBSCRIBED(subscribeFlags)) { - QList Rows; - QList RowsRead; - QList RowsUnread; - int nCount = getSelectedMsgCount (&Rows, &RowsRead, &RowsUnread); + if (IS_GROUP_SUBSCRIBED(subscribeFlags)) { + QList Rows; + QList RowsRead; + QList RowsUnread; + int nCount = getSelectedMsgCount (&Rows, &RowsRead, &RowsUnread); - if (RowsUnread.size() == 0) { + if (RowsUnread.size() == 0) { - markMsgAsRead->setDisabled(true); - } - if (RowsRead.size() == 0) { - markMsgAsUnread->setDisabled(true); - } + markMsgAsRead->setDisabled(true); + } + if (RowsRead.size() == 0) { + markMsgAsUnread->setDisabled(true); + } - bool bHasUnreadChildren = false; - bool bHasReadChildren = false; - int nRowCount = Rows.count(); - for (int i = 0; i < nRowCount; i++) { - if (bHasUnreadChildren || Rows[i]->data(COLUMN_THREAD_DATA, ROLE_THREAD_UNREADCHILDREN).toBool()) { - bHasUnreadChildren = true; - } - if (bHasReadChildren || Rows[i]->data(COLUMN_THREAD_DATA, ROLE_THREAD_READCHILDREN).toBool()) { - bHasReadChildren = true; - } - } - markMsgAsReadChildren->setEnabled(bHasUnreadChildren); - markMsgAsUnreadChildren->setEnabled(bHasReadChildren); + bool bHasUnreadChildren = false; + bool bHasReadChildren = false; + int nRowCount = Rows.count(); + for (int i = 0; i < nRowCount; i++) { + if (bHasUnreadChildren || Rows[i]->data(COLUMN_THREAD_DATA, ROLE_THREAD_UNREADCHILDREN).toBool()) { + bHasUnreadChildren = true; + } + if (bHasReadChildren || Rows[i]->data(COLUMN_THREAD_DATA, ROLE_THREAD_READCHILDREN).toBool()) { + bHasReadChildren = true; + } + } + markMsgAsReadChildren->setEnabled(bHasUnreadChildren); + markMsgAsUnreadChildren->setEnabled(bHasReadChildren); - if (nCount == 1) { - replyAct->setEnabled (true); - replyauthorAct->setEnabled (true); - } else { - replyAct->setDisabled (true); - replyauthorAct->setDisabled (true); - } - } else { - markMsgAsRead->setDisabled(true); - markMsgAsReadChildren->setDisabled(true); - markMsgAsUnread->setDisabled(true); - markMsgAsUnreadChildren->setDisabled(true); - replyAct->setDisabled (true); - replyauthorAct->setDisabled (true); - } + if (nCount == 1) { + replyAct->setEnabled (true); + replyauthorAct->setEnabled (true); + } else { + replyAct->setDisabled (true); + replyauthorAct->setDisabled (true); + } + } else { + markMsgAsRead->setDisabled(true); + markMsgAsReadChildren->setDisabled(true); + markMsgAsUnread->setDisabled(true); + markMsgAsUnreadChildren->setDisabled(true); + replyAct->setDisabled (true); + replyauthorAct->setDisabled (true); + } - contextMnu.addAction( replyAct); - contextMnu.addAction( newthreadAct); - contextMnu.addAction( replyauthorAct); - QAction* action = contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr( "Copy RetroShare Link"), this, SLOT(copyMessageLink())); - action->setEnabled(!mCurrForumId.empty() && !mCurrThreadId.empty()); - contextMnu.addSeparator(); - contextMnu.addAction(markMsgAsRead); - contextMnu.addAction(markMsgAsReadChildren); - contextMnu.addAction(markMsgAsUnread); - contextMnu.addAction(markMsgAsUnreadChildren); - contextMnu.addSeparator(); - contextMnu.addAction( expandAll); - contextMnu.addAction( collapseAll); + contextMnu.addAction( replyAct); + contextMnu.addAction( newthreadAct); + contextMnu.addAction( replyauthorAct); + QAction* action = contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr( "Copy RetroShare Link"), this, SLOT(copyMessageLink())); + action->setEnabled(!mCurrForumId.empty() && !mCurrThreadId.empty()); + contextMnu.addSeparator(); + contextMnu.addAction(markMsgAsRead); + contextMnu.addAction(markMsgAsReadChildren); + contextMnu.addAction(markMsgAsUnread); + contextMnu.addAction(markMsgAsUnreadChildren); + contextMnu.addSeparator(); + contextMnu.addAction( expandAll); + contextMnu.addAction( collapseAll); - contextMnu.exec(QCursor::pos()); + contextMnu.exec(QCursor::pos()); } bool GxsForumsDialog::eventFilter(QObject *obj, QEvent *event) { - if (obj == ui.threadTreeWidget) { - if (event->type() == QEvent::KeyPress) { - QKeyEvent *keyEvent = static_cast(event); - if (keyEvent && keyEvent->key() == Qt::Key_Space) { - // Space pressed - QTreeWidgetItem *item = ui.threadTreeWidget->currentItem (); - clickedThread (item, COLUMN_THREAD_READ); - return true; // eat event - } - } - } - // pass the event on to the parent class - return RsAutoUpdatePage::eventFilter(obj, event); + if (obj == ui.threadTreeWidget) { + if (event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(event); + if (keyEvent && keyEvent->key() == Qt::Key_Space) { + // Space pressed + QTreeWidgetItem *item = ui.threadTreeWidget->currentItem (); + clickedThread (item, COLUMN_THREAD_READ); + return true; // eat event + } + } + } + // pass the event on to the parent class + return RsAutoUpdatePage::eventFilter(obj, event); } void GxsForumsDialog::restoreForumKeys(void) @@ -472,56 +468,56 @@ void GxsForumsDialog::restoreForumKeys(void) void GxsForumsDialog::togglethreadview() { - // save state of button - Settings->setValueToGroup("GxsForumsDialog", "expandButton", ui.expandButton->isChecked()); + // save state of button + Settings->setValueToGroup("GxsForumsDialog", "expandButton", ui.expandButton->isChecked()); - togglethreadview_internal(); + togglethreadview_internal(); } void GxsForumsDialog::togglethreadview_internal() { - if (ui.expandButton->isChecked()) { - ui.postText->setVisible(true); - ui.expandButton->setIcon(QIcon(QString(":/images/edit_remove24.png"))); - ui.expandButton->setToolTip(tr("Hide")); - } else { - ui.postText->setVisible(false); - ui.expandButton->setIcon(QIcon(QString(":/images/edit_add24.png"))); - ui.expandButton->setToolTip(tr("Expand")); - } + if (ui.expandButton->isChecked()) { + ui.postText->setVisible(true); + ui.expandButton->setIcon(QIcon(QString(":/images/edit_remove24.png"))); + ui.expandButton->setToolTip(tr("Hide")); + } else { + ui.postText->setVisible(false); + ui.expandButton->setIcon(QIcon(QString(":/images/edit_add24.png"))); + ui.expandButton->setToolTip(tr("Expand")); + } } void GxsForumsDialog::updateDisplay() { - std::list forumIds; - std::list::iterator it; - if (!rsGxsForums) - return; + std::list forumIds; + std::list::iterator it; + if (!rsGxsForums) + return; #if 0 // TODO groupsChanged... HACK XXX. - if ((rsGxsForums->groupsChanged(forumIds)) || (rsGxsForums->updated())) - { - /* update Forums List */ - insertForums(); + if ((rsGxsForums->groupsChanged(forumIds)) || (rsGxsForums->updated())) + { + /* update Forums List */ + insertForums(); - it = std::find(forumIds.begin(), forumIds.end(), mCurrForumId); - if (it != forumIds.end()) - { - /* update threads as well */ - insertThreads(); - } - } + it = std::find(forumIds.begin(), forumIds.end(), mCurrForumId); + if (it != forumIds.end()) + { + /* update threads as well */ + insertThreads(); + } + } #endif - /* The proper version (above) can be done with a data request -> TODO */ - if (rsGxsForums->updated()) - { - /* update Forums List */ - insertForums(); - /* update threads as well */ - insertThreads(); - } + /* The proper version (above) can be done with a data request -> TODO */ + if (rsGxsForums->updated()) + { + /* update Forums List */ + insertForums(); + /* update threads as well */ + insertThreads(); + } } // HACK until update works. @@ -530,86 +526,83 @@ void GxsForumsDialog::forceUpdateDisplay() std::cerr << "GxsForumsDialog::forceUpdateDisplay()"; std::cerr << std::endl; - /* update Forums List */ - insertForums(); - /* update threads as well */ - insertThreads(); + /* update Forums List */ + insertForums(); + /* update threads as well */ + insertThreads(); } - static void CleanupItems (QList &items) { - QList::iterator item; - for (item = items.begin (); item != items.end (); item++) { - if (*item) { - delete (*item); - } - } - items.clear(); + QList::iterator item; + for (item = items.begin (); item != items.end (); item++) { + if (*item) { + delete (*item); + } + } + items.clear(); } void GxsForumsDialog::forumInfoToGroupItemInfo(const RsGroupMetaData &forumInfo, GroupItemInfo &groupItemInfo) //void GxsForumsDialog::forumInfoToGroupItemInfo(const ForumInfo &forumInfo, GroupItemInfo &groupItemInfo) { - - groupItemInfo.id = QString::fromStdString(forumInfo.mGroupId); - groupItemInfo.name = QString::fromUtf8(forumInfo.mGroupName.c_str()); - //groupItemInfo.description = QString::fromUtf8(forumInfo.forumDesc); - groupItemInfo.popularity = forumInfo.mPop; - groupItemInfo.lastpost = QDateTime::fromTime_t(forumInfo.mLastPost); + groupItemInfo.id = QString::fromStdString(forumInfo.mGroupId); + groupItemInfo.name = QString::fromUtf8(forumInfo.mGroupName.c_str()); + //groupItemInfo.description = QString::fromUtf8(forumInfo.forumDesc); + groupItemInfo.popularity = forumInfo.mPop; + groupItemInfo.lastpost = QDateTime::fromTime_t(forumInfo.mLastPost); #if TOGXS - if (forumInfo.mGroupFlags & RS_DISTRIB_AUTHEN_REQ) { - groupItemInfo.name += " (" + tr("AUTHD") + ")"; - groupItemInfo.icon = QIcon(IMAGE_FORUMAUTHD); - } - else + if (forumInfo.mGroupFlags & RS_DISTRIB_AUTHEN_REQ) { + groupItemInfo.name += " (" + tr("AUTHD") + ")"; + groupItemInfo.icon = QIcon(IMAGE_FORUMAUTHD); + } + else #endif - { - groupItemInfo.icon = QIcon(IMAGE_FORUM); - } + { + groupItemInfo.icon = QIcon(IMAGE_FORUM); + } -// groupItemInfo.id = QString::fromStdString(forumInfo.forumId); -// groupItemInfo.name = QString::fromStdWString(forumInfo.forumName); -// groupItemInfo.description = QString::fromStdWString(forumInfo.forumDesc); -// groupItemInfo.popularity = forumInfo.pop; -// groupItemInfo.lastpost = QDateTime::fromTime_t(forumInfo.lastPost); +// groupItemInfo.id = QString::fromStdString(forumInfo.forumId); +// groupItemInfo.name = QString::fromStdWString(forumInfo.forumName); +// groupItemInfo.description = QString::fromStdWString(forumInfo.forumDesc); +// groupItemInfo.popularity = forumInfo.pop; +// groupItemInfo.lastpost = QDateTime::fromTime_t(forumInfo.lastPost); // -// if (forumInfo.forumFlags & RS_DISTRIB_AUTHEN_REQ) { -// groupItemInfo.name += " (" + tr("AUTHD") + ")"; -// groupItemInfo.icon = QIcon(IMAGE_FORUMAUTHD); -// } else { -// groupItemInfo.icon = QIcon(IMAGE_FORUM); -// } +// if (forumInfo.forumFlags & RS_DISTRIB_AUTHEN_REQ) { +// groupItemInfo.name += " (" + tr("AUTHD") + ")"; +// groupItemInfo.icon = QIcon(IMAGE_FORUMAUTHD); +// } else { +// groupItemInfo.icon = QIcon(IMAGE_FORUM); +// } } - /***** INSERT FORUM LISTS *****/ void GxsForumsDialog::insertForumsData(const std::list &forumList) { std::list::const_iterator it; - QList adminList; - QList subList; - QList popList; - QList otherList; - std::multimap popMap; + QList adminList; + QList subList; + QList popList; + QList otherList; + std::multimap popMap; - for (it = forumList.begin(); it != forumList.end(); it++) { + for (it = forumList.begin(); it != forumList.end(); it++) { /* sort it into Publish (Own), Subscribed, Popular and Other */ uint32_t flags = it->mSubscribeFlags; - GroupItemInfo groupItemInfo; - forumInfoToGroupItemInfo(*it, groupItemInfo); + GroupItemInfo groupItemInfo; + forumInfoToGroupItemInfo(*it, groupItemInfo); - if (IS_GROUP_ADMIN(flags)) { - adminList.push_back(groupItemInfo); - } else if (IS_GROUP_SUBSCRIBED(flags)) { + if (IS_GROUP_ADMIN(flags)) { + adminList.push_back(groupItemInfo); + } else if (IS_GROUP_SUBSCRIBED(flags)) { /* subscribed forum */ - subList.push_back(groupItemInfo); - } else { + subList.push_back(groupItemInfo); + } else { /* rate the others by popularity */ - popMap.insert(std::make_pair(it->mPop, groupItemInfo)); + popMap.insert(std::make_pair(it->mPop, groupItemInfo)); } } @@ -622,190 +615,190 @@ void GxsForumsDialog::insertForumsData(const std::list &forumLi uint32_t i = 0; uint32_t popLimit = 0; - std::multimap::reverse_iterator rit; + std::multimap::reverse_iterator rit; for(rit = popMap.rbegin(); ((rit != popMap.rend()) && (i < popCount)); rit++, i++) ; - if (rit != popMap.rend()) { - popLimit = rit->first; - } + if (rit != popMap.rend()) { + popLimit = rit->first; + } - for (rit = popMap.rbegin(); rit != popMap.rend(); rit++) { + for (rit = popMap.rbegin(); rit != popMap.rend(); rit++) { if (rit->second.popularity < (int) popLimit) { - otherList.append(rit->second); - } else { - popList.append(rit->second); - } + otherList.append(rit->second); + } else { + popList.append(rit->second); + } } /* now we can add them in as a tree! */ - ui.forumTreeWidget->fillGroupItems(yourForums, adminList); - ui.forumTreeWidget->fillGroupItems(subscribedForums, subList); - ui.forumTreeWidget->fillGroupItems(popularForums, popList); - ui.forumTreeWidget->fillGroupItems(otherForums, otherList); + ui.forumTreeWidget->fillGroupItems(yourForums, adminList); + ui.forumTreeWidget->fillGroupItems(subscribedForums, subList); + ui.forumTreeWidget->fillGroupItems(popularForums, popList); + ui.forumTreeWidget->fillGroupItems(otherForums, otherList); updateMessageSummaryList(""); } void GxsForumsDialog::changedForum(const QString &id) { - mCurrForumId = id.toStdString(); + mCurrForumId = id.toStdString(); - insertThreads(); + insertThreads(); } void GxsForumsDialog::changedThread () { - if (mThreadLoading) { - return; - } + if (mThreadLoading) { + return; + } - /* just grab the ids of the current item */ - QTreeWidgetItem *curr = ui.threadTreeWidget->currentItem(); + /* just grab the ids of the current item */ + QTreeWidgetItem *curr = ui.threadTreeWidget->currentItem(); - if ((!curr) || (!curr->isSelected())) { - mCurrThreadId = ""; - } else { - mCurrThreadId = curr->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString(); - } - insertPost(); + if ((!curr) || (!curr->isSelected())) { + mCurrThreadId = ""; + } else { + mCurrThreadId = curr->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString(); + } + insertPost(); } void GxsForumsDialog::clickedThread (QTreeWidgetItem *item, int column) { - if (mCurrForumId.empty() || !IS_GROUP_SUBSCRIBED(subscribeFlags)) { - return; - } + if (mCurrForumId.empty() || !IS_GROUP_SUBSCRIBED(subscribeFlags)) { + return; + } - if (item == NULL) { - return; - } + if (item == NULL) { + return; + } - if (column == COLUMN_THREAD_READ) { - QList Rows; - Rows.append(item); - uint32_t status = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - setMsgReadStatus(Rows, IS_MSG_UNREAD(status)); - return; - } + if (column == COLUMN_THREAD_READ) { + QList Rows; + Rows.append(item); + uint32_t status = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + setMsgReadStatus(Rows, IS_MSG_UNREAD(status)); + return; + } } void GxsForumsDialog::forumMsgReadStatusChanged(const QString &forumId, const QString &msgId, int status) { - if (inMsgAsReadUnread) { - return; - } + if (inMsgAsReadUnread) { + return; + } - if (forumId.toStdString() == mCurrForumId) { - /* Search exisiting item */ - QTreeWidgetItemIterator itemIterator(ui.threadTreeWidget); - QTreeWidgetItem *item = NULL; - while ((item = *itemIterator) != NULL) { - itemIterator++; + if (forumId.toStdString() == mCurrForumId) { + /* Search exisiting item */ + QTreeWidgetItemIterator itemIterator(ui.threadTreeWidget); + QTreeWidgetItem *item = NULL; + while ((item = *itemIterator) != NULL) { + itemIterator++; - if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString() == msgId) { - // update status - item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, status); + if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString() == msgId) { + // update status + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, status); - QTreeWidgetItem *parentItem = item; - while (parentItem->parent()) { - parentItem = parentItem->parent(); - } - CalculateIconsAndFonts(parentItem); - break; - } - } - } - updateMessageSummaryList(forumId.toStdString()); + QTreeWidgetItem *parentItem = item; + while (parentItem->parent()) { + parentItem = parentItem->parent(); + } + CalculateIconsAndFonts(parentItem); + break; + } + } + } + updateMessageSummaryList(forumId.toStdString()); } void GxsForumsDialog::CalculateIconsAndFonts(QTreeWidgetItem *pItem, bool &bHasReadChilddren, bool &bHasUnreadChilddren) { - uint32_t status = pItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + uint32_t status = pItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - bool bUnread = IS_MSG_UNREAD(status); - bool missing = pItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING).toBool(); + bool bUnread = IS_MSG_UNREAD(status); + bool missing = pItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING).toBool(); - // set icon - if (missing) { - pItem->setIcon(COLUMN_THREAD_READ, QIcon()); - pItem->setIcon(COLUMN_THREAD_TITLE, QIcon()); - } else { - if (bUnread) { - pItem->setIcon(COLUMN_THREAD_READ, QIcon(":/images/message-state-unread.png")); - } else { - pItem->setIcon(COLUMN_THREAD_READ, QIcon(":/images/message-state-read.png")); - } - if (IS_MSG_UNREAD(status)) { - pItem->setIcon(COLUMN_THREAD_TITLE, QIcon(":/images/message-state-new.png")); - } else { - pItem->setIcon(COLUMN_THREAD_TITLE, QIcon()); - } - } + // set icon + if (missing) { + pItem->setIcon(COLUMN_THREAD_READ, QIcon()); + pItem->setIcon(COLUMN_THREAD_TITLE, QIcon()); + } else { + if (bUnread) { + pItem->setIcon(COLUMN_THREAD_READ, QIcon(":/images/message-state-unread.png")); + } else { + pItem->setIcon(COLUMN_THREAD_READ, QIcon(":/images/message-state-read.png")); + } + if (IS_MSG_UNREAD(status)) { + pItem->setIcon(COLUMN_THREAD_TITLE, QIcon(":/images/message-state-new.png")); + } else { + pItem->setIcon(COLUMN_THREAD_TITLE, QIcon()); + } + } - int nItem; - int nItemCount = pItem->childCount(); + int nItem; + int nItemCount = pItem->childCount(); - bool bMyReadChilddren = false; - bool bMyUnreadChilddren = false; + bool bMyReadChilddren = false; + bool bMyUnreadChilddren = false; - for (nItem = 0; nItem < nItemCount; nItem++) { - CalculateIconsAndFonts(pItem->child(nItem), bMyReadChilddren, bMyUnreadChilddren); - } + for (nItem = 0; nItem < nItemCount; nItem++) { + CalculateIconsAndFonts(pItem->child(nItem), bMyReadChilddren, bMyUnreadChilddren); + } - // set font - for (int i = 0; i < COLUMN_THREAD_COUNT; i++) { - QFont qf = pItem->font(i); + // set font + for (int i = 0; i < COLUMN_THREAD_COUNT; i++) { + QFont qf = pItem->font(i); - if (!IS_GROUP_SUBSCRIBED(subscribeFlags)) { - qf.setBold(false); - pItem->setTextColor(i, Qt::black); - } else if (bUnread) { - qf.setBold(true); - pItem->setTextColor(i, Qt::black); - } else if (bMyUnreadChilddren) { - qf.setBold(true); - pItem->setTextColor(i, Qt::gray); - } else { - qf.setBold(false); - pItem->setTextColor(i, Qt::gray); - } - if (missing) { - /* Missing message */ - pItem->setTextColor(i, Qt::darkRed); - } - pItem->setFont(i, qf); - } + if (!IS_GROUP_SUBSCRIBED(subscribeFlags)) { + qf.setBold(false); + pItem->setTextColor(i, textColorNotSubscribed()); + } else if (bUnread) { + qf.setBold(true); + pItem->setTextColor(i, textColorUnread()); + } else if (bMyUnreadChilddren) { + qf.setBold(true); + pItem->setTextColor(i, textColorUnreadChildren()); + } else { + qf.setBold(false); + pItem->setTextColor(i, textColorRead()); + } + if (missing) { + /* Missing message */ + pItem->setTextColor(i, textColorMissing()); + } + pItem->setFont(i, qf); + } - pItem->setData(COLUMN_THREAD_DATA, ROLE_THREAD_READCHILDREN, bHasReadChilddren || bMyReadChilddren); - pItem->setData(COLUMN_THREAD_DATA, ROLE_THREAD_UNREADCHILDREN, bHasUnreadChilddren || bMyUnreadChilddren); + pItem->setData(COLUMN_THREAD_DATA, ROLE_THREAD_READCHILDREN, bHasReadChilddren || bMyReadChilddren); + pItem->setData(COLUMN_THREAD_DATA, ROLE_THREAD_UNREADCHILDREN, bHasUnreadChilddren || bMyUnreadChilddren); - bHasReadChilddren = bHasReadChilddren || bMyReadChilddren || !bUnread; - bHasUnreadChilddren = bHasUnreadChilddren || bMyUnreadChilddren || bUnread; + bHasReadChilddren = bHasReadChilddren || bMyReadChilddren || !bUnread; + bHasUnreadChilddren = bHasUnreadChilddren || bMyUnreadChilddren || bUnread; } void GxsForumsDialog::CalculateIconsAndFonts(QTreeWidgetItem *pItem /*= NULL*/) { - bool bDummy1 = false; - bool bDummy2 = false; + bool bDummy1 = false; + bool bDummy2 = false; - if (pItem) { - CalculateIconsAndFonts(pItem, bDummy1, bDummy2); - return; - } + if (pItem) { + CalculateIconsAndFonts(pItem, bDummy1, bDummy2); + return; + } - int nItem; - int nItemCount = ui.threadTreeWidget->topLevelItemCount(); + int nItem; + int nItemCount = ui.threadTreeWidget->topLevelItemCount(); - for (nItem = 0; nItem < nItemCount; nItem++) { - bDummy1 = false; - bDummy2 = false; - CalculateIconsAndFonts(ui.threadTreeWidget->topLevelItem(nItem), bDummy1, bDummy2); - } + for (nItem = 0; nItem < nItemCount; nItem++) { + bDummy1 = false; + bDummy2 = false; + CalculateIconsAndFonts(ui.threadTreeWidget->topLevelItem(nItem), bDummy1, bDummy2); + } } void GxsForumsDialog::fillThreadFinished() { #ifdef DEBUG_FORUMS - std::cerr << "GxsForumsDialog::fillThreadFinished" << std::endl; + std::cerr << "GxsForumsDialog::fillThreadFinished" << std::endl; #endif // This is now only called with a successful Load. @@ -815,43 +808,43 @@ void GxsForumsDialog::fillThreadFinished() ui.progressBar->hide(); ui.progLayOutTxt->hide(); ui.progressBarLayOut->setEnabled(false); - + #ifdef DEBUG_FORUMS std::cerr << "GxsForumsDialog::fillThreadFinished Add messages" << std::endl; #endif - ui.threadTreeWidget->setSortingEnabled(false); + ui.threadTreeWidget->setSortingEnabled(false); - /* add all messages in! */ - if (lastViewType != mThreadLoad.ViewType || lastForumID != mCurrForumId) + /* add all messages in! */ + if (lastViewType != mThreadLoad.ViewType || lastForumID != mCurrForumId) { ui.threadTreeWidget->clear(); lastViewType = mThreadLoad.ViewType; lastForumID = mCurrForumId; ui.threadTreeWidget->insertTopLevelItems(0, mThreadLoad.Items); - + // clear list mThreadLoad.Items.clear(); - } - else + } + else { FillThreads (mThreadLoad.Items, mThreadLoad.ExpandNewMessages, mThreadLoad.ItemToExpand); - + // cleanup list CleanupItems (mThreadLoad.Items); } - ui.threadTreeWidget->setSortingEnabled(true); + ui.threadTreeWidget->setSortingEnabled(true); - if (mThreadLoad.FocusMsgId.empty() == false) + if (mThreadLoad.FocusMsgId.empty() == false) { /* Search exisiting item */ QTreeWidgetItemIterator itemIterator(ui.threadTreeWidget); QTreeWidgetItem *item = NULL; - while ((item = *itemIterator) != NULL) + while ((item = *itemIterator) != NULL) { itemIterator++; - - if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString() == mThreadLoad.FocusMsgId) + + if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString() == mThreadLoad.FocusMsgId) { ui.threadTreeWidget->setCurrentItem(item); ui.threadTreeWidget->setFocus(); @@ -859,40 +852,39 @@ void GxsForumsDialog::fillThreadFinished() } } } - + QList::iterator Item; - for (Item = mThreadLoad.ItemToExpand.begin(); Item != mThreadLoad.ItemToExpand.end(); Item++) + for (Item = mThreadLoad.ItemToExpand.begin(); Item != mThreadLoad.ItemToExpand.end(); Item++) { - if ((*Item)->isHidden() == false) + if ((*Item)->isHidden() == false) { (*Item)->setExpanded(true); } } mThreadLoad.ItemToExpand.clear(); - - if (ui.filterLineEdit->text().isEmpty() == false) { - filterItems(ui.filterLineEdit->text()); + + if (ui.filterLineEdit->text().isEmpty() == false) { + filterItems(ui.filterLineEdit->text()); } - + insertPost (); CalculateIconsAndFonts(); - + ui.newthreadButton->setEnabled (IS_GROUP_SUBSCRIBED(subscribeFlags)); mThreadLoading = false; #ifdef DEBUG_FORUMS - std::cerr << "GxsForumsDialog::fillThreadFinished done" << std::endl; + std::cerr << "GxsForumsDialog::fillThreadFinished done" << std::endl; #endif } void GxsForumsDialog::fillThreadProgress(int current, int count) { - // show fill progress - if (count) { - ui.progressBar->setValue(current * ui.progressBar->maximum() / count); - } - + // show fill progress + if (count) { + ui.progressBar->setValue(current * ui.progressBar->maximum() / count); + } } void GxsForumsDialog::insertThreads() @@ -903,13 +895,13 @@ void GxsForumsDialog::insertThreads() #endif subscribeFlags = 0; - + ui.newmessageButton->setEnabled (false); ui.newthreadButton->setEnabled (false); - + ui.postText->clear(); ui.threadTitle->clear(); - + if (mCurrForumId.empty()) { /* not an actual forum - clear */ @@ -919,14 +911,14 @@ void GxsForumsDialog::insertThreads() /* clear last stored forumID */ mCurrForumId.erase(); lastForumID.erase(); - + #ifdef DEBUG_FORUMS std::cerr << "GxsForumsDialog::insertThreads() Current Thread Invalid" << std::endl; #endif - + return; } - + // Get Current Forum Info... then complete insertForumThreads(). requestGroupSummary_CurrentForum(mCurrForumId); } @@ -934,236 +926,233 @@ void GxsForumsDialog::insertThreads() void GxsForumsDialog::insertForumThreads(const RsGroupMetaData &fi) { - subscribeFlags = fi.mSubscribeFlags; - ui.forumName->setText(QString::fromUtf8(fi.mGroupName.c_str())); + subscribeFlags = fi.mSubscribeFlags; + ui.forumName->setText(QString::fromUtf8(fi.mGroupName.c_str())); - ui.progressBarLayOut->setEnabled(true); + ui.progressBarLayOut->setEnabled(true); - ui.progLayOutTxt->show(); - ui.progressBar->reset(); - ui.progressBar->show(); + ui.progLayOutTxt->show(); + ui.progressBar->reset(); + ui.progressBar->show(); #ifdef DEBUG_FORUMS - std::cerr << "GxsForumsDialog::insertThreads() Start filling Forum threads" << std::endl; + std::cerr << "GxsForumsDialog::insertThreads() Start filling Forum threads" << std::endl; #endif - loadCurrentForumThreads(fi.mGroupId); + loadCurrentForumThreads(fi.mGroupId); } - - - void GxsForumsDialog::FillThreads(QList &ThreadList, bool expandNewMessages, QList &itemToExpand) { #ifdef DEBUG_FORUMS - std::cerr << "GxsForumsDialog::FillThreads()" << std::endl; + std::cerr << "GxsForumsDialog::FillThreads()" << std::endl; #endif - int Index = 0; - QTreeWidgetItem *Thread; - QList::iterator NewThread; + int Index = 0; + QTreeWidgetItem *Thread; + QList::iterator NewThread; - // delete not existing - while (Index < ui.threadTreeWidget->topLevelItemCount ()) { - Thread = ui.threadTreeWidget->topLevelItem (Index); + // delete not existing + while (Index < ui.threadTreeWidget->topLevelItemCount ()) { + Thread = ui.threadTreeWidget->topLevelItem (Index); - // search existing new thread - int Found = -1; - for (NewThread = ThreadList.begin (); NewThread != ThreadList.end (); NewThread++) { - if (Thread->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == (*NewThread)->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { - // found it - Found = Index; - break; - } - } - if (Found >= 0) { - Index++; - } else { - delete (ui.threadTreeWidget->takeTopLevelItem (Index)); - } - } + // search existing new thread + int Found = -1; + for (NewThread = ThreadList.begin (); NewThread != ThreadList.end (); NewThread++) { + if (Thread->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == (*NewThread)->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { + // found it + Found = Index; + break; + } + } + if (Found >= 0) { + Index++; + } else { + delete (ui.threadTreeWidget->takeTopLevelItem (Index)); + } + } - // iterate all new threads - for (NewThread = ThreadList.begin (); NewThread != ThreadList.end (); NewThread++) { - // search existing thread - int Found = -1; - int Count = ui.threadTreeWidget->topLevelItemCount (); - for (Index = 0; Index < Count; Index++) { - Thread = ui.threadTreeWidget->topLevelItem (Index); - if (Thread->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == (*NewThread)->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { - // found it - Found = Index; - break; - } - } + // iterate all new threads + for (NewThread = ThreadList.begin (); NewThread != ThreadList.end (); NewThread++) { + // search existing thread + int Found = -1; + int Count = ui.threadTreeWidget->topLevelItemCount (); + for (Index = 0; Index < Count; Index++) { + Thread = ui.threadTreeWidget->topLevelItem (Index); + if (Thread->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == (*NewThread)->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { + // found it + Found = Index; + break; + } + } - if (Found >= 0) { - // set child data - int i; - for (i = 0; i < COLUMN_THREAD_COUNT; i++) { - Thread->setText (i, (*NewThread)->text (i)); - } - for (i = 0; i < ROLE_THREAD_COUNT; i++) { - Thread->setData (COLUMN_THREAD_DATA, Qt::UserRole + i, (*NewThread)->data (COLUMN_THREAD_DATA, Qt::UserRole + i)); - } + if (Found >= 0) { + // set child data + int i; + for (i = 0; i < COLUMN_THREAD_COUNT; i++) { + Thread->setText (i, (*NewThread)->text (i)); + } + for (i = 0; i < ROLE_THREAD_COUNT; i++) { + Thread->setData (COLUMN_THREAD_DATA, Qt::UserRole + i, (*NewThread)->data (COLUMN_THREAD_DATA, Qt::UserRole + i)); + } - // fill recursive - FillChildren (Thread, *NewThread, expandNewMessages, itemToExpand); - } else { - // add new thread - ui.threadTreeWidget->addTopLevelItem (*NewThread); - Thread = *NewThread; - *NewThread = NULL; - } + // fill recursive + FillChildren (Thread, *NewThread, expandNewMessages, itemToExpand); + } else { + // add new thread + ui.threadTreeWidget->addTopLevelItem (*NewThread); + Thread = *NewThread; + *NewThread = NULL; + } - uint32_t status = Thread->data (COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - if (expandNewMessages && IS_MSG_UNREAD(status)) { - QTreeWidgetItem *pParent = Thread; - while ((pParent = pParent->parent()) != NULL) { - if (std::find(itemToExpand.begin(), itemToExpand.end(), pParent) == itemToExpand.end()) { - itemToExpand.push_back(pParent); - } - } - } - } + uint32_t status = Thread->data (COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + if (expandNewMessages && IS_MSG_UNREAD(status)) { + QTreeWidgetItem *pParent = Thread; + while ((pParent = pParent->parent()) != NULL) { + if (std::find(itemToExpand.begin(), itemToExpand.end(), pParent) == itemToExpand.end()) { + itemToExpand.push_back(pParent); + } + } + } + } #ifdef DEBUG_FORUMS - std::cerr << "GxsForumsDialog::FillThreads() done" << std::endl; + std::cerr << "GxsForumsDialog::FillThreads() done" << std::endl; #endif } void GxsForumsDialog::FillChildren(QTreeWidgetItem *Parent, QTreeWidgetItem *NewParent, bool expandNewMessages, QList &itemToExpand) { - int Index = 0; - int NewIndex; - int NewCount = NewParent->childCount(); + int Index = 0; + int NewIndex; + int NewCount = NewParent->childCount(); - QTreeWidgetItem *Child; - QTreeWidgetItem *NewChild; + QTreeWidgetItem *Child; + QTreeWidgetItem *NewChild; - // delete not existing - while (Index < Parent->childCount ()) { - Child = Parent->child (Index); + // delete not existing + while (Index < Parent->childCount ()) { + Child = Parent->child (Index); - // search existing new child - int Found = -1; - int Count = NewParent->childCount(); - for (NewIndex = 0; NewIndex < Count; NewIndex++) { - NewChild = NewParent->child (NewIndex); - if (NewChild->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == Child->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { - // found it - Found = Index; - break; - } - } - if (Found >= 0) { - Index++; - } else { - delete (Parent->takeChild (Index)); - } - } + // search existing new child + int Found = -1; + int Count = NewParent->childCount(); + for (NewIndex = 0; NewIndex < Count; NewIndex++) { + NewChild = NewParent->child (NewIndex); + if (NewChild->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == Child->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { + // found it + Found = Index; + break; + } + } + if (Found >= 0) { + Index++; + } else { + delete (Parent->takeChild (Index)); + } + } - // iterate all new children - for (NewIndex = 0; NewIndex < NewCount; NewIndex++) { - NewChild = NewParent->child (NewIndex); + // iterate all new children + for (NewIndex = 0; NewIndex < NewCount; NewIndex++) { + NewChild = NewParent->child (NewIndex); - // search existing child - int Found = -1; - int Count = Parent->childCount(); - for (Index = 0; Index < Count; Index++) { - Child = Parent->child (Index); - if (Child->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == NewChild->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { - // found it - Found = Index; - break; - } - } + // search existing child + int Found = -1; + int Count = Parent->childCount(); + for (Index = 0; Index < Count; Index++) { + Child = Parent->child (Index); + if (Child->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == NewChild->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { + // found it + Found = Index; + break; + } + } - if (Found >= 0) { - // set child data - int i; - for (i = 0; i < COLUMN_THREAD_COUNT; i++) { - Child->setText (i, NewChild->text (i)); - } - for (i = 0; i < ROLE_THREAD_COUNT; i++) { - Child->setData (COLUMN_THREAD_DATA, Qt::UserRole + i, NewChild->data (COLUMN_THREAD_DATA, Qt::UserRole + i)); - } + if (Found >= 0) { + // set child data + int i; + for (i = 0; i < COLUMN_THREAD_COUNT; i++) { + Child->setText (i, NewChild->text (i)); + } + for (i = 0; i < ROLE_THREAD_COUNT; i++) { + Child->setData (COLUMN_THREAD_DATA, Qt::UserRole + i, NewChild->data (COLUMN_THREAD_DATA, Qt::UserRole + i)); + } - // fill recursive - FillChildren (Child, NewChild, expandNewMessages, itemToExpand); - } else { - // add new child - Child = NewParent->takeChild(NewIndex); - Parent->addChild (Child); - NewIndex--; - NewCount--; - } + // fill recursive + FillChildren (Child, NewChild, expandNewMessages, itemToExpand); + } else { + // add new child + Child = NewParent->takeChild(NewIndex); + Parent->addChild (Child); + NewIndex--; + NewCount--; + } - uint32_t status = Child->data (COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - if (expandNewMessages && IS_MSG_UNREAD(status)) { - QTreeWidgetItem *pParent = Child; - while ((pParent = pParent->parent()) != NULL) { - if (std::find(itemToExpand.begin(), itemToExpand.end(), pParent) == itemToExpand.end()) { - itemToExpand.push_back(pParent); - } - } - } - } + uint32_t status = Child->data (COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + if (expandNewMessages && IS_MSG_UNREAD(status)) { + QTreeWidgetItem *pParent = Child; + while ((pParent = pParent->parent()) != NULL) { + if (std::find(itemToExpand.begin(), itemToExpand.end(), pParent) == itemToExpand.end()) { + itemToExpand.push_back(pParent); + } + } + } + } } QString GxsForumsDialog::titleFromInfo(const RsMsgMetaData &meta) { - // NOTE - NOTE SURE HOW THIS WILL WORK! + // NOTE - NOTE SURE HOW THIS WILL WORK! #ifdef TOGXS - if (meta.mMsgStatus & RS_DISTRIB_MISSING_MSG) { - return QApplication::translate("GxsForumsDialog", "[ ... Missing Message ... ]"); - } + if (meta.mMsgStatus & RS_DISTRIB_MISSING_MSG) { + return QApplication::translate("GxsForumsDialog", "[ ... Missing Message ... ]"); + } #endif - return QString::fromUtf8(meta.mMsgName.c_str()); + return QString::fromUtf8(meta.mMsgName.c_str()); } QString GxsForumsDialog::messageFromInfo(const RsGxsForumMsg &msg) { #ifdef TOGXS - if (msg.mMeta.mMsgStatus & RS_DISTRIB_MISSING_MSG) { - return QApplication::translate("GxsForumsDialog", "Placeholder for missing Message"); - } + if (msg.mMeta.mMsgStatus & RS_DISTRIB_MISSING_MSG) { + return QApplication::translate("GxsForumsDialog", "Placeholder for missing Message"); + } #endif - return QString::fromUtf8(msg.mMsg.c_str()); + return QString::fromUtf8(msg.mMsg.c_str()); } void GxsForumsDialog::insertPost() { - if ((mCurrForumId == "") || (mCurrThreadId == "")) - { - ui.postText->setText(""); - ui.threadTitle->setText(""); - ui.previousButton->setEnabled(false); - ui.nextButton->setEnabled(false); - ui.newmessageButton->setEnabled (false); - return; - } - - QTreeWidgetItem *curr = ui.threadTreeWidget->currentItem(); - if (curr) { - QTreeWidgetItem *Parent = curr->parent (); - int Index = Parent ? Parent->indexOfChild (curr) : ui.threadTreeWidget->indexOfTopLevelItem (curr); - int Count = Parent ? Parent->childCount () : ui.threadTreeWidget->topLevelItemCount (); - ui.previousButton->setEnabled (Index > 0); - ui.nextButton->setEnabled (Index < Count - 1); - } else { - // there is something wrong - ui.previousButton->setEnabled(false); - ui.nextButton->setEnabled(false); + if ((mCurrForumId == "") || (mCurrThreadId == "")) + { + ui.postText->setText(""); + ui.threadTitle->setText(""); + ui.previousButton->setEnabled(false); + ui.nextButton->setEnabled(false); + ui.newmessageButton->setEnabled (false); return; - } + } - ui.newmessageButton->setEnabled (IS_GROUP_SUBSCRIBED(subscribeFlags) && mCurrThreadId.empty() == false); + QTreeWidgetItem *curr = ui.threadTreeWidget->currentItem(); + if (curr) { + QTreeWidgetItem *Parent = curr->parent (); + int Index = Parent ? Parent->indexOfChild (curr) : ui.threadTreeWidget->indexOfTopLevelItem (curr); + int Count = Parent ? Parent->childCount () : ui.threadTreeWidget->topLevelItemCount (); + ui.previousButton->setEnabled (Index > 0); + ui.nextButton->setEnabled (Index < Count - 1); + } else { + // there is something wrong + ui.previousButton->setEnabled(false); + ui.nextButton->setEnabled(false); + return; + } + + ui.newmessageButton->setEnabled (IS_GROUP_SUBSCRIBED(subscribeFlags) && mCurrThreadId.empty() == false); /* blank text, incase we get nothing */ - ui.postText->setText(""); + ui.postText->setText(""); /* request Post */ RsGxsGrpMsgIdPair postId = std::make_pair(mCurrForumId, mCurrThreadId); @@ -1171,12 +1160,10 @@ void GxsForumsDialog::insertPost() } - - void GxsForumsDialog::insertPostData(const RsGxsForumMsg &msg) { /* As some time has elapsed since request - check that this is still the current msg. - * otherwise, another request will fill the data + * otherwise, another request will fill the data */ if ((msg.mMeta.mGroupId != mCurrForumId) || (msg.mMeta.mMsgId != mCurrThreadId)) @@ -1191,31 +1178,23 @@ void GxsForumsDialog::insertPostData(const RsGxsForumMsg &msg) return; } - QTreeWidgetItem *curr = ui.threadTreeWidget->currentItem(); + QTreeWidgetItem *curr = ui.threadTreeWidget->currentItem(); - bool bSetToReadOnActive = Settings->getForumMsgSetToReadOnActivate(); - uint32_t status = curr->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + bool bSetToReadOnActive = Settings->getForumMsgSetToReadOnActivate(); + uint32_t status = curr->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - QList Row; - Row.append(curr); + QList Row; + Row.append(curr); - if (bSetToReadOnActive && IS_MSG_UNREAD(status)) - { - setMsgReadStatus(Row, true); - } - - QString text; + if (bSetToReadOnActive && IS_MSG_UNREAD(status)) { - QDateTime qtime; - qtime.setTime_t(msg.mMeta.mPublishTs); - - text = qtime.toString("yyyy-MM-dd hh:mm:ss"); - - ui.time_label->setText(text); + setMsgReadStatus(Row, true); } - + +//#AFTER MERGE ui.time_label->setText(DateTime::formatLongDateTime(msg.mMeta.mPublishTs)); + std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); - text = QString::fromUtf8(authorName.c_str()); + QString text = QString::fromUtf8(authorName.c_str()); if (text.isEmpty()) { @@ -1223,51 +1202,48 @@ void GxsForumsDialog::insertPostData(const RsGxsForumMsg &msg) } else { - ui.by_label->setText( tr("By") + " " + text ); - } + ui.by_label->setText( tr("By") + " " + text ); + } - QString extraTxt = RsHtml().formatText(ui.postText->document(), messageFromInfo(msg), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS); - - ui.postText->setHtml(extraTxt); - ui.threadTitle->setText(titleFromInfo(msg.mMeta)); - + QString extraTxt = RsHtml().formatText(ui.postText->document(), messageFromInfo(msg), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS); + ui.postText->setHtml(extraTxt); + ui.threadTitle->setText(titleFromInfo(msg.mMeta)); } - -void GxsForumsDialog::previousMessage () +void GxsForumsDialog::previousMessage() { - QTreeWidgetItem *Item = ui.threadTreeWidget->currentItem (); - if (Item == NULL) { - return; - } + QTreeWidgetItem *Item = ui.threadTreeWidget->currentItem (); + if (Item == NULL) { + return; + } - QTreeWidgetItem *Parent = Item->parent (); - int Index = Parent ? Parent->indexOfChild (Item) : ui.threadTreeWidget->indexOfTopLevelItem (Item); - if (Index > 0) { - QTreeWidgetItem *Previous = Parent ? Parent->child (Index - 1) : ui.threadTreeWidget->topLevelItem (Index - 1); - if (Previous) { - ui.threadTreeWidget->setCurrentItem (Previous); - } - } + QTreeWidgetItem *Parent = Item->parent (); + int Index = Parent ? Parent->indexOfChild (Item) : ui.threadTreeWidget->indexOfTopLevelItem (Item); + if (Index > 0) { + QTreeWidgetItem *Previous = Parent ? Parent->child (Index - 1) : ui.threadTreeWidget->topLevelItem (Index - 1); + if (Previous) { + ui.threadTreeWidget->setCurrentItem (Previous); + } + } } -void GxsForumsDialog::nextMessage () +void GxsForumsDialog::nextMessage() { - QTreeWidgetItem *Item = ui.threadTreeWidget->currentItem (); - if (Item == NULL) { - return; - } + QTreeWidgetItem *Item = ui.threadTreeWidget->currentItem (); + if (Item == NULL) { + return; + } - QTreeWidgetItem *Parent = Item->parent (); - int Index = Parent ? Parent->indexOfChild (Item) : ui.threadTreeWidget->indexOfTopLevelItem (Item); - int Count = Parent ? Parent->childCount () : ui.threadTreeWidget->topLevelItemCount (); - if (Index < Count - 1) { - QTreeWidgetItem *Next = Parent ? Parent->child (Index + 1) : ui.threadTreeWidget->topLevelItem (Index + 1); - if (Next) { - ui.threadTreeWidget->setCurrentItem (Next); - } - } + QTreeWidgetItem *Parent = Item->parent (); + int Index = Parent ? Parent->indexOfChild (Item) : ui.threadTreeWidget->indexOfTopLevelItem (Item); + int Count = Parent ? Parent->childCount () : ui.threadTreeWidget->topLevelItemCount (); + if (Index < Count - 1) { + QTreeWidgetItem *Next = Parent ? Parent->child (Index + 1) : ui.threadTreeWidget->topLevelItem (Index + 1); + if (Next) { + ui.threadTreeWidget->setCurrentItem (Next); + } + } } void GxsForumsDialog::downloadAllFiles() @@ -1286,23 +1262,34 @@ void GxsForumsDialog::downloadAllFiles() void GxsForumsDialog::nextUnreadMessage() { - QTreeWidgetItem* currentItem = ui.threadTreeWidget->currentItem(); - if( !currentItem ) - { - currentItem = ui.threadTreeWidget->topLevelItem(0); - if( !currentItem ) - return; - } + QTreeWidgetItem *currentItem = ui.threadTreeWidget->currentItem(); - do - { - uint32_t status = currentItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - if( IS_MSG_UNREAD(status) ) - { - ui.threadTreeWidget->setCurrentItem(currentItem); - return; - } - } while( (currentItem = ui.threadTreeWidget->itemBelow(currentItem)) != NULL ); + while (TRUE) { + QTreeWidgetItemIterator itemIterator = currentItem ? QTreeWidgetItemIterator(currentItem, QTreeWidgetItemIterator::NotHidden) : QTreeWidgetItemIterator(ui.threadTreeWidget, QTreeWidgetItemIterator::NotHidden); + + QTreeWidgetItem *item; + while ((item = *itemIterator) != NULL) { + itemIterator++; + + if (item == currentItem) { + continue; + } + + uint32_t status = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + if (IS_MSG_UNREAD(status)) { + ui.threadTreeWidget->setCurrentItem(item); + ui.threadTreeWidget->scrollToItem(item, QAbstractItemView::EnsureVisible); + return; + } + } + + if (currentItem == NULL) { + break; + } + + /* start from top */ + currentItem = NULL; + } } // TODO @@ -1326,258 +1313,253 @@ void GxsForumsDialog::removemessage() the messages tree is single selected, but who knows ... */ int GxsForumsDialog::getSelectedMsgCount(QList *pRows, QList *pRowsRead, QList *pRowsUnread) { - if (pRowsRead) pRowsRead->clear(); - if (pRowsUnread) pRowsUnread->clear(); + if (pRowsRead) pRowsRead->clear(); + if (pRowsUnread) pRowsUnread->clear(); - QList selectedItems = ui.threadTreeWidget->selectedItems(); - for(QList::iterator it = selectedItems.begin(); it != selectedItems.end(); it++) { - if (pRows) pRows->append(*it); - if (pRowsRead || pRowsUnread) { - uint32_t status = (*it)->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - if (IS_MSG_UNREAD(status)) { - if (pRowsUnread) pRowsUnread->append(*it); - } else { - if (pRowsRead) pRowsRead->append(*it); - } - } - } + QList selectedItems = ui.threadTreeWidget->selectedItems(); + for(QList::iterator it = selectedItems.begin(); it != selectedItems.end(); it++) { + if (pRows) pRows->append(*it); + if (pRowsRead || pRowsUnread) { + uint32_t status = (*it)->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + if (IS_MSG_UNREAD(status)) { + if (pRowsUnread) pRowsUnread->append(*it); + } else { + if (pRowsRead) pRowsRead->append(*it); + } + } + } - return selectedItems.size(); + return selectedItems.size(); } void GxsForumsDialog::setMsgReadStatus(QList &Rows, bool bRead) { - QList::iterator Row; - std::list changedItems; + QList::iterator Row; + std::list changedItems; - inMsgAsReadUnread = true; + inMsgAsReadUnread = true; - for (Row = Rows.begin(); Row != Rows.end(); Row++) { - if ((*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING).toBool()) { - /* Missing message */ - continue; - } + for (Row = Rows.begin(); Row != Rows.end(); Row++) { + if ((*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING).toBool()) { + /* Missing message */ + continue; + } - uint32_t status = (*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + uint32_t status = (*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - uint32_t statusNew = (status & ~GXS_SERV::GXS_MSG_STATUS_UNREAD); // orig status, without UNREAD. - if (!bRead) { - statusNew |= GXS_SERV::GXS_MSG_STATUS_UNREAD; - } + uint32_t statusNew = (status & ~GXS_SERV::GXS_MSG_STATUS_UNREAD); // orig status, without UNREAD. + if (!bRead) { + statusNew |= GXS_SERV::GXS_MSG_STATUS_UNREAD; + } - if (IS_MSG_UNREAD(status) == bRead) // is it different? - { - std::string msgId = (*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString(); + if (IS_MSG_UNREAD(status) == bRead) // is it different? + { + std::string msgId = (*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString(); - // NB: MUST BE PART OF ACTIVE THREAD--- OR ELSE WE MUST STORE GROUPID SOMEWHERE!. - // LIKE THIS BELOW... - //std::string grpId = (*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_GROUPID).toString().toStdString(); + // NB: MUST BE PART OF ACTIVE THREAD--- OR ELSE WE MUST STORE GROUPID SOMEWHERE!. + // LIKE THIS BELOW... + //std::string grpId = (*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_GROUPID).toString().toStdString(); - RsGxsGrpMsgIdPair msgPair = std::make_pair(mCurrForumId, msgId); + RsGxsGrpMsgIdPair msgPair = std::make_pair(mCurrForumId, msgId); - uint32_t token; - rsGxsForums->setMessageReadStatus(token, msgPair, bRead); + uint32_t token; + rsGxsForums->setMessageReadStatus(token, msgPair, bRead); - (*Row)->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, statusNew); + (*Row)->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, statusNew); - QTreeWidgetItem *parentItem = *Row; - while (parentItem->parent()) { - parentItem = parentItem->parent(); - } - if (std::find(changedItems.begin(), changedItems.end(), parentItem) == changedItems.end()) { - changedItems.push_back(parentItem); - } - } - } + QTreeWidgetItem *parentItem = *Row; + while (parentItem->parent()) { + parentItem = parentItem->parent(); + } + if (std::find(changedItems.begin(), changedItems.end(), parentItem) == changedItems.end()) { + changedItems.push_back(parentItem); + } + } + } - inMsgAsReadUnread = false; + inMsgAsReadUnread = false; - if (changedItems.size()) { - for (std::list::iterator it = changedItems.begin(); it != changedItems.end(); it++) { - CalculateIconsAndFonts(*it); - } - updateMessageSummaryList(mCurrForumId); - } + if (changedItems.size()) { + for (std::list::iterator it = changedItems.begin(); it != changedItems.end(); it++) { + CalculateIconsAndFonts(*it); + } + updateMessageSummaryList(mCurrForumId); + } } void GxsForumsDialog::markMsgAsReadUnread (bool bRead, bool bChildren, bool bForum) { - if (mCurrForumId.empty() || !IS_GROUP_SUBSCRIBED(subscribeFlags)) { - return; - } + if (mCurrForumId.empty() || !IS_GROUP_SUBSCRIBED(subscribeFlags)) { + return; + } - /* get selected messages */ - QList Rows; - if (bForum) { - int itemCount = ui.threadTreeWidget->topLevelItemCount(); - for (int item = 0; item < itemCount; item++) { - Rows.push_back(ui.threadTreeWidget->topLevelItem(item)); - } - } else { - getSelectedMsgCount (&Rows, NULL, NULL); - } + /* get selected messages */ + QList Rows; + if (bForum) { + int itemCount = ui.threadTreeWidget->topLevelItemCount(); + for (int item = 0; item < itemCount; item++) { + Rows.push_back(ui.threadTreeWidget->topLevelItem(item)); + } + } else { + getSelectedMsgCount (&Rows, NULL, NULL); + } - if (bChildren) { - /* add children */ - QList AllRows; + if (bChildren) { + /* add children */ + QList AllRows; - while (Rows.isEmpty() == false) { - QTreeWidgetItem *pRow = Rows.takeFirst(); + while (Rows.isEmpty() == false) { + QTreeWidgetItem *pRow = Rows.takeFirst(); - /* add only items with the right state or with not RSGXS_MSG_STATUS_READ */ - uint32_t status = pRow->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - if (IS_MSG_UNREAD(status) == bRead) { - AllRows.append(pRow); - } + /* add only items with the right state or with not RSGXS_MSG_STATUS_READ */ + uint32_t status = pRow->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + if (IS_MSG_UNREAD(status) == bRead) { + AllRows.append(pRow); + } - for (int i = 0; i < pRow->childCount(); i++) { - /* add child to main list and let the main loop do the work */ - Rows.append(pRow->child(i)); - } - } + for (int i = 0; i < pRow->childCount(); i++) { + /* add child to main list and let the main loop do the work */ + Rows.append(pRow->child(i)); + } + } - if (AllRows.isEmpty()) { - /* nothing to do */ - return; - } + if (AllRows.isEmpty()) { + /* nothing to do */ + return; + } - setMsgReadStatus(AllRows, bRead); + setMsgReadStatus(AllRows, bRead); - return; - } + return; + } - setMsgReadStatus(Rows, bRead); + setMsgReadStatus(Rows, bRead); } void GxsForumsDialog::markMsgAsRead() { - markMsgAsReadUnread(true, false, false); + markMsgAsReadUnread(true, false, false); } void GxsForumsDialog::markMsgAsReadChildren() { - markMsgAsReadUnread(true, true, false); + markMsgAsReadUnread(true, true, false); } void GxsForumsDialog::markMsgAsReadAll() { - markMsgAsReadUnread(true, true, true); + markMsgAsReadUnread(true, true, true); } void GxsForumsDialog::markMsgAsUnread() { - markMsgAsReadUnread(false, false, false); + markMsgAsReadUnread(false, false, false); } void GxsForumsDialog::markMsgAsUnreadChildren() { - markMsgAsReadUnread(false, true, false); + markMsgAsReadUnread(false, true, false); } void GxsForumsDialog::markMsgAsUnreadAll() { - markMsgAsReadUnread(false, true, true); + markMsgAsReadUnread(false, true, true); } void GxsForumsDialog::copyForumLink() { - if (mCurrForumId.empty()) { - return; - } + if (mCurrForumId.empty()) { + return; + } // THIS CODE CALLS getForumInfo() to verify that the Ids are valid. // As we are switching to Request/Response this is now harder to do... // So not bothering any more - shouldn't be necessary. // IF we get errors - fix them, rather than patching here. #if 0 - ForumInfo fi; - if (rsGxsForums->getForumInfo(mCurrForumId, fi)) { - RetroShareLink link; - if (link.createForum(fi.forumId, "")) { - QList urls; - urls.push_back(link); - RSLinkClipboard::copyLinks(urls); - } - } + ForumInfo fi; + if (rsGxsForums->getForumInfo(mCurrForumId, fi)) { + RetroShareLink link; + if (link.createForum(fi.forumId, "")) { + QList urls; + urls.push_back(link); + RSLinkClipboard::copyLinks(urls); + } + } #endif { - RetroShareLink link; - if (link.createForum(mCurrForumId, "")) + RetroShareLink link; + if (link.createForum(mCurrForumId, "")) { - QList urls; - urls.push_back(link); - RSLinkClipboard::copyLinks(urls); + QList urls; + urls.push_back(link); + RSLinkClipboard::copyLinks(urls); } } } - - - void GxsForumsDialog::copyMessageLink() { - if (mCurrForumId.empty() || mCurrThreadId.empty()) { - return; - } + if (mCurrForumId.empty() || mCurrThreadId.empty()) { + return; + } // SEE NOTE In fn above. #if 0 - ForumInfo fi; - if (rsGxsForums->getForumInfo(mCurrForumId, fi)) { - RetroShareLink link; - if (link.createForum(mCurrForumId, mCurrThreadId)) { - QList urls; - urls.push_back(link); - RSLinkClipboard::copyLinks(urls); - } - } + ForumInfo fi; + if (rsGxsForums->getForumInfo(mCurrForumId, fi)) { + RetroShareLink link; + if (link.createForum(mCurrForumId, mCurrThreadId)) { + QList urls; + urls.push_back(link); + RSLinkClipboard::copyLinks(urls); + } + } #endif { - RetroShareLink link; - if (link.createForum(mCurrForumId, mCurrThreadId)) + RetroShareLink link; + if (link.createForum(mCurrForumId, mCurrThreadId)) { - QList urls; - urls.push_back(link); - RSLinkClipboard::copyLinks(urls); + QList urls; + urls.push_back(link); + RSLinkClipboard::copyLinks(urls); } } } - void GxsForumsDialog::newforum() { - GxsForumGroupDialog cf (mForumQueue, this); - //cf.newGroup(); + GxsForumGroupDialog cf (mForumQueue, this); + //cf.newGroup(); - cf.exec (); + cf.exec (); } void GxsForumsDialog::createmessage() { - if (mCurrForumId.empty () || !IS_GROUP_SUBSCRIBED(subscribeFlags)) { - return; - } + if (mCurrForumId.empty () || !IS_GROUP_SUBSCRIBED(subscribeFlags)) { + return; + } - CreateGxsForumMsg *cfm = new CreateGxsForumMsg(mCurrForumId, mCurrThreadId); - cfm->show(); + CreateGxsForumMsg *cfm = new CreateGxsForumMsg(mCurrForumId, mCurrThreadId); + cfm->show(); - /* window will destroy itself! */ + /* window will destroy itself! */ } void GxsForumsDialog::createthread() { - if (mCurrForumId.empty ()) { - QMessageBox::information(this, tr("RetroShare"), tr("No Forum Selected!")); - return; - } + if (mCurrForumId.empty ()) { + QMessageBox::information(this, tr("RetroShare"), tr("No Forum Selected!")); + return; + } - CreateGxsForumMsg *cfm = new CreateGxsForumMsg(mCurrForumId, ""); - cfm->setWindowTitle(tr("Start New Thread")); - cfm->show(); + CreateGxsForumMsg *cfm = new CreateGxsForumMsg(mCurrForumId, ""); + cfm->show(); - /* window will destroy itself! */ + /* window will destroy itself! */ } void GxsForumsDialog::subscribeToForum() @@ -1595,68 +1577,65 @@ void GxsForumsDialog::forumSubscribe(bool subscribe) if (mCurrForumId.empty()) { return; } - + uint32_t token; rsGxsForums->subscribeToGroup(token, mCurrForumId, subscribe); } void GxsForumsDialog::showForumDetails() { - if (mCurrForumId.empty()) { - return; - } + if (mCurrForumId.empty()) { + return; + } - RsGxsForumGroup grp; - grp.mMeta.mGroupId = mCurrForumId; + RsGxsForumGroup grp; + grp.mMeta.mGroupId = mCurrForumId; - GxsForumGroupDialog cf(grp, this); + GxsForumGroupDialog cf(grp, this); - cf.exec (); + cf.exec (); } void GxsForumsDialog::editForumDetails() { - if (mCurrForumId.empty()) { - return; - } + if (mCurrForumId.empty()) { + return; + } - RsGxsForumGroup grp; - grp.mMeta.mGroupId = mCurrForumId; + RsGxsForumGroup grp; + grp.mMeta.mGroupId = mCurrForumId; - GxsForumGroupDialog cf(grp, this); + GxsForumGroupDialog cf(grp, this); - //GxsForumGroupDialog cf (mForumQueue, this, mCurrForumId, GXS_GROUP_DIALOG_EDIT_MODE); + //GxsForumGroupDialog cf (mForumQueue, this, mCurrForumId, GXS_GROUP_DIALOG_EDIT_MODE); - cf.exec (); + cf.exec (); } static QString buildReplyHeader(const RsMsgMetaData &meta) { - RetroShareLink link; - link.createMessage(meta.mAuthorId, ""); - QString from = link.toHtml(); + RetroShareLink link; + link.createMessage(meta.mAuthorId, ""); + QString from = link.toHtml(); - QDateTime qtime; - qtime.setTime_t(meta.mPublishTs); + QString header = QString("-----%1-----").arg(QApplication::translate("GxsForumsDialog", "Original Message")); + header += QString("
%1: %2
").arg(QApplication::translate("GxsForumsDialog", "From"), from); - QString header = QString("-----%1-----").arg(QApplication::translate("GxsForumsDialog", "Original Message")); - header += QString("
%1: %2
").arg(QApplication::translate("GxsForumsDialog", "From"), from); +//#AFTER MERGE header += QString("
%1: %2
").arg(QApplication::translate("GxsForumsDialog", "Sent"), DateTime::formatLongDateTime(meta.mPublishTs)); + header += QString("%1: %2

").arg(QApplication::translate("GxsForumsDialog", "Subject"), QString::fromUtf8(meta.mMsgName.c_str())); + header += "
"; - header += QString("
%1: %2
").arg(QApplication::translate("GxsForumsDialog", "Sent"), qtime.toString(Qt::SystemLocaleLongDate)); - header += QString("%1: %2

").arg(QApplication::translate("GxsForumsDialog", "Subject"), QString::fromUtf8(meta.mMsgName.c_str())); - header += "
"; +//#AFTER MERGE header += QApplication::translate("GxsForumsDialog", "On %1, %2 wrote:").arg(DateTime::formatDateTime(meta.mPublishTs), from); - header += QApplication::translate("GxsForumsDialog", "On %1, %2 wrote:").arg(qtime.toString(Qt::SystemLocaleShortDate), from); - - return header; + return header; } void GxsForumsDialog::replytomessage() { - if (mCurrForumId.empty() || mCurrThreadId.empty()) { - QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to a non-existant Message")); - return; - } + if (mCurrForumId.empty() || mCurrThreadId.empty()) { + QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to a non-existant Message")); + return; + } RsGxsGrpMsgIdPair postId = std::make_pair(mCurrForumId, mCurrThreadId); requestMsgData_ReplyMessage(postId); @@ -1672,210 +1651,210 @@ void GxsForumsDialog::replyMessageData(const RsGxsForumMsg &msg) } // NB: TODO REMOVE rsPeers references. - if (rsPeers->getPeerName(msg.mMeta.mAuthorId) !="") - { - MessageComposer *nMsgDialog = MessageComposer::newMsg(); - nMsgDialog->setTitleText(QString::fromUtf8(msg.mMeta.mMsgName.c_str()), MessageComposer::REPLY); + if (rsPeers->getPeerName(msg.mMeta.mAuthorId) !="") + { + MessageComposer *nMsgDialog = MessageComposer::newMsg(); + nMsgDialog->setTitleText(QString::fromUtf8(msg.mMeta.mMsgName.c_str()), MessageComposer::REPLY); - nMsgDialog->setQuotedMsg(QString::fromUtf8(msg.mMsg.c_str()), buildReplyHeader(msg.mMeta)); + nMsgDialog->setQuotedMsg(QString::fromUtf8(msg.mMsg.c_str()), buildReplyHeader(msg.mMeta)); - nMsgDialog->addRecipient(MessageComposer::TO, msg.mMeta.mAuthorId, false); - nMsgDialog->show(); - nMsgDialog->activateWindow(); + nMsgDialog->addRecipient(MessageComposer::TO, msg.mMeta.mAuthorId, false); + nMsgDialog->show(); + nMsgDialog->activateWindow(); - /* window will destroy itself! */ - } - else - { - QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to an Anonymous Author")); - } + /* window will destroy itself! */ + } + else + { + QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to an Anonymous Author")); + } } void GxsForumsDialog::changedViewBox() { - if (m_bProcessSettings) { - return; - } + if (m_bProcessSettings) { + return; + } - // save index - Settings->setValueToGroup("GxsForumsDialog", "viewBox", ui.viewBox->currentIndex()); + // save index + Settings->setValueToGroup("GxsForumsDialog", "viewBox", ui.viewBox->currentIndex()); - insertThreads(); + insertThreads(); } -void GxsForumsDialog::filterColumnChanged() +void GxsForumsDialog::filterColumnChanged(int column) { - if (m_bProcessSettings) { - return; - } + if (m_bProcessSettings) { + return; + } - int filterColumn = FilterColumnFromComboBox(ui.filterColumnComboBox->currentIndex()); - if (filterColumn == COLUMN_THREAD_CONTENT) { - // need content ... refill - insertThreads(); - } else { - filterItems(ui.filterLineEdit->text()); - } + if (column == COLUMN_THREAD_CONTENT) { + // need content ... refill + insertThreads(); + } else { + filterItems(ui.filterLineEdit->text()); + } - // save index - Settings->setValueToGroup("GxsForumsDialog", "filterColumn", filterColumn); + // save index + Settings->setValueToGroup("GxsForumsDialog", "filterColumn", column); } void GxsForumsDialog::filterItems(const QString& text) { - int filterColumn = FilterColumnFromComboBox(ui.filterColumnComboBox->currentIndex()); +//#AFTER MERGE int filterColumn = ui.filterLineEdit->currentFilter(); + int filterColumn = COLUMN_THREAD_TITLE; - int nCount = ui.threadTreeWidget->topLevelItemCount (); - for (int nIndex = 0; nIndex < nCount; nIndex++) { - filterItem(ui.threadTreeWidget->topLevelItem(nIndex), text, filterColumn); - } + int nCount = ui.threadTreeWidget->topLevelItemCount (); + for (int nIndex = 0; nIndex < nCount; nIndex++) { + filterItem(ui.threadTreeWidget->topLevelItem(nIndex), text, filterColumn); + } } void GxsForumsDialog::shareKey() { - ShareKey shareUi(this, 0, mCurrForumId, FORUM_KEY_SHARE); - shareUi.exec(); + ShareKey shareUi(this, 0, mCurrForumId, FORUM_KEY_SHARE); + shareUi.exec(); } bool GxsForumsDialog::filterItem(QTreeWidgetItem *pItem, const QString &text, int filterColumn) { - bool bVisible = true; + bool bVisible = true; - if (text.isEmpty() == false) { - if (pItem->text(filterColumn).contains(text, Qt::CaseInsensitive) == false) { - bVisible = false; - } - } + if (text.isEmpty() == false) { + if (pItem->text(filterColumn).contains(text, Qt::CaseInsensitive) == false) { + bVisible = false; + } + } - int nVisibleChildCount = 0; - int nCount = pItem->childCount(); - for (int nIndex = 0; nIndex < nCount; nIndex++) { - if (filterItem(pItem->child(nIndex), text, filterColumn)) { - nVisibleChildCount++; - } - } + int nVisibleChildCount = 0; + int nCount = pItem->childCount(); + for (int nIndex = 0; nIndex < nCount; nIndex++) { + if (filterItem(pItem->child(nIndex), text, filterColumn)) { + nVisibleChildCount++; + } + } - if (bVisible || nVisibleChildCount) { - pItem->setHidden(false); - } else { - pItem->setHidden(true); - } + if (bVisible || nVisibleChildCount) { + pItem->setHidden(false); + } else { + pItem->setHidden(true); + } - return (bVisible || nVisibleChildCount); + return (bVisible || nVisibleChildCount); } void GxsForumsDialog::updateMessageSummaryList(std::string forumId) { - QTreeWidgetItem *items[2] = { yourForums, subscribedForums }; + QTreeWidgetItem *items[2] = { yourForums, subscribedForums }; - for (int item = 0; item < 2; item++) { - int child; - int childCount = items[item]->childCount(); - for (child = 0; child < childCount; child++) { - QTreeWidgetItem *childItem = items[item]->child(child); - std::string childId = ui.forumTreeWidget->itemId(childItem).toStdString(); - if (childId.empty()) { - continue; - } + for (int item = 0; item < 2; item++) { + int child; + int childCount = items[item]->childCount(); + for (child = 0; child < childCount; child++) { + QTreeWidgetItem *childItem = items[item]->child(child); + std::string childId = ui.forumTreeWidget->itemId(childItem).toStdString(); + if (childId.empty()) { + continue; + } - if (forumId.empty() || childId == forumId) { - /* calculate unread messages */ - unsigned int newMessageCount = 0; - unsigned int unreadMessageCount = 0; - //rsGxsForums->getMessageCount(childId, newMessageCount, unreadMessageCount); - std::cerr << "IMPLEMENT rsGxsForums->getMessageCount()"; - std::cerr << std::endl; + if (forumId.empty() || childId == forumId) { + /* calculate unread messages */ + unsigned int newMessageCount = 0; + unsigned int unreadMessageCount = 0; - ui.forumTreeWidget->setUnreadCount(childItem, unreadMessageCount); + //rsGxsForums->getMessageCount(childId, newMessageCount, unreadMessageCount); - if (forumId.empty() == false) { - /* Calculate only this forum */ - break; - } - } - } - } + std::cerr << "IMPLEMENT rsGxsForums->getMessageCount()"; + std::cerr << std::endl; + + ui.forumTreeWidget->setUnreadCount(childItem, unreadMessageCount); + + if (forumId.empty() == false) { + /* Calculate only this forum */ + break; + } + } + } + } } bool GxsForumsDialog::navigate(const std::string& forumId, const std::string& msgId) { - if (forumId.empty()) { - return false; - } + if (forumId.empty()) { + return false; + } - if (ui.forumTreeWidget->activateId(QString::fromStdString(forumId), msgId.empty()) == NULL) { - return false; - } + if (ui.forumTreeWidget->activateId(QString::fromStdString(forumId), msgId.empty()) == NULL) { + return false; + } - /* Threads are filled in changedForum */ - if (mCurrForumId != forumId) { - return false; - } + /* Threads are filled in changedForum */ + if (mCurrForumId != forumId) { + return false; + } - if (msgId.empty()) { - return true; - } + if (msgId.empty()) { + return true; + } - if (mThreadLoading) { - mThreadLoad.FocusMsgId = msgId; - return true; - } + if (mThreadLoading) { + mThreadLoad.FocusMsgId = msgId; + return true; + } - /* Search exisiting item */ - QTreeWidgetItemIterator itemIterator(ui.threadTreeWidget); - QTreeWidgetItem *item = NULL; - while ((item = *itemIterator) != NULL) { - itemIterator++; + /* Search exisiting item */ + QTreeWidgetItemIterator itemIterator(ui.threadTreeWidget); + QTreeWidgetItem *item = NULL; + while ((item = *itemIterator) != NULL) { + itemIterator++; - if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString() == msgId) { - ui.threadTreeWidget->setCurrentItem(item); - ui.threadTreeWidget->setFocus(); - return true; - } - } + if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString() == msgId) { + ui.threadTreeWidget->setCurrentItem(item); + ui.threadTreeWidget->setFocus(); + return true; + } + } - return false; + return false; } void GxsForumsDialog::generateMassData() { #ifdef DEBUG_FORUMS - if (mCurrForumId.empty ()) { - return; - } + if (mCurrForumId.empty ()) { + return; + } - if (QMessageBox::question(this, "Generate mass data", "Do you really want to generate mass data ?", QMessageBox::Yes|QMessageBox::No, QMessageBox::No) == QMessageBox::No) { - return; - } + if (QMessageBox::question(this, "Generate mass data", "Do you really want to generate mass data ?", QMessageBox::Yes|QMessageBox::No, QMessageBox::No) == QMessageBox::No) { + return; + } - for (int thread = 1; thread < 1000; thread++) { - ForumMsgInfo threadInfo; - threadInfo.forumId = mCurrForumId; - threadInfo.title = QString("Test %1").arg(thread, 3, 10, QChar('0')).toStdWString(); - threadInfo.msg = QString("That is only a test").toStdWString(); + for (int thread = 1; thread < 1000; thread++) { + ForumMsgInfo threadInfo; + threadInfo.forumId = mCurrForumId; + threadInfo.title = QString("Test %1").arg(thread, 3, 10, QChar('0')).toStdWString(); + threadInfo.msg = QString("That is only a test").toStdWString(); - if (rsGxsForums->ForumMessageSend(threadInfo) == false) { - return; - } + if (rsGxsForums->ForumMessageSend(threadInfo) == false) { + return; + } - for (int msg = 1; msg < 3; msg++) { - ForumMsgInfo msgInfo; - msgInfo.forumId = mCurrForumId; - msgInfo.threadId = threadInfo.msgId; - msgInfo.parentId = threadInfo.msgId; - msgInfo.title = threadInfo.title; - msgInfo.msg = threadInfo.msg; + for (int msg = 1; msg < 3; msg++) { + ForumMsgInfo msgInfo; + msgInfo.forumId = mCurrForumId; + msgInfo.threadId = threadInfo.msgId; + msgInfo.parentId = threadInfo.msgId; + msgInfo.title = threadInfo.title; + msgInfo.msg = threadInfo.msg; - if (rsGxsForums->ForumMessageSend(msgInfo) == false) { - return; - } - } - } + if (rsGxsForums->ForumMessageSend(msgInfo) == false) { + return; + } + } + } #endif } - - /*********************** **** **** **** ***********************/ /** Request / Response of Data ********************************/ /*********************** **** **** **** ***********************/ @@ -1895,73 +1874,71 @@ void GxsForumsDialog::insertForums() void GxsForumsDialog::requestGroupSummary() { - std::cerr << "GxsForumsDialog::requestGroupSummary()"; - std::cerr << std::endl; + std::cerr << "GxsForumsDialog::requestGroupSummary()"; + std::cerr << std::endl; - RsTokReqOptions opts; + RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; uint32_t token; - mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, FORUMSV2DIALOG_LISTING); + mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, FORUMSV2DIALOG_LISTING); } void GxsForumsDialog::loadGroupSummary(const uint32_t &token) { - std::cerr << "GxsForumsDialog::loadGroupSummary()"; - std::cerr << std::endl; + std::cerr << "GxsForumsDialog::loadGroupSummary()"; + std::cerr << std::endl; - std::list groupInfo; - rsGxsForums->getGroupSummary(token, groupInfo); + std::list groupInfo; + rsGxsForums->getGroupSummary(token, groupInfo); - if (groupInfo.size() > 0) - { + if (groupInfo.size() > 0) + { insertForumsData(groupInfo); - } - else - { - std::cerr << "GxsForumsDialog::loadGroupSummary() ERROR No Groups..."; - std::cerr << std::endl; - } + } + else + { + std::cerr << "GxsForumsDialog::loadGroupSummary() ERROR No Groups..."; + std::cerr << std::endl; + } } /*********************** **** **** **** ***********************/ /*********************** **** **** **** ***********************/ - - void GxsForumsDialog::requestGroupSummary_CurrentForum(const std::string &forumId) { RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; - + std::list grpIds; grpIds.push_back(forumId); - std::cerr << "GxsForumsDialog::requestGroupSummary_CurrentForum(" << forumId << ")"; - std::cerr << std::endl; + std::cerr << "GxsForumsDialog::requestGroupSummary_CurrentForum(" << forumId << ")"; + std::cerr << std::endl; - uint32_t token; + uint32_t token; mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, FORUMSV2DIALOG_CURRENTFORUM); } void GxsForumsDialog::loadGroupSummary_CurrentForum(const uint32_t &token) { - std::cerr << "GxsForumsDialog::loadGroupSummary_CurrentForum()"; - std::cerr << std::endl; + std::cerr << "GxsForumsDialog::loadGroupSummary_CurrentForum()"; + std::cerr << std::endl; - std::list groupInfo; - rsGxsForums->getGroupSummary(token, groupInfo); + std::list groupInfo; + rsGxsForums->getGroupSummary(token, groupInfo); - if (groupInfo.size() == 1) - { + if (groupInfo.size() == 1) + { RsGroupMetaData fi = groupInfo.front(); insertForumThreads(fi); - } - else - { - std::cerr << "GxsForumsDialog::loadGroupSummary_CurrentForum() ERROR Invalid Number of Groups..."; - std::cerr << std::endl; - } + } + else + { + std::cerr << "GxsForumsDialog::loadGroupSummary_CurrentForum() ERROR Invalid Number of Groups..."; + std::cerr << std::endl; + } } /*********************** **** **** **** ***********************/ @@ -1969,30 +1946,28 @@ void GxsForumsDialog::loadGroupSummary_CurrentForum(const uint32_t &token) /*********************** **** **** **** ***********************/ /*********************** **** **** **** ***********************/ - - void GxsForumsDialog::loadCurrentForumThreads(const std::string &forumId) { - std::cerr << "GxsForumsDialog::loadCurrentForumThreads(" << forumId << ")"; - std::cerr << std::endl; + std::cerr << "GxsForumsDialog::loadCurrentForumThreads(" << forumId << ")"; + std::cerr << std::endl; /* if already active -> kill current loading */ if (mThreadLoading) { /* Cleanup */ - std::cerr << "GxsForumsDialog::loadCurrentForumThreads() Cleanup old Threads"; - std::cerr << std::endl; + std::cerr << "GxsForumsDialog::loadCurrentForumThreads() Cleanup old Threads"; + std::cerr << std::endl; /* Wipe Widget Tree */ mThreadLoad.Items.clear(); - + /* Stop all active requests */ std::map::iterator it; for(it = mThreadLoad.MsgTokens.begin(); it != mThreadLoad.MsgTokens.end(); it++) { - std::cerr << "GxsForumsDialog::loadCurrentForumThreads() Canceling Request: " << it->first; - std::cerr << std::endl; + std::cerr << "GxsForumsDialog::loadCurrentForumThreads() Canceling Request: " << it->first; + std::cerr << std::endl; mForumQueue->cancelRequest(it->first); } @@ -2002,22 +1977,23 @@ void GxsForumsDialog::loadCurrentForumThreads(const std::string &forumId) } /* initiate loading */ - std::cerr << "GxsForumsDialog::loadCurrentForumThreads() Initiating Loading"; - std::cerr << std::endl; + std::cerr << "GxsForumsDialog::loadCurrentForumThreads() Initiating Loading"; + std::cerr << std::endl; mThreadLoading = true; mThreadLoad.ForumId = mCurrForumId; - mThreadLoad.FilterColumn = FilterColumnFromComboBox(ui.filterColumnComboBox->currentIndex()); - mThreadLoad.ViewType = ui.viewBox->currentIndex(); +//#AFTER MERGE mThreadLoad.FilterColumn = ui.filterLineEdit->currentFilter(); + mThreadLoad.FilterColumn = COLUMN_THREAD_TITLE; + mThreadLoad.ViewType = ui.viewBox->currentIndex(); mThreadLoad.FillComplete = false; - if (lastViewType != mThreadLoad.ViewType || lastForumID != mCurrForumId) { - mThreadLoad.FillComplete = true; - } + if (lastViewType != mThreadLoad.ViewType || lastForumID != mCurrForumId) { + mThreadLoad.FillComplete = true; + } - mThreadLoad.FlatView = false; - mThreadLoad.UseChildTS = false; + mThreadLoad.FlatView = false; + mThreadLoad.UseChildTS = false; mThreadLoad.ExpandNewMessages = Settings->getExpandNewMessages(); mThreadLoad.SubscribeFlags = subscribeFlags; @@ -2028,56 +2004,53 @@ void GxsForumsDialog::loadCurrentForumThreads(const std::string &forumId) } switch(mThreadLoad.ViewType) - { - case VIEW_LAST_POST: + { + case VIEW_LAST_POST: mThreadLoad.UseChildTS = true; - break; - case VIEW_FLAT: + break; + case VIEW_FLAT: mThreadLoad.FlatView = true; - break; - case VIEW_THREADED: - break; + break; + case VIEW_THREADED: + break; } requestGroupThreadData_InsertThreads(forumId); } - - void GxsForumsDialog::requestGroupThreadData_InsertThreads(const std::string &forumId) { RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; - + std::list grpIds; grpIds.push_back(forumId); - std::cerr << "GxsForumsDialog::requestGroupThreadData_InsertThreads(" << forumId << ")"; - std::cerr << std::endl; + std::cerr << "GxsForumsDialog::requestGroupThreadData_InsertThreads(" << forumId << ")"; + std::cerr << std::endl; - uint32_t token; + uint32_t token; mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, FORUMSV2DIALOG_INSERTTHREADS); } - void GxsForumsDialog::loadGroupThreadData_InsertThreads(const uint32_t &token) { std::cerr << "GxsForumsDialog::loadGroupThreadData_InsertThreads()"; std::cerr << std::endl; - + bool someData = false; - std::vector msgs; - std::vector::iterator vit; - if (rsGxsForums->getMsgData(token, msgs)) + std::vector msgs; + std::vector::iterator vit; + if (rsGxsForums->getMsgData(token, msgs)) { for(vit = msgs.begin(); vit != msgs.end(); vit++) { std::cerr << "GxsForumsDialog::loadGroupThreadData_InsertThreads() MsgId: " << vit->mMeta.mMsgId; std::cerr << std::endl; - + loadForumBaseThread(*vit); someData = true; } @@ -2090,93 +2063,95 @@ void GxsForumsDialog::loadGroupThreadData_InsertThreads(const uint32_t &token) } } -bool GxsForumsDialog::convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, - bool useChildTS, uint32_t filterColumn, GxsIdTreeWidgetItem *item) +bool GxsForumsDialog::convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, bool useChildTS, uint32_t filterColumn, GxsIdTreeWidgetItem *item) { - QString text; + QString text; - { - QDateTime qtime; - if (useChildTS) - qtime.setTime_t(msgInfo.mMeta.mChildTs); - else - qtime.setTime_t(msgInfo.mMeta.mPublishTs); + { + QDateTime qtime; + QString sort; - text = qtime.toString("yyyy-MM-dd hh:mm:ss"); - if (useChildTS) - { - QDateTime qtime2; - qtime2.setTime_t(msgInfo.mMeta.mPublishTs); - QString timestamp2 = qtime2.toString("yyyy-MM-dd hh:mm:ss"); - text += " / "; - text += timestamp2; - } - item->setText(COLUMN_THREAD_DATE, text); - } + if (useChildTS) + qtime.setTime_t(msgInfo.mMeta.mChildTs); + else + qtime.setTime_t(msgInfo.mMeta.mPublishTs); - item->setText(COLUMN_THREAD_TITLE, GxsForumsDialog::titleFromInfo(msgInfo.mMeta)); +//#AFTER MERGE text = DateTime::formatDateTime(qtime); + sort = qtime.toString("yyyyMMdd_hhmmss"); + + if (useChildTS) + { + qtime.setTime_t(msgInfo.mMeta.mPublishTs); + text += " / "; +//#AFTER MERGE text += DateTime::formatDateTime(qtime); + sort += "_" + qtime.toString("yyyyMMdd_hhmmss"); + } + item->setText(COLUMN_THREAD_DATE, text); + item->setData(COLUMN_THREAD_DATE, ROLE_THREAD_SORT, sort); + } + + item->setText(COLUMN_THREAD_TITLE, GxsForumsDialog::titleFromInfo(msgInfo.mMeta)); item->setId(msgInfo.mMeta.mAuthorId, COLUMN_THREAD_AUTHOR); #if 0 - text = QString::fromUtf8(authorName.c_str()); + text = QString::fromUtf8(authorName.c_str()); - if (text.isEmpty()) - { - item->setText(COLUMN_THREAD_AUTHOR, tr("Anonymous")); - } - else - { - item->setText(COLUMN_THREAD_AUTHOR, text); - } + if (text.isEmpty()) + { + item->setText(COLUMN_THREAD_AUTHOR, tr("Anonymous")); + } + else + { + item->setText(COLUMN_THREAD_AUTHOR, text); + } #endif #ifdef TOGXS - if (msgInfo.mMeta.mMsgFlags & RS_DISTRIB_AUTHEN_REQ) - { - item->setText(COLUMN_THREAD_SIGNED, tr("signed")); - item->setIcon(COLUMN_THREAD_SIGNED, QIcon(":/images/mail-signed.png")); - } - else - { - item->setText(COLUMN_THREAD_SIGNED, tr("none")); - item->setIcon(COLUMN_THREAD_SIGNED, QIcon(":/images/mail-signature-unknown.png")); - } + if (msgInfo.mMeta.mMsgFlags & RS_DISTRIB_AUTHEN_REQ) + { + item->setText(COLUMN_THREAD_SIGNED, tr("signed")); + item->setIcon(COLUMN_THREAD_SIGNED, QIcon(":/images/mail-signed.png")); + } + else + { + item->setText(COLUMN_THREAD_SIGNED, tr("none")); + item->setIcon(COLUMN_THREAD_SIGNED, QIcon(":/images/mail-signature-unknown.png")); + } #endif - if (filterColumn == COLUMN_THREAD_CONTENT) { - // need content for filter - QTextDocument doc; - doc.setHtml(QString::fromUtf8(msgInfo.mMsg.c_str())); - item->setText(COLUMN_THREAD_CONTENT, doc.toPlainText().replace(QString("\n"), QString(" "))); - } + if (filterColumn == COLUMN_THREAD_CONTENT) { + // need content for filter + QTextDocument doc; + doc.setHtml(QString::fromUtf8(msgInfo.mMsg.c_str())); + item->setText(COLUMN_THREAD_CONTENT, doc.toPlainText().replace(QString("\n"), QString(" "))); + } - item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID, QString::fromStdString(msgInfo.mMeta.mMsgId)); + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID, QString::fromStdString(msgInfo.mMeta.mMsgId)); #if 0 - if (IS_GROUP_SUBSCRIBED(subscribeFlags) && !(msginfo.mMsgFlags & RS_DISTRIB_MISSING_MSG)) { - rsGxsForums->getMessageStatus(msginfo.forumId, msginfo.msgId, status); - } else { - // show message as read - status = RSGXS_MSG_STATUS_READ; - } + if (IS_GROUP_SUBSCRIBED(subscribeFlags) && !(msginfo.mMsgFlags & RS_DISTRIB_MISSING_MSG)) { + rsGxsForums->getMessageStatus(msginfo.forumId, msginfo.msgId, status); + } else { + // show message as read + status = RSGXS_MSG_STATUS_READ; + } #endif - item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, msgInfo.mMeta.mMsgStatus); + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, msgInfo.mMeta.mMsgStatus); #ifdef TOGXS - item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING, (msgInfo.mMeta.mMsgFlags & RS_DISTRIB_MISSING_MSG) ? true : false); + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING, (msgInfo.mMeta.mMsgFlags & RS_DISTRIB_MISSING_MSG) ? true : false); #endif return true; } - void GxsForumsDialog::loadForumBaseThread(const RsGxsForumMsg &msg) { - //std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); - - //QTreeWidgetItem *item = new QTreeWidgetItem(); // no Parent. - GxsIdTreeWidgetItem *item = new GxsIdTreeWidgetItem(); // no Parent. - + //std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); + + //QTreeWidgetItem *item = new QTreeWidgetItem(); // no Parent. + GxsIdTreeWidgetItem *item = new GxsIdTreeWidgetItem(threadCompareRole); // no Parent. + //convertMsgToThreadWidget(msg, authorName, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, item); convertMsgToThreadWidget(msg, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, item); @@ -2189,11 +2164,9 @@ void GxsForumsDialog::loadForumBaseThread(const RsGxsForumMsg &msg) mThreadLoad.MsgTokens[token] = item; /* add item to final tree */ - mThreadLoad.Items.append(item); + mThreadLoad.Items.append(item); } - - /*********************** **** **** **** ***********************/ void GxsForumsDialog::requestChildData_InsertThreads(uint32_t &token, const RsGxsGrpMsgIdPair &parentId) @@ -2201,20 +2174,19 @@ void GxsForumsDialog::requestChildData_InsertThreads(uint32_t &token, const RsGx RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; opts.mOptions = RS_TOKREQOPT_MSG_PARENT | RS_TOKREQOPT_MSG_LATEST; - - std::cerr << "GxsForumsDialog::requestChildData_InsertThreads(" << parentId.first << "," << parentId.second << ")"; - std::cerr << std::endl; - std::vector msgIds; - msgIds.push_back(parentId); - mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMSV2DIALOG_INSERTCHILD); + std::cerr << "GxsForumsDialog::requestChildData_InsertThreads(" << parentId.first << "," << parentId.second << ")"; + std::cerr << std::endl; + + std::vector msgIds; + msgIds.push_back(parentId); + mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMSV2DIALOG_INSERTCHILD); } - void GxsForumsDialog::loadChildData_InsertThreads(const uint32_t &token) { - std::cerr << "GxsForumsDialog::loadChildData_InsertThreads()"; - std::cerr << std::endl; + std::cerr << "GxsForumsDialog::loadChildData_InsertThreads()"; + std::cerr << std::endl; /* find the matching *item */ std::map::iterator it; @@ -2234,15 +2206,15 @@ void GxsForumsDialog::loadChildData_InsertThreads(const uint32_t &token) std::cerr << "GxsForumsDialog::loadChildData_InsertThreads()"; std::cerr << std::endl; - std::vector msgs; - std::vector::iterator vit; - if (rsGxsForums->getRelatedMessages(token, msgs)) + std::vector msgs; + std::vector::iterator vit; + if (rsGxsForums->getRelatedMessages(token, msgs)) { for(vit = msgs.begin(); vit != msgs.end(); vit++) { std::cerr << "GxsForumsDialog::loadChildData_InsertThreads() MsgId: " << vit->mMeta.mMsgId; std::cerr << std::endl; - + loadForumChildMsg(*vit, parent); } } @@ -2263,21 +2235,20 @@ void GxsForumsDialog::loadChildData_InsertThreads(const uint32_t &token) void GxsForumsDialog::loadForumChildMsg(const RsGxsForumMsg &msg, QTreeWidgetItem *parent) { - //std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); + //std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); //QTreeWidgetItem *child = NULL; GxsIdTreeWidgetItem *child = NULL; if (mThreadLoad.FlatView) { - child = new GxsIdTreeWidgetItem(); // no Parent. + child = new GxsIdTreeWidgetItem(threadCompareRole); // no Parent. } else { - child = new GxsIdTreeWidgetItem(parent); + child = new GxsIdTreeWidgetItem(threadCompareRole, parent); } - convertMsgToThreadWidget(msg, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, child); //convertMsgToThreadWidget(msg, authorName, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, child); @@ -2290,12 +2261,12 @@ void GxsForumsDialog::loadForumChildMsg(const RsGxsForumMsg &msg, QTreeWidgetIte mThreadLoad.MsgTokens[token] = child; // Leave this here... BUT IT WILL NEED TO BE FIXED. - if (mThreadLoad.FillComplete && mThreadLoad.ExpandNewMessages && IS_MSG_UNREAD(msg.mMeta.mMsgStatus)) + if (mThreadLoad.FillComplete && mThreadLoad.ExpandNewMessages && IS_MSG_UNREAD(msg.mMeta.mMsgStatus)) { QTreeWidgetItem *pParent = child; - while ((pParent = pParent->parent()) != NULL) + while ((pParent = pParent->parent()) != NULL) { - if (std::find(mThreadLoad.ItemToExpand.begin(), mThreadLoad.ItemToExpand.end(), pParent) == mThreadLoad.ItemToExpand.end()) + if (std::find(mThreadLoad.ItemToExpand.begin(), mThreadLoad.ItemToExpand.end(), pParent) == mThreadLoad.ItemToExpand.end()) { mThreadLoad.ItemToExpand.push_back(pParent); } @@ -2305,12 +2276,10 @@ void GxsForumsDialog::loadForumChildMsg(const RsGxsForumMsg &msg, QTreeWidgetIte if (mThreadLoad.FlatView) { /* add item to final tree */ - mThreadLoad.Items.append(child); + mThreadLoad.Items.append(child); } } - - /*********************** **** **** **** ***********************/ /*********************** **** **** **** ***********************/ @@ -2319,59 +2288,57 @@ void GxsForumsDialog::requestMsgData_InsertPost(const RsGxsGrpMsgIdPair &msgId) #if 0 RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; - - std::cerr << "GxsForumsDialog::requestMsgData_InsertPost(" << msgId.first << "," << msgId.second << ")"; - std::cerr << std::endl; - std::vector msgIds; - msgIds.push_back(msgId); - uint32_t token; - mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_INSERT_POST); + std::cerr << "GxsForumsDialog::requestMsgData_InsertPost(" << msgId.first << "," << msgId.second << ")"; + std::cerr << std::endl; + + std::vector msgIds; + msgIds.push_back(msgId); + uint32_t token; + mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_INSERT_POST); #else RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - - std::cerr << "GxsForumsDialog::requestMsgData_InsertPost(" << msgId.first << "," << msgId.second << ")"; - std::cerr << std::endl; + + std::cerr << "GxsForumsDialog::requestMsgData_InsertPost(" << msgId.first << "," << msgId.second << ")"; + std::cerr << std::endl; GxsMsgReq msgIds; - std::vector &vect = msgIds[msgId.first]; - vect.push_back(msgId.second); + std::vector &vect = msgIds[msgId.first]; + vect.push_back(msgId.second); - uint32_t token; - mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_INSERT_POST); + uint32_t token; + mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_INSERT_POST); #endif } - void GxsForumsDialog::loadMsgData_InsertPost(const uint32_t &token) { - std::cerr << "GxsForumsDialog::loadMsgData_InsertPost()"; - std::cerr << std::endl; + std::cerr << "GxsForumsDialog::loadMsgData_InsertPost()"; + std::cerr << std::endl; - std::vector msgs; + std::vector msgs; #if 0 - if (rsGxsForums->getRelatedMessages(token, msgs)) + if (rsGxsForums->getRelatedMessages(token, msgs)) #else - if (rsGxsForums->getMsgData(token, msgs)) + if (rsGxsForums->getMsgData(token, msgs)) #endif { if (msgs.size() != 1) { - std::cerr << "GxsForumsDialog::loadMsgData_InsertPost() ERROR Wrong number of answers"; - std::cerr << std::endl; + std::cerr << "GxsForumsDialog::loadMsgData_InsertPost() ERROR Wrong number of answers"; + std::cerr << std::endl; return; } insertPostData(msgs[0]); } - else - { - std::cerr << "GxsForumsDialog::loadMsgData_InsertPost() ERROR Missing Message Data..."; - std::cerr << std::endl; - } + else + { + std::cerr << "GxsForumsDialog::loadMsgData_InsertPost() ERROR Missing Message Data..."; + std::cerr << std::endl; + } } - /*********************** **** **** **** ***********************/ /*********************** **** **** **** ***********************/ @@ -2380,139 +2347,102 @@ void GxsForumsDialog::requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId #if 0 RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; - - std::cerr << "GxsForumsDialog::requestMsgData_ReplyMessage(" << msgId.first << "," << msgId.second << ")"; - std::cerr << std::endl; - std::vector msgIds; - msgIds.push_back(msgId); - uint32_t token; - mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_REPLY_MESSAGE); + std::cerr << "GxsForumsDialog::requestMsgData_ReplyMessage(" << msgId.first << "," << msgId.second << ")"; + std::cerr << std::endl; + + std::vector msgIds; + msgIds.push_back(msgId); + uint32_t token; + mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_REPLY_MESSAGE); #else RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - - std::cerr << "GxsForumsDialog::requestMsgData_ReplyMessage(" << msgId.first << "," << msgId.second << ")"; - std::cerr << std::endl; + + std::cerr << "GxsForumsDialog::requestMsgData_ReplyMessage(" << msgId.first << "," << msgId.second << ")"; + std::cerr << std::endl; GxsMsgReq msgIds; - std::vector &vect = msgIds[msgId.first]; - vect.push_back(msgId.second); + std::vector &vect = msgIds[msgId.first]; + vect.push_back(msgId.second); - uint32_t token; - mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_REPLY_MESSAGE); + uint32_t token; + mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_REPLY_MESSAGE); #endif - } - void GxsForumsDialog::loadMsgData_ReplyMessage(const uint32_t &token) { - std::cerr << "GxsForumsDialog::loadMsgData_ReplyMessage()"; - std::cerr << std::endl; + std::cerr << "GxsForumsDialog::loadMsgData_ReplyMessage()"; + std::cerr << std::endl; - std::vector msgs; + std::vector msgs; #if 0 - if (rsGxsForums->getRelatedMessages(token, msgs)) + if (rsGxsForums->getRelatedMessages(token, msgs)) #else - if (rsGxsForums->getMsgData(token, msgs)) + if (rsGxsForums->getMsgData(token, msgs)) #endif { if (msgs.size() != 1) { - std::cerr << "GxsForumsDialog::loadMsgData_ReplyMessage() ERROR Wrong number of answers"; - std::cerr << std::endl; + std::cerr << "GxsForumsDialog::loadMsgData_ReplyMessage() ERROR Wrong number of answers"; + std::cerr << std::endl; return; } replyMessageData(msgs[0]); } - else - { - std::cerr << "GxsForumsDialog::loadMsgData_ReplyMessage() ERROR Missing Message Data..."; - std::cerr << std::endl; - } + else + { + std::cerr << "GxsForumsDialog::loadMsgData_ReplyMessage() ERROR Missing Message Data..."; + std::cerr << std::endl; + } } - +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ /*********************** **** **** **** ***********************/ /*********************** **** **** **** ***********************/ - - -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ - void GxsForumsDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) { std::cerr << "GxsForumsDialog::loadRequest() UserType: " << req.mUserType; std::cerr << std::endl; - + if (queue == mForumQueue) { /* now switch on req */ switch(req.mUserType) { - case FORUMSV2DIALOG_LISTING: - loadGroupSummary(req.mToken); - break; + case FORUMSV2DIALOG_LISTING: + loadGroupSummary(req.mToken); + break; - case FORUMSV2DIALOG_CURRENTFORUM: - loadGroupSummary_CurrentForum(req.mToken); - break; + case FORUMSV2DIALOG_CURRENTFORUM: + loadGroupSummary_CurrentForum(req.mToken); + break; - case FORUMSV2DIALOG_INSERTTHREADS: - loadGroupThreadData_InsertThreads(req.mToken); - break; + case FORUMSV2DIALOG_INSERTTHREADS: + loadGroupThreadData_InsertThreads(req.mToken); + break; - case FORUMSV2DIALOG_INSERTCHILD: - loadChildData_InsertThreads(req.mToken); - break; + case FORUMSV2DIALOG_INSERTCHILD: + loadChildData_InsertThreads(req.mToken); + break; - case FORUMV2DIALOG_INSERT_POST: - loadMsgData_InsertPost(req.mToken); - break; + case FORUMV2DIALOG_INSERT_POST: + loadMsgData_InsertPost(req.mToken); + break; - case FORUMV2DIALOG_REPLY_MESSAGE: - loadMsgData_ReplyMessage(req.mToken); - break; + case FORUMV2DIALOG_REPLY_MESSAGE: + loadMsgData_ReplyMessage(req.mToken); + break; - default: - std::cerr << "GxsForumsDialog::loadRequest() ERROR: INVALID TYPE"; - std::cerr << std::endl; - break; + default: + std::cerr << "GxsForumsDialog::loadRequest() ERROR: INVALID TYPE"; + std::cerr << std::endl; + break; } } } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/retroshare-gui/src/gui/GxsForumsDialog.h b/retroshare-gui/src/gui/GxsForumsDialog.h index f80769575..d74601faf 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.h +++ b/retroshare-gui/src/gui/GxsForumsDialog.h @@ -45,112 +45,126 @@ class ForumInfo; class GxsForumsThreadLoadParameters { - public: - - std::string ForumId; - std::string FocusMsgId; +public: + std::string ForumId; + std::string FocusMsgId; - uint32_t SubscribeFlags; - int ViewType; - uint32_t FilterColumn; - - std::map MsgTokens; - QList Items; - QList ItemToExpand; - - bool FillComplete; - bool FlatView; - bool UseChildTS; - bool ExpandNewMessages; + uint32_t SubscribeFlags; + int ViewType; + uint32_t FilterColumn; + + std::map MsgTokens; + QList Items; + QList ItemToExpand; + + bool FillComplete; + bool FlatView; + bool UseChildTS; + bool ExpandNewMessages; }; - - - - - class GxsForumsDialog : public RsAutoUpdatePage, public TokenResponse { - Q_OBJECT + Q_OBJECT + + Q_PROPERTY(QColor textColorRead READ textColorRead WRITE setTextColorRead) + Q_PROPERTY(QColor textColorUnread READ textColorUnread WRITE setTextColorUnread) + Q_PROPERTY(QColor textColorUnreadChildren READ textColorUnreadChildren WRITE setTextColorUnreadChildren) + Q_PROPERTY(QColor textColorNotSubscribed READ textColorNotSubscribed WRITE setTextColorNotSubscribed) + Q_PROPERTY(QColor textColorMissing READ textColorMissing WRITE setTextColorMissing) public: - GxsForumsDialog(QWidget *parent = 0); - ~GxsForumsDialog(); + GxsForumsDialog(QWidget *parent = 0); + ~GxsForumsDialog(); - bool navigate(const std::string& forumId, const std::string& msgId); +//#AFTER MERGE virtual UserNotify *getUserNotify(QObject *parent); - /* overloaded from RsAuthUpdatePage */ - virtual void updateDisplay(); + bool navigate(const std::string& forumId, const std::string& msgId); + + /* overloaded from RsAuthUpdatePage */ + virtual void updateDisplay(); // Callback for all Loads. -virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); + virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); + + QColor textColorRead() const { return mTextColorRead; } + QColor textColorUnread() const { return mTextColorUnread; } + QColor textColorUnreadChildren() const { return mTextColorUnreadChildren; } + QColor textColorNotSubscribed() const { return mTextColorNotSubscribed; } + QColor textColorMissing() const { return mTextColorMissing; } + + void setTextColorRead(QColor color) { mTextColorRead = color; } + void setTextColorUnread(QColor color) { mTextColorUnread = color; } + void setTextColorUnreadChildren(QColor color) { mTextColorUnreadChildren = color; } + void setTextColorNotSubscribed(QColor color) { mTextColorNotSubscribed = color; } + void setTextColorMissing(QColor color) { mTextColorMissing = color; } protected: - bool eventFilter(QObject *obj, QEvent *ev); + bool eventFilter(QObject *obj, QEvent *ev); + void changeEvent(QEvent *e); private slots: - void forceUpdateDisplay(); // TEMP HACK FN. + void forceUpdateDisplay(); // TEMP HACK FN. - /** Create the context popup menu and it's submenus */ - void forumListCustomPopupMenu( QPoint point ); - void threadListCustomPopupMenu( QPoint point ); - void restoreForumKeys(); - void newforum(); + /** Create the context popup menu and it's submenus */ + void forumListCustomPopupMenu( QPoint point ); + void threadListCustomPopupMenu( QPoint point ); + void restoreForumKeys(); + void newforum(); - void changedForum(const QString &id); - void changedThread(); - void clickedThread (QTreeWidgetItem *item, int column); + void changedForum(const QString &id); + void changedThread(); + void clickedThread (QTreeWidgetItem *item, int column); - void replytomessage(); + void replytomessage(); void replyMessageData(const RsGxsForumMsg &msg); - //void print(); - //void printpreview(); + //void print(); + //void printpreview(); - //void removemessage(); - void markMsgAsRead(); - void markMsgAsReadChildren(); - void markMsgAsReadAll(); - void markMsgAsUnread(); - void markMsgAsUnreadAll(); - void markMsgAsUnreadChildren(); - void copyForumLink(); - void copyMessageLink(); + //void removemessage(); + void markMsgAsRead(); + void markMsgAsReadChildren(); + void markMsgAsReadAll(); + void markMsgAsUnread(); + void markMsgAsUnreadAll(); + void markMsgAsUnreadChildren(); + void copyForumLink(); + void copyMessageLink(); - /* handle splitter */ - void togglethreadview(); + /* handle splitter */ + void togglethreadview(); - void createthread(); - void createmessage(); + void createthread(); + void createmessage(); - void subscribeToForum(); - void unsubscribeToForum(); + void subscribeToForum(); + void unsubscribeToForum(); - void showForumDetails(); - void editForumDetails(); + void showForumDetails(); + void editForumDetails(); - void previousMessage (); - void nextMessage (); - void nextUnreadMessage(); - void downloadAllFiles(); + void previousMessage (); + void nextMessage (); + void nextUnreadMessage(); + void downloadAllFiles(); - void changedViewBox(); + void changedViewBox(); - void filterColumnChanged(); - //void filterRegExpChanged(); - ///void clearFilter(); + void filterColumnChanged(int column); + void filterItems(const QString &text); - void generateMassData(); + void generateMassData(); - void fillThreadFinished(); - void fillThreadProgress(int current, int count); + void fillThreadFinished(); + void fillThreadProgress(int current, int count); - void shareKey(); + void shareKey(); private: - void insertForums(); - void insertThreads(); - void insertPost(); + void insertForums(); + void insertThreads(); + void insertPost(); void insertPostData(const RsGxsForumMsg &msg); // Second Half. // Utility Fns. @@ -159,25 +173,23 @@ private: void forumMsgReadStatusChanged(const QString &forumId, const QString &msgId, int status); - void updateMessageSummaryList(std::string forumId); - //void forumInfoToGroupItemInfo(const ForumInfo &forumInfo, GroupItemInfo &groupItemInfo); - void forumInfoToGroupItemInfo(const RsGroupMetaData &forumInfo, GroupItemInfo &groupItemInfo); + void updateMessageSummaryList(std::string forumId); +// void forumInfoToGroupItemInfo(const ForumInfo &forumInfo, GroupItemInfo &groupItemInfo); + void forumInfoToGroupItemInfo(const RsGroupMetaData &forumInfo, GroupItemInfo &groupItemInfo); - void forumSubscribe(bool subscribe); - void FillThreads(QList &ThreadList, bool bExpandNewMessages, QList &itemToExpand); - void FillChildren(QTreeWidgetItem *Parent, QTreeWidgetItem *NewParent, bool bExpandNewMessages, QList &itemToExpand); + void forumSubscribe(bool subscribe); + void FillThreads(QList &ThreadList, bool bExpandNewMessages, QList &itemToExpand); + void FillChildren(QTreeWidgetItem *Parent, QTreeWidgetItem *NewParent, bool bExpandNewMessages, QList &itemToExpand); - int getSelectedMsgCount(QList *pRows, QList *pRowsRead, QList *pRowsUnread); + int getSelectedMsgCount(QList *pRows, QList *pRowsRead, QList *pRowsUnread); + void setMsgReadStatus(QList &Rows, bool bRead); + void markMsgAsReadUnread(bool bRead, bool bChildren, bool bForum); + void CalculateIconsAndFonts(QTreeWidgetItem *pItem = NULL); + void CalculateIconsAndFonts(QTreeWidgetItem *pItem, bool &bHasReadChilddren, bool &bHasUnreadChilddren); - void setMsgReadStatus(QList &Rows, bool bRead); - void markMsgAsReadUnread(bool bRead, bool bChildren, bool bForum); - void CalculateIconsAndFonts(QTreeWidgetItem *pItem = NULL); - void CalculateIconsAndFonts(QTreeWidgetItem *pItem, bool &bHasReadChilddren, bool &bHasUnreadChilddren); + void processSettings(bool bLoad); + void togglethreadview_internal(); - void processSettings(bool bLoad); - void togglethreadview_internal(); - - void filterItems(const QString& text); bool filterItem(QTreeWidgetItem *pItem, const QString &text, int filterColumn); // New Request/Response Loading Functions. @@ -204,75 +216,40 @@ private: void requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId); void loadMsgData_ReplyMessage(const uint32_t &token); - bool convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, - bool useChildTS, uint32_t filterColumn, GxsIdTreeWidgetItem *item); - //bool convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, std::string authorName, - // bool useChildTS, uint32_t filterColumn, QTreeWidgetItem *item); + bool convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, bool useChildTS, uint32_t filterColumn, GxsIdTreeWidgetItem *item); +// bool convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, std::string authorName, bool useChildTS, uint32_t filterColumn, QTreeWidgetItem *item); TokenQueue *mForumQueue; - - bool m_bProcessSettings; - - QTreeWidgetItem *yourForums; - QTreeWidgetItem *subscribedForums; - QTreeWidgetItem *popularForums; - QTreeWidgetItem *otherForums; - - std::string mCurrForumId; - std::string mCurrThreadId; - int subscribeFlags; - - QFont m_ForumNameFont; - int lastViewType; - std::string lastForumID; - + bool m_bProcessSettings; bool inMsgAsReadUnread; - //GxsForumsFillThread *fillThread; - // New Datatypes to replace the FillThread. - bool mThreadLoading; - GxsForumsThreadLoadParameters mThreadLoad; - + QTreeWidgetItem *yourForums; + QTreeWidgetItem *subscribedForums; + QTreeWidgetItem *popularForums; + QTreeWidgetItem *otherForums; - /** Qt Designer generated object */ - Ui::GxsForumsDialog ui; -}; + RSTreeWidgetItemCompareRole *threadCompareRole; + std::string mCurrForumId; + std::string mCurrThreadId; + int subscribeFlags; -#if 0 -class GxsForumsFillThread : public QThread -{ - Q_OBJECT + int lastViewType; + std::string lastForumID; -public: - GxsForumsFillThread(GxsForumsDialog *parent); - ~GxsForumsFillThread(); + // New Datatypes to replace the FillThread. + bool mThreadLoading; + GxsForumsThreadLoadParameters mThreadLoad; - void run(); - void stop(); - bool wasStopped() { return stopped; } + /* Color definitions (for standard see qss.default) */ + QColor mTextColorRead; + QColor mTextColorUnread; + QColor mTextColorUnreadChildren; + QColor mTextColorNotSubscribed; + QColor mTextColorMissing; -signals: - void progress(int current, int count); - -public: - std::string forumId; - int filterColumn; - int subscribeFlags; - bool fillComplete; - int viewType; - bool expandNewMessages; - std::string focusMsgId; - - QList Items; - QList ItemToExpand; - -private: - volatile bool stopped; + /** Qt Designer generated object */ + Ui::GxsForumsDialog ui; }; #endif - - -#endif - diff --git a/retroshare-gui/src/gui/GxsForumsDialog.ui b/retroshare-gui/src/gui/GxsForumsDialog.ui index c3228a940..9d8f4d4dd 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.ui +++ b/retroshare-gui/src/gui/GxsForumsDialog.ui @@ -10,501 +10,6 @@ 420
- - - 0 - 2 - - - - - 60 - 0 - - - - - - - - - 0 - 0 - 0 - - - - - - - 208 - 208 - 208 - - - - - - - 255 - 255 - 255 - - - - - - - 247 - 247 - 247 - - - - - - - 104 - 104 - 104 - - - - - - - 139 - 139 - 139 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 240 - 240 - 240 - - - - - - - 0 - 0 - 0 - - - - - - - 0 - 0 - 128 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 255 - - - - - - - 255 - 0 - 255 - - - - - - - 231 - 231 - 231 - - - - - - - - - 0 - 0 - 0 - - - - - - - 208 - 208 - 208 - - - - - - - 255 - 255 - 255 - - - - - - - 247 - 247 - 247 - - - - - - - 104 - 104 - 104 - - - - - - - 139 - 139 - 139 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 240 - 240 - 240 - - - - - - - 0 - 0 - 0 - - - - - - - 192 - 192 - 192 - - - - - - - 0 - 0 - 0 - - - - - - - 0 - 0 - 255 - - - - - - - 255 - 0 - 255 - - - - - - - 231 - 231 - 231 - - - - - - - - - 104 - 104 - 104 - - - - - - - 208 - 208 - 208 - - - - - - - 255 - 255 - 255 - - - - - - - 247 - 247 - 247 - - - - - - - 104 - 104 - 104 - - - - - - - 139 - 139 - 139 - - - - - - - 104 - 104 - 104 - - - - - - - 255 - 255 - 255 - - - - - - - 104 - 104 - 104 - - - - - - - 240 - 240 - 240 - - - - - - - 240 - 240 - 240 - - - - - - - 0 - 0 - 0 - - - - - - - 0 - 0 - 128 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 255 - - - - - - - 255 - 0 - 255 - - - - - - - 231 - 231 - 231 - - - - - - - - - Arial - 8 - 50 - false - false - false - false - - - - Qt::DefaultContextMenu - 9 @@ -524,14 +29,8 @@ 300 - - QFrame#frame{border: none;} - - QFrame::StyledPanel - - - QFrame::Raised + QFrame::NoFrame @@ -541,70 +40,51 @@ 0 - - - QFrame#chheaderframe{ -background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #FEFEFE, stop:1 #E8E8E8); - -border: 1px solid #CCCCCC;} - - - + - QFrame::StyledPanel + QFrame::Box - QFrame::Raised + QFrame::Sunken - + 2 - - - - 0 + + + + + 24 + 24 + - - - - - 24 - 24 - - - - - - - :/images/konversation.png - - - true - - - - - - - - Arial - 10 - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Arial'; font-weight:600;">Forums</span></p></body></html> - - - - + + + + + :/images/konversation.png + + + true + + - + + + + + 10 + 75 + true + + + + Forums + + + + Qt::Horizontal @@ -617,39 +97,33 @@ p, li { white-space: pre-wrap; } - - + + Qt::NoFocus Display - - QPushButton::menu-indicator { - subcontrol-origin: padding; - subcontrol-position: bottom right; - } - - QPushButton::menu-indicator:pressed, QPushButton::menu-indicator:open { - position: relative; - top: 2px; left: 2px; /* shift the arrow by 2 px */ - } - - QPushButton:hover { - border: 1px solid #CCCCCC; - } - :/images/looknfeel.png:/images/looknfeel.png - + + + 32 + 16 + + + + QToolButton::InstantPopup + + true - + Qt::NoFocus @@ -661,6 +135,12 @@ p, li { white-space: pre-wrap; } :/images/new_forum16.png:/images/new_forum16.png + + + 32 + 16 + + true @@ -677,17 +157,6 @@ p, li { white-space: pre-wrap; } 0 - - - 9 - - - - - -1 - -1 - - @@ -720,9 +189,6 @@ p, li { white-space: pre-wrap; } 1677215 - - - @@ -1022,93 +488,47 @@ p, li { white-space: pre-wrap; } - + 0 32 - - QFrame#frame_2{ -background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #FEFEFE, stop:1 #E8E8E8); - -border: 1px solid #CCCCCC;} - - QFrame::StyledPanel + QFrame::Box - QFrame::Raised + QFrame::Sunken - + 2 - - - - 2 + + + + Qt::NoFocus - - - - - - - :/images/find-16.png - - - - - - - Search forums - - - - - - - - + + Start new Thread for Selected Forum + + + + :/images/mail_new.png:/images/mail_new.png + + - 0 - 0 + 24 + 16 - - - MS Shell Dlg 2 - + + true - - 1 - - - - Date - - - - - Title - - - - - Author - - - - - Content - - - + Qt::Horizontal @@ -1124,26 +544,10 @@ border: 1px solid #CCCCCC;}
- - - - - 24 - 24 - - - - Qt::NoFocus - + + - Start new Thread for Selected Forum - - - - :/images/mail_new.png:/images/mail_new.png - - - true + Search forums @@ -1186,9 +590,6 @@ border: 1px solid #CCCCCC;} - - - true @@ -1229,20 +630,20 @@ border: 1px solid #CCCCCC;} - GroupTreeWidget - QWidget -
gui/common/GroupTreeWidget.h
- 1 + LinkTextBrowser + QTextBrowser +
gui/common/LinkTextBrowser.h
LineEditClear QLineEdit -
gui/common/LineEditClear.h
+
gui/common/LineEditClear.h
- LinkTextBrowser - QTextBrowser -
gui/common/LinkTextBrowser.h
+ GroupTreeWidget + QWidget +
gui/common/GroupTreeWidget.h
+ 1
diff --git a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp index ef27fb73b..d44ab1a5a 100644 --- a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp @@ -41,7 +41,7 @@ 0) PostedGroupDialog::PostedGroupDialog(TokenQueue* tokenQueue, RsPosted* posted, QWidget *parent) - :GxsGroupDialog(tokenQueue, POSTED_ENABLE_FLAG, POSTED_CREATE_DEFAULT_FLAG, parent, "Create New Posted Topic"), + :GxsGroupDialog(tokenQueue, POSTED_ENABLE_FLAG, POSTED_CREATE_DEFAULT_FLAG, parent), mPosted(posted) { } @@ -51,6 +51,15 @@ PostedGroupDialog::PostedGroupDialog(const RsPostedGroup& grp, uint32_t mode, QW { } +QString PostedGroupDialog::serviceHeader() +{ + return tr("Create New Posted Topic"); +} + +QPixmap PostedGroupDialog::serviceImage() +{ + return QPixmap(); +} bool PostedGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) { diff --git a/retroshare-gui/src/gui/Posted/PostedGroupDialog.h b/retroshare-gui/src/gui/Posted/PostedGroupDialog.h index 187f1416d..3ed4faed3 100644 --- a/retroshare-gui/src/gui/Posted/PostedGroupDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedGroupDialog.h @@ -43,7 +43,8 @@ public: PostedGroupDialog(const RsPostedGroup& grp, uint32_t mode, QWidget *parent = NULL); protected: - + virtual QString serviceHeader(); + virtual QPixmap serviceImage(); bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); private: diff --git a/retroshare-gui/src/gui/forumsv2/CreateForumV2.cpp b/retroshare-gui/src/gui/forumsv2/CreateForumV2.cpp deleted file mode 100644 index d261c024e..000000000 --- a/retroshare-gui/src/gui/forumsv2/CreateForumV2.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/**************************************************************** - * RetroShare is distributed under the following license: - * - * Copyright (C) 2008 Robert Fernie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - ****************************************************************/ - -#include - -#include "util/misc.h" -#include "CreateForumV2.h" -#include "gui/common/PeerDefs.h" - -#include - -#include -#include - -#include - -#define CREATEFORUMSV2_NEWFORUMID 1 - - -/** Constructor */ -CreateForumV2::CreateForumV2(QWidget *parent) -: QDialog(parent) -{ - /* Invoke the Qt Designer generated object setup routine */ - ui.setupUi(this); - - mForumQueue = new TokenQueue(rsForumsV2, this); - - // connect up the buttons. - connect( ui.cancelButton, SIGNAL( clicked ( bool ) ), this, SLOT( cancelForum( ) ) ); - connect( ui.createButton, SIGNAL( clicked ( bool ) ), this, SLOT( createForum( ) ) ); - connect( ui.pubKeyShare_cb, SIGNAL( clicked() ), this, SLOT( setShareList( ) )); - - if (!ui.pubKeyShare_cb->isChecked()) { - ui.contactsdockWidget->hide(); - this->resize(this->size().width() - ui.contactsdockWidget->size().width(), this->size().height()); - } - - /* initialize key share list */ - ui.keyShareList->setHeaderText(tr("Contacts:")); - ui.keyShareList->setModus(FriendSelectionWidget::MODUS_CHECK); - ui.keyShareList->start(); - - newForum(); -} - -void CreateForumV2::newForum() -{ - /* enforce Public for the moment */ - ui.typePublic->setChecked(true); - - ui.typePrivate->setEnabled(false); - ui.typeEncrypted->setEnabled(true); - -#ifdef RS_RELEASE_VERSION - ui.typePrivate->setVisible(false); - ui.typeEncrypted->setVisible(true); -#endif - - ui.msgAnon->setChecked(true); - //ui.msgAuth->setEnabled(false); - - ui.forumName->clear(); - ui.forumDesc->clear(); - - ui.forumName->setFocus(); -} - -void CreateForumV2::createForum() -{ - QString name = misc::removeNewLine(ui.forumName->text()); - QString desc = ui.forumDesc->toPlainText(); //toHtml(); - uint32_t flags = 0; - - if(name.isEmpty()) { - /* error message */ - QMessageBox::warning(this, "RetroShare", tr("Please add a Name"), QMessageBox::Ok, QMessageBox::Ok); - return; //Don't add a empty name!! - } - - if (ui.typePublic->isChecked()) { - flags |= RS_DISTRIB_PUBLIC; - } else if (ui.typePrivate->isChecked()) { - flags |= RS_DISTRIB_PRIVATE; - } else if (ui.typeEncrypted->isChecked()) { - flags |= RS_DISTRIB_ENCRYPTED; - } - - if (ui.msgAuth->isChecked()) { - flags |= RS_DISTRIB_AUTHEN_REQ; - } else if (ui.msgAnon->isChecked()) { - flags |= RS_DISTRIB_AUTHEN_ANON; - } - - if (rsForumsV2) { - - - uint32_t token; - RsForumV2Group grp; - grp.mMeta.mGroupName = std::string(name.toUtf8()); - grp.mDescription = std::string(desc.toUtf8()); - grp.mMeta.mGroupFlags = flags; - - rsForumsV2->createGroup(token, grp, true); - - // get the Queue to handle response. - mForumQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_SUMMARY, CREATEFORUMSV2_NEWFORUMID); - - } -} - -void CreateForumV2::completeCreateNewForum(const RsGroupMetaData &newForumMeta) -{ - sendShareList(newForumMeta.mGroupId); - - close(); -} - - -void CreateForumV2::sendShareList(std::string forumId) -{ - if (!rsForumsV2) - { - std::cerr << "CreateForumV2::sendShareList() ForumsV2 not active"; - std::cerr << std::endl; - return; - } - - if (ui.pubKeyShare_cb->isChecked()) - { - std::list shareList; - ui.keyShareList->selectedSslIds(shareList, false); - rsForumsV2->groupShareKeys(forumId, shareList); - } - close(); -} - - - - - - -void CreateForumV2::setShareList() -{ - if (ui.pubKeyShare_cb->isChecked()){ - this->resize(this->size().width() + ui.contactsdockWidget->size().width(), this->size().height()); - ui.contactsdockWidget->show(); - } else { // hide share widget - ui.contactsdockWidget->hide(); - this->resize(this->size().width() - ui.contactsdockWidget->size().width(), this->size().height()); - } -} - -void CreateForumV2::cancelForum() -{ - close(); -} - - - - -void CreateForumV2::loadNewForumId(const uint32_t &token) -{ - std::cerr << "CreateForumV2::loadNewForumId()"; - std::cerr << std::endl; - - std::list groupInfo; - rsForumsV2->getGroupSummary(token, groupInfo); - - if (groupInfo.size() == 1) - { - RsGroupMetaData fi = groupInfo.front(); - completeCreateNewForum(fi); - } - else - { - std::cerr << "CreateForumV2::loadNewForumId() ERROR INVALID Number of Forums Created"; - std::cerr << std::endl; - } -} - - - - - - - - -void CreateForumV2::loadRequest(const TokenQueue *queue, const TokenRequest &req) -{ - std::cerr << "CreateForumV2::loadRequest() UserType: " << req.mUserType; - std::cerr << std::endl; - - if (queue == mForumQueue) - { - /* now switch on req */ - switch(req.mUserType) - { - - case CREATEFORUMSV2_NEWFORUMID: - loadNewForumId(req.mToken); - break; - default: - std::cerr << "CreateForumV2::loadRequest() UNKNOWN UserType "; - std::cerr << std::endl; - - } - } -} - - - diff --git a/retroshare-gui/src/gui/forumsv2/CreateForumV2.h b/retroshare-gui/src/gui/forumsv2/CreateForumV2.h deleted file mode 100644 index 0aa72e26e..000000000 --- a/retroshare-gui/src/gui/forumsv2/CreateForumV2.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************** - * RetroShare is distributed under the following license: - * - * Copyright (C) 2008 Robert Fernie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - ****************************************************************/ - - -#ifndef _CREATE_FORUMV2_DIALOG_H -#define _CREATE_FORUMV2_DIALOG_H - -#include "ui_CreateForumV2.h" - -#include "util/TokenQueue.h" - -class CreateForumV2 : public QDialog, public TokenResponse -{ - Q_OBJECT - -public: - CreateForumV2(QWidget *parent = 0); - - void newForum(); /* cleanup */ - - // Callback for all Loads. -virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); - -private slots: - /* actions to take.... */ - void createForum(); - void cancelForum(); - - // set private forum key share list - void setShareList(); - -private: - void sendShareList(std::string forumId); - void completeCreateNewForum(const RsGroupMetaData &newForumMeta); - void loadNewForumId(const uint32_t &token); - - - std::list mShareList; - - QPixmap picture; - - TokenQueue *mForumQueue; - - /** Qt Designer generated object */ - Ui::CreateForumV2 ui; -}; - -#endif - diff --git a/retroshare-gui/src/gui/forumsv2/CreateForumV2.ui b/retroshare-gui/src/gui/forumsv2/CreateForumV2.ui deleted file mode 100644 index 0cfcb4ca5..000000000 --- a/retroshare-gui/src/gui/forumsv2/CreateForumV2.ui +++ /dev/null @@ -1,374 +0,0 @@ - - - CreateForumV2 - - - - 0 - 0 - 672 - 495 - - - - Create new Forum - - - - :/images/rstray3.png:/images/rstray3.png - - - - 0 - - - 0 - - - - - - 16777215 - 64 - - - - QFrame#frame_2{background-image: url(:/images/connect/connectFriendBanner.png);} - - - QFrame::NoFrame - - - QFrame::Raised - - - - 6 - - - 6 - - - - - - 48 - 48 - - - - - - - - - - :/images/konversation64.png - - - true - - - - - - - color: rgb(255, 255, 255); - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Arial'; font-size:24pt; font-weight:600; color:#ffffff;">New Forum</span></p></body></html> - - - - - - - - - - QFrame::NoFrame - - - QFrame::Raised - - - - - - - - Name - - - - - - - - - - - - true - - - - 0 - 0 - - - - - 300 - 524287 - - - - - 220 - 0 - - - - - 0 - 0 - - - - check peers you would like to share private publish key with - - - false - - - QDockWidget::NoDockWidgetFeatures - - - Share Key With - - - - - 0 - - - 0 - - - - - - 0 - 4 - - - - - 20 - 0 - - - - - 300 - 16777215 - - - - - 220 - 0 - - - - - 200 - 0 - - - - - - - - - - - - - - Description - - - - - - - - - - - - Type: - - - - 6 - - - - - Public - Anyone can read and publish (Shared Publish Key) - - - - - - - Restricted - Anyone can read, limited publishing (Private Publish Key) - - - - - - - Private - (Private Publish Key required to view Messages) - - - - - - - - - - Key Sharing - - - - 0 - - - 6 - - - - - Key recipients can publish to restricted-type channels, and can view and publish for private-type channels - - - Share Private Publish Key - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - Allowed Messages - - - - 0 - - - 6 - - - - - Authenticated Messages - - - - - - - Anonymous Messages - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - Qt::Horizontal - - - - 238 - 20 - - - - - - - - Cancel - - - - - - - Create - - - true - - - - - - - - - - - FriendSelectionWidget - QWidget -
gui/common/FriendSelectionWidget.h
- 1 -
-
- - - - -
diff --git a/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.cpp b/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.cpp deleted file mode 100644 index 6ace6db7e..000000000 --- a/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.cpp +++ /dev/null @@ -1,424 +0,0 @@ -/**************************************************************** - * RetroShare is distributed under the following license: - * - * Copyright (C) 2008 Robert Fernie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - ****************************************************************/ - -#include "CreateForumV2Msg.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "gui/settings/rsharesettings.h" -#include "gui/RetroShareLink.h" -#include "gui/common/Emoticons.h" - -#include "util/misc.h" - -#include -#include - - -#define CREATEFORUMV2MSG_FORUMINFO 1 -#define CREATEFORUMV2MSG_PARENTMSG 2 - - -/** Constructor */ -CreateForumV2Msg::CreateForumV2Msg(std::string fId, std::string pId) -: QMainWindow(NULL), mForumId(fId), mParentId(pId) -{ - /* Invoke the Qt Designer generated object setup routine */ - ui.setupUi(this); - setAttribute(Qt::WA_DeleteOnClose, true); - - /* Setup Queue */ - mForumQueue = new TokenQueue(rsForumsV2, this); - - Settings->loadWidgetInformation(this); - - connect( ui.forumMessage, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( forumMessageCostumPopupMenu( QPoint ) ) ); - - connect(ui.hashBox, SIGNAL(fileHashingFinished(QList)), this, SLOT(fileHashingFinished(QList))); - - // connect up the buttons. - connect( ui.postmessage_action, SIGNAL( triggered (bool) ), this, SLOT( createMsg( ) ) ); - connect( ui.close_action, SIGNAL( triggered (bool) ), this, SLOT( cancelMsg( ) ) ); - connect( ui.emoticonButton, SIGNAL(clicked()), this, SLOT(smileyWidgetForums())); - connect( ui.attachFileButton, SIGNAL(clicked() ), this , SLOT(addFile())); - connect( ui.pastersButton, SIGNAL(clicked() ), this , SLOT(pasteLink())); - - setAcceptDrops(true); - ui.hashBox->setDropWidget(this); - ui.hashBox->setAutoHide(false); - - mParentMsgLoaded = false; - mForumMetaLoaded = false; - - newMsg(); -} - -/** context menu searchTablewidget2 **/ -void CreateForumV2Msg::forumMessageCostumPopupMenu( QPoint /*point*/ ) -{ - QMenu *contextMnu = ui.forumMessage->createStandardContextMenu(); - - contextMnu->addSeparator(); - QAction *pasteLinkAct = contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste RetroShare Link"), this, SLOT(pasteLink())); - QAction *pasteLinkFullAct = contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste full RetroShare Link"), this, SLOT(pasteLinkFull())); - contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste own certificate link"), this, SLOT(pasteOwnCertificateLink())); - - if (RSLinkClipboard::empty()) { - pasteLinkAct->setDisabled (true); - pasteLinkFullAct->setDisabled (true); - } - - contextMnu->exec(QCursor::pos()); - delete(contextMnu); -} - -void CreateForumV2Msg::newMsg() -{ - /* clear all */ - mParentMsgLoaded = false; - mForumMetaLoaded = false; - - /* request Data */ - { - RsTokReqOptions opts; - - std::list groupIds; - groupIds.push_back(mForumId); - - std::cerr << "ForumsV2Dialog::newMsg() Requesting Group Summary(" << mForumId << ")"; - std::cerr << std::endl; - - uint32_t token; - mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, groupIds, CREATEFORUMV2MSG_FORUMINFO); - - } - - if (mParentId != "") - { - - RsTokReqOptions opts; - - std::list msgIds; - msgIds.push_back(mParentId); - - std::cerr << "ForumsV2Dialog::newMsg() Requesting Parent Summary(" << mParentId << ")"; - std::cerr << std::endl; - - uint32_t token; - //mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, CREATEFORUMV2MSG_PARENTMSG); - } -} - - -void CreateForumV2Msg::saveForumInfo(const RsGroupMetaData &meta) -{ - mForumMeta = meta; - mForumMetaLoaded = true; - - loadFormInformation(); -} - -void CreateForumV2Msg::saveParentMsg(const RsForumV2Msg &msg) -{ - mParentMsg = msg; - mParentMsgLoaded = true; - - loadFormInformation(); -} - -void CreateForumV2Msg::loadFormInformation() -{ - if ((!mParentMsgLoaded) && (mParentId != "")) - { - std::cerr << "CreateForumV2Msg::loadMsgInformation() ParentMsg not Loaded Yet"; - std::cerr << std::endl; - return; - } - - if (!mForumMetaLoaded) - { - std::cerr << "CreateForumV2Msg::loadMsgInformation() ForumMeta not Loaded Yet"; - std::cerr << std::endl; - return; - } - - std::cerr << "CreateForumV2Msg::loadMsgInformation() Data Available!"; - std::cerr << std::endl; - - QString name = QString::fromUtf8(mForumMeta.mGroupName.c_str()); - QString subj; - if (mParentId != "") - { - QString title = QString::fromUtf8(mParentMsg.mMeta.mMsgName.c_str()); - name += " " + tr("In Reply to") + ": "; - name += title; - - QString text = title; - - if (text.startsWith("Re:", Qt::CaseInsensitive)) - { - subj = title; - } - else - { - subj = "Re: " + title; - } - - } - - ui.forumName->setText(misc::removeNewLine(name)); - ui.forumSubject->setText(misc::removeNewLine(subj)); - - if (!ui.forumSubject->text().isEmpty()) - { - ui.forumMessage->setFocus(); - } - else - { - ui.forumSubject->setFocus(); - } - - if (mForumMeta.mGroupFlags & RS_DISTRIB_AUTHEN_REQ) - { - ui.signBox->setChecked(true); - ui.signBox->setEnabled(false); - } - else - { - /* Uncheck sign box by default for anonymous forums */ - ui.signBox->setChecked(false); - ui.signBox->setEnabled(true); - } - - ui.forumMessage->setText(""); -} - - - -void CreateForumV2Msg::createMsg() -{ - QString name = misc::removeNewLine(ui.forumSubject->text()); - QString desc = ui.forumMessage->toHtml(); - - if(desc == QTextDocument(ui.forumMessage->toPlainText()).toHtml()) - desc = ui.forumMessage->toPlainText() ; - - if(name.isEmpty()) - { /* error message */ - QMessageBox::warning(this, tr("RetroShare"),tr("Please set a Forum Subject and Forum Message"), - QMessageBox::Ok, QMessageBox::Ok); - - return; //Don't add a empty Subject!! - } - - RsForumV2Msg msg; - msg.mMeta.mGroupId = mForumId; - msg.mMeta.mParentId = mParentId; - msg.mMeta.mMsgId = ""; - if (mParentMsgLoaded) - { - msg.mMeta.mThreadId = mParentMsg.mMeta.mThreadId; - } - - msg.mMeta.mMsgName = std::string(name.toUtf8()); - msg.mMsg = std::string(desc.toUtf8()); - msg.mMeta.mMsgFlags = RS_DISTRIB_AUTHEN_REQ; - - if ((msg.mMsg == "") && (msg.mMeta.mMsgName == "")) - return; /* do nothing */ - - uint32_t token; - rsForumsV2->createMsg(token, msg, true); - close(); - - - // Previous Info - for reference. - - //ForumMsgInfo msgInfo; - - //msgInfo.forumId = mForumId; - //msgInfo.threadId = ""; - //msgInfo.parentId = mParentId; - //msgInfo.msgId = ""; - - //msgInfo.title = name.toStdWString(); - //msgInfo.msg = desc.toStdWString(); - //msgInfo.msgflags = 0; - - //if (ui.signBox->isChecked()) - //{ - // msgInfo.msgflags = RS_DISTRIB_AUTHEN_REQ; - //} - - //if ((msgInfo.msg == L"") && (msgInfo.title == L"")) - // return; /* do nothing */ - - //if (rsForumsV2->ForumMessageSend(msgInfo) == true) { - // close(); - //} -} - - - - -void CreateForumV2Msg::closeEvent (QCloseEvent * /*event*/) -{ - Settings->saveWidgetInformation(this); -} - -void CreateForumV2Msg::cancelMsg() -{ - close(); -} - -void CreateForumV2Msg::smileyWidgetForums() -{ - Emoticons::showSmileyWidget(this, ui.emoticonButton, SLOT(addSmileys()), false); -} - -void CreateForumV2Msg::addSmileys() -{ - ui.forumMessage->textCursor().insertText(qobject_cast(sender())->toolTip().split("|").first()); -} - -void CreateForumV2Msg::addFile() -{ - QStringList files; - if (misc::getOpenFileNames(this, RshareSettings::LASTDIR_EXTRAFILE, tr("Add Extra File"), "", files)) { - ui.hashBox->addAttachments(files); - } -} - -void CreateForumV2Msg::fileHashingFinished(QList hashedFiles) -{ - std::cerr << "CreateForumV2Msg::fileHashingFinished() started." << std::endl; - - QString mesgString; - - QList::iterator it; - for (it = hashedFiles.begin(); it != hashedFiles.end(); ++it) { - HashedFile& hashedFile = *it; - RetroShareLink link; - if (link.createFile(hashedFile.filename, hashedFile.size, QString::fromStdString(hashedFile.hash))) { - mesgString += link.toHtmlSize() + "
"; - } - } - -#ifdef CHAT_DEBUG - std::cerr << "CreateForumV2Msg::anchorClicked mesgString : " << mesgString.toStdString() << std::endl; -#endif - - if (!mesgString.isEmpty()) { - ui.forumMessage->textCursor().insertHtml(mesgString); - } - - ui.forumMessage->setFocus( Qt::OtherFocusReason ); -} - -void CreateForumV2Msg::pasteLink() -{ - ui.forumMessage->insertHtml(RSLinkClipboard::toHtml()) ; -} - -void CreateForumV2Msg::pasteLinkFull() -{ - ui.forumMessage->insertHtml(RSLinkClipboard::toHtmlFull()) ; -} - -void CreateForumV2Msg::pasteOwnCertificateLink() -{ - RetroShareLink link ; - std::string ownId = rsPeers->getOwnId() ; - if( link.createCertificate(ownId) ) { - ui.forumMessage->insertHtml(link.toHtml() + " "); - } -} - - - - -void CreateForumV2Msg::loadForumInfo(const uint32_t &token) -{ - std::cerr << "CreateForumV2Msg::loadForumInfo()"; - std::cerr << std::endl; - - std::list groupInfo; - rsForumsV2->getGroupSummary(token, groupInfo); - - if (groupInfo.size() == 1) - { - RsGroupMetaData fi = groupInfo.front(); - saveForumInfo(fi); - } - else - { - std::cerr << "CreateForumV2Msg::loadForumInfo() ERROR INVALID Number of Forums"; - std::cerr << std::endl; - } -} - - -void CreateForumV2Msg::loadParentMsg(const uint32_t &token) -{ - std::cerr << "CreateForumV2Msg::loadParentMsg()"; - std::cerr << std::endl; - - // Only grab one.... ignore more (shouldn't be any). - RsForumV2Msg msg; - rsForumsV2->getMsgData(token, msg); - saveParentMsg(msg); -} - - - -void CreateForumV2Msg::loadRequest(const TokenQueue *queue, const TokenRequest &req) -{ - std::cerr << "CreateForumV2::loadRequest() UserType: " << req.mUserType; - std::cerr << std::endl; - - if (queue == mForumQueue) - { - /* now switch on req */ - switch(req.mUserType) - { - case CREATEFORUMV2MSG_FORUMINFO: - loadForumInfo(req.mToken); - break; - - case CREATEFORUMV2MSG_PARENTMSG: - loadParentMsg(req.mToken); - break; - default: - std::cerr << "CreateForumV2::loadRequest() UNKNOWN UserType "; - std::cerr << std::endl; - - } - } -} - diff --git a/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.h b/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.h deleted file mode 100644 index 5b5de0194..000000000 --- a/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************** - * RetroShare is distributed under the following license: - * - * Copyright (C) 2008 Robert Fernie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - ****************************************************************/ - - -#ifndef _CREATE_FORUMV2_MSG_DIALOG_H -#define _CREATE_FORUMV2_MSG_DIALOG_H - -#include "ui_CreateForumV2Msg.h" - -#include "util/TokenQueue.h" - -#include - - -class CreateForumV2Msg : public QMainWindow, public TokenResponse -{ - Q_OBJECT - -public: - CreateForumV2Msg(std::string fId, std::string pId); - - void newMsg(); /* cleanup */ - virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); - -private slots: - /** Create the context popup menu and it's submenus */ - void forumMessageCostumPopupMenu( QPoint point ); - - void fileHashingFinished(QList hashedFiles); - /* actions to take.... */ - void createMsg(); - void cancelMsg(); - void pasteLink(); - void pasteLinkFull(); - void pasteOwnCertificateLink(); - - void smileyWidgetForums(); - void addSmileys(); - void addFile(); - -protected: - void closeEvent (QCloseEvent * event); - -private: - - void saveForumInfo(const RsGroupMetaData &meta); - void saveParentMsg(const RsForumV2Msg &msg); - void loadFormInformation(); - - void loadForumInfo(const uint32_t &token); - void loadParentMsg(const uint32_t &token); - - std::string mForumId; - std::string mParentId; - - bool mParentMsgLoaded; - bool mForumMetaLoaded; - RsForumV2Msg mParentMsg; - RsGroupMetaData mForumMeta; - - TokenQueue *mForumQueue; - - /** Qt Designer generated object */ - Ui::CreateForumV2Msg ui; -}; - -#endif - diff --git a/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.ui b/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.ui deleted file mode 100644 index a9ce1bf29..000000000 --- a/retroshare-gui/src/gui/forumsv2/CreateForumV2Msg.ui +++ /dev/null @@ -1,333 +0,0 @@ - - - CreateForumV2Msg - - - Qt::NonModal - - - - 0 - 0 - 482 - 448 - - - - Post Forum Message - - - - :/images/rstray3.png:/images/rstray3.png - - - QToolBar#toolBar{background-image: url(:/images/connect/connectFriendBanner.png)} - - - Qt::ToolButtonTextUnderIcon - - - - - 0 - - - 0 - - - - - - - QFrame::NoFrame - - - QFrame::Raised - - - - 6 - - - 6 - - - - - - - Forum - - - - - - - false - - - - - - - - - - - Subject - - - - - - - - - - - - - - - - 16777215 - 38 - - - - QFrame#frame_2{ -background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, -stop:0 #FEFEFE, stop:1 #E8E8E8); - -border: 1px solid #CCCCCC;} - - - QFrame::Raised - - - - 6 - - - - - Qt::NoFocus - - - Attach File - - - - - - - :/images/add-share24.png:/images/add-share24.png - - - - 24 - 24 - - - - true - - - - - - - Qt::NoFocus - - - - - - - :/images/emoticons/kopete/kopete020.png:/images/emoticons/kopete/kopete020.png - - - - 24 - 24 - - - - true - - - - - - - Qt::NoFocus - - - Sign Message - - - - :/images/pgp.png:/images/pgp.png - - - - 24 - 24 - - - - true - - - - - - - Qt::Horizontal - - - - 40 - 15 - - - - - - - - Qt::NoFocus - - - Paste RetroShare Link - - - - - - - :/images/pasterslink.png:/images/pasterslink.png - - - true - - - - - - - - - - QFrame::NoFrame - - - QFrame::Raised - - - - 6 - - - 6 - - - - - Forum Post - - - - - - Qt::CustomContextMenu - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></p></body></html> - - - - - - - - - - Attach files via drag and drop - - - - - - - 0 - 0 - - - - You can attach files via drag and drop here in this window - - - true - - - - - - - - - - - - - - - - toolBar - - - TopToolBarArea - - - false - - - - - - - - :/images/mail_send24.png:/images/mail_send24.png - - - Post Forum Msg - - - - - - :/images/button_cancel.png:/images/button_cancel.png - - - Close - - - - - - HashBox - QScrollArea -
gui/common/HashBox.h
- 1 -
-
- - - - -
diff --git a/retroshare-gui/src/gui/forumsv2/EditForumV2Details.cpp b/retroshare-gui/src/gui/forumsv2/EditForumV2Details.cpp deleted file mode 100644 index 5d7d9c690..000000000 --- a/retroshare-gui/src/gui/forumsv2/EditForumV2Details.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************** - * RetroShare is distributed under the following license: - * - * Copyright (C) 2010 RetroShare Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - ****************************************************************/ - -#include "EditForumV2Details.h" - -#include - -#include "util/misc.h" - -#include -#include -#include - - -/** Default constructor */ -EditForumV2Details::EditForumV2Details(std::string forumId, QWidget *parent, Qt::WFlags flags) - : QDialog(parent, flags), m_forumId(forumId) -{ - /* Invoke Qt Designer generated QObject setup routine */ - ui.setupUi(this); - - connect(ui.applyButton, SIGNAL(clicked()), this, SLOT(applyDialog())); - - loadForum(); -} - -void EditForumV2Details::loadForum() -{ - if (!rsForumsV2) { - return; - } - -#warning "EditForumV2Details incomplete" -#if 0 - ForumInfo info; - rsForumsV2->getForumInfo(m_forumId, info); - - // set name - ui.nameline->setText(QString::fromStdWString(info.forumName)); - - // set description - ui.DescriptiontextEdit->setText(QString::fromStdWString(info.forumDesc)); -#endif - -} - -void EditForumV2Details::applyDialog() -{ - if (!rsForumsV2) { - return; - } - - // if text boxes have not been edited leave alone - if (!ui.nameline->isModified() && !ui.DescriptiontextEdit->document()->isModified()) { - return; - } - -#warning "EditForumV2Details incomplete" -#if 0 - - ForumInfo info; - - info.forumName = misc::removeNewLine(ui.nameline->text()).toStdWString(); - info.forumDesc = ui.DescriptiontextEdit->document()->toPlainText().toStdWString(); - - rsForumsV2->setForumInfo(m_forumId, info); -#endif - - /* close the Dialog after the Changes applied */ - close(); -} diff --git a/retroshare-gui/src/gui/forumsv2/EditForumV2Details.h b/retroshare-gui/src/gui/forumsv2/EditForumV2Details.h deleted file mode 100644 index 55c9c2bc7..000000000 --- a/retroshare-gui/src/gui/forumsv2/EditForumV2Details.h +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************** - * RetroShare is distributed under the following license: - * - * Copyright (C) 2010 RetroShare Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - ****************************************************************/ - -#ifndef _EDITFORUMV2DETAILS_H -#define _EDITFORUMV2DETAILS_H - -#include - -#include "ui_EditForumV2Details.h" - -class EditForumV2Details : public QDialog -{ - Q_OBJECT - -public: - /** Default constructor */ - EditForumV2Details(std::string forumId = "", QWidget *parent = 0, Qt::WFlags flags = 0); - -signals: - void configChanged(); - -private slots: - void applyDialog(); - -private: - void loadForum(); - - std::string m_forumId; - - /** Qt Designer generated object */ - Ui::EditForumV2Details ui; -}; - -#endif - diff --git a/retroshare-gui/src/gui/forumsv2/EditForumV2Details.ui b/retroshare-gui/src/gui/forumsv2/EditForumV2Details.ui deleted file mode 100644 index b32810506..000000000 --- a/retroshare-gui/src/gui/forumsv2/EditForumV2Details.ui +++ /dev/null @@ -1,130 +0,0 @@ - - - EditForumV2Details - - - - 0 - 0 - 436 - 355 - - - - Forum Details - - - - :/images/rstray3.png:/images/rstray3.png - - - - - - - - Qt::Horizontal - - - - 311 - 20 - - - - - - - - Cancel - - - - - - - OK - - - false - - - true - - - - - - - - - 0 - - - - - :/images/info16.png:/images/info16.png - - - Edit Forum Details - - - - - - Forum Info - - - - - - Forum Name - - - - - - - - - - Forum Description - - - - - - - - - - - - - - - - - - - - - - - cancelButton - clicked() - EditForumDetails - close() - - - 307 - 333 - - - 217 - 177 - - - - - diff --git a/retroshare-gui/src/gui/forumsv2/ForumV2Details.cpp b/retroshare-gui/src/gui/forumsv2/ForumV2Details.cpp deleted file mode 100644 index 0f3d0f4dc..000000000 --- a/retroshare-gui/src/gui/forumsv2/ForumV2Details.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/**************************************************************** - * RetroShare is distributed under the following license: - * - * Copyright (C) 2009 RetroShare Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - ****************************************************************/ -#include "ForumV2Details.h" - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - - -/* Define the format used for displaying the date and time */ -#define DATETIME_FMT "MMM dd hh:mm:ss" - -/** Default constructor */ -ForumV2Details::ForumV2Details(QWidget *parent, Qt::WFlags flags) - : QDialog(parent, flags) -{ - /* Invoke Qt Designer generated QObject setup routine */ - ui.setupUi(this); - - connect(ui.applyButton, SIGNAL(clicked()), this, SLOT(applyDialog())); - connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(closeinfodlg())); - - ui.applyButton->setToolTip(tr("Apply and Close")); - - ui.nameline ->setReadOnly(true); - ui.popline ->setReadOnly(true); - ui.postline ->setReadOnly(true); - ui.IDline ->setReadOnly(true); - ui.DescriptiontextEdit ->setReadOnly(true); - - ui.radioButton_authd->setEnabled(false); - ui.radioButton_anonymous->setEnabled(false); -} - - -/** - Overloads the default show() slot so we can set opacity*/ - -void -ForumV2Details::show() -{ - //loadSettings(); - if(!this->isVisible()) { - QDialog::show(); - - } -} - -void ForumV2Details::closeEvent (QCloseEvent * event) -{ - QWidget::closeEvent(event); -} - -void ForumV2Details::closeinfodlg() -{ - close(); -} - -void ForumV2Details::showDetails(std::string mCurrForumId) -{ - fId = mCurrForumId; - loadDialog(); -} - -void ForumV2Details::loadDialog() -{ - if (!rsForumsV2) - { - return; - } - -#warning "ForumV2Details Incomplete" -#if 0 - ForumInfo fi; - rsForumsV2->getForumInfo(fId, fi); - - // Set Forum Name - ui.nameline->setText(QString::fromStdWString(fi.forumName)); - - // Set Popularity - ui.popline->setText(QString::number(fi.pop)); - - // Set Last Post Date - if (fi.lastPost) { - QDateTime qtime; - qtime.setTime_t(fi.lastPost); - QString timestamp = qtime.toString("yyyy-MM-dd hh:mm:ss"); - ui.postline->setText(timestamp); - } - - // Set Forum ID - ui.IDline->setText(QString::fromStdString(fi.forumId)); - - // Set Forum Description - ui.DescriptiontextEdit->setText(QString::fromStdWString(fi.forumDesc)); - - if (fi.forumFlags & RS_DISTRIB_AUTHEN_REQ) - { - ui.radioButton_authd->setChecked(true); - ui.radioButton_anonymous->setChecked(false); - } - if (fi.forumFlags & RS_DISTRIB_AUTHEN_ANON) - { - ui.radioButton_authd->setChecked(false); - ui.radioButton_anonymous->setChecked(true); - } -#endif - -} - -void ForumV2Details::applyDialog() -{ - - /* reload now */ - loadDialog(); - - /* close the Dialog after the Changes applied */ - closeinfodlg(); - -} diff --git a/retroshare-gui/src/gui/forumsv2/ForumV2Details.h b/retroshare-gui/src/gui/forumsv2/ForumV2Details.h deleted file mode 100644 index 3489fb344..000000000 --- a/retroshare-gui/src/gui/forumsv2/ForumV2Details.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************** - * RetroShare is distributed under the following license: - * - * Copyright (C) 2009 RetroShare Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - ****************************************************************/ - -#ifndef _FORUMV2DETAILS_H -#define _FORUMV2DETAILS_H - -#include - -#include "ui_ForumV2Details.h" - -class ForumV2Details : public QDialog -{ - Q_OBJECT - - public: - - /** Default constructor */ - ForumV2Details(QWidget *parent = 0, Qt::WFlags flags = 0); - /** Default destructor */ - - void showDetails(std::string mCurrForumId); - -signals: - void configChanged() ; - -public slots: - /** Overloaded QWidget.show */ - void show(); - -protected: - void closeEvent (QCloseEvent * event); - -private slots: - - void closeinfodlg(); - void applyDialog(); - -private: - - void loadDialog(); - - std::string fId; - /** Qt Designer generated object */ - Ui::ForumV2Details ui; - -}; - -#endif - diff --git a/retroshare-gui/src/gui/forumsv2/ForumV2Details.ui b/retroshare-gui/src/gui/forumsv2/ForumV2Details.ui deleted file mode 100644 index c9e05074b..000000000 --- a/retroshare-gui/src/gui/forumsv2/ForumV2Details.ui +++ /dev/null @@ -1,201 +0,0 @@ - - - ForumV2Details - - - - 0 - 0 - 436 - 355 - - - - Forum Details - - - - :/images/rstray3.png:/images/rstray3.png - - - - - - 0 - - - - - :/images/info16.png:/images/info16.png - - - Forum Details - - - - - - Forum Info - - - - - - Forum Name - - - - - - - - - - Popularity - - - - - - - true - - - - - - - Last Post - - - - - - - true - - - - - - - Forum ID - - - - - - - - - - Forum Description - - - - - - - - - - - - - - - - - :/images/encrypted22.png:/images/encrypted22.png - - - Security - - - - - - Allowed Messages - - - - - - Authenticated Messages - - - - - - - Anonymous Messages - - - true - - - - - - - - - - Qt::Vertical - - - - 358 - 172 - - - - - - - - - - - - - - Qt::Horizontal - - - - 311 - 20 - - - - - - - - Cancel - - - - - - - OK - - - false - - - true - - - - - - - - - - - - diff --git a/retroshare-gui/src/gui/gxs/ForumV2GroupDialog.cpp b/retroshare-gui/src/gui/gxs/ForumV2GroupDialog.cpp deleted file mode 100644 index f462181d2..000000000 --- a/retroshare-gui/src/gui/gxs/ForumV2GroupDialog.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/**************************************************************** - * RetroShare is distributed under the following license: - * - * Copyright (C) 2008 Robert Fernie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - ****************************************************************/ - -#include "ForumV2GroupDialog.h" - -#include -#include - -ForumV2GroupDialog::ForumV2GroupDialog(QWidget *parent) - :GxsGroupDialog(rsForumsV2, parent) -{ - - // To start with we only have open forums - with distribution controls. - - uint32_t enabledFlags = ( GXS_GROUP_FLAGS_ICON | - GXS_GROUP_FLAGS_DESCRIPTION | - GXS_GROUP_FLAGS_DISTRIBUTION | - // GXS_GROUP_FLAGS_PUBLISHSIGN | - GXS_GROUP_FLAGS_SHAREKEYS | - // GXS_GROUP_FLAGS_PERSONALSIGN | - // GXS_GROUP_FLAGS_COMMENTS | - 0); - - uint32_t readonlyFlags = 0; - - uint32_t defaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC | - //GXS_GROUP_DEFAULTS_DISTRIB_GROUP | - //GXS_GROUP_DEFAULTS_DISTRIB_LOCAL | - - GXS_GROUP_DEFAULTS_PUBLISH_OPEN | - //GXS_GROUP_DEFAULTS_PUBLISH_THREADS | - //GXS_GROUP_DEFAULTS_PUBLISH_REQUIRED | - //GXS_GROUP_DEFAULTS_PUBLISH_ENCRYPTED | - - //GXS_GROUP_DEFAULTS_PERSONAL_GPG | - GXS_GROUP_DEFAULTS_PERSONAL_REQUIRED | - //GXS_GROUP_DEFAULTS_PERSONAL_IFNOPUB | - - //GXS_GROUP_DEFAULTS_COMMENTS_YES | - GXS_GROUP_DEFAULTS_COMMENTS_NO | - 0); - - setFlags(enabledFlags, readonlyFlags, defaultsFlags); - -} - - -bool ForumV2GroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) -{ - // Specific Function. - RsForumV2Group grp; - grp.mMeta = meta; - //grp.mDescription = std::string(desc.toUtf8()); - - rsForumsV2->createGroup(token, grp, true); - return true; -} - -void ForumV2GroupDialog::service_loadExistingGroup(const uint32_t &token) -{ - std::cerr << "ForumV2GroupDialog::service_loadExistingGroup()"; - std::cerr << std::endl; - - RsForumV2Group group; - if (!rsForumsV2->getGroupData(token, group)) - { - std::cerr << "ForumV2GroupDialog::service_loadExistingGroup() ERROR Getting Group"; - std::cerr << std::endl; - - return; - } - - /* must call metadata loader */ - loadExistingGroupMetaData(group.mMeta); - - /* now load any extra data we feel like */ - -} - - - - diff --git a/retroshare-gui/src/gui/gxs/ForumV2GroupDialog.h b/retroshare-gui/src/gui/gxs/ForumV2GroupDialog.h deleted file mode 100644 index f549ae077..000000000 --- a/retroshare-gui/src/gui/gxs/ForumV2GroupDialog.h +++ /dev/null @@ -1,44 +0,0 @@ -/**************************************************************** - * RetroShare is distributed under the following license: - * - * Copyright (C) 2008 Robert Fernie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - ****************************************************************/ - - -#ifndef _FORUMV2_GROUP_DIALOG_H -#define _FORUMV2_GROUP_DIALOG_H - -#include "GxsGroupDialog.h" - -class ForumV2GroupDialog : public GxsGroupDialog -{ - Q_OBJECT - -public: - ForumV2GroupDialog(QWidget *parent); - -protected: - virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); -// virtual bool service_CompleteCreateGroup(const RsGroupMetaData &meta); - - virtual void service_loadExistingGroup(const uint32_t &token); - -}; - -#endif - diff --git a/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.cpp index 7f8773671..a9dceae31 100644 --- a/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.cpp @@ -55,18 +55,26 @@ const uint32_t ForumCreateDefaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC GxsForumGroupDialog::GxsForumGroupDialog(TokenQueue *tokenQueue, QWidget *parent) - :GxsGroupDialog(tokenQueue, ForumCreateEnabledFlags, ForumCreateDefaultsFlags, parent, "Create New Forum") + :GxsGroupDialog(tokenQueue, ForumCreateEnabledFlags, ForumCreateDefaultsFlags, parent) { } GxsForumGroupDialog::GxsForumGroupDialog(const RsGxsForumGroup &group, QWidget *parent) - :GxsGroupDialog(group.mMeta, GXS_GROUP_DIALOG_SHOW_MODE, parent) + :GxsGroupDialog(group.mMeta, GXS_GROUP_DIALOG_SHOW_MODE, parent) { return; } +QString GxsForumGroupDialog::serviceHeader() +{ + return tr("Create New Forum"); +} +QPixmap GxsForumGroupDialog::serviceImage() +{ + return QPixmap(":/images/konversation64.png"); +} bool GxsForumGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) { @@ -78,5 +86,3 @@ bool GxsForumGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMeta rsGxsForums->createGroup(token, grp); return true; } - - diff --git a/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.h b/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.h index 8d27e0864..2dc8d1a27 100644 --- a/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.h @@ -35,7 +35,9 @@ public: GxsForumGroupDialog(const RsGxsForumGroup &group, QWidget *parent); protected: - virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); + virtual QString serviceHeader(); + virtual QPixmap serviceImage(); + virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); }; #endif diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index 402fd3cde..0cf782840 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -50,27 +50,20 @@ #define GXSGROUP_LOADGROUP 2 /** Constructor */ -GxsGroupDialog::GxsGroupDialog(TokenQueue *tokenQueue, uint32_t enableFlags, uint16_t defaultFlags, QWidget *parent, const QString &serviceHeader) -: QDialog(parent), mTokenQueue(tokenQueue), mMode(GXS_GROUP_DIALOG_CREATE_MODE), mEnabledFlags(enableFlags), mDefaultsFlags(defaultFlags), mReadonlyFlags(0) +GxsGroupDialog::GxsGroupDialog(TokenQueue *tokenQueue, uint32_t enableFlags, uint16_t defaultFlags, QWidget *parent) +: QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint), mTokenQueue(tokenQueue), mMode(GXS_GROUP_DIALOG_CREATE_MODE), mEnabledFlags(enableFlags), mDefaultsFlags(defaultFlags), mReadonlyFlags(0) { /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); // connect up the buttons. - connect( ui.cancelButton, SIGNAL( clicked ( bool ) ), this, SLOT( cancelDialog( ) ) ); - connect( ui.createButton, SIGNAL( clicked ( bool ) ), this, SLOT( submitGroup( ) ) ); + connect( ui.buttonBox, SIGNAL(accepted()), this, SLOT(submitGroup())); + connect( ui.buttonBox, SIGNAL(rejected()), this, SLOT(cancelDialog())); connect( ui.pubKeyShare_cb, SIGNAL( clicked() ), this, SLOT( setShareList( ) )); connect( ui.groupLogo, SIGNAL(clicked() ), this , SLOT(addGroupLogo())); connect( ui.addLogoButton, SIGNAL(clicked() ), this , SLOT(addGroupLogo())); - if(!serviceHeader.isEmpty()) - ui.mServiceHeader->setText(serviceHeader); - setWindowTitle(serviceHeader); - - //ui.headerFrame->setHeaderImage(QPixmap(":/WikiPoos/images/resource-group-new_48.png")); - //ui.headerFrame->setHeaderText(tr("Create")); - if (!ui.pubKeyShare_cb->isChecked()) { ui.contactsdockWidget->hide(); @@ -93,13 +86,22 @@ GxsGroupDialog::GxsGroupDialog(const RsGroupMetaData &grpMeta, uint32_t mode, QW ui.idChooser->loadIds(0,""); } +void GxsGroupDialog::showEvent(QShowEvent*) +{ + QString header = serviceHeader(); + ui.headerFrame->setHeaderText(header); + setWindowTitle(header); + ui.headerFrame->setHeaderImage(serviceImage()); +} + void GxsGroupDialog::setMode(uint32_t mode) { switch(mMode) { case GXS_GROUP_DIALOG_CREATE_MODE: { - ui.createButton->setText(tr("Create Group")); + ui.buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + ui.buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Create Group")); newGroup(); } break; @@ -107,8 +109,7 @@ void GxsGroupDialog::setMode(uint32_t mode) default: case GXS_GROUP_DIALOG_SHOW_MODE: { - ui.cancelButton->setVisible(false); - ui.createButton->setText(tr("Close")); + ui.buttonBox->setStandardButtons(QDialogButtonBox::Close); } break; //TODO @@ -354,7 +355,6 @@ uint32_t GxsGroupDialog::getGroupSignFlags() void GxsGroupDialog::setGroupSignFlags(uint32_t signFlags) { - if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_ENCRYPTED) { ui.publish_encrypt->setChecked(true); } else if (signFlags & RSGXS_GROUP_SIGN_PUBLISH_ALLSIGNED) { @@ -388,7 +388,6 @@ void GxsGroupDialog::setGroupSignFlags(uint32_t signFlags) } } - void GxsGroupDialog::cancelDialog() { std::cerr << "GxsGroupDialog::cancelDialog() Should Close!"; @@ -397,7 +396,6 @@ void GxsGroupDialog::cancelDialog() close(); } - void GxsGroupDialog::addGroupLogo() { QPixmap img = misc::getOpenThumbnailedPicture(this, tr("Load Group Logo"), 64, 64); @@ -408,7 +406,7 @@ void GxsGroupDialog::addGroupLogo() picture = img; // to show the selected - ui.groupLogo->setIcon(picture); + ui.groupLogo->setPixmap(picture); } QPixmap GxsGroupDialog::getLogo() @@ -441,13 +439,13 @@ void GxsGroupDialog::setShareList() } } -void GxsGroupDialog::wikitype() -{ - // hide logo Button/Label - ui.groupLogo->hide(); - ui.addLogoButton->hide(); - - ui.headerImage->setPixmap(QPixmap(":/images/resource-group-new_48.png")) ; - ui.pubKeyShare_cb->setText(tr("Add Wiki Moderators")); - ui.contactsdockWidget->setWindowTitle(tr("Select Wiki Moderators")); -} +void GxsGroupDialog::wikitype() +{ + // hide logo Button/Label + ui.groupLogo->hide(); + ui.addLogoButton->hide(); + + ui.headerFrame->setHeaderImage(QPixmap(":/images/resource-group-new_48.png")) ; + ui.pubKeyShare_cb->setText(tr("Add Wiki Moderators")); + ui.contactsdockWidget->setWindowTitle(tr("Select Wiki Moderators")); +} diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h index b4186c898..4c89e2ac0 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h @@ -125,7 +125,7 @@ public: * @param parent The parent dialog * @param mode */ - GxsGroupDialog(TokenQueue* tokenQueue, uint32_t enableFlags, uint16_t defaultFlags, QWidget *parent = NULL, const QString& serviceHeader = ""); + GxsGroupDialog(TokenQueue* tokenQueue, uint32_t enableFlags, uint16_t defaultFlags, QWidget *parent = NULL); /*! * Contructs a GxsGroupDialog for display a group or editing @@ -134,11 +134,11 @@ public: * @param parent */ GxsGroupDialog(const RsGroupMetaData& grpMeta, uint32_t mode = GXS_GROUP_DIALOG_SHOW_MODE, QWidget *parent = NULL); - void wikitype(); + void wikitype(); private: void newGroup(); - void setMode(uint32_t mode); + void setMode(uint32_t mode); // Functions that can be overloaded for specific stuff. @@ -147,6 +147,10 @@ protected slots: void addGroupLogo(); protected: + virtual void showEvent(QShowEvent*); + + virtual QString serviceHeader() = 0; + virtual QPixmap serviceImage() = 0; /*! * Main purpose is to help tansfer meta data to service diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui index b67f9eee4..c2811703c 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui @@ -25,53 +25,7 @@ 0 - - - - 16777215 - 64 - - - - - 11 - - - - - - - QFrame::NoFrame - - - QFrame::Raised - - - - 6 - - - - - - 48 - 48 - - - - - - - - - - - Create New - - - - - + @@ -103,7 +57,7 @@ 0 - + 64 @@ -116,24 +70,17 @@ 64 - - -border: 2px solid white; -border-radius: 10px; - + + QFrame::StyledPanel - - + + QFrame::Raised - - - :/images/channels.png:/images/channels.png + + :/images/channels.png - - - 64 - 64 - + + true @@ -195,11 +142,7 @@ border-radius: 10px; - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Key recipients can publish to restricted-type Wiki Group, and can view and publish for private-type channels</span></p></body></html> + Key recipients can publish to restricted-type Wiki Group, and can view and publish for private-type channels Share Publish Key @@ -518,33 +461,10 @@ p, li { white-space: pre-wrap; } - - - - Qt::Horizontal - - - - 238 - 20 - - - - - - - Cancel - - - - - - - Create - - - true + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok @@ -554,26 +474,26 @@ p, li { white-space: pre-wrap; } + + GxsIdChooser + QComboBox +
gui/gxs/GxsIdChooser.h
+
+ + HeaderFrame + QFrame +
gui/common/HeaderFrame.h
+ 1 +
FriendSelectionWidget QWidget
gui/common/FriendSelectionWidget.h
1
- - GxsIdChooser - QComboBox -
gui/gxs/GxsIdChooser.h
-
- - - - - - diff --git a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp index bee6c95cd..17668bb61 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp @@ -21,31 +21,28 @@ #include "GxsIdTreeWidgetItem.h" -#include - #include #include /** Constructor */ -GxsIdTreeWidgetItem::GxsIdTreeWidgetItem(QTreeWidget *parent) -:QTreeWidgetItem(parent), QObject(NULL), mTimer(NULL), mCount(0), mColumn(0) +GxsIdTreeWidgetItem::GxsIdTreeWidgetItem(const RSTreeWidgetItemCompareRole *compareRole, QTreeWidget *parent) +:RSTreeWidgetItem(compareRole, parent), QObject(NULL), mTimer(NULL), mCount(0), mColumn(0) { - mTimer = new QTimer(this); - mTimer->setSingleShot(true); - connect(mTimer, SIGNAL(timeout()), this, SLOT(loadId())); - - return; + init(); } -GxsIdTreeWidgetItem::GxsIdTreeWidgetItem(QTreeWidgetItem *parent) -:QTreeWidgetItem(parent), QObject(NULL), mTimer(NULL), mCount(0), mColumn(0) +GxsIdTreeWidgetItem::GxsIdTreeWidgetItem(const RSTreeWidgetItemCompareRole *compareRole, QTreeWidgetItem *parent) +:RSTreeWidgetItem(compareRole, parent), QObject(NULL), mTimer(NULL), mCount(0), mColumn(0) +{ + init(); +} + +void GxsIdTreeWidgetItem::init() { mTimer = new QTimer(this); mTimer->setSingleShot(true); connect(mTimer, SIGNAL(timeout()), this, SLOT(loadId())); - - return; } void GxsIdTreeWidgetItem::setId(const RsGxsId &id, int column) @@ -135,7 +132,6 @@ void GxsIdTreeWidgetItem::loadId() { /* timer event to try again */ mTimer->setInterval(mCount * 1000); - mTimer->start(); + mTimer->start(); } } - diff --git a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.h b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.h index 0db4b346e..9b61bff28 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.h +++ b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.h @@ -23,17 +23,18 @@ #ifndef _GXS_ID_TREEWIDGETITEM_H #define _GXS_ID_TREEWIDGETITEM_H -#include #include #include -class GxsIdTreeWidgetItem : public QObject, public QTreeWidgetItem +#include "gui/common/RSTreeWidgetItem.h" + +class GxsIdTreeWidgetItem : public QObject, public RSTreeWidgetItem { - Q_OBJECT + Q_OBJECT public: - GxsIdTreeWidgetItem(QTreeWidget *parent = NULL); - GxsIdTreeWidgetItem(QTreeWidgetItem *parent); + GxsIdTreeWidgetItem(const RSTreeWidgetItemCompareRole *compareRole, QTreeWidget *parent = NULL); + GxsIdTreeWidgetItem(const RSTreeWidgetItemCompareRole *compareRole, QTreeWidgetItem *parent); void setId(const RsGxsId &id, int column); bool getId(RsGxsId &id); @@ -42,6 +43,7 @@ private slots: void loadId(); private: + void init(); QTimer *mTimer; RsGxsId mId; diff --git a/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp b/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp index 6a4026714..dd7c23288 100644 --- a/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp @@ -52,7 +52,7 @@ uint32_t WikiCreateDefaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC | WikiGroupDialog::WikiGroupDialog(TokenQueue *tokenQueue, QWidget *parent) - :GxsGroupDialog(tokenQueue, WikiCreateEnabledFlags, WikiCreateDefaultsFlags, parent, "Create New Wiki Group") + :GxsGroupDialog(tokenQueue, WikiCreateEnabledFlags, WikiCreateDefaultsFlags, parent) { // To start with we only have open forums - with distribution controls. @@ -93,7 +93,6 @@ WikiGroupDialog::WikiGroupDialog(TokenQueue *tokenQueue, QWidget *parent) WikiGroupDialog::WikiGroupDialog(const RsWikiCollection &collection, QWidget *parent) :GxsGroupDialog(collection.mMeta, GXS_GROUP_DIALOG_SHOW_MODE, parent) - { #if 0 @@ -118,6 +117,15 @@ WikiGroupDialog::WikiGroupDialog(const RsWikiCollection &collection, QWidget *pa } +QString WikiGroupDialog::serviceHeader() +{ + return tr("Create New Wiki Group"); +} + +QPixmap WikiGroupDialog::serviceImage() +{ + return QPixmap(); +} bool WikiGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) { @@ -132,5 +140,3 @@ bool WikiGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData return true; } - - diff --git a/retroshare-gui/src/gui/gxs/WikiGroupDialog.h b/retroshare-gui/src/gui/gxs/WikiGroupDialog.h index fb217d36a..b35333065 100644 --- a/retroshare-gui/src/gui/gxs/WikiGroupDialog.h +++ b/retroshare-gui/src/gui/gxs/WikiGroupDialog.h @@ -35,7 +35,9 @@ public: WikiGroupDialog(const RsWikiCollection &collection, QWidget *parent); protected: - virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); + virtual QString serviceHeader(); + virtual QPixmap serviceImage(); + virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); private: diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForum.cpp b/retroshare-gui/src/gui/gxsforums/CreateGxsForum.cpp deleted file mode 100644 index 3c2a190d4..000000000 --- a/retroshare-gui/src/gui/gxsforums/CreateGxsForum.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/**************************************************************** - * RetroShare is distributed under the following license: - * - * Copyright (C) 2008 Robert Fernie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - ****************************************************************/ - -#include - -#include "util/misc.h" -#include "CreateGxsForum.h" -#include "gui/common/PeerDefs.h" - -#include - -#include -#include - -#include - -#define CREATEGXSFORUMS_NEWFORUMID 1 - - -/** Constructor */ -CreateGxsForum::CreateGxsForum(QWidget *parent) -: QDialog(parent) -{ - /* Invoke the Qt Designer generated object setup routine */ - ui.setupUi(this); - - mForumQueue = new TokenQueue(rsGxsForums->getTokenService(), this); - - // connect up the buttons. - connect( ui.cancelButton, SIGNAL( clicked ( bool ) ), this, SLOT( cancelForum( ) ) ); - connect( ui.createButton, SIGNAL( clicked ( bool ) ), this, SLOT( createForum( ) ) ); - connect( ui.pubKeyShare_cb, SIGNAL( clicked() ), this, SLOT( setShareList( ) )); - - if (!ui.pubKeyShare_cb->isChecked()) { - ui.contactsdockWidget->hide(); - this->resize(this->size().width() - ui.contactsdockWidget->size().width(), this->size().height()); - } - - /* initialize key share list */ - ui.keyShareList->setHeaderText(tr("Contacts:")); - ui.keyShareList->setModus(FriendSelectionWidget::MODUS_CHECK); - ui.keyShareList->start(); - - newForum(); -} - -void CreateGxsForum::newForum() -{ - /* enforce Public for the moment */ - ui.typePublic->setChecked(true); - - ui.typePrivate->setEnabled(false); - ui.typeEncrypted->setEnabled(true); - -#ifdef RS_RELEASE_VERSION - ui.typePrivate->setVisible(false); - ui.typeEncrypted->setVisible(true); -#endif - - ui.msgAnon->setChecked(true); - //ui.msgAuth->setEnabled(false); - - ui.forumName->clear(); - ui.forumDesc->clear(); - - ui.forumName->setFocus(); -} - -void CreateGxsForum::createForum() -{ - QString name = misc::removeNewLine(ui.forumName->text()); - QString desc = ui.forumDesc->toPlainText(); //toHtml(); - uint32_t flags = 0; - - if(name.isEmpty()) { - /* error message */ - QMessageBox::warning(this, "RetroShare", tr("Please add a Name"), QMessageBox::Ok, QMessageBox::Ok); - return; //Don't add a empty name!! - } - -#ifdef TOGXS - if (ui.typePublic->isChecked()) { - flags |= RS_DISTRIB_PUBLIC; - } else if (ui.typePrivate->isChecked()) { - flags |= RS_DISTRIB_PRIVATE; - } else if (ui.typeEncrypted->isChecked()) { - flags |= RS_DISTRIB_ENCRYPTED; - } - - if (ui.msgAuth->isChecked()) { - flags |= RS_DISTRIB_AUTHEN_REQ; - } else if (ui.msgAnon->isChecked()) { - flags |= RS_DISTRIB_AUTHEN_ANON; - } -#endif - - if (rsGxsForums) { - - - uint32_t token; - RsGxsForumGroup grp; - grp.mMeta.mGroupName = std::string(name.toUtf8()); - grp.mDescription = std::string(desc.toUtf8()); - grp.mMeta.mGroupFlags = flags; - - rsGxsForums->createGroup(token, grp); - - // get the Queue to handle response. - mForumQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_SUMMARY, CREATEGXSFORUMS_NEWFORUMID); - - } -} - -void CreateGxsForum::completeCreateNewForum(const RsGroupMetaData &newForumMeta) -{ - sendShareList(newForumMeta.mGroupId); - - close(); -} - - -void CreateGxsForum::sendShareList(std::string forumId) -{ - if (!rsGxsForums) - { - std::cerr << "CreateGxsForum::sendShareList() GxsForums not active"; - std::cerr << std::endl; - return; - } - - if (ui.pubKeyShare_cb->isChecked()) - { - std::list shareList; - ui.keyShareList->selectedSslIds(shareList, false); -#ifdef TOGXS - rsGxsForums->groupShareKeys(forumId, shareList); -#endif - } - close(); -} - - - - - - -void CreateGxsForum::setShareList() -{ - if (ui.pubKeyShare_cb->isChecked()){ - this->resize(this->size().width() + ui.contactsdockWidget->size().width(), this->size().height()); - ui.contactsdockWidget->show(); - } else { // hide share widget - ui.contactsdockWidget->hide(); - this->resize(this->size().width() - ui.contactsdockWidget->size().width(), this->size().height()); - } -} - -void CreateGxsForum::cancelForum() -{ - close(); -} - - - - -void CreateGxsForum::loadNewForumId(const uint32_t &token) -{ - std::cerr << "CreateGxsForum::loadNewForumId()"; - std::cerr << std::endl; - - std::list groupInfo; - rsGxsForums->getGroupSummary(token, groupInfo); - - if (groupInfo.size() == 1) - { - RsGroupMetaData fi = groupInfo.front(); - completeCreateNewForum(fi); - } - else - { - std::cerr << "CreateGxsForum::loadNewForumId() ERROR INVALID Number of Forums Created"; - std::cerr << std::endl; - } -} - - - - - - - - -void CreateGxsForum::loadRequest(const TokenQueue *queue, const TokenRequest &req) -{ - std::cerr << "CreateGxsForum::loadRequest() UserType: " << req.mUserType; - std::cerr << std::endl; - - if (queue == mForumQueue) - { - /* now switch on req */ - switch(req.mUserType) - { - - case CREATEGXSFORUMS_NEWFORUMID: - loadNewForumId(req.mToken); - break; - default: - std::cerr << "CreateGxsForum::loadRequest() UNKNOWN UserType "; - std::cerr << std::endl; - - } - } -} - - - diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForum.h b/retroshare-gui/src/gui/gxsforums/CreateGxsForum.h deleted file mode 100644 index 05ca6d1c5..000000000 --- a/retroshare-gui/src/gui/gxsforums/CreateGxsForum.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************** - * RetroShare is distributed under the following license: - * - * Copyright (C) 2008 Robert Fernie - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - ****************************************************************/ - - -#ifndef _CREATE_GXSFORUM_DIALOG_H -#define _CREATE_GXSFORUM_DIALOG_H - -#include "ui_CreateGxsForum.h" - -#include "util/TokenQueue.h" - -class CreateGxsForum : public QDialog, public TokenResponse -{ - Q_OBJECT - -public: - CreateGxsForum(QWidget *parent = 0); - - void newForum(); /* cleanup */ - - // Callback for all Loads. -virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); - -private slots: - /* actions to take.... */ - void createForum(); - void cancelForum(); - - // set private forum key share list - void setShareList(); - -private: - void sendShareList(std::string forumId); - void completeCreateNewForum(const RsGroupMetaData &newForumMeta); - void loadNewForumId(const uint32_t &token); - - - std::list mShareList; - - QPixmap picture; - - TokenQueue *mForumQueue; - - /** Qt Designer generated object */ - Ui::CreateGxsForum ui; -}; - -#endif - diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForum.ui b/retroshare-gui/src/gui/gxsforums/CreateGxsForum.ui deleted file mode 100644 index 85f7acf24..000000000 --- a/retroshare-gui/src/gui/gxsforums/CreateGxsForum.ui +++ /dev/null @@ -1,374 +0,0 @@ - - - CreateGxsForum - - - - 0 - 0 - 672 - 495 - - - - Create new Forum - - - - :/images/rstray3.png:/images/rstray3.png - - - - 0 - - - 0 - - - - - - 16777215 - 64 - - - - QFrame#frame_2{background-image: url(:/images/connect/connectFriendBanner.png);} - - - QFrame::NoFrame - - - QFrame::Raised - - - - 6 - - - 6 - - - - - - 48 - 48 - - - - - - - - - - :/images/konversation64.png - - - true - - - - - - - color: rgb(255, 255, 255); - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Arial'; font-size:24pt; font-weight:600; color:#ffffff;">New Forum</span></p></body></html> - - - - - - - - - - QFrame::NoFrame - - - QFrame::Raised - - - - - - - - Name - - - - - - - - - - - - true - - - - 0 - 0 - - - - - 300 - 524287 - - - - - 220 - 0 - - - - - 0 - 0 - - - - check peers you would like to share private publish key with - - - false - - - QDockWidget::NoDockWidgetFeatures - - - Share Key With - - - - - 0 - - - 0 - - - - - - 0 - 4 - - - - - 20 - 0 - - - - - 300 - 16777215 - - - - - 220 - 0 - - - - - 200 - 0 - - - - - - - - - - - - - - Description - - - - - - - - - - - - Type: - - - - 6 - - - - - Public - Anyone can read and publish (Shared Publish Key) - - - - - - - Restricted - Anyone can read, limited publishing (Private Publish Key) - - - - - - - Private - (Private Publish Key required to view Messages) - - - - - - - - - - Key Sharing - - - - 0 - - - 6 - - - - - Key recipients can publish to restricted-type channels, and can view and publish for private-type channels - - - Share Private Publish Key - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - Allowed Messages - - - - 0 - - - 6 - - - - - Authenticated Messages - - - - - - - Anonymous Messages - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - Qt::Horizontal - - - - 238 - 20 - - - - - - - - Cancel - - - - - - - Create - - - true - - - - - - - - - - - FriendSelectionWidget - QWidget -
gui/common/FriendSelectionWidget.h
- 1 -
-
- - - - -
diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp index eb8df4a9c..864fe9fb3 100644 --- a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp @@ -35,6 +35,7 @@ #include "gui/RetroShareLink.h" #include "gui/common/Emoticons.h" +#include "util/HandleRichText.h" #include "util/misc.h" #include @@ -46,8 +47,8 @@ /** Constructor */ -CreateGxsForumMsg::CreateGxsForumMsg(std::string fId, std::string pId) -: QMainWindow(NULL), mForumId(fId), mParentId(pId) +CreateGxsForumMsg::CreateGxsForumMsg(const std::string &fId, const std::string &pId) +: QDialog(NULL, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), mForumId(fId), mParentId(pId) { /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); @@ -56,6 +57,12 @@ CreateGxsForumMsg::CreateGxsForumMsg(std::string fId, std::string pId) /* Setup Queue */ mForumQueue = new TokenQueue(rsGxsForums->getTokenService(), this); + QString text = pId.empty() ? tr("Start New Thread") : tr("Post Forum Message"); + setWindowTitle(text); + + ui.headerFrame->setHeaderImage(QPixmap(":/images/konversation64.png")); + ui.headerFrame->setHeaderText(text); + Settings->loadWidgetInformation(this); connect( ui.forumMessage, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( forumMessageCostumPopupMenu( QPoint ) ) ); @@ -63,8 +70,8 @@ CreateGxsForumMsg::CreateGxsForumMsg(std::string fId, std::string pId) connect(ui.hashBox, SIGNAL(fileHashingFinished(QList)), this, SLOT(fileHashingFinished(QList))); // connect up the buttons. - connect( ui.postmessage_action, SIGNAL( triggered (bool) ), this, SLOT( createMsg( ) ) ); - connect( ui.close_action, SIGNAL( triggered (bool) ), this, SLOT( cancelMsg( ) ) ); + connect( ui.buttonBox, SIGNAL(accepted()), this, SLOT(createMsg())); + connect( ui.buttonBox, SIGNAL(rejected()), this, SLOT(close())); connect( ui.emoticonButton, SIGNAL(clicked()), this, SLOT(smileyWidgetForums())); connect( ui.attachFileButton, SIGNAL(clicked() ), this , SLOT(addFile())); connect( ui.pastersButton, SIGNAL(clicked() ), this , SLOT(pasteLink())); @@ -80,9 +87,9 @@ CreateGxsForumMsg::CreateGxsForumMsg(std::string fId, std::string pId) } /** context menu searchTablewidget2 **/ -void CreateGxsForumMsg::forumMessageCostumPopupMenu( QPoint /*point*/ ) +void CreateGxsForumMsg::forumMessageCostumPopupMenu(QPoint point) { - QMenu *contextMnu = ui.forumMessage->createStandardContextMenu(); + QMenu *contextMnu = ui.forumMessage->createStandardContextMenu(point); contextMnu->addSeparator(); QAction *pasteLinkAct = contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste RetroShare Link"), this, SLOT(pasteLink())); @@ -233,10 +240,9 @@ void CreateGxsForumMsg::loadFormInformation() void CreateGxsForumMsg::createMsg() { QString name = misc::removeNewLine(ui.forumSubject->text()); - QString desc = ui.forumMessage->toHtml(); + QString desc; - if(desc == QTextDocument(ui.forumMessage->toPlainText()).toHtml()) - desc = ui.forumMessage->toPlainText() ; + RsHtml::optimizeHtml(ui.forumMessage, desc); if(name.isEmpty()) { /* error message */ @@ -324,11 +330,6 @@ void CreateGxsForumMsg::closeEvent (QCloseEvent * /*event*/) Settings->saveWidgetInformation(this); } -void CreateGxsForumMsg::cancelMsg() -{ - close(); -} - void CreateGxsForumMsg::smileyWidgetForums() { Emoticons::showSmileyWidget(this, ui.emoticonButton, SLOT(addSmileys()), false); diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.h b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.h index a3be9e183..7227234fd 100644 --- a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.h +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.h @@ -29,17 +29,16 @@ #include - -class CreateGxsForumMsg : public QMainWindow, public TokenResponse +class CreateGxsForumMsg : public QDialog, public TokenResponse { Q_OBJECT public: - CreateGxsForumMsg(std::string fId, std::string pId); + CreateGxsForumMsg(const std::string &fId, const std::string &pId); void newMsg(); /* cleanup */ virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); - + private slots: /** Create the context popup menu and it's submenus */ void forumMessageCostumPopupMenu( QPoint point ); @@ -47,7 +46,6 @@ private slots: void fileHashingFinished(QList hashedFiles); /* actions to take.... */ void createMsg(); - void cancelMsg(); void pasteLink(); void pasteLinkFull(); void pasteOwnCertificateLink(); @@ -60,17 +58,16 @@ protected: void closeEvent (QCloseEvent * event); private: - void saveForumInfo(const RsGroupMetaData &meta); void saveParentMsg(const RsGxsForumMsg &msg); void loadFormInformation(); void loadForumInfo(const uint32_t &token); void loadParentMsg(const uint32_t &token); - + std::string mForumId; std::string mParentId; - + bool mParentMsgLoaded; bool mForumMetaLoaded; RsGxsForumMsg mParentMsg; diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.ui b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.ui index 40d8dcb15..fcd330af9 100644 --- a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.ui +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.ui @@ -1,16 +1,13 @@ CreateGxsForumMsg - - - Qt::NonModal - + 0 0 482 - 497 + 448 @@ -20,24 +17,27 @@ :/images/rstray3.png:/images/rstray3.png - - QToolBar#toolBar{background-image: url(:/images/connect/connectFriendBanner.png)} - - - Qt::ToolButtonTextUnderIcon - - - - - 0 - - - 0 - - - - - + + + 0 + + + 0 + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + QFrame::NoFrame @@ -45,64 +45,49 @@ QFrame::Raised - - 6 - - - 6 + + 0 - - - - - Forum - - - - - - - false - - - - + + + Forum + + + + + + + false + + - - - - - Subject - - - - - - - + + + Subject + + + + + - - + + 16777215 38 - - QFrame#frame_2{ -background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, -stop:0 #FEFEFE, stop:1 #E8E8E8); - -border: 1px solid #CCCCCC;} + + QFrame::Box - QFrame::Raised + QFrame::Sunken @@ -219,107 +204,65 @@ border: 1px solid #CCCCCC;}
- - - - QFrame::NoFrame + + + + Forum Post - - QFrame::Raised - - - - 6 - - - 6 - + - - - Forum Post + + + Qt::CustomContextMenu - - - - - Qt::CustomContextMenu - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;"></p></body></html> - - - - - - - - - - Attach files via drag and drop +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></p></body></html> - - - - - - 0 - 0 - - - - You can attach files via drag and drop here in this window - - - true - - - - + + + + Attach files via drag and drop + + + + + + + 0 + 0 + + + + You can attach files via drag and drop here in this window + + + true + + + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + - - - - - - toolBar - - - TopToolBarArea - - - false - - - - - - - - :/images/mail_send24.png:/images/mail_send24.png - - - Post Forum Msg - - - - - - :/images/button_cancel.png:/images/button_cancel.png - - - Close - - + + + @@ -327,6 +270,12 @@ p, li { white-space: pre-wrap; } QComboBox
gui/gxs/GxsIdChooser.h
+ + HeaderFrame + QFrame +
gui/common/HeaderFrame.h
+ 1 +
HashBox QScrollArea diff --git a/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.cpp b/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.cpp index 13ebfe43e..840a7f47f 100644 --- a/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.cpp +++ b/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.cpp @@ -31,13 +31,14 @@ /** Default constructor */ -EditGxsForumDetails::EditGxsForumDetails(std::string forumId, QWidget *parent, Qt::WFlags flags) - : QDialog(parent, flags), m_forumId(forumId) +EditGxsForumDetails::EditGxsForumDetails(std::string forumId, QWidget *parent) + : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint), m_forumId(forumId) { /* Invoke Qt Designer generated QObject setup routine */ ui.setupUi(this); - connect(ui.applyButton, SIGNAL(clicked()), this, SLOT(applyDialog())); + connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(applyDialog())); + connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(close())); loadForum(); } diff --git a/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.h b/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.h index 3a38cc7c9..b21fadafc 100644 --- a/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.h +++ b/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.h @@ -32,7 +32,7 @@ class EditGxsForumDetails : public QDialog public: /** Default constructor */ - EditGxsForumDetails(std::string forumId = "", QWidget *parent = 0, Qt::WFlags flags = 0); + EditGxsForumDetails(std::string forumId = "", QWidget *parent = 0); signals: void configChanged(); diff --git a/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.ui b/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.ui index b211bd0e6..483e94a2f 100644 --- a/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.ui +++ b/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.ui @@ -21,35 +21,9 @@ - - - Qt::Horizontal - - - - 311 - 20 - - - - - - - - Cancel - - - - - - - OK - - - false - - - true + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok @@ -109,22 +83,5 @@ - - - cancelButton - clicked() - EditForumDetails - close() - - - 307 - 333 - - - 217 - 177 - - - - + diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumDetails.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumDetails.cpp index 3f26dc1c5..ed45f8dfd 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumDetails.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumDetails.cpp @@ -19,6 +19,7 @@ * Boston, MA 02110-1301, USA. ****************************************************************/ #include "GxsForumDetails.h" +//#AFTER MERGE #include "util/DateTime.h" #include #include @@ -37,16 +38,13 @@ #define DATETIME_FMT "MMM dd hh:mm:ss" /** Default constructor */ -GxsForumDetails::GxsForumDetails(QWidget *parent, Qt::WFlags flags) - : QDialog(parent, flags) +GxsForumDetails::GxsForumDetails(QWidget *parent) + : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint) { /* Invoke Qt Designer generated QObject setup routine */ ui.setupUi(this); - connect(ui.applyButton, SIGNAL(clicked()), this, SLOT(applyDialog())); - connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(closeinfodlg())); - - ui.applyButton->setToolTip(tr("Apply and Close")); + connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(close())); ui.nameline ->setReadOnly(true); ui.popline ->setReadOnly(true); @@ -72,16 +70,6 @@ GxsForumDetails::show() } } -void GxsForumDetails::closeEvent (QCloseEvent * event) -{ - QWidget::closeEvent(event); -} - -void GxsForumDetails::closeinfodlg() -{ - close(); -} - void GxsForumDetails::showDetails(std::string mCurrForumId) { fId = mCurrForumId; @@ -108,10 +96,7 @@ void GxsForumDetails::loadDialog() // Set Last Post Date if (fi.lastPost) { - QDateTime qtime; - qtime.setTime_t(fi.lastPost); - QString timestamp = qtime.toString("yyyy-MM-dd hh:mm:ss"); - ui.postline->setText(timestamp); + ui.postline->setText(DateTime::formatLongDateTime(fi.lastPost)); } // Set Forum ID @@ -133,14 +118,3 @@ void GxsForumDetails::loadDialog() #endif } - -void GxsForumDetails::applyDialog() -{ - - /* reload now */ - loadDialog(); - - /* close the Dialog after the Changes applied */ - closeinfodlg(); - -} diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumDetails.h b/retroshare-gui/src/gui/gxsforums/GxsForumDetails.h index a45f9d018..d7c014262 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumDetails.h +++ b/retroshare-gui/src/gui/gxsforums/GxsForumDetails.h @@ -33,8 +33,7 @@ class GxsForumDetails : public QDialog public: /** Default constructor */ - GxsForumDetails(QWidget *parent = 0, Qt::WFlags flags = 0); - /** Default destructor */ + GxsForumDetails(QWidget *parent = 0); void showDetails(std::string mCurrForumId); @@ -45,14 +44,6 @@ public slots: /** Overloaded QWidget.show */ void show(); -protected: - void closeEvent (QCloseEvent * event); - -private slots: - - void closeinfodlg(); - void applyDialog(); - private: void loadDialog(); diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumDetails.ui b/retroshare-gui/src/gui/gxsforums/GxsForumDetails.ui index 182d7bc63..b6dfb4c1e 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumDetails.ui +++ b/retroshare-gui/src/gui/gxsforums/GxsForumDetails.ui @@ -158,35 +158,9 @@ - - - Qt::Horizontal - - - - 311 - 20 - - - - - - - - Cancel - - - - - - - OK - - - false - - - true + + + QDialogButtonBox::Close From ff52e3751b55331af6f6d1236c5ce755e9d60081 Mon Sep 17 00:00:00 2001 From: drbob Date: Wed, 21 Nov 2012 22:13:08 +0000 Subject: [PATCH 168/222] fix #include (missing capitals) git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5870 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui index c0b45cb68..da4436fd7 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui @@ -391,7 +391,7 @@ p, li { white-space: pre-wrap; } HeaderFrame QFrame -
gui/common/headerframe.h
+
gui/common/HeaderFrame.h
1
From 1513da30b9092ddbdf89fb66da806cbe95b34749 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Wed, 21 Nov 2012 23:35:33 +0000 Subject: [PATCH 169/222] Removed empty directory. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5871 b45a01b8-16f6-495d-af2f-9b41ad6348cc From ffff660bbdee3074647acfbdaf6321b141d2d6c5 Mon Sep 17 00:00:00 2001 From: defnax Date: Thu, 22 Nov 2012 11:52:24 +0000 Subject: [PATCH 170/222] Added to display a default Album Thumbnail, when Album has no Thumbnail ( temporary solution ) git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5872 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/gui/PhotoShare/AlbumDialog.cpp | 11 ++++++++++- .../src/gui/PhotoShare/AlbumItem.cpp | 11 ++++++++++- .../src/gui/PhotoShare/Photo_images.qrc | 3 ++- .../gui/PhotoShare/images/album_create_64.png | Bin 4554 -> 4543 bytes .../PhotoShare/images/album_default_128.png | Bin 0 -> 21446 bytes 5 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 retroshare-gui/src/gui/PhotoShare/images/album_default_128.png diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp index fefe8b261..d198db140 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp @@ -38,7 +38,16 @@ void AlbumDialog::setUp() QPixmap qtn; qtn.loadFromData(mAlbum.mThumbnail.data, mAlbum.mThumbnail.size, mAlbum.mThumbnail.type.c_str()); - ui->label_thumbNail->setPixmap(qtn); + + if(mAlbum.mThumbnail.size != 0) + { + ui->label_thumbNail->setPixmap(qtn); + } + else + { + // display a default Album icon when album has no Thumbnail + ui->label_thumbNail->setPixmap(QPixmap(":/images/album_default_128.png")); + } } void AlbumDialog::updateAlbumPhotos(){ diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumItem.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumItem.cpp index ab9de9797..ad74bdabb 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumItem.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumItem.cpp @@ -23,7 +23,16 @@ void AlbumItem::setUp() ui->label_Photographer->setText(QString::fromStdString(mAlbum.mPhotographer)); QPixmap qtn; qtn.loadFromData(mAlbum.mThumbnail.data, mAlbum.mThumbnail.size, mAlbum.mThumbnail.type.c_str()); - ui->label_Thumbnail->setPixmap(qtn); + + if(mAlbum.mThumbnail.size != 0) + { + ui->label_Thumbnail->setPixmap(qtn); + } + else + { + // display a default Album icon when album has no Thumbnail + ui->label_Thumbnail->setPixmap(QPixmap(":/images/album_default_128.png")); + } } void AlbumItem::mousePressEvent(QMouseEvent *event) diff --git a/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc b/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc index bf435030e..519bf66ee 100644 --- a/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc +++ b/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc @@ -6,6 +6,7 @@ images/album_64.png images/album_subscribe.png images/album_unsubscribe.png - images/album_create_64.png + images/album_create_64.png + images/album_default_128.png
diff --git a/retroshare-gui/src/gui/PhotoShare/images/album_create_64.png b/retroshare-gui/src/gui/PhotoShare/images/album_create_64.png index f19ea20eeb7eafbba0188572a56b6ee56eb8efb0..a8392c0abbe16c834453b96e452097b34444e8f7 100644 GIT binary patch delta 4505 zcmV;K5oYenBfle%EC?1087Y2kku#ArD1S~#L_t(|+U;6vj9u4N-g}>Yp7-3x+cnYCFtkmJ>n1Avsi=fRp`aiH;s@dn{NNw_DMFPHQbmbCP+D3FZky25 zvD<{yO^A~?aqLNK$If^jcjnH_eV_L^d$Z2_%)<{7Dl1a9t-1G{Ip^&4t@W*Mt$)4G zV9q)EAP;i84fqhi?Ka>;0JqzK4*}e61K#hTPzRoV`sv$k#(Nycjvb?>X~MUoM~?=+ zPY8mthB2JL*+m%R>)pTZS8EQ}J|r3(r8P6Fp7EEBhw;e1=O?4jAmECkoIH6F&Qs6x zZnq!*Z$lJiQOpl%<~D&+_!)TKdVi1Ojh@V0zV<@A=B^E6O$2cI1>I@{!n-%NJv9Cx zB+2GufA&mtL&zkOSPO>n*dm_&i*T{x15-;1+)1EkSm1$RIF261lh5pes)UQBX+&yPy-1O$=uN!HLgPl#$h7+9rCk9)LiE&~|WkdRyi;%;T_!?oHwv zMk(=m==;cK9;;F8o_IKc6~-dFk3>!-$s;f?$N?vX>`1-LQw=8}b)zuiESVxi8{}jY07M8W z#A1H%nEq*?6GkL_hyoS+I=qOWG+2rKk=xSgIV!k3iRn5Ci+P^LJAZ-@Qx~BW3XZ~k zGYXM{tvrfElDL@+#;g(20Fi>-xBvs^8Jd4)DPG`C1|{=wO5fzdI3r>_Hv>QfU}%_{ zsiBFDI8mLH>fysu4yEi~D~oHwohCI;(jetjdXQ>Zmd6?6Q$-4S#rekOZIcM_f)_*O zWDy^5EMsvA%EMoD3V%*2Mpiiz^-c5$Cqyf#%Nmu45pkTVP<9DUQh+hGvG>dXBvxRW zDP3ejXg$NRqK2(f!i}7YILmUL$W!>+*n=tK5=M~p_Yv&md}1&|xz+g{DTG*pfF1be zIUo?u^YDY3@>Kb8UXj;;j+H-7chDY!d6u)WV#OiIJ9AzF&goCI2K^diPh9ngaq)Gb%k7aVY_irB%+ROegc)Obt%$EFNY9<3dPcCdJB-7V_jO6p0Al#Q4o3 zAPUf;WwWd?hJUXOAx=tiYy`n;e^(SGlmrc>VxB2%F7t&uaUq41#E&~m&NsoZJ_1BY zRyAm?xu}?uIi#d_OnN?;i_q|pd3h3Kod}La5U*`@6T+ubkcn*GuHaPOGH=}o02OfN z^|YBqD2IgdqLij+>|r8EzGn;Oyys(SXd7ZdmbKZ9sefa$hA^oq`LlBX2<1e|I@?XU zxedLLARt`WFU>NrNS(Z2NFyM~z4P>MpMC<1A`1eNcEBm+(tB~P2?f@r znv?}3YG4Z$cw+!E0I8J%#i)?(iKJwFj;1Y45YbeWz4M^FIH=mW_%1T>A-Fffe1j% z?J#`VVyplo*GMc<``UTs+;LGPvM#T*jM2I>Qh$?<9KPf7izofZK1&6fJw7TRJY6Of zif%EQ8N*V)fuz7QfY&StZ??K!gsL~p0g~|tr+qwM*KH-vqJrORk?CjP0yjXuX|1gG zC%5YDjyLi&Pwsx; zF@HE`_MFDdOlN8K%@7n7`PVL}4W;^)3ceT#9SqKIAF z9j=!&S@0{0AMibO`qTgT_80&34{Q?`xsYWvJm|+i{hQA|a;Rf=TisS@eSk0{6C)FQ z>r-Dp^%WG<&OZ0l+?ChOcGI_E7I#=zHGffC@9}lYM1@pZaJo3mvIOIFZ4d^=eC3C< zJ1>jpcwR$qMKx$g3Bjc+gc9*XnXccG)qF?fMLW6m6V z^z$o=4GOMyZ3ze$?sfw>+E-4dZJz_ZP68bSOgz=+|!7(+BY`OflN3BA%E|r zk|wRt%f!`C5b5C3tMcmGYFYFA;NsP$(H~6h8Jifdx*P`#R=3!60-abdpZrhmcUudK zdcD5)z=M15K3J(K@HF2Kp9lQzlb%8QJ<=6yU?cz_{XxHNwM&w4^y3fisE@Um+u$r+ zr!QZcZUxTA@4EMT0J7r%7dnVsw12bQ5(L(7@+&WvOA3^2+j2&#^4~|ZBFTHb78}nyQe{FSj&|0x=+dc8Gf4}3-JMTL5OLrbTylwZCB#JPJpbA96tQ;`H zm_dn00_I~8E0VgaKI#s-b1Ms2CgWml@5IE(=~w2KrR%6rN)^iNf+mqXzB<>wXKGt#V4c5o`P9qjo1OO9C`7+HRvT%F&WzKWwVQ&> zm)<=;JN??Je^bV{Z-Xi~t4{Cv#6eLK1;`u@v1HgKz$-3r2BPCTt$xoyrYe#?kz8)7 zlF(<1H<3}y-JJPZ(MXnA0DnMSdE+^ow&^)03e*OIOXU@$vSAu}4 zic~F;u~F9Pb_X`^_094y^##xONJT2aDzDp^^B5<)Jff0tt5c?6v8#H>g2eE+z+e^C zH%yA+qczp_>_)SF z;oZiiYl~pCWjl`R>6)~2%TPrF0;7-YtU_b%xW;_La23Nb9ZsUnWfYWE1sV-2@EEuh z07z7j1ma^(nJ)!C@_4j#Baqb8hn}z7b*L{IynnuT0n5U5B9H;_LCkQ#xeyH$tq@=_ z+U>OF&b@Z|)#v6fy?^HT{&KUk(i)hyt?H5@i39~et}(sx(OtVHw~o%N%$0)L)#f}c zduo|c%jZ~-WWqe|I*{Z+MNvdwXuA$102KuyVdRASeqod_T+A5fp6hVm?;D;&`-{8> zZPm`w#MbRYn*(539iU(^)m6bZsw8(!v)6TZ)wf9)s;fN* zswqQv5VriBK>G^$>v_n7b-3fZRu38x*Yq863!fBgQdbu>ddJA zoYv~he1q1wZGRgiz#>FhgcU#5m;_uNC8Fw3c>^jJuvWF|~WX zc}Xsr){=0?_zpgBgU+Bw2aQ&L-?j-B7$Vh8%f}TYOELq0qaZ+#ydH?X$J|m`H3R4M z*{dU^3LWBmwC%)VZ#5T6y4+rrHwOTD6n}a7*zV^ypU)-ydlq%E+y?>;ZG)+@$8g|1;jmmKgnp$XNf+%uG!`R4A)af0MM zyMHELdwc%$OVbl$;`48xCHwnVeFJLNHf>^}I-yrfN(pj7qTwbP=y1?7mwNqyVH@z@ zw9UX~jn&!KLQ|wr9Yk1N2_#BN_>{u$piP!yczqkhdR-kzLU7Lm1IxAH`2%yQs)`@E zM}lzs0Ufx5T4izDB;NMPeF9gzeM6Q61Ah|D?`)qKy6fKE3k#P=>sLyZ@^6k;8?9C7 zx@M8|w&B?`ea~__MyoNH8}5&cmB;E@U8NdiZr}&5*%Y+gr5`P4| zheQyoaQg)UYB9$@&m5PFQYat3gDBh%_$|KJhYqF8J2;@o6wO$U2X=o+UMxwvPRbIO zpcpv770Yr4E^c8wpj6^i69NrknG+E)fk(S9&|@J4ow>&Y>|+&Yd!!qBAy^<1YWuDZ z9+06$;c6K=XDGKEsylOn5-5?1YJaK-8VN*Fm|Q{RQp55ns*GYt&hS-5iHr>6r7jEA z-NsPXhgGiW3nPu`YpqJVG^CEwk$Z*@OjhmG>`$_n^1MUC-0TVFU zw)KJ_k~IKeF&=+;?t8uB{_T5vO&@PVedX(a{nn-F@BiI#(+!shVSms`x(5%MCX1C) z`RMOHey%#bs9Ym; zo9$d|YJIkoldOf(br8=s03Uwf;h|dX(1Ano%Ypp)(Ex^g_4rp8-&rKX7?%;LVy&c= z^|Gdx=Gs?jPyF*={eKI`bCUPc@jLG5rMIe-K$`B|ec$Tr>KXv?mLdrQ{C*=4qj~7y zL-0R6waFh!{PU@QX?B|8Rt4!uQmLw_Fv?o_8lSBx!(Tf3rA_}(qFhdPC7zmn3Po=v zLo)s7#EF}`{r`I`udI}uk|ZLcB2fy50z+277wvB6*^{Sk<$oa*Kp#1B#BrSWX2kpX ztIhJim!ZK15`f+VrvZQ{!ukwW6N0YmhYugV!M)&jXiH%Bu+r(#_<8zz^C40ZdY@38 zgmCpj!XM#))S{G*jEvmMLvHI|Y(e91=PzQi5$|x_;<()aBJ~C)u&~lb1HO766aXmf zX`!p;J`bYd!+(Gl&j~&-0EDO}`yO%v$MK{8flYkj)&bC4z3}HSAZy3fac9{c>er|& zh+HNE&uInI;w=@IEXra~|*0z4(k>B_L0DxXY rFY95q7LRn(7xMVv)WKVP$o~QZh01b0E3&Qt0000}13?j%fee;ntD1TW=L_t(|+U;6dj2%~6KIhb_z3$Sx-Q9LO zUOI_m$0j(j2?>FL3G$dk6JADukfLFbSR{l5;$+tUwidpdq@;{BIR_e@2z|5RQ=2MfB$z*HGk%u zqfhc6ciVtZ9k|;DeCoj6HsDhS?zRCRbx`O7FTVKV-8SPxjw45oP}4Nw-QmNB1K%eE zL0iKZKET;Y7~@;bU-Q+f!_^mw21jYn%(`d%X8mD2viJFi(Q6QJMNy6)KMtQ$&-3nf z9RGhq6lGD&4`~)Qfl~Mzc;4EGR=i+pNdY^F>zOZbK`N)AzMI*MHg?|+U{zsM>t z!_Rrax2)*$GjZ-w?mPrEaRT4Y0XRztjg0OT8o{Gkq1o^*{0b+xz|oyqfb~-H!8|HD^!|*0~ z4YQQQJdAy0GmqIQ4srq$oPW|AM(IHYwb)SjK*->P6GkI(nj;(#T!7nc9H4}-&P22GoevAR(KNO#H}zF**p>jl_ZzIyg&z>6sjYQGEX_2gwT!Bh_hmfJX%L58#q9O z5JD`*2an;OCOSbxf`=$kaje6W2uhQc*dK*0y*)>TkS94^Lt!z_(|>$NF2vA9D0Kx# z>An+$NWoSfWg;ouj0R)W2x)>y!ERh|1LqZ*zh)&~z)t2$7U2}W$%%1A#QxmL0U`iG z!_rI*O>D#o>!eT*FP35`MfYl2T$S#$sCiNbDW=kcl*6(*&Jdq6Qivlu8LUawy`g%6URh;kR)FQ^X~RAnEs!+sWsN!3^bA=QC0lVhRFu z;5*lVKse9S4{XX)=Er$QUgdPm{BgMh_YlmpnvEGNPC-Ur34fIqY6hjiN;o)gVKIa_ z$@{n)t{XVYBAO5fPw|5?TqQ1~jF1L70}IdKk~%J($69+B@Sd|m7^)+$-FjGgHt<;huOfmkdhclF*Br%JUI(RB!V|E zexnSC0!Xy%E`O_x;j2@Kla?GCLGbGDill^+q@k3|GltD+zAzIPN;oO}SXpwufe&jl zK!jvfgI1f1iY1x5lxW99^TE9c4G)=@7eS^(a7==DwbV@jpHe|avbkKrDZORUx}5`5 zz**E&F^f>{63UxWTB31;i6Hr&EtqqjkEOm*#Dc79vww+cU^79O^pyPCxdRC0K+2Tu z25N4d77_%63;U&61s0)`>xDD}g4~`vD_nlHj2g9GS$*>Nuqd)1AgKaQA(zg@IVTiQ zmvT~;kVwE5I`H}gWDcZO3KXM4xhIs8;W@f(;RX>*McJEsZ}9R9eG;|<_43&tx%IC+ z@jHJcgn#*CtKymlGtp}4opUXLbIljAT%w>0JaEfCP=HY0nljAcJm`7Gqia(U&7ae+ zyySX;2`g;hefYtx|L`wIwXt2l^y^PKwwFdNTlo~>kt3fM0AK9ZD6RO|xkQ28CIgWJ zF}B0>Ws9+b8#zZ}k=obKE9Z`iB9RSwsnHwiSAPbp(h~>oxqRxl|J3KGK(ot74TPu5 zghJCTW-~)r8aJR6xCY>w1>t0?)k3Ip+ZrGlesHSe`5LvA1d9rOyFsR2f)m^T`KGnB z+}X0(SZVflPj0$;a=y8=JTg8U_`DcQTvXE0%Z0N?Uw-v3I=v1Lq7S1r9&llQU;mR& z{(tGjjwfp~GtI>t@0~i)hWcvE|MAK1ZRXHpWkqb+ z?m)k;$%0>2{DAN1r*Hn}H-Gcb{?ImY5er#GXOjDsH~;o?j~{57twyU6S|1?H$k^c6 z&i={2`nNyPJ3Gvkx^Kf>+yO(?L~U)v*MBe*6;f)!>EbY}5{%QeL6{ixo$u4uoTMwR z>E4)Mxp=v@f8Q2emm!X>8%%7joO+R$J#r;-ee!=MP-?{J5&Ik6F zs|sAr_tVOVAl@PE9__SAORxc#-~j1#J1f>of4Tg~*lq}xVbHfPO*I1N=kDKoD+jXU z02dTQPTE;*2?FcX`PEY;U4gc3TYt`AMSft{0Kmqm7y%2KJ^Na1;jJqdwPAneX0aj0@M$Oj56#Jz!ev`&w?H@RgrXvQMzYKT z2gIebuaV_hI?#t%V92y(GJn$r@qqs4$LC)^eQvhC6a-9Fq>4_4hgh@K>e{^BF-rr~ z7d+o1Wl4usUaL0iF}`)A`p~Xj$2uxeNx0!DQ^o>U^^gUH;c)>LQe?6^5qQ2B2t-wl z3EJ@5w}4Q3Ot>ExYU~YXNn3{E5*4*~bGCc+>`+y8J-b$4xp1v^>3{kH7;V{(<9dcB zO>F8bYq}($`z9(N%pJEkSL?Y-&oLcNqRnL#lvD+Th81`_CdR6Yj!h(h0}>S^f%uqH z=1YN(JRU9JL=m-G4)w(z@0@R6z_M_Q3}g=YKw~)IT!;pWRtT^dZ8aOS=gwSy_qDl8 zXB^+ZS#K^ix~6TbhJU0;B0&LwYuG6N%(iV?HV@4#&FVpQx;{rso?2qm@;MeHnJ|yL z4itG%Rus_}KA5?FRj9dx0Tcig1tMYOgu8!Xt}sl2CEQfX$cpGHZgg&-;yl-O% zSk?z97)%XSFqh{qUYN%cnXk=Vy>#~S)R~*}HHb7w233}N9e=l6QmTWhWja74MpaX> zRFdi9a--H><=W}Yg^Ez@kb+-?1%5{B+-cii5x*|8i4%b*cL z;m-+(Sg2pmLmrs#L*SgAxQTBOt5VAlHG0qB&>b=`H#7C}%g2^(%s7qZnYkLRa@+2a z0E>`c5mx+IV}BB0K^fGvk_4=7AR-|=K0E}8TWTzB9UO5zb8K?^T>X-)o7SRm&&XEZ zb%SQNO}n*5XV>T$RHjG`(+bN}lA&?=vLrJM9U=%26t4%A?=e>|sSGhsadv3q#A5H) z=XFC~S&%n&04gYc^Y-ztnM=)}Z7nV=LcAZ{wofbTn}3HlOPFZ={l|Xr-;eB>eE8wr zSEsMM|9<`PNA_QvzSeBD_dfX0E2mHY?9Q!UIP%PUC;!*)lh4)8PYfUUt)~vYdF|5q zxv96#zH2cPkDzm69qNg3-wy&#K`b)8s`m3iJFr~_4G{#vfJbIat9$KQLsbNa;e z+stE*=YQg5MC$mfhmS)gNmP91z%#z$r$wC7s6qM;?cVVLy-qy;vB_;^L+38Oxv=cG z?gSSqidGU;UGCpHjvqeo*@2M}+k0d0KIQluKYaJ}kADA)pa1&vU!QBVAADfvFCO^$ z(V?v`oxX8y?$i}F{m_^8D7sRCPGRV(u4$TL(0`ID=&&$@sB5&;u{&V2?OC=T5`s(J zdnUGj=?}hWITrJwo(T>xVIe9(1lzZEUPEW>j=Vhl-GBxK##h95l?ucBk93d+=-8W?-}0 z@{PuPU8K+*L|9`9Bq~jKmBRO+Q7xtCb!?#QtPdn9*z-u&a&5SB*IcZq;(dFhDBZN{ zcB|!u(JgrNmv;$VZFPFGB=oGd<2T30`hV`GL>v{G}$FrPfuTksH4s-^GOT+zIze+Wz+`tc9#|56X!FJ1ZyB=y2zt`@8rNFJC z04_v604E9prvih&g02}WZUYEEaX?5PF&%y5pJgf3-!?~P2Pq0jGo(t$C=p7aNq-QC z8xn!6!tEDGrNtcoJab$wN+EIh4x%s}{I@t&!>0!pBny>z69*KTq8XEN*X}IJ3%X<& zq$F`E0Eh!tEX(P-xPft(Qi)Sd2sDIcPDI269__(^(n1LIxyJ+SV>KkMby^4(h=kg{ zYk==Eh!d`sKsiIZ1!01i6X?K1Du1e~B5)+wrZBmT$fcU)QB)qnzOE3%YQu&gm?$K z5#{6Jy>UyKRqW7soba2nWzAfcliUb{7fjSn# zU4Ifj^ne-QK)?h{MmJv&M3OiFi}Co)Yu{-X_isPkWBPOxIvjufPk(>&{-vq!{^L>8 z4HpXG))q;3;(^&@v8hBUW5|3k_5Np`{*~N; zcuSFlsr{%KDDEsgy8lu5z0E&L{OgJ5>&?2jSwRMpRH`Z}jFMKm&TmwefoBgti&p=m zM5&bQO1$vG3x^&&MB``lKR9;m&SC#}#?sP~?&y+;h>Aoh9DfQ7S%HYGw3;VgdG+?w zDY*N@6Hhpf^Wkp)(f@0+^sN%eY+w`Md%!d}Ad0X)gEfU<7{;&BuI4k@U4k$1v(ZRvN+fV-~_>V0R{&xO2CL8e%*B!@ChXWCZ z^N?d$GT^QENq=zwg~}FGHTQWC4Ic(bJSX_XI3Pql+4m4ozT-!~flYkjCvkw@`IL`& zK-G?@BhF2`uT!P6Aaa@b)KR?wG`xt~cbtCr9eDcC)6aeHxz4d>%XN^(8(I&^Xuet> z&^CYJ@!$9aH~?D1C>fzzi$}Wk3w6AIa{nEt{~wQ@(GjnLEsp5`0000z5Mdq4l+o!ump{g9c> z&L&rq7!@Vy?+Ew^007{-tjrI!|76Jj2oB~yJ|b*7{hxq$kK*~8i0#@U5bRziZ*#m(8u*1-}0@Y%{&x7JWU#}<0pdk~k84oQ=DR>OiL zRTGa3!Az#6Cxb_oizX}H#8MqXlaz!em?(;dN=yui$5LfPibdFfJs~Se3@eR}oq9X; zFSTFmeL9`}Y+n~XtGmx{orfKSL&}ihP~{3isum|kI|v&e1s$F+i-salx&Tn&S}n-j zKPVso&q0EM4CI5b{QwA`Wkfi@pknSID`C_Z%7u8g0YpeR#GpqquRL4`CP36LQM>{m zDg_aepGB<>D1ru15}s*CN#mP%Ycyl=WKrnfPNYo7DQ1pfE2?r`Uk*908lrt z6)OqQVFh4X$&c~@Hkbgcvf5TMfTj+>;2bJq3jhuYz^WP@K?i{L2bfGyQ1}4CvjLb= zciMut3=ODf^#6G(yG5{zl20;JACActR$H5yn08JUhXIq@6w)+DlzG@U8;?Dd6XoE3 z1^_5Z#`^EJ_a8oU$PIII+=)PBW2TD%m@jfOv*SAvR%$^WI-KA|KL4RDcjG*%Vg*z~~1hv&K}b$T%DT@S`Y{zDbPWVF;IT5QcE* z+s+W;y9sx=IOXWDII1{;MF^pr30>V!aoWh)CL($hmK9MV&Oue1$W#|(=3&iFWFZ%n zS5vrxA==(hcxbT+I1E#=t!N0dSRIN)IGpT=XR;v~X!JNr(#dE{RdV@cE*UnpSPfE5 z8KOHOH%PuH1F7z0fe8Tn&-ch)X|}Y`7FD4Yq;`p}DjxiBsS?Bm3lFxOBtI;2_YUOv6zgGf{xOLOcg01B`4YzJP$lnxau$sd1{q>8+A9@%P6iHJ6n{F z3?s!FdJ+Z;s(-Y^C=Vrij08JP*Dpxf<}!^X^d+e!CpC(5#_C*78GMS=$t?@}7FfPC zMpA}}h?D%2krR#+f)lbkeS~~7QP;9(^&?ufDLXklFe;c63}czaE~Z(UqqbXBtbxXr zq$gfq3{-1WjjF=n^vvO#4a1g|FRw32U&gn=v3as>{O!?=wwq3@l)0e2G<`1pJM%Zx zgE!LmNUX5&Xlq)$TwGXOYdmk<#w>*jyyZB&aSc`;w#%%uY?N$gO&xk5eE?SS6hgXO zI(0e$J&Q(lO-0RK4Wj0~=CnpqwUK&YgOnzR`f)Y}G%$eNWa0QBRyu zO?5G!1cw}lcB|Tbnw1FbahB_Io`(|r8Es|eeNgNk<_+Bu9YF=BLKmB*fqhLzW`<6! zOs#6I^kpA+!&PN|MW1Ak?pr9b*ti^x0gbeE(%iTFGxbgN-AaT?Y(*jd#|Gva`*MQf zo*&)=PLh;5zyEcYyTJ$JvuM9)W$5m*K6w3KZ*(W}tC2KG8d=<(^6 z>uBm3wo29K*Hf+a)b~`PRdy+*D%BROS&uZ`0w;mh9e7RP4Vdi)pd&EQ)Y=Tkx?`+i z^?d!M*inCbEYtJE&*tFqVGh`SK+(DZZ3ZTc8(XRBfAiPA6r;T@-J8M8ZyOHp!J3Isg>7son=JJ z=a^Gm2McjJ?4*6`uexu#Ob9^nir*S~wCnV+E!LLWRs*v!Q+ye<1q`!SGp$qGzj*R) z3cs$sN-#IxM>T?WV7h`2@mPF|iGp+c=q6!5g$YK45|< z=c$40owT;<+R-kHd8;L>^V2=10)6C+n#|KoWT)?&TW#O>wc4&8|4DAMWX{rV_k;l@ zx=IHGJ9{lFC+B7bL^R4Y9yDGxxUZLX+fCP>offYN{Cod#{#o7D?|u3Zp6uV&gwRx6 zwOX}&lYMJ_5^0F3Ie*T0b2O}1a&)~KhgyRAfTchNu6M1h5-ka7s3om2TuLL4lk|V) z-*_{9=l-slkOw-VaQWeTa{dIr|3v(qf6FW0zwQurnZ%38nux_tJm)S)Dpx({P2Wtv zTX{x!aqVKy?_GME1SOACP}f)PUSraB>-^_(s`cG`e13X&cj(ErSQZr={Y z`KBAy<8VpxEAC97S76TIuG8bLWgCp4-Km|^$Zza;;c+4OnYyez-jmmp)6ivL-*xTR z*Y0oibWTvfGq?ND=X;C&wYFNoC$!sl@8|q9_Vl=qy&L34^D#Hwv*}H9UEizRYy2R3 zCAKNC8?`E;|GBeqvlDDL=v{QbxFh`p6A?E5nf#c9BJnLLJ83%dd*o#SuP`6qk%-&J z`Fo|ryv00q0nTU1=X3)OHcQa+>gD>}V%B1D=3Qp$fMY=U$Hm|!UgI`s7)0DZ>BGTh z^q}>2HRQeHO>|SbkD`1MKpIT@W%JVfsJ>A7mWr2}`UMS@b^mV8!LLlz*p_j&DaVD;~l%)h^~QOBOIJLty9%>p0|8(j4KPhU@l zAT<2{9egx!0npIigc*mPK1#C#DlwSvwm-9FQ+l`ARxX)BAboxpM_v2>9fF-d@pY1f zwr6TkB>a3@e7wdn`k^BCk%+ruI^tJb=wCpSBzQOR$P)ZA%>n@F*$d6z_cBh;Bzt?Jv2h@K1x@tSvZi^)7rOtIk5WHzj~%)Z`-aH zaP40B_VPbtBG>8ap8lyf!hwb;IExU~wkNXI&F}+zSJ6{zkU$ru_pTZSy+!!aH2$}1sm03T zwE+8e-XGhnxRn=82 zbHkA)=I5uxlKY$M+NN*5+fCO*UL9+CZRk?1@g#2yg$#9^cd)Q6U3j2@Yy)Ttzu5HWx{a($iy!z_6Z;#QW- z#~jEAb4o|SmUnHYuj?5)d5bmYRufS@u!F-@Euq!Nm@7~%Q7j!~Q#0Q*Hm_mp67^kO zHNIUp*6c1pCCJ${Ts5#Z%cWY18 zP4Kgw~uE+aRq@ooo?my zh+1Y-(Cw@=^*IqWvz0;0w?yu7s)?HEH_eY5(-BUmsD}L=+%UHB61qb*W_e}|H%pAY z+WpfeX!^M2D7ekwKJ2(^n_l%k|8iD1LS@r2(vk~S<|Ut`VHpGx(;w;PEu=M{gynL} zEn}C4H&+dh0>gk+eNS6kpkFCd{;&EY1RIDjaSb+AHFl&m?n3o|3VLdJQCaZUnPGN= z;x4vn2`7SBELSE711^G07md@TPT-%}jv^AHgOnZ4Ryd~Sl{1~-k4JBYaxy3_xn;U> z%e0kSdAUqgU!)(W@rtPNHSsm?fBeqNxiM{bG|q`)=e5AS7T9%azn4aI&@{SW(`C;4 zNmvpaYTom5@BNu18sVpM~`FSzunl8ipn;wY97!l@|vtd z9emZnr_A1oZe~TiPEC3SuGAW!TFyWrZ3evR8V>Tt{(uJ$1w(}^{hZ@w?Su}5JVmcnM2Z_DL{48mVm zeQ&u)CcY?figko?wv1bHSM&_Wzm|kH%qUF5hh^yZbwKyS7vJJs zsW%{U%eU*fo5d#_TX8FPlGQ45RvW4WQ*2BMZ-McA2$zFf{}%oC4^4CrjiGHCvMgZDpId5Z@*Z7IhMBT!kqQE9DWGR zOtNl5ZJnEiq`AZ6k(`h&_E3ko(Y2lCwV*?cJ!7<8Nw*iEcmu{)o30^^E?bPp3Fv36 zNZM)A;xhg%gi&~0Ln^c6HCjTTT9o6-vQt(58a1V zUo*vX$zHI6-0CK6b{SEx&a}<=)6*-G9?cKT6dRh&zRukIQ{(XT*Lby9X4>zL9W?Ua zDer9Q9W}=Gi&SkJRc5VXmFL&f6V zQk~6Ez3T^sp6el}AJy!hJ%B$*=g}3W*?u;t# z#kL(@=N6TV?}CLA&o{yQUi=m37o@h;>LD5P2FCw6IQupRg7}zsm|rDz!>fOoEM}) zMUR;ZikYU<^+`ev)*pSChR}24Yw~+C_<+Sv%r2W$P$soJte`wbW#Q{|Mpat;nB5!! zp>fHMc$d>V04nS-`sD)OBHG^UDCZPx?{O7^2CtT=sra_`F=ox8srcdYcujDuB-TDd z1-G#N5fo3N_KytjDi~6CcY~$`MSMLAD9x#JEtqexL|UeGAQX1(G!@UPKo%HMMSNN+ zeh#iT{NUlLa^ANIb#8Tf| zyxeqHrJSc__NNBbiWQrjRO=~bO+e4f-jtm~{;ak_!N^&9Ll>@vXLk)dd0eVv-!$W(4hII=h1%T-!|cQ5u)r7H)FnB}89CzGCW=IJb#Nt@giW_amNJflKV*M0Trf_o zl5oN>A`@(2BG;IuE?w+ahB9O5q`EODn_o_SmDI%tF`^M#-nqL~G*!Bo~I<`nyEPwaJMaQ6M zU4K0Y>T4aEGiavQ&issXGq$A#q6x{UA5_;wYZBX+9b)|nC{eG_Yq(^(H@z&AON?A( zohQ_~MXfB+hB_bF`9?LXkKgKM)|hLd7RQZ$El#McgO^lta9ywIj&wwbr-QYaS5whB zA(rDNNUoIKlPyB^E4Kw;Daz^jcpK;gILk<{6{n+?(Tzg%rk2B-kQc31<&CYRHc~A& z0a|SDP?frNRKPJb95>3cp7qqOt5n2}HPpL3M956iZbzts4I9I=fIJz?^qH8+v=OhZC3AWjdsHwPwY0~O;>_~y%_6`K zLyc2BzGI_wET8KF#qt#6j-H54t_7Jx`vzz?B(H6hZtDqEt})9okq2ztQtwtPOiMM( z;_3D+5w+{eT;T++9Md7mrt3j?ixKqYYZyyQzHxyp<#_4{Z)2IT1QSMV4g6*uv{qH3 zjBuiMToc;%45%`09TZu(A8|g2#Y_Twy6LnuYFPD8N8DtzG%Lj|`4%z`tmb^>O!H?e z(z@t%Ep3i6x52L@at7^%sHR0DD8U zsI+q}*H&N0Y9)n+ieYSMoAUTJCj^b;17KaNK)PTyMRQq(Ki(-sRZ1jVo0`2}&d)?b zdcJL6A!SpGa@VznezYEh?pq5bVG6E3ruK|x+2_-AfhhCNIOj3CvvWSD0aWoprxng-VGL|HwKy^w4q#uoQb8J zAX&S-h7OxM!d?w>k)5QfZ0B#eJk?}r;7sTknnm|e$H_rPF!g*ONwjbj8RoY z@lQzs3)K+<4SdPH7;Ar%_;-6-q5p1rw zF+0iSrpW}HAG)!4@1}MwnWDWOo`7De8)irJE>@RF66yHE^p>gJue$bE=@c!r={=em z#rX79Yx7+>!CW}OwY^)sUBxx4VijtVUHZOCd6s;bzb`oJs7nbujBiEtPK8ow?)wls zZ*a0PGP(E4$?J1G^z+)ZYM-*dbpociAQe?1B8-kWU8hwCx4QYI3}Nau z>nv$m!Qr(j+D(@2idkps1pI5s#@kYo_Q>!W7pQ6wKs7Oq#TiXzBlC?K6OG$~ql5%T4$sBj6~8ZWTD@N;Ak&8$H#gOJ8~Rcyd_rNGn(Bd(wX9O?bpGmE4X&ssWXN)E zfZ?8ML(Y+G{&H+jm0BvhW{q|-7MAc|IkGA@Xi879QfM3E@6DwbvZ$31lK8uQj$ZPs zzsQuR+N}<4erwdy3k6cRG|x5EsB2Vvh%!H};D%sHYts5QLu>JLgO;e)T1Mq$E>?sY z6Xf*xBJ1m?y}Ch%sIp6#7YGkI(G|9Ez?G020id+aC;d+yG z(?8>NTz{l--nnku{3*wlo{?WE6TbjkXn=|tPMengrS}-}#UAs8N{;2E`|oIY!n?}P z*b$#;jM0@b;^_bCozx@L)hgyzBQ%pYaA&k92Zq9>?-_Hshu2@=O-*(>B)_hu2%U~r zl~^cg-|jsCrb2NZXXnu$*)yn-@l^VBmk;Dvw zhO3)a^#rYNU2~uf{Im@2q`1H~$z3fTt+kH37z-gL;4%jgp0j%0BB7m)%TR8LZ%j^_ zQQHyTXhx33@s9rOu3n81lYX3|9r$n05WpFaVN|n_6F#=qv(ZI99fV86bXV5=BFDP9 z@@SadI@4@6r3yz!XQ460?JtvQNd_)E)arVasmxa6(izk12oM;c`KBJlg~Q9u*_pGB znAttiwUnvCtU>Xu)qNn7&qnk76W`Lg_|FirUY}ZP1JN#~};`o@&X*!%yQ@*Jvx%m-42BQJy1{Bg3K5o?9g=+AcN zs;jREU%lng717QWYpT34AWxMltLm3$)8k@OTNI6yckgKLZJi?S&J3DTzpap}@y%wa zdH=zs;u`y7_boXxDobJyd4y(_a_Iq?+;X;Gbs;$uWMltiT;dv)s={^8%K{pONb^K@ zP&6!5=~SfsK3DDfjXg6~%OPr7-^B2rUfvjUuGns(g=vGFojktwz`mX+6@sQyVPIE; z`z5V@`C_qM$CaMOEM|6#thhk>U`_*?eobO*{(plQbu7X7RAwzlYxh-jv>%vK;i6(W zXD1a!66KWC?VQz_+umn>1egD;x_e}hd1mP=4R#r0(K*oS_~$eY)z(JG?#oIWrQ_omGEawWo{h7||yfpv4+WO1Vb9X0$uD}nY z7`(*TVC<4>bUH?*=3Q2^wT;>0lx+{uh#aUAh2~JNR&W!L-YxWj`beSpoGxLe`9v7r z?W=JL-`^ofa*%HZAe2I0r%|YF%#KRUmG*)9Fp@N=PjU2rS9%ZN~qJtcaBss1vn~tgNOok#(^=n>V?NY1g*+N z4mMug%UbaS2;SaLzux$SZ)p+_Nd%-bez^C=V?DIGTSLjrN_Bs){!W^yXJfjzGW9#} znGD!4x$a;)yUT!FEk~p@Jj><6Pi^UR#t?Obb2dm^O&~w5IknG%Qj~q1e|BePPrx-z zC^K~R><(QzQwx_Lk!K&+5EAF9r)o$RNQH90{m0S3Z}lEP4(P!28k zKpV~8N&dW-7R2pNioDS}6Q@>3q3VrXODm6mGY6=-|NVzdF^DRtD)zD)Qw*D2RsV)c zQ)?y`A)gtn>h`+|8;r^Q$KWMJf?RT%QY^FjFoQ&@OSqolbP;50`*7Y983Vc{-NhY+PTOEOHFs5Ot( zsArk`d_zo4rpRXRWX>Bh&lDkGDZ1WIDEaVSc*6jF&=y(Uol|iEZ(}26i)tT(oFK2V z;rpVs>}hYmH2h8Q+6kj$y9!?$HHEnDSmge`4yZ20G2+2lynjx*WaVxRioq&O7mK^E z#P0GlALT#^j*0pjlYaRm`Fe_`w$%-A#aF5^+?2^V1F4b3mFA_&6BcprZ-H_F6*E}n zIb+&R54ngD|9Y1j-*c4B~4 z;Zn<&)Ay_@pFaG)bJw~k?04q5HUEWBfR~!XZ2=#L=y(Lp4Fvg2wX`jm1@E6dOhP>6 z86RciAQ``G27{tV{G!uWHCs4q)u$?c>Hj5ko(iuMt0P+v;(%SMDhcP~)Nv!Zk20I( zn&q=KCA34&W{_YYyfMucj*L`)1!lgk35wnpHt-v!VTxdA%6F#KZ1mkd zVP&EH)mSWT&{%e@p9(Ozyz?%vRg+t&Ik&~pd<3Sm@%)wLW-%donAq{GZlAD(Umw?s zrh%tj>qL$gL91CdJ*HTcCiUN2VvR zIyc{bpRLxfq?<+)?nw3t zrMfmAoN0T-LEw}s{2~89IqoB@hpC#93vx(dO*BhnVc{TFj7cTbi&YMO%C})T zSOOC{_1~fErj)ib8*tEcjna{x< z*U@Br{%u;H>CdHw^H+tI@cK)h$)$KLd2@xLb>$h0<{$H)p4WP!;CzKd^ z23P5P^!ZBvQx{daQ!J5xsGS=49xpbLy&AKI{x6U$f{&~{uspoJcgRPNI4_{HV0Z>R zS#EIUXQ}p{AvS9!41YfD7-aep97B7F^q+vIT5XU7hc`%mnN;lwvqwp+tIr>38;cPE zJv`Kkvb-0RUbGB0AzVZbpkBrWh^UO>DOj>#j*By_Pz5n2>gr#+O>ePh z68B7jwT%x$VM#~}=DdZvNVf?g71y}Sop6%%qk!#7nH-7F>WuD+)YmUnTWtM)heRGp z^wwX$|wo#o8%(V9*jTDvo%n(zXne^vrNuEkK6Xm#l(sjCyqzGJ5H6pZvdz~vid zQno&Cl^!#gT^3_O3!AvThGADKBTuAa?yuVzFT_BkrjFvBDH9#v-5Lg6JAcjReVu>h zD|JLoUiJQ|p%>*7S9H+T^8B+|PqD%0w72-ca~1rk>Ndq^w$7BiE}q8zt|1^Kf3OtC z;sOR+clv@YnT76gVfD4q>KFRQM)6eBmhIYa{d1fK!WyAe_+$xqcRzvi%zp#+X<|#9 zHwmi#1O%HH&UntzR~Z&@u0-;BG`eE8ZpBLUcGjB%{}mKeW;+^-4Lpw>SxK5Ii04?9 z^`k<^D#=S^n70rT*|5UopS8U*q1)Sj6P7hYwbaE87j$`|D|n9BKgy0GIph#|g;E$_ z+Bp^^J111ICE$C>d*8NIYgUTZx@X%aw!2Vqdew45A29F$W5rB-UNf@@-Fg;$JQ{;v zFO^$*f-oTEy%#Ek;B2a~Zy7-_!t!yk3IvHPZMv#Z-KI&l{DRK#{)>-19)ov;z~QtSjn-$z80;4prj9bY$}?uaqWzvV>D%Q1v|KH z;hrAzfbjK3hh?I+-~YCu=_wW2A?u@4BAJKwns+9c#*GU)Fa1Z`2 zy;Ng%pZ%4fi#J6LmzpB@Cb?ph+O{t-dgT98E5~R+lGf$? zf*6O{iPeU#|3Sa;K1$eKMC>4$icRb{MK)QYdQ-+ZrDXBBH`H7`)BVFb3Aml6@VGxo zM6>|wcb8o#4kC3FCksB)*~w##D*0?jVc&}@HW$ya${zW_rQ0IYXlfQs&<8{B>pR6x z=U>j{T?U!7qPpUBRYv9p7qcb>)JVpE;w6)5kB7vr1!l{?wDfs-qj9M*GV~lBu1zVa ze&cB=y*L<=^eGDs=6Ut=rEkwoCgeAft|iO&NNT-V?fqW3hpK@}8&!`l{K8MQZ)|De zq*bP6@OUfLjpd58Hr_vK=iz3P9iDojB7XmU74S!*k}M7`07WIf0*&7xd9H%eHCBz7 z=SjLvK$x4T#r2VX|0Nr?^X`=zwr5-6$t&)3%4=ehq+fHjeAutJLqFo@mWy37O#}H15Mrg-q@@gg!pZwWh>a z>Nf4cPX$!h8o?SKq?yJ*LTgO)hF7wPm*OKCxH1CrctE9k7~IS&Shk zve>Nx`358}%vBAJmigQN-i@-I_88V$BXB-`4L^><5@hidSh*IDxUpCeQbj22An4|_ z^a-7U<#}}fLfyl?7IMeM~d+`{)W^|LPV5 zy?p0x=$o4V+&%NXU>E>d1jn=E**g4Y^tO4#=JVX{+xbXVcHJKjBB`yF$5nUmO`Y%g z;vqWop8yPNp{*PHyyqJD+~x}2w;TTq3lulz?Q5HO(Z3n3$k?3((Ytn?as_l3mBGTF8!H=S85)WT|2Ko+N67gAu(pn2Pl7v1ZzgR2 z8?4VkkFZ$f6^?W_xLmG!l-1YW0$~eEB!oB8nm8y+oA`xYyWoRAaNg}}m>rR3F4Tr! zE)|4Vpta-m#+S(Q(B>;VTLRTBPiDkv-pfOtW2s|eg%oPDG>KFj4lC?~qHSzw z?GBu7->nTeZ;tBf2+qK1>>ql}KkRq{bl1J~PpZ{PW}aSK_<E*izeld~6gEjv#Diql&qTHxHj$$;el-!$#b+?c=7z{E46M$iWJ_O z4!_>U?iQ6I6KpEk+a82foe3f+HA{a!|7fjUlUcE$c$=U1R%adf>@n<&4!Wc2jg+1M`c)2YJoJSc7dC1u{w_m@$-AQ&I) zpVxiNJ**XSkUU4ecHN1QN;3n(__yYK02T=NouS`#wL|pdIBf^N#6~;^u}@Hk-71xC(It{5mNHJqK#w$65zVrT+vx1VA-6cEdE+s8C(1nbF(A$>rI~Bn6dlaS z*zs3#LtZN2X54>=PvC7%Xi(qScSKhox%PO#zEu^{*r zlEt`lX7wu2jln{7Zb@$9_Lx|#hR^#5mkzHOy+U{N<#-(L2H%M=o^MU>2m}&VO!@a5FL@25m^v zDSn+mw%%r4GU&%QjFoXn1oMe@d`~j+%OJ>luVqhQLYe~R*xSO0zt5N zx;gBv6m$DMKd*I>fgJq(2NC$j_6}tesda<6%`g=IC8uN6AHSmr_5Un6K0RNf>_~6Z zdf1#Z0a?4K=8;BB6`B@CGV@e1-4B;EwK88HV4+H6#nH!Y8hx<;`s88Qd@GojTc?;~ zy7h=u*e2Y`OL@&;Rr!^qgt@OuuX~+}dbl<{cbf1P?`0&LP9Jg_EL?I^$L%E49}8kO>J>J)UrtHW^yc zj@d$zU<+$F*aB<`-{=1GCs7t7Zhftcnu@5BG@}WOrl^)8E0u%yu2L#^*dyX5;FZzj zb;n2p!_=D*B^7NAzpSc&Nrj6PI@Q(Rube{VvBi}3Z_<7C->hNDCiL!-4`e>8iC|2O zHC{h=^jcAbZ614qI;Sw~w)wwGj4ecAfyL-uj|r1=Od80sT4e`!Fu2dT@LR8@w+qE- z71I#J&kEj{sjI76N@KG)7xZ2YRnwXmoLsM0 zAjdN}YvY*eaP<%&8V$C=Ys+Uk`g&Nutw*ZyN?Mr=o-+F|u4MI+ zJ;yRnSKq?kJ~#jH7Y`7{=Q=%ZM`s^wB1pwEhUNj%>8}6fB~LL$F>C$bYjx*ihiVbt zcy?W7a2WJd6p83YUHmVfzVB%d`ELrMT*xO5f-v#lnfiQuMHufzeWI zwpPv6sK5XRD_d{Q-6BOfsT50{+~vz~gDt%?ipm=kd;cg$k&}Y$c@riiX^axev62Nj zG#|Qrr`+^*&6Y6uW!reE)XltAb0KP2jw43NF?`jGAyP_N^{rwnZf=DNwyAZv*xf6# z{Ghm%INgD+gbO-xG%10MhKsvFp&I~nQ0*rhn^yr^TY^`?$Q_^gr8QtycB1y|BzAZi zfB#8!%Dl5<=sJCU!3y+mkC;OM435KL1G#)`ajyfBRrDrO!YP3dnR?GUTlLtjyktq{ z!>ktk1xM|iR~hrW4EEtn3&m#j15+P`g7f#oC&SB>^2qzM zq-GbvlZff{+qNd2f<+?-Q}r<1p?kVQI`c`#IT!Zhl_~UotcI(bL%N7b_Y~b>a~$JS z6G2N)(+GE(B=gqzurPSiHYgNxw~FksD(r&QI%nktrX*WIGFglx-Kil;@_W(;!3hj2 z^|&*C%H{A|PBZ@hvX8B~>}JQC!7Px?S5Dx@^eFGXQmNHXJ~P54BE8{jt|g>{3(_@- ztJGGXwwl@eyICxStm7?IrK_$=_b>ez+Pj^muAo%wLZ7sJdmdb5XO}~;HQp?BH1K3O zZ}cQ<^cP4H@nP63Q`bUO_{3HT*XKkxkp|n=_J^g%EAg@}XtrKR$veqa{|nQU;l#w7 zV8F7o+ZAj7*3m7e8&iYBwqO z5w9sfAqEYb@z+*n=j+z;PUkBOtbeY;KMK7*KplA^2Y(-+p6hCmqLuI5L(0y*LS1s> zHl`I*HNytG6e^+;`sz(bR@Mp+F`t`=g_3~4iExJ$pDGVdyOVF%)Y^J9`=9N*SAy&_UWc>I9su43Kd5``V*bT zX`d9Al8(V2L`_0@>`f4TO1Xy~h5LS=RM&#-QdUf4Irf)5lrclNsJR@uO7P;Qm#572 zMI)54z9$!P0X8pQ*jvIQvOf-NL9NlG>I%nsUMv>V2G-7e_{jG6~p5~wPg)dYkvT_v? zk^Z?4I5?e6K@sBvubOR{KZ)5llOV|cLcN8)@%jb?-Wa%r3uRZ)$(#v;?~(gJ<~@&qpr(l{wo+s7TU=;QvVL8uk$YI7GuF> z8D!aEYQvO)qOsOB6p3|Y`o zD`v-6(9VxsS~(CRvGJch9&#z&uq@s|AxEk+E?h-HcbRhLw)ov)J`oLMmMaZLtTW%e zzFMX|#vEmFa>eshdUQK-cRX$EYzC9e7Ox$3r4*_0u@NWuJeK2Z?DWsAPh?%~oiG@` z!<4H2yb$wY9MRDq9ix<_>MqivDk4JYE3onw5ckcv79ZS8r$dZ`FcPr#=Ar)M&sgxM zw2rKUt^ePxL~+M~d1a1!U+MzeLpMa>>jsVQLktaGg@8qCw8@slWR|VK>5fVAwk}0d zfYv&;@8=Z51gV*2`^cO_bmMnKM%QytbdQrz*eFxVZQ8X%Oen(Ues(iQUW$2Vf9t&A znG+b;T6ya^b@~sR7^1$wG|;}#X=Cit!U3r=Pw&E98T3PSjy7lMPDrXXoKkV3C2jdk zsfpKyW6liOYIwdkSr$T)bbNdO(N4)Qq0f#)n3F+k+27UY#rZYq|8N9(x z34_k93zxS$bC-ESeN)z7_ae#<9KnSI+6CtB3`ZFp!qmWCH`C1Ro1WBfjvM-gF6JL0 zx=8XL+}!b9ZkBPB7+NrfiJtzHc1dTAhL*euoz`HjMA;vd-+*uuc!{cZ1D8T}@81#}+ROtnKZ{EHQ8a%5}SJ0_V?$s@Xcewq- zJ$Ej5g+KF2K?KJH#Awi5k+Dtx_;K`v0-PRxE{Y0>oiK58w-8mi^~nlA9?KZ_ED(Iv z2;uTYWc{*1bA7sMJuv6vmrsg{EJas49eCaQh}7upoce)3UT4ca)vAbEpE5q=1JfB8BUp~z9{x>E1B-4uDL z+zdWOxSSV`>~j3hrE{ts{GyGU2Tr9Nz%o}6=4VmvMLnz`;@xEI*)n(^Tw=cWErCQ)Jb zyD@TSW7o>DTHcJNu7T(*#P!+x#2@a_w@sCWuhJ<|+@JKrv7k(@KbIN8fvUK*)#TyyjKz76ETCdAD-S**~(?p^=bTUp7$HL`N8tV zPa#4X>$OSZ#NOF4(gmhkOJs5zpVW`0R-Y4b$v_c$hA-hX{SV2N?!p^?M9jDLc@Lf+ z3k@%@xD0YyVp~7&{@o25XF_uM>r?&xf+eVc z#c*KqrUwl1y6+voJzsG86!=GAW1C>v(cAa7OB**QueOJPc3^Dq=I@>QJgRbK+ZG?g zUdY!G%e!p<>&g8n#`B`c^IKQYi|*$N$rt0*8aZMggwY0-oEo=N;?Tpb;Njle^+~RB z|3o{%TfpPtxb6V&(M(dFXcQ4Q^T4o&;E=s7e;kz4z$53^;nNq~w(3-+@VzZ@=NobV zU4-!&PVkGW@W1M$mY%MmxOw5Ztr&e3qe1DL{xHHZzu=Gs%g0glTM#!%-xsrmWz54? zxV!hxyYQ=YPFNpf|TF^dAM_OG0CCn8@>jbm!R&JkW}w!Kiz(@ME&@WO4r) z!PxKc+cmF04nzL8A8tA`n|u2w4@W}pf1d(=;xO+Voa2luET6>g`n&hOFOU4Va;w`s{!7r{oJA6CqR-=27A0H2Me+Xp*3v}} z3WO&0F9nQ-8$+0b#;?_Z@m>3l+YyofV!#Z`C#3P)#fZn&cua*k=r~K{_FNhDjZS&s zFXPum+<<~pICu{|#gb5@c{rL*S?CQiuHJHP-!HN0@^(W#sW~t(ib1=9jdu+!;k`32 z@-YycY)$N6uzUWCrdertC6{i^V@$H8gLL*Fs6 z9=J(zeLrpdEcpo*`C9LFyTXSbZWMl@75Th*?=kSXqC%$54Y;8ZnfkhK{rVOB__BX; z@rb=!_y$=#Fwz_pSNJ?qcnYp$zJGBJN}UMH&*ezbnyEHta4--!p!x5w?(Dq(7ZH7O zNZwaS2H*CSTfHuInFqY`jRvL}3)~(b2?U?>Ne-7udJ3=a(EEniT3kU6_M>wSqcQqQ z?zTQ*f!Y5TS`(%0(r>}9eeE0k%5VKTfAJ^&7+-k&i(I^RK-gMDW|ph3@8RW&y-~sw zkG#ZR{vZDeJ9{^H?YWzfhkWeQf0Q5kzT>>Qae>F5e~uvZ84t&(Y04;`^4UN87g;HL zC*A`F0MVLPF7E=+50`lC+3VcA{`0J!U4T}XOP6kNY_&({#3KLV*M5VK-Sq)3T^@1q z!XB%OU2a}{gPEDKc=ZO#3Tw-!SRYThdhIITb>E%bbN((a`WyVx!!Ocl3twM)ojYzl z!Sd-9u3XvVr+?<3acb=pk3R7zKlr_$;hC3TV5!^X%U}Bjul$pXy!hlzbUPqv3yZxj zuRL>|;qD%17rM;$S9pGX1cA>_|D%7+-FKbgmFANt`R;=lW^{%aO`9omCs6vD;VFL2}Lb^eF{@o#bO&;Jwt`~TyAV?3Sl{FCc^ z>JtxOlZ5~EAN~US`%|VFoV&%tmjQ8Rn8rClu*|XJck<%PLt5b}mKFz$^C=?}b1)vW z7@T2x^I3M22=Nv$7)-p#FMsKE{@BM)zBdCf#u5e|_uYLz03ZCoeH=^@+CEH%Q$Bp( zhY*ReNlvUfgi6ux2xo6QMgFM=IM#0yNlqN4Or{A+pxX|Z<~cw3nfsaK8(h6|iB#Xp z%df0+|Jjd_=azW5&+#*-d2w)&t(`r_2kU&`jx}~RuW--WDNZaeamNSNh|MQ>>6INu zlRaK}<_SJ{@4ei1&jZ~5p?g^v^w_v^jW7J#BRuuY>%^(z{`*c51TkjRL-{RUeQk@` zWRpREz*4wIm|0%mx=y>j!2UR+Wqa7XIIJq0jaXh;Cd?OUOU%a~{4jAGao_!Svbxgc zj`MeLV|$+@-o`2q$#b%4%>L{Ky+NPkU=M9l_ICE!ygcG||4#0{?=IrIBF?R?FpXmF zJ%1mb@8JasqdiDtM&k@mJdz~E3j^}ZFjyGikrR=!yt2UYWR#TC}I=oh&3p+V?rv>2Q9v%}bYW;s+te7h!#Co9n|CE1f=fu9fHP zijQYwL|ft{V`rGqYlpmcbDfbHa(UxxEPInN-Z%lP zm_-?jgBA-*1K!x4ky@d%GURyAKo~OdT6kJ>Vb9|EKAi={o^Fxs1k6-M)-_n|^OeWH z!oT>9eMU({FVI-4$d#tQ+DBm+rzta=(d`XTMnTZ#i%));EJ@H>Gh2-D!kndU7xEmF z3%>86lwmd-lS)n)bP3aG(S&P@c2f_*5K) z)%YQ#X^!85R6#x~N=5toMa@VVh{izsDt-tyh2smF4Fy|KPLf00K*ujcr-Qx^Ess$= zLmNfdR3LHc!2kX#p zfnI?0dZG0Xd{EmEC(sdC76=eFuUdAuZ{S(T5PU3wE_xf|7&2Ada}*VAZm*4tf|cZg zmvN;@~d>Ck-PHY%j!_-)!7#0_Nl1WO(c=Usi$Yf*@L{ZA# z(BO3y$4>fq0Yp*Ea06N$$OOitVr}xIpzZy3ajI*Q^B%JRQwTtgoh&@VaH0r&OB4xW zHT{-maR3KVfzXwK;mptu6xOr&osCSx)(93(m2mdEMAGUIfH$qiWwacm(H!nUT>Q;Z|SI0p$dOchse%;@$N z5-2(%oFU}OLV{WJ3Dca^6T-g6q=tiG&T3mT&T~vhNXIbF4Xs?TIkbHt*9u~TDMcbG zHnciLXL472M6(p7bWu*8WTYWT2EEv0bJH*h6Lf4@Cgkc?%0`yc_rT=B!3?@S?3t97 z7qH|F*x!ig`dvch6WB4Me8Obi(pLt5!6(pd{8mgW)TDrIXGm5ww#~-iYa!1q5}WrY z2uaIwa;POoOHw0czXU%70J!bEQVX&mw zil_J*+AU3PEcN{2Ak(B^aN!Lfr5jnMFoX; zWfDQlKuam297ZEcuVoqZ1?4G*V?#F(rjjxq(Te+oWgv-}6 zG(t-8+=U<%@*Khr=p1xboN~ImKO@a^_A)rp^0;;R9H-YZ4$LlFy9aD-Oo_B22tou{ zSn9B_WZ1txVi;RGEeNclH_*(+(R)t=^V~AJQG^6vgK1e_zd6Nd%VHpm^WueVPt)oI z#O)l(EuIx7)10=>X;~o+6n;yS znv98a&??7@N3fwdwa{j~l&}|Nqz4++g^9N0nL={KbYxJ*qPv34E$xnnYAGThh&_~s zgGq*s4QV2b#gvCH30ZFGDHyb18d=gvu@UD)6N}9tM`*2BtS*GC=v7i&h;!4Q&aLQufvwSRM&t{A!F)K?xtya#y zHOvwrxnXGe(9U4F9k8{VGgdkMI7PQZ+DjgpmlR@?DddTejSOMeL)tKz<|J4qM(F#3 zkDvovbos=B*Mme^rn?3e2onRj$vD;%@?0<(Osyr!E#00%Ym3d{L`PT}C`O58JcC|K zP`PE}4O2{hXt5r|Gw5~{i-Q(vnsDjb4X)dD+HDWj_Xt9tR8l0)Avesjn0O|v_ClgK zCJ8JyfOIU-D-QDL`R@P&ywww?i}HWWu;>e6O$mJk2R%h1olNyV7igaYz7!``$ux0TCMl+Zt8F`!_N-@_xc>4E+v-Iiyp_v?bF8nCi8QCzOQXO46=!3;422phGkEa%oNv#3CTpUB?((P!CJ+lQS4*c4KfBQBOlE$ zV?|~%BB0mRw0n^EastnzJI-mf6_K)R4HJ58U9@k$lMvt@g;K?UG*4-_$|lj4!WSWk zbEXr^){bRi0pcBKb%fS&IEYf>9gCMh+7-r$#Y|E>T^!Z!N3geR>2wS_fT=Z{>9yG2 zkBMSfC15r)#MWne7P=wyePL^8nOcxGNSLF=G9C)r2Y*q42rG$Zyg(*{&LJv;)5Nbs%mS|!i7ee3S8%PqNx2OpM1InY* zx8#$IObN4zC5~X=D_T9+nHs`S$gIUnp{qR-3}MR>?_08|B5hfE%bJk~y|&_v-)0zR zWHUn&S@sh{-}hJwG$}dxFyofxCB{L*-ZY|Xg`K?|PlU;C#?q339NrkG99vclmOa`U z4z_vkwE&YhTELmH%u+)ZK`SYQLh-J!yrgKKwB(7vu4OhYQb21gh3S_a2_ zwDm~FDF@Sx)zyIM)R1gX$+U-PAs^%nb%rNMCNS@K_c;p6hU7S+lO9Ai%$R>psX(?fKsg3mv*P{t%76vS> z47f2GvOS)Wr74l0qLoK`AlSBGX0X!tuwqEY3E~$mb~iQ-$Tcjk_84?JbQXpTCo${^ z+Zz_WWLfMAlaXb2W-ys$7V+M*00EZD-on(kOs(Za+aqi#u1#Xjp6H=`!_<%H_kHqV z!f^#t-xANDV_|8%vUtqj60sc-Nmiq0TlXE;U= ze7bGLMw~H=1j!A@dx}UIc1O_GKm@*6R`2%72AYHQl&;AcCWeDa#zI?AVTwth-&2gP zC5(2U*M+kuL!P-DGs<9L0or}xxbpBlk7+w)5k+7P(=1{&|VZeVSts4c1z=p^P*|VhuwX!Hx0gD^dBS%OroN@ zS$Z(di%E?R3=?C?HH>4}nP%v=Wx+4b42)x-2dPd;Cn=*1%WN^m*c|OE0x^Z+8DTuJ zq*IGh5Ok#AIcAWj;D-W2a-fq6t1Zjwz~kJR7B`X!^x(F3NVlC4t_0)*O>`-yCkAPyY#mr` zZWRpPcihz{==n@GXE1@(kBF?0cQP&>>@e2Q4`L?UFq{G^=lJoQXb7i5!-@w73FJP+ zZMbkHW1$O+AxvU8*n?KbLJz_zOvbRi1#JaqP84Tlym62)ScE)+cpLgYWM0ZRfOsR} z)mMO9a!xMA^tFeLGi(H5-?D!IHxFQS4F+8pZ$hpuZA&46Un(BeIms<6T}X`K(sgLJ z;N-E46Rm)Ye`pZWVcO&`A;J`{LfJ?YEY z*1q{H;O60qZ#s6E`Hz@?9KARnXq~fX-0!UpbA0n>&7XGmwg)6Rr*a>D7}K{qdF!2B zZ+^(rnsEF7Idxez#xqN5;P;5oE13tyU{+ zx7%+~8h-cg?VY~o_uA|J|8TY2?a&Q2p67X{)oSt7Q%^nmxzBwrNYhk*>xlQ;X9U*T zf2)&MegC%#d%u(8`<)24Z#Q0Rt<_qahaZ0U8zN$D=@z8Z>8M_>7sheyMNt$gr2@Xi za|GV$pzFuae4E#QtKZK(%<^|&vfhaS{4Tl-kN~lWWY*dQFk-DmYb~DVAtLm8Ju$}o zwtQojWn@|QzCR~Ti$f9qP3@N7>0SD71qq0d=ecz~0)QN${@>#e@yGy<4B%)Mjtt=F zIx>Kx>&O6(t|J3Dx{eIs=sGfhqwB~3j;l4B+Vc d-FW?f0|0idJ%Cu-^br66002ovPDHLkV1jnO(lh`7 literal 0 HcmV?d00001 From 7398a2176f51cf55288c7bc7de786033dc042da5 Mon Sep 17 00:00:00 2001 From: defnax Date: Thu, 22 Nov 2012 15:51:13 +0000 Subject: [PATCH 171/222] moved subscribe button to the left side, reorder category, added some category git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5874 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/gui/PhotoShare/AlbumCreateDialog.ui | 31 +++++++++++-- .../src/gui/PhotoShare/PhotoShare.ui | 46 +++++++++---------- 2 files changed, 51 insertions(+), 26 deletions(-) diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui index b45df4373..89b016535 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui @@ -67,12 +67,12 @@ - Travel + Animals - Holiday + Family @@ -82,7 +82,32 @@ - Family + Flowers + + + + + Holiday + + + + + Landcapes + + + + + Pets + + + + + Portraits + + + + + Travel diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui index ba24bf785..f27d948dd 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui @@ -69,6 +69,29 @@ + + + + Subscribe To Album + + + + :/images/album_subscribe.png:/images/album_subscribe.png + + + + 24 + 24 + + + + Qt::ToolButtonTextBesideIcon + + + true + + + @@ -105,29 +128,6 @@ - - - - Subscribe To Album - - - - :/images/album_subscribe.png:/images/album_subscribe.png - - - - 24 - 24 - - - - Qt::ToolButtonTextBesideIcon - - - true - - - From 4e635614733ee8e99f2e9711a5e02be9607ce962 Mon Sep 17 00:00:00 2001 From: defnax Date: Thu, 22 Nov 2012 16:55:45 +0000 Subject: [PATCH 172/222] Added Header Images git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5875 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/gui/Posted/PostedGroupDialog.cpp | 2 +- retroshare-gui/src/gui/Posted/Posted_images.qrc | 3 ++- .../src/gui/WikiPoos/WikiEditDialog.cpp | 15 ++++++++++++--- .../src/gui/WikiPoos/WikiEditDialog.ui | 10 +++++++++- retroshare-gui/src/gui/WikiPoos/Wiki_images.qrc | 7 +++++-- .../gui/WikiPoos/images/appointment-new_64.png | Bin 0 -> 8079 bytes .../gui/WikiPoos/images/resource-group_64.png | Bin 0 -> 5049 bytes .../src/gui/WikiPoos/images/story-editor_48.png | Bin 0 -> 2543 bytes retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp | 2 +- 9 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 retroshare-gui/src/gui/WikiPoos/images/appointment-new_64.png create mode 100644 retroshare-gui/src/gui/WikiPoos/images/resource-group_64.png create mode 100644 retroshare-gui/src/gui/WikiPoos/images/story-editor_48.png diff --git a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp index d44ab1a5a..6004975c7 100644 --- a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp @@ -58,7 +58,7 @@ QString PostedGroupDialog::serviceHeader() QPixmap PostedGroupDialog::serviceImage() { - return QPixmap(); + return QPixmap(":/images/posted_add_64.png"); } bool PostedGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) diff --git a/retroshare-gui/src/gui/Posted/Posted_images.qrc b/retroshare-gui/src/gui/Posted/Posted_images.qrc index b2686ad8b..34fce9491 100644 --- a/retroshare-gui/src/gui/Posted/Posted_images.qrc +++ b/retroshare-gui/src/gui/Posted/Posted_images.qrc @@ -3,6 +3,7 @@ images/posted_24.png images/posted_32.png images/posted_48.png - images/posted_64.png + images/posted_64.png + images/posted_add_64.png diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp index 52a0d75c0..3c66b73b9 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp @@ -30,7 +30,9 @@ WikiEditDialog::WikiEditDialog(QWidget *parent) : QWidget(parent) { - ui.setupUi(this); + ui.setupUi(this); + + connect(ui.pushButton_Cancel, SIGNAL( clicked( void ) ), this, SLOT( cancelEdit( void ) ) ); connect(ui.pushButton_Revert, SIGNAL( clicked( void ) ), this, SLOT( revertEdit( void ) ) ); @@ -71,7 +73,10 @@ void WikiEditDialog::setNewPage() mRepublishMode = false; ui.lineEdit_Page->setText(""); ui.lineEdit_PrevVersion->setText(""); - ui.textEdit->setPlainText(""); + ui.textEdit->setPlainText(""); + + ui.headerFrame->setHeaderImage(QPixmap(":/images/appointment-new_64.png")); + ui.headerFrame->setHeaderText(tr("Create New Wiki Page")); } @@ -196,7 +201,11 @@ void WikiEditDialog::setupData(const std::string &groupId, const std::string &pa { RsGxsGrpMsgIdPair msgId = std::make_pair(groupId, pageId); requestPage(msgId); - } + } + + + ui.headerFrame->setHeaderImage(QPixmap(":/images/story-editor_48.png")); + ui.headerFrame->setHeaderText(tr("Edit Wiki Page")); } diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui index c215c3901..f64b82c6a 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui @@ -21,7 +21,7 @@ 0 - + QFrame::StyledPanel @@ -191,6 +191,14 @@ + + + HeaderFrame + QFrame +
gui/common/HeaderFrame.h
+ 1 +
+
diff --git a/retroshare-gui/src/gui/WikiPoos/Wiki_images.qrc b/retroshare-gui/src/gui/WikiPoos/Wiki_images.qrc index 76299597a..1ea8313ef 100644 --- a/retroshare-gui/src/gui/WikiPoos/Wiki_images.qrc +++ b/retroshare-gui/src/gui/WikiPoos/Wiki_images.qrc @@ -5,9 +5,12 @@ images/resource-group-new.png images/appointment-new.png images/book2_32.png - images/story-editor.png + images/story-editor.png + images/story-editor_48.png images/republish.png images/resource-group-new_48.png - images/wikibook_32.png + images/wikibook_32.png + images/resource-group_64.png + images/appointment-new_64.png diff --git a/retroshare-gui/src/gui/WikiPoos/images/appointment-new_64.png b/retroshare-gui/src/gui/WikiPoos/images/appointment-new_64.png new file mode 100644 index 0000000000000000000000000000000000000000..7b99cd8770c3d35d7afb53557b9573ee9e85c6c9 GIT binary patch literal 8079 zcmV;AA8_D_P)3MY(Tw;A^haC=dPXj)mKs&Npi3(;FkA^1B) zo#qmGgcEtK16L#jxTj*PkYZy{?rU(k1}Jto6z6=dIa{&4H&Nz)@cenA|8#^=V6cgJ z-#5P@ihPz-?7we-yBo;J2_F#^{3kMc9?`fLi0Cj;zt12xgtZofcMziBhrXW|{E+DJ z;U&&LKAfoTcSRQ0{f?+?knhW7gNO=^^_){^Y;G3EkIbGFKa%KFV(Ocx5{dS{Z9OeY$#0frciv+I(Ir27WAGf@-S zwt%QgaUwIAXeA`_c!Q|&P9pD4gz%o^7vepM=*3DE*1TAWsMUy4ty_&C^7+u?tj~us z)M3Q2k!s=(M_IZ$ej|=2DG7fNu6Be-ADZ)UI)q<4?#$)2F6C)gFP)t#kBhd_{+kN{}<6iKFIX%iMF7`7N`i}ky-x8etxDz96#G@ ze8ug(#^Wpx+Yk>AB4d+Ln-FHSkxWS}yd%Wk3i7N?-JCiTg?o2aR#pkADN(u-1gif6 zFo4%fUd6r6!Cw9R`up`KGP+q?Y-{m4CtaoaOjn}oSIPH__C`55M4t{n_Ti_)F%PAm zOFx`Wh?Hg|kueNLI0-{wdTL}R8i}+1`2UJ<-vHMw^+O6nWHfX|F?hSPQQVRFl`(Ju z^9fPXr^r(!A$;$Sl{|W*6|-HoKCqpE;O)&Bgs`14x-nZri~}sN{iCeMvZ^9;KRe&x z!ly)&A{$O`-2&cAe5c?&kG>Z;D*L%$N zz4k`-QbcqAbF|=Gw1~0k7ly|wBh)5|Of;F1XdKTRBC3zcX+{>F3nmp&_YI&TP?6ak zC4V&0bVyfV1)95X2wz%+Jro#b!w`0>S*b`j*d%C^*O8z>czmsCN{>I(T+QrR&m1l1 z_cY2fXLru{BXcK&segLWIZPn4V_UqitSVhM`V3!x>_rIvz~iOcl<1AuOZR@ZKm!Q< zwJT6EKgaooyzX#U7cs!Q&XdduzhoXsoJzD{|IwTU`|TK8WwTiO8x0sqq}1Nh~?M28w@!9}1Um@HPZ) zVM-70Yv*PE1blrIM)at>_ z)6gLvs5rFbd49cu>$%O$UWU?N6a1;OvCQ-(AUtzbr@t7Zr6ZnsN8F|3JJF0r1jQDO z2qHvcB1xqB5;@Q)CQl}+gPQe00M43mhYV2g^V|}8>mkb)_e2>*w&#)gDitwTbpw+_KKUFMNi;3XpO*KM+%FEC6Q!TS@ly&T6`!d@9>1Wy5( z=Tn(4dTGL*V|3kkG2^SR>Q%&~Q>j|15?|qUmile*eilMMqGPfgKke{izWi~{@J#&N>MhYT*TfLH9!zTDdQgmzq{kX|TvCK+ zct_Z6nvqAicAA^gUyQ+P7_P>yCJegenCj0!*0?2*rS#7|L_E~Bke4Sgh<>3M_NQTh zXhH8I2M94 zdpbjezjwr|MWMYF^RC^O=IwojC?O;vAwkYa@F$7OI4>KP+6`Nj{X!eS9D}bq3WX~T zZ}~L17Y5;FJiZVf;*#?mT_?VsI<>~PQg)>_`fE4bYDyekREmw1{G z?jW_Wpsks3UvmrL`OM-;E3->rQfa(n_679eKfd1k{Mm7I-FT+K+>Q^7K#}gzFtX@) zs8JxWspmNs+R>jsb=q0SHzMO}j-Q1uJHjQeTi7=kfjB;6x4X~_94eC9>^KY%e$)3yBsOgwQCu=cQIcr^KvdJ!#`D?s5=s%D5ikNyzv#~vw#DH!aUNM3NNN6 zJ`WLvgc!+%AaTI2R$*SA6&ztH!CR^=Uf)($d1jyG*6++Y|450>fm8=nVkb0i3VY5$rzxv3+Z zb3dlM%N4(Y=)wr&K>A^*=bt@^B$8_@=2lT&36W41mU1GBmU9YBJa&xkS-2*vx!(@cnkI4%U2&=7 zkhnCeUS$ZcP44#uA&dxBQoWWO^ z8~L4tV;^T@*Do0VPR^5#5b&d}06V^gV@i>2(tN&CNfw*-OIE6G0yQUTgQs^PI^5Gh zk=us(F9_a7Z9}0sH%0q`w%44n7xj=pg;=_$2be`6*p6kVkASJTt&?9?f|Y z@|t6->lMp$pzWaN4xW{*tzQ3<$G3P^;>^Gbc{aGG6~mcmt7nGVF7rap=+3elU8#(L zj>cKTRoV&9+ebPRxL9U+=X{p^6H24srS*x(@qRDwXz6O#>U#~Tx|#hkAaZLi;b)sDmTx1&j7 zSl34JNXd=WJ_-S>VIA4m`_x%(6a~<0UvQ#QSsBYs{YGtReik zM^9TFD+avHvdo#Bc{JS^2;o0>ROh}qd%fd?qdE+5BrB3PPEt}X_R0JNOcrNYRmknS9J&8=`b}!&Jo$)U!PKi*Q z{RyjxQv)u;02wdr1?&{>4!lfx?4B^bB zOS?2)x|D7`+6kzWci75K-uU3NgH3A)X5n3(ydU)E5^6OQ!N0Vm z+0~G$9>_&$rPU9LeAnCEJ0ZDYr zVJpNSn(WxzezF6{&4bICp)f#JpQ8^tA#6RXya@f2)y!n}uu?_v#a1B;0>c(#P3AM^ zV3RMzmN%o#>1q$&C?^ZqGHd|Xd#*=Zr}%SYnL3|0QZhU8f+=Ne+}uobKO3q$Yn*@~ z9Hl(Zs*5xQ`)LF0P+PhxW6WmTmZ*%H(l}pF0dYg>umPxa!`MLd$o8y;1vw0)#VeU;hPA`v{=`~p1A++uZy;ICOT&Gz86n37E1t3zqpEPL^T zjoQ)!L>W=Cvr!f%AlGjYzBIhSw5 zA1VFIv;ig%@#|(^kj$DB`Kd~Ti>>5%oKZ&jd*ifly17WWk{R*mV`Gt{x(xTa%U?1d z?>8mnMh2?*!jSSTV1Z2BO@MHAf$dqy2lN*3c~=wR3(m&EEuA&g)I?DrRJyuHv3KWd@22 zXP&{AK_FMC(H*?T7-SB@<7>>#Mp+!sFeA({^7tyQB(@5+wOrCOj|4BeycM5fW$7lo z=k57|?E@=DO8Ode2>5wxrWFddnPW`mtyX&xzPS-$ZU(P5R~zl+{euh$j{Khv@g)qf zYk=!pR~Wdh>l6=N&ez!`oiIRJy^9ZJ_vJn~r`3hmiQ>Nr7?8eQa>$EFc#crADFPSF zv0q~LYh~XcJjFJI*?)trg&eqYiepU=3^Isd!Kptr^5=|$N-N{ znDjaupwip5R*K{5IVP2!K|uVsL#$^hap>3@aVL54sgYl~S30}UgX<;)cDn<@is9n2Ji`7%m! zuw?33t33;8t`_0ySwl>2=ITPo+AJtaxXH}t%W za-APL5M`Jr+d)-Zy=3u%;^y7V@0S9Og1FUu?SAzXRknGl>ay1NK|5P~y*ppR{4GiK``48_NF%wWzr ztA~C)%ZxB)fD4-{e2DyIMwBa8p>|fK-5KTmc||5FyY3OjSZqTUP)K zFy9`I+Jo=FQ*57&~6--SI{SXt;ZBCL17RUUi2uvhT}G*x_rX zE5QgcLP}0Q;Rr4KjGP=f-jq|2+1}6DhExP7a&%E_U&?nA5WN#c)M3rF4A5T;fPO!Z z0cs1CQO73aF)( zZDcBFnO2Xdg7i7Dy?Dq{$`CBte<0(Vb&7&D_IU1|X=h0AGQHotricilZ+Jx`$#z#a$J^pL}h~Eou z`pOCzUphRDfZ1m6E01rpzXF26F-j6vs^;HG#q-<>6HP|X zG5|I3S3JM|aW()PS|8b8!h-OFQ33kF2ZOFQp7N+#%B4sEpi@&N3X!f>TYz?!Z+no51Rx@=68bu zU?4m?hz5ZV7^jUqJzJy#9>cfaPYM!xFiUox5be3L-`;11cqi$9>L8U@+NJB z8RiV5y>$BvS$Ojc7^9mQWQ=5V2V=Sj8-vH$7|~c&=u(gKSolTq^D~S=lKH{N@gQ)D zSqqGTN3(ZY8GtzR4H{^y;;R*?17&y%SYO-@{L|fUQM{|+S|D5+ZQ%g$0%sTA>2Snn z7I%WPKf9RY@Z+7rxGD}5)#Odhd+;BFB&GQfksEqGNbTsQyu(z5A`Oqrb=Vx$Z&`#d?0b3Ujt z{z`&!6Dsfgk~Y8}iZA1R&sRZGqxpLa&s~fp+E;@lqBioLk%bXMPFZ-vM(bU!oGvcc z%nm8F7BD;PWb6X9rkxbP~mE%HuJRVQfyv-4G}xp0El9KF7G$-Dg9v4YvY+-Rqa zZ5xe)CbSAOmmj53gsE4(tw9W+>gfHGcU5S{DI;5&F2e2Z25lpS$Iv$j`R zH)}i2t52iwhYcW^#%-iFLT|;gEW@}sepbsk=WoJmT#3xsSDmJ&5DL><;z?qFZ}oC@ zvTEKOPZ%k3yw8y5X``8{GrOJ^ew|{UPTBxJDt4md;tRo(uF2GbSH>CfQn?F^Latqh_Qtr%!^ z+9!5BfT?NThN_+BZ9pO2Makb@4B~~6#L>NqW5y^>ZLZik^7;l?&Bztt zZk1?llw9H3G2CFVC;{0eFhm^~L}zRa^pb5EMA54+9F4}fteRe`-zxn4j?B_cc4YGY zfy39;Mhu`0kyS-=!>fPC&v8;Qwsut{UH!X)wjNq|Pc8ggTJTS_;M!m|ypIcJ+V!m} z?e8MXSHM&WpAntb!k=iYh3|0nO(Bj(LU71+4Uk%!kvj$4c8ShwltBU*R-hvv7;L40 z?3WlYLNf-YhGGmDU^9a#t|No!q{A`tByw-VsWM?3Ann2OCB8aXo{i*8fRW^$AYBoz zRDzM(0FAFUfEl6Knt64p_n58N@WRi2jc&dPQA8c0&tlQl??I+N%zOHJdv~egC_OT< z>55Z=72Chg`->sBYyh1>I`eM5)M_E}8pZtv(?-eL%-S0yCTTs(O+mM4H0i{obK$?H~bUyblsGa0FI|-6!4L8SR4VS4akf$!s zUXJ%Xd*SQV${8MrsrP~5851AC^WouNcM1>R3*px9L$+7NCuo%`cwAL2yf(>M55*Th zQ+#=wklYR~5k@-xssVIqy!8^TjiLwiW+mEf2D^E)sCyviHw*}Ofq}}fngKcHF)-u> z88E;ZwB3+ z5`FsybK|mgfgsly?=x`x1_Q@!8ALRdk^B7&gxUdQ5P2P8@YPgCpWP&}v!mjp!xg7h z%DrHv;*J}Dk{Ee2C?A(-dB1$TY?b%B#{NbiBlr7yN?b9<>*uurb}E+J=;hMT-7~;J zMjiq3ZHfNxt3)2L3^y7etuEtk^#J*8XVLxFIP#98M-fK8GeF)F?VgK2`F~Y$`v&un zaK8a`4{*Ok-?$Rpd4sv%0EZY?gu7p&uU(1mp22Kq8E!N{dOb#-DZtGo+Wo7FduK44 zME*0t?U(3Lj9bkhcdaViWw88X03B{9(Qa)P-ET1W8z7dED}WnHv>UGyx__#(wldsk zfQ29XuaAo3c-ow`WlPzYIMn%92ocy2V=}4R|Cdxq~dIB?mzS-G4ReCAdZnMoO?HZ^8dvj=M)Cf=^zHtuJa6{ z%ykT8bTI}|@M#9o1FaZD#m+Hu|IMT$-!RS$Y5g!`{Pv_3jNK2D#7Td}DVr5L9He6Z zoi~6){#eiF|DDC$-y=Bu7K3Q(Wd>27&I}^6J%fnC1eA4zfeKNVK@`1_5#OrwA;$O# zM>jFH$7V`MQhz8}|*G0j-|G2^?QTKN82 z`1ciO_tC@l%J)fI!XOH-#()8aGKgY!F)p?2w~sOT zz3@Yft!H$``)T3#Y2h#2BjNKJ;F0~>0Owp1bDzmB!62e;jO%64{X2yyNPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L0B*Vf0B*Vg*50uf00007bV*G`2iXY> z0Sf?J6^U{H024V$L_t(|+U;6-kX6;0|DAL1+h6zVrfFztLDmKV7eG`LkVO(T;=Yp6 zXr-cAW+qd!WhygCB{fN9QZ;|fWTujtEM;Px)FhL|g(4bU5@Q?@5EP^lyP=`!onGF4 zw{y;X_nhl{WtljE#>!ItmESwxJ?C=Y`Tf4-eD}4Ok|~*zDVdTfnUX1)k|~*zDVdTf znUdcNxo7>d)0m%}F#Mj#4XYO5@x9&n1DyE?HCK+e2IR~xpoIO2tO@DDz zKJoJK9|r;J7SFnh@cld>&_N)XQW8*r!rO(wBNnq@alSv1#HBl5?f3tn323o_b7tf& zj#<_|^1gy1gir+Z?ORjPXPm(MzA$SXAhI^R-aqk+o>z8Y?#k=_un0K1X9wnAavd(1 zJ$>ADog84mE3>P2xL+!uDVIR8;OV74Hd5LM;3aW%cqU-#XHL zY$jo2VFq{_xQZfN!4Cw+3RNtaGXqzzz5v&*UW!W=w!!yYboPzGb6v(QJ9*FTTMxak z=e0vP1F><2@~z#?`0(m+WAABfX~_EP*=;TG6+_h%kj%ol?QOVj^Ln(MHy_eYfgu3O6S#Bm7#`og1Ap_-Gw3zco@%j_Tps!P&-K8Qv&8JkXL;BKyGU$jjhRyT9!%zu{gPr1Pbs2fZGb`2CPhG zv6A-r*~j{FaH@E^RKOEM18V!HKTtRdlCQp$!xyjFp%mlz#H}0AzT`sKjnfExjKIfe zOwecpWP{VFlu&P z%{JotL<(1>(?C3-z_`+Tski`Kuy>x;W`>1o1F1%APGs2CgzsM;I@nloDtMxhm)mdr zQvA`ceQXR@uelgJkuvR$=8_w4>ks-=5)pJj320#!>{J6TyU#}M zOyK4(J>779ioBf4$XGI|y{gY9$JcrWQYXnyBArd*j${sZw$1bLO+d|Qo6Z>H09d4` z0f*vHQh+f9Why^7t!b_-n|g>=g!1uwZ<+p&|M|no5wQI^_mlG$;d3i4utam#;(-JT zWlcMK58gl2Mf^6l@$!8v^uDMaN6M%QRnkDfkfTE?S{rl6F@kF zp;H3S{jabZGI67kF`#3`Dyp_k6^+2KRI&(0*}ED6k>wG^?ZKl zSRQ>tS=G_LSk7!|z*yx798qLa22e2VDEp0MsCpe>mLg@j#5szIW}Fx~g}zgLtnBrv zFI{;LJP|-j30r$y0va3xxG=;;Ay1Q%VDg69WtU9i5`aZFR~ghd#DQ6~t_z-UlR!5F9$fPkh9IX;i6o335=<2hH{ zU7d6%m_6TK&k|yjW$W*UMIYQE)!XoJs(g$Mmk+YJt;^Y#C4Z)7WmjWlVvOoU8D&SX ziYtl4B)DooN9$&6TJj)f5&@D300P0Vf9MddnYjU(YzB#V z+?)ce9#bq-B}r91^hvo2AccTUn`~Qi_p&hjzw*$JCm#X6PZPd^MZhf|G%DC+``Qjr zss`A5{BgWFvJ*?sS;s!H<;x1ebhfMeNt_t%#ESDaV&OT<@%rFn*m>liFkTvERmX$l zD(3ot7kb}=jso8W2E0-H=-88Zuw@%mCIc`ICLNb_I5_Y#^cG%Z9W&Nr%SB&6L;T}-uIpd$&0U|R z{(Tr#*8}}Ws_;(mW(-qqd+*D5VEG+n`-pKKdEOj*Q8?6700M|=h44J$K|X{?CY=K5 zg^8fODf3V_>0ekxd3SHjSaJAmJeI90lV7!-WAnaq#n@*U96;fPNS7o?Zuf zixsSHnosG{ibOIIg*`}=v1`@eC`f}KP;RA)+~s#&he-<8EZhW0DX9oT(X;i2eV@S> z3PEIhg2o`cX0!og`+~y_B*v>JFi{yq#ql&K@Bal~j|^J^fA@=rRdu2Sw_4SnRuCrV zWk6aVq0FnYQ!cYW_z%FyO=&fYvWx%RG~+m$7Q#Gibo!F=-$%Saji>kQesb5Iy%;|=3ZEXV%*&5a z4h_Css-XK=4^9<|V#~HqRdE)?t`UGR0stO@vtW7wPHGvoeNt_kl!$CSUvVplS&jyL zy5K!hTasqeC%TRvLm&j!uDJ}2O-+c!V&-U+64gpob<_IZ!$)x24cGU8UvKn^f$LnbWGVK)*`-1fmM)mjQpqGN z&Jjq7lfxtE8XQ*d-?V`>=W_1ZCqOGRxosgj`=g#9h=|}cudkH`u1VqwRo8{Z%5XKf z(*R#T=Fu^2Mn^*?jdho;RweoeZ}bg7C@3DYRWgxe;hW!0D^~KBrY5FDa4tx?y1KA% z;li_*0)X*|=bN+N4nTxxkR}yu9z{n;1g|wsULa8t#WMpB=+^kdfBEm<>3;Mp)DLCU zw3b$7CE|+Nwv5H&NW>E?l}cLaWRh{t)W~SLk^29g&AG-cXRin<#t_vVA>Jx-EIRJY z@n=p5Qv(9B&Cv+m92Lt&0xC}%JjmX*_HN{wnym%be}qvcfW<6DNJ9lDhPlO=MYctx zkBo6kzdG0~THTU@X=&+ot1>iKcm0^JTX&JDv=0(f3v9`^af*B45D3 zz`(+>v56fY+;;!K{r7$JV~Awi-S_==5#UHz-k|eb<9M>C$xXwOT!EQQn~;yf-Pp$S zwRsaEWvBWM@Qw?(4$zut!RF~#;`Z!Tw2qvI!8c3Dk5(Z<7GWA3#!R?#lk0Q@#_@x% zec$>r5wY_p&mfVAn{}f^fCCn7()R;4J~ob%C;Mg&4GezumYeTZAG-G=Ur!_w`iS`S zr$7JhFGJ}Blqk!Rf5JbkCZwCOQtgREEbVilgi?$%nBN9Cplxn!OJ6g6LX3=tX+Y!< zc*ir*vpCg(b&YE<+ntM2pFm;4hwlXSzyC!>p^(R&cijrxj%n{ElS%yBXFh|{cfO7H zwNA%N+qbjIk|j8Q`En?wGyzAcDcZ5)DOk20y*rxsnXr|vk~0eV{3_1)pRZiG`ZlLh zDec?8SHC*nddmmV*?HjY1XLVIBB8`$7=n*3zt4X|j7hJ-PPGvcDGx%yQp|wnH6l!v zh9O`K$d@J3$l=1o3S44chS+EWCI&s^#~p}3nGk1yl*)i-&?1$@+O=!Y*474_06q28 zQ)p~&$HdN^x(jSrvj&YU#by zm#n(-8|ynt)J`&}YvEsh^Qj!=XUIC7*5d-v|s`-u9N+M0qw%#P8V z(ox|$E{eqx%H_&sfco2uFItuT;g7zz^BsQ}aRBAy;iN4LrW(|^mBCTr%6-*WE6*aw zH)rN2*YjDb*>850MMUU#gn;Q6s5WN-g8n213x#@!!xSv@CKuXT^~P$yb~7`!x1Woi zo*qn_HVw09&qgRNk+Fo*VdTI;;KB=W`Q?`r@FO76B+;`Y;0or`I3@@JC`;CeF;OQp z(dFI(Qkl$OUvu4!4?AV|0LQP9ihvrOfa8=fWLs)aBBOp}JMy2)`zoI+{>ptU=uA%d z11Y!_t~>!EAV6k(7Ai#-mTlF3*Qb#NNvgDGIJXRVK+i!L<;>IpYHMrYtARj%*Dhq^ zar8g`Jl>Ly4(c1`%n6T0L=S?}1V;*Gh!HaSE(Q74nhcAxkH8NgeDUDVfAJ)2yo-bp zT&0LeP()<16cHAV235H)zo+tS>?q%qU6@?2&Ouk3|K^R^*R=lu}fufX(oLDn8ut0|1z z^~k9IMh`1yArL`G!tDV5)W&Ziu7Gs&s1gxwmWZ%3=ng7!-}tV|bEPh}fh}skD$TrR zz<6Abs8@MbvsEnuB4+f!8At!X04@pwLjVEn{^c)`qwr7A8Ynf!#>UXn*r?az6cvL5 zL*{w9rYO`OtC=v*sUgtoqyiQ*4j=+%T(xOStVY0T6Oo~a$f8@6)!sy**%4WBm-#Dk zpbMT5QhU;bD2qH%C&1*d1dBY{-`}sRH>n0Nw095MElY=J3swEDmv^ISMmvNl77$Qass8&lD^j+-EWE(~aj8c%g*hHcM z8i%OR)ujQwTHrUtK7lPLX%<+8WI}aHGNz&x;f&Ke*3Yn9{+>hwlQ5C3tk9n>U zQv>QV(S3TKlnQMelMt8iIs%^W$(TNV6tqfdHWC#((x@Ps8|s@iBx#$vI1M;_&iME^ z1bLX#wTx0Cf9O!Srb#Lk3MiI}=Gi9g>cv$VHFGiw3{_t@d(+Qyoodd;B!yc%F`geA z%A_-l8WhF3#hCdr6V6fZ9@S%Q6Zf=k}F zK==0c!nQ5rRaGmgI(oRJ=j)AT{oPxW2@v=oP;@UF8yhW8ngA)JH#E@q-;IsA=4`g% z&O{>FYSZQ|Zt2R;6ahBC>u;KY(9M%X)ExpC92|nY=o{rq>6J+nK%SJ;Y9AKD|3a}? z*q+H`u1Tje?~5mr=f`ZDS(aUUfk6ZowJowJG);@$bG!#LX3WIMv7>0Uedw!J&K2R=~9(Ua8bDrxQqA18unt&+R zrR%ywq&w;1FBgl&N2noMnoeb|j3*K+VzKyn)Z@2W7Qy69hre_sh#&<<66N~-{rj={ zlGPaM>H@8xEW;E4d|IRY!khbELG!d`yx!RvhA~wA&t{51vM}PLFpXCre2)MQQPJ#n z9cOp7T6sxGahSY+f^IL@59#+#VwP=ZsVAR7;W~?uw^NOn6N|^^5fL*vz`6?6sf%G~VpEJjDPj`UANm3E0x5V(#+g!81=ki*l(PC=1cX z^7I7RV?@M&=epfA_DU)Hq!i)xsR*?AUH-4KcBn)~k_uRobHc}X3P1u3aRwGA5SAbK zJf2L2pPx#32;bRa{vGo!vFvj!vPg=O+o+w00(qQO+^RU2NnY@E3juS;s5{u24YJ`L;(K) z{{a7>y{D4^010nNL_t(|+SQp0a23@V$A4#c@67{(fj|IJ5Ku}jg4K?Q_<(8@i()`9 zv{)rLO;D}ns_$;CY6-ovZBp3pDlE>Y>yL(Re zo>`GNn45&Pk8kd`XLe`LcmDtHaUOduIw3dScq7Y}E#q*RK7Bf?R;{9I61~mN5YPiH zTC_-co(F(wnv|532+~NDHq#R@fr;d^n~_*pcz^_appv$E#q)4|7l6!oW@@nU^dkca zs8E6MzP%WL_=?tkjm;rsV1|7xZO>ycJ9v%#_#F|*2M%xr^H~y;CVAPt>DwbWX!~Gf zDjeHUj^_x?)wR^^AI~Z4WgSDNl}T1SBWUAfq|}TPGc62Zpp?RsK1n}`?YRW~v0aBm z&^CJYBodBteQlGNA6Jt$jW6?EL0xM-wXKcRwbj!qZFqvYxvbWA{SNR$jis0<9# zguSq=^a=bhh8ac%B*92|T7fBo7E`OhKuQCbR0ISd5P%^>pkM|UVFFdK^r7WQApyv; zGQkGJFc3lk3Z?uIm;%w2BG#St70;0jo7bBPxfx3cVy5;oXZJV(C*kUQLr8=Oy`>bs zq0l#gl&Lh5xW1o?NT7;j!sEPqhSJpX5w4Utp7uDytv-QGU)u<@d$W)Lq)MsMssY$4 z0II+=KnWcoHvmBjJO(a)NE>{mFr*Cqu5D=GUP}EGP>Js=l1UFejs&F8c75B|<7on6 z-$RB!0igJ_(@wvmpx}bL7cXA?`y&!iTD6gOB&4C*ffIh%;-mOtKm$`42qT16195*h%C5a1V)&{5EO*mLb1O+acgArU~q#bYOr zbB3IA@75RYQ~3i1vwz%Aj0pPPlPV-~cqAmAQVjG_znXUL#eGIxsfH)Uh~%HH;i=Lv4GS`iP)hxf zgia?k3C{yJMaBpGFBi~k3(Ch16J=YMsKB{^eFgi&6fmn zfOlD{HmimFkBEBbEVfkI%wBv@B<#mIWk{o!J9vs!6J2A0OkDt1hoaozgY3B@8pIcoAkR~k)kpNou*WYRV7 z>BX?FMpt@H|gPR~QzpRWFg_Y~;x` z4U|5$gLpj7Ymc~8?RPl2Xg9v+BT!(35WA5=dcdef7$$AC{~){RNuGVBg}Was$1r1T zc+jJvp@xw&Y5|Er9sO4c%d&`C5{>0#e0~pQ+giEhp=y*0QnjQF?9UlqcmTtUrw5;& zfCitc0Ug>XL@J2U!g&Lhv*Ri{(P z;M=H3Yfy*z_czyBzn;~+#dha;;a@T*s^?ivY^L0^9z;|Hx|)}kJ4 z-6iOmrC4!$f{!bEaOwPKaqYC=qpN{w)24O7@dmBCSJGquO6HYjQuav?;uiezwmRzC zhH%NeEx6kAX+0fH3WX#(9p?ImgVg=&O;$gj#p<_uVwr-cZ>yx<9>h6Uzm4nIfI@Xp zbCIS{m`3Tn5N^GpntQaZs{DC%CSw$BHV2^!&eO z&6-ZsfS`Kc=M;?XM{U(xOdQ?7_GzMVCb+B8hke;+8S89 zcJ0^JKu%5$bLLz_ZA~Tj-Z7ICMqkgiZQB_-^h8a*i(m4hokqi)WXhB&+Q^aS{PpYC zvwL?XOO`C5xVTuSThK54_9H#W==MUM=Y8$8dGq}FR8&-O?6Jp^NF+4)2mnPwAnl)Q zJ9g~g(*V3}+ff{PqTdT;Wo6Nkj2SZqfb8sSB9Q1J5DP>IF&oJ2$T3}UVg&El0W3>L zIvs)FrMTj002ovPDHLk FV1kN7(xm_Z literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp b/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp index dd7c23288..d5f68e084 100644 --- a/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp @@ -124,7 +124,7 @@ QString WikiGroupDialog::serviceHeader() QPixmap WikiGroupDialog::serviceImage() { - return QPixmap(); + return QPixmap(":/images/resource-group_64.png"); } bool WikiGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) From ebbe967402a7277b3f8c59b6cede4a30ae22436d Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Thu, 22 Nov 2012 22:40:31 +0000 Subject: [PATCH 173/222] Fixed posted item serialisation (wrong way round) cleaned up comments gui and added loading framework correctly initialisaed posted items git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5876 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/serialiser/rsposteditems.cc | 3 +- .../src/gui/Posted/PostedComments.cpp | 11 +- .../src/gui/Posted/PostedComments.h | 77 +-- .../src/gui/Posted/PostedComments.ui | 475 +++++++++++++----- .../src/gui/Posted/PostedCreatePostDialog.cpp | 1 + .../src/gui/Posted/PostedCreatePostDialog.ui | 20 +- .../src/gui/Posted/PostedDialog.cpp | 21 +- retroshare-gui/src/gui/Posted/PostedDialog.h | 23 +- retroshare-gui/src/gui/Posted/PostedItem.cpp | 50 +- retroshare-gui/src/gui/Posted/PostedItem.h | 17 +- retroshare-gui/src/gui/Posted/PostedItem.ui | 8 +- .../src/gui/Posted/PostedListDialog.cpp | 22 +- .../src/gui/Posted/PostedListDialog.h | 15 +- .../src/gui/gxs/GxsCommentTreeWidget.cpp | 3 +- 14 files changed, 456 insertions(+), 290 deletions(-) diff --git a/libretroshare/src/serialiser/rsposteditems.cc b/libretroshare/src/serialiser/rsposteditems.cc index ce0f71bab..38421a8eb 100644 --- a/libretroshare/src/serialiser/rsposteditems.cc +++ b/libretroshare/src/serialiser/rsposteditems.cc @@ -194,9 +194,8 @@ bool RsGxsPostedSerialiser::serialiseGxsPostedPostItem(RsGxsPostedPostItem* item /* GxsPhotoAlbumItem */ - ok &= SetTlvString(data, tlvsize, &offset, 1, item->mPost.mNotes); ok &= SetTlvString(data, tlvsize, &offset, 1, item->mPost.mLink); - + ok &= SetTlvString(data, tlvsize, &offset, 1, item->mPost.mNotes); if(offset != tlvsize) { diff --git a/retroshare-gui/src/gui/Posted/PostedComments.cpp b/retroshare-gui/src/gui/Posted/PostedComments.cpp index 90345adf8..12558668d 100644 --- a/retroshare-gui/src/gui/Posted/PostedComments.cpp +++ b/retroshare-gui/src/gui/Posted/PostedComments.cpp @@ -61,16 +61,13 @@ PostedComments::PostedComments(QWidget *parent) :QWidget(parent) { - ui.setupUi(this); - - /* setup TokenQueue */ - //mPhotoQueue = new TokenQueue(rsPhoto, this); - - ui.treeWidget->setup(rsPosted->getTokenService()); + ui.setupUi(this); + ui.postFrame->setVisible(false); + ui.treeWidget->setup(rsPosted->getTokenService()); } -void PostedComments::loadComments( std::string threadId ) +void PostedComments::loadComments(const RsGxsMessageId& threadId ) { std::cerr << "PostedComments::loadComments(" << threadId << ")"; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/Posted/PostedComments.h b/retroshare-gui/src/gui/Posted/PostedComments.h index 8a1d78e57..5458fafc0 100644 --- a/retroshare-gui/src/gui/Posted/PostedComments.h +++ b/retroshare-gui/src/gui/Posted/PostedComments.h @@ -31,12 +31,9 @@ #include -//#include "gui/Posted/PostedItem.h" -//#include "gui/PhotoShare/PhotoAddDialog.h" -//#include "gui/PhotoShare/PhotoSlideShow.h" -#include "util/TokenQueueVEG.h" +#include "util/TokenQueue.h" -class PostedComments: public QWidget, public TokenResponseVEG +class PostedComments: public QWidget, public TokenResponse { Q_OBJECT @@ -44,75 +41,13 @@ public: PostedComments(QWidget *parent = 0); public slots: - void loadComments( std::string ); + + void loadComments(const RsGxsMessageId& ); private: - void loadRequest(const TokenQueueVEG *queue, const TokenRequestVEG &req) { return; } + void loadRequest(const TokenQueue *queue, const TokenRequest &req) { return; } -#if 0 -virtual void deletePhotoItem(PhotoItem *, uint32_t type); -virtual void notifySelection(PhotoItem *item, int ptype); - - void notifyAlbumSelection(PhotoItem *item); - void notifyPhotoSelection(PhotoItem *item); - - - -private slots: - - void checkUpdate(); - void OpenOrShowPhotoAddDialog(); - void OpenPhotoEditDialog(); - void OpenSlideShow(); -private: - - /* Request Response Functions for loading data */ - void requestAlbumList(); - void requestAlbumData(const std::list &ids); - void requestPhotoList(const std::string &albumId); - void requestPhotoData(const std::list &photoIds); - - void loadAlbumList(const uint32_t &token); - bool loadAlbumData(const uint32_t &token); - void loadPhotoList(const uint32_t &token); - void loadPhotoData(const uint32_t &token); - - void loadRequest(const TokenQueue *queue, const TokenRequest &req); - - - /* TODO: These functions must be filled in for proper filtering to work - * and tied to the GUI input - */ - - bool matchesAlbumFilter(const RsPhotoAlbum &album); - double AlbumScore(const RsPhotoAlbum &album); - bool matchesPhotoFilter(const RsPhotoPhoto &photo); - double PhotoScore(const RsPhotoPhoto &photo); - - /* Grunt work of setting up the GUI */ - - //bool FilterNSortAlbums(const std::list &albumIds, std::list &filteredAlbumIds, int count); - //bool FilterNSortPhotos(const std::list &photoIds, std::list &filteredPhotoIds, int count); - //void insertAlbums(); - //void insertPhotosForAlbum(const std::list &albumIds); - - void insertPhotosForSelectedAlbum(); - - void addAlbum(const RsPhotoAlbum &album); - void addPhoto(const RsPhotoPhoto &photo); - - void clearAlbums(); - void clearPhotos(); - - PhotoAddDialog *mAddDialog; - PhotoSlideShow *mSlideShow; - - PhotoItem *mAlbumSelected; - PhotoItem *mPhotoSelected; - -#endif - - TokenQueueVEG *mPhotoQueue; + TokenQueue *mPhotoQueue; /* UI - from Designer */ Ui::PostedComments ui; diff --git a/retroshare-gui/src/gui/Posted/PostedComments.ui b/retroshare-gui/src/gui/Posted/PostedComments.ui index e2ea38c34..8347d0c5b 100644 --- a/retroshare-gui/src/gui/Posted/PostedComments.ui +++ b/retroshare-gui/src/gui/Posted/PostedComments.ui @@ -1,117 +1,358 @@ - - - PostedComments - - - - 0 - 0 - 632 - 398 - - - - Form - - - - - - - - Hot - - - - - - - New - - - - - - - Top - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Refresh - - - - - - - - - - Stuff - - - - - New Column - - - - - Yes More - - - - - more, more, more - - - - - More Stuff - - - - - Less Stuff - - - - - More - - - - - asdf - - - - - - - - - GxsCommentTreeWidget - QTreeWidget -
gui/gxs/GxsCommentTreeWidget.h
-
-
- - -
+ + + PostedComments + + + + 0 + 0 + 632 + 398 + + + + Form + + + + + + + 0 + 0 + + + + QFrame#frame{border: 2px solid #CCCCCC; +background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0 #EEEEEE, stop: 1 #CCCCCC); +border-radius: 10px} + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + 20 + + + + 1 + + + + + + + + + /\ + + + + + + + score + + + + + + + \/ + + + + + + + + + + 0 + 0 + + + + + 12 + 75 + true + + + + Title this is a very very very very loooooooooooooooonnnnnnnnnnnnnnnnng title dont you think? yes it is and should wrap around I hope + + + true + + + true + + + + + + + + + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + Date + + + + + + + + 0 + 0 + + + + + 9 + + + + You eyes only + + + true + + + + + + + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + From + + + + + + + + 0 + 0 + + + + + 9 + + + + Signed by + + + true + + + + + + + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + Site + + + + + + + + 0 + 0 + + + + + 9 + + + + Signed by + + + true + + + + + + + + + + + + + + + + false + + + + 6 + + + 0 + + + + + Hot + + + true + + + true + + + + + + + New + + + true + + + true + + + + + + + Top + + + true + + + false + + + true + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Refresh + + + + + + + + + + Comment + + + + + Author + + + + + Points + + + + + + + + + GxsCommentTreeWidget + QTreeWidget +
gui/gxs/GxsCommentTreeWidget.h
+
+
+ + +
diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp index 91d97f703..00512379e 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp @@ -15,6 +15,7 @@ void PostedCreatePostDialog::createPost() post.mMeta.mGroupId = mGrpId; post.mLink = ui->linkEdit->text().toStdString(); post.mNotes = ui->notesTextEdit->toPlainText().toStdString(); + post.mMeta.mMsgName = ui->titleEdit->text().toStdString(); uint32_t token; mPosted->submitPost(token, post); diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui index 2b0be21e8..e565194d0 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui @@ -7,13 +7,31 @@ 0 0 406 - 168 + 195 Create Post + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Title</span></p></body></html> + + + + + + + + diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.cpp b/retroshare-gui/src/gui/Posted/PostedDialog.cpp index 1f1ec1cdd..283969441 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedDialog.cpp @@ -47,17 +47,22 @@ PostedDialog::PostedDialog(QWidget *parent) : MainPage(parent) { - ui.setupUi(this); + ui.setupUi(this); - mPostedList = new PostedListDialog(NULL); - mPostedComments = new PostedComments(NULL); + mPostedList = new PostedListDialog(NULL); + mPostedComments = new PostedComments(NULL); - QString list("List"); - ui.tabWidget->addTab(mPostedList, list); - QString comments("Comments"); - ui.tabWidget->addTab(mPostedComments, comments); + QString list("List"); + ui.tabWidget->addTab(mPostedList, list); + QString comments("Comments"); + ui.tabWidget->addTab(mPostedComments, comments); - connect(mPostedList, SIGNAL(loadComments( std::string ) ), mPostedComments, SLOT(loadComments( std::string ) ) ); + connect(mPostedList, SIGNAL(loadComments( std::string ) ), mPostedComments, SLOT(loadComments( std::string ) ) ); +} + +void PostedDialog::commentLoad(const RsGxsMessageId &msgId) +{ + mPostedComments->loadComments(msgId); } diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.h b/retroshare-gui/src/gui/Posted/PostedDialog.h index 823d44850..82210b913 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedDialog.h @@ -31,28 +31,27 @@ #include -//#include "gui/Posted/PostedList.h" -//#include "gui/Posted/PostedComments.h" +class CommentHolder +{ +public: -//#include "gui/PhotoShare/PhotoAddDialog.h" -//#include "gui/PhotoShare/PhotoSlideShow.h" -//#include "util/TokenQueue.h" + /*! + * This should be used for loading comments of a message on a main comment viewing page + * @param msgId the message id for which comments will be requested + */ + virtual void commentLoad(const RsGxsMessageId& msgId) = 0; +}; class PostedListDialog; class PostedComments; -class PostedDialog : public MainPage +class PostedDialog : public MainPage, public CommentHolder { Q_OBJECT public: PostedDialog(QWidget *parent = 0); - -//virtual void addTab(std::string item); - -private slots: - - //void OpenSlideShow(); + void commentLoad(const RsGxsMessageId &msgId); private: diff --git a/retroshare-gui/src/gui/Posted/PostedItem.cpp b/retroshare-gui/src/gui/Posted/PostedItem.cpp index 9a0f756c5..3bfaceda3 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.cpp +++ b/retroshare-gui/src/gui/Posted/PostedItem.cpp @@ -35,55 +35,41 @@ #include #include -/**** - * #define DEBUG_ITEM 1 - ****/ /** Constructor */ -PostedItem::PostedItem(PostedHolder *parent, const RsPostedPost &post) -:QWidget(NULL) +PostedItem::PostedItem(PostedHolder *postHolder, const RsPostedPost &post) +:QWidget(NULL), mPostHolder(postHolder) { setupUi(this); setAttribute ( Qt::WA_DeleteOnClose, true ); - titleLabel->setText(QString::fromUtf8(post.mMeta.mMsgName.c_str())); - //dateLabel->setText(QString("Whenever")); + QDateTime qtime; + qtime.setTime_t(mPost.mMeta.mPublishTs); + QString timestamp = qtime.toString("dd.MMMM yyyy hh:mm"); + dateLabel->setText(timestamp); fromLabel->setText(QString::fromUtf8(post.mMeta.mAuthorId.c_str())); - //siteLabel->setText(QString::fromUtf8(post.mMeta.mAuthorId.c_str())); - //scoreLabel->setText(QString("1140")); + titleLabel->setText("
" + + QString::fromStdString(post.mMeta.mMsgName) + ""); + siteLabel->setText("" + + QString::fromStdString(post.mLink) + ""); - // exposed for testing... - float score = 0; - time_t now = time(NULL); - - QString fromLabelTxt = QString(" Age: ") + QString::number(now - post.mMeta.mPublishTs); - fromLabelTxt += QString(" Score: ") + QString::number(score); - fromLabel->setText(fromLabelTxt); - - uint32_t votes = 0; - uint32_t comments = 0; - //rsPosted->extractPostedCache(post.mMeta.mServiceString, votes, comments); - scoreLabel->setText(QString::number(votes)); - QString commentLabel = QString("Comments: ") + QString::number(comments); - commentLabel += QString(" Votes: ") + QString::number(votes); - siteLabel->setText(commentLabel); - - QDateTime ts; - ts.setTime_t(post.mMeta.mPublishTs); - dateLabel->setText(ts.toString(QString("yyyy/MM/dd hh:mm:ss"))); - - mThreadId = post.mMeta.mThreadId; - mParent = parent; + scoreLabel->setText(QString("1")); connect( commentButton, SIGNAL( clicked() ), this, SLOT( loadComments() ) ); return; } +RsPostedPost PostedItem::getPost() const +{ + return mPost; +} void PostedItem::loadComments() { std::cerr << "PostedItem::loadComments() Requesting for " << mThreadId; std::cerr << std::endl; - mParent->requestComments(mThreadId); + mPostHolder->showComments(mPost.mMeta.mMsgId); } diff --git a/retroshare-gui/src/gui/Posted/PostedItem.h b/retroshare-gui/src/gui/Posted/PostedItem.h index 0a233457b..1c066f74d 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.h +++ b/retroshare-gui/src/gui/Posted/PostedItem.h @@ -34,10 +34,8 @@ class PostedItem; class PostedHolder { public: -virtual void deletePostedItem(PostedItem *, uint32_t ptype) = 0; -virtual void notifySelection(PostedItem *item, int ptype) = 0; -virtual void requestComments(std::string threadId) = 0; + virtual void showComments(const RsGxsMessageId& threadId) = 0; }; @@ -48,15 +46,7 @@ class PostedItem : public QWidget, private Ui::PostedItem public: PostedItem(PostedHolder *parent, const RsPostedPost &item); - //void setDummyText(); - //void updateParent(PhotoHolder *parent); // for external construction. - //void removeItem(); - - //void setSelected(bool on); - //bool isSelected(); - -protected: - //void mousePressEvent(QMouseEvent *event); + RsPostedPost getPost() const; private slots: void loadComments(); @@ -66,7 +56,8 @@ private: bool mSelected; std::string mThreadId; - PostedHolder *mParent; + PostedHolder *mPostHolder; + RsPostedPost mPost; }; diff --git a/retroshare-gui/src/gui/Posted/PostedItem.ui b/retroshare-gui/src/gui/Posted/PostedItem.ui index bacacace5..1d0fe0307 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.ui +++ b/retroshare-gui/src/gui/Posted/PostedItem.ui @@ -60,7 +60,7 @@ border-radius: 10px} - + /\ @@ -74,7 +74,7 @@ border-radius: 10px} - + \/ @@ -278,8 +278,6 @@ border-radius: 10px} - - - + diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp index 63a6d3ad4..da542da71 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp @@ -25,6 +25,7 @@ #include "gui/Posted/PostedGroupDialog.h" #include "gui/Posted/PostedCreatePostDialog.h" +#include "gui/Posted/PostedDialog.h" #include #include @@ -63,8 +64,8 @@ #define IMAGE_COPYLINK ":/images/copyrslink.png" /** Constructor */ -PostedListDialog::PostedListDialog(QWidget *parent) -: RsAutoUpdatePage(1000,parent) +PostedListDialog::PostedListDialog(CommentHolder *commentHolder, QWidget *parent) +: RsAutoUpdatePage(1000,parent), mCommentHolder(commentHolder) { /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); @@ -93,7 +94,7 @@ void PostedListDialog::groupListCustomPopupMenu( QPoint /*point*/ ) { QMenu contextMnu( this ); - QAction *action = contextMnu.addAction(QIcon(IMAGE_MESSAGE), tr("Create Topic"), this, SLOT(newPost())); + QAction *action = contextMnu.addAction(QIcon(IMAGE_MESSAGE), tr("Submit Post"), this, SLOT(newPost())); action->setDisabled (mCurrTopicId.empty()); contextMnu.exec(QCursor::pos()); @@ -105,6 +106,11 @@ void PostedListDialog::newPost() cp.exec(); } +void PostedListDialog::showComments(const RsGxsMessageId &threadId) +{ + mCommentHolder->commentLoad(threadId); +} + void PostedListDialog::updateDisplay() { std::list groupIds; @@ -121,16 +127,6 @@ void PostedListDialog::updateDisplay() } -void PostedListDialog::requestComments(std::string threadId) -{ - /* call a signal */ - std::cerr << "PostedListDialog::requestComments(" << threadId << ")"; - std::cerr << std::endl; - - loadComments(threadId); - -} - void PostedListDialog::changedTopic(const QString &id) { diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.h b/retroshare-gui/src/gui/Posted/PostedListDialog.h index 8889babf4..d4dc5f9f0 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.h @@ -35,9 +35,11 @@ #include "gui/common/GroupTreeWidget.h" #include "util/TokenQueue.h" - #include "retroshare-gui/RsAutoUpdatePage.h" + +class CommentHolder; + /*********************** **** **** **** ***********************/ /** Request / Response of Data ********************************/ /*********************** **** **** **** ***********************/ @@ -54,14 +56,9 @@ class PostedListDialog : public RsAutoUpdatePage, public PostedHolder, public To Q_OBJECT public: - PostedListDialog(QWidget *parent = 0); + PostedListDialog(CommentHolder* commentHolder, QWidget *parent = 0); - virtual void deletePostedItem(PostedItem *, uint32_t ptype) { return; } - virtual void notifySelection(PostedItem *item, int ptype) { return; } - virtual void requestComments(std::string threadId); - -signals: - void loadComments( std::string ); + void showComments(const RsGxsMessageId &threadId); private slots: @@ -117,6 +114,8 @@ private: QMap mGroups; TokenQueue *mPostedQueue; + CommentHolder* mCommentHolder; + /* UI - from Designer */ Ui::PostedListDialog ui; diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp index 88248879c..ccd35b887 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp @@ -43,7 +43,8 @@ GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent) :QTreeWidget(parent), mRsService(NULL), mTokenQueue(NULL) { - return; + + return; } void GxsCommentTreeWidget::setup(RsTokenService *service) From 86e1f105e65150140e491c9628b2872339038997 Mon Sep 17 00:00:00 2001 From: defnax Date: Fri, 23 Nov 2012 00:11:05 +0000 Subject: [PATCH 174/222] some layout improvements for Create Album added placeholder text git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5877 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/gui/PhotoShare/AlbumCreateDialog.cpp | 7 + .../src/gui/PhotoShare/AlbumCreateDialog.ui | 305 ++++++++++-------- .../src/gui/PhotoShare/PhotoShare.ui | 26 +- 3 files changed, 194 insertions(+), 144 deletions(-) diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp index 7356747e1..c4e2bf462 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp @@ -14,6 +14,13 @@ AlbumCreateDialog::AlbumCreateDialog(TokenQueue *photoQueue, RsPhotoV2 *rs_photo ui->headerFrame->setHeaderImage(QPixmap(":/images/album_create_64.png")); ui->headerFrame->setHeaderText(tr("Create Album")); + + +#if QT_VERSION >= 0x040700 + ui->lineEdit_Title_2->setPlaceholderText(tr("Untitle Album")) ; + //ui->textEdit_Description->setPlaceholderText(tr("Say something about this album...")) ; + ui->lineEdit_Where->setPlaceholderText(tr("Where were this taken?")) ; +#endif connect(ui->publishButton, SIGNAL(clicked()), this, SLOT(publishAlbum())); connect(ui->AlbumThumbNail, SIGNAL(clicked()), this, SLOT(addAlbumThumbnail())); diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui index 89b016535..24f33b61f 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui @@ -180,35 +180,48 @@ border-radius: 10px; - + + + + Description: + + + + + + + + + + Photographer: - - + + - - - Description - - - - - - - Where: - - + + + + Qt::Vertical + + + + 20 + 40 + + + @@ -219,119 +232,6 @@ border-radius: 10px; - - - - - 1 - 0 - - - - Share Options - - - - - - - 0 - 0 - - - - - Public - - - - - Restricted - - - - - - - - - 0 - 0 - - - - - Resize Images (< 1Mb) - - - - - Resize Images (< 10Mb) - - - - - Send Original Images - - - - - - - - - 0 - 0 - - - - - No Comments Allowed - - - - - Authenticated Comments - - - - - Any Comments Allowed - - - - - - - - - 0 - 0 - - - - - Publish with Identity - - - - - - - - - - - Qt::Horizontal - - - - 168 - 20 - - - - @@ -359,6 +259,155 @@ border-radius: 10px; + + + + + 1 + 0 + + + + Share Options + + + + + + + + Policy: + + + + + + + Quality: + + + + + + + Comments: + + + + + + + Identity: + + + + + + + + + + + + 0 + 0 + + + + + Public + + + + + Restricted + + + + + + + + + 0 + 0 + + + + + Resize Images (< 1Mb) + + + + + Resize Images (< 10Mb) + + + + + Send Original Images + + + + + + + + + 0 + 0 + + + + + No Comments Allowed + + + + + Authenticated Comments + + + + + Any Comments Allowed + + + + + + + + + 0 + 0 + + + + + Publish with Identity + + + + + + + + + + Qt::Horizontal + + + + 168 + 20 + + + + + + + diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui index f27d948dd..8d16bb21b 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui @@ -236,7 +236,7 @@ Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - + 0 @@ -248,21 +248,7 @@ QWidget#scrollAreaWidgetContents{border: none;} - - - - - Qt::Horizontal - - - - 426 - 20 - - - - - + @@ -299,6 +285,14 @@ + + + PhotoDrop + QWidget +
gui/PhotoShare/PhotoDrop.h
+ 1 +
+
From 6db70b058103f6e7c07314e74b9ecea0859bf248 Mon Sep 17 00:00:00 2001 From: defnax Date: Fri, 23 Nov 2012 00:14:33 +0000 Subject: [PATCH 175/222] restored back wrong commit git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5878 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/gui/PhotoShare/PhotoShare.ui | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui index 8d16bb21b..f27d948dd 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui @@ -236,7 +236,7 @@ Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - + 0 @@ -248,7 +248,21 @@ QWidget#scrollAreaWidgetContents{border: none;} - + + + + + Qt::Horizontal + + + + 426 + 20 + + + + + @@ -285,14 +299,6 @@ - - - PhotoDrop - QWidget -
gui/PhotoShare/PhotoDrop.h
- 1 -
-
From da39d1de77d2a03115a58e9a5c88b073fbe62162 Mon Sep 17 00:00:00 2001 From: defnax Date: Fri, 23 Nov 2012 15:31:37 +0000 Subject: [PATCH 176/222] Added minimize/maximize buttons to QDialog, Added to display "Where" and "Description" Label on Album Dialog Added a StackedWidget to Create Album Dialog, to use later for adding Photos, when generating a new Album git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5879 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/gui/PhotoShare/AlbumCreateDialog.cpp | 85 +- .../src/gui/PhotoShare/AlbumCreateDialog.h | 14 +- .../src/gui/PhotoShare/AlbumCreateDialog.ui | 810 ++++++++++-------- .../src/gui/PhotoShare/AlbumDialog.cpp | 5 +- .../src/gui/PhotoShare/AlbumDialog.ui | 95 +- .../src/gui/PhotoShare/PhotoDialog.cpp | 2 +- .../gui/PhotoShare/images/album_create_64.png | Bin 4543 -> 5201 bytes 7 files changed, 617 insertions(+), 394 deletions(-) diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp index c4e2bf462..a923cafdf 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp @@ -7,8 +7,8 @@ #include "gxs/rsgxsflags.h" AlbumCreateDialog::AlbumCreateDialog(TokenQueue *photoQueue, RsPhotoV2 *rs_photo, QWidget *parent): - QDialog(parent), - ui(new Ui::AlbumCreateDialog), mPhotoQueue(photoQueue), mRsPhoto(rs_photo) + QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), + ui(new Ui::AlbumCreateDialog), mPhotoQueue(photoQueue), mRsPhoto(rs_photo), mPhotoSelected(NULL) { ui->setupUi(this); @@ -17,14 +17,25 @@ AlbumCreateDialog::AlbumCreateDialog(TokenQueue *photoQueue, RsPhotoV2 *rs_photo #if QT_VERSION >= 0x040700 - ui->lineEdit_Title_2->setPlaceholderText(tr("Untitle Album")) ; + ui->lineEdit_Title_2->setPlaceholderText(tr("Untitle Album")); + ui->lineEdit_Caption_2->setPlaceholderText(tr("Say something about this album...")); //ui->textEdit_Description->setPlaceholderText(tr("Say something about this album...")) ; - ui->lineEdit_Where->setPlaceholderText(tr("Where were this taken?")) ; + ui->lineEdit_Where->setPlaceholderText(tr("Where were this taken?")); #endif + ui->backButton->hide(); + connect(ui->publishButton, SIGNAL(clicked()), this, SLOT(publishAlbum())); connect(ui->AlbumThumbNail, SIGNAL(clicked()), this, SLOT(addAlbumThumbnail())); + connect(ui->addphotosButton, SIGNAL(clicked()),this, SLOT(changePage())); + connect(ui->backButton, SIGNAL(clicked()),this, SLOT(backPage())); + + + mPhotoDrop = ui->scrollAreaWidgetContents; + mPhotoDrop->setPhotoItemHolder(this); + + } AlbumCreateDialog::~AlbumCreateDialog() @@ -68,9 +79,35 @@ void AlbumCreateDialog::publishAlbum() uint32_t token; mRsPhoto->submitAlbumDetails(token, album); mPhotoQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, 0); + + publishPhotos(); + close(); } +void AlbumCreateDialog::publishPhotos() +{ + // get fields for album to publish, publish and then exit dialog + RsPhotoAlbum album; + + QSet photos; + + mPhotoDrop->getPhotos(photos); + + QSetIterator sit(photos); + + while(sit.hasNext()) + { + PhotoItem* item = sit.next(); + uint32_t token; + RsPhotoPhoto photo = item->getPhotoDetails(); + photo.mMeta.mGroupId = album.mMeta.mGroupId; + mRsPhoto->submitPhoto(token, photo); + mPhotoQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); + } + +} + bool AlbumCreateDialog::getAlbumThumbnail(RsPhotoThumbnail &nail) { const QPixmap *tmppix = &mThumbNail; @@ -111,3 +148,43 @@ void AlbumCreateDialog::addAlbumThumbnail() // to show the selected ui->AlbumThumbNail->setIcon(mThumbNail); } + +void AlbumCreateDialog::changePage() +{ + int nextPage = ui->stackedWidget->currentIndex() + 1; + if (nextPage >= ui->stackedWidget->count()) + nextPage = 0; + ui->stackedWidget->setCurrentIndex(nextPage); + + ui->backButton->show(); + ui->addphotosButton->hide(); +} + +void AlbumCreateDialog::backPage() +{ + int nextPage = ui->stackedWidget->currentIndex() - 1; + if (nextPage >= ui->stackedWidget->count()) + nextPage = 0; + ui->stackedWidget->setCurrentIndex(nextPage); + + ui->backButton->hide(); + ui->addphotosButton->show(); +} + +void AlbumCreateDialog::notifySelection(PhotoShareItem *selection) +{ + + PhotoItem* pItem = dynamic_cast(selection); + + if(mPhotoSelected == NULL) + { + return; + } + else + { + mPhotoSelected->setSelected(false); + mPhotoSelected = pItem; + } + + mPhotoSelected->setSelected(true); +} diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.h b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.h index 9303ce6f6..1e40da671 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.h @@ -4,23 +4,33 @@ #include #include "util/TokenQueue.h" #include "retroshare/rsphotoV2.h" +#include "PhotoShareItemHolder.h" +#include "PhotoItem.h" +#include "PhotoDrop.h" namespace Ui { class AlbumCreateDialog; } -class AlbumCreateDialog : public QDialog +class AlbumCreateDialog : public QDialog, public PhotoShareItemHolder { Q_OBJECT public: explicit AlbumCreateDialog(TokenQueue* photoQueue, RsPhotoV2* rs_photo, QWidget *parent = 0); ~AlbumCreateDialog(); + + void notifySelection(PhotoShareItem* selection); + private slots: void publishAlbum(); + void publishPhotos(); void addAlbumThumbnail(); + void changePage(); + void backPage(); + private: @@ -31,6 +41,8 @@ private: TokenQueue* mPhotoQueue; RsPhotoV2* mRsPhoto; QPixmap mThumbNail; + PhotoDrop* mPhotoDrop; + PhotoItem* mPhotoSelected; }; diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui index 24f33b61f..52a285a90 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui @@ -6,8 +6,8 @@ 0 0 - 530 - 488 + 643 + 550 @@ -16,7 +16,7 @@ true - + 0 @@ -34,205 +34,429 @@ - - - QFrame::StyledPanel + + + 0 - - QFrame::Raised - - - - - - - - - - Album Name: - - - - - - - - - - Category: - - - - - + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + - - Animals - + + + + + Album Name: + + + + + + + + + + Category: + + + + + + + + Animals + + + + + Family + + + + + Friends + + + + + Flowers + + + + + Holiday + + + + + Landcapes + + + + + Pets + + + + + Portraits + + + + + Travel + + + + + Work + + + + + Random + + + + + - - Family - - - - - Friends - - - - - Flowers - - - - - Holiday - - - - - Landcapes - - - - - Pets - - - - - Portraits - - - - - Travel - - - - - Work - - - - - Random - - - - - - - - - - - 64 - 64 - - - - - 64 - 64 - - - - + + + + 64 + 64 + + + + + 64 + 64 + + + + border: 2px solid white; border-radius: 10px; - - - - - - - :/images/album_64.png:/images/album_64.png - - - - 64 - 64 - - - - - - - - - - Qt::Horizontal - - - - - - - - - Caption: - - - - - - - - - - Description: - - - - - - - - - - - - - Photographer: - - - - - - - - - - Where: - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Qt::Horizontal - - - - + + + + + + + :/images/album_64.png:/images/album_64.png + + + + 64 + 64 + + + + + + + + + + Qt::Horizontal + + + + + + + + + Caption: + + + + + + + + + + Description: + + + + + + + + + + + + + Photographer: + + + + + + + + + + Where: + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::Horizontal + + + + + + + + 1 + 0 + + + + Share Options + + + + + + + + Policy: + + + + + + + Quality: + + + + + + + Comments: + + + + + + + Identity: + + + + + + + + + + + + 0 + 0 + + + + + Public + + + + + Restricted + + + + + + + + + 0 + 0 + + + + + Resize Images (< 1Mb) + + + + + Resize Images (< 10Mb) + + + + + Send Original Images + + + + + + + + + 0 + 0 + + + + + No Comments Allowed + + + + + Authenticated Comments + + + + + Any Comments Allowed + + + + + + + + + 0 + 0 + + + + + Publish with Identity + + + + + + + + + + Qt::Horizontal + + + + 168 + 20 + + + + + + + + + + + + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600;"> Drag &amp; Drop to insert pictures. Click on a picture to edit details below.</span></p></body></html> + + + + + + + + 0 + 10 + + + + true + + + Qt::ScrollBarAsNeeded + + + true + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + 0 + 0 + 98 + 28 + + + + QWidget#scrollAreaWidgetContents{border: none;} + + + + + + + + + + + + + + + + 9 + + Qt::Horizontal @@ -245,167 +469,32 @@ border-radius: 10px; - - - - Publish Album - - - - + QDialogButtonBox::Cancel - - - - - 1 - 0 - + + + + Back - - Share Options + + + + + + Add Photos + + + + + + + Publish Album - - - - - - - Policy: - - - - - - - Quality: - - - - - - - Comments: - - - - - - - Identity: - - - - - - - - - - - - 0 - 0 - - - - - Public - - - - - Restricted - - - - - - - - - 0 - 0 - - - - - Resize Images (< 1Mb) - - - - - Resize Images (< 10Mb) - - - - - Send Original Images - - - - - - - - - 0 - 0 - - - - - No Comments Allowed - - - - - Authenticated Comments - - - - - Any Comments Allowed - - - - - - - - - 0 - 0 - - - - - Publish with Identity - - - - - - - - - - Qt::Horizontal - - - - 168 - 20 - - - - - @@ -420,27 +509,16 @@ border-radius: 10px;
gui/common/HeaderFrame.h
1 + + PhotoDrop + QWidget +
gui/PhotoShare/PhotoDrop.h
+ 1 +
- - - buttonBox - rejected() - AlbumCreateDialog - close() - - - 398 - 466 - - - 264 - 243 - - - - + diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp index d198db140..35d93a33c 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp @@ -5,7 +5,7 @@ #include "gxs/rsgxsflags.h" AlbumDialog::AlbumDialog(const RsPhotoAlbum& album, TokenQueue* photoQueue, RsPhotoV2* rs_Photo, QWidget *parent) : - QDialog(parent), + QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), ui(new Ui::AlbumDialog), mRsPhoto(rs_Photo), mPhotoQueue(photoQueue), mAlbum(album), mPhotoSelected(NULL) { ui->setupUi(this); @@ -35,6 +35,9 @@ void AlbumDialog::setUp() ui->lineEdit_Caption->setText(QString::fromStdString(mAlbum.mCaption)); ui->lineEdit_Category->setText(QString::fromStdString(mAlbum.mCategory)); ui->lineEdit_Identity->setText(QString::fromStdString(mAlbum.mMeta.mAuthorId)); + ui->lineEdit_Where->setText(QString::fromStdString(mAlbum.mWhere)); + ui->textEdit_description->setText(QString::fromStdString(mAlbum.mDescription)); + QPixmap qtn; qtn.loadFromData(mAlbum.mThumbnail.data, mAlbum.mThumbnail.size, mAlbum.mThumbnail.type.c_str()); diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui index da4436fd7..d3d02fe27 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui @@ -6,8 +6,8 @@ 0 0 - 649 - 436 + 725 + 427
@@ -77,6 +77,13 @@ Summary + + + + Album Title: + + + @@ -97,6 +104,19 @@ + + + + false + + + + 0 + 0 + + + + @@ -137,6 +157,13 @@ + + + + When + + + @@ -150,32 +177,45 @@ - - + + - Album Title: + Description: - - - - When + + + + true - - - - false + + + + Qt::Vertical - - - 0 - 0 - + + + 20 + 40 + - + + + + + + Qt::Vertical + + + + 20 + 40 + + + @@ -254,6 +294,19 @@ + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -299,8 +352,8 @@ p, li { white-space: pre-wrap; } 0 0 - 625 - 112 + 701 + 69 diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index b56f0b13d..8634bab52 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -6,7 +6,7 @@ #include "AddCommentDialog.h" PhotoDialog::PhotoDialog(RsPhotoV2 *rs_photo, const RsPhotoPhoto &photo, QWidget *parent) : - QDialog(parent), + QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), ui(new Ui::PhotoDialog), mRsPhoto(rs_photo), mPhotoQueue(new TokenQueue(mRsPhoto->getTokenService(), this)), mPhotoDetails(photo) { diff --git a/retroshare-gui/src/gui/PhotoShare/images/album_create_64.png b/retroshare-gui/src/gui/PhotoShare/images/album_create_64.png index a8392c0abbe16c834453b96e452097b34444e8f7..9a1fe09612911d6e92681c4de5e3fa4a14e26da6 100644 GIT binary patch literal 5201 zcmV-X6t3%uP)`kY_j6`8-=60__nvF#MIA!s zdVJ5BnX_lFZ+&a6Z|yl(NGb9Ec{8r|1g`e>2>@4n0#|$c1c0kOfvdfJ0>IUtz}4O? z>HzWd(@%R>dm>k3d-&mph1F~}bL!254?gI)jst_7P})ccbyW0yKnQWgK?hy4=GcI- zgH8JX;&+-zi(apHEZX(=ediGTc3p`~CWAwV4q58F)$8@_a6Id(y5py?*>;+H|1pc+ zi6J$u00Xzz!$4~@mundP+XT8<8lHrwdHS-fRbv)F)q&gMeM)ut?`knkQ!t4FJ2;sjs zL^4~UIpC>3`{nfk(6`C0H^P%LzOl&>{7L!Nh7;#`Wo$Cha9WWQMQpnUm;XUOC&Zq` z>QWR7F7lL(FnPZ%82H(*V|6&V_sa0l^~0tvX$ z`95z)pBY$I5coQ|$e)mZZxOiwNv;tgCEqOoW>^stBNdGUU&XA|DptgWh?Y@;TAjUh zAmUJn*c1D{KUv0{5Ucs2yETr}5QONEh*=@=9sn>*!=IcN4=>}44g=a$;UgP_fe7=0 zmi@(A@2?k;LL}6V^MIBoB67slVHE~Kk9Dmo_~9Yf)|x9aKy!3h^*kRD8I>_3I4h;* zrFb&^f=0veN~(FP|Z^=ub#gbBvb#m_ogc-<=Ce@2f3BdD^vNfCKo*W3 zJxx0Gb)pf=weC>pI6n!2KJSpSr4@>6R3P@XVTaC&W+ z%^CC@fz;?`rg66~;pt-~ah}jVGC)XyzFYSJ5WUh~$Nm!#R|Y^kXqtigTfNdTh)4Z0 zy`KSQ8r7L&Fwg!6hET#>V+h$__+1FwCI&7mX}^YuSd(}=(jdSZ=4)k7i2hXyRXzN2 zEt62aaxb76XIerZE^9SXWIzBw7^5xMJqvlG2f3vzaUywN|i`eL#s$;y75hDRVq9=d^rYa2MwM63C&_{ z5K9CRixM9k%Y;)c!8rAde{GjHcbY9ME!VJhQvoaG25#JQ4bB~zMR{o%8@EitbymsA z&|~WNsbdH5?BPE}txbnx^8L#(K&}fw;_Uv+tqUH(3Aw!%*O1q2ku{?5V zf-{tX<4RmRX5oc@`zC(lOTUkHv%iqW^`F}hkNh|y!TT4o$l1BUAuwpc!7^oRaNyy! zWkiNS7I{m(X#V*7uqrc1p$8(IuF!r`GZWnjIGfqlK3bJqhX1yR-8sjE&*C zy?5ifoAzO7Boopcs2No>tQx9D1!miV=_mjU)ao^?v{uksnn7{;Rou3jCHC68v2AP; zD~l_>Lka~8FP}MulH0-0+;Gd40MHM*F}>r%dSTWR4?W`579h{Pgd#n!RAjr=!NhPH zH|-wxDPI^a(0CW+MjLO>&Evn`I*r^Uy?f*pt_{|?)(zaBT-@pHI- z-+nlr12db2k)bp%y6_ASUV|*?G2D1g*aDeU3U}Z3XTO@}c#GJ%ra!G%s07uyRk(-N27K7os;Ud40& zl0j?d9Ik)hcGxMK=a@rCXNNQrUBeF#$xyXy6XoR!n)ND*ISZv48NzIXQLDN7T(YpE0I;!i>@bYwX;|ZO5ivUiM# zpP-_?+M?&}OcssBY1Gdh!-kP81y37u3oAJJ_8iWG1*4CV5m zGw`YH!weP4a}CVQHPFp8&}nuc4HPd!#d3gZz&2U_w0WN1_GRD>JhdT{d>uZ&A z3Dd`4#o1R5W9H1O=r|4*7s?bobu`;;WD6cPBG(mF;vW8WFm_ey-DApFp@)-aZn_EFDX<9luzT|qC2Yfg&X6W3p74A|s2`OGRc-HiUF3^df7wt_ zNF1Ge6DyfICh|kDMk%&(TVS+2ysw)nc%9p<<{Hr z!=p#>>Fc)P^AGo$6W=y9UYFQ??F@nG{CUybG?FGM_+GOCE zoM0!}MwbS6-7b?~u(!G`T(@-(Uf+5W^A_jW>0m+5A}iCdRxBJ^ei@$QvEk|>(@f#l zwmyafhYsMe`yX2;32J4qV2tAK8?VKi);p}Z4({Ev149L7=B~iv{4$eQ7u%__hBG-7 z?JV-?F>Ko+aOWKlV0`07((rlQvNwZ6&%cOQj=qN9`{L*Djjw$JGo>mz#WLnHv$*Z? zn~|Yz7-l&vaO`ZJ49aCtu!_i2SB(qw|87+?B>tFjOHl28FeE?K)i?)@O4i=ZrqqJPc)UMss z^l660JSP=MWYXVKfWjPp(dDci>8+!UsUrzn>41SHEum|`glmNV6&NvU~>WwMS2!%ywab`x&f z!`$*kD#!)cRtmOh`-?cHssc>Z>a~#y-YYrTVwLID+I|^cKL=_cQY|(QK8mO^QMg!z3h~+Woi^R+_DR^vuD`~ zpF@7Ah~K0n{?-d`;Z&Uo@InneD#mhy$+13-@!A9?i<213jUj90{AF#I)u>Bvs}k96 zwkfijRC?3_RRd0gf`?&ZsS?R5q2zb~0(bQzdE8UKP2_XzM7t$_fn{9)OzkT&2cG{b zjS2c`>J&6`5xR7k?9}R!ttyA1DwI#Tme+xEg7MdtOqdics>$i_ z8opjwQ4d%OkY&a`@7}bVae1wi>X*{<$fpVn!y-~LMM1-H2vn=pLWjvxl*o-bjZIMn z=BPy3pTq?Szv@L>9u=)C}g}ehIqF#b1n3EhoKFelH(;yS`;*Blj8FV(;g~r z1w9HT<>h*+PS!5^N>h0-?PXwdJfp+e6FgC&S2G-Gh!e=OFW`Lz!_J^1eD70F_)EA1 z)MFpw^;G5PLT0?n1E9CNwW{~RFk8Gc7#QC$YPbSDY&wJsZ5!iBWYmx`GdQ9mg_2^Wm7NMf z7zUdp-j!hXSne$LSOt1>auZwD&(2X(AXwy3wVaezy@OCQGK1w@(Idz*hr;Xx=1#qX z($EU>qgiaQCUEokUThuOO#m{;*cm?&DhBv@U&(kigaUxONl-R#I>|g?tPg-%w2ZdH z-%*Xjss~gb(zita;;Vm&H_p6)@BZxphLRV2*~dWqJj7peP*sKv&``dJ2Y>rf93MV~ z`3y_)80VSqFcL~wqDm~R6!D{Pzlf&SUxee~}eqt?nEA z?a(VdP#b7GwDtPrnL_deCpdQRUH4*iWE6Moy`%3zF;->hbUKYMKlx?MzcmkIoTCTcZDX=%27qX06}E5>xGwU#s_n!2Q@rB0ichgU-miG7>b#0!1%OQjnWDf@f~Qa@9NoWv z|AX&kT;=p!F4t6lDnRjMx*VjY_74ky4{Nh6yQlgNze=bl)=J_sPNOvnm2WJ|awaAw zmfr6@KH7gVqP~};a+~(-Kl+Z6NWPQ%fwqr60AY1jVdb&ZDaq{bd@Xw)cL0=ql(XuI zigeUpd$|7YIF7Fp-H!Y52S6n{RmRlQqmJ8Qy$^S{4Z|@%FaRIvKa)`jZ)0{NI*VWO=62g|5**^lHTN^F?Gf;~I3 zfbrZWeEu`P{?f-50Ltbk3&p|(c85-UQ2TxW6QQ+l&%W0_$UXiC(*4=F9MeVf00000 LNkvXXu0mjf5Zdlj literal 4543 zcmV;w5kT&VP)00007bV*G`2iyx5 z3mGYXZILqo000SaNLh0L08StP08StQ7JZrC00004XF*Lt006O%3;baP000qANkl%zdBtIeW9t`^>`+ z5-KZFwynAMoH^(0^{w@-Z>_!0V9q)EAP;i84fqhi?Ka>;0JqzK4*}e61K#hTPzRoV z`sv$k#(Nycjvb?>X~MUoM~?=+PY8mthB2JL*+m%R>)pTZS8EQ}J|r3(r8P6Fp7EEB zhw;e1=O?4jAmECkoIH6F&Qs6xZnq!*Z$lJiQOpl%<~D&+_!)TKdXM9cp3Gdn_Cmbo zt_@>N1aSHV-D(8FyEnEyH2xqY$>w8!_Dpm`$Rv_j3x@I7BA)$=aIxY8Q%efmNuXy~ z;DKN`jvmI7&+LNaJ{(;WJ}Yu9N#+i}#}4|zUwv*90NEIu+|MEeaIt`KIA3URWD4hC zaXNhlC^uH}697aADa2xa@R-xBvs^8Jd4)DPG`C1|{=w zO5fzdI3r>_Hv>QfU}%_{siBFDI8mLH>fysu4yEi~D~oHwohCI;(jetjdXQ>Zmd6?6 zQ$-4S#rekOZIcM_f)_*OWDy^5EMsvA%EMoD3Qj6URyh*&P4oySL@TJv8kL9n($mb0;9#UaS#E0NMd z&Y+Z7i3aB-ET#}AS^e73OKhS-2&FpBqf#DaX`FnqHl@j#_YE9n9!-RUr~E+~uM!BU zBBV~v$ig$al9THC0C<`M0#7q4Jr{8)0g$Ct&ZbN!^W01gPVFonW&`6wNMa_% z%8(ZF_YkyZ1C6ojWrDC2bY%cSKJ8>a} zlf;iZOU^gJus#ArNLDpyt+}X}k~yTLcT9Rdn2XTxka>9$WSt0(MG&uTbrZs;Qjm#k z-mc(O-ZF392mlpu=Jm9hMJR`a@}iWcXzXDkNWNza=Dg=)X=oc_L6)`Ijj3a^hA^oq z`LlBX2<1e|I@?XUxedLLARt`WFU>NrNS(Z2NFyM~z4P>MpMC<1A`1eN zcEBm+(tB~P2?f@rnv?}3YG4Z$cw+!E0I8J%#i)?(iKJwFj;1Y45YbeWz4dd59OJ~k|37q$Qk;)|zF+zE#~j;By_T(fiuA~t&kKYvR%?`I zd<-t>z-|zM2tds3Fnrl!tNg|rPe`?E>(+i!I)$#3PfzON1#Dz}!!nxzm{^T$FMxO`KF^elX zsaNZde)3Q5e&8`UXZD=N%uHu#_RSYh^&r1m3x9n2hnq%#Zv>EfJQtI!Y+*tI&*JC4 zM}3QNp`wUg+a0c#G+FQ~iXZSjb^6o)`1Tk7^bc$k7rBsSG(70XKmD7}K60pIc3a(6 zXnlY%BNHPNd+SqQKlK$9)XqNl)ZCTV&34nbVHS5-S2a;v@9}lYM1@pZaJo3mvIOIF zZ4d^=eC3CjpcwR$qMKx$g3Bjc+gc9*XnXccG)q zF?fMLW6m6V^z$o=4GOMyZ3ze$?sfw>+E-4dZJz_ZP68bSOgz=+|!7(+BY`O zflN3BA@8J;CauuR#MMv`>EP0<^6J}aS@Znh;?<_nA585Tn;5UU90v?mx7c(7omelQ z{7>$8TMLVNy}tLrgM05jSg9%SG~W-O2mJ1no5Mv2EKu@vncs*zX`NTm{5(UT{4zXm|CBQ2#a0a5|JFR}tK&C2^ zK9O8*s*=!Wi#L%`%-x*%SdE+^ow&^)03e*OIOXU@$v zSAu}4ic~F;u~F9Pb_X`^_094y^##xONJT2aDzDp^^B5<)Jff0tt5c?6v8#H>g2eE+ zz+e^CH%yA33y>|K4=jJcH=J@_{v$N6~n6|Czk|K!&1wgJbz4FmryC%1e&aBLpg4)&Q zJS}@_nNiE-9?(kLLtZeseFKD-nT|;%7d8#CLO|#c^ch$E^7^FhgcU#5m;_uNC8Fw3c>^jJuvWF|~WX zc}Xsr){=0?_zpgBgU+Bw2aQ&L-?j-B7$Vh8%f}TYOELq0qaZ+#ydH?X$J|m`H3R4M z*{dU^3LWBmwC%)VZ#5T6y4+rrHwOTD6n}a7@~L=+8r>f+0R%N)}seMA=VKYi}`FMsCCQ~U3vk@0B~r!uOOp$GTxd7EA%p8xRF zu8LmbE?!<-bzFBR7pjU@7S)nm-?1Ivf9TQS@p0RG;obwv$rpb1>Y1~@|J$Gc);GR2 z-|F3W_ugMV^owU_FPy&i%3WXFtCW-~)Cj$#mNZRMbXr!05-iEU>l!Wh?LHW7dzS5o zQs7eej-9)o_`~0`9EQ?A}*V^}I-yrfN(pj7qTwbP=y1?7mwNqyVH@z@w9UX~ zjn&!KLQ|wr9Yk1N2_#BN_>{u$piP!yczqkhdR-kzLU7Lm1IxAH`2%yQs)`@EM}lzs z0Ufx5T4izDB;NMPeF9gzeM6Q60}{>eY@Zmq>)zc93ztXhS4x%gZ;n?RtySo{W|8!^ z;n_2N&vH6Ot1*}x?vIR>$Ld;Lr5a>z;0Lbbg2LKhyJflq5A}#|^bD{Rv{e)ULWBX- zP!Kp382l7Un%;I>nbao$g!C2D@fZF;my1#;AHIVq+z$9HzSxHjrOZ1xpvV->SdIsFe@R{}NxDwT5|^MDIKUOl zat1DLVLYHz;#3m?4PluR5ix;ByD!jVAq1Vd#{=wR6=!>-8+svFAQEc(t_~iMp+(_p z89HYuw;ZZFbAl2mk&0@n2pS1QQkYyp)=tDDI${zNO2qEt{^BJRRRQas3H~#p*VCu{0KKWp;&Vkb{a0s zx*kB*HurnJkxRxV#@e4~kRV!Zfg2?bT@zqK@%EpG zRj%m^BaP{6txCHzq>j>&dxj58R`w|p)M^FtSP1v~N%*=0?f?J*6ENAf^@1RhH2`2S z9)Ef6d%fcR?R$GoA8$i_>I6I=!e| zBX#7JoHlN)&;`9+e*U{ZGnoOD!7P3Sgu-Pfv}rz4uyXY9XGBUjuf&_}Tx@E6wv&^r zh0=8p&o%%be&FGuTJ6w*L-EUj{Q1!UhJ5w-R~O$|B*Pe&5vgLWq?Prurk3W~S7}fD z^I!c7$8(bR((ya)=%u%+lt7y9-F@Hc?CKf-@s=V91N?p?5TkkM;6v~~J+;XnO8oPw ze`$7_;#LLeNK&b)s4&V}`5K?CDZ^hn`lU_(P@-H;b|s#geF{ZyB||d(=){SeyZ!%r zEU&DToRTCWq9RcWhXO-Zz!&Xq=h>5|Zsj2qKp#1B#BrSWX2kpXtIhJim!ZK15`f+V zrvZQ{!ukwW6N0YmhYugV!M)&jXiH%Bu+r(#_<8zz^C40ZdY@38gmCpj!XM#))S{G* zjEvmMLvHI|Y(e91=PzQi5$|x_;<()aBJ~C)u&~lb1HO766aXmfX`!p;J`bYd!+;jg z2|h3Ygs3L_9&!T5@uUBNO?=_j0nl5$@aHffYsb}bXW1U=*QhLrTqZtsRBsrKEur2m zKIC=+c>KY~pZvj-{S%$8>mZG{Gy}tVMRk95-)^7!D? d!CQRD{{jPr%5ps`vaSFC002ovPDHLkV1i)^$>0D0 From 744a78b14069021211239162fc270f58b0161095 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sat, 24 Nov 2012 19:49:23 +0000 Subject: [PATCH 177/222] Added cleanup code for GXS services in rsinit (services now based in GXS_phase1 folder in .retroshare/ folder disabled msg synchronisation by default through compilation #define (use GXS_ENABLE_MSG_SYNC to enable message sync) Finally removed v2 suffix from all photo components and filenames (please edit your libretroshare.pro file accordingly) git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5883 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgxsnetservice.cc | 3 + .../src/retroshare/{rsphotoV2.h => rsphoto.h} | 10 +- libretroshare/src/rsserver/rsinit.cc | 47 +- .../{rsphotov2items.cc => rsphotoitems.cc} | 2 +- .../{rsphotov2items.h => rsphotoitems.h} | 2 +- ...{p3photoserviceV2.cc => p3photoservice.cc} | 776 ++++----- .../{p3photoserviceV2.h => p3photoservice.h} | 296 ++-- .../src/gui/PhotoShare/AlbumCreateDialog.cpp | 380 ++--- .../src/gui/PhotoShare/AlbumCreateDialog.h | 101 +- .../src/gui/PhotoShare/AlbumDialog.cpp | 224 +-- .../src/gui/PhotoShare/AlbumDialog.h | 86 +- retroshare-gui/src/gui/PhotoShare/AlbumItem.h | 76 +- .../src/gui/PhotoShare/PhotoCommentItem.h | 58 +- .../src/gui/PhotoShare/PhotoDialog.cpp | 474 +++--- .../src/gui/PhotoShare/PhotoDialog.h | 124 +- retroshare-gui/src/gui/PhotoShare/PhotoItem.h | 104 +- .../src/gui/PhotoShare/PhotoShare.cpp | 1418 ++++++++--------- .../src/gui/PhotoShare/PhotoShare.h | 194 +-- .../src/gui/PhotoShare/PhotoSlideShow.cpp | 4 +- .../src/gui/PhotoShare/PhotoSlideShow.h | 2 +- 20 files changed, 2202 insertions(+), 2179 deletions(-) rename libretroshare/src/retroshare/{rsphotoV2.h => rsphoto.h} (95%) rename libretroshare/src/serialiser/{rsphotov2items.cc => rsphotoitems.cc} (99%) rename libretroshare/src/serialiser/{rsphotov2items.h => rsphotoitems.h} (99%) rename libretroshare/src/services/{p3photoserviceV2.cc => p3photoservice.cc} (78%) rename libretroshare/src/services/{p3photoserviceV2.h => p3photoservice.h} (93%) diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index b572c3336..cca02d0fc 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -86,6 +86,8 @@ void RsGxsNetService::syncWithPeers() sendItem(grp); } + +#ifdef GXS_ENABLE_SYNC_MSGS std::map grpMeta; mDataStore->retrieveGxsGrpMetaData(grpMeta); @@ -123,6 +125,7 @@ void RsGxsNetService::syncWithPeers() sendItem(msg); } } +#endif } bool RsGxsNetService::loadList(std::list& load) diff --git a/libretroshare/src/retroshare/rsphotoV2.h b/libretroshare/src/retroshare/rsphoto.h similarity index 95% rename from libretroshare/src/retroshare/rsphotoV2.h rename to libretroshare/src/retroshare/rsphoto.h index 55880ee4a..7d3c1ae09 100644 --- a/libretroshare/src/retroshare/rsphotoV2.h +++ b/libretroshare/src/retroshare/rsphoto.h @@ -32,8 +32,8 @@ #include "rsgxsservice.h" /* The Main Interface Class - for information about your Peers */ -class RsPhotoV2; -extern RsPhotoV2 *rsPhotoV2; +class RsPhoto; +extern RsPhoto *rsPhoto; /******************* NEW STUFF FOR NEW CACHE SYSTEM *********/ @@ -176,7 +176,7 @@ typedef std::map > PhotoResult; typedef std::map > PhotoCommentResult; typedef std::map > PhotoRelatedCommentResult; -class RsPhotoV2 +class RsPhoto { public: @@ -186,9 +186,9 @@ public: static const uint32_t FLAG_MSG_TYPE_MASK; - RsPhotoV2() { return; } + RsPhoto() { return; } - virtual ~RsPhotoV2() { return; } + virtual ~RsPhoto() { return; } /*! * Use to enquire if groups or msgs have changed diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index ee455565f..eb353f7a7 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1827,7 +1827,7 @@ RsTurtle *rsTurtle = NULL ; #include "services/p3idservice.h" #include "services/p3wiki.h" #include "services/p3posted.h" -#include "services/p3photoserviceV2.h" +#include "services/p3photoservice.h" #include "services/p3gxsforums.h" // Not too many to convert now! @@ -2278,9 +2278,28 @@ int RsServer::StartupRetroShare() mPluginsManager->registerCacheServices() ; - #ifdef ENABLE_GXS_SERVICES + // The idea is that if priorGxsDir is non + // empty and matches an exist directory location + // the given ssl user id then this directory is cleaned + // and deleted + std::string priorGxsDir = "./" + mLinkMgr->getOwnId() + "/", currGxsDir = RsInitConfig::configDir + "/GXS_phase1"; + bool cleanUpGxsDir = false; + + if(!priorGxsDir.empty()) + cleanUpGxsDir = RsDirUtil::checkDirectory(priorGxsDir); + + std::list filesToKeep; + bool cleanUpSuccess = RsDirUtil::cleanupDirectory(priorGxsDir, filesToKeep); + + if(!cleanUpSuccess) + std::cerr << "RsInit::StartupRetroShare() Clean up of Old Gxs Dir Failed!"; + else + rmdir(priorGxsDir.c_str()); + + RsDirUtil::checkCreateDirectory(currGxsDir); + // Testing New Cache Services. //p3WikiServiceVEG *mWikis = new p3WikiServiceVEG(RS_SERVICE_GXSV1_TYPE_WIKI); //pqih -> addService(mWikis); @@ -2295,7 +2314,7 @@ int RsServer::StartupRetroShare() // TODO: temporary to store GXS service data, remove - RsDirUtil::checkCreateDirectory(mLinkMgr->getOwnId()); + RsDirUtil::checkCreateDirectory(currGxsDir); RsNxsNetMgr* nxsMgr = new RsNxsNetMgrImpl(mLinkMgr); @@ -2303,7 +2322,7 @@ int RsServer::StartupRetroShare() p3IdService *mGxsIdService = NULL; - RsGeneralDataService* gxsid_ds = new RsDataService("./" + mLinkMgr->getOwnId() + "/", "gxsid_db", + RsGeneralDataService* gxsid_ds = new RsDataService(currGxsDir + "/", "gxsid_db", RS_SERVICE_GXSV1_TYPE_GXSID, NULL); gxsid_ds->resetDataStore(); @@ -2338,27 +2357,27 @@ int RsServer::StartupRetroShare() RsGenExchange::setAuthenPolicyFlag(flag, photoAuthenPolicy, RsGenExchange::GRP_OPTION_BITS); - p3PhotoServiceV2 *mPhotoV2 = NULL; + p3PhotoService *mPhoto = NULL; - RsGeneralDataService* photo_ds = new RsDataService("./" + mLinkMgr->getOwnId() + "/", "photoV2_db", + RsGeneralDataService* photo_ds = new RsDataService(currGxsDir + "/", "photoV2_db", RS_SERVICE_GXSV1_TYPE_PHOTO, NULL); photo_ds->resetDataStore(); //TODO: remove, new service data per RS session, for testing // init gxs services - mPhotoV2 = new p3PhotoServiceV2(photo_ds, NULL, mGxsIdService, photoAuthenPolicy); + mPhoto = new p3PhotoService(photo_ds, NULL, mGxsIdService, photoAuthenPolicy); // create GXS photo service RsGxsNetService* photo_ns = new RsGxsNetService( - RS_SERVICE_GXSV1_TYPE_PHOTO, photo_ds, nxsMgr, mPhotoV2); + RS_SERVICE_GXSV1_TYPE_PHOTO, photo_ds, nxsMgr, mPhoto); /**** Posted GXS service ****/ p3Posted *mPosted = NULL; - RsGeneralDataService* posted_ds = new RsDataService("./" + mLinkMgr->getOwnId()+ "/", "posted_db", + RsGeneralDataService* posted_ds = new RsDataService(currGxsDir + "/", "posted_db", RS_SERVICE_GXSV1_TYPE_POSTED); posted_ds->resetDataStore(); //TODO: remove, new service data per RS session, for testing @@ -2374,7 +2393,7 @@ int RsServer::StartupRetroShare() p3Wiki *mWiki = NULL; - RsGeneralDataService* wiki_ds = new RsDataService("./" + mLinkMgr->getOwnId()+ "/", "wiki_db", + RsGeneralDataService* wiki_ds = new RsDataService(currGxsDir + "/", "wiki_db", RS_SERVICE_GXSV1_TYPE_WIKI); wiki_ds->resetDataStore(); //TODO: remove, new service data per RS session, for testing @@ -2389,7 +2408,7 @@ int RsServer::StartupRetroShare() p3GxsForums *mGxsForums = NULL; - RsGeneralDataService* gxsforums_ds = new RsDataService("./" + mLinkMgr->getOwnId()+ "/", "gxsforums_db", + RsGeneralDataService* gxsforums_ds = new RsDataService(currGxsDir + "/", "gxsforums_db", RS_SERVICE_GXSV1_TYPE_FORUMS); gxsforums_ds->resetDataStore(); //TODO: remove, new service data per RS session, for testing @@ -2411,12 +2430,12 @@ int RsServer::StartupRetroShare() //mGxsCore->addService(mGxsIdService); #if ENABLE_OTHER_GXS_SERVICES createThread(*mGxsIdService); - createThread(*mPhotoV2); + createThread(*mPhoto); createThread(*mPosted); createThread(*mWiki); createThread(*mGxsForums); // -// mGxsCore->addService(mPhotoV2); +// mGxsCore->addService(mPhoto); // mGxsCore->addService(mPosted); // mGxsCore->addService(mWiki); #endif @@ -2707,7 +2726,7 @@ int RsServer::StartupRetroShare() #if ENABLE_OTHER_GXS_SERVICES rsWiki = mWiki; rsPosted = mPosted; - rsPhotoV2 = mPhotoV2; + rsPhoto = mPhoto; rsGxsForums = mGxsForums; #endif diff --git a/libretroshare/src/serialiser/rsphotov2items.cc b/libretroshare/src/serialiser/rsphotoitems.cc similarity index 99% rename from libretroshare/src/serialiser/rsphotov2items.cc rename to libretroshare/src/serialiser/rsphotoitems.cc index ea09415ff..7d08c6373 100644 --- a/libretroshare/src/serialiser/rsphotov2items.cc +++ b/libretroshare/src/serialiser/rsphotoitems.cc @@ -25,7 +25,7 @@ #include -#include "rsphotov2items.h" +#include "rsphotoitems.h" #include "serialiser/rstlvbase.h" #include "serialiser/rsbaseserial.h" diff --git a/libretroshare/src/serialiser/rsphotov2items.h b/libretroshare/src/serialiser/rsphotoitems.h similarity index 99% rename from libretroshare/src/serialiser/rsphotov2items.h rename to libretroshare/src/serialiser/rsphotoitems.h index 54cb76a07..f03135340 100644 --- a/libretroshare/src/serialiser/rsphotov2items.h +++ b/libretroshare/src/serialiser/rsphotoitems.h @@ -33,7 +33,7 @@ #include "serialiser/rstlvtypes.h" #include "rsgxsitems.h" -#include "retroshare/rsphotoV2.h" +#include "retroshare/rsphoto.h" const uint8_t RS_PKT_SUBTYPE_PHOTO_ITEM = 0x02; const uint8_t RS_PKT_SUBTYPE_PHOTO_SHOW_ITEM = 0x03; diff --git a/libretroshare/src/services/p3photoserviceV2.cc b/libretroshare/src/services/p3photoservice.cc similarity index 78% rename from libretroshare/src/services/p3photoserviceV2.cc rename to libretroshare/src/services/p3photoservice.cc index ab5d48727..e704f6e66 100644 --- a/libretroshare/src/services/p3photoserviceV2.cc +++ b/libretroshare/src/services/p3photoservice.cc @@ -1,388 +1,388 @@ -#include "p3photoserviceV2.h" -#include "serialiser/rsphotov2items.h" -#include "gxs/rsgxsflags.h" - -RsPhotoV2 *rsPhotoV2 = NULL; - - -const uint32_t RsPhotoV2::FLAG_MSG_TYPE_MASK = 0x000f; -const uint32_t RsPhotoV2::FLAG_MSG_TYPE_PHOTO_POST = 0x0001; -const uint32_t RsPhotoV2::FLAG_MSG_TYPE_PHOTO_COMMENT = 0x0002; - - - - -bool RsPhotoThumbnail::copyFrom(const RsPhotoThumbnail &nail) -{ - if (data) - { - deleteImage(); - } - - if ((!nail.data) || (nail.size == 0)) - { - return false; - } - - size = nail.size; - type = nail.type; - data = (uint8_t *) malloc(size); - memcpy(data, nail.data, size); - - return true; -} - -bool RsPhotoThumbnail::deleteImage() -{ - if (data) - { - free(data); - data = NULL; - size = 0; - type.clear(); - } - return true; -} - - -RsPhotoPhoto::RsPhotoPhoto() - :mSetFlags(0), mOrder(0), mMode(0), mModFlags(0) -{ - return; -} - -RsPhotoAlbum::RsPhotoAlbum() - :mMode(0), mSetFlags(0), mModFlags(0) -{ - return; -} - -RsPhotoComment::RsPhotoComment() - : mComment(""), mCommentFlag(0) { - -} - -RsPhotoComment::RsPhotoComment(const RsGxsPhotoCommentItem &comment) - : mComment(""), mCommentFlag(0) { - - *this = comment.comment; - (*this).mMeta = comment.meta; - -} -std::ostream &operator<<(std::ostream &out, const RsPhotoPhoto &photo) -{ - out << "RsPhotoPhoto [ "; - out << "Title: " << photo.mMeta.mMsgName; - out << "]"; - return out; -} - - -std::ostream &operator<<(std::ostream &out, const RsPhotoAlbum &album) -{ - out << "RsPhotoAlbum [ "; - out << "Title: " << album.mMeta.mGroupName; - out << "]"; - return out; -} - -p3PhotoServiceV2::p3PhotoServiceV2(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs, - uint32_t authenPolicy) - : RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_GXSV1_TYPE_PHOTO, gixs, authenPolicy), - mPhotoMutex(std::string("Photo Mutex")) -{ - - // create dummy grps - - RsGxsPhotoAlbumItem* item1 = new RsGxsPhotoAlbumItem(), *item2 = new RsGxsPhotoAlbumItem(); - - item1->meta.mGroupName = "Dummy Album 1"; - item1->meta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_RESTRICTED; - item1->album.mCaption = "Dummy 1"; - item2->meta.mGroupName = "Dummy Album 2"; - item2->meta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_RESTRICTED; - item2->album.mCaption = "Dummy 2"; - - createDummyGroup(item1); - createDummyGroup(item2); -} - -bool p3PhotoServiceV2::updated() -{ - RsStackMutex stack(mPhotoMutex); - - bool changed = (!mGroupChange.empty() || !mMsgChange.empty()); - - return changed; -} - -void p3PhotoServiceV2::service_tick() -{ - -} - - - -void p3PhotoServiceV2::groupsChanged(std::list& grpIds) -{ - RsStackMutex stack(mPhotoMutex); - - while(!mGroupChange.empty()) - { - RsGxsGroupChange* gc = mGroupChange.back(); - std::list& gList = gc->grpIdList; - std::list::iterator lit = gList.begin(); - for(; lit != gList.end(); lit++) - grpIds.push_back(*lit); - - mGroupChange.pop_back(); - delete gc; - } -} - - -void p3PhotoServiceV2::msgsChanged( - std::map >& msgs) -{ - RsStackMutex stack(mPhotoMutex); - - while(!mMsgChange.empty()) - { - RsGxsMsgChange* mc = mMsgChange.back(); - msgs = mc->msgChangeMap; - mMsgChange.pop_back(); - delete mc; - } -} - - -RsTokenService* p3PhotoServiceV2::getTokenService() { - - return RsGenExchange::getTokenService(); -} - - -bool p3PhotoServiceV2::getGroupList(const uint32_t& token, - std::list& groupIds) -{ - return RsGenExchange::getGroupList(token, groupIds); -} - - -bool p3PhotoServiceV2::getMsgList(const uint32_t& token, - GxsMsgIdResult& msgIds) -{ - - return RsGenExchange::getMsgList(token, msgIds); -} - - -bool p3PhotoServiceV2::getGroupSummary(const uint32_t& token, - std::list& groupInfo) -{ - return RsGenExchange::getGroupMeta(token, groupInfo); -} - - -bool p3PhotoServiceV2::getMsgSummary(const uint32_t& token, - MsgMetaResult& msgInfo) -{ - return RsGenExchange::getMsgMeta(token, msgInfo); -} - - -bool p3PhotoServiceV2::getAlbum(const uint32_t& token, std::vector& albums) -{ - std::vector grpData; - bool ok = RsGenExchange::getGroupData(token, grpData); - - if(ok) - { - std::vector::iterator vit = grpData.begin(); - - for(; vit != grpData.end(); vit++) - { - RsGxsPhotoAlbumItem* item = dynamic_cast(*vit); - RsPhotoAlbum album = item->album; - item->album.mMeta = item->meta; - album.mMeta = item->album.mMeta; - delete item; - albums.push_back(album); - } - } - - return ok; -} - - -bool p3PhotoServiceV2::getPhoto(const uint32_t& token, PhotoResult& photos) -{ - GxsMsgDataMap msgData; - bool ok = RsGenExchange::getMsgData(token, msgData); - - if(ok) - { - GxsMsgDataMap::iterator mit = msgData.begin(); - - for(; mit != msgData.end(); mit++) - { - RsGxsGroupId grpId = mit->first; - std::vector& msgItems = mit->second; - std::vector::iterator vit = msgItems.begin(); - - for(; vit != msgItems.end(); vit++) - { - RsGxsPhotoPhotoItem* item = dynamic_cast(*vit); - - if(item) - { - RsPhotoPhoto photo = item->photo; - photo.mMeta = item->meta; - photos[grpId].push_back(photo); - delete item; - }else - { - std::cerr << "Not a photo Item, deleting!" << std::endl; - delete *vit; - } - } - } - } - - return ok; -} - -bool p3PhotoServiceV2::getPhotoComment(const uint32_t &token, PhotoCommentResult &comments) -{ - GxsMsgDataMap msgData; - bool ok = RsGenExchange::getMsgData(token, msgData); - - if(ok) - { - GxsMsgDataMap::iterator mit = msgData.begin(); - - for(; mit != msgData.end(); mit++) - { - RsGxsGroupId grpId = mit->first; - std::vector& msgItems = mit->second; - std::vector::iterator vit = msgItems.begin(); - - for(; vit != msgItems.end(); vit++) - { - RsGxsPhotoCommentItem* item = dynamic_cast(*vit); - - if(item) - { - RsPhotoComment comment = item->comment; - comment.mMeta = item->meta; - comments[grpId].push_back(comment); - delete item; - }else - { - std::cerr << "Not a comment Item, deleting!" << std::endl; - delete *vit; - } - } - } - } - - return ok; -} - -RsPhotoComment& RsPhotoComment::operator=(const RsGxsPhotoCommentItem& comment) -{ - *this = comment.comment; - return *this; -} - -bool p3PhotoServiceV2::getPhotoRelatedComment(const uint32_t &token, PhotoRelatedCommentResult &comments) -{ - - return RsGenExchange::getMsgRelatedDataT(token, comments); - -} - -bool p3PhotoServiceV2::submitAlbumDetails(uint32_t& token, RsPhotoAlbum& album) -{ - RsGxsPhotoAlbumItem* albumItem = new RsGxsPhotoAlbumItem(); - albumItem->album = album; - albumItem->meta = album.mMeta; - RsGenExchange::publishGroup(token, albumItem); - return true; -} - - - -void p3PhotoServiceV2::notifyChanges(std::vector& changes) -{ - - RsStackMutex stack(mPhotoMutex); - - std::vector::iterator vit = changes.begin(); - - for(; vit != changes.end(); vit++) - { - RsGxsNotify* n = *vit; - RsGxsGroupChange* gc; - RsGxsMsgChange* mc; - if((mc = dynamic_cast(n)) != NULL) - { - mMsgChange.push_back(mc); - } - else if((gc = dynamic_cast(n)) != NULL) - { - mGroupChange.push_back(gc); - } - else - { - delete n; - } - } -} - -bool p3PhotoServiceV2::submitPhoto(uint32_t& token, RsPhotoPhoto& photo) -{ - RsGxsPhotoPhotoItem* photoItem = new RsGxsPhotoPhotoItem(); - photoItem->photo = photo; - photoItem->meta = photo.mMeta; - photoItem->meta.mMsgFlags = FLAG_MSG_TYPE_PHOTO_POST; - - RsGenExchange::publishMsg(token, photoItem); - return true; -} - -bool p3PhotoServiceV2::submitComment(uint32_t &token, RsPhotoComment &comment) -{ - RsGxsPhotoCommentItem* commentItem = new RsGxsPhotoCommentItem(); - commentItem->comment = comment; - commentItem->meta = comment.mMeta; - commentItem->meta.mMsgFlags = FLAG_MSG_TYPE_PHOTO_COMMENT; - - RsGenExchange::publishMsg(token, commentItem); - return true; -} - -bool p3PhotoServiceV2::acknowledgeMsg(const uint32_t& token, - std::pair& msgId) -{ - return RsGenExchange::acknowledgeTokenMsg(token, msgId); -} - - -bool p3PhotoServiceV2::acknowledgeGrp(const uint32_t& token, - RsGxsGroupId& grpId) -{ - return RsGenExchange::acknowledgeTokenGrp(token, grpId); -} - -bool p3PhotoServiceV2::subscribeToAlbum(uint32_t &token, const RsGxsGroupId &grpId, bool subscribe) -{ - if(subscribe) - RsGenExchange::setGroupSubscribeFlags(token, grpId, GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED, GXS_SERV::GROUP_SUBSCRIBE_MASK); - else - RsGenExchange::setGroupSubscribeFlags(token, grpId, 0, GXS_SERV::GROUP_SUBSCRIBE_MASK); - - return true; -} - - +#include "p3photoservice.h" +#include "serialiser/rsphotoitems.h" +#include "gxs/rsgxsflags.h" + +RsPhoto *rsPhoto = NULL; + + +const uint32_t RsPhoto::FLAG_MSG_TYPE_MASK = 0x000f; +const uint32_t RsPhoto::FLAG_MSG_TYPE_PHOTO_POST = 0x0001; +const uint32_t RsPhoto::FLAG_MSG_TYPE_PHOTO_COMMENT = 0x0002; + + + + +bool RsPhotoThumbnail::copyFrom(const RsPhotoThumbnail &nail) +{ + if (data) + { + deleteImage(); + } + + if ((!nail.data) || (nail.size == 0)) + { + return false; + } + + size = nail.size; + type = nail.type; + data = (uint8_t *) malloc(size); + memcpy(data, nail.data, size); + + return true; +} + +bool RsPhotoThumbnail::deleteImage() +{ + if (data) + { + free(data); + data = NULL; + size = 0; + type.clear(); + } + return true; +} + + +RsPhotoPhoto::RsPhotoPhoto() + :mSetFlags(0), mOrder(0), mMode(0), mModFlags(0) +{ + return; +} + +RsPhotoAlbum::RsPhotoAlbum() + :mMode(0), mSetFlags(0), mModFlags(0) +{ + return; +} + +RsPhotoComment::RsPhotoComment() + : mComment(""), mCommentFlag(0) { + +} + +RsPhotoComment::RsPhotoComment(const RsGxsPhotoCommentItem &comment) + : mComment(""), mCommentFlag(0) { + + *this = comment.comment; + (*this).mMeta = comment.meta; + +} +std::ostream &operator<<(std::ostream &out, const RsPhotoPhoto &photo) +{ + out << "RsPhotoPhoto [ "; + out << "Title: " << photo.mMeta.mMsgName; + out << "]"; + return out; +} + + +std::ostream &operator<<(std::ostream &out, const RsPhotoAlbum &album) +{ + out << "RsPhotoAlbum [ "; + out << "Title: " << album.mMeta.mGroupName; + out << "]"; + return out; +} + +p3PhotoService::p3PhotoService(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs, + uint32_t authenPolicy) + : RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_GXSV1_TYPE_PHOTO, gixs, authenPolicy), + mPhotoMutex(std::string("Photo Mutex")) +{ + + // create dummy grps + + RsGxsPhotoAlbumItem* item1 = new RsGxsPhotoAlbumItem(), *item2 = new RsGxsPhotoAlbumItem(); + + item1->meta.mGroupName = "Dummy Album 1"; + item1->meta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_RESTRICTED; + item1->album.mCaption = "Dummy 1"; + item2->meta.mGroupName = "Dummy Album 2"; + item2->meta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_RESTRICTED; + item2->album.mCaption = "Dummy 2"; + + createDummyGroup(item1); + createDummyGroup(item2); +} + +bool p3PhotoService::updated() +{ + RsStackMutex stack(mPhotoMutex); + + bool changed = (!mGroupChange.empty() || !mMsgChange.empty()); + + return changed; +} + +void p3PhotoService::service_tick() +{ + +} + + + +void p3PhotoService::groupsChanged(std::list& grpIds) +{ + RsStackMutex stack(mPhotoMutex); + + while(!mGroupChange.empty()) + { + RsGxsGroupChange* gc = mGroupChange.back(); + std::list& gList = gc->grpIdList; + std::list::iterator lit = gList.begin(); + for(; lit != gList.end(); lit++) + grpIds.push_back(*lit); + + mGroupChange.pop_back(); + delete gc; + } +} + + +void p3PhotoService::msgsChanged( + std::map >& msgs) +{ + RsStackMutex stack(mPhotoMutex); + + while(!mMsgChange.empty()) + { + RsGxsMsgChange* mc = mMsgChange.back(); + msgs = mc->msgChangeMap; + mMsgChange.pop_back(); + delete mc; + } +} + + +RsTokenService* p3PhotoService::getTokenService() { + + return RsGenExchange::getTokenService(); +} + + +bool p3PhotoService::getGroupList(const uint32_t& token, + std::list& groupIds) +{ + return RsGenExchange::getGroupList(token, groupIds); +} + + +bool p3PhotoService::getMsgList(const uint32_t& token, + GxsMsgIdResult& msgIds) +{ + + return RsGenExchange::getMsgList(token, msgIds); +} + + +bool p3PhotoService::getGroupSummary(const uint32_t& token, + std::list& groupInfo) +{ + return RsGenExchange::getGroupMeta(token, groupInfo); +} + + +bool p3PhotoService::getMsgSummary(const uint32_t& token, + MsgMetaResult& msgInfo) +{ + return RsGenExchange::getMsgMeta(token, msgInfo); +} + + +bool p3PhotoService::getAlbum(const uint32_t& token, std::vector& albums) +{ + std::vector grpData; + bool ok = RsGenExchange::getGroupData(token, grpData); + + if(ok) + { + std::vector::iterator vit = grpData.begin(); + + for(; vit != grpData.end(); vit++) + { + RsGxsPhotoAlbumItem* item = dynamic_cast(*vit); + RsPhotoAlbum album = item->album; + item->album.mMeta = item->meta; + album.mMeta = item->album.mMeta; + delete item; + albums.push_back(album); + } + } + + return ok; +} + + +bool p3PhotoService::getPhoto(const uint32_t& token, PhotoResult& photos) +{ + GxsMsgDataMap msgData; + bool ok = RsGenExchange::getMsgData(token, msgData); + + if(ok) + { + GxsMsgDataMap::iterator mit = msgData.begin(); + + for(; mit != msgData.end(); mit++) + { + RsGxsGroupId grpId = mit->first; + std::vector& msgItems = mit->second; + std::vector::iterator vit = msgItems.begin(); + + for(; vit != msgItems.end(); vit++) + { + RsGxsPhotoPhotoItem* item = dynamic_cast(*vit); + + if(item) + { + RsPhotoPhoto photo = item->photo; + photo.mMeta = item->meta; + photos[grpId].push_back(photo); + delete item; + }else + { + std::cerr << "Not a photo Item, deleting!" << std::endl; + delete *vit; + } + } + } + } + + return ok; +} + +bool p3PhotoService::getPhotoComment(const uint32_t &token, PhotoCommentResult &comments) +{ + GxsMsgDataMap msgData; + bool ok = RsGenExchange::getMsgData(token, msgData); + + if(ok) + { + GxsMsgDataMap::iterator mit = msgData.begin(); + + for(; mit != msgData.end(); mit++) + { + RsGxsGroupId grpId = mit->first; + std::vector& msgItems = mit->second; + std::vector::iterator vit = msgItems.begin(); + + for(; vit != msgItems.end(); vit++) + { + RsGxsPhotoCommentItem* item = dynamic_cast(*vit); + + if(item) + { + RsPhotoComment comment = item->comment; + comment.mMeta = item->meta; + comments[grpId].push_back(comment); + delete item; + }else + { + std::cerr << "Not a comment Item, deleting!" << std::endl; + delete *vit; + } + } + } + } + + return ok; +} + +RsPhotoComment& RsPhotoComment::operator=(const RsGxsPhotoCommentItem& comment) +{ + *this = comment.comment; + return *this; +} + +bool p3PhotoService::getPhotoRelatedComment(const uint32_t &token, PhotoRelatedCommentResult &comments) +{ + + return RsGenExchange::getMsgRelatedDataT(token, comments); + +} + +bool p3PhotoService::submitAlbumDetails(uint32_t& token, RsPhotoAlbum& album) +{ + RsGxsPhotoAlbumItem* albumItem = new RsGxsPhotoAlbumItem(); + albumItem->album = album; + albumItem->meta = album.mMeta; + RsGenExchange::publishGroup(token, albumItem); + return true; +} + + + +void p3PhotoService::notifyChanges(std::vector& changes) +{ + + RsStackMutex stack(mPhotoMutex); + + std::vector::iterator vit = changes.begin(); + + for(; vit != changes.end(); vit++) + { + RsGxsNotify* n = *vit; + RsGxsGroupChange* gc; + RsGxsMsgChange* mc; + if((mc = dynamic_cast(n)) != NULL) + { + mMsgChange.push_back(mc); + } + else if((gc = dynamic_cast(n)) != NULL) + { + mGroupChange.push_back(gc); + } + else + { + delete n; + } + } +} + +bool p3PhotoService::submitPhoto(uint32_t& token, RsPhotoPhoto& photo) +{ + RsGxsPhotoPhotoItem* photoItem = new RsGxsPhotoPhotoItem(); + photoItem->photo = photo; + photoItem->meta = photo.mMeta; + photoItem->meta.mMsgFlags = FLAG_MSG_TYPE_PHOTO_POST; + + RsGenExchange::publishMsg(token, photoItem); + return true; +} + +bool p3PhotoService::submitComment(uint32_t &token, RsPhotoComment &comment) +{ + RsGxsPhotoCommentItem* commentItem = new RsGxsPhotoCommentItem(); + commentItem->comment = comment; + commentItem->meta = comment.mMeta; + commentItem->meta.mMsgFlags = FLAG_MSG_TYPE_PHOTO_COMMENT; + + RsGenExchange::publishMsg(token, commentItem); + return true; +} + +bool p3PhotoService::acknowledgeMsg(const uint32_t& token, + std::pair& msgId) +{ + return RsGenExchange::acknowledgeTokenMsg(token, msgId); +} + + +bool p3PhotoService::acknowledgeGrp(const uint32_t& token, + RsGxsGroupId& grpId) +{ + return RsGenExchange::acknowledgeTokenGrp(token, grpId); +} + +bool p3PhotoService::subscribeToAlbum(uint32_t &token, const RsGxsGroupId &grpId, bool subscribe) +{ + if(subscribe) + RsGenExchange::setGroupSubscribeFlags(token, grpId, GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED, GXS_SERV::GROUP_SUBSCRIBE_MASK); + else + RsGenExchange::setGroupSubscribeFlags(token, grpId, 0, GXS_SERV::GROUP_SUBSCRIBE_MASK); + + return true; +} + + diff --git a/libretroshare/src/services/p3photoserviceV2.h b/libretroshare/src/services/p3photoservice.h similarity index 93% rename from libretroshare/src/services/p3photoserviceV2.h rename to libretroshare/src/services/p3photoservice.h index dc2ce80cb..728fc7402 100644 --- a/libretroshare/src/services/p3photoserviceV2.h +++ b/libretroshare/src/services/p3photoservice.h @@ -1,148 +1,148 @@ -#ifndef P3PHOTOSERVICEV2_H -#define P3PHOTOSERVICEV2_H - -/* - * libretroshare/src/retroshare: rsphoto.h - * - * RetroShare C++ Interface. - * - * Copyright 2008-2012 by Robert Fernie, Christopher Evi-Parker - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "gxs/rsgenexchange.h" -#include "retroshare/rsphotoV2.h" - -class p3PhotoServiceV2 : public RsPhotoV2, public RsGenExchange -{ -public: - - p3PhotoServiceV2(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs, - uint32_t authenPolicy); - -public: - - /*! - * @return true if a change has occured - */ - bool updated(); - - /*! - * - */ - void service_tick(); - -protected: - - void notifyChanges(std::vector& changes); -public: - - /** Requests **/ - - void groupsChanged(std::list& grpIds); - - - void msgsChanged(std::map >& msgs); - - RsTokenService* getTokenService(); - - bool getGroupList(const uint32_t &token, - std::list &groupIds); - bool getMsgList(const uint32_t &token, - GxsMsgIdResult& msgIds); - - /* Generic Summary */ - bool getGroupSummary(const uint32_t &token, - std::list &groupInfo); - - bool getMsgSummary(const uint32_t &token, - MsgMetaResult &msgInfo); - - /* Specific Service Data */ - bool getAlbum(const uint32_t &token, std::vector &albums); - bool getPhoto(const uint32_t &token, PhotoResult &photos); - bool getPhotoComment(const uint32_t &token, PhotoCommentResult &comments); - bool getPhotoRelatedComment(const uint32_t &token, PhotoRelatedCommentResult &comments); - -public: - - /** Modifications **/ - - /*! - * submits album, which returns a token that needs - * to be acknowledge to get album grp id - * @param token token to redeem for acknowledgement - * @param album album to be submitted - */ - bool submitAlbumDetails(uint32_t& token, RsPhotoAlbum &album); - - /*! - * submits photo, which returns a token that needs - * to be acknowledge to get photo msg-grp id pair - * @param token token to redeem for acknowledgement - * @param photo photo to be submitted - */ - bool submitPhoto(uint32_t& token, RsPhotoPhoto &photo); - - /*! - * submits photo comment, which returns a token that needs - * to be acknowledged to get photo msg-grp id pair - * The mParentId needs to be set to an existing msg for which - * commenting is enabled - * @param token token to redeem for acknowledgement - * @param comment comment to be submitted - */ - bool submitComment(uint32_t& token, RsPhotoComment &photo); - - /*! - * subscribes to group, and returns token which can be used - * to be acknowledged to get group Id - * @param token token to redeem for acknowledgement - * @param grpId the id of the group to subscribe to - */ - bool subscribeToAlbum(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe); - - /*! - * This allows the client service to acknowledge that their msgs has - * been created/modified and retrieve the create/modified msg ids - * @param token the token related to modification/create request - * @param msgIds map of grpid->msgIds of message created/modified - * @return true if token exists false otherwise - */ - bool acknowledgeMsg(const uint32_t& token, std::pair& msgId); - - /*! - * This allows the client service to acknowledge that their grps has - * been created/modified and retrieve the create/modified grp ids - * @param token the token related to modification/create request - * @param msgIds vector of ids of groups created/modified - * @return true if token exists false otherwise - */ - bool acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId); - -private: - - std::vector mGroupChange; - std::vector mMsgChange; - - RsMutex mPhotoMutex; -}; - -#endif // P3PHOTOSERVICEV2_H +#ifndef P3PHOTOSERVICEV2_H +#define P3PHOTOSERVICEV2_H + +/* + * libretroshare/src/retroshare: rsphoto.h + * + * RetroShare C++ Interface. + * + * Copyright 2008-2012 by Robert Fernie, Christopher Evi-Parker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "gxs/rsgenexchange.h" +#include "retroshare/rsphoto.h" + +class p3PhotoService : public RsPhoto, public RsGenExchange +{ +public: + + p3PhotoService(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs, + uint32_t authenPolicy); + +public: + + /*! + * @return true if a change has occured + */ + bool updated(); + + /*! + * + */ + void service_tick(); + +protected: + + void notifyChanges(std::vector& changes); +public: + + /** Requests **/ + + void groupsChanged(std::list& grpIds); + + + void msgsChanged(std::map >& msgs); + + RsTokenService* getTokenService(); + + bool getGroupList(const uint32_t &token, + std::list &groupIds); + bool getMsgList(const uint32_t &token, + GxsMsgIdResult& msgIds); + + /* Generic Summary */ + bool getGroupSummary(const uint32_t &token, + std::list &groupInfo); + + bool getMsgSummary(const uint32_t &token, + MsgMetaResult &msgInfo); + + /* Specific Service Data */ + bool getAlbum(const uint32_t &token, std::vector &albums); + bool getPhoto(const uint32_t &token, PhotoResult &photos); + bool getPhotoComment(const uint32_t &token, PhotoCommentResult &comments); + bool getPhotoRelatedComment(const uint32_t &token, PhotoRelatedCommentResult &comments); + +public: + + /** Modifications **/ + + /*! + * submits album, which returns a token that needs + * to be acknowledge to get album grp id + * @param token token to redeem for acknowledgement + * @param album album to be submitted + */ + bool submitAlbumDetails(uint32_t& token, RsPhotoAlbum &album); + + /*! + * submits photo, which returns a token that needs + * to be acknowledge to get photo msg-grp id pair + * @param token token to redeem for acknowledgement + * @param photo photo to be submitted + */ + bool submitPhoto(uint32_t& token, RsPhotoPhoto &photo); + + /*! + * submits photo comment, which returns a token that needs + * to be acknowledged to get photo msg-grp id pair + * The mParentId needs to be set to an existing msg for which + * commenting is enabled + * @param token token to redeem for acknowledgement + * @param comment comment to be submitted + */ + bool submitComment(uint32_t& token, RsPhotoComment &photo); + + /*! + * subscribes to group, and returns token which can be used + * to be acknowledged to get group Id + * @param token token to redeem for acknowledgement + * @param grpId the id of the group to subscribe to + */ + bool subscribeToAlbum(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe); + + /*! + * This allows the client service to acknowledge that their msgs has + * been created/modified and retrieve the create/modified msg ids + * @param token the token related to modification/create request + * @param msgIds map of grpid->msgIds of message created/modified + * @return true if token exists false otherwise + */ + bool acknowledgeMsg(const uint32_t& token, std::pair& msgId); + + /*! + * This allows the client service to acknowledge that their grps has + * been created/modified and retrieve the create/modified grp ids + * @param token the token related to modification/create request + * @param msgIds vector of ids of groups created/modified + * @return true if token exists false otherwise + */ + bool acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId); + +private: + + std::vector mGroupChange; + std::vector mMsgChange; + + RsMutex mPhotoMutex; +}; + +#endif // P3PHOTOSERVICEV2_H diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp index a923cafdf..746f748ac 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.cpp @@ -1,190 +1,190 @@ -#include - -#include "AlbumCreateDialog.h" -#include "ui_AlbumCreateDialog.h" - -#include "util/misc.h" -#include "gxs/rsgxsflags.h" - -AlbumCreateDialog::AlbumCreateDialog(TokenQueue *photoQueue, RsPhotoV2 *rs_photo, QWidget *parent): - QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), - ui(new Ui::AlbumCreateDialog), mPhotoQueue(photoQueue), mRsPhoto(rs_photo), mPhotoSelected(NULL) -{ - ui->setupUi(this); - - ui->headerFrame->setHeaderImage(QPixmap(":/images/album_create_64.png")); - ui->headerFrame->setHeaderText(tr("Create Album")); - - -#if QT_VERSION >= 0x040700 - ui->lineEdit_Title_2->setPlaceholderText(tr("Untitle Album")); - ui->lineEdit_Caption_2->setPlaceholderText(tr("Say something about this album...")); - //ui->textEdit_Description->setPlaceholderText(tr("Say something about this album...")) ; - ui->lineEdit_Where->setPlaceholderText(tr("Where were this taken?")); -#endif - - ui->backButton->hide(); - - connect(ui->publishButton, SIGNAL(clicked()), this, SLOT(publishAlbum())); - connect(ui->AlbumThumbNail, SIGNAL(clicked()), this, SLOT(addAlbumThumbnail())); - - connect(ui->addphotosButton, SIGNAL(clicked()),this, SLOT(changePage())); - connect(ui->backButton, SIGNAL(clicked()),this, SLOT(backPage())); - - - mPhotoDrop = ui->scrollAreaWidgetContents; - mPhotoDrop->setPhotoItemHolder(this); - - -} - -AlbumCreateDialog::~AlbumCreateDialog() -{ - delete ui; -} - -#define PUBLIC_INDEX 0 -#define RESTRICTED_INDEX 1 -#define PRIVATE_INDEX 2 - -void AlbumCreateDialog::publishAlbum() -{ - // get fields for album to publish, publish and then exit dialog - RsPhotoAlbum album; - - album.mCaption = ui->lineEdit_Caption_2->text().toStdString(); - album.mPhotographer = ui->lineEdit_Photographer->text().toStdString(); - album.mMeta.mGroupName = ui->lineEdit_Title_2->text().toStdString(); - album.mDescription = ui->textEdit_Description->toPlainText().toStdString(); - album.mWhere = ui->lineEdit_Where->text().toStdString(); - album.mPhotographer = ui->lineEdit_Photographer->text().toStdString(); - getAlbumThumbnail(album.mThumbnail); - - - int currIndex = ui->privacyComboBox->currentIndex(); - - switch(currIndex) - { - case PUBLIC_INDEX: - album.mMeta.mGroupFlags |= GXS_SERV::FLAG_PRIVACY_PUBLIC; - break; - case RESTRICTED_INDEX: - album.mMeta.mGroupFlags |= GXS_SERV::FLAG_PRIVACY_RESTRICTED; - break; - case PRIVATE_INDEX: - album.mMeta.mGroupFlags |= GXS_SERV::FLAG_PRIVACY_PRIVATE; - break; - } - - uint32_t token; - mRsPhoto->submitAlbumDetails(token, album); - mPhotoQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, 0); - - publishPhotos(); - - close(); -} - -void AlbumCreateDialog::publishPhotos() -{ - // get fields for album to publish, publish and then exit dialog - RsPhotoAlbum album; - - QSet photos; - - mPhotoDrop->getPhotos(photos); - - QSetIterator sit(photos); - - while(sit.hasNext()) - { - PhotoItem* item = sit.next(); - uint32_t token; - RsPhotoPhoto photo = item->getPhotoDetails(); - photo.mMeta.mGroupId = album.mMeta.mGroupId; - mRsPhoto->submitPhoto(token, photo); - mPhotoQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); - } - -} - -bool AlbumCreateDialog::getAlbumThumbnail(RsPhotoThumbnail &nail) -{ - const QPixmap *tmppix = &mThumbNail; - - QByteArray ba; - QBuffer buffer(&ba); - - if(!tmppix->isNull()) - { - // send chan image - - buffer.open(QIODevice::WriteOnly); - tmppix->save(&buffer, "PNG"); // writes image into ba in PNG format - - RsPhotoThumbnail tmpnail; - tmpnail.data = (uint8_t *) ba.data(); - tmpnail.size = ba.size(); - - nail.copyFrom(tmpnail); - - return true; - } - - nail.data = NULL; - nail.size = 0; - return false; -} - -void AlbumCreateDialog::addAlbumThumbnail() -{ - QPixmap img = misc::getOpenThumbnailedPicture(this, tr("Load Album Thumbnail"), 128, 128); - - if (img.isNull()) - return; - - mThumbNail = img; - - // to show the selected - ui->AlbumThumbNail->setIcon(mThumbNail); -} - -void AlbumCreateDialog::changePage() -{ - int nextPage = ui->stackedWidget->currentIndex() + 1; - if (nextPage >= ui->stackedWidget->count()) - nextPage = 0; - ui->stackedWidget->setCurrentIndex(nextPage); - - ui->backButton->show(); - ui->addphotosButton->hide(); -} - -void AlbumCreateDialog::backPage() -{ - int nextPage = ui->stackedWidget->currentIndex() - 1; - if (nextPage >= ui->stackedWidget->count()) - nextPage = 0; - ui->stackedWidget->setCurrentIndex(nextPage); - - ui->backButton->hide(); - ui->addphotosButton->show(); -} - -void AlbumCreateDialog::notifySelection(PhotoShareItem *selection) -{ - - PhotoItem* pItem = dynamic_cast(selection); - - if(mPhotoSelected == NULL) - { - return; - } - else - { - mPhotoSelected->setSelected(false); - mPhotoSelected = pItem; - } - - mPhotoSelected->setSelected(true); -} +#include + +#include "AlbumCreateDialog.h" +#include "ui_AlbumCreateDialog.h" + +#include "util/misc.h" +#include "gxs/rsgxsflags.h" + +AlbumCreateDialog::AlbumCreateDialog(TokenQueue *photoQueue, RsPhoto *rs_photo, QWidget *parent): + QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), + ui(new Ui::AlbumCreateDialog), mPhotoQueue(photoQueue), mRsPhoto(rs_photo), mPhotoSelected(NULL) +{ + ui->setupUi(this); + + ui->headerFrame->setHeaderImage(QPixmap(":/images/album_create_64.png")); + ui->headerFrame->setHeaderText(tr("Create Album")); + + +#if QT_VERSION >= 0x040700 + ui->lineEdit_Title_2->setPlaceholderText(tr("Untitle Album")); + ui->lineEdit_Caption_2->setPlaceholderText(tr("Say something about this album...")); + //ui->textEdit_Description->setPlaceholderText(tr("Say something about this album...")) ; + ui->lineEdit_Where->setPlaceholderText(tr("Where were this taken?")); +#endif + + ui->backButton->hide(); + + connect(ui->publishButton, SIGNAL(clicked()), this, SLOT(publishAlbum())); + connect(ui->AlbumThumbNail, SIGNAL(clicked()), this, SLOT(addAlbumThumbnail())); + + connect(ui->addphotosButton, SIGNAL(clicked()),this, SLOT(changePage())); + connect(ui->backButton, SIGNAL(clicked()),this, SLOT(backPage())); + + + mPhotoDrop = ui->scrollAreaWidgetContents; + mPhotoDrop->setPhotoItemHolder(this); + + +} + +AlbumCreateDialog::~AlbumCreateDialog() +{ + delete ui; +} + +#define PUBLIC_INDEX 0 +#define RESTRICTED_INDEX 1 +#define PRIVATE_INDEX 2 + +void AlbumCreateDialog::publishAlbum() +{ + // get fields for album to publish, publish and then exit dialog + RsPhotoAlbum album; + + album.mCaption = ui->lineEdit_Caption_2->text().toStdString(); + album.mPhotographer = ui->lineEdit_Photographer->text().toStdString(); + album.mMeta.mGroupName = ui->lineEdit_Title_2->text().toStdString(); + album.mDescription = ui->textEdit_Description->toPlainText().toStdString(); + album.mWhere = ui->lineEdit_Where->text().toStdString(); + album.mPhotographer = ui->lineEdit_Photographer->text().toStdString(); + getAlbumThumbnail(album.mThumbnail); + + + int currIndex = ui->privacyComboBox->currentIndex(); + + switch(currIndex) + { + case PUBLIC_INDEX: + album.mMeta.mGroupFlags |= GXS_SERV::FLAG_PRIVACY_PUBLIC; + break; + case RESTRICTED_INDEX: + album.mMeta.mGroupFlags |= GXS_SERV::FLAG_PRIVACY_RESTRICTED; + break; + case PRIVATE_INDEX: + album.mMeta.mGroupFlags |= GXS_SERV::FLAG_PRIVACY_PRIVATE; + break; + } + + uint32_t token; + mRsPhoto->submitAlbumDetails(token, album); + mPhotoQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, 0); + + publishPhotos(); + + close(); +} + +void AlbumCreateDialog::publishPhotos() +{ + // get fields for album to publish, publish and then exit dialog + RsPhotoAlbum album; + + QSet photos; + + mPhotoDrop->getPhotos(photos); + + QSetIterator sit(photos); + + while(sit.hasNext()) + { + PhotoItem* item = sit.next(); + uint32_t token; + RsPhotoPhoto photo = item->getPhotoDetails(); + photo.mMeta.mGroupId = album.mMeta.mGroupId; + mRsPhoto->submitPhoto(token, photo); + mPhotoQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); + } + +} + +bool AlbumCreateDialog::getAlbumThumbnail(RsPhotoThumbnail &nail) +{ + const QPixmap *tmppix = &mThumbNail; + + QByteArray ba; + QBuffer buffer(&ba); + + if(!tmppix->isNull()) + { + // send chan image + + buffer.open(QIODevice::WriteOnly); + tmppix->save(&buffer, "PNG"); // writes image into ba in PNG format + + RsPhotoThumbnail tmpnail; + tmpnail.data = (uint8_t *) ba.data(); + tmpnail.size = ba.size(); + + nail.copyFrom(tmpnail); + + return true; + } + + nail.data = NULL; + nail.size = 0; + return false; +} + +void AlbumCreateDialog::addAlbumThumbnail() +{ + QPixmap img = misc::getOpenThumbnailedPicture(this, tr("Load Album Thumbnail"), 128, 128); + + if (img.isNull()) + return; + + mThumbNail = img; + + // to show the selected + ui->AlbumThumbNail->setIcon(mThumbNail); +} + +void AlbumCreateDialog::changePage() +{ + int nextPage = ui->stackedWidget->currentIndex() + 1; + if (nextPage >= ui->stackedWidget->count()) + nextPage = 0; + ui->stackedWidget->setCurrentIndex(nextPage); + + ui->backButton->show(); + ui->addphotosButton->hide(); +} + +void AlbumCreateDialog::backPage() +{ + int nextPage = ui->stackedWidget->currentIndex() - 1; + if (nextPage >= ui->stackedWidget->count()) + nextPage = 0; + ui->stackedWidget->setCurrentIndex(nextPage); + + ui->backButton->hide(); + ui->addphotosButton->show(); +} + +void AlbumCreateDialog::notifySelection(PhotoShareItem *selection) +{ + + PhotoItem* pItem = dynamic_cast(selection); + + if(mPhotoSelected == NULL) + { + return; + } + else + { + mPhotoSelected->setSelected(false); + mPhotoSelected = pItem; + } + + mPhotoSelected->setSelected(true); +} diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.h b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.h index 1e40da671..79af02c2d 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.h @@ -1,50 +1,51 @@ -#ifndef ALBUMCREATEDIALOG_H -#define ALBUMCREATEDIALOG_H - -#include -#include "util/TokenQueue.h" -#include "retroshare/rsphotoV2.h" -#include "PhotoShareItemHolder.h" -#include "PhotoItem.h" -#include "PhotoDrop.h" - -namespace Ui { - class AlbumCreateDialog; -} - - -class AlbumCreateDialog : public QDialog, public PhotoShareItemHolder -{ - Q_OBJECT - -public: - explicit AlbumCreateDialog(TokenQueue* photoQueue, RsPhotoV2* rs_photo, QWidget *parent = 0); - ~AlbumCreateDialog(); - - void notifySelection(PhotoShareItem* selection); - - -private slots: - void publishAlbum(); - void publishPhotos(); - void addAlbumThumbnail(); - void changePage(); - void backPage(); - - -private: - - bool getAlbumThumbnail(RsPhotoThumbnail &nail); -private: - Ui::AlbumCreateDialog *ui; - - TokenQueue* mPhotoQueue; - RsPhotoV2* mRsPhoto; - QPixmap mThumbNail; - PhotoDrop* mPhotoDrop; - PhotoItem* mPhotoSelected; -}; - - - -#endif // ALBUMCREATEDIALOG_H +#ifndef ALBUMCREATEDIALOG_H +#define ALBUMCREATEDIALOG_H + +#include +#include "util/TokenQueue.h" +#include "retroshare/rsphoto.h" +#include "retroshare/rsphoto.h" +#include "PhotoShareItemHolder.h" +#include "PhotoItem.h" +#include "PhotoDrop.h" + +namespace Ui { + class AlbumCreateDialog; +} + + +class AlbumCreateDialog : public QDialog, public PhotoShareItemHolder +{ + Q_OBJECT + +public: + explicit AlbumCreateDialog(TokenQueue* photoQueue, RsPhoto* rs_photo, QWidget *parent = 0); + ~AlbumCreateDialog(); + + void notifySelection(PhotoShareItem* selection); + + +private slots: + void publishAlbum(); + void publishPhotos(); + void addAlbumThumbnail(); + void changePage(); + void backPage(); + + +private: + + bool getAlbumThumbnail(RsPhotoThumbnail &nail); +private: + Ui::AlbumCreateDialog *ui; + + TokenQueue* mPhotoQueue; + RsPhoto* mRsPhoto; + QPixmap mThumbNail; + PhotoDrop* mPhotoDrop; + PhotoItem* mPhotoSelected; +}; + + + +#endif // ALBUMCREATEDIALOG_H diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp index 35d93a33c..7d20fffeb 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp @@ -1,112 +1,112 @@ -#include - -#include "AlbumDialog.h" -#include "ui_AlbumDialog.h" -#include "gxs/rsgxsflags.h" - -AlbumDialog::AlbumDialog(const RsPhotoAlbum& album, TokenQueue* photoQueue, RsPhotoV2* rs_Photo, QWidget *parent) : - QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), - ui(new Ui::AlbumDialog), mRsPhoto(rs_Photo), mPhotoQueue(photoQueue), mAlbum(album), mPhotoSelected(NULL) -{ - ui->setupUi(this); - - ui->headerFrame->setHeaderImage(QPixmap(":/images/kview_64.png")); - ui->headerFrame->setHeaderText(tr("Album")); - - connect(ui->pushButton_PublishPhotos, SIGNAL(clicked()), this, SLOT(updateAlbumPhotos())); - connect(ui->pushButton_DeletePhoto, SIGNAL(clicked()), this, SLOT(deletePhoto())); - - mPhotoDrop = ui->scrollAreaWidgetContents; - - if(!(mAlbum.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)) - { - ui->scrollAreaPhotos->setEnabled(false); - ui->pushButton_DeletePhoto->setEnabled(false); - } - mPhotoDrop->setPhotoItemHolder(this); - - setUp(); -} - - -void AlbumDialog::setUp() -{ - ui->lineEdit_Title->setText(QString::fromStdString(mAlbum.mMeta.mGroupName)); - ui->lineEdit_Caption->setText(QString::fromStdString(mAlbum.mCaption)); - ui->lineEdit_Category->setText(QString::fromStdString(mAlbum.mCategory)); - ui->lineEdit_Identity->setText(QString::fromStdString(mAlbum.mMeta.mAuthorId)); - ui->lineEdit_Where->setText(QString::fromStdString(mAlbum.mWhere)); - ui->textEdit_description->setText(QString::fromStdString(mAlbum.mDescription)); - - - QPixmap qtn; - qtn.loadFromData(mAlbum.mThumbnail.data, mAlbum.mThumbnail.size, mAlbum.mThumbnail.type.c_str()); - - if(mAlbum.mThumbnail.size != 0) - { - ui->label_thumbNail->setPixmap(qtn); - } - else - { - // display a default Album icon when album has no Thumbnail - ui->label_thumbNail->setPixmap(QPixmap(":/images/album_default_128.png")); - } -} - -void AlbumDialog::updateAlbumPhotos(){ - - QSet photos; - - mPhotoDrop->getPhotos(photos); - - QSetIterator sit(photos); - - while(sit.hasNext()) - { - PhotoItem* item = sit.next(); - uint32_t token; - RsPhotoPhoto photo = item->getPhotoDetails(); - photo.mMeta.mGroupId = mAlbum.mMeta.mGroupId; - mRsPhoto->submitPhoto(token, photo); - mPhotoQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); - } - close(); -} - -void AlbumDialog::deletePhoto(){ - - if(mPhotoSelected) - { - mPhotoSelected->setSelected(false); - mPhotoDrop->deletePhoto(mPhotoSelected); - } - -} - -void AlbumDialog::editPhoto() -{ - -} - -AlbumDialog::~AlbumDialog() -{ - delete ui; -} - -void AlbumDialog::notifySelection(PhotoShareItem *selection) -{ - - PhotoItem* pItem = dynamic_cast(selection); - - if(mPhotoSelected == NULL) - { - return; - } - else - { - mPhotoSelected->setSelected(false); - mPhotoSelected = pItem; - } - - mPhotoSelected->setSelected(true); -} +#include + +#include "AlbumDialog.h" +#include "ui_AlbumDialog.h" +#include "gxs/rsgxsflags.h" + +AlbumDialog::AlbumDialog(const RsPhotoAlbum& album, TokenQueue* photoQueue, RsPhoto* rs_Photo, QWidget *parent) : + QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), + ui(new Ui::AlbumDialog), mRsPhoto(rs_Photo), mPhotoQueue(photoQueue), mAlbum(album), mPhotoSelected(NULL) +{ + ui->setupUi(this); + + ui->headerFrame->setHeaderImage(QPixmap(":/images/kview_64.png")); + ui->headerFrame->setHeaderText(tr("Album")); + + connect(ui->pushButton_PublishPhotos, SIGNAL(clicked()), this, SLOT(updateAlbumPhotos())); + connect(ui->pushButton_DeletePhoto, SIGNAL(clicked()), this, SLOT(deletePhoto())); + + mPhotoDrop = ui->scrollAreaWidgetContents; + + if(!(mAlbum.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)) + { + ui->scrollAreaPhotos->setEnabled(false); + ui->pushButton_DeletePhoto->setEnabled(false); + } + mPhotoDrop->setPhotoItemHolder(this); + + setUp(); +} + + +void AlbumDialog::setUp() +{ + ui->lineEdit_Title->setText(QString::fromStdString(mAlbum.mMeta.mGroupName)); + ui->lineEdit_Caption->setText(QString::fromStdString(mAlbum.mCaption)); + ui->lineEdit_Category->setText(QString::fromStdString(mAlbum.mCategory)); + ui->lineEdit_Identity->setText(QString::fromStdString(mAlbum.mMeta.mAuthorId)); + ui->lineEdit_Where->setText(QString::fromStdString(mAlbum.mWhere)); + ui->textEdit_description->setText(QString::fromStdString(mAlbum.mDescription)); + + + QPixmap qtn; + qtn.loadFromData(mAlbum.mThumbnail.data, mAlbum.mThumbnail.size, mAlbum.mThumbnail.type.c_str()); + + if(mAlbum.mThumbnail.size != 0) + { + ui->label_thumbNail->setPixmap(qtn); + } + else + { + // display a default Album icon when album has no Thumbnail + ui->label_thumbNail->setPixmap(QPixmap(":/images/album_default_128.png")); + } +} + +void AlbumDialog::updateAlbumPhotos(){ + + QSet photos; + + mPhotoDrop->getPhotos(photos); + + QSetIterator sit(photos); + + while(sit.hasNext()) + { + PhotoItem* item = sit.next(); + uint32_t token; + RsPhotoPhoto photo = item->getPhotoDetails(); + photo.mMeta.mGroupId = mAlbum.mMeta.mGroupId; + mRsPhoto->submitPhoto(token, photo); + mPhotoQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); + } + close(); +} + +void AlbumDialog::deletePhoto(){ + + if(mPhotoSelected) + { + mPhotoSelected->setSelected(false); + mPhotoDrop->deletePhoto(mPhotoSelected); + } + +} + +void AlbumDialog::editPhoto() +{ + +} + +AlbumDialog::~AlbumDialog() +{ + delete ui; +} + +void AlbumDialog::notifySelection(PhotoShareItem *selection) +{ + + PhotoItem* pItem = dynamic_cast(selection); + + if(mPhotoSelected == NULL) + { + return; + } + else + { + mPhotoSelected->setSelected(false); + mPhotoSelected = pItem; + } + + mPhotoSelected->setSelected(true); +} diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h index 8ee8b0405..a33ea2ded 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.h @@ -1,43 +1,43 @@ -#ifndef ALBUMDIALOG_H -#define ALBUMDIALOG_H - -#include -#include "retroshare/rsphotoV2.h" -#include "util/TokenQueue.h" -#include "PhotoShareItemHolder.h" -#include "PhotoItem.h" -#include "PhotoDrop.h" - -namespace Ui { - class AlbumDialog; -} - -class AlbumDialog : public QDialog, public PhotoShareItemHolder -{ - Q_OBJECT - -public: - explicit AlbumDialog(const RsPhotoAlbum& album, TokenQueue* photoQueue, RsPhotoV2* rs_Photo, QWidget *parent = 0); - ~AlbumDialog(); - - void notifySelection(PhotoShareItem* selection); - -private: - - void setUp(); - -private slots: - - void updateAlbumPhotos(); - void deletePhoto(); - void editPhoto(); -private: - Ui::AlbumDialog *ui; - RsPhotoV2* mRsPhoto; - TokenQueue* mPhotoQueue; - RsPhotoAlbum mAlbum; - PhotoDrop* mPhotoDrop; - PhotoItem* mPhotoSelected; -}; - -#endif // ALBUMDIALOG_H +#ifndef ALBUMDIALOG_H +#define ALBUMDIALOG_H + +#include +#include "retroshare/rsphoto.h" +#include "util/TokenQueue.h" +#include "PhotoShareItemHolder.h" +#include "PhotoItem.h" +#include "PhotoDrop.h" + +namespace Ui { + class AlbumDialog; +} + +class AlbumDialog : public QDialog, public PhotoShareItemHolder +{ + Q_OBJECT + +public: + explicit AlbumDialog(const RsPhotoAlbum& album, TokenQueue* photoQueue, RsPhoto* rs_Photo, QWidget *parent = 0); + ~AlbumDialog(); + + void notifySelection(PhotoShareItem* selection); + +private: + + void setUp(); + +private slots: + + void updateAlbumPhotos(); + void deletePhoto(); + void editPhoto(); +private: + Ui::AlbumDialog *ui; + RsPhoto* mRsPhoto; + TokenQueue* mPhotoQueue; + RsPhotoAlbum mAlbum; + PhotoDrop* mPhotoDrop; + PhotoItem* mPhotoSelected; +}; + +#endif // ALBUMDIALOG_H diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumItem.h b/retroshare-gui/src/gui/PhotoShare/AlbumItem.h index 5cabfba17..b7e7cd0ce 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumItem.h +++ b/retroshare-gui/src/gui/PhotoShare/AlbumItem.h @@ -1,38 +1,38 @@ -#ifndef ALBUMITEM_H -#define ALBUMITEM_H - -#include -#include "string.h" -#include "retroshare/rsphotoV2.h" -#include "PhotoShareItemHolder.h" - -namespace Ui { - class AlbumItem; -} - -class AlbumItem : public QWidget, public PhotoShareItem -{ - Q_OBJECT - -public: - explicit AlbumItem(const RsPhotoAlbum& album, PhotoShareItemHolder* albumHolder, QWidget *parent = 0); - virtual ~AlbumItem(); - - const RsPhotoAlbum& getAlbum(); - - bool isSelected() { return mSelected ;} - void setSelected(bool selected); - -protected: - void mousePressEvent(QMouseEvent *event); - -private: - void setUp(); -private: - Ui::AlbumItem *ui; - RsPhotoAlbum mAlbum; - PhotoShareItemHolder* mAlbumHolder; - bool mSelected; -}; - -#endif // ALBUMITEM_H +#ifndef ALBUMITEM_H +#define ALBUMITEM_H + +#include +#include "string.h" +#include "retroshare/rsphoto.h" +#include "PhotoShareItemHolder.h" + +namespace Ui { + class AlbumItem; +} + +class AlbumItem : public QWidget, public PhotoShareItem +{ + Q_OBJECT + +public: + explicit AlbumItem(const RsPhotoAlbum& album, PhotoShareItemHolder* albumHolder, QWidget *parent = 0); + virtual ~AlbumItem(); + + const RsPhotoAlbum& getAlbum(); + + bool isSelected() { return mSelected ;} + void setSelected(bool selected); + +protected: + void mousePressEvent(QMouseEvent *event); + +private: + void setUp(); +private: + Ui::AlbumItem *ui; + RsPhotoAlbum mAlbum; + PhotoShareItemHolder* mAlbumHolder; + bool mSelected; +}; + +#endif // ALBUMITEM_H diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.h b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.h index 4f414839c..85fd2887d 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoCommentItem.h @@ -1,29 +1,29 @@ -#ifndef PHOTOCOMMENTITEM_H -#define PHOTOCOMMENTITEM_H - -#include -#include "retroshare/rsphotoV2.h" - -namespace Ui { - class PhotoCommentItem; -} - -class PhotoCommentItem : public QWidget -{ - Q_OBJECT - -public: - explicit PhotoCommentItem(const RsPhotoComment& comment, QWidget *parent = 0); - ~PhotoCommentItem(); - - const RsPhotoComment& getComment(); - -private: - - void setUp(); -private: - Ui::PhotoCommentItem *ui; - RsPhotoComment mComment; -}; - -#endif // PHOTOCOMMENTITEM_H +#ifndef PHOTOCOMMENTITEM_H +#define PHOTOCOMMENTITEM_H + +#include +#include "retroshare/rsphoto.h" + +namespace Ui { + class PhotoCommentItem; +} + +class PhotoCommentItem : public QWidget +{ + Q_OBJECT + +public: + explicit PhotoCommentItem(const RsPhotoComment& comment, QWidget *parent = 0); + ~PhotoCommentItem(); + + const RsPhotoComment& getComment(); + +private: + + void setUp(); +private: + Ui::PhotoCommentItem *ui; + RsPhotoComment mComment; +}; + +#endif // PHOTOCOMMENTITEM_H diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index 8634bab52..fbec92ef5 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -1,237 +1,237 @@ -#include -#include -#include "PhotoDialog.h" -#include "ui_PhotoDialog.h" -#include "retroshare/rsidentity.h" -#include "AddCommentDialog.h" - -PhotoDialog::PhotoDialog(RsPhotoV2 *rs_photo, const RsPhotoPhoto &photo, QWidget *parent) : - QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), - ui(new Ui::PhotoDialog), mRsPhoto(rs_photo), mPhotoQueue(new TokenQueue(mRsPhoto->getTokenService(), this)), - mPhotoDetails(photo) -{ - ui->setupUi(this); - setAttribute ( Qt::WA_DeleteOnClose, true ); - - connect(ui->pushButton_AddComment, SIGNAL(clicked()), this, SLOT(createComment())); - connect(ui->pushButton_AddCommentDlg, SIGNAL(clicked()), this, SLOT(addComment())); - connect(ui->fullscreenButton, SIGNAL(clicked()),this, SLOT(setFullScreen())); - -#if QT_VERSION >= 0x040700 - ui->lineEdit->setPlaceholderText(tr("Write a comment...")) ; -#endif - - setUp(); -} - -PhotoDialog::~PhotoDialog() -{ - delete ui; - delete mPhotoQueue; -} - -void PhotoDialog::setUp() -{ - QPixmap qtn; - qtn.loadFromData(mPhotoDetails.mThumbnail.data, mPhotoDetails.mThumbnail.size, mPhotoDetails.mThumbnail.type.c_str()); - ui->label_Photo->setPixmap(qtn); - ui->lineEdit_Title->setText(QString::fromStdString(mPhotoDetails.mMeta.mMsgName)); - - requestComments(); -} - -void PhotoDialog::addComment() -{ - AddCommentDialog dlg(this); - if (dlg.exec() == QDialog::Accepted) { - RsPhotoComment comment; - comment.mComment = dlg.getComment().toUtf8().constData(); - - uint32_t token; - comment.mMeta.mGroupId = mPhotoDetails.mMeta.mGroupId; - comment.mMeta.mParentId = mPhotoDetails.mMeta.mOrigMsgId; - mRsPhoto->submitComment(token, comment); - mPhotoQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); - } -} - -void PhotoDialog::clearComments() -{ - //QLayout* l = ui->scrollAreaWidgetContents->layout(); - QSetIterator sit(mComments); - while(sit.hasNext()) - { - PhotoCommentItem* item = sit.next(); - ui->verticalLayout->removeWidget(item); - item->setParent(NULL); - delete item; - } - - mComments.clear(); -} - -void PhotoDialog::resetComments() -{ - QSetIterator sit(mComments); - //QLayout* l = ui->scrollAreaWidgetContents->layout(); - while(sit.hasNext()) - { - PhotoCommentItem* item = sit.next(); - ui->verticalLayout->insertWidget(0,item); - } -} - -void PhotoDialog::requestComments() -{ - RsTokReqOptions opts; - opts.mMsgFlagMask = RsPhotoV2::FLAG_MSG_TYPE_MASK; - opts.mMsgFlagFilter = RsPhotoV2::FLAG_MSG_TYPE_PHOTO_COMMENT; - - opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; - opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; - opts.mOptions = RS_TOKREQOPT_MSG_PARENT | RS_TOKREQOPT_MSG_LATEST; - RsGxsGrpMsgIdPair msgId; - uint32_t token; - msgId.first = mPhotoDetails.mMeta.mGroupId; - msgId.second = mPhotoDetails.mMeta.mMsgId; - std::vector msgIdV; - msgIdV.push_back(msgId); - mPhotoQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIdV, 0); -} - -void PhotoDialog::createComment() -{ - RsPhotoComment comment; - QString commentString = ui->lineEdit->text(); - - comment.mComment = commentString.toUtf8().constData(); - - uint32_t token; - comment.mMeta.mGroupId = mPhotoDetails.mMeta.mGroupId; - comment.mMeta.mParentId = mPhotoDetails.mMeta.mOrigMsgId; - mRsPhoto->submitComment(token, comment); - mPhotoQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); - - ui->lineEdit->clear(); -} - - -/*************** message loading **********************/ - -void PhotoDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) -{ - std::cerr << "PhotoShare::loadRequest()"; - std::cerr << std::endl; - - if (queue == mPhotoQueue) - { - /* now switch on req */ - switch(req.mType) - { - case TOKENREQ_MSGINFO: - { - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_DATA: - loadComment(req.mToken); - break; - case RS_TOKREQ_ANSTYPE_LIST: - loadList(req.mToken); - break; - case RS_TOKREQ_ANSTYPE_ACK: - acknowledgeComment(req.mToken); - break; - default: - std::cerr << "PhotoShare::loadRequest() ERROR: MSG INVALID TYPE"; - std::cerr << std::endl; - break; - } - break; - } - - default: - { - std::cerr << "PhotoShare::loadRequest() ERROR: INVALID TYPE"; - std::cerr << std::endl; - break; - } - } - } - -} - -void PhotoDialog::loadComment(uint32_t token) -{ - - clearComments(); - - PhotoRelatedCommentResult results; - mRsPhoto->getPhotoRelatedComment(token, results); - - PhotoRelatedCommentResult::iterator mit = results.begin(); - - for(; mit != results.end(); mit++) - { - const std::vector& commentV = mit->second; - std::vector::const_iterator vit = commentV.begin(); - - for(; vit != commentV.end(); vit++) - { - addComment(*vit); - } - } - - resetComments(); -} - -void PhotoDialog::loadList(uint32_t token) -{ - GxsMsgReq msgIds; - mRsPhoto->getMsgList(token, msgIds); - RsTokReqOptions opts; - - // just use data as no need to worry about getting comments - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - uint32_t reqToken; - mPhotoQueue->requestMsgInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, 0); -} - -void PhotoDialog::addComment(const RsPhotoComment &comment) -{ - PhotoCommentItem* item = new PhotoCommentItem(comment); - mComments.insert(item); -} - -void PhotoDialog::acknowledgeComment(uint32_t token) -{ - RsGxsGrpMsgIdPair msgId; - mRsPhoto->acknowledgeMsg(token, msgId); - - if(msgId.first.empty() || msgId.second.empty()){ - - }else - { - requestComments(); - } -} - -void PhotoDialog::setFullScreen() -{ - if (!isFullScreen()) { - // hide menu & toolbars - -#ifdef Q_WS_X11 - show(); - raise(); - setWindowState( windowState() | Qt::WindowFullScreen ); -#else - setWindowState( windowState() | Qt::WindowFullScreen ); - show(); - raise(); -#endif - } else { - - setWindowState( windowState() ^ Qt::WindowFullScreen ); - show(); - } -} +#include +#include +#include "PhotoDialog.h" +#include "ui_PhotoDialog.h" +#include "retroshare/rsidentity.h" +#include "AddCommentDialog.h" + +PhotoDialog::PhotoDialog(RsPhoto *rs_photo, const RsPhotoPhoto &photo, QWidget *parent) : + QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), + ui(new Ui::PhotoDialog), mRsPhoto(rs_photo), mPhotoQueue(new TokenQueue(mRsPhoto->getTokenService(), this)), + mPhotoDetails(photo) +{ + ui->setupUi(this); + setAttribute ( Qt::WA_DeleteOnClose, true ); + + connect(ui->pushButton_AddComment, SIGNAL(clicked()), this, SLOT(createComment())); + connect(ui->pushButton_AddCommentDlg, SIGNAL(clicked()), this, SLOT(addComment())); + connect(ui->fullscreenButton, SIGNAL(clicked()),this, SLOT(setFullScreen())); + +#if QT_VERSION >= 0x040700 + ui->lineEdit->setPlaceholderText(tr("Write a comment...")) ; +#endif + + setUp(); +} + +PhotoDialog::~PhotoDialog() +{ + delete ui; + delete mPhotoQueue; +} + +void PhotoDialog::setUp() +{ + QPixmap qtn; + qtn.loadFromData(mPhotoDetails.mThumbnail.data, mPhotoDetails.mThumbnail.size, mPhotoDetails.mThumbnail.type.c_str()); + ui->label_Photo->setPixmap(qtn); + ui->lineEdit_Title->setText(QString::fromStdString(mPhotoDetails.mMeta.mMsgName)); + + requestComments(); +} + +void PhotoDialog::addComment() +{ + AddCommentDialog dlg(this); + if (dlg.exec() == QDialog::Accepted) { + RsPhotoComment comment; + comment.mComment = dlg.getComment().toUtf8().constData(); + + uint32_t token; + comment.mMeta.mGroupId = mPhotoDetails.mMeta.mGroupId; + comment.mMeta.mParentId = mPhotoDetails.mMeta.mOrigMsgId; + mRsPhoto->submitComment(token, comment); + mPhotoQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); + } +} + +void PhotoDialog::clearComments() +{ + //QLayout* l = ui->scrollAreaWidgetContents->layout(); + QSetIterator sit(mComments); + while(sit.hasNext()) + { + PhotoCommentItem* item = sit.next(); + ui->verticalLayout->removeWidget(item); + item->setParent(NULL); + delete item; + } + + mComments.clear(); +} + +void PhotoDialog::resetComments() +{ + QSetIterator sit(mComments); + //QLayout* l = ui->scrollAreaWidgetContents->layout(); + while(sit.hasNext()) + { + PhotoCommentItem* item = sit.next(); + ui->verticalLayout->insertWidget(0,item); + } +} + +void PhotoDialog::requestComments() +{ + RsTokReqOptions opts; + opts.mMsgFlagMask = RsPhoto::FLAG_MSG_TYPE_MASK; + opts.mMsgFlagFilter = RsPhoto::FLAG_MSG_TYPE_PHOTO_COMMENT; + + opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; + opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; + opts.mOptions = RS_TOKREQOPT_MSG_PARENT | RS_TOKREQOPT_MSG_LATEST; + RsGxsGrpMsgIdPair msgId; + uint32_t token; + msgId.first = mPhotoDetails.mMeta.mGroupId; + msgId.second = mPhotoDetails.mMeta.mMsgId; + std::vector msgIdV; + msgIdV.push_back(msgId); + mPhotoQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIdV, 0); +} + +void PhotoDialog::createComment() +{ + RsPhotoComment comment; + QString commentString = ui->lineEdit->text(); + + comment.mComment = commentString.toUtf8().constData(); + + uint32_t token; + comment.mMeta.mGroupId = mPhotoDetails.mMeta.mGroupId; + comment.mMeta.mParentId = mPhotoDetails.mMeta.mOrigMsgId; + mRsPhoto->submitComment(token, comment); + mPhotoQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); + + ui->lineEdit->clear(); +} + + +/*************** message loading **********************/ + +void PhotoDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) +{ + std::cerr << "PhotoShare::loadRequest()"; + std::cerr << std::endl; + + if (queue == mPhotoQueue) + { + /* now switch on req */ + switch(req.mType) + { + case TOKENREQ_MSGINFO: + { + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_DATA: + loadComment(req.mToken); + break; + case RS_TOKREQ_ANSTYPE_LIST: + loadList(req.mToken); + break; + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgeComment(req.mToken); + break; + default: + std::cerr << "PhotoShare::loadRequest() ERROR: MSG INVALID TYPE"; + std::cerr << std::endl; + break; + } + break; + } + + default: + { + std::cerr << "PhotoShare::loadRequest() ERROR: INVALID TYPE"; + std::cerr << std::endl; + break; + } + } + } + +} + +void PhotoDialog::loadComment(uint32_t token) +{ + + clearComments(); + + PhotoRelatedCommentResult results; + mRsPhoto->getPhotoRelatedComment(token, results); + + PhotoRelatedCommentResult::iterator mit = results.begin(); + + for(; mit != results.end(); mit++) + { + const std::vector& commentV = mit->second; + std::vector::const_iterator vit = commentV.begin(); + + for(; vit != commentV.end(); vit++) + { + addComment(*vit); + } + } + + resetComments(); +} + +void PhotoDialog::loadList(uint32_t token) +{ + GxsMsgReq msgIds; + mRsPhoto->getMsgList(token, msgIds); + RsTokReqOptions opts; + + // just use data as no need to worry about getting comments + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + uint32_t reqToken; + mPhotoQueue->requestMsgInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, 0); +} + +void PhotoDialog::addComment(const RsPhotoComment &comment) +{ + PhotoCommentItem* item = new PhotoCommentItem(comment); + mComments.insert(item); +} + +void PhotoDialog::acknowledgeComment(uint32_t token) +{ + RsGxsGrpMsgIdPair msgId; + mRsPhoto->acknowledgeMsg(token, msgId); + + if(msgId.first.empty() || msgId.second.empty()){ + + }else + { + requestComments(); + } +} + +void PhotoDialog::setFullScreen() +{ + if (!isFullScreen()) { + // hide menu & toolbars + +#ifdef Q_WS_X11 + show(); + raise(); + setWindowState( windowState() | Qt::WindowFullScreen ); +#else + setWindowState( windowState() | Qt::WindowFullScreen ); + show(); + raise(); +#endif + } else { + + setWindowState( windowState() ^ Qt::WindowFullScreen ); + show(); + } +} diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h index dae81cdb0..15cf6bf5f 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.h @@ -1,62 +1,62 @@ -#ifndef PHOTODIALOG_H -#define PHOTODIALOG_H - -#include -#include -#include "retroshare/rsphotoV2.h" -#include "util/TokenQueue.h" -#include "PhotoCommentItem.h" - -namespace Ui { - class PhotoDialog; -} - -class PhotoDialog : public QDialog, public TokenResponse -{ - Q_OBJECT - -public: - explicit PhotoDialog(RsPhotoV2* rs_photo, const RsPhotoPhoto& photo, QWidget *parent = 0); - ~PhotoDialog(); - -private slots: - - void addComment(); - void createComment(); - void setFullScreen(); - -public: - void loadRequest(const TokenQueue *queue, const TokenRequest &req); -private: - void setUp(); - - /*! - * clears comments - * and places them back in dialog - */ - void resetComments(); - - /*! - * Request comments - */ - void requestComments(); - - /*! - * Simply removes comments but doesn't place them back in dialog - */ - void clearComments(); - - void acknowledgeComment(uint32_t token); - void loadComment(uint32_t token); - void loadList(uint32_t token); - void addComment(const RsPhotoComment& comment); -private: - Ui::PhotoDialog *ui; - - RsPhotoV2* mRsPhoto; - TokenQueue* mPhotoQueue; - RsPhotoPhoto mPhotoDetails; - QSet mComments; -}; - -#endif // PHOTODIALOG_H +#ifndef PHOTODIALOG_H +#define PHOTODIALOG_H + +#include +#include +#include "retroshare/rsphoto.h" +#include "util/TokenQueue.h" +#include "PhotoCommentItem.h" + +namespace Ui { + class PhotoDialog; +} + +class PhotoDialog : public QDialog, public TokenResponse +{ + Q_OBJECT + +public: + explicit PhotoDialog(RsPhoto* rs_photo, const RsPhotoPhoto& photo, QWidget *parent = 0); + ~PhotoDialog(); + +private slots: + + void addComment(); + void createComment(); + void setFullScreen(); + +public: + void loadRequest(const TokenQueue *queue, const TokenRequest &req); +private: + void setUp(); + + /*! + * clears comments + * and places them back in dialog + */ + void resetComments(); + + /*! + * Request comments + */ + void requestComments(); + + /*! + * Simply removes comments but doesn't place them back in dialog + */ + void clearComments(); + + void acknowledgeComment(uint32_t token); + void loadComment(uint32_t token); + void loadList(uint32_t token); + void addComment(const RsPhotoComment& comment); +private: + Ui::PhotoDialog *ui; + + RsPhoto* mRsPhoto; + TokenQueue* mPhotoQueue; + RsPhotoPhoto mPhotoDetails; + QSet mComments; +}; + +#endif // PHOTODIALOG_H diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoItem.h b/retroshare-gui/src/gui/PhotoShare/PhotoItem.h index c1f92e1d3..45160d443 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoItem.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoItem.h @@ -1,52 +1,52 @@ -#ifndef PHOTOITEM_H -#define PHOTOITEM_H - -#include -#include -#include "PhotoShareItemHolder.h" -#include "retroshare/rsphotoV2.h" - -namespace Ui { - class PhotoItem; -} - -class PhotoItem : public QWidget, public PhotoShareItem -{ - Q_OBJECT - -public: - - PhotoItem(PhotoShareItemHolder *holder, const RsPhotoPhoto& photo, QWidget* parent = 0); - PhotoItem(PhotoShareItemHolder *holder, const QString& path, QWidget* parent = 0); // for new photos. - ~PhotoItem(); - void setSelected(bool selected); - bool isSelected(){ return mSelected; } - const RsPhotoPhoto& getPhotoDetails(); - bool getPhotoThumbnail(RsPhotoThumbnail &nail); - -protected: - void mousePressEvent(QMouseEvent *event); - -private: - void updateImage(const RsPhotoThumbnail &thumbnail); - void setUp(); - - private slots: - void setTitle(); - void setPhotoGrapher(); - -private: - Ui::PhotoItem *ui; - - QPixmap mThumbNail; - - QPixmap getPixmap() { return mThumbNail; } - - bool mSelected; - RsPhotoPhoto mPhotoDetails; - PhotoShareItemHolder* mHolder; - - QLabel *mTitleLabel, *mPhotoGrapherLabel; -}; - -#endif // PHOTOITEM_H +#ifndef PHOTOITEM_H +#define PHOTOITEM_H + +#include +#include +#include "PhotoShareItemHolder.h" +#include "retroshare/rsphoto.h" + +namespace Ui { + class PhotoItem; +} + +class PhotoItem : public QWidget, public PhotoShareItem +{ + Q_OBJECT + +public: + + PhotoItem(PhotoShareItemHolder *holder, const RsPhotoPhoto& photo, QWidget* parent = 0); + PhotoItem(PhotoShareItemHolder *holder, const QString& path, QWidget* parent = 0); // for new photos. + ~PhotoItem(); + void setSelected(bool selected); + bool isSelected(){ return mSelected; } + const RsPhotoPhoto& getPhotoDetails(); + bool getPhotoThumbnail(RsPhotoThumbnail &nail); + +protected: + void mousePressEvent(QMouseEvent *event); + +private: + void updateImage(const RsPhotoThumbnail &thumbnail); + void setUp(); + + private slots: + void setTitle(); + void setPhotoGrapher(); + +private: + Ui::PhotoItem *ui; + + QPixmap mThumbNail; + + QPixmap getPixmap() { return mThumbNail; } + + bool mSelected; + RsPhotoPhoto mPhotoDetails; + PhotoShareItemHolder* mHolder; + + QLabel *mTitleLabel, *mPhotoGrapherLabel; +}; + +#endif // PHOTOITEM_H diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp index dcef37533..3fd0f2527 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.cpp @@ -1,709 +1,709 @@ - -/* - * Retroshare Photo Plugin. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "PhotoShare.h" -#include "ui_PhotoShare.h" - -#include -#include -#include - -#include -#include - -#include -#include - -#include "AlbumCreateDialog.h" -#include "AlbumItem.h" -#include "PhotoItem.h" - -/****** - * #define PHOTO_DEBUG 1 - *****/ - - -/**************************************************************** - * New Photo Display Widget. - * - * This has two 'lists'. - * Top list shows Albums. - * Lower list is photos from the selected Album. - * - * Notes: - * Each Item will be an AlbumItem, which contains a thumbnail & random details. - * We will limit Items to < 100. With a 'Filter to see more message. - * - * Thumbnails will come from Service. - * Option to Share albums / pictures onward (if permissions allow). - * Option to Download the albums to a specified directory. (is this required if sharing an album?) - * - * Will introduce a FullScreen SlideShow later... first get basics happening. - */ - -#define IS_ALBUM_ADMIN(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) -#define IS_ALBUM_SUBSCRIBED(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) -#define IS_ALBUM_N_SUBSCR_OR_ADMIN(subscribeFlags) ((subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_MASK) == 0) - - -/** Constructor */ -PhotoShare::PhotoShare(QWidget *parent) -: MainPage(parent) -{ - ui.setupUi(this); - - mAlbumSelected = NULL; - mPhotoSelected = NULL; - - connect( ui.toolButton_NewAlbum, SIGNAL(clicked()), this, SLOT(createAlbum())); - connect( ui.toolButton_ViewAlbum, SIGNAL(clicked()), this, SLOT(OpenAlbumDialog())); - connect( ui.toolButton_SlideShow, SIGNAL(clicked()), this, SLOT(OpenSlideShow())); - connect( ui.toolButton_subscribe, SIGNAL(clicked()), this, SLOT(subscribeToAlbum())); - connect(ui.toolButton_ViewPhoto, SIGNAL(clicked()), this, SLOT(OpenPhotoDialog())); - - connect( ui.pushButton_YourAlbums, SIGNAL(clicked()), this, SLOT(updateAlbums())); - connect( ui.pushButton_SharedAlbums, SIGNAL(clicked()), this, SLOT(updateAlbums())); - connect( ui.pushButton_SubscribedAlbums, SIGNAL(clicked()), this, SLOT(updateAlbums())); - - ui.pushButton_YourAlbums->setChecked(true); // default to your albums view - - QTimer *timer = new QTimer(this); - timer->connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate())); - timer->start(1000); - - /* setup TokenQueue */ - mPhotoQueue = new TokenQueue(rsPhotoV2->getTokenService(), this); - requestAlbumData(); -} - -void PhotoShare::notifySelection(PhotoShareItem *selection) -{ - - AlbumItem* aItem; - PhotoItem* pItem; - - if((aItem = dynamic_cast(selection)) != NULL) - { - - if(mPhotoSelected) - mPhotoSelected->setSelected(false); - - if(mAlbumSelected == aItem) - { - mAlbumSelected->setSelected(true); - } - else - { - if(mAlbumSelected == NULL) - { - mAlbumSelected = aItem; - } - else - { - mAlbumSelected->setSelected(false); - mAlbumSelected = aItem; - } - - mAlbumSelected->setSelected(true); - - // get photo data - std::list grpIds; - grpIds.push_back(mAlbumSelected->getAlbum().mMeta.mGroupId); - requestPhotoData(grpIds); - } - } - else if((pItem = dynamic_cast(selection)) != NULL) - { - if(mPhotoSelected == pItem) - { - mPhotoSelected->setSelected(true); - } - else - { - if(mPhotoSelected == NULL) - { - mPhotoSelected = pItem; - } - else - { - mPhotoSelected->setSelected(false); - mPhotoSelected = pItem; - } - - mPhotoSelected->setSelected(true); - } - } - else - { - - } - -} - - -void PhotoShare::checkUpdate() -{ - /* update */ - if (!rsPhotoV2) - return; - - if (rsPhotoV2->updated()) - { - //insertAlbums(); - std::list grpIds; - rsPhotoV2->groupsChanged(grpIds); - if(!grpIds.empty()) - { - RsTokReqOptions opts; - uint32_t token; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); - } - - GxsMsgIdResult res; - rsPhotoV2->msgsChanged(res); - if(!res.empty()) - requestPhotoList(res); - } - - return; -} - - -/*************** New Photo Dialog ***************/ - -void PhotoShare::OpenSlideShow() -{ - // TODO. - if (!mAlbumSelected) { - // ALERT. - int ret = QMessageBox::information(this, tr("PhotoShare"), - tr("Please select an album before\n" - "requesting to edit it!"), - QMessageBox::Ok); - return; - } - - PhotoSlideShow *dlg = new PhotoSlideShow(mAlbumSelected->getAlbum(), NULL); - dlg->show(); -} - - -/*************** New Photo Dialog ***************/ - -void PhotoShare::createAlbum() -{ - AlbumCreateDialog albumCreate(mPhotoQueue, rsPhotoV2, this); - albumCreate.exec(); -} - -void PhotoShare::OpenAlbumDialog() -{ - if (mAlbumSelected) { - AlbumDialog dlg(mAlbumSelected->getAlbum(), mPhotoQueue, rsPhotoV2); - dlg.exec(); - } -} - -void PhotoShare::OpenPhotoDialog() -{ - if (mPhotoSelected) { - PhotoDialog *dlg = new PhotoDialog(rsPhotoV2, mPhotoSelected->getPhotoDetails()); - dlg->show(); - } -} - -/*************** Edit Photo Dialog ***************/ - -void PhotoShare::clearAlbums() -{ - clearPhotos(); - - std::cerr << "PhotoShare::clearAlbums()" << std::endl; - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - - QSetIterator sit(mAlbumItems); - - while(sit.hasNext()) - { - AlbumItem* item = sit.next(); - alayout->removeWidget(item); - item->setParent(NULL); - } - - // set no albums to be selected - if(mAlbumSelected) - { - mAlbumSelected->setSelected(false); - mAlbumSelected = NULL; - } -} - -void PhotoShare::deleteAlbums() -{ - std::cerr << "PhotoShare::clearAlbums()" << std::endl; - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - - QSetIterator sit(mAlbumItems); - - while(sit.hasNext()) - { - AlbumItem* item = sit.next(); - alayout->removeWidget(item); - delete item; - } - - mAlbumItems.clear(); - - mAlbumSelected = NULL; -} - - -void PhotoShare::clearPhotos() -{ - std::cerr << "PhotoShare::clearPhotos()" << std::endl; - - QLayout *layout = ui.scrollAreaWidgetContents_2->layout(); - - if(mAlbumSelected) - { - QSetIterator sit(mPhotoItems); - - while(sit.hasNext()) - { - PhotoItem* item = sit.next(); - layout->removeWidget(item); - item->setParent(NULL); - delete item; // remove item - } - mPhotoItems.clear(); - } - mPhotoSelected = NULL; -} - -void PhotoShare::updateAlbums() -{ - - clearAlbums(); - - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - QSetIterator sit(mAlbumItems); - - if(ui.pushButton_YourAlbums->isChecked()) - { - - ui.toolButton_subscribe->setEnabled(false); - ui.toolButton_NewAlbum->setEnabled(true); - ui.toolButton_SlideShow->setEnabled(true); - - while(sit.hasNext()){ - - AlbumItem* item = sit.next(); - uint32_t flags = item->getAlbum().mMeta.mSubscribeFlags; - - if(IS_ALBUM_ADMIN(flags)) - alayout->addWidget(item); - } - }else if(ui.pushButton_SubscribedAlbums->isChecked()) - { - - ui.toolButton_subscribe->setEnabled(true); - ui.toolButton_subscribe->setText("Unsubscribe From Album"); - ui.toolButton_subscribe->setIcon(QIcon(":/images/album_unsubscribe.png")); - //ui.toolButton_NewAlbum->setEnabled(false); - ui.toolButton_SlideShow->setEnabled(true); - - while(sit.hasNext()){ - - AlbumItem* item = sit.next(); - uint32_t flags = item->getAlbum().mMeta.mSubscribeFlags; - - if(IS_ALBUM_SUBSCRIBED(flags)) - alayout->addWidget(item); - } - - }else if(ui.pushButton_SharedAlbums->isChecked()) - { - - ui.toolButton_subscribe->setEnabled(true); - ui.toolButton_subscribe->setText("Subscribe To Album"); - ui.toolButton_subscribe->setIcon(QIcon(":/images/album_subscribe.png")); - //ui.toolButton_NewAlbum->setEnabled(false); - ui.toolButton_SlideShow->setEnabled(false); - - while(sit.hasNext()){ - - AlbumItem* item = sit.next(); - uint32_t flags = item->getAlbum().mMeta.mSubscribeFlags; - - if(IS_ALBUM_N_SUBSCR_OR_ADMIN(flags)) - alayout->addWidget(item); - - } - } -} - -void PhotoShare::deleteAlbum(const RsGxsGroupId &grpId) -{ - - QSetIterator sit(mAlbumItems); - - while(sit.hasNext()) - { - AlbumItem* item = sit.next(); - - if(item->getAlbum().mMeta.mGroupId == grpId){ - - if(mAlbumSelected == item) - { - item->setSelected(false); - mAlbumSelected = NULL; - } - - QLayout *alayout = ui.scrollAreaWidgetContents->layout(); - alayout->removeWidget(item); - mAlbumItems.remove(item); - item->setParent(NULL); - delete item; - return; - } - } -} - -void PhotoShare::addAlbum(const RsPhotoAlbum &album) -{ - std::cerr << " PhotoShare::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; - - deleteAlbum(album.mMeta.mGroupId); // remove from ui - AlbumItem *item = new AlbumItem(album, this, this); - mAlbumItems.insert(item); -} - - -void PhotoShare::addPhoto(const RsPhotoPhoto &photo) -{ - std::cerr << "PhotoShare::addPhoto() AlbumId: " << photo.mMeta.mGroupId; - std::cerr << " PhotoId: " << photo.mMeta.mMsgId; - std::cerr << std::endl; - - PhotoItem* item = new PhotoItem(this, photo, this); - mPhotoItems.insert(item); -} - -void PhotoShare::subscribeToAlbum() -{ - if(mAlbumSelected){ - RsGxsGroupId id = mAlbumSelected->getAlbum().mMeta.mGroupId; - uint32_t token; - - if(IS_ALBUM_SUBSCRIBED(mAlbumSelected->getAlbum().mMeta.mSubscribeFlags)) - rsPhotoV2->subscribeToAlbum(token, id, false); - else if(IS_ALBUM_ADMIN(mAlbumSelected->getAlbum().mMeta.mSubscribeFlags)) - return; - else if(IS_ALBUM_N_SUBSCR_OR_ADMIN( - mAlbumSelected->getAlbum().mMeta.mSubscribeFlags)) - rsPhotoV2->subscribeToAlbum(token, id, true); - else - return; - - mPhotoQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, 0); - } -} - -void PhotoShare::updatePhotos() -{ - - if(mAlbumSelected) - { - QSetIterator sit(mPhotoItems); - - while(sit.hasNext()) - { - QLayout *layout = ui.scrollAreaWidgetContents_2->layout(); - layout->addWidget(sit.next()); - } - } -} - -/**************************** Request / Response Filling of Data ************************/ - - -void PhotoShare::requestAlbumList(std::list& ids) -{ - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; - uint32_t token; - mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, ids, 0); -} - -void PhotoShare::requestPhotoList(GxsMsgReq& req) -{ - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; - uint32_t token; - mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, req, 0); - return; -} - - -void PhotoShare::loadAlbumList(const uint32_t &token) -{ - std::cerr << "PhotoShare::loadAlbumList()"; - std::cerr << std::endl; - - std::list albumIds; - rsPhotoV2->getGroupList(token, albumIds); - - requestAlbumData(albumIds); - - std::list::iterator it; - for(it = albumIds.begin(); it != albumIds.end(); it++) - { - requestPhotoList(*it); - } -} - - -void PhotoShare::requestAlbumData(std::list &ids) -{ - RsTokReqOptions opts; - uint32_t token; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, 0); -} - -void PhotoShare::requestAlbumData() -{ - RsTokReqOptions opts; - uint32_t token; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, 0); -} - -bool PhotoShare::loadAlbumData(const uint32_t &token) -{ - std::cerr << "PhotoShare::loadAlbumData()"; - std::cerr << std::endl; - - std::vector albums; - rsPhotoV2->getAlbum(token, albums); - - std::vector::iterator vit = albums.begin(); - - for(; vit != albums.end(); vit++) - { - RsPhotoAlbum& album = *vit; - - std::cerr << " PhotoShare::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; - - addAlbum(album); - } - - updateAlbums(); - return true; -} - - -void PhotoShare::requestPhotoList(const std::string &albumId) -{ - - std::list grpIds; - grpIds.push_back(albumId); - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - uint32_t token; - mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, grpIds, 0); -} - - -void PhotoShare::acknowledgeGroup(const uint32_t &token) -{ - RsGxsGroupId grpId; - rsPhotoV2->acknowledgeGrp(token, grpId); - - if(!grpId.empty()) - { - std::list grpIds; - grpIds.push_back(grpId); - - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - uint32_t reqToken; - mPhotoQueue->requestGroupInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); - } -} - -void PhotoShare::acknowledgeMessage(const uint32_t &token) -{ - std::pair p; - rsPhotoV2->acknowledgeMsg(token, p); - - // just acknowledge don't load it - // loading is only instigated by clicking an album (i.e. requesting photo data) - // but load it if the album is selected -// if(!p.first.empty()) -// { -// if(mAlbumSelected) -// { -// if(mAlbumSelected->getAlbum().mMeta.mGroupId == p.first) -// { -// std::list grpIds; -// grpIds.push_back(p.first); -// requestPhotoData(grpIds); -// } -// } -// } -} - -void PhotoShare::loadPhotoList(const uint32_t &token) -{ - std::cerr << "PhotoShare::loadPhotoList()"; - std::cerr << std::endl; - - GxsMsgIdResult res; - - rsPhotoV2->getMsgList(token, res); - requestPhotoData(res); -} - - -void PhotoShare::requestPhotoData(GxsMsgReq &photoIds) -{ - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - uint32_t token; - mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, photoIds, 0); -} - -void PhotoShare::requestPhotoData(const std::list& grpIds) -{ - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - uint32_t token; - mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); -} - - -void PhotoShare::loadPhotoData(const uint32_t &token) -{ - std::cerr << "PhotoShare::loadPhotoData()"; - std::cerr << std::endl; - - clearPhotos(); - - PhotoResult res; - rsPhotoV2->getPhoto(token, res); - PhotoResult::iterator mit = res.begin(); - - - for(; mit != res.end(); mit++) - { - std::vector& photoV = mit->second; - std::vector::iterator vit = photoV.begin(); - - for(; vit != photoV.end(); vit++) - { - RsPhotoPhoto& photo = *vit; - addPhoto(photo); - std::cerr << "PhotoShare::loadPhotoData() AlbumId: " << photo.mMeta.mGroupId; - std::cerr << " PhotoId: " << photo.mMeta.mMsgId; - std::cerr << std::endl; - } - } - updatePhotos(); -} - - -/**************************** Request / Response Filling of Data ************************/ - -void PhotoShare::loadRequest(const TokenQueue *queue, const TokenRequest &req) -{ - std::cerr << "PhotoShare::loadRequest()"; - std::cerr << std::endl; - - if (queue == mPhotoQueue) - { - /* now switch on req */ - switch(req.mType) - { - case TOKENREQ_GROUPINFO: - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_LIST: - loadAlbumList(req.mToken); - break; - case RS_TOKREQ_ANSTYPE_DATA: - loadAlbumData(req.mToken); - break; - case RS_TOKREQ_ANSTYPE_ACK: - acknowledgeGroup(req.mToken); - break; - default: - std::cerr << "PhotoShare::loadRequest() ERROR: GROUP: INVALID ANS TYPE"; - std::cerr << std::endl; - break; - } - break; - case TOKENREQ_MSGINFO: - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_LIST: - loadPhotoList(req.mToken); - break; - case RS_TOKREQ_ANSTYPE_ACK: - acknowledgeMessage(req.mToken); - break; - case RS_TOKREQ_ANSTYPE_DATA: - loadPhotoData(req.mToken); - break; - default: - std::cerr << "PhotoShare::loadRequest() ERROR: MSG: INVALID ANS TYPE"; - std::cerr << std::endl; - break; - } - break; - case TOKENREQ_MSGRELATEDINFO: - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_DATA: - loadPhotoData(req.mToken); - break; - default: - std::cerr << "PhotoShare::loadRequest() ERROR: MSG: INVALID ANS TYPE"; - std::cerr << std::endl; - break; - } - break; - default: - std::cerr << "PhotoShare::loadRequest() ERROR: INVALID TYPE"; - std::cerr << std::endl; - break; - } - } -} - - -/**************************** Request / Response Filling of Data ************************/ - + +/* + * Retroshare Photo Plugin. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "PhotoShare.h" +#include "ui_PhotoShare.h" + +#include +#include +#include + +#include +#include + +#include +#include + +#include "AlbumCreateDialog.h" +#include "AlbumItem.h" +#include "PhotoItem.h" + +/****** + * #define PHOTO_DEBUG 1 + *****/ + + +/**************************************************************** + * New Photo Display Widget. + * + * This has two 'lists'. + * Top list shows Albums. + * Lower list is photos from the selected Album. + * + * Notes: + * Each Item will be an AlbumItem, which contains a thumbnail & random details. + * We will limit Items to < 100. With a 'Filter to see more message. + * + * Thumbnails will come from Service. + * Option to Share albums / pictures onward (if permissions allow). + * Option to Download the albums to a specified directory. (is this required if sharing an album?) + * + * Will introduce a FullScreen SlideShow later... first get basics happening. + */ + +#define IS_ALBUM_ADMIN(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) +#define IS_ALBUM_SUBSCRIBED(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) +#define IS_ALBUM_N_SUBSCR_OR_ADMIN(subscribeFlags) ((subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_MASK) == 0) + + +/** Constructor */ +PhotoShare::PhotoShare(QWidget *parent) +: MainPage(parent) +{ + ui.setupUi(this); + + mAlbumSelected = NULL; + mPhotoSelected = NULL; + + connect( ui.toolButton_NewAlbum, SIGNAL(clicked()), this, SLOT(createAlbum())); + connect( ui.toolButton_ViewAlbum, SIGNAL(clicked()), this, SLOT(OpenAlbumDialog())); + connect( ui.toolButton_SlideShow, SIGNAL(clicked()), this, SLOT(OpenSlideShow())); + connect( ui.toolButton_subscribe, SIGNAL(clicked()), this, SLOT(subscribeToAlbum())); + connect(ui.toolButton_ViewPhoto, SIGNAL(clicked()), this, SLOT(OpenPhotoDialog())); + + connect( ui.pushButton_YourAlbums, SIGNAL(clicked()), this, SLOT(updateAlbums())); + connect( ui.pushButton_SharedAlbums, SIGNAL(clicked()), this, SLOT(updateAlbums())); + connect( ui.pushButton_SubscribedAlbums, SIGNAL(clicked()), this, SLOT(updateAlbums())); + + ui.pushButton_YourAlbums->setChecked(true); // default to your albums view + + QTimer *timer = new QTimer(this); + timer->connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate())); + timer->start(1000); + + /* setup TokenQueue */ + mPhotoQueue = new TokenQueue(rsPhoto->getTokenService(), this); + requestAlbumData(); +} + +void PhotoShare::notifySelection(PhotoShareItem *selection) +{ + + AlbumItem* aItem; + PhotoItem* pItem; + + if((aItem = dynamic_cast(selection)) != NULL) + { + + if(mPhotoSelected) + mPhotoSelected->setSelected(false); + + if(mAlbumSelected == aItem) + { + mAlbumSelected->setSelected(true); + } + else + { + if(mAlbumSelected == NULL) + { + mAlbumSelected = aItem; + } + else + { + mAlbumSelected->setSelected(false); + mAlbumSelected = aItem; + } + + mAlbumSelected->setSelected(true); + + // get photo data + std::list grpIds; + grpIds.push_back(mAlbumSelected->getAlbum().mMeta.mGroupId); + requestPhotoData(grpIds); + } + } + else if((pItem = dynamic_cast(selection)) != NULL) + { + if(mPhotoSelected == pItem) + { + mPhotoSelected->setSelected(true); + } + else + { + if(mPhotoSelected == NULL) + { + mPhotoSelected = pItem; + } + else + { + mPhotoSelected->setSelected(false); + mPhotoSelected = pItem; + } + + mPhotoSelected->setSelected(true); + } + } + else + { + + } + +} + + +void PhotoShare::checkUpdate() +{ + /* update */ + if (!rsPhoto) + return; + + if (rsPhoto->updated()) + { + //insertAlbums(); + std::list grpIds; + rsPhoto->groupsChanged(grpIds); + if(!grpIds.empty()) + { + RsTokReqOptions opts; + uint32_t token; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); + } + + GxsMsgIdResult res; + rsPhoto->msgsChanged(res); + if(!res.empty()) + requestPhotoList(res); + } + + return; +} + + +/*************** New Photo Dialog ***************/ + +void PhotoShare::OpenSlideShow() +{ + // TODO. + if (!mAlbumSelected) { + // ALERT. + int ret = QMessageBox::information(this, tr("PhotoShare"), + tr("Please select an album before\n" + "requesting to edit it!"), + QMessageBox::Ok); + return; + } + + PhotoSlideShow *dlg = new PhotoSlideShow(mAlbumSelected->getAlbum(), NULL); + dlg->show(); +} + + +/*************** New Photo Dialog ***************/ + +void PhotoShare::createAlbum() +{ + AlbumCreateDialog albumCreate(mPhotoQueue, rsPhoto, this); + albumCreate.exec(); +} + +void PhotoShare::OpenAlbumDialog() +{ + if (mAlbumSelected) { + AlbumDialog dlg(mAlbumSelected->getAlbum(), mPhotoQueue, rsPhoto); + dlg.exec(); + } +} + +void PhotoShare::OpenPhotoDialog() +{ + if (mPhotoSelected) { + PhotoDialog *dlg = new PhotoDialog(rsPhoto, mPhotoSelected->getPhotoDetails()); + dlg->show(); + } +} + +/*************** Edit Photo Dialog ***************/ + +void PhotoShare::clearAlbums() +{ + clearPhotos(); + + std::cerr << "PhotoShare::clearAlbums()" << std::endl; + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); + + QSetIterator sit(mAlbumItems); + + while(sit.hasNext()) + { + AlbumItem* item = sit.next(); + alayout->removeWidget(item); + item->setParent(NULL); + } + + // set no albums to be selected + if(mAlbumSelected) + { + mAlbumSelected->setSelected(false); + mAlbumSelected = NULL; + } +} + +void PhotoShare::deleteAlbums() +{ + std::cerr << "PhotoShare::clearAlbums()" << std::endl; + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); + + QSetIterator sit(mAlbumItems); + + while(sit.hasNext()) + { + AlbumItem* item = sit.next(); + alayout->removeWidget(item); + delete item; + } + + mAlbumItems.clear(); + + mAlbumSelected = NULL; +} + + +void PhotoShare::clearPhotos() +{ + std::cerr << "PhotoShare::clearPhotos()" << std::endl; + + QLayout *layout = ui.scrollAreaWidgetContents_2->layout(); + + if(mAlbumSelected) + { + QSetIterator sit(mPhotoItems); + + while(sit.hasNext()) + { + PhotoItem* item = sit.next(); + layout->removeWidget(item); + item->setParent(NULL); + delete item; // remove item + } + mPhotoItems.clear(); + } + mPhotoSelected = NULL; +} + +void PhotoShare::updateAlbums() +{ + + clearAlbums(); + + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); + QSetIterator sit(mAlbumItems); + + if(ui.pushButton_YourAlbums->isChecked()) + { + + ui.toolButton_subscribe->setEnabled(false); + ui.toolButton_NewAlbum->setEnabled(true); + ui.toolButton_SlideShow->setEnabled(true); + + while(sit.hasNext()){ + + AlbumItem* item = sit.next(); + uint32_t flags = item->getAlbum().mMeta.mSubscribeFlags; + + if(IS_ALBUM_ADMIN(flags)) + alayout->addWidget(item); + } + }else if(ui.pushButton_SubscribedAlbums->isChecked()) + { + + ui.toolButton_subscribe->setEnabled(true); + ui.toolButton_subscribe->setText("Unsubscribe From Album"); + ui.toolButton_subscribe->setIcon(QIcon(":/images/album_unsubscribe.png")); + //ui.toolButton_NewAlbum->setEnabled(false); + ui.toolButton_SlideShow->setEnabled(true); + + while(sit.hasNext()){ + + AlbumItem* item = sit.next(); + uint32_t flags = item->getAlbum().mMeta.mSubscribeFlags; + + if(IS_ALBUM_SUBSCRIBED(flags)) + alayout->addWidget(item); + } + + }else if(ui.pushButton_SharedAlbums->isChecked()) + { + + ui.toolButton_subscribe->setEnabled(true); + ui.toolButton_subscribe->setText("Subscribe To Album"); + ui.toolButton_subscribe->setIcon(QIcon(":/images/album_subscribe.png")); + //ui.toolButton_NewAlbum->setEnabled(false); + ui.toolButton_SlideShow->setEnabled(false); + + while(sit.hasNext()){ + + AlbumItem* item = sit.next(); + uint32_t flags = item->getAlbum().mMeta.mSubscribeFlags; + + if(IS_ALBUM_N_SUBSCR_OR_ADMIN(flags)) + alayout->addWidget(item); + + } + } +} + +void PhotoShare::deleteAlbum(const RsGxsGroupId &grpId) +{ + + QSetIterator sit(mAlbumItems); + + while(sit.hasNext()) + { + AlbumItem* item = sit.next(); + + if(item->getAlbum().mMeta.mGroupId == grpId){ + + if(mAlbumSelected == item) + { + item->setSelected(false); + mAlbumSelected = NULL; + } + + QLayout *alayout = ui.scrollAreaWidgetContents->layout(); + alayout->removeWidget(item); + mAlbumItems.remove(item); + item->setParent(NULL); + delete item; + return; + } + } +} + +void PhotoShare::addAlbum(const RsPhotoAlbum &album) +{ + std::cerr << " PhotoShare::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; + + deleteAlbum(album.mMeta.mGroupId); // remove from ui + AlbumItem *item = new AlbumItem(album, this, this); + mAlbumItems.insert(item); +} + + +void PhotoShare::addPhoto(const RsPhotoPhoto &photo) +{ + std::cerr << "PhotoShare::addPhoto() AlbumId: " << photo.mMeta.mGroupId; + std::cerr << " PhotoId: " << photo.mMeta.mMsgId; + std::cerr << std::endl; + + PhotoItem* item = new PhotoItem(this, photo, this); + mPhotoItems.insert(item); +} + +void PhotoShare::subscribeToAlbum() +{ + if(mAlbumSelected){ + RsGxsGroupId id = mAlbumSelected->getAlbum().mMeta.mGroupId; + uint32_t token; + + if(IS_ALBUM_SUBSCRIBED(mAlbumSelected->getAlbum().mMeta.mSubscribeFlags)) + rsPhoto->subscribeToAlbum(token, id, false); + else if(IS_ALBUM_ADMIN(mAlbumSelected->getAlbum().mMeta.mSubscribeFlags)) + return; + else if(IS_ALBUM_N_SUBSCR_OR_ADMIN( + mAlbumSelected->getAlbum().mMeta.mSubscribeFlags)) + rsPhoto->subscribeToAlbum(token, id, true); + else + return; + + mPhotoQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, 0); + } +} + +void PhotoShare::updatePhotos() +{ + + if(mAlbumSelected) + { + QSetIterator sit(mPhotoItems); + + while(sit.hasNext()) + { + QLayout *layout = ui.scrollAreaWidgetContents_2->layout(); + layout->addWidget(sit.next()); + } + } +} + +/**************************** Request / Response Filling of Data ************************/ + + +void PhotoShare::requestAlbumList(std::list& ids) +{ + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; + uint32_t token; + mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, ids, 0); +} + +void PhotoShare::requestPhotoList(GxsMsgReq& req) +{ + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; + uint32_t token; + mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, req, 0); + return; +} + + +void PhotoShare::loadAlbumList(const uint32_t &token) +{ + std::cerr << "PhotoShare::loadAlbumList()"; + std::cerr << std::endl; + + std::list albumIds; + rsPhoto->getGroupList(token, albumIds); + + requestAlbumData(albumIds); + + std::list::iterator it; + for(it = albumIds.begin(); it != albumIds.end(); it++) + { + requestPhotoList(*it); + } +} + + +void PhotoShare::requestAlbumData(std::list &ids) +{ + RsTokReqOptions opts; + uint32_t token; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, 0); +} + +void PhotoShare::requestAlbumData() +{ + RsTokReqOptions opts; + uint32_t token; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + mPhotoQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, 0); +} + +bool PhotoShare::loadAlbumData(const uint32_t &token) +{ + std::cerr << "PhotoShare::loadAlbumData()"; + std::cerr << std::endl; + + std::vector albums; + rsPhoto->getAlbum(token, albums); + + std::vector::iterator vit = albums.begin(); + + for(; vit != albums.end(); vit++) + { + RsPhotoAlbum& album = *vit; + + std::cerr << " PhotoShare::addAlbum() AlbumId: " << album.mMeta.mGroupId << std::endl; + + addAlbum(album); + } + + updateAlbums(); + return true; +} + + +void PhotoShare::requestPhotoList(const std::string &albumId) +{ + + std::list grpIds; + grpIds.push_back(albumId); + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST; + uint32_t token; + mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_LIST, opts, grpIds, 0); +} + + +void PhotoShare::acknowledgeGroup(const uint32_t &token) +{ + RsGxsGroupId grpId; + rsPhoto->acknowledgeGrp(token, grpId); + + if(!grpId.empty()) + { + std::list grpIds; + grpIds.push_back(grpId); + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + uint32_t reqToken; + mPhotoQueue->requestGroupInfo(reqToken, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); + } +} + +void PhotoShare::acknowledgeMessage(const uint32_t &token) +{ + std::pair p; + rsPhoto->acknowledgeMsg(token, p); + + // just acknowledge don't load it + // loading is only instigated by clicking an album (i.e. requesting photo data) + // but load it if the album is selected +// if(!p.first.empty()) +// { +// if(mAlbumSelected) +// { +// if(mAlbumSelected->getAlbum().mMeta.mGroupId == p.first) +// { +// std::list grpIds; +// grpIds.push_back(p.first); +// requestPhotoData(grpIds); +// } +// } +// } +} + +void PhotoShare::loadPhotoList(const uint32_t &token) +{ + std::cerr << "PhotoShare::loadPhotoList()"; + std::cerr << std::endl; + + GxsMsgIdResult res; + + rsPhoto->getMsgList(token, res); + requestPhotoData(res); +} + + +void PhotoShare::requestPhotoData(GxsMsgReq &photoIds) +{ + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + uint32_t token; + mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, photoIds, 0); +} + +void PhotoShare::requestPhotoData(const std::list& grpIds) +{ + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + uint32_t token; + mPhotoQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, 0); +} + + +void PhotoShare::loadPhotoData(const uint32_t &token) +{ + std::cerr << "PhotoShare::loadPhotoData()"; + std::cerr << std::endl; + + clearPhotos(); + + PhotoResult res; + rsPhoto->getPhoto(token, res); + PhotoResult::iterator mit = res.begin(); + + + for(; mit != res.end(); mit++) + { + std::vector& photoV = mit->second; + std::vector::iterator vit = photoV.begin(); + + for(; vit != photoV.end(); vit++) + { + RsPhotoPhoto& photo = *vit; + addPhoto(photo); + std::cerr << "PhotoShare::loadPhotoData() AlbumId: " << photo.mMeta.mGroupId; + std::cerr << " PhotoId: " << photo.mMeta.mMsgId; + std::cerr << std::endl; + } + } + updatePhotos(); +} + + +/**************************** Request / Response Filling of Data ************************/ + +void PhotoShare::loadRequest(const TokenQueue *queue, const TokenRequest &req) +{ + std::cerr << "PhotoShare::loadRequest()"; + std::cerr << std::endl; + + if (queue == mPhotoQueue) + { + /* now switch on req */ + switch(req.mType) + { + case TOKENREQ_GROUPINFO: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_LIST: + loadAlbumList(req.mToken); + break; + case RS_TOKREQ_ANSTYPE_DATA: + loadAlbumData(req.mToken); + break; + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgeGroup(req.mToken); + break; + default: + std::cerr << "PhotoShare::loadRequest() ERROR: GROUP: INVALID ANS TYPE"; + std::cerr << std::endl; + break; + } + break; + case TOKENREQ_MSGINFO: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_LIST: + loadPhotoList(req.mToken); + break; + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgeMessage(req.mToken); + break; + case RS_TOKREQ_ANSTYPE_DATA: + loadPhotoData(req.mToken); + break; + default: + std::cerr << "PhotoShare::loadRequest() ERROR: MSG: INVALID ANS TYPE"; + std::cerr << std::endl; + break; + } + break; + case TOKENREQ_MSGRELATEDINFO: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_DATA: + loadPhotoData(req.mToken); + break; + default: + std::cerr << "PhotoShare::loadRequest() ERROR: MSG: INVALID ANS TYPE"; + std::cerr << std::endl; + break; + } + break; + default: + std::cerr << "PhotoShare::loadRequest() ERROR: INVALID TYPE"; + std::cerr << std::endl; + break; + } + } +} + + +/**************************** Request / Response Filling of Data ************************/ + diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.h b/retroshare-gui/src/gui/PhotoShare/PhotoShare.h index 53b722bd1..e0de61063 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.h @@ -1,97 +1,97 @@ -#ifndef PHOTOSHARE_H -#define PHOTOSHARE_H - -#include -#include -#include "ui_PhotoShare.h" - -#include "retroshare/rsphotoV2.h" -#include "retroshare-gui/mainpage.h" - -#include "AlbumCreateDialog.h" -#include "AlbumDialog.h" -#include "PhotoDialog.h" - -#include "AlbumItem.h" -#include "PhotoItem.h" -#include "PhotoSlideShow.h" - -#include "util/TokenQueue.h" -#include "PhotoShareItemHolder.h" - -namespace Ui { - class PhotoShare; -} - -class PhotoShare : public MainPage, public TokenResponse, public PhotoShareItemHolder -{ - Q_OBJECT - -public: - PhotoShare(QWidget *parent = 0); - - void notifySelection(PhotoShareItem* selection); - -private slots: - void checkUpdate(); - void createAlbum(); - void OpenAlbumDialog(); - void OpenPhotoDialog(); - void OpenSlideShow(); - void updateAlbums(); - void subscribeToAlbum(); - void deleteAlbum(const RsGxsGroupId&); - -private: - /* Request Response Functions for loading data */ - void requestAlbumList(std::list& ids); - void requestAlbumData(std::list &ids); - - /*! - * request data for all groups - */ - void requestAlbumData(); - void requestPhotoList(GxsMsgReq &albumIds); - void requestPhotoList(const std::string &albumId); - void requestPhotoData(GxsMsgReq &photoIds); - void requestPhotoData(const std::list &grpIds); - - void loadAlbumList(const uint32_t &token); - bool loadAlbumData(const uint32_t &token); - void loadPhotoList(const uint32_t &token); - void loadPhotoData(const uint32_t &token); - - void loadRequest(const TokenQueue *queue, const TokenRequest &req); - - void acknowledgeGroup(const uint32_t &token); - void acknowledgeMessage(const uint32_t &token); - - /* Grunt work of setting up the GUI */ - - void addAlbum(const RsPhotoAlbum &album); - void addPhoto(const RsPhotoPhoto &photo); - - void clearAlbums(); - void clearPhotos(); - void deleteAlbums(); - /*! - * Fills up photo ui with photos held in mPhotoItems (current groups photos) - */ - void updatePhotos(); - -private: - AlbumItem* mAlbumSelected; - PhotoItem* mPhotoSelected; - - - TokenQueue *mPhotoQueue; - - /* UI - from Designer */ - Ui::PhotoShare ui; - - QSet mAlbumItems; - QSet mPhotoItems; // the current album selected - -}; - -#endif // PHOTOSHARE_H +#ifndef PHOTOSHARE_H +#define PHOTOSHARE_H + +#include +#include +#include "ui_PhotoShare.h" + +#include "retroshare/rsphoto.h" +#include "retroshare-gui/mainpage.h" + +#include "AlbumCreateDialog.h" +#include "AlbumDialog.h" +#include "PhotoDialog.h" + +#include "AlbumItem.h" +#include "PhotoItem.h" +#include "PhotoSlideShow.h" + +#include "util/TokenQueue.h" +#include "PhotoShareItemHolder.h" + +namespace Ui { + class PhotoShare; +} + +class PhotoShare : public MainPage, public TokenResponse, public PhotoShareItemHolder +{ + Q_OBJECT + +public: + PhotoShare(QWidget *parent = 0); + + void notifySelection(PhotoShareItem* selection); + +private slots: + void checkUpdate(); + void createAlbum(); + void OpenAlbumDialog(); + void OpenPhotoDialog(); + void OpenSlideShow(); + void updateAlbums(); + void subscribeToAlbum(); + void deleteAlbum(const RsGxsGroupId&); + +private: + /* Request Response Functions for loading data */ + void requestAlbumList(std::list& ids); + void requestAlbumData(std::list &ids); + + /*! + * request data for all groups + */ + void requestAlbumData(); + void requestPhotoList(GxsMsgReq &albumIds); + void requestPhotoList(const std::string &albumId); + void requestPhotoData(GxsMsgReq &photoIds); + void requestPhotoData(const std::list &grpIds); + + void loadAlbumList(const uint32_t &token); + bool loadAlbumData(const uint32_t &token); + void loadPhotoList(const uint32_t &token); + void loadPhotoData(const uint32_t &token); + + void loadRequest(const TokenQueue *queue, const TokenRequest &req); + + void acknowledgeGroup(const uint32_t &token); + void acknowledgeMessage(const uint32_t &token); + + /* Grunt work of setting up the GUI */ + + void addAlbum(const RsPhotoAlbum &album); + void addPhoto(const RsPhotoPhoto &photo); + + void clearAlbums(); + void clearPhotos(); + void deleteAlbums(); + /*! + * Fills up photo ui with photos held in mPhotoItems (current groups photos) + */ + void updatePhotos(); + +private: + AlbumItem* mAlbumSelected; + PhotoItem* mPhotoSelected; + + + TokenQueue *mPhotoQueue; + + /* UI - from Designer */ + Ui::PhotoShare ui; + + QSet mAlbumItems; + QSet mPhotoItems; // the current album selected + +}; + +#endif // PHOTOSHARE_H diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp index f64120908..e3997e0a6 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.cpp @@ -39,7 +39,7 @@ PhotoSlideShow::PhotoSlideShow(const RsPhotoAlbum& album, QWidget *parent) connect(ui.pushButton_Close, SIGNAL( clicked( void ) ), this, SLOT( closeShow( void ) ) ); connect(ui.fullscreenButton, SIGNAL(clicked()),this, SLOT(setFullScreen())); - mPhotoQueue = new TokenQueue(rsPhotoV2->getTokenService(), this); + mPhotoQueue = new TokenQueue(rsPhoto->getTokenService(), this); mRunning = true; mShotActive = true; @@ -236,7 +236,7 @@ bool PhotoSlideShow::loadPhotoData(const uint32_t &token) std::cerr << std::endl; PhotoResult res; - rsPhotoV2->getPhoto(token, res); + rsPhoto->getPhoto(token, res); PhotoResult::iterator mit = res.begin(); diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.h b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.h index 6da052c1d..23183035d 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.h +++ b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.h @@ -26,7 +26,7 @@ #include "ui_PhotoSlideShow.h" -#include +#include #include "util/TokenQueue.h" #include "AlbumItem.h" From 8cef4da8960040c16ed3ec17bf455cc5319de5a4 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sun, 25 Nov 2012 21:50:45 +0000 Subject: [PATCH 178/222] Added posted comment creation contextMnurequested does not seem to be working....may have to use an old fashioned non-derived treewidget. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5894 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/retroshare/rsposted.h | 4 + libretroshare/src/services/p3posted.cc | 11 + libretroshare/src/services/p3posted.h | 1 + .../src/gui/Posted/PostedComments.cpp | 45 ++- .../src/gui/Posted/PostedComments.h | 9 +- .../src/gui/Posted/PostedComments.ui | 37 +++ .../gui/Posted/PostedCreateCommentDialog.cpp | 20 +- .../gui/Posted/PostedCreateCommentDialog.h | 11 +- .../gui/Posted/PostedCreateCommentDialog.ui | 57 ++-- .../src/gui/Posted/PostedDialog.cpp | 7 +- retroshare-gui/src/gui/Posted/PostedDialog.h | 4 +- .../src/gui/Posted/PostedGroupDialog.cpp | 3 +- retroshare-gui/src/gui/Posted/PostedItem.cpp | 4 +- retroshare-gui/src/gui/Posted/PostedItem.h | 2 +- .../src/gui/Posted/PostedListDialog.cpp | 5 +- .../src/gui/Posted/PostedListDialog.h | 3 +- .../src/gui/gxs/GxsCommentTreeWidget.cpp | 284 +++++++++--------- .../src/gui/gxs/GxsCommentTreeWidget.h | 52 ++-- 18 files changed, 357 insertions(+), 202 deletions(-) diff --git a/libretroshare/src/retroshare/rsposted.h b/libretroshare/src/retroshare/rsposted.h index 1f585fd94..a10de0fef 100644 --- a/libretroshare/src/retroshare/rsposted.h +++ b/libretroshare/src/retroshare/rsposted.h @@ -68,6 +68,7 @@ class RsPostedVote; typedef std::map > PostedPostResult; typedef std::map > PostedCommentResult; typedef std::map > PostedVoteResult; +typedef std::map > PostedRelatedCommentResult; typedef std::pair GroupRank; std::ostream &operator<<(std::ostream &out, const RsPostedGroup &group); @@ -93,6 +94,7 @@ virtual ~RsPosted() { return; } virtual bool getGroup(const uint32_t &token, std::vector &group) = 0; virtual bool getPost(const uint32_t &token, PostedPostResult &post) = 0; virtual bool getComment(const uint32_t &token, PostedCommentResult &comment) = 0; +virtual bool getRelatedComment(const uint32_t& token, PostedRelatedCommentResult& comments) = 0; virtual bool getGroupRank(const uint32_t &token, GroupRank& grpRank) = 0; virtual bool submitGroup(uint32_t &token, RsPostedGroup &group) = 0; @@ -132,6 +134,7 @@ class RsPostedVote RsMsgMetaData mMeta; }; +class RsGxsPostedCommentItem; class RsPostedComment { @@ -142,6 +145,7 @@ class RsPostedComment return; } + RsPostedComment(const RsGxsPostedCommentItem& ); std::string mComment; RsMsgMetaData mMeta; }; diff --git a/libretroshare/src/services/p3posted.cc b/libretroshare/src/services/p3posted.cc index 350a559bc..d34e8f5ea 100644 --- a/libretroshare/src/services/p3posted.cc +++ b/libretroshare/src/services/p3posted.cc @@ -7,6 +7,12 @@ const uint32_t RsPosted::FLAG_MSGTYPE_VOTE = 0x0004; RsPosted *rsPosted = NULL; +RsPostedComment::RsPostedComment(const RsGxsPostedCommentItem & item) +{ + mComment = item.mComment.mComment; + mMeta = item.meta; +} + p3Posted::p3Posted(RsGeneralDataService *gds, RsNetworkExchangeService *nes) : RsGenExchange(gds, nes, new RsGxsPostedSerialiser(), RS_SERVICE_GXSV1_TYPE_POSTED), RsPosted(this) { @@ -118,6 +124,11 @@ bool p3Posted::getComment(const uint32_t &token, PostedCommentResult &comments) return ok; } +bool p3Posted::getRelatedComment(const uint32_t& token, PostedRelatedCommentResult &comments) +{ + return RsGenExchange::getMsgRelatedDataT(token, comments); +} + bool p3Posted::getGroupRank(const uint32_t &token, GroupRank &grpRank) { diff --git a/libretroshare/src/services/p3posted.h b/libretroshare/src/services/p3posted.h index 18be77e7b..78e6c9ea5 100644 --- a/libretroshare/src/services/p3posted.h +++ b/libretroshare/src/services/p3posted.h @@ -29,6 +29,7 @@ public: bool getGroup(const uint32_t &token, std::vector &group); bool getPost(const uint32_t &token, PostedPostResult& posts) ; bool getComment(const uint32_t &token, PostedCommentResult& comments) ; + bool getRelatedComment(const uint32_t& token, PostedRelatedCommentResult &comments); bool getGroupRank(const uint32_t& token, GroupRank& grpRank); bool submitGroup(uint32_t &token, RsPostedGroup &group); diff --git a/retroshare-gui/src/gui/Posted/PostedComments.cpp b/retroshare-gui/src/gui/Posted/PostedComments.cpp index 12558668d..04c07e467 100644 --- a/retroshare-gui/src/gui/Posted/PostedComments.cpp +++ b/retroshare-gui/src/gui/Posted/PostedComments.cpp @@ -22,6 +22,7 @@ */ #include "PostedComments.h" +#include "PostedCreateCommentDialog.h" #include @@ -30,10 +31,8 @@ #include #include +#include -/****** - * #define PHOTO_DEBUG 1 - *****/ /**************************************************************** @@ -64,15 +63,51 @@ PostedComments::PostedComments(QWidget *parent) ui.setupUi(this); ui.postFrame->setVisible(false); ui.treeWidget->setup(rsPosted->getTokenService()); + connect(ui.treeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(test(QPoint))); +} + +void PostedComments::test(QPoint p) +{ + int x = p.x(); + int y = p.y(); + int c= x+y; } -void PostedComments::loadComments(const RsGxsMessageId& threadId ) +void PostedComments::loadComments(const RsPostedPost& post) { - std::cerr << "PostedComments::loadComments(" << threadId << ")"; + std::cerr << "PostedComments::loadComments(" << post.mMeta.mOrigMsgId << ")"; std::cerr << std::endl; + mCurrentPost = post; + setUpPostFrame(); + + RsGxsGrpMsgIdPair threadId; + + threadId.first = post.mMeta.mOrigMsgId; + threadId.second = post.mMeta.mGroupId; + ui.treeWidget->requestComments(threadId); } +void PostedComments::setUpPostFrame() +{ + ui.postFrame->setVisible(true); + + QDateTime qtime; + qtime.setTime_t(mCurrentPost.mMeta.mPublishTs); + QString timestamp = qtime.toString("dd.MMMM yyyy hh:mm"); + ui.dateLabel->setText(timestamp); + ui.fromLabel->setText(QString::fromUtf8(mCurrentPost.mMeta.mAuthorId.c_str())); + ui.titleLabel->setText("" + + QString::fromStdString(mCurrentPost.mMeta.mMsgName) + ""); + ui.siteLabel->setText("" + + QString::fromStdString(mCurrentPost.mLink) + ""); + + ui.scoreLabel->setText(QString("1")); + +} + diff --git a/retroshare-gui/src/gui/Posted/PostedComments.h b/retroshare-gui/src/gui/Posted/PostedComments.h index 5458fafc0..5bf557364 100644 --- a/retroshare-gui/src/gui/Posted/PostedComments.h +++ b/retroshare-gui/src/gui/Posted/PostedComments.h @@ -42,12 +42,17 @@ public: public slots: - void loadComments(const RsGxsMessageId& ); + void loadComments(const RsPostedPost& ); + + private slots: + + void test(QPoint p); private: void loadRequest(const TokenQueue *queue, const TokenRequest &req) { return; } + void setUpPostFrame(); - TokenQueue *mPhotoQueue; + RsPostedPost mCurrentPost; /* UI - from Designer */ Ui::PostedComments ui; diff --git a/retroshare-gui/src/gui/Posted/PostedComments.ui b/retroshare-gui/src/gui/Posted/PostedComments.ui index 8347d0c5b..d06b8d0c1 100644 --- a/retroshare-gui/src/gui/Posted/PostedComments.ui +++ b/retroshare-gui/src/gui/Posted/PostedComments.ui @@ -344,6 +344,43 @@ border-radius: 10px} + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Make Comment + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + diff --git a/retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.cpp index e9a020f14..e5eaa27c6 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.cpp @@ -1,11 +1,27 @@ #include "PostedCreateCommentDialog.h" #include "ui_PostedCreateCommentDialog.h" -PostedCreateCommentDialog::PostedCreateCommentDialog(QWidget *parent) : +PostedCreateCommentDialog::PostedCreateCommentDialog(TokenQueue *tokQ, const RsGxsGrpMsgIdPair &parentId, const RsGxsMessageId& threadId, QWidget *parent) : QDialog(parent), - ui(new Ui::PostedCreateCommentDialog) + ui(new Ui::PostedCreateCommentDialog), mTokenQueue(tokQ), mParentId(parentId), mThreadId(threadId) { ui->setupUi(this); + connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(createComment())); +} + +void PostedCreateCommentDialog::createComment() +{ + RsPostedComment comment; + + comment.mComment = ui->commentTextEdit->document()->toPlainText().toStdString(); + comment.mMeta.mParentId = mParentId.second; + comment.mMeta.mGroupId = mParentId.first; + comment.mMeta.mThreadId = mThreadId; + + uint32_t token; + rsPosted->submitComment(token, comment); + mTokenQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); + close(); } PostedCreateCommentDialog::~PostedCreateCommentDialog() diff --git a/retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.h b/retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.h index 22ff82598..8edae3e1a 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.h @@ -2,6 +2,8 @@ #define POSTEDCREATECOMMENTDIALOG_H #include +#include "retroshare/rsposted.h" +#include "util/TokenQueue.h" namespace Ui { class PostedCreateCommentDialog; @@ -12,11 +14,18 @@ class PostedCreateCommentDialog : public QDialog Q_OBJECT public: - explicit PostedCreateCommentDialog(QWidget *parent = 0); + explicit PostedCreateCommentDialog(TokenQueue* tokQ, const RsGxsGrpMsgIdPair& parentId, const RsGxsMessageId& threadId, QWidget *parent = 0); ~PostedCreateCommentDialog(); +private slots: + + void createComment(); + private: Ui::PostedCreateCommentDialog *ui; + TokenQueue* mTokenQueue; + RsGxsGrpMsgIdPair mParentId; + RsGxsMessageId mThreadId; }; #endif // POSTEDCREATECOMMENTDIALOG_H diff --git a/retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.ui b/retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.ui index c35128f27..ddecc9214 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.ui +++ b/retroshare-gui/src/gui/Posted/PostedCreateCommentDialog.ui @@ -1,38 +1,49 @@ + - - - PostedCreateCommentDialog 0 0 - 400 - 300 + 372 + 145 - Dialog + Make Comment - - - - 30 - 240 - 341 - 32 - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Comment</span></p></body></html> + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + - diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.cpp b/retroshare-gui/src/gui/Posted/PostedDialog.cpp index 283969441..ba0c55432 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedDialog.cpp @@ -49,7 +49,7 @@ PostedDialog::PostedDialog(QWidget *parent) { ui.setupUi(this); - mPostedList = new PostedListDialog(NULL); + mPostedList = new PostedListDialog(this, NULL); mPostedComments = new PostedComments(NULL); QString list("List"); @@ -60,9 +60,10 @@ PostedDialog::PostedDialog(QWidget *parent) connect(mPostedList, SIGNAL(loadComments( std::string ) ), mPostedComments, SLOT(loadComments( std::string ) ) ); } -void PostedDialog::commentLoad(const RsGxsMessageId &msgId) +void PostedDialog::commentLoad(const RsPostedPost &post) { - mPostedComments->loadComments(msgId); + mPostedComments->loadComments(post); + ui.tabWidget->setCurrentWidget(mPostedComments); } diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.h b/retroshare-gui/src/gui/Posted/PostedDialog.h index 82210b913..4b491770d 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedDialog.h @@ -39,7 +39,7 @@ public: * This should be used for loading comments of a message on a main comment viewing page * @param msgId the message id for which comments will be requested */ - virtual void commentLoad(const RsGxsMessageId& msgId) = 0; + virtual void commentLoad(const RsPostedPost&) = 0; }; class PostedListDialog; @@ -51,7 +51,7 @@ class PostedDialog : public MainPage, public CommentHolder public: PostedDialog(QWidget *parent = 0); - void commentLoad(const RsGxsMessageId &msgId); + void commentLoad(const RsPostedPost &); private: diff --git a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp index 6004975c7..080447989 100644 --- a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp @@ -56,9 +56,10 @@ QString PostedGroupDialog::serviceHeader() return tr("Create New Posted Topic"); } + QPixmap PostedGroupDialog::serviceImage() { - return QPixmap(":/images/posted_add_64.png"); + return QPixmap(":/images/posted_add_64.png"); } bool PostedGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) diff --git a/retroshare-gui/src/gui/Posted/PostedItem.cpp b/retroshare-gui/src/gui/Posted/PostedItem.cpp index 3bfaceda3..449f54fc5 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.cpp +++ b/retroshare-gui/src/gui/Posted/PostedItem.cpp @@ -38,7 +38,7 @@ /** Constructor */ PostedItem::PostedItem(PostedHolder *postHolder, const RsPostedPost &post) -:QWidget(NULL), mPostHolder(postHolder) +:QWidget(NULL), mPostHolder(postHolder), mPost(post) { setupUi(this); setAttribute ( Qt::WA_DeleteOnClose, true ); @@ -71,5 +71,5 @@ void PostedItem::loadComments() { std::cerr << "PostedItem::loadComments() Requesting for " << mThreadId; std::cerr << std::endl; - mPostHolder->showComments(mPost.mMeta.mMsgId); + mPostHolder->showComments(mPost); } diff --git a/retroshare-gui/src/gui/Posted/PostedItem.h b/retroshare-gui/src/gui/Posted/PostedItem.h index 1c066f74d..6ed65ac9e 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.h +++ b/retroshare-gui/src/gui/Posted/PostedItem.h @@ -35,7 +35,7 @@ class PostedHolder { public: - virtual void showComments(const RsGxsMessageId& threadId) = 0; + virtual void showComments(const RsPostedPost& post) = 0; }; diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp index da542da71..059c356e6 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp @@ -106,9 +106,9 @@ void PostedListDialog::newPost() cp.exec(); } -void PostedListDialog::showComments(const RsGxsMessageId &threadId) +void PostedListDialog::showComments(const RsPostedPost& post) { - mCommentHolder->commentLoad(threadId); + mCommentHolder->commentLoad(post); } void PostedListDialog::updateDisplay() @@ -403,6 +403,7 @@ void PostedListDialog::loadRequest(const TokenQueue *queue, const TokenRequest & break; case RS_TOKREQ_ANSTYPE_SUMMARY: loadGroupSummary(req.mToken); + break; default: std::cerr << "Error, unexpected anstype:" << req.mAnsType << std::endl; break; diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.h b/retroshare-gui/src/gui/Posted/PostedListDialog.h index d4dc5f9f0..0f61aefc1 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.h @@ -24,6 +24,7 @@ #ifndef MRK_POSTED_LIST_DIALOG_H #define MRK_POSTED_LIST_DIALOG_H + #include "retroshare-gui/mainpage.h" #include "ui_PostedListDialog.h" @@ -58,7 +59,7 @@ class PostedListDialog : public RsAutoUpdatePage, public PostedHolder, public To public: PostedListDialog(CommentHolder* commentHolder, QWidget *parent = 0); - void showComments(const RsGxsMessageId &threadId); + void showComments(const RsPostedPost& post); private slots: diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp index ccd35b887..4f32e04e0 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp @@ -21,14 +21,16 @@ #include #include +#include #include "gui/gxs/GxsCommentTreeWidget.h" +#include "gui/Posted/PostedCreateCommentDialog.h" #include -#define PCITEM_COLUMN_DATE 0 -#define PCITEM_COLUMN_COMMENT 1 -#define PCITEM_COLUMN_AUTHOR 2 +#define PCITEM_COLUMN_COMMENT 0 +#define PCITEM_COLUMN_AUTHOR 1 +#define PCITEM_COLUMN_DATE 2 #define PCITEM_COLUMN_SERVSTRING 3 #define PCITEM_COLUMN_MSGID 4 #define PCITEM_COLUMN_PARENTID 5 @@ -38,54 +40,104 @@ // Temporarily make this specific. #include "retroshare/rsposted.h" +/* Images for context menu icons */ +#define IMAGE_MESSAGE ":/images/folder-draft.png" GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent) :QTreeWidget(parent), mRsService(NULL), mTokenQueue(NULL) { +// QTreeWidget* widget = this; +// QFont font = QFont("ARIAL", 10); +// font.setBold(true); + +// QString name("test"); +// QTreeWidgetItem *item = new QTreeWidgetItem(); +// item->setText(0, name); +// item->setFont(0, font); +// item->setSizeHint(0, QSize(18, 18)); +// item->setForeground(0, QBrush(QColor(79, 79, 79))); + +// addTopLevelItem(item); +// item->setExpanded(true); + return; } +void GxsCommentTreeWidget::setCurrentMsgId(QTreeWidgetItem *current, QTreeWidgetItem *previous) +{ + + Q_UNUSED(previous); + + if(current) + { + mCurrentMsgId = current->text(PCITEM_COLUMN_MSGID).toStdString(); + }else{ + mCurrentMsgId = ""; + } +} + +void GxsCommentTreeWidget::customPopUpMenu(const QPoint& point) +{ + QMenu contextMnu( this ); + contextMnu.addAction(QIcon(IMAGE_MESSAGE), tr("Submit Comment"), this, SLOT(makeComment())); + contextMnu.exec(QCursor::pos()); +} + +void GxsCommentTreeWidget::makeComment() +{ + + if(mCurrentMsgId.empty()) + { + PostedCreateCommentDialog pcc(mTokenQueue, mThreadId, mThreadId.second, this); + pcc.exec(); + } + else + { + RsGxsGrpMsgIdPair msgId; + msgId.first = mThreadId.first; + msgId.second = mCurrentMsgId; + PostedCreateCommentDialog pcc(mTokenQueue, msgId, mThreadId.second, this); + pcc.exec(); + } +} + void GxsCommentTreeWidget::setup(RsTokenService *service) { - mRsService = service; - mTokenQueue = new TokenQueue(service, this); + mRsService = service; + mTokenQueue = new TokenQueue(service, this); + connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customPopUpMenu(QPoint))); + connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(setCurrentMsgId(QTreeWidgetItem*, QTreeWidgetItem*))); - return; + return; } /* Load Comments */ -void GxsCommentTreeWidget::requestComments(std::string threadId) +void GxsCommentTreeWidget::requestComments(const RsGxsGrpMsgIdPair& threadId) { - /* request comments */ + /* request comments */ - service_requestComments(threadId); + mThreadId = threadId; + service_requestComments(threadId); } -void GxsCommentTreeWidget::service_requestComments(std::string threadId) +void GxsCommentTreeWidget::service_requestComments(const RsGxsGrpMsgIdPair& threadId) { /* request comments */ - //std::cerr << "GxsCommentTreeWidget::service_requestComments() ERROR must be overloaded!"; - //std::cerr << std::endl; - - std::cerr << "GxsCommentTreeWidget::service_requestComments(" << threadId << ")"; + std::cerr << "GxsCommentTreeWidget::service_requestComments(" << threadId.second << ")"; std::cerr << std::endl; RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; - opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; -// opts.mFlagsFilter = RSPOSTED_MSGTYPE_COMMENT; -// opts.mFlagsMask = RSPOSTED_MSGTYPE_COMMENT; - - std::list msgIds; + std::vector msgIds; msgIds.push_back(threadId); - - mThreadId = threadId; uint32_t token; -// mTokenQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, GXSCOMMENTS_LOADTHREAD); + mTokenQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, GXSCOMMENTS_LOADTHREAD); } @@ -138,7 +190,7 @@ void GxsCommentTreeWidget::completeItems() parent->addChild(pit->second); } - else if (parentId == mThreadId) + else if (parentId == mThreadId.second) { std::cerr << "GxsCommentTreeWidget::completeItems() Added to topLevelItems"; std::cerr << std::endl; @@ -206,64 +258,75 @@ void GxsCommentTreeWidget::loadThread(const uint32_t &token) completeItems(); } +void GxsCommentTreeWidget::acknowledgeComment(const uint32_t &token) +{ + RsGxsGrpMsgIdPair msgId; + rsPosted->acknowledgeMsg(token, msgId); + + // simply reload data + service_requestComments(mThreadId); +} + void GxsCommentTreeWidget::service_loadThread(const uint32_t &token) { - std::cerr << "GxsCommentTreeWidget::service_loadThread() ERROR must be overloaded!"; - std::cerr << std::endl; + std::cerr << "GxsCommentTreeWidget::service_loadThread() ERROR must be overloaded!"; + std::cerr << std::endl; -// RsPostedComment comment; -// while(rsPosted->getComment(token, comment)) -// { -// /* convert to a QTreeWidgetItem */ -// std::cerr << "GxsCommentTreeWidget::service_loadThread() Got Comment: " << comment; -// std::cerr << std::endl; - -// QTreeWidgetItem *item = new QTreeWidgetItem(); -// QString text; + PostedRelatedCommentResult commentResult; + rsPosted->getRelatedComment(token, commentResult); -// { -// QDateTime qtime; -// qtime.setTime_t(comment.mMeta.mPublishTs); - -// text = qtime.toString("yyyy-MM-dd hh:mm:ss"); -// item->setText(PCITEM_COLUMN_DATE, text); -// } - -// text = QString::fromUtf8(comment.mComment.c_str()); -// item->setText(PCITEM_COLUMN_COMMENT, text); - -// text = QString::fromUtf8(comment.mMeta.mAuthorId.c_str()); -// if (text.isEmpty()) -// { -// item->setText(PCITEM_COLUMN_AUTHOR, tr("Anonymous")); -// } -// else -// { -// item->setText(PCITEM_COLUMN_AUTHOR, text); -// } + std::vector& commentV = commentResult[mThreadId]; + std::vector::iterator vit = commentV.begin(); + for(; vit != commentV.end(); vit++) + { + RsPostedComment& comment = *vit; + /* convert to a QTreeWidgetItem */ + std::cerr << "GxsCommentTreeWidget::service_loadThread() Got Comment: " << comment.mMeta.mMsgId; + std::cerr << std::endl; -// text = QString::fromUtf8(comment.mMeta.mMsgId.c_str()); -// item->setText(PCITEM_COLUMN_MSGID, text); + QTreeWidgetItem *item = new QTreeWidgetItem(); + QString text; -// text = QString::fromUtf8(comment.mMeta.mParentId.c_str()); -// item->setText(PCITEM_COLUMN_PARENTID, text); + { + QDateTime qtime; + qtime.setTime_t(comment.mMeta.mPublishTs); -// text = QString::fromUtf8(comment.mMeta.mServiceString.c_str()); -// item->setText(PCITEM_COLUMN_SERVSTRING, text); + text = qtime.toString("yyyy-MM-dd hh:mm:ss"); + item->setText(PCITEM_COLUMN_DATE, text); + } -// addItem(comment.mMeta.mMsgId, comment.mMeta.mParentId, item); -// } + text = QString::fromUtf8(comment.mComment.c_str()); + item->setText(PCITEM_COLUMN_COMMENT, text); + + text = QString::fromUtf8(comment.mMeta.mAuthorId.c_str()); + if (text.isEmpty()) + { + item->setText(PCITEM_COLUMN_AUTHOR, tr("Anonymous")); + } + else + { + item->setText(PCITEM_COLUMN_AUTHOR, text); + } + + text = QString::fromUtf8(comment.mMeta.mMsgId.c_str()); + item->setText(PCITEM_COLUMN_MSGID, text); + + text = QString::fromUtf8(comment.mMeta.mParentId.c_str()); + item->setText(PCITEM_COLUMN_PARENTID, text); + + text = QString::fromUtf8(comment.mMeta.mServiceString.c_str()); + item->setText(PCITEM_COLUMN_SERVSTRING, text); + + addItem(comment.mMeta.mMsgId, comment.mMeta.mParentId, item); + } return; } -QTreeWidgetItem *GxsCommentTreeWidget::service_createMissingItem(std::string parent) +QTreeWidgetItem *GxsCommentTreeWidget::service_createMissingItem(const RsGxsMessageId& parent) { - //std::cerr << "GxsCommentTreeWidget::service_createMissingItem() ERROR must be overloaded!"; - //std::cerr << std::endl; - std::cerr << "GxsCommentTreeWidget::service_createMissingItem()"; std::cerr << std::endl; @@ -280,13 +343,14 @@ QTreeWidgetItem *GxsCommentTreeWidget::service_createMissingItem(std::string par item->setText(PCITEM_COLUMN_SERVSTRING, text); - text = QString::fromUtf8(parent.c_str()); + text = QString::fromUtf8(parent.c_str()); item->setText(PCITEM_COLUMN_PARENTID, text); return item; } + void GxsCommentTreeWidget::loadRequest(const TokenQueue *queue, const TokenRequest &req) { std::cerr << "GxsCommentTreeWidget::loadRequest() UserType: " << req.mUserType; @@ -300,74 +364,26 @@ void GxsCommentTreeWidget::loadRequest(const TokenQueue *queue, const TokenReque } /* now switch on req */ - switch(req.mUserType) + switch(req.mType) { - case GXSCOMMENTS_LOADTHREAD: - loadThread(req.mToken); - break; - default: - std::cerr << "GxsCommentTreeWidget::loadRequest() UNKNOWN UserType "; - std::cerr << std::endl; - break; + case TOKENREQ_MSGINFO: + { + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgeComment(req.mToken); + break; + case RS_TOKREQ_ANSTYPE_DATA: + loadThread(req.mToken); + break; + } + } + break; + default: + std::cerr << "GxsCommentTreeWidget::loadRequest() UNKNOWN UserType "; + std::cerr << std::endl; + break; + } } - - - -#if 0 - - -QMimeData * GxsCommentTreeWidget::mimeData ( const QList items ) const -{ - /* extract from each QTreeWidgetItem... all the member text */ - QList::const_iterator it; - QString text; - for(it = items.begin(); it != items.end(); it++) - { - QString line = QString("%1/%2/%3/").arg((*it)->text(SR_NAME_COL), (*it)->text(SR_HASH_COL), (*it)->text(SR_SIZE_COL)); - - bool isLocal = (*it)->data(SR_DATA_COL, SR_ROLE_LOCAL).toBool(); - if (isLocal) - { - line += "Local"; - } - else - { - line += "Remote"; - } - line += "/\n"; - - text += line; - } - - std::cerr << "Created MimeData:"; - std::cerr << std::endl; - - std::string str = text.toUtf8().constData(); - std::cerr << str; - std::cerr << std::endl; - - QMimeData *data = new QMimeData(); - data->setData("application/x-rsfilelist", QByteArray(str.c_str())); - - return data; -} - - - -QStringList GxsCommentTreeWidget::mimeTypes () const -{ - QStringList list; - list.push_back("application/x-rsfilelist"); - - return list; -} - - -Qt::DropActions GxsCommentTreeWidget::supportedDropActions () const -{ - return Qt::CopyAction; -} - -#endif diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h index 87859d8ba..448c2e324 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h @@ -44,42 +44,48 @@ class GxsCommentTreeWidget : public QTreeWidget, public TokenResponse Q_OBJECT public: - GxsCommentTreeWidget(QWidget *parent = 0); - void setup(RsTokenService *service); + GxsCommentTreeWidget(QWidget *parent = 0); + void setup(RsTokenService *service); - void requestComments(std::string threadId); + void requestComments(const RsGxsGrpMsgIdPair& threadId); + void getCurrentMsgId(RsGxsMessageId& parentId); + void setCurrentMsgId(QTreeWidgetItem* current, QTreeWidgetItem* previous); - void loadRequest(const TokenQueue *queue, const TokenRequest &req); + void loadRequest(const TokenQueue *queue, const TokenRequest &req); protected: - /* to be overloaded */ - virtual void service_requestComments(std::string threadId); - virtual void service_loadThread(const uint32_t &token); - virtual QTreeWidgetItem *service_createMissingItem(std::string parent); + /* to be overloaded */ + virtual void service_requestComments(const RsGxsGrpMsgIdPair& threadId); + virtual void service_loadThread(const uint32_t &token); + virtual QTreeWidgetItem *service_createMissingItem(const RsGxsMessageId& parent); - void clearItems(); - void completeItems(); + void clearItems(); + void completeItems(); - void loadThread(const uint32_t &token); - - void addItem(std::string itemId, std::string parentId, QTreeWidgetItem *item); + void acknowledgeComment(const uint32_t& token); + void loadThread(const uint32_t &token); + + void addItem(std::string itemId, std::string parentId, QTreeWidgetItem *item); + +public slots: + void customPopUpMenu(const QPoint& point); +private slots: + void makeComment(); - /* Data */ - std::string mThreadId; +protected: - std::map mLoadingMap; - std::multimap mPendingInsertMap; + /* Data */ + RsGxsGrpMsgIdPair mThreadId; + RsGxsMessageId mCurrentMsgId; - TokenQueue *mTokenQueue; - RsTokenService *mRsService; + std::map mLoadingMap; + std::multimap mPendingInsertMap; - protected: -//virtual QMimeData * mimeData ( const QList items ) const; -//virtual QStringList mimeTypes () const; -//virtual Qt::DropActions supportedDropActions () const; + TokenQueue *mTokenQueue; + RsTokenService *mRsService; }; From 6fba39505424e3ee6e69e7488de108bc0e46cc05 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Sun, 25 Nov 2012 23:44:51 +0000 Subject: [PATCH 179/222] Source code maintenance git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5897 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/util/TokenQueue.cpp | 89 ++++++++++---------------- retroshare-gui/src/util/TokenQueue.h | 54 ++++++++-------- 2 files changed, 60 insertions(+), 83 deletions(-) diff --git a/retroshare-gui/src/util/TokenQueue.cpp b/retroshare-gui/src/util/TokenQueue.cpp index 9184926e0..43b3b419d 100644 --- a/retroshare-gui/src/util/TokenQueue.cpp +++ b/retroshare-gui/src/util/TokenQueue.cpp @@ -26,16 +26,14 @@ #include - /****** * #define ID_DEBUG 1 *****/ /** Constructor */ TokenQueue::TokenQueue(RsTokenService *service, TokenResponse *resp) -:QWidget(NULL), mService(service), mResponder(resp) + : QWidget(NULL), mService(service), mResponder(resp) { - return; } bool TokenQueue::requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, std::list& ids, uint32_t usertype) @@ -47,14 +45,13 @@ bool TokenQueue::requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTok return true; } - bool TokenQueue::requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, uint32_t usertype) { - uint32_t basictype = TOKENREQ_GROUPINFO; - mService->requestGroupInfo(token, anstype, opts); - queueRequest(token, basictype, anstype, usertype); + uint32_t basictype = TOKENREQ_GROUPINFO; + mService->requestGroupInfo(token, anstype, opts); + queueRequest(token, basictype, anstype, usertype); - return true; + return true; } bool TokenQueue::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, const GxsMsgReq& ids, uint32_t usertype) @@ -66,35 +63,33 @@ bool TokenQueue::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokRe return true; } - bool TokenQueue::requestMsgRelatedInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, const std::vector &msgId, uint32_t usertype) { - uint32_t basictype = TOKENREQ_MSGINFO; - mService->requestMsgRelatedInfo(token, anstype, opts, msgId); - queueRequest(token, basictype, anstype, usertype); + uint32_t basictype = TOKENREQ_MSGINFO; + mService->requestMsgRelatedInfo(token, anstype, opts, msgId); + queueRequest(token, basictype, anstype, usertype); - return true; + return true; } - bool TokenQueue::requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, - const std::list &grpIds, uint32_t usertype) + const std::list &grpIds, uint32_t usertype) { - uint32_t basictype = TOKENREQ_MSGINFO; - mService->requestMsgInfo(token, anstype, opts, grpIds); - queueRequest(token, basictype, anstype, usertype); + uint32_t basictype = TOKENREQ_MSGINFO; + mService->requestMsgInfo(token, anstype, opts, grpIds); + queueRequest(token, basictype, anstype, usertype); - return true; + return true; } void TokenQueue::queueRequest(uint32_t token, uint32_t basictype, uint32_t anstype, uint32_t usertype) { - std::cerr << "TokenQueue::queueRequest() Token: " << token << " Type: " << basictype; + std::cerr << "TokenQueue::queueRequest() Token: " << token << " Type: " << basictype; std::cerr << " AnsType: " << anstype << " UserType: " << usertype; std::cerr << std::endl; - TokenRequest req; + TokenRequest req; req.mToken = token; req.mType = basictype; req.mAnsType = anstype; @@ -103,7 +98,7 @@ void TokenQueue::queueRequest(uint32_t token, uint32_t basictype, uint32_t ansty gettimeofday(&req.mRequestTs, NULL); req.mPollTs = req.mRequestTs; - mRequests.push_back(req); + mRequests.push_back(req); if (mRequests.size() == 1) { @@ -119,26 +114,23 @@ void TokenQueue::doPoll(float dt) QTimer::singleShot((int) (dt * 1000.0), this, SLOT(pollRequests())); } - void TokenQueue::pollRequests() { double pollPeriod = 1.0; // max poll period. - - if (mRequests.empty()) - { + if (mRequests.empty()) { return; } - TokenRequest req; - req = mRequests.front(); - mRequests.pop_front(); + TokenRequest req; + req = mRequests.front(); + mRequests.pop_front(); - if (checkForRequest(req.mToken)) - { - /* clean it up and handle */ - loadRequest(req); - } + if (checkForRequest(req.mToken)) + { + /* clean it up and handle */ + loadRequest(req); + } else { @@ -147,15 +139,14 @@ void TokenQueue::pollRequests() /* drop old requests too */ if (time(NULL) - req.mRequestTs.tv_sec < MAX_REQUEST_AGE) { - mRequests.push_back(req); + mRequests.push_back(req); } else { - std::cerr << "TokenQueue::loadRequest(): "; + std::cerr << "TokenQueue::loadRequest(): "; std::cerr << "Dropping old Token: " << req.mToken << " Type: " << req.mType; std::cerr << std::endl; } - } if (mRequests.size() > 0) @@ -164,35 +155,31 @@ void TokenQueue::pollRequests() } } - bool TokenQueue::checkForRequest(uint32_t token) { /* check token */ - uint32_t status = mService->requestStatus(token); - return ( (RsTokenService::GXS_REQUEST_V2_STATUS_FAILED == status) || - (RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE == status) ); + uint32_t status = mService->requestStatus(token); + return ( (RsTokenService::GXS_REQUEST_V2_STATUS_FAILED == status) || + (RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE == status) ); } void TokenQueue::loadRequest(const TokenRequest &req) { - std::cerr << "TokenQueue::loadRequest(): "; + std::cerr << "TokenQueue::loadRequest(): "; std::cerr << "Token: " << req.mToken << " Type: " << req.mType; std::cerr << " AnsType: " << req.mAnsType << " UserType: " << req.mUserType; std::cerr << std::endl; mResponder->loadRequest(this, req); - - return; } - bool TokenQueue::cancelRequest(const uint32_t token) { /* cancel at lower level first */ mService->cancelRequest(token); - std::list::iterator it; + std::list::iterator it; for(it = mRequests.begin(); it != mRequests.end(); it++) { @@ -200,21 +187,15 @@ bool TokenQueue::cancelRequest(const uint32_t token) { mRequests.erase(it); - std::cerr << "TokenQueue::cancelRequest() Cleared Request: " << token; + std::cerr << "TokenQueue::cancelRequest() Cleared Request: " << token; std::cerr << std::endl; return true; } } - std::cerr << "TokenQueue::cancelRequest() Failed to Find Request: " << token; + std::cerr << "TokenQueue::cancelRequest() Failed to Find Request: " << token; std::cerr << std::endl; return false; } - - - - - - diff --git a/retroshare-gui/src/util/TokenQueue.h b/retroshare-gui/src/util/TokenQueue.h index 2bffd6d44..f69b81d37 100644 --- a/retroshare-gui/src/util/TokenQueue.h +++ b/retroshare-gui/src/util/TokenQueue.h @@ -33,11 +33,10 @@ #include +#define COMPLETED_REQUEST 4 -#define COMPLETED_REQUEST 4 - -#define TOKENREQ_GROUPINFO 1 -#define TOKENREQ_MSGINFO 2 +#define TOKENREQ_GROUPINFO 1 +#define TOKENREQ_MSGINFO 2 #define TOKENREQ_MSGRELATEDINFO 3 @@ -45,7 +44,7 @@ class TokenQueue; class TokenRequest { - public: +public: uint32_t mToken; uint32_t mType; uint32_t mAnsType; @@ -56,10 +55,10 @@ class TokenRequest class TokenResponse { - public: +public: //virtual ~TokenResponse() { return; } // These Functions are overloaded to get results out. - virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req) = 0; + virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req) = 0; }; @@ -69,37 +68,36 @@ class TokenResponse */ class TokenQueue: public QWidget { - Q_OBJECT + Q_OBJECT public: - TokenQueue(RsTokenService *service, TokenResponse *resp); + TokenQueue(RsTokenService *service, TokenResponse *resp); /* generic handling of token / response update behaviour */ - /*! - * - * @token the token to be redeem is assigned here - * - */ - bool requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, - std::list& ids, uint32_t usertype); + /*! + * + * @token the token to be redeem is assigned here + * + */ + bool requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, + std::list& ids, uint32_t usertype); + bool requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, uint32_t usertype); - bool requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, uint32_t usertype); + bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, + const std::list& grpIds, uint32_t usertype); - bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, - const std::list& grpIds, uint32_t usertype); + bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, + const GxsMsgReq& grpIds, uint32_t usertype); - bool requestMsgInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, - const GxsMsgReq& grpIds, uint32_t usertype); - - bool requestMsgRelatedInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, const std::vector& msgId, uint32_t usertype); + bool requestMsgRelatedInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, const std::vector& msgId, uint32_t usertype); bool cancelRequest(const uint32_t token); void queueRequest(uint32_t token, uint32_t basictype, uint32_t anstype, uint32_t usertype); bool checkForRequest(uint32_t token); - void loadRequest(const TokenRequest &req); + void loadRequest(const TokenRequest &req); protected: void doPoll(float dt); @@ -109,14 +107,12 @@ private slots: private: /* Info for Data Requests */ - std::list mRequests; + std::list mRequests; - RsTokenService *mService; - TokenResponse *mResponder; + RsTokenService *mService; + TokenResponse *mResponder; QTimer *mTrigger; }; #endif - - From bf46905d6a359afb9b8bc585f23c873901ec82c8 Mon Sep 17 00:00:00 2001 From: defnax Date: Mon, 26 Nov 2012 12:19:04 +0000 Subject: [PATCH 180/222] fixed layout, to have a better look git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5898 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/gui/PhotoShare/AlbumCreateDialog.ui | 277 +++++++++--------- 1 file changed, 146 insertions(+), 131 deletions(-) diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui index 52a285a90..e95cca12f 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumCreateDialog.ui @@ -43,95 +43,31 @@ - QFrame::StyledPanel + QFrame::NoFrame - - QFrame::Raised - - - - - - - - - - Album Name: - - - - - - - - - - Category: - - - - - - - - Animals - - - - - Family - - - - - Friends - - - - - Flowers - - - - - Holiday - - - - - Landcapes - - - - - Pets - - - - - Portraits - - - - - Travel - - - - - Work - - - - - Random - - - - - + + + 0 + + + 6 + + + + + 3 + + + + + Album Name: + + - + + + + @@ -166,58 +102,113 @@ border-radius: 10px; - - - - - - Qt::Horizontal - - - - - - + + + + Category: + + + + + + + + Animals + + + + + Family + + + + + Friends + + + + + Flowers + + + + + Holiday + + + + + Landcapes + + + + + Pets + + + + + Portraits + + + + + Travel + + + + + Work + + + + + Random + + + + + Caption: - + - - - - Description: - - - - - - - - - - - - - Photographer: - - - - - - - + Where: - + + + + + + + Photographer: + + + + + + + + + + Description: + + + + + + + Qt::Vertical @@ -230,16 +221,23 @@ border-radius: 10px; + + + + Qt::Horizontal + + + - + Qt::Horizontal - + @@ -433,8 +431,8 @@ p, li { white-space: pre-wrap; } 0 0 - 98 - 28 + 621 + 458 @@ -451,7 +449,7 @@ p, li { white-space: pre-wrap; } - + 9 @@ -520,5 +518,22 @@ p, li { white-space: pre-wrap; } - + + + buttonBox + rejected() + AlbumCreateDialog + close() + + + 353 + 529 + + + 321 + 274 + + + + From 1eaf10dc787a8b920d0340bafc7691fea1d59c87 Mon Sep 17 00:00:00 2001 From: defnax Date: Mon, 26 Nov 2012 15:26:47 +0000 Subject: [PATCH 181/222] Added a titlebar frame to PostedDialog git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5899 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/Posted/PostedDialog.ui | 65 ++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.ui b/retroshare-gui/src/gui/Posted/PostedDialog.ui index fef6921dd..757f2f61b 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.ui +++ b/retroshare-gui/src/gui/Posted/PostedDialog.ui @@ -11,6 +11,67 @@ + + 1 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + + + + 24 + 24 + + + + + + + :/images/posted_24.png + + + + + + + + 10 + 75 + true + + + + Posted Links + + + + + + + Qt::Horizontal + + + + 573 + 20 + + + + + + + @@ -20,6 +81,8 @@ - + + + From 6a063ff32d84d60c105c949a609bdb16c5feb564 Mon Sep 17 00:00:00 2001 From: defnax Date: Mon, 26 Nov 2012 16:53:40 +0000 Subject: [PATCH 182/222] set window title for Edit/Create Wiki Page git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5900 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp index 3c66b73b9..6422c7a76 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp @@ -76,7 +76,8 @@ void WikiEditDialog::setNewPage() ui.textEdit->setPlainText(""); ui.headerFrame->setHeaderImage(QPixmap(":/images/appointment-new_64.png")); - ui.headerFrame->setHeaderText(tr("Create New Wiki Page")); + ui.headerFrame->setHeaderText(tr("Create New Wiki Page")); + setWindowTitle(tr("Create New Wiki Page")); } @@ -205,7 +206,8 @@ void WikiEditDialog::setupData(const std::string &groupId, const std::string &pa ui.headerFrame->setHeaderImage(QPixmap(":/images/story-editor_48.png")); - ui.headerFrame->setHeaderText(tr("Edit Wiki Page")); + ui.headerFrame->setHeaderText(tr("Edit Wiki Page")); + setWindowTitle(tr("Edit Wiki Page")); } From 78bc0a45676d7a6dc17341fc8a5671a852fa0e4c Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 26 Nov 2012 22:53:44 +0000 Subject: [PATCH 183/222] * Cleaned up lots of old VEG services. - left the code for p3gxsserviceVEG and p3postedVEG, until p3posted is finished. * Converted p3wireVEG => p3wire * cleaned up rsinit.cc and libretroshare.pro git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5901 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/libretroshare.pro | 57 +- libretroshare/src/retroshare/rsforumsVEG.h | 106 -- libretroshare/src/retroshare/rsidentityVEG.h | 534 ------ libretroshare/src/retroshare/rswikiVEG.h | 106 -- .../src/retroshare/{rswireVEG.h => rswire.h} | 70 +- libretroshare/src/rsserver/rsinit.cc | 58 +- libretroshare/src/serialiser/rswikiitems.cc | 6 +- libretroshare/src/serialiser/rswikiitems.h | 2 +- libretroshare/src/serialiser/rswireitems.cc | 408 +++++ libretroshare/src/serialiser/rswireitems.h | 93 + libretroshare/src/services/p3forumsVEG.cc | 805 --------- libretroshare/src/services/p3forumsVEG.h | 126 -- libretroshare/src/services/p3idserviceVEG.cc | 1552 ----------------- libretroshare/src/services/p3idserviceVEG.h | 186 -- libretroshare/src/services/p3wiki.cc | 2 +- libretroshare/src/services/p3wiki.h | 2 +- .../src/services/p3wikiserviceVEG.cc | 595 ------- libretroshare/src/services/p3wikiserviceVEG.h | 129 -- libretroshare/src/services/p3wire.cc | 207 +++ libretroshare/src/services/p3wire.h | 71 + libretroshare/src/services/p3wireVEG.cc | 939 ---------- libretroshare/src/services/p3wireVEG.h | 120 -- 22 files changed, 859 insertions(+), 5315 deletions(-) delete mode 100644 libretroshare/src/retroshare/rsforumsVEG.h delete mode 100644 libretroshare/src/retroshare/rsidentityVEG.h delete mode 100644 libretroshare/src/retroshare/rswikiVEG.h rename libretroshare/src/retroshare/{rswireVEG.h => rswire.h} (62%) create mode 100644 libretroshare/src/serialiser/rswireitems.cc create mode 100644 libretroshare/src/serialiser/rswireitems.h delete mode 100644 libretroshare/src/services/p3forumsVEG.cc delete mode 100644 libretroshare/src/services/p3forumsVEG.h delete mode 100644 libretroshare/src/services/p3idserviceVEG.cc delete mode 100644 libretroshare/src/services/p3idserviceVEG.h delete mode 100644 libretroshare/src/services/p3wikiserviceVEG.cc delete mode 100644 libretroshare/src/services/p3wikiserviceVEG.h create mode 100644 libretroshare/src/services/p3wire.cc create mode 100644 libretroshare/src/services/p3wire.h delete mode 100644 libretroshare/src/services/p3wireVEG.cc delete mode 100644 libretroshare/src/services/p3wireVEG.h diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 4c3ed995e..62c97a810 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -137,16 +137,15 @@ PUBLIC_HEADERS = retroshare/rsblogs.h \ retroshare/rstypes.h \ retroshare/rsdht.h \ retroshare/rsdsdv.h \ - retroshare/rsconfig.h \ - retroshare/rsphotoV2.h + retroshare/rsconfig.h + HEADERS += plugins/pluginmanager.h \ plugins/dlfcn_win32.h \ serialiser/rspluginitems.h HEADERS += $$PUBLIC_HEADERS # public headers to be... -HEADERS += retroshare/rsgame.h \ - retroshare/rsphoto.h +HEADERS += retroshare/rsgame.h # ################################ Linux ########################################## linux-* { @@ -610,16 +609,12 @@ HEADERS += retroshare/rsgame.h \ gxs/rsgxsdataaccess.h \ retroshare/rsgxsservice.h \ serialiser/rsgxsitems.h \ - serialiser/rsphotov2items.h \ util/retrodb.h \ util/contentvalue.h \ gxs/gxscoreserver.h \ gxs/gxssecurity.h \ gxs/rsgxsifaceimpl.h \ gxs/gxstokenqueue.h \ - services/p3posted.h \ - retroshare/rsposted.h \ - serialiser/rsposteditems.h SOURCES += serialiser/rsnxsitems.cc \ @@ -628,17 +623,13 @@ HEADERS += retroshare/rsgame.h \ gxs/rsgxsnetservice.cc \ gxs/rsgxsdata.cc \ serialiser/rsgxsitems.cc \ - services/p3photoserviceV2.cc \ gxs/rsgxsdataaccess.cc \ - serialiser/rsphotov2items.cc \ util/retrodb.cc \ util/contentvalue.cc \ gxs/gxscoreserver.cc \ gxs/gxssecurity.cc \ gxs/rsgxsifaceimpl.cc \ gxs/gxstokenqueue.cc \ - services/p3posted.cc \ - serialiser/rsposteditems.cc # Identity Service HEADERS += retroshare/rsidentity.h \ @@ -665,26 +656,34 @@ HEADERS += retroshare/rsgame.h \ SOURCES += services/p3wiki.cc \ serialiser/rswikiitems.cc \ + # Wiki Service + HEADERS += retroshare/rswire.h \ + services/p3wire.h \ + serialiser/rswireitems.h + + SOURCES += services/p3wire.cc \ + serialiser/rswireitems.cc \ + + # Posted Service + HEADERS += services/p3posted.h \ + retroshare/rsposted.h \ + serialiser/rsposteditems.h + + SOURCES += services/p3posted.cc \ + serialiser/rsposteditems.cc + + #Photo Service + HEADERS += services/p3photoservice.h \ + retroshare/rsphoto.h \ + serialiser/rsphotoitems.h \ + + SOURCES += services/p3photoservice.cc \ + serialiser/rsphotoitems.cc \ } newservices { - HEADERS += services/p3photoserviceV2.h \ - retroshare/rsphotoVEG.h \ - services/p3gxsserviceVEG.h \ - services/p3wikiserviceVEG.h \ - retroshare/rswikiVEG.h \ - retroshare/rswireVEG.h \ - services/p3wireVEG.h \ - retroshare/rsforumsVEG.h \ - services/p3forumsVEG.h - # Do I need this? - #serialiser/rsphotoitemsVEG.h \ + # source code for p3gxsserviceVEG / p3postedVEG will be maintained + # until they are finished - for reference... but it wont compile. - SOURCES += services/p3gxsserviceVEG.cc \ - services/p3wikiserviceVEG.cc \ - services/p3wireVEG.cc \ - services/p3forumsVEG.cc - # Do I need this? - # serialiser/rsphotoitemsVEG.cc \ } diff --git a/libretroshare/src/retroshare/rsforumsVEG.h b/libretroshare/src/retroshare/rsforumsVEG.h deleted file mode 100644 index 1f12377cc..000000000 --- a/libretroshare/src/retroshare/rsforumsVEG.h +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef RETROSHARE_FORUMV2_GUI_INTERFACE_H -#define RETROSHARE_FORUMV2_GUI_INTERFACE_H - -/* - * libretroshare/src/retroshare: rsforumv2.h - * - * RetroShare C++ Interface. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include -#include -#include - -#include - -/* The Main Interface Class - for information about your Peers */ -class RsForumsVEG; -extern RsForumsVEG *rsForumsVEG; - -class RsForumV2Group -{ - public: - - // All the MetaData is Stored here: - RsGroupMetaData mMeta; - - // THESE ARE IN THE META DATA. - //std::string mGroupId; - //std::string mName; - - std::string mDescription; - - // THESE ARE CURRENTLY UNUSED. - //std::string mCategory; - //std::string mHashTags; -}; - -class RsForumV2Msg -{ - public: - - // All the MetaData is Stored here: - RsMsgMetaData mMeta; - - // THESE ARE IN THE META DATA. - //std::string mGroupId; - //std::string mMsgId; - //std::string mOrigMsgId; - //std::string mThreadId; - //std::string mParentId; - //std::string mName; (aka. Title) - - std::string mMsg; // all the text is stored here. - - // THESE ARE CURRENTLY UNUSED. - //std::string mHashTags; -}; - -class RsForumsVEG: public RsTokenServiceVEG -{ - public: - - RsForumsVEG() { return; } -virtual ~RsForumsVEG() { return; } - - /* Specific Service Data */ -virtual bool getGroupData(const uint32_t &token, RsForumV2Group &group) = 0; -virtual bool getMsgData(const uint32_t &token, RsForumV2Msg &msg) = 0; - - - // ONES THAT WE ARE NOT IMPLEMENTING. (YET!) -//virtual bool getMessageStatus(const std::string& fId, const std::string& mId, uint32_t& status) = 0; - -// THINK WE CAN GENERALISE THIS TO: a list function, and you can just count the list entries... -// requestGroupList(groupId, UNREAD, ...) -//virtual bool getMessageCount(const std::string &groupId, unsigned int &newCount, unsigned int &unreadCount) = 0; - - -/* details are updated in group - to choose GroupID */ -virtual bool createGroup(uint32_t &token, RsForumV2Group &group, bool isNew) = 0; -virtual bool createMsg(uint32_t &token, RsForumV2Msg &msg, bool isNew) = 0; - -}; - - - -#endif diff --git a/libretroshare/src/retroshare/rsidentityVEG.h b/libretroshare/src/retroshare/rsidentityVEG.h deleted file mode 100644 index 6cb50fc42..000000000 --- a/libretroshare/src/retroshare/rsidentityVEG.h +++ /dev/null @@ -1,534 +0,0 @@ -#ifndef RETROSHARE_IDENTITY_GUI_VEG_INTERFACE_H -#define RETROSHARE_IDENTITY_GUI_VEG_INTERFACE_H - -/* - * libretroshare/src/retroshare: rsidentity.h - * - * RetroShare C++ Interface. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include -#include -#include - -// FLAGS WILL BE REUSED FROM RSDISTRIB -> FOR NOW. -#include - -/********** Generic Token Request Interface *********************** - * This is packaged here, as most TokenServices will require ID Services too. - * The requests can be generic, but the reponses are service specific (dependent on data types). - */ - -// This bit will be filled out over time. -#define RS_TOKREQOPT_MSG_VERSIONS 0x0001 // MSGRELATED: Returns All MsgIds with OrigMsgId = MsgId. -#define RS_TOKREQOPT_MSG_ORIGMSG 0x0002 // MSGLIST: All Unique OrigMsgIds in a Group. -#define RS_TOKREQOPT_MSG_LATEST 0x0004 // MSGLIST: All Latest MsgIds in Group. MSGRELATED: Latest MsgIds for Input Msgs. - -#define RS_TOKREQOPT_MSG_THREAD 0x0010 // MSGRELATED: All Msgs in Thread. MSGLIST: All Unique Thread Ids in Group. -#define RS_TOKREQOPT_MSG_PARENT 0x0020 // MSGRELATED: All Children Msgs. - -#define RS_TOKREQOPT_MSG_AUTHOR 0x0040 // MSGLIST: Messages from this AuthorId - - -// Status Filtering... should it be a different Option Field. -#define RS_TOKREQOPT_GROUP_UPDATED 0x0100 // GROUPLIST: Groups that have been updated. -#define RS_TOKREQOPT_MSG_UPDATED 0x0200 // MSGLIST: Msg that have been updated from specified groups. -#define RS_TOKREQOPT_MSG_UPDATED 0x0200 // MSGLIST: Msg that have been updated from specified groups. - - - -// Read Status. -#define RS_TOKREQOPT_READ 0x0001 -#define RS_TOKREQOPT_UNREAD 0x0002 - -#define RS_TOKREQ_ANSTYPE_LIST 0x0001 -#define RS_TOKREQ_ANSTYPE_SUMMARY 0x0002 -#define RS_TOKREQ_ANSTYPE_DATA 0x0003 - - - -class RsTokReqOptionsVEG -{ - public: - RsTokReqOptionsVEG() - { - mOptions = 0; - mStatusFilter = 0; mStatusMask = 0; - mFlagsFilter = 0; mFlagsMask = 0; - mSubscribeFilter = 0; - mBefore = 0; mAfter = 0; - } - - uint32_t mOptions; - - // Request specific matches with Group / Message Status. - // Should be usable with any Options... applied afterwards. - uint32_t mStatusFilter; - uint32_t mStatusMask; - - // MsgFlags or GroupsFlags, depends on Request. - uint32_t mFlagsFilter; - uint32_t mFlagsMask; - - uint32_t mSubscribeFilter; // Only for Groups. - - // Time range... again applied after Options. - time_t mBefore; - time_t mAfter; -}; - - -/********************************************************* - * Documentation for Groups Definitions. - * - * A Group is defined by: - * - TWO RSA Keys. (Admin Key & Publish Key) - * - Publish TS: Used to select the latest definition. - * - * - Operating Mode: - * - Circle (Public, External, Private). - * - Publish Mode: Encrypted / All-Signed / Only ThreadHead / None Required. - * - AuthorId: GPG Required / Any Required / Only if no Publish Signature. - * - * - Description: - * - Name & Description. - * - Optional AuthorId. - * - * Most of this information is contained inside the GroupMetaData. - * except for Actual Admin / Publish Keys, which are maintained internally. - * - ******* - * - Group Definition must be signed by Admin Key, otherwise invalid. - * - Circle Definition controls distribution of Group and Messages, see section on this for more details. - * - Public parts of Keys are distributed with Definition. - * - Private parts can be distributed to select people via alternative channels. - * - A Message Requires at least one signature: publish or Author. This signature will be used as MsgId. - * - * Groups will operate in the following modes: - * 1) Public Forum: PublishMode = None Required, AuthorId: Required. - * 2) Closed Forum: PublishMode = All-Signed, AuthorId: Required. - * 3) Private Forum: PublishMode = Encrypted, AuthorId: Required. - * - * 4) Anon Channel: PublishMode = All-Signed, AuthorId: None. - * 5) Anon Channel with Comments: PublishMode = Only ThreadHead, AuthorId: If No Publish Signature. - * 6) Private Channel: PublishMode = Encrypted. - * - * 7) Personal Photos - with comments: PublishMode = Only ThreadHead, AuthorId: Required. - * 8) Personal Photos - no comments: PublishMode = All-Signed, AuthorId: Required. - * - * 9 ) Public Wiki: PublishMode = None Required, AuthorId: Required. - * 10) Closed Wiki: PublishMode = All-Signed, AuthorId: Required. - * 11) Private Wiki: PublishMode = Encrypted, AuthorId: Required. - * - * 12) Twitter: PublishMode = Only ThreadHead, AuthorId: Required. - * - * 13) Posted: PublishMode = None Required, AuthorId: Required. - * - * - ****** - * - * Additionally to this information. The MetaData also contains several fields which can - * be used to store local information for the benefit of the service. - * - * In Particular: MsgStatus & GroupStatus inform the service if the user has read the message or if anything has changed. - * - ***/ - - -// Control of Publish Signatures. -#define RSGXS_GROUP_SIGN_PUBLISH_MASK 0x000000ff -#define RSGXS_GROUP_SIGN_PUBLISH_ENCRYPTED 0x00000001 -#define RSGXS_GROUP_SIGN_PUBLISH_ALLSIGNED 0x00000002 -#define RSGXS_GROUP_SIGN_PUBLISH_THREADHEAD 0x00000004 -#define RSGXS_GROUP_SIGN_PUBLISH_NONEREQ 0x00000008 - -// Author Signature. -#define RSGXS_GROUP_SIGN_AUTHOR_MASK 0x0000ff00 -#define RSGXS_GROUP_SIGN_AUTHOR_GPG 0x00000100 -#define RSGXS_GROUP_SIGN_AUTHOR_REQUIRED 0x00000200 -#define RSGXS_GROUP_SIGN_AUTHOR_IFNOPUBSIGN 0x00000400 -#define RSGXS_GROUP_SIGN_AUTHOR_NONE 0x00000800 - -// NB: That one signature is required... -// so some combinations are not possible. e.g. -// SIGN_PUBLISH_NONEREQ && SIGN_AUTHOR_NONE is not allowed. -// SIGN_PUBLISH_THREADHEAD && SIGN_AUTHOR_NONE is also invalid. - -#define RSGXS_GROUP_SIGN_RESERVED_MASK 0xffff0000 - - -// STATUS FLAGS: There is space here for Service specific flags - if they so desire. -// -// Msgs: UNREAD_BY_USER & PROCESSED are useful. -// Groups: NEW_MESSAGES & GROUP_UPDATED. - -#define RSGXS_MSG_STATUS_MASK 0x0000000f -#define RSGXS_MSG_STATUS_READ 0x00000001 // New or Not New -#define RSGXS_MSG_STATUS_UNREAD_BY_USER 0x00000002 -#define RSGXS_MSG_STATUS_UNPROCESSED 0x00000004 // By the Service. - -#define RSGXS_MSG_STATUS_SERVICE_MASK 0xffff0000 - -#define RSGXS_GROUP_STATUS_MASK 0x0000000f -#define RSGXS_GROUP_STATUS_UPDATED 0x00000001 -#define RSGXS_GROUP_STATUS_NEWGROUP 0x00000002 -#define RSGXS_GROUP_STATUS_NEWMSG 0x00000004 - -#define RSGXS_GROUP_STATUS_SERVICE_MASK 0xffff0000 - - - -// Subscription Flags. (LOCAL) -#define RSGXS_GROUP_SUBSCRIBE_MASK 0x0000000f -#define RSGXS_GROUP_SUBSCRIBE_ADMIN 0x00000001 -#define RSGXS_GROUP_SUBSCRIBE_PUBLISH 0x00000002 -#define RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED 0x00000004 -#define RSGXS_GROUP_SUBSCRIBE_MONITOR 0x00000008 - - -// Some MACROS for EASE OF USE. (USED BY FORUMSV2 At the moment. -// MOVED TO REAL GXS STUFF -//#define IS_MSG_UNREAD(status) ((status & RSGXS_MSG_STATUS_READ) == 0 || (status & RSGXS_MSG_STATUS_UNREAD_BY_USER)) -//#define IS_GROUP_ADMIN(subscribeFlags) (subscribeFlags & RSGXS_GROUP_SUBSCRIBE_ADMIN) -//#define IS_GROUP_SUBSCRIBED(subscribeFlags) (subscribeFlags & (RSGXS_GROUP_SUBSCRIBE_ADMIN | RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED)) - - - -#define RSGXS_MAX_SERVICE_STRING 200 // Sensible limit for dbase usage. - -#include "serialiser/rsgxsitems.h" - -//class RsGroupMetaData -//{ -// public: -// -// RsGroupMetaData() -// { -// mGroupFlags = 0; -// mSignFlags = 0; -// mSubscribeFlags = 0; -// -// mPop = 0; -// mMsgCount = 0; -// mLastPost = 0; -// mGroupStatus = 0; -// -// //mPublishTs = 0; -// } -// -// std::string mGroupId; -// std::string mGroupName; -// uint32_t mGroupFlags; // Service Specific Options ???? -// uint32_t mSignFlags; // Combination of RSGXS_GROUP_SIGN_PUBLISH_MASK & RSGXS_GROUP_SIGN_AUTHOR_MASK. -// -// time_t mPublishTs; // Mandatory. -// std::string mAuthorId; // Optional. -// -// // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. -// -// uint32_t mSubscribeFlags; -// -// uint32_t mPop; // HOW DO WE DO THIS NOW. -// uint32_t mMsgCount; // ??? -// time_t mLastPost; // ??? -// -// uint32_t mGroupStatus; -// -// std::string mServiceString; // Service Specific Free-Form extra storage. -//}; -// -// -// -// -//class RsMsgMetaData -//{ -// public: -// -// RsMsgMetaData() -// { -// mPublishTs = 0; -// mMsgFlags = 0; -// mMsgStatus = 0; -// mChildTs = 0; -// } -// -// std::string mGroupId; -// std::string mMsgId; -// -// std::string mThreadId; -// std::string mParentId; -// std::string mOrigMsgId; -// -// std::string mAuthorId; -// -// std::string mMsgName; -// time_t mPublishTs; -// -// uint32_t mMsgFlags; // Whats this for? (Optional Service Specific - e.g. flag MsgType) -// -// // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. -// // normally READ / UNREAD flags. LOCAL Data. -// uint32_t mMsgStatus; -// time_t mChildTs; -// -// std::string mServiceString; // Service Specific Free-Form extra storage. -// -//}; - -//std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta); -//std::ostream &operator<<(std::ostream &out, const RsMsgMetaData &meta); - -class RsTokenServiceVEG -{ - public: - - RsTokenServiceVEG() { return; } -virtual ~RsTokenServiceVEG() { return; } - - /* changed? */ -virtual bool updated() = 0; - - /* Data Requests */ -virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) = 0; -virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) = 0; -virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds) = 0; - - /* Generic Lists */ -virtual bool getGroupList( const uint32_t &token, std::list &groupIds) = 0; -virtual bool getMsgList( const uint32_t &token, std::list &msgIds) = 0; - - /* Generic Summary */ -virtual bool getGroupSummary( const uint32_t &token, std::list &groupInfo) = 0; -virtual bool getMsgSummary( const uint32_t &token, std::list &msgInfo) = 0; - - /* Actual Data -> specific to Interface */ - - - - /* Poll */ -virtual uint32_t requestStatus(const uint32_t token) = 0; - - /* Cancel Request */ -virtual bool cancelRequest(const uint32_t &token) = 0; - - - ////////////////////////////////////////////////////////////////////////////// - /* Functions from Forums -> need to be implemented generically */ - // Groups Changed is now part of requestGroupInfo request. -//virtual bool groupsChanged(std::list &groupIds) = 0; - - // Message/Group Status - is retrived via requests... - // These operations could have a token, but for the moment we are going to assume - // they are async and always succeed - (or fail silently). -virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask) = 0; -virtual bool setGroupStatus(const std::string &grpId, const uint32_t status, const uint32_t statusMask) = 0; - -virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) = 0; - -virtual bool setMessageServiceString(const std::string &msgId, const std::string &str) = 0; -virtual bool setGroupServiceString(const std::string &grpId, const std::string &str) = 0; - - // (FUTURE WORK). -virtual bool groupRestoreKeys(const std::string &groupId) = 0; -virtual bool groupShareKeys(const std::string &groupId, std::list& peers) = 0; - - - - -}; - - - - -/* The Main Interface Class - for information about your Peers */ -class RsIdentityVEG; -extern RsIdentityVEG *rsIdentityVEG; - -#define RSID_TYPE_MASK 0xff00 -#define RSID_RELATION_MASK 0x00ff - -#define RSID_TYPE_REALID 0x0100 -#define RSID_TYPE_PSEUDONYM 0x0200 - -#define RSID_RELATION_YOURSELF 0x0001 -#define RSID_RELATION_FRIEND 0x0002 -#define RSID_RELATION_FOF 0x0004 -#define RSID_RELATION_OTHER 0x0008 -#define RSID_RELATION_UNKNOWN 0x0010 - -std::string rsIdTypeToString(uint32_t idtype); - -class RsIdGroup -{ - public: - - - RsGroupMetaData mMeta; - - // In GroupMetaData. - //std::string mNickname; (mGroupName) - //std::string mKeyId; (mGroupId) - - uint32_t mIdType; - - std::string mGpgIdHash; // SHA(KeyId + Gpg Fingerprint) -> can only be IDed if GPG known. - - // NOTE: These cannot be transmitted as part of underlying messages.... - // Must use ServiceString. - bool mGpgIdKnown; // if GpgIdHash has been identified. - std::string mGpgId; // if known. - std::string mGpgName; // if known. - std::string mGpgEmail; // if known. -}; - - - -class RsIdMsg -{ - public: - - RsMsgMetaData mMeta; - - // In MsgMetaData. - //std::string mKeyId; (mGroupId) - //std::string mPeerId; (mAuthorId) ??? - - int mOpinion; - double mReputation; - //int mRating; - //int mPeersRating; - //std::string mComment; -}; - - - -std::ostream &operator<<(std::ostream &out, const RsIdGroup &meta); -std::ostream &operator<<(std::ostream &out, const RsIdMsg &meta); - - - -#if 0 -class RsIdReputation -{ - public: - std::string mKeyId; - - int mYourRating; - int mPeersRating; - int mFofRating; - int mTotalRating; - - std::string mComment; -}; - -class RsIdOpinion -{ - public: - - std::string mKeyId; - std::string mPeerId; - - int mRating; - int mPeersRating; - std::string mComment; -}; - -#endif - - -class RsIdentityVEG: public RsTokenServiceVEG -{ - public: - - RsIdentityVEG() { return; } -virtual ~RsIdentityVEG() { return; } - - - /* INCLUDES INTERFACE FROM RS TOKEN SERVICE */ - ////////////////////////////////////////////////////////////////////////////// - - - /* Specific Service Data */ -virtual bool getGroupData(const uint32_t &token, RsIdGroup &group) = 0; -virtual bool getMsgData(const uint32_t &token, RsIdMsg &msg) = 0; - -virtual bool createGroup(uint32_t &token, RsIdGroup &group, bool isNew) = 0; -virtual bool createMsg(uint32_t &token, RsIdMsg &msg, bool isNew) = 0; - - /* In the Identity System - You don't access the Messages Directly. - * as they represent idividuals opinions.... - * This is reflected in the TokenService calls returning false. - * - * Below is the additional interface to look at reputation. - */ - - /* So we will want to cache much of the identity stuff, so that we have quick access to the results. - * The following bits of data will not use the request/response interface, and should be available immediately. - * - * ID => Nickname, knownGPG, reputation. - * - * This will require quite a bit of data... - * 20 Bytes + 50 + 1 + 4 Bytes? (< 100 Bytes). - * x 10,000 IDs. => ~1 MB of cache (Good). - * x 100,000 IDs. => ~10 MB of cache (Good). - * x 1,000,000 IDs. => ~100 MB of cache (Too Big). - * - * We also need to store quick access to your OwnIds. - */ - -//virtual uint32_t getIdDetails(const std::string &id, std::string &nickname, bool &isGpgKnown, -// uint32_t &ownOpinion, float &reputation); -//virtual uint32_t getOwnIds(std::list &ownIds); -//virtual bool setOpinion(const std::string &id, uint32_t opinion); - - -virtual void generateDummyData() = 0; - -#if 0 - - /* Data Requests */ -virtual bool requestIdentityList(uint32_t &token) = 0; -virtual bool requestIdentities(uint32_t &token, const std::list &ids) = 0; -virtual bool requestIdReputations(uint32_t &token, const std::list &ids) = 0; -virtual bool requestIdPeerOpinion(uint32_t &token, const std::string &aboutId, const std::string &peerId) = 0; -//virtual bool requestIdGpgDetails(uint32_t &token, const std::list &ids) = 0; - - /* Poll */ -virtual uint32_t requestStatus(const uint32_t token) = 0; - - /* Retrieve Data */ -virtual bool getIdentityList(const uint32_t token, std::list &ids) = 0; -virtual bool getIdentity(const uint32_t token, RsIdData &data) = 0; -virtual bool getIdReputation(const uint32_t token, RsIdReputation &reputation) = 0; -virtual bool getIdPeerOpinion(const uint32_t token, RsIdOpinion &opinion) = 0; - - /* Updates */ -virtual bool updateIdentity(RsIdData &data) = 0; -virtual bool updateOpinion(RsIdOpinion &opinion) = 0; - -#endif - -}; - - - -#endif diff --git a/libretroshare/src/retroshare/rswikiVEG.h b/libretroshare/src/retroshare/rswikiVEG.h deleted file mode 100644 index 8431ee3d8..000000000 --- a/libretroshare/src/retroshare/rswikiVEG.h +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef RETROSHARE_WIKI_VEG_GUI_INTERFACE_H -#define RETROSHARE_WIKI_VEG_GUI_INTERFACE_H - -/* - * libretroshare/src/retroshare: rswiki.h - * - * RetroShare C++ Interface. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include -#include -#include - -#include - -/* The Main Interface Class - for information about your Peers */ -class RsWikiVEG; -extern RsWikiVEG *rsWikiVEG; - -class RsWikiGroupShare -{ - public: - - uint32_t mShareType; - std::string mShareGroupId; - std::string mPublishKey; - uint32_t mCommentMode; - uint32_t mResizeMode; -}; - -class RsWikiGroup -{ - public: - - RsGroupMetaData mMeta; - - //std::string mGroupId; - //std::string mName; - - std::string mDescription; - std::string mCategory; - - std::string mHashTags; - - RsWikiGroupShare mShareOptions; -}; - -class RsWikiPage -{ - public: - - RsMsgMetaData mMeta; - - // IN META DATA. - //std::string mGroupId; - //std::string mOrigPageId; - //std::string mPageId; - //std::string mName; - - // WE SHOULD SWITCH TO USING THREAD/PARENT IDS HERE.... - std::string mPrevId; - - std::string mPage; // all the text is stored here. - - std::string mHashTags; -}; - -class RsWikiVEG: public RsTokenServiceVEG -{ - public: - - RsWikiVEG() { return; } -virtual ~RsWikiVEG() { return; } - - /* Specific Service Data */ -virtual bool getGroupData(const uint32_t &token, RsWikiGroup &group) = 0; -virtual bool getMsgData(const uint32_t &token, RsWikiPage &page) = 0; - -virtual bool createGroup(uint32_t &token, RsWikiGroup &group, bool isNew) = 0; -virtual bool createPage(uint32_t &token, RsWikiPage &page, bool isNew) = 0; - - -}; - - - -#endif diff --git a/libretroshare/src/retroshare/rswireVEG.h b/libretroshare/src/retroshare/rswire.h similarity index 62% rename from libretroshare/src/retroshare/rswireVEG.h rename to libretroshare/src/retroshare/rswire.h index 314e8dc1c..d30b496fa 100644 --- a/libretroshare/src/retroshare/rswireVEG.h +++ b/libretroshare/src/retroshare/rswire.h @@ -30,38 +30,20 @@ #include #include -#include +#include "gxs/rstokenservice.h" +#include "gxs/rsgxsifaceimpl.h" + /* The Main Interface Class - for information about your Peers */ -class RsWireVEG; -extern RsWireVEG *rsWireVEG; - -class RsWireGroupShare -{ - public: - - uint32_t mShareType; - std::string mShareGroupId; - std::string mPublishKey; - uint32_t mCommentMode; - uint32_t mResizeMode; -}; +class RsWire; +extern RsWire *rsWire; class RsWireGroup { public: RsGroupMetaData mMeta; - - //std::string mGroupId; - //std::string mName; - std::string mDescription; - std::string mCategory; - - std::string mHashTags; - - RsWireGroupShare mShareOptions; }; @@ -102,46 +84,40 @@ class RsWirePulse RsMsgMetaData mMeta; - //std::string mGroupId; - //std::string mOrigPageId; - //std::string mPrevId; - //std::string mPageId; - //std::string mName; + std::string mPulseText; // all the text is stored here. + std::string mHashTags; - std::string mPulse; // all the text is stored here. +// These will be added at some point. +// std::string mInReplyPulse; - std::string mInReplyPulse; +// uint32_t mPulseFlags; - uint32_t mPulseFlags; +// std::list mMentions; +// std::list mHashTags; +// std::list mUrls; - std::list mMentions; - std::list mHashTags; - std::list mUrls; - - RsWirePlace mPlace; +// RsWirePlace mPlace; }; +std::ostream &operator<<(std::ostream &out, const RsWireGroup &group); +std::ostream &operator<<(std::ostream &out, const RsWirePulse &pulse); - -class RsWireVEG: public RsTokenServiceVEG +class RsWire: public RsGxsIfaceImpl { public: - RsWireVEG() { return; } -virtual ~RsWireVEG() { return; } + RsWire(RsGenExchange *gxs): RsGxsIfaceImpl(gxs) { return; } +virtual ~RsWire() { return; } /* Specific Service Data */ -virtual bool getGroupData(const uint32_t &token, RsWireGroup &group) = 0; -virtual bool getMsgData(const uint32_t &token, RsWirePulse &pulse) = 0; +virtual bool getGroupData(const uint32_t &token, std::vector &groups) = 0; +virtual bool getPulseData(const uint32_t &token, std::vector &pulses) = 0; - /* Create Stuff */ -virtual bool createGroup(uint32_t &token, RsWireGroup &group, bool isNew) = 0; -virtual bool createPulse(uint32_t &token, RsWirePulse &pulse, bool isNew) = 0; +virtual bool createGroup(uint32_t &token, RsWireGroup &group) = 0; +virtual bool createPulse(uint32_t &token, RsWirePulse &pulse) = 0; }; - - #endif diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index eb353f7a7..874f60f24 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1829,12 +1829,7 @@ RsTurtle *rsTurtle = NULL ; #include "services/p3posted.h" #include "services/p3photoservice.h" #include "services/p3gxsforums.h" - -// Not too many to convert now! -#include "services/p3wikiserviceVEG.h" -#include "services/p3wireVEG.h" -//#include "services/p3idserviceVEG.h" -//#include "services/p3forumsVEG.h" +#include "services/p3wire.h" #endif #ifndef PQI_DISABLE_TUNNEL @@ -2284,7 +2279,8 @@ int RsServer::StartupRetroShare() // empty and matches an exist directory location // the given ssl user id then this directory is cleaned // and deleted - std::string priorGxsDir = "./" + mLinkMgr->getOwnId() + "/", currGxsDir = RsInitConfig::configDir + "/GXS_phase1"; + std::string priorGxsDir = "./" + mLinkMgr->getOwnId() + "/"; + std::string currGxsDir = RsInitConfig::configDir + "/GXS_phase1"; bool cleanUpGxsDir = false; if(!priorGxsDir.empty()) @@ -2298,21 +2294,6 @@ int RsServer::StartupRetroShare() else rmdir(priorGxsDir.c_str()); - RsDirUtil::checkCreateDirectory(currGxsDir); - - // Testing New Cache Services. - //p3WikiServiceVEG *mWikis = new p3WikiServiceVEG(RS_SERVICE_GXSV1_TYPE_WIKI); - //pqih -> addService(mWikis); - - // Testing New Cache Services. - p3WireVEG *mWire = new p3WireVEG(RS_SERVICE_GXSV1_TYPE_WIRE); - pqih -> addService(mWire); - - // Testing New Cache Services. - //p3ForumsVEG *mForumsV2 = new p3ForumsVEG(RS_SERVICE_GXSV1_TYPE_FORUMS); - //pqih -> addService(mForumsV2); - - // TODO: temporary to store GXS service data, remove RsDirUtil::checkCreateDirectory(currGxsDir); @@ -2339,7 +2320,6 @@ int RsServer::StartupRetroShare() /**** Photo service ****/ // create photo authentication policy - uint32_t photoAuthenPolicy = 0; uint8_t flag = 0; @@ -2404,6 +2384,23 @@ int RsServer::StartupRetroShare() RsGxsNetService* wiki_ns = new RsGxsNetService( RS_SERVICE_GXSV1_TYPE_WIKI, wiki_ds, nxsMgr, mWiki); + + /**** Wire GXS service ****/ + + p3Wire *mWire = NULL; + + RsGeneralDataService* wire_ds = new RsDataService(currGxsDir + "/", "wire_db", + RS_SERVICE_GXSV1_TYPE_WIRE); + + wire_ds->resetDataStore(); //TODO: remove, new service data per RS session, for testing + + mWire = new p3Wire(wire_ds, NULL); + + // create GXS photo service + RsGxsNetService* wire_ns = new RsGxsNetService( + RS_SERVICE_GXSV1_TYPE_WIRE, wire_ds, nxsMgr, mWire); + + /**** Forum GXS service ****/ p3GxsForums *mGxsForums = NULL; @@ -2425,19 +2422,13 @@ int RsServer::StartupRetroShare() #ifdef ENABLE_GXS_CORE /*** start up GXS core runner ***/ - -// GxsCoreServer* mGxsCore = new GxsCoreServer(); - //mGxsCore->addService(mGxsIdService); #if ENABLE_OTHER_GXS_SERVICES createThread(*mGxsIdService); createThread(*mPhoto); createThread(*mPosted); createThread(*mWiki); + createThread(*mWire); createThread(*mGxsForums); -// -// mGxsCore->addService(mPhoto); -// mGxsCore->addService(mPosted); -// mGxsCore->addService(mWiki); #endif // cores ready start up GXS net servers @@ -2446,6 +2437,7 @@ int RsServer::StartupRetroShare() createThread(*photo_ns); createThread(*posted_ns); createThread(*wiki_ns); + createThread(*wire_ns); createThread(*gxsforums_ns); #endif @@ -2458,8 +2450,6 @@ int RsServer::StartupRetroShare() pqih->addService(gxsforums_ns); #endif - // start up gxs core server - //createThread(*mGxsCore); #endif @@ -2728,10 +2718,9 @@ int RsServer::StartupRetroShare() rsPosted = mPosted; rsPhoto = mPhoto; rsGxsForums = mGxsForums; + rsWire = mWire; #endif - rsWireVEG = mWire; - //rsForumsVEG = mForumsV2; #endif // ENABLE_GXS_SERVICES @@ -2748,7 +2737,6 @@ int RsServer::StartupRetroShare() rsGameLauncher = NULL; #endif - /* put a welcome message in! */ if (RsInitConfig::firsttime_run) { diff --git a/libretroshare/src/serialiser/rswikiitems.cc b/libretroshare/src/serialiser/rswikiitems.cc index 56d20bb6b..66c7f9309 100644 --- a/libretroshare/src/serialiser/rswikiitems.cc +++ b/libretroshare/src/serialiser/rswikiitems.cc @@ -198,7 +198,7 @@ bool RsGxsWikiSerialiser::serialiseGxsWikiCollectionItem(RsGxsWikiCollectionItem #ifdef GXSID_DEBUG if (!ok) { - std::cerr << "RsGxsWikiSerialiser::serialiseGxsIdcollectionItem() NOK" << std::endl; + std::cerr << "RsGxsWikiSerialiser::serialiseGxsWikiCollectionItem() NOK" << std::endl; } #endif @@ -354,7 +354,7 @@ bool RsGxsWikiSerialiser::serialiseGxsWikiSnapshotItem(RsGxsWikiSnapshotItem *it #ifdef GXSID_DEBUG if (!ok) { - std::cerr << "RsGxsWikiSerialiser::serialiseGxsIdgroupItem() NOK" << std::endl; + std::cerr << "RsGxsWikiSerialiser::serialiseGxsWikiSnapshotItem() NOK" << std::endl; } #endif @@ -502,7 +502,7 @@ bool RsGxsWikiSerialiser::serialiseGxsWikiCommentItem(RsGxsWikiCommentItem *item #ifdef GXSID_DEBUG if (!ok) { - std::cerr << "RsGxsWikiSerialiser::serialiseGxsIdgroupItem() NOK" << std::endl; + std::cerr << "RsGxsWikiSerialiser::serialiseGxsWikiCommentItem() NOK" << std::endl; } #endif diff --git a/libretroshare/src/serialiser/rswikiitems.h b/libretroshare/src/serialiser/rswikiitems.h index 2b356c400..4b57c968d 100644 --- a/libretroshare/src/serialiser/rswikiitems.h +++ b/libretroshare/src/serialiser/rswikiitems.h @@ -7,7 +7,7 @@ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. + * License Version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/libretroshare/src/serialiser/rswireitems.cc b/libretroshare/src/serialiser/rswireitems.cc new file mode 100644 index 000000000..068499bf8 --- /dev/null +++ b/libretroshare/src/serialiser/rswireitems.cc @@ -0,0 +1,408 @@ +/* + * libretroshare/src/serialiser: rswikiitems.cc + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include + +#include "rswireitems.h" +#include "serialiser/rstlvbase.h" +#include "serialiser/rsbaseserial.h" + +#define WIRE_DEBUG 1 + + +uint32_t RsGxsWireSerialiser::size(RsItem *item) +{ + RsGxsWireGroupItem* grp_item = NULL; + RsGxsWirePulseItem* snap_item = NULL; + + if((grp_item = dynamic_cast(item)) != NULL) + { + return sizeGxsWireGroupItem(grp_item); + } + else if((snap_item = dynamic_cast(item)) != NULL) + { + return sizeGxsWirePulseItem(snap_item); + } + return NULL; +} + +bool RsGxsWireSerialiser::serialise(RsItem *item, void *data, uint32_t *size) +{ + RsGxsWireGroupItem* grp_item = NULL; + RsGxsWirePulseItem* snap_item = NULL; + + if((grp_item = dynamic_cast(item)) != NULL) + { + return serialiseGxsWireGroupItem(grp_item, data, size); + } + else if((snap_item = dynamic_cast(item)) != NULL) + { + return serialiseGxsWirePulseItem(snap_item, data, size); + } + return false; +} + +RsItem* RsGxsWireSerialiser::deserialise(void* data, uint32_t* size) +{ + +#ifdef WIRE_DEBUG + std::cerr << "RsGxsWireSerialiser::deserialise()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_WIRE != getRsItemService(rstype))) + { + return NULL; /* wrong type */ + } + + switch(getRsItemSubType(rstype)) + { + + case RS_PKT_SUBTYPE_WIRE_GROUP_ITEM: + return deserialiseGxsWireGroupItem(data, size); + break; + case RS_PKT_SUBTYPE_WIRE_PULSE_ITEM: + return deserialiseGxsWirePulseItem(data, size); + break; + default: +#ifdef WIRE_DEBUG + std::cerr << "RsGxsWireSerialiser::deserialise(): unknown subtype"; + std::cerr << std::endl; +#endif + break; + } + return NULL; +} + + + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + + +void RsGxsWireGroupItem::clear() +{ + group.mDescription.clear(); +} + +std::ostream& RsGxsWireGroupItem::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsGxsWireGroupItem", indent); + uint16_t int_Indent = indent + 2; + + printIndent(out, int_Indent); + out << "Description: " << group.mDescription << std::endl; + + printRsItemEnd(out ,"RsGxsWireGroupItem", indent); + return out; +} + + +uint32_t RsGxsWireSerialiser::sizeGxsWireGroupItem(RsGxsWireGroupItem *item) +{ + + const RsWireGroup& group = item->group; + uint32_t s = 8; // header + + s += GetTlvStringSize(group.mDescription); + + return s; +} + +bool RsGxsWireSerialiser::serialiseGxsWireGroupItem(RsGxsWireGroupItem *item, void *data, uint32_t *size) +{ + +#ifdef WIRE_DEBUG + std::cerr << "RsGxsWireSerialiser::serialiseGxsWireGroupItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsWireGroupItem(item); + uint32_t offset = 0; + + if(*size < tlvsize) + { +#ifdef WIRE_DEBUG + std::cerr << "RsGxsWireSerialiser::serialiseGxsWireGroupItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsWireGroupItem */ + ok &= SetTlvString(data, tlvsize, &offset, 1, item->group.mDescription); + + if(offset != tlvsize) + { +#ifdef WIRE_DEBUG + std::cerr << "RsGxsWireSerialiser::serialiseGxsWireGroupItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef WIRE_DEBUG + if (!ok) + { + std::cerr << "RsGxsWireSerialiser::serialiseGxsWireGroupItem() NOK" << std::endl; + } +#endif + + return ok; + } + +RsGxsWireGroupItem* RsGxsWireSerialiser::deserialiseGxsWireGroupItem(void *data, uint32_t *size) +{ + +#ifdef WIRE_DEBUG + std::cerr << "RsGxsWireSerialiser::deserialiseGxsWireGroupItem()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_WIRE != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_WIRE_GROUP_ITEM != getRsItemSubType(rstype))) + { +#ifdef WIRE_DEBUG + std::cerr << "RsGxsWireSerialiser::deserialiseGxsWireGroupItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef WIRE_DEBUG + std::cerr << "RsGxsWireSerialiser::deserialiseGxsWireGroupItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsWireGroupItem* item = new RsGxsWireGroupItem(); + /* skip the header */ + offset += 8; + + ok &= GetTlvString(data, rssize, &offset, 1, item->group.mDescription); + + if (offset != rssize) + { +#ifdef WIRE_DEBUG + std::cerr << "RsGxsWireSerialiser::deserialiseGxsWireGroupItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef WIRE_DEBUG + std::cerr << "RsGxsWireSerialiser::deserialiseGxsWireGroupItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + + + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + + +void RsGxsWirePulseItem::clear() +{ + pulse.mPulseText.clear(); + pulse.mHashTags.clear(); +} + +std::ostream& RsGxsWirePulseItem::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsGxsWirePulseItem", indent); + uint16_t int_Indent = indent + 2; + + printIndent(out, int_Indent); + out << "Page: " << pulse.mPulseText << std::endl; + + printIndent(out, int_Indent); + out << "HashTags: " << pulse.mHashTags << std::endl; + + printRsItemEnd(out ,"RsGxsWirePulseItem", indent); + return out; +} + + +uint32_t RsGxsWireSerialiser::sizeGxsWirePulseItem(RsGxsWirePulseItem *item) +{ + + const RsWirePulse& pulse = item->pulse; + uint32_t s = 8; // header + + s += GetTlvStringSize(pulse.mPulseText); + s += GetTlvStringSize(pulse.mHashTags); + + return s; +} + +bool RsGxsWireSerialiser::serialiseGxsWirePulseItem(RsGxsWirePulseItem *item, void *data, uint32_t *size) +{ + +#ifdef WIRE_DEBUG + std::cerr << "RsGxsWireSerialiser::serialiseGxsWirePulseItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsWirePulseItem(item); + uint32_t offset = 0; + + if(*size < tlvsize) + { +#ifdef WIRE_DEBUG + std::cerr << "RsGxsWireSerialiser::serialiseGxsWirePulseItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsWirePulseItem */ + ok &= SetTlvString(data, tlvsize, &offset, 1, item->pulse.mPulseText); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->pulse.mHashTags); + + if(offset != tlvsize) + { +#ifdef WIRE_DEBUG + std::cerr << "RsGxsWireSerialiser::serialiseGxsWirePulseItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef WIRE_DEBUG + if (!ok) + { + std::cerr << "RsGxsWireSerialiser::serialiseGxsWirePulseItem() NOK" << std::endl; + } +#endif + + return ok; + } + +RsGxsWirePulseItem* RsGxsWireSerialiser::deserialiseGxsWirePulseItem(void *data, uint32_t *size) +{ + +#ifdef WIRE_DEBUG + std::cerr << "RsGxsWireSerialiser::deserialiseGxsWirePulseItem()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_WIRE != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_WIRE_PULSE_ITEM != getRsItemSubType(rstype))) + { +#ifdef WIRE_DEBUG + std::cerr << "RsGxsWireSerialiser::deserialiseGxsWirePulseItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef WIRE_DEBUG + std::cerr << "RsGxsWireSerialiser::deserialiseGxsWirePulseItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsWirePulseItem* item = new RsGxsWirePulseItem(); + /* skip the header */ + offset += 8; + + ok &= GetTlvString(data, rssize, &offset, 1, item->pulse.mPulseText); + ok &= GetTlvString(data, rssize, &offset, 1, item->pulse.mHashTags); + + if (offset != rssize) + { +#ifdef WIRE_DEBUG + std::cerr << "RsGxsWireSerialiser::deserialiseGxsWirePulseItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef WIRE_DEBUG + std::cerr << "RsGxsWireSerialiser::deserialiseGxsWirePulseItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + diff --git a/libretroshare/src/serialiser/rswireitems.h b/libretroshare/src/serialiser/rswireitems.h new file mode 100644 index 000000000..c7dfc4f03 --- /dev/null +++ b/libretroshare/src/serialiser/rswireitems.h @@ -0,0 +1,93 @@ +/* + * libretroshare/src/serialiser: rswireitems.h + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#ifndef RS_WIRE_ITEMS_H +#define RS_WIRE_ITEMS_H + +#include + +#include "serialiser/rsserviceids.h" +#include "serialiser/rsserial.h" +#include "serialiser/rstlvtypes.h" + +#include "rsgxsitems.h" +#include "retroshare/rswire.h" + +const uint8_t RS_PKT_SUBTYPE_WIRE_GROUP_ITEM = 0x02; +const uint8_t RS_PKT_SUBTYPE_WIRE_PULSE_ITEM = 0x03; + +class RsGxsWireGroupItem : public RsGxsGrpItem +{ + +public: + + RsGxsWireGroupItem(): RsGxsGrpItem(RS_SERVICE_GXSV1_TYPE_WIRE, + RS_PKT_SUBTYPE_WIRE_GROUP_ITEM) { return;} + virtual ~RsGxsWireGroupItem() { return;} + + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + + RsWireGroup group; +}; + +class RsGxsWirePulseItem : public RsGxsMsgItem +{ +public: + + RsGxsWirePulseItem(): RsGxsMsgItem(RS_SERVICE_GXSV1_TYPE_WIRE, + RS_PKT_SUBTYPE_WIRE_PULSE_ITEM) {return; } + virtual ~RsGxsWirePulseItem() { return;} + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + RsWirePulse pulse; +}; + +class RsGxsWireSerialiser : public RsSerialType +{ +public: + + RsGxsWireSerialiser() + :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXSV1_TYPE_WIRE) + { return; } + virtual ~RsGxsWireSerialiser() { return; } + + uint32_t size(RsItem *item); + bool serialise (RsItem *item, void *data, uint32_t *size); + RsItem * deserialise(void *data, uint32_t *size); + + private: + + uint32_t sizeGxsWireGroupItem(RsGxsWireGroupItem *item); + bool serialiseGxsWireGroupItem (RsGxsWireGroupItem *item, void *data, uint32_t *size); + RsGxsWireGroupItem * deserialiseGxsWireGroupItem(void *data, uint32_t *size); + + uint32_t sizeGxsWirePulseItem(RsGxsWirePulseItem *item); + bool serialiseGxsWirePulseItem (RsGxsWirePulseItem *item, void *data, uint32_t *size); + RsGxsWirePulseItem * deserialiseGxsWirePulseItem(void *data, uint32_t *size); +}; + +#endif /* RS_WIKI_ITEMS_H */ diff --git a/libretroshare/src/services/p3forumsVEG.cc b/libretroshare/src/services/p3forumsVEG.cc deleted file mode 100644 index 2e3a81ceb..000000000 --- a/libretroshare/src/services/p3forumsVEG.cc +++ /dev/null @@ -1,805 +0,0 @@ -/* - * libretroshare/src/services p3forumsv2.cc - * - * ForumsV2 interface for RetroShare. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "services/p3forumsVEG.h" - -#include "util/rsrandom.h" -#include - -/**** - * #define FORUMV2_DEBUG 1 - ****/ - -RsForumsVEG *rsForumsVEG = NULL; - - - -/********************************************************************************/ -/******************* Startup / Tick ******************************************/ -/********************************************************************************/ - -p3ForumsVEG::p3ForumsVEG(uint16_t type) - :p3GxsDataServiceVEG(type, new ForumDataProxy()), mForumMtx("p3ForumsV2"), mUpdated(true) -{ - { - RsStackMutex stack(mForumMtx); /********** STACK LOCKED MTX ******/ - - mForumProxy = (ForumDataProxy *) mProxy; - } - - generateDummyData(); - - return; -} - - -int p3ForumsVEG::tick() -{ - //std::cerr << "p3ForumsVEG::tick()"; - //std::cerr << std::endl; - - fakeprocessrequests(); - - return 0; -} - -bool p3ForumsVEG::updated() -{ - RsStackMutex stack(mForumMtx); /********** STACK LOCKED MTX ******/ - - if (mUpdated) - { - mUpdated = false; - return true; - } - return false; -} - - - - /* Data Requests */ -bool p3ForumsVEG::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) -{ - generateToken(token); - std::cerr << "p3ForumsVEG::requestGroupInfo() gets Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); - - return true; -} - -bool p3ForumsVEG::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) -{ - generateToken(token); - std::cerr << "p3ForumsVEG::requestMsgInfo() gets Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds); - - return true; -} - -bool p3ForumsVEG::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds) -{ - generateToken(token); - std::cerr << "p3ForumsVEG::requestMsgRelatedInfo() gets Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); - - return true; -} - - /* Generic Lists */ -bool p3ForumsVEG::getGroupList( const uint32_t &token, std::list &groupIds) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_LIST) - { - std::cerr << "p3ForumsVEG::getGroupList() ERROR AnsType Wrong" << std::endl; - return false; - } - - if (reqtype != GXS_REQUEST_TYPE_GROUPS) - { - std::cerr << "p3ForumsVEG::getGroupList() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3ForumsVEG::getGroupList() ERROR Status Incomplete" << std::endl; - return false; - } - - bool ans = loadRequestOutList(token, groupIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - return ans; -} - - - - -bool p3ForumsVEG::getMsgList( const uint32_t &token, std::list &msgIds) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_LIST) - { - std::cerr << "p3ForumsVEG::getMsgList() ERROR AnsType Wrong" << std::endl; - return false; - } - - if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) - { - std::cerr << "p3ForumsVEG::getMsgList() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3ForumsVEG::getMsgList() ERROR Status Incomplete" << std::endl; - return false; - } - - bool ans = loadRequestOutList(token, msgIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - return ans; -} - - - /* Generic Summary */ -bool p3ForumsVEG::getGroupSummary( const uint32_t &token, std::list &groupInfo) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY) - { - std::cerr << "p3ForumsVEG::getGroupSummary() ERROR AnsType Wrong" << std::endl; - return false; - } - - if (reqtype != GXS_REQUEST_TYPE_GROUPS) - { - std::cerr << "p3ForumsVEG::getGroupSummary() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3ForumsVEG::getGroupSummary() ERROR Status Incomplete" << std::endl; - return false; - } - - std::list groupIds; - bool ans = loadRequestOutList(token, groupIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - /* convert to RsGroupMetaData */ - mProxy->getGroupSummary(groupIds, groupInfo); - - return ans; -} - -bool p3ForumsVEG::getMsgSummary( const uint32_t &token, std::list &msgInfo) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY) - { - std::cerr << "p3ForumsVEG::getMsgSummary() ERROR AnsType Wrong" << std::endl; - return false; - } - - if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) - { - std::cerr << "p3ForumsVEG::getMsgSummary() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3ForumsVEG::getMsgSummary() ERROR Status Incomplete" << std::endl; - return false; - } - - std::list msgIds; - bool ans = loadRequestOutList(token, msgIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - /* convert to RsMsgMetaData */ - mProxy->getMsgSummary(msgIds, msgInfo); - - return ans; -} - - - /* Specific Service Data */ -bool p3ForumsVEG::getGroupData(const uint32_t &token, RsForumV2Group &group) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - - if (anstype != RS_TOKREQ_ANSTYPE_DATA) - { - std::cerr << "p3ForumsVEG::getGroupData() ERROR AnsType Wrong" << std::endl; - return false; - } - - if (reqtype != GXS_REQUEST_TYPE_GROUPS) - { - std::cerr << "p3ForumsVEG::getGroupData() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3ForumsVEG::getGroupData() ERROR Status Incomplete" << std::endl; - return false; - } - - std::string id; - if (!popRequestOutList(token, id)) - { - /* finished */ - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - return false; - } - - /* convert to RsForumAlbum */ - bool ans = mForumProxy->getForumGroup(id, group); - return ans; -} - - -bool p3ForumsVEG::getMsgData(const uint32_t &token, RsForumV2Msg &msg) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - - if (anstype != RS_TOKREQ_ANSTYPE_DATA) - { - std::cerr << "p3ForumsVEG::getMsgData() ERROR AnsType Wrong" << std::endl; - return false; - } - - if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) - { - std::cerr << "p3ForumsVEG::getMsgData() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3ForumsVEG::getMsgData() ERROR Status Incomplete" << std::endl; - return false; - } - - std::string id; - if (!popRequestOutList(token, id)) - { - /* finished */ - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - return false; - } - - /* convert to RsForumAlbum */ - bool ans = mForumProxy->getForumMsg(id, msg); - return ans; -} - - - - /* Poll */ -uint32_t p3ForumsVEG::requestStatus(const uint32_t token) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - return status; -} - - - /* Cancel Request */ -bool p3ForumsVEG::cancelRequest(const uint32_t &token) -{ - return clearRequest(token); -} - - ////////////////////////////////////////////////////////////////////////////// - -bool p3ForumsVEG::setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask) -{ - return mForumProxy->setMessageStatus(msgId, status, statusMask); -} - -bool p3ForumsVEG::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask) -{ - return mForumProxy->setGroupStatus(groupId, status, statusMask); -} - -bool p3ForumsVEG::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) -{ - return mForumProxy->setGroupSubscribeFlags(groupId, subscribeFlags, subscribeMask); -} - -bool p3ForumsVEG::setMessageServiceString(const std::string &msgId, const std::string &str) -{ - return mForumProxy->setMessageServiceString(msgId, str); -} - -bool p3ForumsVEG::setGroupServiceString(const std::string &grpId, const std::string &str) -{ - return mForumProxy->setGroupServiceString(grpId, str); -} - - - -bool p3ForumsVEG::groupRestoreKeys(const std::string &groupId) -{ - return false; -} - -bool p3ForumsVEG::groupShareKeys(const std::string &groupId, std::list& peers) -{ - return false; -} - - - - -/********************************************************************************************/ - - -std::string p3ForumsVEG::genRandomId() -{ - std::string randomId; - for(int i = 0; i < 20; i++) - { - randomId += (char) ('a' + (RSRandom::random_u32() % 26)); - } - - return randomId; -} - -bool p3ForumsVEG::createGroup(uint32_t &token, RsForumV2Group &group, bool isNew) -{ - if (group.mMeta.mGroupId.empty()) - { - /* new photo */ - - /* generate a temp id */ - group.mMeta.mGroupId = genRandomId(); - } - else - { - std::cerr << "p3ForumsVEG::createGroup() Group with existing Id... dropping"; - std::cerr << std::endl; - return false; - } - - { - RsStackMutex stack(mForumMtx); /********** STACK LOCKED MTX ******/ - - mUpdated = true; - mForumProxy->addForumGroup(group); - } - - // Fake a request to return the GroupMetaData. - generateToken(token); - uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptionsVEG opts; // NULL is good. - std::list groupIds; - groupIds.push_back(group.mMeta.mGroupId); // It will just return this one. - - std::cerr << "p3ForumsVEG::createGroup() Generating Request Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); - - return true; -} - - - - -bool p3ForumsVEG::createMsg(uint32_t &token, RsForumV2Msg &msg, bool isNew) -{ - if (msg.mMeta.mGroupId.empty()) - { - /* new photo */ - std::cerr << "p3ForumsVEG::createForumMsg() Missing MsgID"; - std::cerr << std::endl; - return false; - } - - /* check if its a mod or new msg */ - if (msg.mMeta.mOrigMsgId.empty()) - { - std::cerr << "p3ForumsVEG::createForumMsg() New Msg"; - std::cerr << std::endl; - - /* new msg, generate a new OrigMsgId */ - msg.mMeta.mOrigMsgId = genRandomId(); - msg.mMeta.mMsgId = msg.mMeta.mOrigMsgId; - } - else - { - std::cerr << "p3ForumsVEG::createForumMsg() Modified Msg"; - std::cerr << std::endl; - - /* mod msg, keep orig msg id, generate a new MsgId */ - msg.mMeta.mMsgId = genRandomId(); - } - - std::cerr << "p3ForumsVEG::createForumMsg() GroupId: " << msg.mMeta.mGroupId; - std::cerr << std::endl; - std::cerr << "p3ForumsVEG::createForumMsg() MsgId: " << msg.mMeta.mMsgId; - std::cerr << std::endl; - std::cerr << "p3ForumsVEG::createForumMsg() OrigMsgId: " << msg.mMeta.mOrigMsgId; - std::cerr << std::endl; - - { - RsStackMutex stack(mForumMtx); /********** STACK LOCKED MTX ******/ - - mUpdated = true; - mForumProxy->addForumMsg(msg); - } - - // Fake a request to return the MsgMetaData. - generateToken(token); - uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptionsVEG opts; // NULL is good. - std::list msgIds; - msgIds.push_back(msg.mMeta.mMsgId); // It will just return this one. - - std::cerr << "p3ForumsVEG::createMsg() Generating Request Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); - - return true; -} - - - -/********************************************************************************************/ - - -bool ForumDataProxy::getForumGroup(const std::string &id, RsForumV2Group &group) -{ - void *groupData = NULL; - RsGroupMetaData meta; - if (getGroupData(id, groupData) && getGroupSummary(id, meta)) - { - RsForumV2Group *pG = (RsForumV2Group *) groupData; - group = *pG; - - // update definitive version of the metadata. - group.mMeta = meta; - - std::cerr << "ForumDataProxy::getForumGroup() Id: " << id; - std::cerr << " MetaData: " << meta << " DataPointer: " << groupData; - std::cerr << std::endl; - return true; - } - - std::cerr << "ForumDataProxy::getForumGroup() FAILED Id: " << id; - std::cerr << std::endl; - - return false; -} - -bool ForumDataProxy::getForumMsg(const std::string &id, RsForumV2Msg &page) -{ - void *msgData = NULL; - RsMsgMetaData meta; - if (getMsgData(id, msgData) && getMsgSummary(id, meta)) - { - RsForumV2Msg *pP = (RsForumV2Msg *) msgData; - // Shallow copy of thumbnail. - page = *pP; - - // update definitive version of the metadata. - page.mMeta = meta; - - std::cerr << "ForumDataProxy::getForumMsg() Id: " << id; - std::cerr << " MetaData: " << meta << " DataPointer: " << msgData; - std::cerr << std::endl; - return true; - } - - std::cerr << "ForumDataProxy::getForumMsg() FAILED Id: " << id; - std::cerr << std::endl; - - return false; -} - -bool ForumDataProxy::addForumGroup(const RsForumV2Group &group) -{ - // Make duplicate. - RsForumV2Group *pG = new RsForumV2Group(); - *pG = group; - - std::cerr << "ForumDataProxy::addForumGroup()"; - std::cerr << " MetaData: " << pG->mMeta << " DataPointer: " << pG; - std::cerr << std::endl; - - return createGroup(pG); -} - - -bool ForumDataProxy::addForumMsg(const RsForumV2Msg &msg) -{ - // Make duplicate. - RsForumV2Msg *pM = new RsForumV2Msg(); - *pM = msg; - - std::cerr << "ForumDataProxy::addForumMsg()"; - std::cerr << " MetaData: " << pM->mMeta << " DataPointer: " << pM; - std::cerr << std::endl; - - return createMsg(pM); -} - - - - /* These Functions must be overloaded to complete the service */ -bool ForumDataProxy::convertGroupToMetaData(void *groupData, RsGroupMetaData &meta) -{ - RsForumV2Group *group = (RsForumV2Group *) groupData; - meta = group->mMeta; - - return true; -} - -bool ForumDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta) -{ - RsForumV2Msg *page = (RsForumV2Msg *) msgData; - meta = page->mMeta; - - return true; -} - - -/********************************************************************************************/ - - - -bool p3ForumsVEG::generateDummyData() -{ - /* so we want to generate 100's of forums */ -#define MAX_FORUMS 10 //100 -#define MAX_THREADS 10 //1000 -#define MAX_MSGS 100 //10000 - - std::list mGroups; - std::list::iterator git; - - std::list mMsgs; - std::list::iterator mit; - -#define DUMMY_NAME_MAX_LEN 10000 - char name[DUMMY_NAME_MAX_LEN]; - int i, j; - time_t now = time(NULL); - - for(i = 0; i < MAX_FORUMS; i++) - { - /* generate a new forum */ - RsForumV2Group forum; - - /* generate a temp id */ - forum.mMeta.mGroupId = genRandomId(); - - snprintf(name, DUMMY_NAME_MAX_LEN, "TestForum_%d", i+1); - - forum.mMeta.mGroupId = genRandomId(); - forum.mMeta.mGroupName = name; - - forum.mMeta.mPublishTs = now - (RSRandom::random_f32() * 100000); - /* key fields to fill in: - * GroupId. - * Name. - * Flags. - * Pop. - */ - - - - /* use probability to decide which are subscribed / own / popularity. - */ - - float rnd = RSRandom::random_f32(); - if (rnd < 0.1) - { - forum.mMeta.mSubscribeFlags = RSGXS_GROUP_SUBSCRIBE_ADMIN; - - } - else if (rnd < 0.3) - { - forum.mMeta.mSubscribeFlags = RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED; - } - else - { - forum.mMeta.mSubscribeFlags = 0; - } - - forum.mMeta.mPop = (int) (RSRandom::random_f32() * 10.0); - - mGroups.push_back(forum); - - - //std::cerr << "p3ForumsVEG::generateDummyData() Generated Forum: " << forum.mMeta; - //std::cerr << std::endl; - } - - - for(i = 0; i < MAX_THREADS; i++) - { - /* generate a base thread */ - - /* rotate the Forum Groups Around, then pick one. - */ - - int rnd = (int) (RSRandom::random_f32() * 10.0); - - for(j = 0; j < rnd; j++) - { - RsForumV2Group head = mGroups.front(); - mGroups.pop_front(); - mGroups.push_back(head); - } - - RsForumV2Group forum = mGroups.front(); - - /* now create a new thread */ - - RsForumV2Msg msg; - - /* fill in key data - * GroupId - * MsgId - * OrigMsgId - * ThreadId - * ParentId - * PublishTS (take Forum TS + a bit ). - * - * ChildTS ???? - */ - snprintf(name, DUMMY_NAME_MAX_LEN, "%s => ThreadMsg_%d", forum.mMeta.mGroupName.c_str(), i+1); - msg.mMeta.mMsgName = name; - - msg.mMeta.mGroupId = forum.mMeta.mGroupId; - msg.mMeta.mMsgId = genRandomId(); - msg.mMeta.mOrigMsgId = msg.mMeta.mMsgId; - msg.mMeta.mThreadId = msg.mMeta.mMsgId; - msg.mMeta.mParentId = ""; - - msg.mMeta.mPublishTs = forum.mMeta.mPublishTs + (RSRandom::random_f32() * 10000); - if (msg.mMeta.mPublishTs > now) - msg.mMeta.mPublishTs = now - 1; - - mMsgs.push_back(msg); - - //std::cerr << "p3ForumsVEG::generateDummyData() Generated Thread: " << msg.mMeta; - //std::cerr << std::endl; - - } - - for(i = 0; i < MAX_MSGS; i++) - { - /* generate a base thread */ - - /* rotate the Forum Groups Around, then pick one. - */ - - int rnd = (int) (RSRandom::random_f32() * 10.0); - - for(j = 0; j < rnd; j++) - { - RsForumV2Msg head = mMsgs.front(); - mMsgs.pop_front(); - mMsgs.push_back(head); - } - - RsForumV2Msg parent = mMsgs.front(); - - /* now create a new child msg */ - - RsForumV2Msg msg; - - /* fill in key data - * GroupId - * MsgId - * OrigMsgId - * ThreadId - * ParentId - * PublishTS (take Forum TS + a bit ). - * - * ChildTS ???? - */ - snprintf(name, DUMMY_NAME_MAX_LEN, "%s => Msg_%d", parent.mMeta.mMsgName.c_str(), i+1); - msg.mMeta.mMsgName = name; - msg.mMsg = name; - - msg.mMeta.mGroupId = parent.mMeta.mGroupId; - msg.mMeta.mMsgId = genRandomId(); - msg.mMeta.mOrigMsgId = msg.mMeta.mMsgId; - msg.mMeta.mThreadId = parent.mMeta.mThreadId; - msg.mMeta.mParentId = parent.mMeta.mOrigMsgId; - - msg.mMeta.mPublishTs = parent.mMeta.mPublishTs + (RSRandom::random_f32() * 10000); - if (msg.mMeta.mPublishTs > now) - msg.mMeta.mPublishTs = now - 1; - - mMsgs.push_back(msg); - - //std::cerr << "p3ForumsVEG::generateDummyData() Generated Child Msg: " << msg.mMeta; - //std::cerr << std::endl; - - } - - - mUpdated = true; - - /* Then - at the end, we push them all into the Proxy */ - for(git = mGroups.begin(); git != mGroups.end(); git++) - { - /* pushback */ - mForumProxy->addForumGroup(*git); - - } - - for(mit = mMsgs.begin(); mit != mMsgs.end(); mit++) - { - /* pushback */ - mForumProxy->addForumMsg(*mit); - } - - return true; -} - diff --git a/libretroshare/src/services/p3forumsVEG.h b/libretroshare/src/services/p3forumsVEG.h deleted file mode 100644 index 4bf01a5b1..000000000 --- a/libretroshare/src/services/p3forumsVEG.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * libretroshare/src/services: p3forumsv2.h - * - * Wiki interface for RetroShare. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#ifndef P3_FORUMSV2_SERVICE_HEADER -#define P3_FORUMSV2_SERVICE_HEADER - -#include "services/p3gxsserviceVEG.h" - -#include "retroshare/rsforumsVEG.h" - -#include -#include - -/* - * - */ - -class ForumDataProxy: public GxsDataProxyVEG -{ - public: - - bool getForumGroup(const std::string &id, RsForumV2Group &group); - bool getForumMsg(const std::string &id, RsForumV2Msg &msg); - - bool addForumGroup(const RsForumV2Group &group); - bool addForumMsg(const RsForumV2Msg &msg); - - /* These Functions must be overloaded to complete the service */ -virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta); -virtual bool convertMsgToMetaData(void *msgData, RsMsgMetaData &meta); - -}; - - - - - -class p3ForumsVEG: public p3GxsDataServiceVEG, public RsForumsVEG -{ - public: - - p3ForumsVEG(uint16_t type); - -virtual int tick(); - - public: - - -virtual bool updated(); - - - /* Data Requests */ -virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); -virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); -virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds); - - /* Generic Lists */ -virtual bool getGroupList( const uint32_t &token, std::list &groupIds); -virtual bool getMsgList( const uint32_t &token, std::list &msgIds); - - /* Generic Summary */ -virtual bool getGroupSummary( const uint32_t &token, std::list &groupInfo); -virtual bool getMsgSummary( const uint32_t &token, std::list &msgInfo); - - /* Actual Data -> specific to Interface */ - /* Specific Service Data */ -virtual bool getGroupData(const uint32_t &token, RsForumV2Group &group); -virtual bool getMsgData(const uint32_t &token, RsForumV2Msg &msg); - - /* Poll */ -virtual uint32_t requestStatus(const uint32_t token); - - /* Cancel Request */ -virtual bool cancelRequest(const uint32_t &token); - - ////////////////////////////////////////////////////////////////////////////// -virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask); -virtual bool setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask); -virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask); -virtual bool setMessageServiceString(const std::string &msgId, const std::string &str); -virtual bool setGroupServiceString(const std::string &grpId, const std::string &str); - -virtual bool groupRestoreKeys(const std::string &groupId); -virtual bool groupShareKeys(const std::string &groupId, std::list& peers); - -virtual bool createGroup(uint32_t &token, RsForumV2Group &group, bool isNew); -virtual bool createMsg(uint32_t &token, RsForumV2Msg &msg, bool isNew); - - private: - -std::string genRandomId(); -bool generateDummyData(); - - ForumDataProxy *mForumProxy; - - RsMutex mForumMtx; - - /***** below here is locked *****/ - - bool mUpdated; - -}; - -#endif diff --git a/libretroshare/src/services/p3idserviceVEG.cc b/libretroshare/src/services/p3idserviceVEG.cc deleted file mode 100644 index 27b16a6a4..000000000 --- a/libretroshare/src/services/p3idserviceVEG.cc +++ /dev/null @@ -1,1552 +0,0 @@ -/* - * libretroshare/src/services p3idservice.cc - * - * Id interface for RetroShare. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "services/p3idserviceVEG.h" - -#include "util/rsrandom.h" -#include -#include -#include - -/**** - * #define ID_DEBUG 1 - ****/ - -#define ID_REQUEST_LIST 0x0001 -#define ID_REQUEST_IDENTITY 0x0002 -#define ID_REQUEST_REPUTATION 0x0003 -#define ID_REQUEST_OPINION 0x0004 - -RsIdentityVEG *rsIdentityVEG = NULL; - - -/********************************************************************************/ -/******************* Startup / Tick ******************************************/ -/********************************************************************************/ - -p3IdServiceVEG::p3IdServiceVEG(uint16_t type) - :p3GxsDataServiceVEG(type, new IdDataProxy()), mIdMtx("p3IdService"), mUpdated(true) -{ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - mIdProxy = (IdDataProxy *) mProxy; - return; -} - - -int p3IdServiceVEG::tick() -{ - //std::cerr << "p3IdServiceVEG::tick()"; - //std::cerr << std::endl; - - fakeprocessrequests(); - // Disable for now. - // background_tick(); - - return 0; -} - -bool p3IdServiceVEG::updated() -{ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - if (mUpdated) - { - mUpdated = false; - return true; - } - return false; -} - - - - /* Data Requests */ -bool p3IdServiceVEG::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) -{ - generateToken(token); - std::cerr << "p3IdServiceVEG::requestGroupInfo() gets Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); - - return true; -} - -bool p3IdServiceVEG::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) -{ - generateToken(token); - std::cerr << "p3IdServiceVEG::requestMsgInfo() gets Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds); - - return true; -} - -bool p3IdServiceVEG::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds) -{ - generateToken(token); - std::cerr << "p3IdServiceVEG::requestMsgRelatedInfo() gets Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); - - return true; -} - - /* Generic Lists */ -bool p3IdServiceVEG::getGroupList( const uint32_t &token, std::list &groupIds) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_LIST) - { - std::cerr << "p3IdServiceVEG::getGroupList() ERROR AnsType Wrong" << std::endl; - return false; - } - - if (reqtype != GXS_REQUEST_TYPE_GROUPS) - { - std::cerr << "p3IdServiceVEG::getGroupList() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3IdServiceVEG::getGroupList() ERROR Status Incomplete" << std::endl; - return false; - } - - bool ans = loadRequestOutList(token, groupIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - return ans; -} - - - - -bool p3IdServiceVEG::getMsgList( const uint32_t &token, std::list &msgIds) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_LIST) - { - std::cerr << "p3IdServiceVEG::getMsgList() ERROR AnsType Wrong" << std::endl; - return false; - } - - if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) - { - std::cerr << "p3IdServiceVEG::getMsgList() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3IdServiceVEG::getMsgList() ERROR Status Incomplete" << std::endl; - return false; - } - - bool ans = loadRequestOutList(token, msgIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - return ans; -} - - - /* Generic Summary */ -bool p3IdServiceVEG::getGroupSummary( const uint32_t &token, std::list &groupInfo) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY) - { - std::cerr << "p3IdServiceVEG::getGroupSummary() ERROR AnsType Wrong" << std::endl; - return false; - } - - if (reqtype != GXS_REQUEST_TYPE_GROUPS) - { - std::cerr << "p3IdServiceVEG::getGroupSummary() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3IdServiceVEG::getGroupSummary() ERROR Status Incomplete" << std::endl; - return false; - } - - std::list groupIds; - bool ans = loadRequestOutList(token, groupIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - /* convert to RsGroupMetaData */ - mProxy->getGroupSummary(groupIds, groupInfo); - - return ans; -} - -bool p3IdServiceVEG::getMsgSummary( const uint32_t &token, std::list &msgInfo) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY) - { - std::cerr << "p3IdServiceVEG::getMsgSummary() ERROR AnsType Wrong" << std::endl; - return false; - } - - if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) - { - std::cerr << "p3IdServiceVEG::getMsgSummary() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3IdServiceVEG::getMsgSummary() ERROR Status Incomplete" << std::endl; - return false; - } - - std::list msgIds; - bool ans = loadRequestOutList(token, msgIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - /* convert to RsMsgMetaData */ - mProxy->getMsgSummary(msgIds, msgInfo); - - return ans; -} - - - /* Specific Service Data */ -bool p3IdServiceVEG::getGroupData(const uint32_t &token, RsIdGroup &group) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - - if (anstype != RS_TOKREQ_ANSTYPE_DATA) - { - std::cerr << "p3IdServiceVEG::getGroupData() ERROR AnsType Wrong" << std::endl; - return false; - } - - if (reqtype != GXS_REQUEST_TYPE_GROUPS) - { - std::cerr << "p3IdServiceVEG::getGroupData() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3IdServiceVEG::getGroupData() ERROR Status Incomplete" << std::endl; - return false; - } - - std::string id; - if (!popRequestOutList(token, id)) - { - /* finished */ - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - return false; - } - - /* convert to RsIdGroup */ - bool ans = mIdProxy->getGroup(id, group); - return ans; -} - - -bool p3IdServiceVEG::getMsgData(const uint32_t &token, RsIdMsg &msg) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - - if (anstype != RS_TOKREQ_ANSTYPE_DATA) - { - std::cerr << "p3IdServiceVEG::getMsgData() ERROR AnsType Wrong" << std::endl; - return false; - } - - if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) - { - std::cerr << "p3IdServiceVEG::getMsgData() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3IdServiceVEG::getMsgData() ERROR Status Incomplete" << std::endl; - return false; - } - - std::string id; - if (!popRequestOutList(token, id)) - { - /* finished */ - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - return false; - } - - /* convert to RsIdMsg */ - bool ans = mIdProxy->getMsg(id, msg); - return ans; -} - - - - /* Poll */ -uint32_t p3IdServiceVEG::requestStatus(const uint32_t token) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - return status; -} - - - /* Cancel Request */ -bool p3IdServiceVEG::cancelRequest(const uint32_t &token) -{ - return clearRequest(token); -} - - ////////////////////////////////////////////////////////////////////////////// -bool p3IdServiceVEG::setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask) -{ - return mIdProxy->setMessageStatus(msgId, status, statusMask); -} - -bool p3IdServiceVEG::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask) -{ - return mIdProxy->setGroupStatus(groupId, status, statusMask); -} - -bool p3IdServiceVEG::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) -{ - return mIdProxy->setGroupSubscribeFlags(groupId, subscribeFlags, subscribeMask); -} - -bool p3IdServiceVEG::setMessageServiceString(const std::string &msgId, const std::string &str) -{ - return mIdProxy->setMessageServiceString(msgId, str); -} - -bool p3IdServiceVEG::setGroupServiceString(const std::string &grpId, const std::string &str) -{ - return mIdProxy->setGroupServiceString(grpId, str); -} - - -bool p3IdServiceVEG::groupRestoreKeys(const std::string &groupId) -{ - return false; -} - -bool p3IdServiceVEG::groupShareKeys(const std::string &groupId, std::list& peers) -{ - return false; -} - - -/********************************************************************************************/ - - -std::string p3IdServiceVEG::genRandomId() -{ - std::string randomId; - for(int i = 0; i < 20; i++) - { - randomId += (char) ('a' + (RSRandom::random_u32() % 26)); - } - - return randomId; -} - -bool p3IdServiceVEG::createGroup(uint32_t &token, RsIdGroup &group, bool isNew) -{ - if (group.mMeta.mGroupId.empty()) - { - /* new photo */ - - /* generate a temp id */ - group.mMeta.mGroupId = genRandomId(); - } - else - { - std::cerr << "p3IdServiceVEG::createGroup() Group with existing Id... dropping"; - std::cerr << std::endl; - return false; - } - - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - mUpdated = true; - mIdProxy->addGroup(group); - } - - // Fake a request to return the GroupMetaData. - generateToken(token); - uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptionsVEG opts; // NULL is good. - std::list groupIds; - groupIds.push_back(group.mMeta.mGroupId); // It will just return this one. - - std::cerr << "p3IdServiceVEG::createGroup() Generating Request Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); - - - return true; -} - - - - -bool p3IdServiceVEG::createMsg(uint32_t &token, RsIdMsg &msg, bool isNew) -{ - if (msg.mMeta.mGroupId.empty()) - { - /* new photo */ - std::cerr << "p3IdServiceVEG::createMsg() Missing MsgID"; - std::cerr << std::endl; - return false; - } - - /* check if its a mod or new msg */ - if (msg.mMeta.mOrigMsgId.empty()) - { - std::cerr << "p3IdServiceVEG::createMsg() New Msg"; - std::cerr << std::endl; - - /* new msg, generate a new OrigMsgId */ - msg.mMeta.mOrigMsgId = genRandomId(); - msg.mMeta.mMsgId = msg.mMeta.mOrigMsgId; - } - else - { - std::cerr << "p3IdServiceVEG::createMsg() Modified Msg"; - std::cerr << std::endl; - - /* mod msg, keep orig msg id, generate a new MsgId */ - msg.mMeta.mMsgId = genRandomId(); - } - - std::cerr << "p3IdServiceVEG::createMsg() GroupId: " << msg.mMeta.mGroupId; - std::cerr << std::endl; - std::cerr << "p3IdServiceVEG::createMsg() MsgId: " << msg.mMeta.mMsgId; - std::cerr << std::endl; - std::cerr << "p3IdServiceVEG::createMsg() OrigMsgId: " << msg.mMeta.mOrigMsgId; - std::cerr << std::endl; - - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - mUpdated = true; - mIdProxy->addMsg(msg); - } - - // Fake a request to return the MsgMetaData. - generateToken(token); - uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptionsVEG opts; // NULL is good. - std::list msgIds; - msgIds.push_back(msg.mMeta.mMsgId); // It will just return this one. - - std::cerr << "p3IdServiceVEG::createMsg() Generating Request Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); - - return true; -} - - - -/********************************************************************************************/ - - - -bool IdDataProxy::getGroup(const std::string &id, RsIdGroup &group) -{ - void *groupData = NULL; - RsGroupMetaData meta; - if (getGroupData(id, groupData) && getGroupSummary(id, meta)) - { - RsIdGroup *pG = (RsIdGroup *) groupData; - group = *pG; - - // update definitive version of the metadata. - group.mMeta = meta; - - std::cerr << "IdDataProxy::getGroup() Id: " << id; - std::cerr << " MetaData: " << meta << " DataPointer: " << groupData; - std::cerr << std::endl; - return true; - } - - std::cerr << "IdDataProxy::getGroup() FAILED Id: " << id; - std::cerr << std::endl; - - return false; -} - -bool IdDataProxy::getMsg(const std::string &id, RsIdMsg &msg) -{ - void *msgData = NULL; - RsMsgMetaData meta; - if (getMsgData(id, msgData) && getMsgSummary(id, meta)) - { - RsIdMsg *pM = (RsIdMsg *) msgData; - // Shallow copy of thumbnail. - msg = *pM; - - // update definitive version of the metadata. - msg.mMeta = meta; - - std::cerr << "IdDataProxy::getMsg() Id: " << id; - std::cerr << " MetaData: " << meta << " DataPointer: " << msgData; - std::cerr << std::endl; - return true; - } - - std::cerr << "IdDataProxy::getMsg() FAILED Id: " << id; - std::cerr << std::endl; - - return false; -} - -bool IdDataProxy::addGroup(const RsIdGroup &group) -{ - // Make duplicate. - RsIdGroup *pG = new RsIdGroup(); - *pG = group; - - std::cerr << "IdDataProxy::addGroup()"; - std::cerr << " MetaData: " << pG->mMeta << " DataPointer: " << pG; - std::cerr << std::endl; - - return createGroup(pG); -} - - -bool IdDataProxy::addMsg(const RsIdMsg &msg) -{ - // Make duplicate. - RsIdMsg *pM = new RsIdMsg(); - *pM = msg; - - std::cerr << "IdDataProxy::addMsg()"; - std::cerr << " MetaData: " << pM->mMeta << " DataPointer: " << pM; - std::cerr << std::endl; - - return createMsg(pM); -} - - - - /* These Functions must be overloaded to complete the service */ -bool IdDataProxy::convertGroupToMetaData(void *groupData, RsGroupMetaData &meta) -{ - RsIdGroup *group = (RsIdGroup *) groupData; - meta = group->mMeta; - - return true; -} - -bool IdDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta) -{ - RsIdMsg *page = (RsIdMsg *) msgData; - meta = page->mMeta; - - return true; -} - - - - -/************************************************************************************/ -/************************************************************************************/ -/************************************************************************************/ -/************************************************************************************/ -/************************************************************************************/ - -#if 0 - -/* details are updated */ -bool p3IdServiceVEG::updateIdentity(RsIdData &data) -{ - if (data.mKeyId.empty()) - { - /* new photo */ - - /* generate a temp id */ - data.mKeyId = genRandomId(); - - if (data.mIdType & RSID_TYPE_REALID) - { - data.mGpgIdHash = genRandomId(); - } - else - { - data.mGpgIdHash = ""; - } - - } - - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - mUpdated = true; - - /* add / modify */ - mIds[data.mKeyId] = data; - - return true; -} - - - - -bool p3IdServiceVEG::updateOpinion(RsIdOpinion &opinion) -{ - if (opinion.mKeyId.empty()) - { - /* new photo */ - std::cerr << "p3IdServiceVEG::updateOpinion() Missing KeyId"; - std::cerr << std::endl; - return false; - } - - /* check if its a mod or new page */ - if (opinion.mPeerId.empty()) - { - std::cerr << "p3IdServiceVEG::updateOpinion() Missing PeerId"; - std::cerr << std::endl; - return false; - } - - std::cerr << "p3IdServiceVEG::updateOpinion() KeyId: " << opinion.mKeyId; - std::cerr << std::endl; - std::cerr << "p3IdServiceVEG::updateOpinion() PeerId: " << opinion.mPeerId; - std::cerr << std::endl; - - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - mUpdated = true; - - std::map >::iterator it; - std::map::iterator oit; - - it = mOpinions.find(opinion.mKeyId); - if (it == mOpinions.end()) - { - std::map emptyMap; - mOpinions[opinion.mKeyId] = emptyMap; - - it = mOpinions.find(opinion.mKeyId); - } - - (it->second)[opinion.mPeerId] = opinion; - return true; -} - - -#endif - - - -void p3IdServiceVEG::generateDummyData() -{ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - /* grab all the gpg ids... and make some ids */ - - std::list gpgids; - std::list::iterator it; - - rsPeers->getGPGAllList(gpgids); - - std::string ownId = rsPeers->getGPGOwnId(); - gpgids.push_back(ownId); - - int i; - for(it = gpgids.begin(); it != gpgids.end(); it++) - { - /* create one or two for each one */ - int nIds = 1 + (RSRandom::random_u32() % 2); - for(i = 0; i < nIds; i++) - { - RsIdGroup id; - - RsPeerDetails details; - - //id.mKeyId = genRandomId(); - id.mMeta.mGroupId = genRandomId(); - id.mIdType = RSID_TYPE_REALID; - id.mGpgIdHash = genRandomId(); - - if (rsPeers->getPeerDetails(*it, details)) - { - std::ostringstream out; - out << details.name << "_" << i + 1; - - //id.mNickname = out.str(); - id.mMeta.mGroupName = out.str(); - - id.mGpgIdKnown = true; - - id.mGpgId = *it; - id.mGpgName = details.name; - id.mGpgEmail = details.email; - - if (*it == ownId) - { - id.mIdType |= RSID_RELATION_YOURSELF; - } - else if (rsPeers->isGPGAccepted(*it)) - { - id.mIdType |= RSID_RELATION_FRIEND; - } - else - { - id.mIdType |= RSID_RELATION_OTHER; - } - - } - else - { - std::cerr << "p3IdServiceVEG::generateDummyData() missing" << std::endl; - std::cerr << std::endl; - - id.mIdType |= RSID_RELATION_OTHER; - //id.mNickname = genRandomId(); - id.mMeta.mGroupName = genRandomId(); - id.mGpgIdKnown = false; - } - - //mIds[id.mKeyId] = id; - mIdProxy->addGroup(id); - } - } - -#define MAX_RANDOM_GPGIDS 10 //1000 -#define MAX_RANDOM_PSEUDOIDS 50 //5000 - - int nFakeGPGs = (RSRandom::random_u32() % MAX_RANDOM_GPGIDS); - int nFakePseudoIds = (RSRandom::random_u32() % MAX_RANDOM_PSEUDOIDS); - - /* make some fake gpg ids */ - for(i = 0; i < nFakeGPGs; i++) - { - RsIdGroup id; - - RsPeerDetails details; - - //id.mKeyId = genRandomId(); - id.mMeta.mGroupId = genRandomId(); - id.mIdType = RSID_TYPE_REALID; - id.mGpgIdHash = genRandomId(); - - id.mIdType |= RSID_RELATION_OTHER; - //id.mNickname = genRandomId(); - id.mMeta.mGroupName = genRandomId(); - id.mGpgIdKnown = false; - id.mGpgId = ""; - id.mGpgName = ""; - id.mGpgEmail = ""; - - //mIds[id.mKeyId] = id; - mIdProxy->addGroup(id); - } - - /* make lots of pseudo ids */ - for(i = 0; i < nFakePseudoIds; i++) - { - RsIdGroup id; - - RsPeerDetails details; - - //id.mKeyId = genRandomId(); - id.mMeta.mGroupId = genRandomId(); - id.mIdType = RSID_TYPE_PSEUDONYM; - id.mGpgIdHash = ""; - - //id.mNickname = genRandomId(); - id.mMeta.mGroupName = genRandomId(); - id.mGpgIdKnown = false; - id.mGpgId = ""; - id.mGpgName = ""; - id.mGpgEmail = ""; - - //mIds[id.mKeyId] = id; - mIdProxy->addGroup(id); - } - - mUpdated = true; - - return; -} - - - -std::string rsIdTypeToString(uint32_t idtype) -{ - std::string str; - if (idtype & RSID_TYPE_REALID) - { - str += "GPGID "; - } - if (idtype & RSID_TYPE_PSEUDONYM) - { - str += "PSEUDO "; - } - if (idtype & RSID_RELATION_YOURSELF) - { - str += "YOURSELF "; - } - if (idtype & RSID_RELATION_FRIEND) - { - str += "FRIEND "; - } - if (idtype & RSID_RELATION_FOF) - { - str += "FOF "; - } - if (idtype & RSID_RELATION_OTHER) - { - str += "OTHER "; - } - if (idtype & RSID_RELATION_UNKNOWN) - { - str += "UNKNOWN "; - } - return str; -} - - - - - - - - -/************************************************************************************/ -/************************************************************************************/ -/************************************************************************************/ -/************************************************************************************/ - - -/* here we are running a background process that calculates the reputation scores - * for each of the IDs.... - * - * As this class will be extensively used by many other threads... it is best - * that we don't block at all. This should be in a background thread. - * Perhaps a generic method to handle this will be advisable.... but we do that later. - * - * To start with we will work from the Posted service. - * - * - * - * So Reputation.... - * Three components: - * 1) Your Opinion: Should override everything else. - * 2) Implicit Factors: Know the associated GPG Key. - * 3) Your Friends Opinions: - * 4) Your Friends Calculated Reputation Scores. - * - * Must make sure that there is no Feedback loop in the Reputation calculation. - * - * So: Our Score + Friends Scores => Local Reputation. - * Local Reputation + Friends Reputations => Final Reputation? - * - * Do we need to 'ignore' Non-scores? - * ---> This becomes like the "Best Comment" algorithm from Reddit... - * Use a statistical mechanism to work out a lower bound on Reputation. - * - * But what if your opinion is wrong?.... well likely your friends will - * get their messages and reply... you'll see the missing message - request it - check reputation etc. - * - * So we are going to have three different scores (Own, Peers, (the neighbour) Hood)... - * - * So next question, when do we need to incrementally calculate the score? - * .... how often do we need to recalculate everything -> this could lead to a flux of messages. - * - * - * - * MORE NOTES: - * - * The Opinion Messages will have to be signed by PGP or SSL Keys, to guarantee that we don't - * multiple votes per person... As the message system doesn't handle uniqueness in this respect, - * we might have to do FULL_CALC for everything - This bit TODO. - * - * This will make IdService quite different to the other GXS services. - */ - -/************************************************************************************/ -/* - * Processing Algorithm: - * - Grab all Groups which have received messages. - * (opt 1)-> grab latest msgs for each of these and process => score. - * (opt 2)-> try incremental system (people probably won't change opinions often -> just set them once) - * --> if not possible, fallback to full calculation. - * - * - */ - - -#define ID_BACKGROUND_PERIOD 60 - -int p3IdServiceVEG::background_tick() -{ - std::cerr << "p3IdServiceVEG::background_tick()"; - std::cerr << std::endl; - - // Run Background Stuff. - background_checkTokenRequest(); - - /* every minute - run a background check */ - time_t now = time(NULL); - bool doCheck = false; - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - if (now - mLastBgCheck > ID_BACKGROUND_PERIOD) - { - doCheck = true; - mLastBgCheck = now; - } - } - - if (doCheck) - { - //addExtraDummyData(); - background_requestGroups(); - } - - - - // Add in new votes + comments. - return 0; -} - - - - -/***** Background Processing **** - * - * Process Each Message - as it arrives. - * - * Update - * - */ -#define ID_BG_IDLE 0 -#define ID_BG_REQUEST_GROUPS 1 -#define ID_BG_REQUEST_UNPROCESSED 2 -#define ID_BG_REQUEST_FULLCALC 3 - -bool p3IdServiceVEG::background_checkTokenRequest() -{ - uint32_t token = 0; - uint32_t phase = 0; - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - if (!mBgProcessing) - { - return false; - } - - token = mBgToken; - phase = mBgPhase; - } - - - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (status == GXS_REQUEST_STATUS_COMPLETE) - { - switch(phase) - { - case ID_BG_REQUEST_GROUPS: - background_requestNewMessages(); - break; - case ID_BG_REQUEST_UNPROCESSED: - background_processNewMessages(); - break; - case ID_BG_REQUEST_FULLCALC: - background_processFullCalc(); - break; - default: - break; - } - } - return true; -} - - -bool p3IdServiceVEG::background_requestGroups() -{ - std::cerr << "p3IdServiceVEG::background_requestGroups()"; - std::cerr << std::endl; - - // grab all the subscribed groups. - uint32_t token = 0; - - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - if (mBgProcessing) - { - std::cerr << "p3IdServiceVEG::background_requestGroups() ERROR Already processing, Skip this cycle"; - std::cerr << std::endl; - return false; - } - - mBgProcessing = true; - mBgPhase = ID_BG_REQUEST_GROUPS; - mBgToken = 0; - } - - uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptionsVEG opts; - std::list groupIds; - - opts.mStatusFilter = RSGXS_GROUP_STATUS_NEWMSG; - opts.mStatusMask = RSGXS_GROUP_STATUS_NEWMSG; - - requestGroupInfo(token, ansType, opts, groupIds); - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mBgToken = token; - } - - return true; -} - - - -bool p3IdServiceVEG::background_requestNewMessages() -{ - std::cerr << "p3IdServiceVEG::background_requestNewMessages()"; - std::cerr << std::endl; - - std::list modGroupList; - std::list::iterator it; - - std::list groupIds; - uint32_t token = 0; - - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - token = mBgToken; - } - - if (!getGroupSummary(token, modGroupList)) - { - std::cerr << "p3IdServiceVEG::background_requestNewMessages() ERROR No Group List"; - std::cerr << std::endl; - background_cleanup(); - return false; - } - - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mBgPhase = ID_BG_REQUEST_UNPROCESSED; - mBgToken = 0; - - /* now we process the modGroupList -> a map so we can use it easily later, and create id list too */ - for(it = modGroupList.begin(); it != modGroupList.end(); it++) - { - setGroupStatus(it->mGroupId, 0, RSGXS_GROUP_STATUS_NEWMSG); - - mBgGroupMap[it->mGroupId] = *it; - groupIds.push_back(it->mGroupId); - } - } - - uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptionsVEG opts; - token = 0; - - opts.mStatusFilter = RSGXS_MSG_STATUS_UNPROCESSED; - opts.mStatusMask = RSGXS_MSG_STATUS_UNPROCESSED; - - requestMsgInfo(token, ansType, opts, groupIds); - - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mBgToken = token; - } - return true; -} - - -bool p3IdServiceVEG::background_processNewMessages() -{ - std::cerr << "p3IdServiceVEG::background_processNewMessages()"; - std::cerr << std::endl; - - std::list newMsgList; - std::list::iterator it; - uint32_t token = 0; - - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - token = mBgToken; - } - - if (!getMsgSummary(token, newMsgList)) - { - std::cerr << "p3IdServiceVEG::background_processNewMessages() ERROR No New Msgs"; - std::cerr << std::endl; - background_cleanup(); - return false; - } - - - /* iterate through the msgs.. update the mBgGroupMap with new data, - * and flag these items as modified - so we rewrite them to the db later. - * - * If a message is not an original -> store groupId for requiring full analysis later. - */ - - std::map::iterator mit; - for(it = newMsgList.begin(); it != newMsgList.end(); it++) - { - std::cerr << "p3IdServiceVEG::background_processNewMessages() new MsgId: " << it->mMsgId; - std::cerr << std::endl; - - /* flag each new vote as processed */ - setMessageStatus(it->mMsgId, 0, RSGXS_MSG_STATUS_UNPROCESSED); - - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - mit = mBgGroupMap.find(it->mGroupId); - if (mit == mBgGroupMap.end()) - { - std::cerr << "p3IdServiceVEG::background_processNewMessages() ERROR missing GroupId: "; - std::cerr << it->mGroupId; - std::cerr << std::endl; - - /* error */ - continue; - } - - if (mit->second.mGroupStatus & ID_LOCAL_STATUS_FULL_CALC_FLAG) - { - std::cerr << "p3IdServiceVEG::background_processNewMessages() Group Already marked FULL_CALC"; - std::cerr << std::endl; - - /* already marked */ - continue; - } - - if (it->mMsgId != it->mOrigMsgId) - { - /* - * not original -> hard, redo calc (alt: could substract previous score) - */ - - std::cerr << "p3IdServiceVEG::background_processNewMessages() Update, mark for FULL_CALC"; - std::cerr << std::endl; - - mit->second.mGroupStatus |= ID_LOCAL_STATUS_FULL_CALC_FLAG; - } - else - { - /* - * Try incremental calculation. - * - extract parameters from group. - * - increment, & save back. - * - flag group as modified. - */ - - std::cerr << "p3IdServiceVEG::background_processNewMessages() NewOpt, Try Inc Calc"; - std::cerr << std::endl; - - mit->second.mGroupStatus |= ID_LOCAL_STATUS_INC_CALC_FLAG; - - std::string serviceString; - IdGroupServiceStrData ssData; - - if (!extractIdGroupCache(serviceString, ssData)) - { - /* error */ - std::cerr << "p3IdServiceVEG::background_processNewMessages() ERROR Extracting"; - std::cerr << std::endl; - } - - /* do calcs */ - std::cerr << "p3IdServiceVEG::background_processNewMessages() Extracted: "; - std::cerr << std::endl; - - /* store it back in */ - std::cerr << "p3IdServiceVEG::background_processNewMessages() Stored: "; - std::cerr << std::endl; - - if (!encodeIdGroupCache(serviceString, ssData)) - { - /* error */ - std::cerr << "p3IdServiceVEG::background_processNewMessages() ERROR Storing"; - std::cerr << std::endl; - } - } - } - - - /* now iterate through groups again - * -> update status as we go - * -> record one requiring a full analyssis - */ - - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - std::cerr << "p3IdServiceVEG::background_processNewMessages() Checking Groups for Calc Type"; - std::cerr << std::endl; - - for(mit = mBgGroupMap.begin(); mit != mBgGroupMap.end(); mit++) - { - if (mit->second.mGroupStatus & ID_LOCAL_STATUS_FULL_CALC_FLAG) - { - std::cerr << "p3IdServiceVEG::background_processNewMessages() FullCalc for: "; - std::cerr << mit->second.mGroupId; - std::cerr << std::endl; - - mBgFullCalcGroups.push_back(mit->second.mGroupId); - } - else if (mit->second.mGroupStatus & ID_LOCAL_STATUS_INC_CALC_FLAG) - { - std::cerr << "p3IdServiceVEG::background_processNewMessages() IncCalc done for: "; - std::cerr << mit->second.mGroupId; - std::cerr << std::endl; - - /* set Cache */ - setGroupServiceString(mit->second.mGroupId, mit->second.mServiceString); - } - else - { - /* why is it here? error. */ - std::cerr << "p3IdServiceVEG::background_processNewMessages() ERROR for: "; - std::cerr << mit->second.mGroupId; - std::cerr << std::endl; - } - } - } - - return background_FullCalcRequest(); -} - - -bool p3IdServiceVEG::encodeIdGroupCache(std::string &str, const IdGroupServiceStrData &data) -{ - char line[RSGXS_MAX_SERVICE_STRING]; - - snprintf(line, RSGXS_MAX_SERVICE_STRING, "v1 {%s} {Y:%d O:%d %d %f %f R:%d %d %f %f}", - data.pgpId.c_str(), data.ownScore, - data.opinion.count, data.opinion.nullcount, data.opinion.sum, data.opinion.sumsq, - data.reputation.count, data.reputation.nullcount, data.reputation.sum, data.reputation.sumsq); - - str = line; - return true; -} - - -bool p3IdServiceVEG::extractIdGroupCache(std::string &str, IdGroupServiceStrData &data) -{ - char pgpline[RSGXS_MAX_SERVICE_STRING]; - char scoreline[RSGXS_MAX_SERVICE_STRING]; - - uint32_t iOwnScore; - IdRepCumulScore iOpin; - IdRepCumulScore iRep; - - // split into two parts. - if (2 != sscanf(str.c_str(), "v1 {%[^}]} {%[^}]", pgpline, scoreline)) - { - std::cerr << "p3IdServiceVEG::extractIdGroupCache() Failed to extract Two Parts"; - std::cerr << std::endl; - return false; - } - - std::cerr << "p3IdServiceVEG::extractIdGroupCache() pgpline: " << pgpline; - std::cerr << std::endl; - std::cerr << "p3IdServiceVEG::extractIdGroupCache() scoreline: " << scoreline; - std::cerr << std::endl; - - std::string pgptmp = pgpline; - if (pgptmp.length() > 5) - { - std::cerr << "p3IdServiceVEG::extractIdGroupCache() Believe to have pgpId: " << pgptmp; - std::cerr << std::endl; - data.pgpIdKnown = true; - data.pgpId = pgptmp; - } - else - { - std::cerr << "p3IdServiceVEG::extractIdGroupCache() Think pgpId Invalid"; - std::cerr << std::endl; - data.pgpIdKnown = false; - } - - - if (9 == sscanf(scoreline, " Y:%d O:%d %d %lf %lf R:%d %d %lf %lf", &iOwnScore, - &(iOpin.count), &(iOpin.nullcount), &(iOpin.sum), &(iOpin.sumsq), - &(iRep.count), &(iRep.nullcount), &(iRep.sum), &(iRep.sumsq))) - { - data.ownScore = iOwnScore; - data.opinion = iOpin; - data.reputation = iRep; - return true; - } - - std::cerr << "p3IdServiceVEG::extractIdGroupCache() Failed to extract scores"; - std::cerr << std::endl; - - return false; -} - - - -bool p3IdServiceVEG::background_FullCalcRequest() -{ - /* - * grab an GroupId from List. - * - If empty, we are finished. - * - request all latest mesgs - */ - - std::list groupIds; - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mBgPhase = ID_BG_REQUEST_FULLCALC; - mBgToken = 0; - mBgGroupMap.clear(); - - if (mBgFullCalcGroups.empty()) - { - /* finished! */ - background_cleanup(); - return true; - - } - - groupIds.push_back(mBgFullCalcGroups.front()); - mBgFullCalcGroups.pop_front(); - - } - - /* request the summary info from the parents */ - uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; - uint32_t token = 0; - RsTokReqOptionsVEG opts; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - - requestMsgInfo(token, ansType, opts, groupIds); - - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mBgToken = token; - } - return true; -} - - - - -bool p3IdServiceVEG::background_processFullCalc() -{ - std::cerr << "p3IdServiceVEG::background_processFullCalc()"; - std::cerr << std::endl; - - std::list msgList; - std::list::iterator it; - - RsIdMsg msg; - - bool validmsgs = false; - - /* calc variables */ - uint32_t opinion_count = 0; - uint32_t opinion_nullcount = 0; - double opinion_sum = 0; - double opinion_sumsq = 0; - - uint32_t rep_count = 0; - uint32_t rep_nullcount = 0; - double rep_sum = 0; - double rep_sumsq = 0; - - while(getMsgData(mBgToken, msg)) - { - std::cerr << "p3IdServiceVEG::background_processFullCalc() Msg:"; - std::cerr << msg; - std::cerr << std::endl; - - validmsgs = true; - - /* for each msg ... extract score, and reputation */ - if (msg.mOpinion != 0) - { - opinion_count++; - opinion_sum += msg.mOpinion; - opinion_sum += (msg.mOpinion * msg.mOpinion); - } - else - { - opinion_nullcount++; - } - - - /* for each msg ... extract score, and reputation */ - if (msg.mReputation != 0) - { - rep_nullcount++; - rep_sum += msg.mReputation; - rep_sum += (msg.mReputation * msg.mReputation); - } - else - { - rep_nullcount++; - } - } - - double opinion_avg = 0; - double opinion_var = 0; - double opinion_frac = 0; - - double rep_avg = 0; - double rep_var = 0; - double rep_frac = 0; - - - if (opinion_count) - { - opinion_avg = opinion_sum / opinion_count; - opinion_var = (opinion_sumsq - opinion_count * opinion_avg * opinion_avg) / opinion_count; - opinion_frac = opinion_count / ((float) (opinion_count + opinion_nullcount)); - } - - if (rep_count) - { - rep_avg = rep_sum / rep_count; - rep_var = (rep_sumsq - rep_count * rep_avg * rep_avg) / rep_count; - rep_frac = rep_count / ((float) (rep_count + rep_nullcount)); - } - - - if (validmsgs) - { - std::string groupId = msg.mMeta.mGroupId; - - std::string serviceString; - IdGroupServiceStrData ssData; - - - if (!encodeIdGroupCache(serviceString, ssData)) - { - std::cerr << "p3IdServiceVEG::background_updateVoteCounts() Failed to encode Votes"; - std::cerr << std::endl; - } - else - { - std::cerr << "p3IdServiceVEG::background_updateVoteCounts() Encoded String: " << serviceString; - std::cerr << std::endl; - /* store new result */ - setGroupServiceString(it->mMsgId, serviceString); - } - } - - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mBgPhase = ID_BG_IDLE; - mBgToken = 0; - } - - return background_FullCalcRequest(); -} - - -bool p3IdServiceVEG::background_cleanup() -{ - std::cerr << "p3IdServiceVEG::background_cleanup()"; - std::cerr << std::endl; - - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - // Cleanup. - mBgProcessing = false; - mBgPhase = ID_BG_IDLE; - mBgToken = 0; - mBgGroupMap.clear(); - mBgFullCalcGroups.clear(); - - return true; -} - - -std::ostream &operator<<(std::ostream &out, const RsIdGroup &grp) -{ - out << "RsIdGroup: Meta: " << grp.mMeta; - out << " IdType: " << grp.mIdType << " GpgIdHash: " << grp.mGpgIdHash; - out << "(((Unusable: ( GpgIdKnown: " << grp.mGpgIdKnown << " GpgId: " << grp.mGpgId; - out << " GpgName: " << grp.mGpgName << " GpgEmail: " << grp.mGpgEmail << ") )))"; - out << std::endl; - - return out; -} - -std::ostream &operator<<(std::ostream &out, const RsIdMsg &msg) -{ - out << "RsIdMsg: Meta: " << msg.mMeta; - //out << " IdType: " << grp.mIdType << " GpgIdHash: " << grp.mGpgIdHash; - out << std::endl; - - return out; -} - diff --git a/libretroshare/src/services/p3idserviceVEG.h b/libretroshare/src/services/p3idserviceVEG.h deleted file mode 100644 index d0618b1d4..000000000 --- a/libretroshare/src/services/p3idserviceVEG.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * libretroshare/src/services: p3idservice.h - * - * Identity interface for RetroShare. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#ifndef P3_IDENTITY_SERVICE_VEG_HEADER -#define P3_IDENTITY_SERVICE_VEG_HEADER - -#include "services/p3service.h" -#include "services/p3gxsserviceVEG.h" - -#include "retroshare/rsidentityVEG.h" - -#include -#include - -/* - * Identity Service - * - */ - -class IdDataProxy: public GxsDataProxyVEG -{ - public: - - bool getGroup(const std::string &id, RsIdGroup &group); - bool getMsg(const std::string &id, RsIdMsg &msg); - - bool addGroup(const RsIdGroup &group); - bool addMsg(const RsIdMsg &msg); - - /* These Functions must be overloaded to complete the service */ -virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta); -virtual bool convertMsgToMetaData(void *msgData, RsMsgMetaData &meta); -}; - - - -// INTERNAL DATA TYPES... -// Describes data stored in GroupServiceString. -class IdRepCumulScore -{ -public: - uint32_t count; - uint32_t nullcount; - double sum; - double sumsq; - - // derived parameters: -}; - - -class IdGroupServiceStrData -{ -public: - IdGroupServiceStrData() { pgpIdKnown = false; } - bool pgpIdKnown; - std::string pgpId; - - uint32_t ownScore; - IdRepCumulScore opinion; - IdRepCumulScore reputation; - -}; - -#define ID_LOCAL_STATUS_FULL_CALC_FLAG 0x00010000 -#define ID_LOCAL_STATUS_INC_CALC_FLAG 0x00020000 - -class p3IdServiceVEG: public p3GxsDataServiceVEG, public RsIdentityVEG -{ - public: - - p3IdServiceVEG(uint16_t type); - -virtual int tick(); - - public: - - - /* changed? */ -virtual bool updated(); - - /* From RsTokenService */ - /* Data Requests */ -virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); -virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); -virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds); - - /* Generic Lists */ -virtual bool getGroupList( const uint32_t &token, std::list &groupIds); -virtual bool getMsgList( const uint32_t &token, std::list &msgIds); - - /* Generic Summary */ -virtual bool getGroupSummary( const uint32_t &token, std::list &groupInfo); -virtual bool getMsgSummary( const uint32_t &token, std::list &msgInfo); - - /* Actual Data -> specific to Interface */ -virtual bool getGroupData(const uint32_t &token, RsIdGroup &group); -virtual bool getMsgData(const uint32_t &token, RsIdMsg &msg); - - /* Poll */ -virtual uint32_t requestStatus(const uint32_t token); - - /* Cancel Request */ -virtual bool cancelRequest(const uint32_t &token); - - ////////////////////////////////////////////////////////////////////////////// -virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask); -virtual bool setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask); -virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask); -virtual bool setMessageServiceString(const std::string &msgId, const std::string &str); -virtual bool setGroupServiceString(const std::string &grpId, const std::string &str); - -virtual bool groupRestoreKeys(const std::string &groupId); -virtual bool groupShareKeys(const std::string &groupId, std::list& peers); - -virtual bool createGroup(uint32_t &token, RsIdGroup &group, bool isNew); -virtual bool createMsg(uint32_t &token, RsIdMsg &msg, bool isNew); - - - private: - -virtual void generateDummyData(); - -std::string genRandomId(); - - int background_tick(); - bool background_checkTokenRequest(); - bool background_requestGroups(); - bool background_requestNewMessages(); - bool background_processNewMessages(); - bool background_FullCalcRequest(); - bool background_processFullCalc(); - - bool background_cleanup(); - - bool encodeIdGroupCache(std::string &str, const IdGroupServiceStrData &data); - bool extractIdGroupCache(std::string &str, IdGroupServiceStrData &data); - - IdDataProxy *mIdProxy; - - RsMutex mIdMtx; - - /***** below here is locked *****/ - bool mLastBgCheck; - bool mBgProcessing; - - uint32_t mBgToken; - uint32_t mBgPhase; - - std::map mBgGroupMap; - std::list mBgFullCalcGroups; - - - bool mUpdated; - -#if 0 - std::map mIds; - std::map > mOpinions; - - std::map mReputations; // this is created locally. -#endif - -}; - -#endif diff --git a/libretroshare/src/services/p3wiki.cc b/libretroshare/src/services/p3wiki.cc index 29cc0200e..9b3f01aa4 100644 --- a/libretroshare/src/services/p3wiki.cc +++ b/libretroshare/src/services/p3wiki.cc @@ -7,7 +7,7 @@ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. + * License Version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/libretroshare/src/services/p3wiki.h b/libretroshare/src/services/p3wiki.h index 01d82767e..5700563bc 100644 --- a/libretroshare/src/services/p3wiki.h +++ b/libretroshare/src/services/p3wiki.h @@ -7,7 +7,7 @@ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. + * License Version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/libretroshare/src/services/p3wikiserviceVEG.cc b/libretroshare/src/services/p3wikiserviceVEG.cc deleted file mode 100644 index dc0a1f7b9..000000000 --- a/libretroshare/src/services/p3wikiserviceVEG.cc +++ /dev/null @@ -1,595 +0,0 @@ -/* - * libretroshare/src/services p3wikiservice.cc - * - * Wiki interface for RetroShare. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "services/p3wikiserviceVEG.h" - -#include "util/rsrandom.h" - -/**** - * #define WIKI_DEBUG 1 - ****/ - -RsWikiVEG *rsWikiVEG = NULL; - - -/********************************************************************************/ -/******************* Startup / Tick ******************************************/ -/********************************************************************************/ - -p3WikiServiceVEG::p3WikiServiceVEG(uint16_t type) - :p3GxsDataServiceVEG(type, new WikiDataProxy()), mWikiMtx("p3WikiService"), mUpdated(true) -{ - RsStackMutex stack(mWikiMtx); /********** STACK LOCKED MTX ******/ - - mWikiProxy = (WikiDataProxy *) mProxy; - return; -} - - -int p3WikiServiceVEG::tick() -{ - //std::cerr << "p3WikiServiceVEG::tick()"; - //std::cerr << std::endl; - - fakeprocessrequests(); - - return 0; -} - -bool p3WikiServiceVEG::updated() -{ - RsStackMutex stack(mWikiMtx); /********** STACK LOCKED MTX ******/ - - if (mUpdated) - { - mUpdated = false; - return true; - } - return false; -} - - - - /* Data Requests */ -bool p3WikiServiceVEG::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) -{ - generateToken(token); - std::cerr << "p3WikiServiceVEG::requestGroupInfo() gets Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); - - return true; -} - -bool p3WikiServiceVEG::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) -{ - generateToken(token); - std::cerr << "p3WikiServiceVEG::requestMsgInfo() gets Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds); - - return true; -} - -bool p3WikiServiceVEG::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds) -{ - generateToken(token); - std::cerr << "p3WikiServiceVEG::requestMsgRelatedInfo() gets Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); - - return true; -} - - /* Generic Lists */ -bool p3WikiServiceVEG::getGroupList( const uint32_t &token, std::list &groupIds) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_LIST) - { - std::cerr << "p3WikiServiceVEG::getGroupList() ERROR AnsType Wrong" << std::endl; - return false; - } - - if (reqtype != GXS_REQUEST_TYPE_GROUPS) - { - std::cerr << "p3WikiServiceVEG::getGroupList() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3WikiServiceVEG::getGroupList() ERROR Status Incomplete" << std::endl; - return false; - } - - bool ans = loadRequestOutList(token, groupIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - return ans; -} - - - - -bool p3WikiServiceVEG::getMsgList( const uint32_t &token, std::list &msgIds) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_LIST) - { - std::cerr << "p3WikiServiceVEG::getMsgList() ERROR AnsType Wrong" << std::endl; - return false; - } - - if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) - { - std::cerr << "p3WikiServiceVEG::getMsgList() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3WikiServiceVEG::getMsgList() ERROR Status Incomplete" << std::endl; - return false; - } - - bool ans = loadRequestOutList(token, msgIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - return ans; -} - - - /* Generic Summary */ -bool p3WikiServiceVEG::getGroupSummary( const uint32_t &token, std::list &groupInfo) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY) - { - std::cerr << "p3WikiServiceVEG::getGroupSummary() ERROR AnsType Wrong" << std::endl; - return false; - } - - if (reqtype != GXS_REQUEST_TYPE_GROUPS) - { - std::cerr << "p3WikiServiceVEG::getGroupSummary() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3WikiServiceVEG::getGroupSummary() ERROR Status Incomplete" << std::endl; - return false; - } - - std::list groupIds; - bool ans = loadRequestOutList(token, groupIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - /* convert to RsGroupMetaData */ - mProxy->getGroupSummary(groupIds, groupInfo); - - return ans; -} - -bool p3WikiServiceVEG::getMsgSummary( const uint32_t &token, std::list &msgInfo) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY) - { - std::cerr << "p3WikiServiceVEG::getMsgSummary() ERROR AnsType Wrong" << std::endl; - return false; - } - - if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) - { - std::cerr << "p3WikiServiceVEG::getMsgSummary() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3WikiServiceVEG::getMsgSummary() ERROR Status Incomplete" << std::endl; - return false; - } - - std::list msgIds; - bool ans = loadRequestOutList(token, msgIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - /* convert to RsMsgMetaData */ - mProxy->getMsgSummary(msgIds, msgInfo); - - return ans; -} - - - /* Specific Service Data */ -bool p3WikiServiceVEG::getGroupData(const uint32_t &token, RsWikiGroup &group) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - - if (anstype != RS_TOKREQ_ANSTYPE_DATA) - { - std::cerr << "p3WikiServiceVEG::getGroupData() ERROR AnsType Wrong" << std::endl; - return false; - } - - if (reqtype != GXS_REQUEST_TYPE_GROUPS) - { - std::cerr << "p3WikiServiceVEG::getGroupData() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3WikiServiceVEG::getGroupData() ERROR Status Incomplete" << std::endl; - return false; - } - - std::string id; - if (!popRequestOutList(token, id)) - { - /* finished */ - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - return false; - } - - /* convert to RsWikiAlbum */ - bool ans = mWikiProxy->getGroup(id, group); - return ans; -} - - -bool p3WikiServiceVEG::getMsgData(const uint32_t &token, RsWikiPage &page) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - - if (anstype != RS_TOKREQ_ANSTYPE_DATA) - { - std::cerr << "p3WikiServiceVEG::getMsgData() ERROR AnsType Wrong" << std::endl; - return false; - } - - if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) - { - std::cerr << "p3WikiServiceVEG::getMsgData() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3WikiServiceVEG::getMsgData() ERROR Status Incomplete" << std::endl; - return false; - } - - std::string id; - if (!popRequestOutList(token, id)) - { - /* finished */ - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - return false; - } - - /* convert to RsWikiAlbum */ - bool ans = mWikiProxy->getPage(id, page); - return ans; -} - - - - /* Poll */ -uint32_t p3WikiServiceVEG::requestStatus(const uint32_t token) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - return status; -} - - - /* Cancel Request */ -bool p3WikiServiceVEG::cancelRequest(const uint32_t &token) -{ - return clearRequest(token); -} - - - ////////////////////////////////////////////////////////////////////////////// -bool p3WikiServiceVEG::setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask) -{ - return mWikiProxy->setMessageStatus(msgId, status, statusMask); -} - -bool p3WikiServiceVEG::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask) -{ - return mWikiProxy->setGroupStatus(groupId, status, statusMask); -} - -bool p3WikiServiceVEG::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) -{ - return mWikiProxy->setGroupSubscribeFlags(groupId, subscribeFlags, subscribeMask); -} - -bool p3WikiServiceVEG::setMessageServiceString(const std::string &msgId, const std::string &str) -{ - return mWikiProxy->setMessageServiceString(msgId, str); -} - -bool p3WikiServiceVEG::setGroupServiceString(const std::string &grpId, const std::string &str) -{ - return mWikiProxy->setGroupServiceString(grpId, str); -} - - -bool p3WikiServiceVEG::groupRestoreKeys(const std::string &groupId) -{ - return false; -} - -bool p3WikiServiceVEG::groupShareKeys(const std::string &groupId, std::list& peers) -{ - return false; -} - - -/********************************************************************************************/ - - -std::string p3WikiServiceVEG::genRandomId() -{ - std::string randomId; - for(int i = 0; i < 20; i++) - { - randomId += (char) ('a' + (RSRandom::random_u32() % 26)); - } - - return randomId; -} - -bool p3WikiServiceVEG::createGroup(uint32_t &token, RsWikiGroup &group, bool isNew) -{ - if (group.mMeta.mGroupId.empty()) - { - /* new photo */ - - /* generate a temp id */ - group.mMeta.mGroupId = genRandomId(); - } - else - { - std::cerr << "p3WikiServiceVEG::createGroup() Group with existing Id... dropping"; - std::cerr << std::endl; - return false; - } - - { - RsStackMutex stack(mWikiMtx); /********** STACK LOCKED MTX ******/ - - mUpdated = true; - mWikiProxy->addGroup(group); - } - - // Fake a request to return the GroupMetaData. - generateToken(token); - uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptionsVEG opts; // NULL is good. - std::list groupIds; - groupIds.push_back(group.mMeta.mGroupId); // It will just return this one. - - std::cerr << "p3WikiServiceVEG::createGroup() Generating Request Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); - - return true; -} - - - -bool p3WikiServiceVEG::createPage(uint32_t &token, RsWikiPage &page, bool isNew) -{ - if (page.mMeta.mGroupId.empty()) - { - /* new photo */ - std::cerr << "p3WikiServiceVEG::createPage() Missing PageID"; - std::cerr << std::endl; - return false; - } - - /* check if its a mod or new page */ - if (page.mMeta.mOrigMsgId.empty()) - { - std::cerr << "p3WikiServiceVEG::createPage() New Page"; - std::cerr << std::endl; - - /* new page, generate a new OrigPageId */ - page.mMeta.mOrigMsgId = genRandomId(); - page.mMeta.mMsgId = page.mMeta.mOrigMsgId; - } - else - { - std::cerr << "p3WikiServiceVEG::createPage() Modified Page"; - std::cerr << std::endl; - - /* mod page, keep orig page id, generate a new PageId */ - page.mMeta.mMsgId = genRandomId(); - } - - std::cerr << "p3WikiServiceVEG::createPage() GroupId: " << page.mMeta.mGroupId; - std::cerr << std::endl; - std::cerr << "p3WikiServiceVEG::createPage() PageId: " << page.mMeta.mMsgId; - std::cerr << std::endl; - std::cerr << "p3WikiServiceVEG::createPage() OrigPageId: " << page.mMeta.mOrigMsgId; - std::cerr << std::endl; - - { - RsStackMutex stack(mWikiMtx); /********** STACK LOCKED MTX ******/ - - mUpdated = true; - mWikiProxy->addPage(page); - } - - // Fake a request to return the MsgMetaData. - generateToken(token); - uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptionsVEG opts; // NULL is good. - std::list msgIds; - msgIds.push_back(page.mMeta.mMsgId); // It will just return this one. - - std::cerr << "p3WikiServiceVEG::createPage() Generating Request Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); - - return true; -} - - - -/********************************************************************************************/ - - - -bool WikiDataProxy::getGroup(const std::string &id, RsWikiGroup &group) -{ - void *groupData = NULL; - RsGroupMetaData meta; - if (getGroupData(id, groupData) && getGroupSummary(id, meta)) - { - RsWikiGroup *pG = (RsWikiGroup *) groupData; - group = *pG; - - // update definitive version of the metadata. - group.mMeta = meta; - - std::cerr << "WikiDataProxy::getGroup() Id: " << id; - std::cerr << " MetaData: " << meta << " DataPointer: " << groupData; - std::cerr << std::endl; - return true; - } - - std::cerr << "WikiDataProxy::getGroup() FAILED Id: " << id; - std::cerr << std::endl; - - return false; -} - -bool WikiDataProxy::getPage(const std::string &id, RsWikiPage &page) -{ - void *msgData = NULL; - RsMsgMetaData meta; - if (getMsgData(id, msgData) && getMsgSummary(id, meta)) - { - RsWikiPage *pP = (RsWikiPage *) msgData; - // Shallow copy of thumbnail. - page = *pP; - - // update definitive version of the metadata. - page.mMeta = meta; - - std::cerr << "WikiDataProxy::getPage() Id: " << id; - std::cerr << " MetaData: " << meta << " DataPointer: " << msgData; - std::cerr << std::endl; - return true; - } - - std::cerr << "WikiDataProxy::getPage() FAILED Id: " << id; - std::cerr << std::endl; - - return false; -} - -bool WikiDataProxy::addGroup(const RsWikiGroup &group) -{ - // Make duplicate. - RsWikiGroup *pG = new RsWikiGroup(); - *pG = group; - - std::cerr << "WikiDataProxy::addGroup()"; - std::cerr << " MetaData: " << pG->mMeta << " DataPointer: " << pG; - std::cerr << std::endl; - - return createGroup(pG); -} - - -bool WikiDataProxy::addPage(const RsWikiPage &page) -{ - // Make duplicate. - RsWikiPage *pP = new RsWikiPage(); - *pP = page; - - std::cerr << "WikiDataProxy::addPage()"; - std::cerr << " MetaData: " << pP->mMeta << " DataPointer: " << pP; - std::cerr << std::endl; - - return createMsg(pP); -} - - - - /* These Functions must be overloaded to complete the service */ -bool WikiDataProxy::convertGroupToMetaData(void *groupData, RsGroupMetaData &meta) -{ - RsWikiGroup *group = (RsWikiGroup *) groupData; - meta = group->mMeta; - - return true; -} - -bool WikiDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta) -{ - RsWikiPage *page = (RsWikiPage *) msgData; - meta = page->mMeta; - - return true; -} diff --git a/libretroshare/src/services/p3wikiserviceVEG.h b/libretroshare/src/services/p3wikiserviceVEG.h deleted file mode 100644 index f172f4d3f..000000000 --- a/libretroshare/src/services/p3wikiserviceVEG.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * libretroshare/src/services: p3wikiservice.h - * - * Wiki interface for RetroShare. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#ifndef P3_WIKI_SERVICE_VEG_HEADER -#define P3_WIKI_SERVICE_VEG_HEADER - -#include "services/p3gxsserviceVEG.h" -#include "retroshare/rswikiVEG.h" - -#include -#include - -/* - * Wiki Service - * - * This is an example service for the new cache system. - * For the moment, it will only hold data passed to it from the GUI. - * and spew that back when asked.... - * - * We are doing it like this - so we can check the required interface functionality. - * - * Expect it won't take long before it'll be properly linked into the backend! - * - * This will be transformed into a Plugin Service, once the basics have been worked out. - * - */ - -class WikiDataProxy: public GxsDataProxyVEG -{ - public: - - bool getGroup(const std::string &id, RsWikiGroup &group); - bool getPage(const std::string &id, RsWikiPage &wiki); - - bool addGroup(const RsWikiGroup &group); - bool addPage(const RsWikiPage &page); - - /* These Functions must be overloaded to complete the service */ -virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta); -virtual bool convertMsgToMetaData(void *msgData, RsMsgMetaData &meta); -}; - - -class p3WikiServiceVEG: public p3GxsDataServiceVEG, public RsWikiVEG -{ - public: - - p3WikiServiceVEG(uint16_t type); - -virtual int tick(); - - public: - - -virtual bool updated(); - - /* Data Requests */ -virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); -virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); -virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds); - - /* Generic Lists */ -virtual bool getGroupList( const uint32_t &token, std::list &groupIds); -virtual bool getMsgList( const uint32_t &token, std::list &msgIds); - - /* Generic Summary */ -virtual bool getGroupSummary( const uint32_t &token, std::list &groupInfo); -virtual bool getMsgSummary( const uint32_t &token, std::list &msgInfo); - - /* Actual Data -> specific to Interface */ - /* Specific Service Data */ -virtual bool getGroupData(const uint32_t &token, RsWikiGroup &group); -virtual bool getMsgData(const uint32_t &token, RsWikiPage &page); - - /* Poll */ -virtual uint32_t requestStatus(const uint32_t token); - - /* Cancel Request */ -virtual bool cancelRequest(const uint32_t &token); - - ////////////////////////////////////////////////////////////////////////////// -virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask); -virtual bool setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask); -virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask); -virtual bool setMessageServiceString(const std::string &msgId, const std::string &str); -virtual bool setGroupServiceString(const std::string &grpId, const std::string &str); - -virtual bool groupRestoreKeys(const std::string &groupId); -virtual bool groupShareKeys(const std::string &groupId, std::list& peers); - -virtual bool createGroup(uint32_t &token, RsWikiGroup &group, bool isNew); -virtual bool createPage(uint32_t &token, RsWikiPage &page, bool isNew); - - private: - -std::string genRandomId(); - - WikiDataProxy *mWikiProxy; - - RsMutex mWikiMtx; - - bool mUpdated; - - -}; - -#endif diff --git a/libretroshare/src/services/p3wire.cc b/libretroshare/src/services/p3wire.cc new file mode 100644 index 000000000..a25fe9112 --- /dev/null +++ b/libretroshare/src/services/p3wire.cc @@ -0,0 +1,207 @@ +/* + * libretroshare/src/services p3wire.cc + * + * Wire interface for RetroShare. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "services/p3wire.h" +#include "serialiser/rswireitems.h" + +#include "util/rsrandom.h" + +/**** + * #define WIRE_DEBUG 1 + ****/ + +RsWire *rsWire = NULL; + + +p3Wire::p3Wire(RsGeneralDataService* gds, RsNetworkExchangeService* nes) + :RsGenExchange(gds, nes, new RsGxsWireSerialiser(), RS_SERVICE_GXSV1_TYPE_WIRE), RsWire(this), mWireMtx("WireMtx") +{ + +} + +void p3Wire::service_tick() +{ + return; +} + + +void p3Wire::notifyChanges(std::vector& changes) +{ + std::cerr << "p3Wire::notifyChanges() New stuff"; + std::cerr << std::endl; + + receiveChanges(changes); +} + + /* Specific Service Data */ +bool p3Wire::getGroupData(const uint32_t &token, std::vector &groups) +{ + std::cerr << "p3Wire::getGroupData()"; + std::cerr << std::endl; + + std::vector grpData; + bool ok = RsGenExchange::getGroupData(token, grpData); + + if(ok) + { + std::vector::iterator vit = grpData.begin(); + + for(; vit != grpData.end(); vit++) + { + RsGxsWireGroupItem* item = dynamic_cast(*vit); + + if (item) + { + RsWireGroup group = item->group; + group.mMeta = item->meta; + delete item; + groups.push_back(group); + + std::cerr << "p3Wire::getGroupData() Adding WireGroup to Vector: "; + std::cerr << std::endl; + std::cerr << group; + std::cerr << std::endl; + } + else + { + std::cerr << "Not a WireGroupItem, deleting!" << std::endl; + delete *vit; + } + + } + } + return ok; +} + + +bool p3Wire::getPulseData(const uint32_t &token, std::vector &pulses) +{ + GxsMsgDataMap msgData; + bool ok = RsGenExchange::getMsgData(token, msgData); + + if(ok) + { + GxsMsgDataMap::iterator mit = msgData.begin(); + + for(; mit != msgData.end(); mit++) + { + RsGxsGroupId grpId = mit->first; + std::vector& msgItems = mit->second; + std::vector::iterator vit = msgItems.begin(); + + for(; vit != msgItems.end(); vit++) + { + RsGxsWirePulseItem* item = dynamic_cast(*vit); + + if(item) + { + RsWirePulse pulse = item->pulse; + pulse.mMeta = item->meta; + pulses.push_back(pulse); + delete item; + } + else + { + std::cerr << "Not a WikiPulse Item, deleting!" << std::endl; + delete *vit; + } + } + } + } + return ok; +} + + +bool p3Wire::createGroup(uint32_t &token, RsWireGroup &group) +{ + RsGxsWireGroupItem* groupItem = new RsGxsWireGroupItem(); + groupItem->group = group; + groupItem->meta = group.mMeta; + + std::cerr << "p3Wire::createGroup(): "; + std::cerr << std::endl; + std::cerr << group; + std::cerr << std::endl; + + std::cerr << "p3Wire::createGroup() pushing to RsGenExchange"; + std::cerr << std::endl; + + RsGenExchange::publishGroup(token, groupItem); + return true; +} + + +bool p3Wire::createPulse(uint32_t &token, RsWirePulse &pulse) +{ + std::cerr << "p3Wire::createPulse(): " << pulse; + std::cerr << std::endl; + + RsGxsWirePulseItem* pulseItem = new RsGxsWirePulseItem(); + pulseItem->pulse = pulse; + pulseItem->meta = pulse.mMeta; + + RsGenExchange::publishMsg(token, pulseItem); + return true; +} + + +std::ostream &operator<<(std::ostream &out, const RsWireGroup &group) +{ + out << "RsWireGroup [ "; + out << " Name: " << group.mMeta.mGroupName; + out << " Desc: " << group.mDescription; + //out << " Category: " << group.mCategory; + out << " ]"; + return out; +} + +std::ostream &operator<<(std::ostream &out, const RsWirePulse &pulse) +{ + out << "RsWirePulse [ "; + out << "Title: " << pulse.mMeta.mMsgName; + out << "PulseText: " << pulse.mPulseText; + out << "]"; + return out; +} + +/***** FOR TESTING *****/ + +std::string p3Wire::genRandomId() +{ + std::string randomId; + for(int i = 0; i < 20; i++) + { + randomId += (char) ('a' + (RSRandom::random_u32() % 26)); + } + + return randomId; +} + +void p3Wire::generateDummyData() +{ + +} + + diff --git a/libretroshare/src/services/p3wire.h b/libretroshare/src/services/p3wire.h new file mode 100644 index 000000000..8d93961e8 --- /dev/null +++ b/libretroshare/src/services/p3wire.h @@ -0,0 +1,71 @@ +/* + * libretroshare/src/services: p3wire.h + * + * Wiki interface for RetroShare. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#ifndef P3_WIRE_SERVICE_HEADER +#define P3_WIRE_SERVICE_HEADER + +#include "retroshare/rswire.h" +#include "gxs/rsgenexchange.h" + +#include +#include + +/* + * Wiki Service + * + * + */ + +class p3Wire: public RsGenExchange, public RsWire +{ +public: + p3Wire(RsGeneralDataService* gds, RsNetworkExchangeService* nes); + +protected: + +virtual void notifyChanges(std::vector& changes) ; + +public: + +virtual void service_tick(); + + /* Specific Service Data */ +virtual bool getGroupData(const uint32_t &token, std::vector &groups); +virtual bool getPulseData(const uint32_t &token, std::vector &pulses); + +virtual bool createGroup(uint32_t &token, RsWireGroup &group); +virtual bool createPulse(uint32_t &token, RsWirePulse &pulse); + + private: + +virtual void generateDummyData(); +std::string genRandomId(); + + RsMutex mWireMtx; + + +}; + +#endif diff --git a/libretroshare/src/services/p3wireVEG.cc b/libretroshare/src/services/p3wireVEG.cc deleted file mode 100644 index 3aec51a0a..000000000 --- a/libretroshare/src/services/p3wireVEG.cc +++ /dev/null @@ -1,939 +0,0 @@ -/* - * libretroshare/src/services p3wire.cc - * - * Wire interface for RetroShare. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "services/p3wireVEG.h" - -#include "util/rsrandom.h" - -/**** - * #define WIKI_DEBUG 1 - ****/ - -RsWireVEG *rsWireVEG = NULL; - - -/********************************************************************************/ -/******************* Startup / Tick ******************************************/ -/********************************************************************************/ - -p3WireVEG::p3WireVEG(uint16_t type) - :p3GxsDataServiceVEG(type, new WireDataProxy()), mWireMtx("p3Wire"), mUpdated(true) -{ - RsStackMutex stack(mWireMtx); /********** STACK LOCKED MTX ******/ - - mWireProxy = (WireDataProxy *) mProxy; - return; -} - - -int p3WireVEG::tick() -{ - //std::cerr << "p3WireVEG::tick()"; - //std::cerr << std::endl; - - fakeprocessrequests(); - - return 0; -} - -bool p3WireVEG::updated() -{ - RsStackMutex stack(mWireMtx); /********** STACK LOCKED MTX ******/ - - if (mUpdated) - { - mUpdated = false; - return true; - } - return false; -} - - - - /* Data Requests */ -bool p3WireVEG::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) -{ - generateToken(token); - std::cerr << "p3WireVEG::requestGroupInfo() gets Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); - - return true; -} - -bool p3WireVEG::requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds) -{ - generateToken(token); - std::cerr << "p3WireVEG::requestMsgInfo() gets Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGS, groupIds); - - return true; -} - -bool p3WireVEG::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds) -{ - generateToken(token); - std::cerr << "p3WireVEG::requestMsgRelatedInfo() gets Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); - - return true; -} - - /* Generic Lists */ -bool p3WireVEG::getGroupList( const uint32_t &token, std::list &groupIds) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_LIST) - { - std::cerr << "p3WireVEG::getGroupList() ERROR AnsType Wrong" << std::endl; - return false; - } - - if (reqtype != GXS_REQUEST_TYPE_GROUPS) - { - std::cerr << "p3WireVEG::getGroupList() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3WireVEG::getGroupList() ERROR Status Incomplete" << std::endl; - return false; - } - - bool ans = loadRequestOutList(token, groupIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - return ans; -} - - - - -bool p3WireVEG::getMsgList( const uint32_t &token, std::list &msgIds) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_LIST) - { - std::cerr << "p3WireVEG::getMsgList() ERROR AnsType Wrong" << std::endl; - return false; - } - - if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) - { - std::cerr << "p3WireVEG::getMsgList() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3WireVEG::getMsgList() ERROR Status Incomplete" << std::endl; - return false; - } - - bool ans = loadRequestOutList(token, msgIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - return ans; -} - - - /* Generic Summary */ -bool p3WireVEG::getGroupSummary( const uint32_t &token, std::list &groupInfo) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY) - { - std::cerr << "p3WireVEG::getGroupSummary() ERROR AnsType Wrong" << std::endl; - return false; - } - - if (reqtype != GXS_REQUEST_TYPE_GROUPS) - { - std::cerr << "p3WireVEG::getGroupSummary() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3WireVEG::getGroupSummary() ERROR Status Incomplete" << std::endl; - return false; - } - - std::list groupIds; - bool ans = loadRequestOutList(token, groupIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - /* convert to RsGroupMetaData */ - mProxy->getGroupSummary(groupIds, groupInfo); - - return ans; -} - -bool p3WireVEG::getMsgSummary( const uint32_t &token, std::list &msgInfo) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - if (anstype != RS_TOKREQ_ANSTYPE_SUMMARY) - { - std::cerr << "p3WireVEG::getMsgSummary() ERROR AnsType Wrong" << std::endl; - return false; - } - - if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) - { - std::cerr << "p3WireVEG::getMsgSummary() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3WireVEG::getMsgSummary() ERROR Status Incomplete" << std::endl; - return false; - } - - std::list msgIds; - bool ans = loadRequestOutList(token, msgIds); - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - - /* convert to RsMsgMetaData */ - mProxy->getMsgSummary(msgIds, msgInfo); - - return ans; -} - - - /* Specific Service Data */ -bool p3WireVEG::getGroupData(const uint32_t &token, RsWireGroup &group) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - - if (anstype != RS_TOKREQ_ANSTYPE_DATA) - { - std::cerr << "p3WireVEG::getGroupData() ERROR AnsType Wrong" << std::endl; - return false; - } - - if (reqtype != GXS_REQUEST_TYPE_GROUPS) - { - std::cerr << "p3WireVEG::getGroupData() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3WireVEG::getGroupData() ERROR Status Incomplete" << std::endl; - return false; - } - - std::string id; - if (!popRequestOutList(token, id)) - { - /* finished */ - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - return false; - } - - /* convert to RsWireGroup */ - bool ans = mWireProxy->getGroup(id, group); - return ans; -} - - -bool p3WireVEG::getMsgData(const uint32_t &token, RsWirePulse &pulse) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - - if (anstype != RS_TOKREQ_ANSTYPE_DATA) - { - std::cerr << "p3WireVEG::getMsgData() ERROR AnsType Wrong" << std::endl; - return false; - } - - if ((reqtype != GXS_REQUEST_TYPE_MSGS) && (reqtype != GXS_REQUEST_TYPE_MSGRELATED)) - { - std::cerr << "p3WireVEG::getMsgData() ERROR ReqType Wrong" << std::endl; - return false; - } - - if (status != GXS_REQUEST_STATUS_COMPLETE) - { - std::cerr << "p3WireVEG::getMsgData() ERROR Status Incomplete" << std::endl; - return false; - } - - std::string id; - if (!popRequestOutList(token, id)) - { - /* finished */ - updateRequestStatus(token, GXS_REQUEST_STATUS_DONE); - return false; - } - - /* convert to RsWirePulse */ - bool ans = mWireProxy->getPulse(id, pulse); - return ans; -} - - - - /* Poll */ -uint32_t p3WireVEG::requestStatus(const uint32_t token) -{ - uint32_t status; - uint32_t reqtype; - uint32_t anstype; - time_t ts; - checkRequestStatus(token, status, reqtype, anstype, ts); - - return status; -} - - - /* Cancel Request */ -bool p3WireVEG::cancelRequest(const uint32_t &token) -{ - return clearRequest(token); -} - - ////////////////////////////////////////////////////////////////////////////// - -bool p3WireVEG::setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask) -{ - return mWireProxy->setMessageStatus(msgId, status, statusMask); -} - - -bool p3WireVEG::setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask) -{ - return mWireProxy->setGroupStatus(groupId, status, statusMask); -} - -bool p3WireVEG::setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask) -{ - return mWireProxy->setGroupSubscribeFlags(groupId, subscribeFlags, subscribeMask); -} - -bool p3WireVEG::setMessageServiceString(const std::string &msgId, const std::string &str) -{ - return mWireProxy->setMessageServiceString(msgId, str); -} - -bool p3WireVEG::setGroupServiceString(const std::string &grpId, const std::string &str) -{ - return mWireProxy->setGroupServiceString(grpId, str); -} - - -bool p3WireVEG::groupRestoreKeys(const std::string &groupId) -{ - return false; -} - -bool p3WireVEG::groupShareKeys(const std::string &groupId, std::list& peers) -{ - return false; -} - - -/********************************************************************************************/ - - -std::string p3WireVEG::genRandomId() -{ - std::string randomId; - for(int i = 0; i < 20; i++) - { - randomId += (char) ('a' + (RSRandom::random_u32() % 26)); - } - - return randomId; -} - - -bool p3WireVEG::createGroup(uint32_t &token, RsWireGroup &group, bool isNew) -{ - if (group.mMeta.mGroupId.empty()) - { - /* new photo */ - - /* generate a temp id */ - group.mMeta.mGroupId = genRandomId(); - } - else - { - std::cerr << "p3WireVEG::createGroup() Group with existing Id... dropping"; - std::cerr << std::endl; - return false; - } - - { - RsStackMutex stack(mWireMtx); /********** STACK LOCKED MTX ******/ - - mUpdated = true; - mWireProxy->addGroup(group); - } - - // Fake a request to return the GroupMetaData. - generateToken(token); - uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptionsVEG opts; // NULL is good. - std::list groupIds; - groupIds.push_back(group.mMeta.mGroupId); // It will just return this one. - - std::cerr << "p3Wiree::createGroup() Generating Request Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_GROUPS, groupIds); - - return true; -} - - - - -bool p3WireVEG::createPulse(uint32_t &token, RsWirePulse &pulse, bool isNew) -{ - if (pulse.mMeta.mGroupId.empty()) - { - /* new photo */ - std::cerr << "p3WireVEG::createPulse() Missing PulseID"; - std::cerr << std::endl; - return false; - } - - /* check if its a mod or new pulse */ - if (pulse.mMeta.mOrigMsgId.empty()) - { - std::cerr << "p3WireVEG::createPulse() New Pulse"; - std::cerr << std::endl; - - /* new pulse, generate a new OrigPulseId */ - pulse.mMeta.mOrigMsgId = genRandomId(); - pulse.mMeta.mMsgId = pulse.mMeta.mOrigMsgId; - } - else - { - std::cerr << "p3WireVEG::createPulse() Modified Pulse"; - std::cerr << std::endl; - - /* mod pulse, keep orig pulse id, generate a new PulseId */ - pulse.mMeta.mMsgId = genRandomId(); - } - - std::cerr << "p3WireVEG::createPulse() GroupId: " << pulse.mMeta.mGroupId; - std::cerr << std::endl; - std::cerr << "p3WireVEG::createPulse() PulseId: " << pulse.mMeta.mMsgId; - std::cerr << std::endl; - std::cerr << "p3WireVEG::createPulse() OrigPulseId: " << pulse.mMeta.mOrigMsgId; - std::cerr << std::endl; - - { - RsStackMutex stack(mWireMtx); /********** STACK LOCKED MTX ******/ - - mUpdated = true; - mWireProxy->addPulse(pulse); - } - - // Fake a request to return the MsgMetaData. - generateToken(token); - uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptionsVEG opts; // NULL is good. - std::list msgIds; - msgIds.push_back(pulse.mMeta.mMsgId); // It will just return this one. - - std::cerr << "p3WireVEG::createPulse() Generating Request Token: " << token << std::endl; - storeRequest(token, ansType, opts, GXS_REQUEST_TYPE_MSGRELATED, msgIds); - - return true; -} - - - -/********************************************************************************************/ - - - -bool WireDataProxy::getGroup(const std::string &id, RsWireGroup &group) -{ - void *groupData = NULL; - RsGroupMetaData meta; - if (getGroupData(id, groupData) && getGroupSummary(id, meta)) - { - RsWireGroup *pG = (RsWireGroup *) groupData; - group = *pG; - - // update definitive version of the metadata. - group.mMeta = meta; - - std::cerr << "WireDataProxy::getGroup() Id: " << id; - std::cerr << " MetaData: " << meta << " DataPointer: " << groupData; - std::cerr << std::endl; - return true; - } - - std::cerr << "WireDataProxy::getGroup() FAILED Id: " << id; - std::cerr << std::endl; - - return false; -} - -bool WireDataProxy::getPulse(const std::string &id, RsWirePulse &pulse) -{ - void *msgData = NULL; - RsMsgMetaData meta; - if (getMsgData(id, msgData) && getMsgSummary(id, meta)) - { - RsWirePulse *pP = (RsWirePulse *) msgData; - // Shallow copy of thumbnail. - pulse = *pP; - - // update definitive version of the metadata. - pulse.mMeta = meta; - - std::cerr << "WireDataProxy::getPulse() Id: " << id; - std::cerr << " MetaData: " << meta << " DataPointer: " << msgData; - std::cerr << std::endl; - return true; - } - - std::cerr << "WireDataProxy::getPulse() FAILED Id: " << id; - std::cerr << std::endl; - - return false; -} - -bool WireDataProxy::addGroup(const RsWireGroup &group) -{ - // Make duplicate. - RsWireGroup *pG = new RsWireGroup(); - *pG = group; - - std::cerr << "WireDataProxy::addGroup()"; - std::cerr << " MetaData: " << pG->mMeta << " DataPointer: " << pG; - std::cerr << std::endl; - - return createGroup(pG); -} - - -bool WireDataProxy::addPulse(const RsWirePulse &pulse) -{ - // Make duplicate. - RsWirePulse *pP = new RsWirePulse(); - *pP = pulse; - - std::cerr << "WireDataProxy::addPulse()"; - std::cerr << " MetaData: " << pP->mMeta << " DataPointer: " << pP; - std::cerr << std::endl; - - return createMsg(pP); -} - - - - /* These Functions must be overloaded to complete the service */ -bool WireDataProxy::convertGroupToMetaData(void *groupData, RsGroupMetaData &meta) -{ - RsWireGroup *group = (RsWireGroup *) groupData; - meta = group->mMeta; - - return true; -} - -bool WireDataProxy::convertMsgToMetaData(void *msgData, RsMsgMetaData &meta) -{ - RsWirePulse *page = (RsWirePulse *) msgData; - meta = page->mMeta; - - return true; -} - - - -/***********************************************************************/ -/***********************************************************************/ -/***********************************************************************/ -/***********************************************************************/ - - -#if 0 - -bool p3WireVEG::generateDummyData() -{ -#define MAX_GROUPS 100 -#define MAX_POSTS 1000 - -#define MAX_BASE_COMMENTS 1000 //10000 -#define MAX_COMMENTS 4000 //10000 - -#define MAX_VOTES 10000 //10000 - - std::list mGroups; - std::list::iterator git; - - std::list mPosts; - std::list::iterator pit; - - std::list mVotes; - std::list::iterator vit; - - std::list mComments; - std::list::iterator cit; - -#define DUMMY_NAME_MAX_LEN 10000 - char name[DUMMY_NAME_MAX_LEN]; - int i, j; - time_t now = time(NULL); - - for(i = 0; i < MAX_GROUPS; i++) - { - /* generate a new forum */ - RsPostedGroup group; - - snprintf(name, DUMMY_NAME_MAX_LEN, "TestTopic_%d", i+1); - - group.mMeta.mGroupId = genRandomId(); - group.mMeta.mGroupName = name; - - group.mMeta.mPublishTs = now - (RSRandom::random_f32() * 100000); - /* key fields to fill in: - * GroupId. - * Name. - * Flags. - * Pop. - */ - - - - /* use probability to decide which are subscribed / own / popularity. - */ - - float rnd = RSRandom::random_f32(); - if (rnd < 0.1) - { - group.mMeta.mSubscribeFlags = RSGXS_GROUP_SUBSCRIBE_ADMIN | RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED; - - } - else if (rnd < 0.3) - { - group.mMeta.mSubscribeFlags = RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED; - } - else - { - group.mMeta.mSubscribeFlags = 0; - } - - group.mMeta.mPop = (int) (RSRandom::random_f32() * 10.0); - mGroups.push_back(group); - - } - - for(i = 0; i < MAX_POSTS; i++) - { - /* generate a base thread */ - - /* rotate the Forum Groups Around, then pick one. - */ - - int rnd = (int) (RSRandom::random_f32() * 10.0); - - for(j = 0; j < rnd; j++) - { - RsPostedGroup head = mGroups.front(); - mGroups.pop_front(); - mGroups.push_back(head); - } - - RsPostedGroup group = mGroups.front(); - - /* now create a new thread */ - - RsPostedPost post; - - snprintf(name, DUMMY_NAME_MAX_LEN, "%s => Post_%d", group.mMeta.mGroupName.c_str(), i+1); - post.mMeta.mMsgName = name; - - post.mMeta.mGroupId = group.mMeta.mGroupId; - post.mMeta.mMsgId = genRandomId(); - post.mMeta.mOrigMsgId = post.mMeta.mMsgId; - post.mMeta.mThreadId = post.mMeta.mMsgId; - post.mMeta.mParentId = ""; - - post.mMeta.mPublishTs = group.mMeta.mPublishTs + (RSRandom::random_f32() * 10000); - if (post.mMeta.mPublishTs > now) - post.mMeta.mPublishTs = now - 1; - - mPosts.push_back(post); - - } - - for(i = 0; i < MAX_BASE_COMMENTS; i++) - { - /* generate a base thread */ - - /* rotate the Forum Groups Around, then pick one. - */ - - int rnd = (int) (RSRandom::random_f32() * 10.0); - - for(j = 0; j < rnd; j++) - { - RsPostedPost head = mPosts.front(); - mPosts.pop_front(); - mPosts.push_back(head); - } - - RsPostedPost parent = mPosts.front(); - - /* now create a new child msg */ - - RsPostedComment comment; - - /* fill in key data - * GroupId - * MsgId - * OrigMsgId - * ThreadId - * ParentId - * PublishTS (take Forum TS + a bit ). - * - * ChildTS ???? - */ - snprintf(name, DUMMY_NAME_MAX_LEN, "%s => Comment_%d", parent.mMeta.mMsgName.c_str(), i+1); - comment.mMeta.mMsgName = name; - //comment.mMsg = name; - - comment.mMeta.mGroupId = parent.mMeta.mGroupId; - comment.mMeta.mMsgId = genRandomId(); - comment.mMeta.mOrigMsgId = comment.mMeta.mMsgId; - comment.mMeta.mThreadId = parent.mMeta.mThreadId; - comment.mMeta.mParentId = parent.mMeta.mOrigMsgId; - - comment.mMeta.mPublishTs = parent.mMeta.mPublishTs + (RSRandom::random_f32() * 10000); - if (comment.mMeta.mPublishTs > now) - comment.mMeta.mPublishTs = now - 1; - - mComments.push_back(comment); - } - - - for(i = 0; i < MAX_COMMENTS; i++) - { - /* generate a base thread */ - - /* rotate the Forum Groups Around, then pick one. - */ - - int rnd = (int) (RSRandom::random_f32() * 10.0); - - for(j = 0; j < rnd; j++) - { - RsPostedComment head = mComments.front(); - mComments.pop_front(); - mComments.push_back(head); - } - - RsPostedComment parent = mComments.front(); - - /* now create a new child msg */ - - RsPostedComment comment; - - /* fill in key data - * GroupId - * MsgId - * OrigMsgId - * ThreadId - * ParentId - * PublishTS (take Forum TS + a bit ). - * - * ChildTS ???? - */ - snprintf(name, DUMMY_NAME_MAX_LEN, "%s => Comment_%d", parent.mMeta.mMsgName.c_str(), i+1); - comment.mMeta.mMsgName = name; - //comment.mMsg = name; - - comment.mMeta.mGroupId = parent.mMeta.mGroupId; - comment.mMeta.mMsgId = genRandomId(); - comment.mMeta.mOrigMsgId = comment.mMeta.mMsgId; - comment.mMeta.mThreadId = parent.mMeta.mThreadId; - comment.mMeta.mParentId = parent.mMeta.mOrigMsgId; - - comment.mMeta.mPublishTs = parent.mMeta.mPublishTs + (RSRandom::random_f32() * 10000); - if (comment.mMeta.mPublishTs > now) - comment.mMeta.mPublishTs = now - 1; - - mComments.push_back(comment); - } - - - for(i = 0; i < MAX_VOTES; i++) - { - /* generate a base thread */ - - /* rotate the Forum Groups Around, then pick one. - */ - - int rnd = (int) (RSRandom::random_f32() * 10.0); - - for(j = 0; j < rnd; j++) - { - RsPostedPost head = mPosts.front(); - mPosts.pop_front(); - mPosts.push_back(head); - } - - RsPostedPost parent = mPosts.front(); - - /* now create a new child msg */ - - RsPostedVote vote; - - snprintf(name, DUMMY_NAME_MAX_LEN, "%s => Vote_%d", parent.mMeta.mMsgName.c_str(), i+1); - vote.mMeta.mMsgName = name; - //vote.mMsg = name; - - vote.mMeta.mGroupId = parent.mMeta.mGroupId; - vote.mMeta.mMsgId = genRandomId(); - vote.mMeta.mOrigMsgId = vote.mMeta.mMsgId; - vote.mMeta.mThreadId = parent.mMeta.mThreadId; - vote.mMeta.mParentId = parent.mMeta.mOrigMsgId; - - vote.mMeta.mPublishTs = parent.mMeta.mPublishTs + (RSRandom::random_f32() * 10000); - if (vote.mMeta.mPublishTs > now) - vote.mMeta.mPublishTs = now - 1; - - mVotes.push_back(vote); - } - - - mUpdated = true; - - /* Then - at the end, we push them all into the Proxy */ - for(git = mGroups.begin(); git != mGroups.end(); git++) - { - /* pushback */ - mPostedProxy->addGroup(*git); - - } - - for(pit = mPosts.begin(); pit != mPosts.end(); pit++) - { - /* pushback */ - mPostedProxy->addPost(*pit); - } - - for(cit = mComments.begin(); cit != mComments.end(); cit++) - { - /* pushback */ -#define COMMENT_FRAC_FOR_LATER (0.70) - if (RSRandom::random_f32() > COMMENT_FRAC_FOR_LATER) - { - mPostedProxy->addComment(*cit); - } - else - { - mDummyLaterComments.push_back(*cit); - } - } - - - for(vit = mVotes.begin(); vit != mVotes.end(); vit++) - { - /* pushback */ - -#define VOTE_FRAC_FOR_LATER (0.70) - if (RSRandom::random_f32() > VOTE_FRAC_FOR_LATER) - { - mPostedProxy->addVote(*vit); - } - else - { - mDummyLaterVotes.push_back(*vit); - } - } - - return true; -} - -#define EXTRA_COMMENT_ADD (20) -#define EXTRA_VOTE_ADD (50) - -bool p3PostedService::addExtraDummyData() -{ - std::cerr << "p3PostedService::addExtraDummyData()"; - std::cerr << std::endl; - - int i = 0; - - std::list::iterator vit; - std::list::iterator cit; - - for(cit = mDummyLaterComments.begin(); (cit != mDummyLaterComments.end()) && (i < EXTRA_COMMENT_ADD); i++) - { - mPostedProxy->addComment(*cit); - cit = mDummyLaterComments.erase(cit); - } - - i = 0; - for(vit = mDummyLaterVotes.begin(); (vit != mDummyLaterVotes.end()) && (i < EXTRA_VOTE_ADD); i++) - { - mPostedProxy->addVote(*vit); - vit = mDummyLaterVotes.erase(vit); - } - - return true; -} - -#endif - - diff --git a/libretroshare/src/services/p3wireVEG.h b/libretroshare/src/services/p3wireVEG.h deleted file mode 100644 index b009b116f..000000000 --- a/libretroshare/src/services/p3wireVEG.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * libretroshare/src/services: p3wire.h - * - * Wire interface for RetroShare. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#ifndef P3_WIRE_SERVICE_VEG_HEADER -#define P3_WIRE_SERVICE_VEG_HEADER - -#include "services/p3gxsserviceVEG.h" - -#include "retroshare/rswireVEG.h" - -#include -#include - -/* - * Wire Service - * - */ -class WireDataProxy: public GxsDataProxyVEG -{ - public: - - bool getGroup(const std::string &id, RsWireGroup &group); - bool getPulse(const std::string &id, RsWirePulse &pulse); - - bool addGroup(const RsWireGroup &group); - bool addPulse(const RsWirePulse &pulse); - - /* These Functions must be overloaded to complete the service */ -virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta); -virtual bool convertMsgToMetaData(void *msgData, RsMsgMetaData &meta); -}; - - -class p3WireVEG: public p3GxsDataServiceVEG, public RsWireVEG -{ - public: - - p3WireVEG(uint16_t type); - -virtual int tick(); - - public: - - -virtual bool updated(); - - /* Data Requests */ -virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); -virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &groupIds); -virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list &msgIds); - - /* Generic Lists */ -virtual bool getGroupList( const uint32_t &token, std::list &groupIds); -virtual bool getMsgList( const uint32_t &token, std::list &msgIds); - - /* Generic Summary */ -virtual bool getGroupSummary( const uint32_t &token, std::list &groupInfo); -virtual bool getMsgSummary( const uint32_t &token, std::list &msgInfo); - - /* Actual Data -> specific to Interface */ - /* Specific Service Data */ -virtual bool getGroupData(const uint32_t &token, RsWireGroup &group); -virtual bool getMsgData(const uint32_t &token, RsWirePulse &page); - - /* Poll */ -virtual uint32_t requestStatus(const uint32_t token); - - /* Cancel Request */ -virtual bool cancelRequest(const uint32_t &token); - - ////////////////////////////////////////////////////////////////////////////// -virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask); -virtual bool setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask); -virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask); -virtual bool setMessageServiceString(const std::string &msgId, const std::string &str); -virtual bool setGroupServiceString(const std::string &grpId, const std::string &str); - -virtual bool groupRestoreKeys(const std::string &groupId); -virtual bool groupShareKeys(const std::string &groupId, std::list& peers); - -virtual bool createGroup(uint32_t &token, RsWireGroup &group, bool isNew); -virtual bool createPulse(uint32_t &token, RsWirePulse &pulse, bool isNew); - - private: - -std::string genRandomId(); - - WireDataProxy *mWireProxy; - - RsMutex mWireMtx; - - /***** below here is locked *****/ - - bool mUpdated; - -}; - -#endif From ca3ef2759590751f07436d78ba8f2d7849c5c0c6 Mon Sep 17 00:00:00 2001 From: drbob Date: Mon, 26 Nov 2012 22:54:16 +0000 Subject: [PATCH 184/222] disabled TokenQueueVEG, as it doesn't compile anymore. To remove when Wire service is finished. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5902 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/RetroShare.pro | 2 -- 1 file changed, 2 deletions(-) diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index 9af9bfef8..ca2ae0c62 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -988,7 +988,6 @@ posted { gui/Posted/PostedListDialog.h \ gui/Posted/PostedItem.h \ gui/Posted/PostedComments.h \ - util/TokenQueueVEG.h \ gui/Posted/PostedGroupDialog.h \ gui/Posted/PostedCreatePostDialog.h \ gui/Posted/PostedCreateCommentDialog.h @@ -1004,7 +1003,6 @@ posted { gui/Posted/PostedListDialog.cpp \ gui/Posted/PostedItem.cpp \ gui/Posted/PostedComments.cpp \ - util/TokenQueueVEG.cpp \ gui/Posted/PostedGroupDialog.cpp \ gui/Posted/PostedCreatePostDialog.cpp \ gui/Posted/PostedCreateCommentDialog.cpp From 25de47c6f94baba5fbb93959774ee80ef79312ac Mon Sep 17 00:00:00 2001 From: thunder2 Date: Tue, 27 Nov 2012 23:21:20 +0000 Subject: [PATCH 185/222] Added tabs to gxsforums. Moved the thread message part from GxsForumsDialog to GxsForumThreadWidget. Added placeholder text to existing and new base classes to display for example "Loading". git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5905 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/RetroShare.pro | 6 +- retroshare-gui/src/gui/GxsForumsDialog.cpp | 1997 ++--------------- retroshare-gui/src/gui/GxsForumsDialog.h | 160 +- retroshare-gui/src/gui/GxsForumsDialog.ui | 477 +--- .../src/gui/common/GroupTreeWidget.cpp | 14 + .../src/gui/common/GroupTreeWidget.h | 2 + .../src/gui/common/LinkTextBrowser.cpp | 25 + .../src/gui/common/LinkTextBrowser.h | 7 + .../src/gui/common/RSTreeWidget.cpp | 52 + retroshare-gui/src/gui/common/RSTreeWidget.h | 43 + .../gui/gxsforums/GxsForumThreadWidget.cpp | 1924 ++++++++++++++++ .../src/gui/gxsforums/GxsForumThreadWidget.h | 191 ++ .../src/gui/gxsforums/GxsForumThreadWidget.ui | 511 +++++ 13 files changed, 2946 insertions(+), 2463 deletions(-) create mode 100644 retroshare-gui/src/gui/common/RSTreeWidget.cpp create mode 100644 retroshare-gui/src/gui/common/RSTreeWidget.h create mode 100644 retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp create mode 100644 retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h create mode 100644 retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.ui diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index ca2ae0c62..87ab75547 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -376,6 +376,7 @@ HEADERS += rshare.h \ gui/common/PopularityDefs.h \ gui/common/GroupTreeWidget.h \ gui/common/RSTreeView.h \ + gui/common/RSTreeWidget.h \ gui/common/AvatarWidget.h \ gui/common/FriendList.h \ gui/common/FriendSelectionWidget.h \ @@ -636,6 +637,7 @@ SOURCES += main.cpp \ gui/common/PopularityDefs.cpp \ gui/common/GroupTreeWidget.cpp \ gui/common/RSTreeView.cpp \ + gui/common/RSTreeWidget.cpp \ gui/common/AvatarWidget.cpp \ gui/common/FriendList.cpp \ gui/common/FriendSelectionWidget.cpp \ @@ -968,17 +970,19 @@ gxsforums { gui/gxsforums/GxsForumDetails.h \ gui/gxsforums/EditGxsForumDetails.h \ gui/gxsforums/CreateGxsForumMsg.h \ + gui/gxsforums/GxsForumThreadWidget.h FORMS += gui/GxsForumsDialog.ui \ gui/gxsforums/GxsForumDetails.ui \ gui/gxsforums/EditGxsForumDetails.ui \ gui/gxsforums/CreateGxsForumMsg.ui \ + gui/gxsforums/GxsForumThreadWidget.ui SOURCES += gui/GxsForumsDialog.cpp \ gui/gxsforums/GxsForumDetails.cpp \ gui/gxsforums/EditGxsForumDetails.cpp \ gui/gxsforums/CreateGxsForumMsg.cpp \ - + gui/gxsforums/GxsForumThreadWidget.cpp } diff --git a/retroshare-gui/src/gui/GxsForumsDialog.cpp b/retroshare-gui/src/gui/GxsForumsDialog.cpp index 19d1aff46..dfe21b81d 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/GxsForumsDialog.cpp @@ -20,45 +20,22 @@ ****************************************************************/ #include -#include -#include #include -#include -#include #include "GxsForumsDialog.h" #include "gxs/GxsForumGroupDialog.h" -#include "gxsforums/CreateGxsForumMsg.h" +#include "gxsforums/GxsForumThreadWidget.h" -#include "msgs/MessageComposer.h" #include "settings/rsharesettings.h" -#include "common/Emoticons.h" -#include "common/RSItemDelegate.h" -#include "common/PopularityDefs.h" -#include "common/RSTreeWidgetItem.h" #include "RetroShareLink.h" #include "channels/ShareKey.h" #include "notifyqt.h" -#include "util/HandleRichText.h" -//#AFTER MERGE #include "util/DateTime.h" - -#include -#include // These should be in retroshare/ folder. #include "gxs/rsgxsflags.h" -#include - //#define DEBUG_FORUMS -/* Images for context menu icons */ -#define IMAGE_MESSAGE ":/images/folder-draft.png" -#define IMAGE_MESSAGEREPLY ":/images/mail_reply.png" -#define IMAGE_MESSAGEREMOVE ":/images/mail_delete.png" -#define IMAGE_DOWNLOAD ":/images/start.png" -#define IMAGE_DOWNLOADALL ":/images/startall.png" - /* Images for TreeWidget */ #define IMAGE_FOLDER ":/images/folder16.png" #define IMAGE_FOLDERGREEN ":/images/folder_green.png" @@ -72,31 +49,6 @@ #define IMAGE_FORUMAUTHD ":/images/konv_message2.png" #define IMAGE_COPYLINK ":/images/copyrslink.png" -#define VIEW_LAST_POST 0 -#define VIEW_THREADED 1 -#define VIEW_FLAT 2 - -/* Thread constants */ -#define COLUMN_THREAD_COUNT 6 -#define COLUMN_THREAD_TITLE 0 -#define COLUMN_THREAD_READ 1 -#define COLUMN_THREAD_DATE 2 -#define COLUMN_THREAD_AUTHOR 3 -#define COLUMN_THREAD_SIGNED 4 -#define COLUMN_THREAD_CONTENT 5 - -#define COLUMN_THREAD_DATA 0 // column for storing the userdata like msgid and parentid - -#define ROLE_THREAD_MSGID Qt::UserRole -#define ROLE_THREAD_STATUS Qt::UserRole + 1 -#define ROLE_THREAD_MISSING Qt::UserRole + 2 -// no need to copy, don't count in ROLE_THREAD_COUNT -#define ROLE_THREAD_READCHILDREN Qt::UserRole + 3 -#define ROLE_THREAD_UNREADCHILDREN Qt::UserRole + 4 -#define ROLE_THREAD_SORT Qt::UserRole + 5 - -#define ROLE_THREAD_COUNT 3 - /* * Transformation Notes: * there are still a couple of things that the new forums differ from Old version. @@ -115,75 +67,22 @@ GxsForumsDialog::GxsForumsDialog(QWidget *parent) /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); - m_bProcessSettings = false; - subscribeFlags = 0; - inMsgAsReadUnread = false; - - threadCompareRole = new RSTreeWidgetItemCompareRole; - threadCompareRole->setRole(COLUMN_THREAD_DATE, ROLE_THREAD_SORT); - - /* Setup Queue */ + /* Setup Queue */ mForumQueue = new TokenQueue(rsGxsForums->getTokenService(), this); - connect( ui.forumTreeWidget, SIGNAL( treeCustomContextMenuRequested( QPoint ) ), this, SLOT( forumListCustomPopupMenu( QPoint ) ) ); - connect( ui.threadTreeWidget, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( threadListCustomPopupMenu( QPoint ) ) ); - + connect(ui.forumTreeWidget, SIGNAL(treeCustomContextMenuRequested(QPoint)), this, SLOT(forumListCustomPopupMenu(QPoint))); connect(ui.newForumButton, SIGNAL(clicked()), this, SLOT(newforum())); - connect(ui.newmessageButton, SIGNAL(clicked()), this, SLOT(createmessage())); - connect(ui.newthreadButton, SIGNAL(clicked()), this, SLOT(createthread())); - - connect( ui.forumTreeWidget, SIGNAL( treeCurrentItemChanged(QString) ), this, SLOT( changedForum(QString) ) ); - - connect( ui.threadTreeWidget, SIGNAL( itemSelectionChanged() ), this, SLOT( changedThread () ) ); - connect( ui.threadTreeWidget, SIGNAL( itemClicked(QTreeWidgetItem*,int)), this, SLOT( clickedThread (QTreeWidgetItem*,int) ) ); - connect( ui.viewBox, SIGNAL( currentIndexChanged ( int ) ), this, SLOT( changedViewBox () ) ); - - connect(ui.expandButton, SIGNAL(clicked()), this, SLOT(togglethreadview())); - connect(ui.previousButton, SIGNAL(clicked()), this, SLOT(previousMessage())); - connect(ui.nextButton, SIGNAL(clicked()), this, SLOT(nextMessage())); - connect(ui.nextUnreadButton, SIGNAL(clicked()), this, SLOT(nextUnreadMessage())); + connect(ui.forumTreeWidget, SIGNAL(treeItemClicked(QString)), this, SLOT(changedForum(QString))); + connect(ui.threadTabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(threadTabCloseRequested(int))); + connect(NotifyQt::getInstance(), SIGNAL(forumMsgReadSatusChanged(QString,QString,int)), this, SLOT(forumMsgReadSatusChanged(QString,QString,int))); // HACK - TEMPORARY HIJACKING THIS BUTTON FOR REFRESH. - //connect(ui.nextUnreadButton, SIGNAL(clicked()), this, SLOT(nextUnreadMessage())); - connect(ui.nextUnreadButton, SIGNAL(clicked()), this, SLOT(forceUpdateDisplay())); - - connect(ui.downloadButton, SIGNAL(clicked()), this, SLOT(downloadAllFiles())); - - connect(ui.filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterItems(QString))); - connect(ui.filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterColumnChanged(int))); - - connect(NotifyQt::getInstance(), SIGNAL(forumMsgReadSatusChanged(QString,QString,int)), this, SLOT(forumMsgReadSatusChanged(QString,QString,int))); + connect(ui.refreshButton, SIGNAL(clicked()), this, SLOT(forceUpdateDisplay())); /* Set initial size the splitter */ QList sizes; sizes << 300 << width(); // Qt calculates the right sizes - //ui.splitter->setSizes(sizes); - - /* Set own item delegate */ - RSItemDelegate *itemDelegate = new RSItemDelegate(this); - itemDelegate->setSpacing(QSize(0, 2)); - ui.threadTreeWidget->setItemDelegate(itemDelegate); - - /* Set header resize modes and initial section sizes */ - QHeaderView * ttheader = ui.threadTreeWidget->header () ; - ttheader->setResizeMode (COLUMN_THREAD_TITLE, QHeaderView::Interactive); - ttheader->resizeSection (COLUMN_THREAD_DATE, 140); - ttheader->resizeSection (COLUMN_THREAD_TITLE, 290); - - ui.threadTreeWidget->sortItems( COLUMN_THREAD_DATE, Qt::DescendingOrder ); - - /* Set text of column "Read" to empty - without this the column has a number as header text */ - QTreeWidgetItem *headerItem = ui.threadTreeWidget->headerItem(); - headerItem->setText(COLUMN_THREAD_READ, ""); - -//#AFTER MERGE setTextColorNotSubscribed(Qt::black); -//#AFTER MERGE setTextColorUnread(Qt::black); -//#AFTER MERGE setTextColorUnreadChildren(Qt::gray); -//#AFTER MERGE setTextColorRead(Qt::gray); -//#AFTER MERGE setTextColorMissing(Qt::darkRed); - - /* Initialize group tree */ -//#AFTER MERGE ui.forumTreeWidget->initDisplayMenu(ui.displayButton); + ui.splitter->setSizes(sizes); /* create forum tree */ yourForums = ui.forumTreeWidget->addCategoryItem(tr("Your Forums"), QIcon(IMAGE_FOLDER), true); @@ -191,33 +90,9 @@ GxsForumsDialog::GxsForumsDialog(QWidget *parent) popularForums = ui.forumTreeWidget->addCategoryItem(tr("Popular Forums"), QIcon(IMAGE_FOLDERGREEN), false); otherForums = ui.forumTreeWidget->addCategoryItem(tr("Other Forums"), QIcon(IMAGE_FOLDERYELLOW), false); - lastViewType = -1; - - /* add filter actions */ -//#AFTER MERGE ui.filterLineEdit->addFilter(QIcon(), tr("Title"), COLUMN_THREAD_TITLE, tr("Search Title")); -//#AFTER MERGE ui.filterLineEdit->addFilter(QIcon(), tr("Date"), COLUMN_THREAD_DATE, tr("Search Date")); -//#AFTER MERGE ui.filterLineEdit->addFilter(QIcon(), tr("Author"), COLUMN_THREAD_AUTHOR, tr("Search Author")); -//#AFTER MERGE ui.filterLineEdit->addFilter(QIcon(), tr("Content"), COLUMN_THREAD_CONTENT, tr("Search Content")); -//#AFTER MERGE ui.filterLineEdit->setCurrentFilter(COLUMN_THREAD_TITLE); - // load settings processSettings(true); - /* Set header sizes for the fixed columns and resize modes, must be set after processSettings */ - ttheader->resizeSection (COLUMN_THREAD_READ, 24); - ttheader->setResizeMode (COLUMN_THREAD_READ, QHeaderView::Fixed); - ttheader->hideSection (COLUMN_THREAD_CONTENT); - - ui.progressBar->hide(); - ui.progLayOutTxt->hide(); - ui.progressBarLayOut->setEnabled(false); - - mThreadLoading = false; - - insertThreads(); - - ui.threadTreeWidget->installEventFilter(this); - /* Hide platform specific features */ #ifdef Q_WS_WIN @@ -226,10 +101,10 @@ GxsForumsDialog::GxsForumsDialog(QWidget *parent) GxsForumsDialog::~GxsForumsDialog() { - delete(threadCompareRole); - // save settings processSettings(false); + + delete(mForumQueue); } //#AFTER MERGE UserNotify *GxsForumsDialog::getUserNotify(QObject *parent) @@ -239,254 +114,96 @@ GxsForumsDialog::~GxsForumsDialog() void GxsForumsDialog::processSettings(bool bLoad) { - m_bProcessSettings = true; - - QHeaderView *pHeader = ui.threadTreeWidget->header () ; - Settings->beginGroup(QString("GxsForumsDialog")); if (bLoad) { // load settings - // expandFiles - bool bValue = Settings->value("expandButton", true).toBool(); - ui.expandButton->setChecked(bValue); - togglethreadview_internal(); - - // filterColumn -//#AFTER MERGE ui.filterLineEdit->setCurrentFilter(Settings->value("filterColumn", COLUMN_THREAD_TITLE).toInt()); - - // index of viewBox - ui.viewBox->setCurrentIndex(Settings->value("viewBox", VIEW_THREADED).toInt()); - - // state of thread tree - pHeader->restoreState(Settings->value("ThreadTree").toByteArray()); - // state of splitter ui.splitter->restoreState(Settings->value("Splitter").toByteArray()); - ui.threadSplitter->restoreState(Settings->value("threadSplitter").toByteArray()); } else { // save settings - // state of thread tree - Settings->setValue("ThreadTree", pHeader->saveState()); - // state of splitter Settings->setValue("Splitter", ui.splitter->saveState()); - Settings->setValue("threadSplitter", ui.threadSplitter->saveState()); } ui.forumTreeWidget->processSettings(Settings, bLoad); Settings->endGroup(); - m_bProcessSettings = false; } -void GxsForumsDialog::changeEvent(QEvent *e) +int GxsForumsDialog::subscribeFlags(const std::string &forumId) { - QWidget::changeEvent(e); - switch (e->type()) { - case QEvent::StyleChange: - CalculateIconsAndFonts(); - break; - default: - // remove compiler warnings - break; + QMap::const_iterator it = mSubscribeFlags.find(mForumId); + if (it != mSubscribeFlags.end()) { + return it.value(); } + + return 0; } -void GxsForumsDialog::forumListCustomPopupMenu( QPoint /*point*/ ) +void GxsForumsDialog::forumListCustomPopupMenu(QPoint /*point*/) { - QMenu contextMnu( this ); + int flags = subscribeFlags(mForumId); + + QMenu contextMnu(this); QAction *action = contextMnu.addAction(QIcon(IMAGE_SUBSCRIBE), tr("Subscribe to Forum"), this, SLOT(subscribeToForum())); - action->setDisabled (mCurrForumId.empty() || IS_GROUP_SUBSCRIBED(subscribeFlags)); + action->setDisabled (mForumId.empty() || IS_GROUP_SUBSCRIBED(flags)); action = contextMnu.addAction(QIcon(IMAGE_UNSUBSCRIBE), tr("Unsubscribe to Forum"), this, SLOT(unsubscribeToForum())); - action->setEnabled (!mCurrForumId.empty() && IS_GROUP_SUBSCRIBED(subscribeFlags)); + action->setEnabled (!mForumId.empty() && IS_GROUP_SUBSCRIBED(flags)); contextMnu.addSeparator(); contextMnu.addAction(QIcon(IMAGE_NEWFORUM), tr("New Forum"), this, SLOT(newforum())); action = contextMnu.addAction(QIcon(IMAGE_INFO), tr("Show Forum Details"), this, SLOT(showForumDetails())); - action->setEnabled (!mCurrForumId.empty ()); + action->setEnabled (!mForumId.empty ()); action = contextMnu.addAction(QIcon(":/images/settings16.png"), tr("Edit Forum Details"), this, SLOT(editForumDetails())); - action->setEnabled (!mCurrForumId.empty () && IS_GROUP_ADMIN(subscribeFlags)); + action->setEnabled (!mForumId.empty () && IS_GROUP_ADMIN(flags)); QAction *shareKeyAct = new QAction(QIcon(":/images/gpgp_key_generate.png"), tr("Share Forum"), &contextMnu); connect( shareKeyAct, SIGNAL( triggered() ), this, SLOT( shareKey() ) ); - shareKeyAct->setEnabled(!mCurrForumId.empty() && IS_GROUP_ADMIN(subscribeFlags)); + shareKeyAct->setEnabled(!mForumId.empty() && IS_GROUP_ADMIN(flags)); contextMnu.addAction( shareKeyAct); QAction *restoreKeysAct = new QAction(QIcon(":/images/settings16.png"), tr("Restore Publish Rights for Forum" ), &contextMnu); connect( restoreKeysAct , SIGNAL( triggered() ), this, SLOT( restoreForumKeys() ) ); - restoreKeysAct->setEnabled(!mCurrForumId.empty() && !IS_GROUP_ADMIN(subscribeFlags)); + restoreKeysAct->setEnabled(!mForumId.empty() && !IS_GROUP_ADMIN(flags)); contextMnu.addAction( restoreKeysAct); action = contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyForumLink())); - action->setEnabled(!mCurrForumId.empty()); + action->setEnabled(!mForumId.empty()); contextMnu.addSeparator(); action = contextMnu.addAction(QIcon(":/images/message-mail-read.png"), tr("Mark all as read"), this, SLOT(markMsgAsReadAll())); - action->setEnabled (!mCurrForumId.empty () && IS_GROUP_SUBSCRIBED(subscribeFlags)); + action->setEnabled (!mForumId.empty () && IS_GROUP_SUBSCRIBED(flags)); action = contextMnu.addAction(QIcon(":/images/message-mail.png"), tr("Mark all as unread"), this, SLOT(markMsgAsUnreadAll())); - action->setEnabled (!mCurrForumId.empty () && IS_GROUP_SUBSCRIBED(subscribeFlags)); + action->setEnabled (!mForumId.empty () && IS_GROUP_SUBSCRIBED(flags)); #ifdef DEBUG_FORUMS contextMnu.addSeparator(); action = contextMnu.addAction("Generate mass data", this, SLOT(generateMassData())); - action->setEnabled (!mCurrForumId.empty() && IS_GROUP_SUBSCRIBED(subscribeFlags)); + action->setEnabled (!mCurrForumId.empty() && IS_GROUP_SUBSCRIBED(mSubscribeFlags)); #endif contextMnu.exec(QCursor::pos()); } -void GxsForumsDialog::threadListCustomPopupMenu( QPoint /*point*/ ) -{ - if (mThreadLoading) { - return; - } - - QMenu contextMnu( this ); - - QAction *replyAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr( "Reply" ), &contextMnu ); - connect( replyAct , SIGNAL( triggered() ), this, SLOT( createmessage() ) ); - - QAction *newthreadAct = new QAction(QIcon(IMAGE_DOWNLOADALL), tr( "Start New Thread" ), &contextMnu ); - newthreadAct->setEnabled (IS_GROUP_SUBSCRIBED(subscribeFlags)); - connect( newthreadAct , SIGNAL( triggered() ), this, SLOT( createthread() ) ); - - QAction *replyauthorAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr( "Reply to Author" ), &contextMnu ); - connect( replyauthorAct , SIGNAL( triggered() ), this, SLOT( replytomessage() ) ); - - QAction* expandAll = new QAction(tr( "Expand all" ), &contextMnu ); - connect( expandAll , SIGNAL( triggered() ), ui.threadTreeWidget, SLOT (expandAll()) ); - - QAction* collapseAll = new QAction(tr( "Collapse all" ), &contextMnu ); - connect( collapseAll , SIGNAL( triggered() ), ui.threadTreeWidget, SLOT(collapseAll()) ); - - QAction *markMsgAsRead = new QAction(QIcon(":/images/message-mail-read.png"), tr("Mark as read"), &contextMnu); - connect(markMsgAsRead , SIGNAL(triggered()), this, SLOT(markMsgAsRead())); - - QAction *markMsgAsReadChildren = new QAction(QIcon(":/images/message-mail-read.png"), tr("Mark as read") + " (" + tr ("with children") + ")", &contextMnu); - connect(markMsgAsReadChildren, SIGNAL(triggered()), this, SLOT(markMsgAsReadChildren())); - - QAction *markMsgAsUnread = new QAction(QIcon(":/images/message-mail.png"), tr("Mark as unread"), &contextMnu); - connect(markMsgAsUnread , SIGNAL(triggered()), this, SLOT(markMsgAsUnread())); - - QAction *markMsgAsUnreadChildren = new QAction(QIcon(":/images/message-mail.png"), tr("Mark as unread") + " (" + tr ("with children") + ")", &contextMnu); - connect(markMsgAsUnreadChildren , SIGNAL(triggered()), this, SLOT(markMsgAsUnreadChildren())); - - if (IS_GROUP_SUBSCRIBED(subscribeFlags)) { - QList Rows; - QList RowsRead; - QList RowsUnread; - int nCount = getSelectedMsgCount (&Rows, &RowsRead, &RowsUnread); - - if (RowsUnread.size() == 0) { - - markMsgAsRead->setDisabled(true); - } - if (RowsRead.size() == 0) { - markMsgAsUnread->setDisabled(true); - } - - bool bHasUnreadChildren = false; - bool bHasReadChildren = false; - int nRowCount = Rows.count(); - for (int i = 0; i < nRowCount; i++) { - if (bHasUnreadChildren || Rows[i]->data(COLUMN_THREAD_DATA, ROLE_THREAD_UNREADCHILDREN).toBool()) { - bHasUnreadChildren = true; - } - if (bHasReadChildren || Rows[i]->data(COLUMN_THREAD_DATA, ROLE_THREAD_READCHILDREN).toBool()) { - bHasReadChildren = true; - } - } - markMsgAsReadChildren->setEnabled(bHasUnreadChildren); - markMsgAsUnreadChildren->setEnabled(bHasReadChildren); - - if (nCount == 1) { - replyAct->setEnabled (true); - replyauthorAct->setEnabled (true); - } else { - replyAct->setDisabled (true); - replyauthorAct->setDisabled (true); - } - } else { - markMsgAsRead->setDisabled(true); - markMsgAsReadChildren->setDisabled(true); - markMsgAsUnread->setDisabled(true); - markMsgAsUnreadChildren->setDisabled(true); - replyAct->setDisabled (true); - replyauthorAct->setDisabled (true); - } - - contextMnu.addAction( replyAct); - contextMnu.addAction( newthreadAct); - contextMnu.addAction( replyauthorAct); - QAction* action = contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr( "Copy RetroShare Link"), this, SLOT(copyMessageLink())); - action->setEnabled(!mCurrForumId.empty() && !mCurrThreadId.empty()); - contextMnu.addSeparator(); - contextMnu.addAction(markMsgAsRead); - contextMnu.addAction(markMsgAsReadChildren); - contextMnu.addAction(markMsgAsUnread); - contextMnu.addAction(markMsgAsUnreadChildren); - contextMnu.addSeparator(); - contextMnu.addAction( expandAll); - contextMnu.addAction( collapseAll); - - contextMnu.exec(QCursor::pos()); -} - -bool GxsForumsDialog::eventFilter(QObject *obj, QEvent *event) -{ - if (obj == ui.threadTreeWidget) { - if (event->type() == QEvent::KeyPress) { - QKeyEvent *keyEvent = static_cast(event); - if (keyEvent && keyEvent->key() == Qt::Key_Space) { - // Space pressed - QTreeWidgetItem *item = ui.threadTreeWidget->currentItem (); - clickedThread (item, COLUMN_THREAD_READ); - return true; // eat event - } - } - } - // pass the event on to the parent class - return RsAutoUpdatePage::eventFilter(obj, event); -} - void GxsForumsDialog::restoreForumKeys(void) { + QMessageBox::warning(this, "RetroShare", "ToDo"); + #ifdef TOGXS rsGxsForums->groupRestoreKeys(mCurrForumId); #endif } -void GxsForumsDialog::togglethreadview() -{ - // save state of button - Settings->setValueToGroup("GxsForumsDialog", "expandButton", ui.expandButton->isChecked()); - - togglethreadview_internal(); -} - -void GxsForumsDialog::togglethreadview_internal() -{ - if (ui.expandButton->isChecked()) { - ui.postText->setVisible(true); - ui.expandButton->setIcon(QIcon(QString(":/images/edit_remove24.png"))); - ui.expandButton->setToolTip(tr("Hide")); - } else { - ui.postText->setVisible(false); - ui.expandButton->setIcon(QIcon(QString(":/images/edit_add24.png"))); - ui.expandButton->setToolTip(tr("Expand")); - } -} - void GxsForumsDialog::updateDisplay() { std::list forumIds; @@ -516,7 +233,7 @@ void GxsForumsDialog::updateDisplay() /* update Forums List */ insertForums(); /* update threads as well */ - insertThreads(); +//#TODO insertThreads(); } } @@ -529,22 +246,10 @@ void GxsForumsDialog::forceUpdateDisplay() /* update Forums List */ insertForums(); /* update threads as well */ - insertThreads(); -} - -static void CleanupItems (QList &items) -{ - QList::iterator item; - for (item = items.begin (); item != items.end (); item++) { - if (*item) { - delete (*item); - } - } - items.clear(); +//#TODO insertThreads(); } void GxsForumsDialog::forumInfoToGroupItemInfo(const RsGroupMetaData &forumInfo, GroupItemInfo &groupItemInfo) -//void GxsForumsDialog::forumInfoToGroupItemInfo(const ForumInfo &forumInfo, GroupItemInfo &groupItemInfo) { groupItemInfo.id = QString::fromStdString(forumInfo.mGroupId); groupItemInfo.name = QString::fromUtf8(forumInfo.mGroupName.c_str()); @@ -580,6 +285,8 @@ void GxsForumsDialog::forumInfoToGroupItemInfo(const RsGroupMetaData &forumInfo, /***** INSERT FORUM LISTS *****/ void GxsForumsDialog::insertForumsData(const std::list &forumList) { + mSubscribeFlags.clear(); + std::list::const_iterator it; QList adminList; @@ -592,6 +299,9 @@ void GxsForumsDialog::insertForumsData(const std::list &forumLi /* sort it into Publish (Own), Subscribed, Popular and Other */ uint32_t flags = it->mSubscribeFlags; + /* store for later use with poll */ + mSubscribeFlags[it->mGroupId] = flags; + GroupItemInfo groupItemInfo; forumInfoToGroupItemInfo(*it, groupItemInfo); @@ -640,464 +350,55 @@ void GxsForumsDialog::insertForumsData(const std::list &forumLi void GxsForumsDialog::changedForum(const QString &id) { - mCurrForumId = id.toStdString(); - - insertThreads(); -} - -void GxsForumsDialog::changedThread () -{ - if (mThreadLoading) { + mForumId = id.toStdString(); + if (mForumId.empty()) { return; } - /* just grab the ids of the current item */ - QTreeWidgetItem *curr = ui.threadTreeWidget->currentItem(); +// requestGroupSummary_CurrentForum(mForumId); - if ((!curr) || (!curr->isSelected())) { - mCurrThreadId = ""; - } else { - mCurrThreadId = curr->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString(); + /* search exisiting tab */ + GxsForumThreadWidget *threadWidget = NULL; + int tabCount = ui.threadTabWidget->count(); + for (int index = 0; index < tabCount; ++index) { + GxsForumThreadWidget *childWidget = dynamic_cast(ui.threadTabWidget->widget(index)); + if (childWidget && childWidget->forumId() == id.toStdString()) { + threadWidget = childWidget; + break; + } } - insertPost(); + + if (!threadWidget) { + /* create a thread widget */ + threadWidget = new GxsForumThreadWidget(id.toStdString()); + ui.threadTabWidget->addTab(threadWidget, tr("Loading")); + connect(threadWidget, SIGNAL(forumChanged(QWidget*)), this, SLOT(threadTabChanged(QWidget*))); + } + + ui.threadTabWidget->setCurrentWidget(threadWidget); } -void GxsForumsDialog::clickedThread (QTreeWidgetItem *item, int column) +void GxsForumsDialog::threadTabCloseRequested(int index) { - if (mCurrForumId.empty() || !IS_GROUP_SUBSCRIBED(subscribeFlags)) { + GxsForumThreadWidget *threadWidget = dynamic_cast(ui.threadTabWidget->widget(index)); + if (threadWidget) { + delete(threadWidget); + } +} + +void GxsForumsDialog::threadTabChanged(QWidget *widget) +{ + int index = ui.threadTabWidget->indexOf(widget); + if (index < 0) { return; } - if (item == NULL) { + GxsForumThreadWidget *threadWidget = dynamic_cast(ui.threadTabWidget->widget(index)); + if (!threadWidget) { return; } - if (column == COLUMN_THREAD_READ) { - QList Rows; - Rows.append(item); - uint32_t status = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - setMsgReadStatus(Rows, IS_MSG_UNREAD(status)); - return; - } -} - -void GxsForumsDialog::forumMsgReadStatusChanged(const QString &forumId, const QString &msgId, int status) -{ - if (inMsgAsReadUnread) { - return; - } - - if (forumId.toStdString() == mCurrForumId) { - /* Search exisiting item */ - QTreeWidgetItemIterator itemIterator(ui.threadTreeWidget); - QTreeWidgetItem *item = NULL; - while ((item = *itemIterator) != NULL) { - itemIterator++; - - if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString() == msgId) { - // update status - item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, status); - - QTreeWidgetItem *parentItem = item; - while (parentItem->parent()) { - parentItem = parentItem->parent(); - } - CalculateIconsAndFonts(parentItem); - break; - } - } - } - updateMessageSummaryList(forumId.toStdString()); -} - -void GxsForumsDialog::CalculateIconsAndFonts(QTreeWidgetItem *pItem, bool &bHasReadChilddren, bool &bHasUnreadChilddren) -{ - uint32_t status = pItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - - bool bUnread = IS_MSG_UNREAD(status); - bool missing = pItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING).toBool(); - - // set icon - if (missing) { - pItem->setIcon(COLUMN_THREAD_READ, QIcon()); - pItem->setIcon(COLUMN_THREAD_TITLE, QIcon()); - } else { - if (bUnread) { - pItem->setIcon(COLUMN_THREAD_READ, QIcon(":/images/message-state-unread.png")); - } else { - pItem->setIcon(COLUMN_THREAD_READ, QIcon(":/images/message-state-read.png")); - } - if (IS_MSG_UNREAD(status)) { - pItem->setIcon(COLUMN_THREAD_TITLE, QIcon(":/images/message-state-new.png")); - } else { - pItem->setIcon(COLUMN_THREAD_TITLE, QIcon()); - } - } - - int nItem; - int nItemCount = pItem->childCount(); - - bool bMyReadChilddren = false; - bool bMyUnreadChilddren = false; - - for (nItem = 0; nItem < nItemCount; nItem++) { - CalculateIconsAndFonts(pItem->child(nItem), bMyReadChilddren, bMyUnreadChilddren); - } - - // set font - for (int i = 0; i < COLUMN_THREAD_COUNT; i++) { - QFont qf = pItem->font(i); - - if (!IS_GROUP_SUBSCRIBED(subscribeFlags)) { - qf.setBold(false); - pItem->setTextColor(i, textColorNotSubscribed()); - } else if (bUnread) { - qf.setBold(true); - pItem->setTextColor(i, textColorUnread()); - } else if (bMyUnreadChilddren) { - qf.setBold(true); - pItem->setTextColor(i, textColorUnreadChildren()); - } else { - qf.setBold(false); - pItem->setTextColor(i, textColorRead()); - } - if (missing) { - /* Missing message */ - pItem->setTextColor(i, textColorMissing()); - } - pItem->setFont(i, qf); - } - - pItem->setData(COLUMN_THREAD_DATA, ROLE_THREAD_READCHILDREN, bHasReadChilddren || bMyReadChilddren); - pItem->setData(COLUMN_THREAD_DATA, ROLE_THREAD_UNREADCHILDREN, bHasUnreadChilddren || bMyUnreadChilddren); - - bHasReadChilddren = bHasReadChilddren || bMyReadChilddren || !bUnread; - bHasUnreadChilddren = bHasUnreadChilddren || bMyUnreadChilddren || bUnread; -} - -void GxsForumsDialog::CalculateIconsAndFonts(QTreeWidgetItem *pItem /*= NULL*/) -{ - bool bDummy1 = false; - bool bDummy2 = false; - - if (pItem) { - CalculateIconsAndFonts(pItem, bDummy1, bDummy2); - return; - } - - int nItem; - int nItemCount = ui.threadTreeWidget->topLevelItemCount(); - - for (nItem = 0; nItem < nItemCount; nItem++) { - bDummy1 = false; - bDummy2 = false; - CalculateIconsAndFonts(ui.threadTreeWidget->topLevelItem(nItem), bDummy1, bDummy2); - } -} - -void GxsForumsDialog::fillThreadFinished() -{ -#ifdef DEBUG_FORUMS - std::cerr << "GxsForumsDialog::fillThreadFinished" << std::endl; -#endif - - // This is now only called with a successful Load. - // cleanup of incomplete is handled elsewhere. - - // current thread has finished, hide progressbar and release thread - ui.progressBar->hide(); - ui.progLayOutTxt->hide(); - ui.progressBarLayOut->setEnabled(false); - -#ifdef DEBUG_FORUMS - std::cerr << "GxsForumsDialog::fillThreadFinished Add messages" << std::endl; -#endif - ui.threadTreeWidget->setSortingEnabled(false); - - /* add all messages in! */ - if (lastViewType != mThreadLoad.ViewType || lastForumID != mCurrForumId) - { - ui.threadTreeWidget->clear(); - lastViewType = mThreadLoad.ViewType; - lastForumID = mCurrForumId; - ui.threadTreeWidget->insertTopLevelItems(0, mThreadLoad.Items); - - // clear list - mThreadLoad.Items.clear(); - } - else - { - FillThreads (mThreadLoad.Items, mThreadLoad.ExpandNewMessages, mThreadLoad.ItemToExpand); - - // cleanup list - CleanupItems (mThreadLoad.Items); - } - - ui.threadTreeWidget->setSortingEnabled(true); - - if (mThreadLoad.FocusMsgId.empty() == false) - { - /* Search exisiting item */ - QTreeWidgetItemIterator itemIterator(ui.threadTreeWidget); - QTreeWidgetItem *item = NULL; - while ((item = *itemIterator) != NULL) - { - itemIterator++; - - if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString() == mThreadLoad.FocusMsgId) - { - ui.threadTreeWidget->setCurrentItem(item); - ui.threadTreeWidget->setFocus(); - break; - } - } - } - - QList::iterator Item; - for (Item = mThreadLoad.ItemToExpand.begin(); Item != mThreadLoad.ItemToExpand.end(); Item++) - { - if ((*Item)->isHidden() == false) - { - (*Item)->setExpanded(true); - } - } - mThreadLoad.ItemToExpand.clear(); - - if (ui.filterLineEdit->text().isEmpty() == false) { - filterItems(ui.filterLineEdit->text()); - } - - insertPost (); - CalculateIconsAndFonts(); - - ui.newthreadButton->setEnabled (IS_GROUP_SUBSCRIBED(subscribeFlags)); - - mThreadLoading = false; - -#ifdef DEBUG_FORUMS - std::cerr << "GxsForumsDialog::fillThreadFinished done" << std::endl; -#endif -} - -void GxsForumsDialog::fillThreadProgress(int current, int count) -{ - // show fill progress - if (count) { - ui.progressBar->setValue(current * ui.progressBar->maximum() / count); - } -} - -void GxsForumsDialog::insertThreads() -{ -#ifdef DEBUG_FORUMS - /* get the current Forum */ - std::cerr << "GxsForumsDialog::insertThreads()" << std::endl; -#endif - - subscribeFlags = 0; - - ui.newmessageButton->setEnabled (false); - ui.newthreadButton->setEnabled (false); - - ui.postText->clear(); - ui.threadTitle->clear(); - - if (mCurrForumId.empty()) - { - /* not an actual forum - clear */ - ui.threadTreeWidget->clear(); - /* when no Thread selected - clear */ - ui.forumName->clear(); - /* clear last stored forumID */ - mCurrForumId.erase(); - lastForumID.erase(); - -#ifdef DEBUG_FORUMS - std::cerr << "GxsForumsDialog::insertThreads() Current Thread Invalid" << std::endl; -#endif - - return; - } - - // Get Current Forum Info... then complete insertForumThreads(). - requestGroupSummary_CurrentForum(mCurrForumId); -} - - -void GxsForumsDialog::insertForumThreads(const RsGroupMetaData &fi) -{ - subscribeFlags = fi.mSubscribeFlags; - ui.forumName->setText(QString::fromUtf8(fi.mGroupName.c_str())); - - ui.progressBarLayOut->setEnabled(true); - - ui.progLayOutTxt->show(); - ui.progressBar->reset(); - ui.progressBar->show(); - -#ifdef DEBUG_FORUMS - std::cerr << "GxsForumsDialog::insertThreads() Start filling Forum threads" << std::endl; -#endif - - loadCurrentForumThreads(fi.mGroupId); -} - -void GxsForumsDialog::FillThreads(QList &ThreadList, bool expandNewMessages, QList &itemToExpand) -{ -#ifdef DEBUG_FORUMS - std::cerr << "GxsForumsDialog::FillThreads()" << std::endl; -#endif - - int Index = 0; - QTreeWidgetItem *Thread; - QList::iterator NewThread; - - // delete not existing - while (Index < ui.threadTreeWidget->topLevelItemCount ()) { - Thread = ui.threadTreeWidget->topLevelItem (Index); - - // search existing new thread - int Found = -1; - for (NewThread = ThreadList.begin (); NewThread != ThreadList.end (); NewThread++) { - if (Thread->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == (*NewThread)->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { - // found it - Found = Index; - break; - } - } - if (Found >= 0) { - Index++; - } else { - delete (ui.threadTreeWidget->takeTopLevelItem (Index)); - } - } - - // iterate all new threads - for (NewThread = ThreadList.begin (); NewThread != ThreadList.end (); NewThread++) { - // search existing thread - int Found = -1; - int Count = ui.threadTreeWidget->topLevelItemCount (); - for (Index = 0; Index < Count; Index++) { - Thread = ui.threadTreeWidget->topLevelItem (Index); - if (Thread->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == (*NewThread)->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { - // found it - Found = Index; - break; - } - } - - if (Found >= 0) { - // set child data - int i; - for (i = 0; i < COLUMN_THREAD_COUNT; i++) { - Thread->setText (i, (*NewThread)->text (i)); - } - for (i = 0; i < ROLE_THREAD_COUNT; i++) { - Thread->setData (COLUMN_THREAD_DATA, Qt::UserRole + i, (*NewThread)->data (COLUMN_THREAD_DATA, Qt::UserRole + i)); - } - - // fill recursive - FillChildren (Thread, *NewThread, expandNewMessages, itemToExpand); - } else { - // add new thread - ui.threadTreeWidget->addTopLevelItem (*NewThread); - Thread = *NewThread; - *NewThread = NULL; - } - - uint32_t status = Thread->data (COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - if (expandNewMessages && IS_MSG_UNREAD(status)) { - QTreeWidgetItem *pParent = Thread; - while ((pParent = pParent->parent()) != NULL) { - if (std::find(itemToExpand.begin(), itemToExpand.end(), pParent) == itemToExpand.end()) { - itemToExpand.push_back(pParent); - } - } - } - } - -#ifdef DEBUG_FORUMS - std::cerr << "GxsForumsDialog::FillThreads() done" << std::endl; -#endif -} - -void GxsForumsDialog::FillChildren(QTreeWidgetItem *Parent, QTreeWidgetItem *NewParent, bool expandNewMessages, QList &itemToExpand) -{ - int Index = 0; - int NewIndex; - int NewCount = NewParent->childCount(); - - QTreeWidgetItem *Child; - QTreeWidgetItem *NewChild; - - // delete not existing - while (Index < Parent->childCount ()) { - Child = Parent->child (Index); - - // search existing new child - int Found = -1; - int Count = NewParent->childCount(); - for (NewIndex = 0; NewIndex < Count; NewIndex++) { - NewChild = NewParent->child (NewIndex); - if (NewChild->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == Child->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { - // found it - Found = Index; - break; - } - } - if (Found >= 0) { - Index++; - } else { - delete (Parent->takeChild (Index)); - } - } - - // iterate all new children - for (NewIndex = 0; NewIndex < NewCount; NewIndex++) { - NewChild = NewParent->child (NewIndex); - - // search existing child - int Found = -1; - int Count = Parent->childCount(); - for (Index = 0; Index < Count; Index++) { - Child = Parent->child (Index); - if (Child->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == NewChild->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { - // found it - Found = Index; - break; - } - } - - if (Found >= 0) { - // set child data - int i; - for (i = 0; i < COLUMN_THREAD_COUNT; i++) { - Child->setText (i, NewChild->text (i)); - } - for (i = 0; i < ROLE_THREAD_COUNT; i++) { - Child->setData (COLUMN_THREAD_DATA, Qt::UserRole + i, NewChild->data (COLUMN_THREAD_DATA, Qt::UserRole + i)); - } - - // fill recursive - FillChildren (Child, NewChild, expandNewMessages, itemToExpand); - } else { - // add new child - Child = NewParent->takeChild(NewIndex); - Parent->addChild (Child); - NewIndex--; - NewCount--; - } - - uint32_t status = Child->data (COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - if (expandNewMessages && IS_MSG_UNREAD(status)) { - QTreeWidgetItem *pParent = Child; - while ((pParent = pParent->parent()) != NULL) { - if (std::find(itemToExpand.begin(), itemToExpand.end(), pParent) == itemToExpand.end()) { - itemToExpand.push_back(pParent); - } - } - } - } + ui.threadTabWidget->setTabText(index, threadWidget->forumName()); } QString GxsForumsDialog::titleFromInfo(const RsMsgMetaData &meta) @@ -1123,352 +424,9 @@ QString GxsForumsDialog::messageFromInfo(const RsGxsForumMsg &msg) return QString::fromUtf8(msg.mMsg.c_str()); } -void GxsForumsDialog::insertPost() -{ - if ((mCurrForumId == "") || (mCurrThreadId == "")) - { - ui.postText->setText(""); - ui.threadTitle->setText(""); - ui.previousButton->setEnabled(false); - ui.nextButton->setEnabled(false); - ui.newmessageButton->setEnabled (false); - return; - } - - QTreeWidgetItem *curr = ui.threadTreeWidget->currentItem(); - if (curr) { - QTreeWidgetItem *Parent = curr->parent (); - int Index = Parent ? Parent->indexOfChild (curr) : ui.threadTreeWidget->indexOfTopLevelItem (curr); - int Count = Parent ? Parent->childCount () : ui.threadTreeWidget->topLevelItemCount (); - ui.previousButton->setEnabled (Index > 0); - ui.nextButton->setEnabled (Index < Count - 1); - } else { - // there is something wrong - ui.previousButton->setEnabled(false); - ui.nextButton->setEnabled(false); - return; - } - - ui.newmessageButton->setEnabled (IS_GROUP_SUBSCRIBED(subscribeFlags) && mCurrThreadId.empty() == false); - - /* blank text, incase we get nothing */ - ui.postText->setText(""); - /* request Post */ - - RsGxsGrpMsgIdPair postId = std::make_pair(mCurrForumId, mCurrThreadId); - requestMsgData_InsertPost(postId); - -} - -void GxsForumsDialog::insertPostData(const RsGxsForumMsg &msg) -{ - /* As some time has elapsed since request - check that this is still the current msg. - * otherwise, another request will fill the data - */ - - if ((msg.mMeta.mGroupId != mCurrForumId) || (msg.mMeta.mMsgId != mCurrThreadId)) - { - std::cerr << "GxsForumsDialog::insertPostData() Ignoring Invalid Data...."; - std::cerr << std::endl; - std::cerr << "\t CurrForumId: " << mCurrForumId << " != msg.GroupId: " << msg.mMeta.mGroupId; - std::cerr << std::endl; - std::cerr << "\t or CurrThdId: " << mCurrThreadId << " != msg.MsgId: " << msg.mMeta.mMsgId; - std::cerr << std::endl; - std::cerr << std::endl; - return; - } - - QTreeWidgetItem *curr = ui.threadTreeWidget->currentItem(); - - bool bSetToReadOnActive = Settings->getForumMsgSetToReadOnActivate(); - uint32_t status = curr->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - - QList Row; - Row.append(curr); - - if (bSetToReadOnActive && IS_MSG_UNREAD(status)) - { - setMsgReadStatus(Row, true); - } - -//#AFTER MERGE ui.time_label->setText(DateTime::formatLongDateTime(msg.mMeta.mPublishTs)); - - std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); - QString text = QString::fromUtf8(authorName.c_str()); - - if (text.isEmpty()) - { - ui.by_label->setText( tr("By") + " " + tr("Anonymous")); - } - else - { - ui.by_label->setText( tr("By") + " " + text ); - } - - QString extraTxt = RsHtml().formatText(ui.postText->document(), messageFromInfo(msg), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS); - - ui.postText->setHtml(extraTxt); - ui.threadTitle->setText(titleFromInfo(msg.mMeta)); -} - -void GxsForumsDialog::previousMessage() -{ - QTreeWidgetItem *Item = ui.threadTreeWidget->currentItem (); - if (Item == NULL) { - return; - } - - QTreeWidgetItem *Parent = Item->parent (); - int Index = Parent ? Parent->indexOfChild (Item) : ui.threadTreeWidget->indexOfTopLevelItem (Item); - if (Index > 0) { - QTreeWidgetItem *Previous = Parent ? Parent->child (Index - 1) : ui.threadTreeWidget->topLevelItem (Index - 1); - if (Previous) { - ui.threadTreeWidget->setCurrentItem (Previous); - } - } -} - -void GxsForumsDialog::nextMessage() -{ - QTreeWidgetItem *Item = ui.threadTreeWidget->currentItem (); - if (Item == NULL) { - return; - } - - QTreeWidgetItem *Parent = Item->parent (); - int Index = Parent ? Parent->indexOfChild (Item) : ui.threadTreeWidget->indexOfTopLevelItem (Item); - int Count = Parent ? Parent->childCount () : ui.threadTreeWidget->topLevelItemCount (); - if (Index < Count - 1) { - QTreeWidgetItem *Next = Parent ? Parent->child (Index + 1) : ui.threadTreeWidget->topLevelItem (Index + 1); - if (Next) { - ui.threadTreeWidget->setCurrentItem (Next); - } - } -} - -void GxsForumsDialog::downloadAllFiles() -{ - QStringList urls; - if (RsHtml::findAnchors(ui.postText->toHtml(), urls) == false) { - return; - } - - if (urls.count() == 0) { - return; - } - - RetroShareLink::process(urls, RetroShareLink::TYPE_FILE/*, true*/); -} - -void GxsForumsDialog::nextUnreadMessage() -{ - QTreeWidgetItem *currentItem = ui.threadTreeWidget->currentItem(); - - while (TRUE) { - QTreeWidgetItemIterator itemIterator = currentItem ? QTreeWidgetItemIterator(currentItem, QTreeWidgetItemIterator::NotHidden) : QTreeWidgetItemIterator(ui.threadTreeWidget, QTreeWidgetItemIterator::NotHidden); - - QTreeWidgetItem *item; - while ((item = *itemIterator) != NULL) { - itemIterator++; - - if (item == currentItem) { - continue; - } - - uint32_t status = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - if (IS_MSG_UNREAD(status)) { - ui.threadTreeWidget->setCurrentItem(item); - ui.threadTreeWidget->scrollToItem(item, QAbstractItemView::EnsureVisible); - return; - } - } - - if (currentItem == NULL) { - break; - } - - /* start from top */ - currentItem = NULL; - } -} - -// TODO -#if 0 -void GxsForumsDialog::removemessage() -{ - //std::cerr << "GxsForumsDialog::removemessage()" << std::endl; - std::string cid, mid; - if (!getCurrentMsg(cid, mid)) - { - //std::cerr << "GxsForumsDialog::removemessage()"; - //std::cerr << " No Message selected" << std::endl; - return; - } - - rsMsgs -> MessageDelete(mid); -} -#endif - -/* get selected messages - the messages tree is single selected, but who knows ... */ -int GxsForumsDialog::getSelectedMsgCount(QList *pRows, QList *pRowsRead, QList *pRowsUnread) -{ - if (pRowsRead) pRowsRead->clear(); - if (pRowsUnread) pRowsUnread->clear(); - - QList selectedItems = ui.threadTreeWidget->selectedItems(); - for(QList::iterator it = selectedItems.begin(); it != selectedItems.end(); it++) { - if (pRows) pRows->append(*it); - if (pRowsRead || pRowsUnread) { - uint32_t status = (*it)->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - if (IS_MSG_UNREAD(status)) { - if (pRowsUnread) pRowsUnread->append(*it); - } else { - if (pRowsRead) pRowsRead->append(*it); - } - } - } - - return selectedItems.size(); -} - -void GxsForumsDialog::setMsgReadStatus(QList &Rows, bool bRead) -{ - QList::iterator Row; - std::list changedItems; - - inMsgAsReadUnread = true; - - for (Row = Rows.begin(); Row != Rows.end(); Row++) { - if ((*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING).toBool()) { - /* Missing message */ - continue; - } - - uint32_t status = (*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - - uint32_t statusNew = (status & ~GXS_SERV::GXS_MSG_STATUS_UNREAD); // orig status, without UNREAD. - if (!bRead) { - statusNew |= GXS_SERV::GXS_MSG_STATUS_UNREAD; - } - - if (IS_MSG_UNREAD(status) == bRead) // is it different? - { - std::string msgId = (*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString(); - - // NB: MUST BE PART OF ACTIVE THREAD--- OR ELSE WE MUST STORE GROUPID SOMEWHERE!. - // LIKE THIS BELOW... - //std::string grpId = (*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_GROUPID).toString().toStdString(); - - RsGxsGrpMsgIdPair msgPair = std::make_pair(mCurrForumId, msgId); - - uint32_t token; - rsGxsForums->setMessageReadStatus(token, msgPair, bRead); - - (*Row)->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, statusNew); - - QTreeWidgetItem *parentItem = *Row; - while (parentItem->parent()) { - parentItem = parentItem->parent(); - } - if (std::find(changedItems.begin(), changedItems.end(), parentItem) == changedItems.end()) { - changedItems.push_back(parentItem); - } - } - } - - inMsgAsReadUnread = false; - - if (changedItems.size()) { - for (std::list::iterator it = changedItems.begin(); it != changedItems.end(); it++) { - CalculateIconsAndFonts(*it); - } - updateMessageSummaryList(mCurrForumId); - } -} - -void GxsForumsDialog::markMsgAsReadUnread (bool bRead, bool bChildren, bool bForum) -{ - if (mCurrForumId.empty() || !IS_GROUP_SUBSCRIBED(subscribeFlags)) { - return; - } - - /* get selected messages */ - QList Rows; - if (bForum) { - int itemCount = ui.threadTreeWidget->topLevelItemCount(); - for (int item = 0; item < itemCount; item++) { - Rows.push_back(ui.threadTreeWidget->topLevelItem(item)); - } - } else { - getSelectedMsgCount (&Rows, NULL, NULL); - } - - if (bChildren) { - /* add children */ - QList AllRows; - - while (Rows.isEmpty() == false) { - QTreeWidgetItem *pRow = Rows.takeFirst(); - - /* add only items with the right state or with not RSGXS_MSG_STATUS_READ */ - uint32_t status = pRow->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - if (IS_MSG_UNREAD(status) == bRead) { - AllRows.append(pRow); - } - - for (int i = 0; i < pRow->childCount(); i++) { - /* add child to main list and let the main loop do the work */ - Rows.append(pRow->child(i)); - } - } - - if (AllRows.isEmpty()) { - /* nothing to do */ - return; - } - - setMsgReadStatus(AllRows, bRead); - - return; - } - - setMsgReadStatus(Rows, bRead); -} - -void GxsForumsDialog::markMsgAsRead() -{ - markMsgAsReadUnread(true, false, false); -} - -void GxsForumsDialog::markMsgAsReadChildren() -{ - markMsgAsReadUnread(true, true, false); -} - -void GxsForumsDialog::markMsgAsReadAll() -{ - markMsgAsReadUnread(true, true, true); -} - -void GxsForumsDialog::markMsgAsUnread() -{ - markMsgAsReadUnread(false, false, false); -} - -void GxsForumsDialog::markMsgAsUnreadChildren() -{ - markMsgAsReadUnread(false, true, false); -} - -void GxsForumsDialog::markMsgAsUnreadAll() -{ - markMsgAsReadUnread(false, true, true); -} - void GxsForumsDialog::copyForumLink() { - if (mCurrForumId.empty()) { + if (mForumId.empty()) { return; } @@ -1488,80 +446,15 @@ void GxsForumsDialog::copyForumLink() } #endif - { - RetroShareLink link; - if (link.createForum(mCurrForumId, "")) - { - QList urls; - urls.push_back(link); - RSLinkClipboard::copyLinks(urls); - } - } -} - -void GxsForumsDialog::copyMessageLink() -{ - if (mCurrForumId.empty() || mCurrThreadId.empty()) { - return; - } - -// SEE NOTE In fn above. -#if 0 - ForumInfo fi; - if (rsGxsForums->getForumInfo(mCurrForumId, fi)) { - RetroShareLink link; - if (link.createForum(mCurrForumId, mCurrThreadId)) { - QList urls; - urls.push_back(link); - RSLinkClipboard::copyLinks(urls); - } - } -#endif - - { - RetroShareLink link; - if (link.createForum(mCurrForumId, mCurrThreadId)) - { - QList urls; - urls.push_back(link); - RSLinkClipboard::copyLinks(urls); - } - } + QMessageBox::warning(this, "RetroShare", "ToDo"); } void GxsForumsDialog::newforum() { - GxsForumGroupDialog cf (mForumQueue, this); - //cf.newGroup(); - + GxsForumGroupDialog cf(mForumQueue, this); cf.exec (); } -void GxsForumsDialog::createmessage() -{ - if (mCurrForumId.empty () || !IS_GROUP_SUBSCRIBED(subscribeFlags)) { - return; - } - - CreateGxsForumMsg *cfm = new CreateGxsForumMsg(mCurrForumId, mCurrThreadId); - cfm->show(); - - /* window will destroy itself! */ -} - -void GxsForumsDialog::createthread() -{ - if (mCurrForumId.empty ()) { - QMessageBox::information(this, tr("RetroShare"), tr("No Forum Selected!")); - return; - } - - CreateGxsForumMsg *cfm = new CreateGxsForumMsg(mCurrForumId, ""); - cfm->show(); - - /* window will destroy itself! */ -} - void GxsForumsDialog::subscribeToForum() { forumSubscribe(true); @@ -1574,36 +467,35 @@ void GxsForumsDialog::unsubscribeToForum() void GxsForumsDialog::forumSubscribe(bool subscribe) { - if (mCurrForumId.empty()) { + if (mForumId.empty()) { return; } uint32_t token; - rsGxsForums->subscribeToGroup(token, mCurrForumId, subscribe); + rsGxsForums->subscribeToGroup(token, mForumId, subscribe); } void GxsForumsDialog::showForumDetails() { - if (mCurrForumId.empty()) { + if (mForumId.empty()) { return; } RsGxsForumGroup grp; - grp.mMeta.mGroupId = mCurrForumId; + grp.mMeta.mGroupId = mForumId; GxsForumGroupDialog cf(grp, this); - cf.exec (); } void GxsForumsDialog::editForumDetails() { - if (mCurrForumId.empty()) { + if (mForumId.empty()) { return; } RsGxsForumGroup grp; - grp.mMeta.mGroupId = mCurrForumId; + grp.mMeta.mGroupId = mForumId; GxsForumGroupDialog cf(grp, this); @@ -1612,137 +504,12 @@ void GxsForumsDialog::editForumDetails() cf.exec (); } -static QString buildReplyHeader(const RsMsgMetaData &meta) -{ - RetroShareLink link; - link.createMessage(meta.mAuthorId, ""); - QString from = link.toHtml(); - - QString header = QString("-----%1-----").arg(QApplication::translate("GxsForumsDialog", "Original Message")); - header += QString("
%1: %2
").arg(QApplication::translate("GxsForumsDialog", "From"), from); - -//#AFTER MERGE header += QString("
%1: %2
").arg(QApplication::translate("GxsForumsDialog", "Sent"), DateTime::formatLongDateTime(meta.mPublishTs)); - header += QString("%1: %2

").arg(QApplication::translate("GxsForumsDialog", "Subject"), QString::fromUtf8(meta.mMsgName.c_str())); - header += "
"; - -//#AFTER MERGE header += QApplication::translate("GxsForumsDialog", "On %1, %2 wrote:").arg(DateTime::formatDateTime(meta.mPublishTs), from); - - return header; -} - -void GxsForumsDialog::replytomessage() -{ - if (mCurrForumId.empty() || mCurrThreadId.empty()) { - QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to a non-existant Message")); - return; - } - - RsGxsGrpMsgIdPair postId = std::make_pair(mCurrForumId, mCurrThreadId); - requestMsgData_ReplyMessage(postId); -} - -void GxsForumsDialog::replyMessageData(const RsGxsForumMsg &msg) -{ - if ((msg.mMeta.mGroupId != mCurrForumId) || (msg.mMeta.mMsgId != mCurrThreadId)) - { - std::cerr << "GxsForumsDialog::replyMessageData() ERROR Message Ids have changed!"; - std::cerr << std::endl; - return; - } - - // NB: TODO REMOVE rsPeers references. - if (rsPeers->getPeerName(msg.mMeta.mAuthorId) !="") - { - MessageComposer *nMsgDialog = MessageComposer::newMsg(); - nMsgDialog->setTitleText(QString::fromUtf8(msg.mMeta.mMsgName.c_str()), MessageComposer::REPLY); - - nMsgDialog->setQuotedMsg(QString::fromUtf8(msg.mMsg.c_str()), buildReplyHeader(msg.mMeta)); - - nMsgDialog->addRecipient(MessageComposer::TO, msg.mMeta.mAuthorId, false); - nMsgDialog->show(); - nMsgDialog->activateWindow(); - - /* window will destroy itself! */ - } - else - { - QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to an Anonymous Author")); - } -} - -void GxsForumsDialog::changedViewBox() -{ - if (m_bProcessSettings) { - return; - } - - // save index - Settings->setValueToGroup("GxsForumsDialog", "viewBox", ui.viewBox->currentIndex()); - - insertThreads(); -} - -void GxsForumsDialog::filterColumnChanged(int column) -{ - if (m_bProcessSettings) { - return; - } - - if (column == COLUMN_THREAD_CONTENT) { - // need content ... refill - insertThreads(); - } else { - filterItems(ui.filterLineEdit->text()); - } - - // save index - Settings->setValueToGroup("GxsForumsDialog", "filterColumn", column); -} - -void GxsForumsDialog::filterItems(const QString& text) -{ -//#AFTER MERGE int filterColumn = ui.filterLineEdit->currentFilter(); - int filterColumn = COLUMN_THREAD_TITLE; - - int nCount = ui.threadTreeWidget->topLevelItemCount (); - for (int nIndex = 0; nIndex < nCount; nIndex++) { - filterItem(ui.threadTreeWidget->topLevelItem(nIndex), text, filterColumn); - } -} - void GxsForumsDialog::shareKey() { - ShareKey shareUi(this, 0, mCurrForumId, FORUM_KEY_SHARE); + ShareKey shareUi(this, 0, mForumId, FORUM_KEY_SHARE); shareUi.exec(); } -bool GxsForumsDialog::filterItem(QTreeWidgetItem *pItem, const QString &text, int filterColumn) -{ - bool bVisible = true; - - if (text.isEmpty() == false) { - if (pItem->text(filterColumn).contains(text, Qt::CaseInsensitive) == false) { - bVisible = false; - } - } - - int nVisibleChildCount = 0; - int nCount = pItem->childCount(); - for (int nIndex = 0; nIndex < nCount; nIndex++) { - if (filterItem(pItem->child(nIndex), text, filterColumn)) { - nVisibleChildCount++; - } - } - - if (bVisible || nVisibleChildCount) { - pItem->setHidden(false); - } else { - pItem->setHidden(true); - } - - return (bVisible || nVisibleChildCount); -} - void GxsForumsDialog::updateMessageSummaryList(std::string forumId) { QTreeWidgetItem *items[2] = { yourForums, subscribedForums }; @@ -1762,7 +529,7 @@ void GxsForumsDialog::updateMessageSummaryList(std::string forumId) unsigned int newMessageCount = 0; unsigned int unreadMessageCount = 0; - //rsGxsForums->getMessageCount(childId, newMessageCount, unreadMessageCount); +//#TODO rsGxsForums->getMessageCount(childId, newMessageCount, unreadMessageCount); std::cerr << "IMPLEMENT rsGxsForums->getMessageCount()"; std::cerr << std::endl; @@ -1789,7 +556,7 @@ bool GxsForumsDialog::navigate(const std::string& forumId, const std::string& ms } /* Threads are filled in changedForum */ - if (mCurrForumId != forumId) { + if (mForumId != forumId) { return false; } @@ -1797,23 +564,24 @@ bool GxsForumsDialog::navigate(const std::string& forumId, const std::string& ms return true; } - if (mThreadLoading) { - mThreadLoad.FocusMsgId = msgId; - return true; - } +//#TODO +// if (mThreadLoading) { +// mThreadLoad.FocusMsgId = msgId; +// return true; +// } /* Search exisiting item */ - QTreeWidgetItemIterator itemIterator(ui.threadTreeWidget); - QTreeWidgetItem *item = NULL; - while ((item = *itemIterator) != NULL) { - itemIterator++; +// QTreeWidgetItemIterator itemIterator(ui.threadTreeWidget); +// QTreeWidgetItem *item = NULL; +// while ((item = *itemIterator) != NULL) { +// itemIterator++; - if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString() == msgId) { - ui.threadTreeWidget->setCurrentItem(item); - ui.threadTreeWidget->setFocus(); - return true; - } - } +// if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString() == msgId) { +// ui.threadTreeWidget->setCurrentItem(item); +// ui.threadTreeWidget->setFocus(); +// return true; +// } +// } return false; } @@ -1860,12 +628,7 @@ void GxsForumsDialog::generateMassData() /*********************** **** **** **** ***********************/ #define FORUMSV2DIALOG_LISTING 1 -#define FORUMSV2DIALOG_CURRENTFORUM 2 -#define FORUMSV2DIALOG_INSERTTHREADS 3 -#define FORUMSV2DIALOG_INSERTCHILD 4 -#define FORUMV2DIALOG_INSERT_POST 5 -#define FORUMV2DIALOG_REPLY_MESSAGE 6 - +//#define FORUMSV2DIALOG_CURRENTFORUM 2 void GxsForumsDialog::insertForums() { @@ -1881,7 +644,7 @@ void GxsForumsDialog::requestGroupSummary() opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; uint32_t token; - mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, FORUMSV2DIALOG_LISTING); + mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, FORUMSV2DIALOG_LISTING); } void GxsForumsDialog::loadGroupSummary(const uint32_t &token) @@ -1906,502 +669,44 @@ void GxsForumsDialog::loadGroupSummary(const uint32_t &token) /*********************** **** **** **** ***********************/ /*********************** **** **** **** ***********************/ -void GxsForumsDialog::requestGroupSummary_CurrentForum(const std::string &forumId) -{ - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; +//void GxsForumsDialog::requestGroupSummary_CurrentForum(const std::string &forumId) +//{ +// RsTokReqOptions opts; +// opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; + +// std::list grpIds; +// grpIds.push_back(forumId); + +// std::cerr << "GxsForumsDialog::requestGroupSummary_CurrentForum(" << forumId << ")"; +// std::cerr << std::endl; + +// uint32_t token; +// mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, FORUMSV2DIALOG_CURRENTFORUM); +//} + +//void GxsForumsDialog::loadGroupSummary_CurrentForum(const uint32_t &token) +//{ +// std::cerr << "GxsForumsDialog::loadGroupSummary_CurrentForum()"; +// std::cerr << std::endl; + +// std::list groupInfo; +// rsGxsForums->getGroupSummary(token, groupInfo); + +// if (groupInfo.size() == 1) +// { +// RsGroupMetaData fi = groupInfo.front(); +// mSubscribeFlags = fi.mSubscribeFlags; +// } +// else +// { +// resetData(); +// std::cerr << "GxsForumsDialog::loadGroupSummary_CurrentForum() ERROR Invalid Number of Groups..."; +// std::cerr << std::endl; +// } + +// setValid(true); +//} - std::list grpIds; - grpIds.push_back(forumId); - - std::cerr << "GxsForumsDialog::requestGroupSummary_CurrentForum(" << forumId << ")"; - std::cerr << std::endl; - - uint32_t token; - mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, FORUMSV2DIALOG_CURRENTFORUM); -} - -void GxsForumsDialog::loadGroupSummary_CurrentForum(const uint32_t &token) -{ - std::cerr << "GxsForumsDialog::loadGroupSummary_CurrentForum()"; - std::cerr << std::endl; - - std::list groupInfo; - rsGxsForums->getGroupSummary(token, groupInfo); - - if (groupInfo.size() == 1) - { - RsGroupMetaData fi = groupInfo.front(); - insertForumThreads(fi); - } - else - { - std::cerr << "GxsForumsDialog::loadGroupSummary_CurrentForum() ERROR Invalid Number of Groups..."; - std::cerr << std::endl; - } -} - -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ - -void GxsForumsDialog::loadCurrentForumThreads(const std::string &forumId) -{ - - std::cerr << "GxsForumsDialog::loadCurrentForumThreads(" << forumId << ")"; - std::cerr << std::endl; - - /* if already active -> kill current loading */ - if (mThreadLoading) - { - /* Cleanup */ - std::cerr << "GxsForumsDialog::loadCurrentForumThreads() Cleanup old Threads"; - std::cerr << std::endl; - - /* Wipe Widget Tree */ - mThreadLoad.Items.clear(); - - /* Stop all active requests */ - std::map::iterator it; - for(it = mThreadLoad.MsgTokens.begin(); it != mThreadLoad.MsgTokens.end(); it++) - { - std::cerr << "GxsForumsDialog::loadCurrentForumThreads() Canceling Request: " << it->first; - std::cerr << std::endl; - - mForumQueue->cancelRequest(it->first); - } - - mThreadLoad.MsgTokens.clear(); - mThreadLoad.ItemToExpand.clear(); - } - - /* initiate loading */ - std::cerr << "GxsForumsDialog::loadCurrentForumThreads() Initiating Loading"; - std::cerr << std::endl; - - mThreadLoading = true; - - mThreadLoad.ForumId = mCurrForumId; -//#AFTER MERGE mThreadLoad.FilterColumn = ui.filterLineEdit->currentFilter(); - mThreadLoad.FilterColumn = COLUMN_THREAD_TITLE; - mThreadLoad.ViewType = ui.viewBox->currentIndex(); - mThreadLoad.FillComplete = false; - - if (lastViewType != mThreadLoad.ViewType || lastForumID != mCurrForumId) { - mThreadLoad.FillComplete = true; - } - - mThreadLoad.FlatView = false; - mThreadLoad.UseChildTS = false; - mThreadLoad.ExpandNewMessages = Settings->getExpandNewMessages(); - mThreadLoad.SubscribeFlags = subscribeFlags; - - if (mThreadLoad.ViewType == VIEW_FLAT) { - ui.threadTreeWidget->setRootIsDecorated(false); - } else { - ui.threadTreeWidget->setRootIsDecorated(true); - } - - switch(mThreadLoad.ViewType) - { - case VIEW_LAST_POST: - mThreadLoad.UseChildTS = true; - break; - case VIEW_FLAT: - mThreadLoad.FlatView = true; - break; - case VIEW_THREADED: - break; - } - - requestGroupThreadData_InsertThreads(forumId); -} - -void GxsForumsDialog::requestGroupThreadData_InsertThreads(const std::string &forumId) -{ - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - - opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; - - std::list grpIds; - grpIds.push_back(forumId); - - std::cerr << "GxsForumsDialog::requestGroupThreadData_InsertThreads(" << forumId << ")"; - std::cerr << std::endl; - - uint32_t token; - mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, FORUMSV2DIALOG_INSERTTHREADS); -} - -void GxsForumsDialog::loadGroupThreadData_InsertThreads(const uint32_t &token) -{ - std::cerr << "GxsForumsDialog::loadGroupThreadData_InsertThreads()"; - std::cerr << std::endl; - - bool someData = false; - - std::vector msgs; - std::vector::iterator vit; - if (rsGxsForums->getMsgData(token, msgs)) - { - for(vit = msgs.begin(); vit != msgs.end(); vit++) - { - std::cerr << "GxsForumsDialog::loadGroupThreadData_InsertThreads() MsgId: " << vit->mMeta.mMsgId; - std::cerr << std::endl; - - loadForumBaseThread(*vit); - someData = true; - } - } - - /* completed with no data */ - if (!someData) - { - fillThreadFinished(); - } -} - -bool GxsForumsDialog::convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, bool useChildTS, uint32_t filterColumn, GxsIdTreeWidgetItem *item) -{ - QString text; - - { - QDateTime qtime; - QString sort; - - if (useChildTS) - qtime.setTime_t(msgInfo.mMeta.mChildTs); - else - qtime.setTime_t(msgInfo.mMeta.mPublishTs); - -//#AFTER MERGE text = DateTime::formatDateTime(qtime); - sort = qtime.toString("yyyyMMdd_hhmmss"); - - if (useChildTS) - { - qtime.setTime_t(msgInfo.mMeta.mPublishTs); - text += " / "; -//#AFTER MERGE text += DateTime::formatDateTime(qtime); - sort += "_" + qtime.toString("yyyyMMdd_hhmmss"); - } - item->setText(COLUMN_THREAD_DATE, text); - item->setData(COLUMN_THREAD_DATE, ROLE_THREAD_SORT, sort); - } - - item->setText(COLUMN_THREAD_TITLE, GxsForumsDialog::titleFromInfo(msgInfo.mMeta)); - - item->setId(msgInfo.mMeta.mAuthorId, COLUMN_THREAD_AUTHOR); -#if 0 - text = QString::fromUtf8(authorName.c_str()); - - if (text.isEmpty()) - { - item->setText(COLUMN_THREAD_AUTHOR, tr("Anonymous")); - } - else - { - item->setText(COLUMN_THREAD_AUTHOR, text); - } -#endif - -#ifdef TOGXS - if (msgInfo.mMeta.mMsgFlags & RS_DISTRIB_AUTHEN_REQ) - { - item->setText(COLUMN_THREAD_SIGNED, tr("signed")); - item->setIcon(COLUMN_THREAD_SIGNED, QIcon(":/images/mail-signed.png")); - } - else - { - item->setText(COLUMN_THREAD_SIGNED, tr("none")); - item->setIcon(COLUMN_THREAD_SIGNED, QIcon(":/images/mail-signature-unknown.png")); - } -#endif - - if (filterColumn == COLUMN_THREAD_CONTENT) { - // need content for filter - QTextDocument doc; - doc.setHtml(QString::fromUtf8(msgInfo.mMsg.c_str())); - item->setText(COLUMN_THREAD_CONTENT, doc.toPlainText().replace(QString("\n"), QString(" "))); - } - - item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID, QString::fromStdString(msgInfo.mMeta.mMsgId)); - -#if 0 - if (IS_GROUP_SUBSCRIBED(subscribeFlags) && !(msginfo.mMsgFlags & RS_DISTRIB_MISSING_MSG)) { - rsGxsForums->getMessageStatus(msginfo.forumId, msginfo.msgId, status); - } else { - // show message as read - status = RSGXS_MSG_STATUS_READ; - } -#endif - item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, msgInfo.mMeta.mMsgStatus); - -#ifdef TOGXS - item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING, (msgInfo.mMeta.mMsgFlags & RS_DISTRIB_MISSING_MSG) ? true : false); -#endif - - return true; -} - -void GxsForumsDialog::loadForumBaseThread(const RsGxsForumMsg &msg) -{ - //std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); - - //QTreeWidgetItem *item = new QTreeWidgetItem(); // no Parent. - GxsIdTreeWidgetItem *item = new GxsIdTreeWidgetItem(threadCompareRole); // no Parent. - - //convertMsgToThreadWidget(msg, authorName, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, item); - convertMsgToThreadWidget(msg, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, item); - - /* request Children Data */ - uint32_t token; - RsGxsGrpMsgIdPair parentId = std::make_pair(msg.mMeta.mGroupId, msg.mMeta.mMsgId); - requestChildData_InsertThreads(token, parentId); - - /* store pair of (token, item) */ - mThreadLoad.MsgTokens[token] = item; - - /* add item to final tree */ - mThreadLoad.Items.append(item); -} - -/*********************** **** **** **** ***********************/ - -void GxsForumsDialog::requestChildData_InsertThreads(uint32_t &token, const RsGxsGrpMsgIdPair &parentId) -{ - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; - opts.mOptions = RS_TOKREQOPT_MSG_PARENT | RS_TOKREQOPT_MSG_LATEST; - - std::cerr << "GxsForumsDialog::requestChildData_InsertThreads(" << parentId.first << "," << parentId.second << ")"; - std::cerr << std::endl; - - std::vector msgIds; - msgIds.push_back(parentId); - mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMSV2DIALOG_INSERTCHILD); -} - -void GxsForumsDialog::loadChildData_InsertThreads(const uint32_t &token) -{ - std::cerr << "GxsForumsDialog::loadChildData_InsertThreads()"; - std::cerr << std::endl; - - /* find the matching *item */ - std::map::iterator it; - it = mThreadLoad.MsgTokens.find(token); - if (it == mThreadLoad.MsgTokens.end()) - { - std::cerr << "GxsForumsDialog::loadChildData_InsertThreads() ERROR Missing Token->Parent in Map"; - std::cerr << std::endl; - /* finished with this one */ - return; - } - - QTreeWidgetItem *parent = it->second; - // cleanup map. - mThreadLoad.MsgTokens.erase(it); - - std::cerr << "GxsForumsDialog::loadChildData_InsertThreads()"; - std::cerr << std::endl; - - std::vector msgs; - std::vector::iterator vit; - if (rsGxsForums->getRelatedMessages(token, msgs)) - { - for(vit = msgs.begin(); vit != msgs.end(); vit++) - { - std::cerr << "GxsForumsDialog::loadChildData_InsertThreads() MsgId: " << vit->mMeta.mMsgId; - std::cerr << std::endl; - - loadForumChildMsg(*vit, parent); - } - } - else - { - std::cerr << "GxsForumsDialog::loadChildData_InsertThreads() Error getting MsgData"; - std::cerr << std::endl; - } - - /* check for completion */ - if (mThreadLoad.MsgTokens.size() == 0) - { - /* finished */ - /* push data into GUI */ - fillThreadFinished(); - } -} - -void GxsForumsDialog::loadForumChildMsg(const RsGxsForumMsg &msg, QTreeWidgetItem *parent) -{ - //std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); - - //QTreeWidgetItem *child = NULL; - GxsIdTreeWidgetItem *child = NULL; - - if (mThreadLoad.FlatView) - { - child = new GxsIdTreeWidgetItem(threadCompareRole); // no Parent. - } - else - { - child = new GxsIdTreeWidgetItem(threadCompareRole, parent); - } - - convertMsgToThreadWidget(msg, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, child); - //convertMsgToThreadWidget(msg, authorName, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, child); - - /* request Children Data */ - uint32_t token; - RsGxsGrpMsgIdPair parentId = std::make_pair(msg.mMeta.mGroupId, msg.mMeta.mMsgId); - requestChildData_InsertThreads(token, parentId); - - /* store pair of (token, item) */ - mThreadLoad.MsgTokens[token] = child; - - // Leave this here... BUT IT WILL NEED TO BE FIXED. - if (mThreadLoad.FillComplete && mThreadLoad.ExpandNewMessages && IS_MSG_UNREAD(msg.mMeta.mMsgStatus)) - { - QTreeWidgetItem *pParent = child; - while ((pParent = pParent->parent()) != NULL) - { - if (std::find(mThreadLoad.ItemToExpand.begin(), mThreadLoad.ItemToExpand.end(), pParent) == mThreadLoad.ItemToExpand.end()) - { - mThreadLoad.ItemToExpand.push_back(pParent); - } - } - } - - if (mThreadLoad.FlatView) - { - /* add item to final tree */ - mThreadLoad.Items.append(child); - } -} - -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ - -void GxsForumsDialog::requestMsgData_InsertPost(const RsGxsGrpMsgIdPair &msgId) -{ -#if 0 - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; - - std::cerr << "GxsForumsDialog::requestMsgData_InsertPost(" << msgId.first << "," << msgId.second << ")"; - std::cerr << std::endl; - - std::vector msgIds; - msgIds.push_back(msgId); - uint32_t token; - mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_INSERT_POST); -#else - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - - std::cerr << "GxsForumsDialog::requestMsgData_InsertPost(" << msgId.first << "," << msgId.second << ")"; - std::cerr << std::endl; - - GxsMsgReq msgIds; - std::vector &vect = msgIds[msgId.first]; - vect.push_back(msgId.second); - - uint32_t token; - mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_INSERT_POST); -#endif -} - -void GxsForumsDialog::loadMsgData_InsertPost(const uint32_t &token) -{ - std::cerr << "GxsForumsDialog::loadMsgData_InsertPost()"; - std::cerr << std::endl; - - std::vector msgs; -#if 0 - if (rsGxsForums->getRelatedMessages(token, msgs)) -#else - if (rsGxsForums->getMsgData(token, msgs)) -#endif - { - if (msgs.size() != 1) - { - std::cerr << "GxsForumsDialog::loadMsgData_InsertPost() ERROR Wrong number of answers"; - std::cerr << std::endl; - return; - } - insertPostData(msgs[0]); - } - else - { - std::cerr << "GxsForumsDialog::loadMsgData_InsertPost() ERROR Missing Message Data..."; - std::cerr << std::endl; - } -} - -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ - -void GxsForumsDialog::requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId) -{ -#if 0 - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; - - std::cerr << "GxsForumsDialog::requestMsgData_ReplyMessage(" << msgId.first << "," << msgId.second << ")"; - std::cerr << std::endl; - - std::vector msgIds; - msgIds.push_back(msgId); - uint32_t token; - mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_REPLY_MESSAGE); -#else - - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - - std::cerr << "GxsForumsDialog::requestMsgData_ReplyMessage(" << msgId.first << "," << msgId.second << ")"; - std::cerr << std::endl; - - GxsMsgReq msgIds; - std::vector &vect = msgIds[msgId.first]; - vect.push_back(msgId.second); - - uint32_t token; - mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_REPLY_MESSAGE); -#endif -} - -void GxsForumsDialog::loadMsgData_ReplyMessage(const uint32_t &token) -{ - std::cerr << "GxsForumsDialog::loadMsgData_ReplyMessage()"; - std::cerr << std::endl; - - std::vector msgs; -#if 0 - if (rsGxsForums->getRelatedMessages(token, msgs)) -#else - if (rsGxsForums->getMsgData(token, msgs)) -#endif - { - if (msgs.size() != 1) - { - std::cerr << "GxsForumsDialog::loadMsgData_ReplyMessage() ERROR Wrong number of answers"; - std::cerr << std::endl; - return; - } - - replyMessageData(msgs[0]); - } - else - { - std::cerr << "GxsForumsDialog::loadMsgData_ReplyMessage() ERROR Missing Message Data..."; - std::cerr << std::endl; - } -} - -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ /*********************** **** **** **** ***********************/ /*********************** **** **** **** ***********************/ @@ -2419,25 +724,9 @@ void GxsForumsDialog::loadRequest(const TokenQueue *queue, const TokenRequest &r loadGroupSummary(req.mToken); break; - case FORUMSV2DIALOG_CURRENTFORUM: - loadGroupSummary_CurrentForum(req.mToken); - break; - - case FORUMSV2DIALOG_INSERTTHREADS: - loadGroupThreadData_InsertThreads(req.mToken); - break; - - case FORUMSV2DIALOG_INSERTCHILD: - loadChildData_InsertThreads(req.mToken); - break; - - case FORUMV2DIALOG_INSERT_POST: - loadMsgData_InsertPost(req.mToken); - break; - - case FORUMV2DIALOG_REPLY_MESSAGE: - loadMsgData_ReplyMessage(req.mToken); - break; +// case FORUMSV2DIALOG_CURRENTFORUM: +// loadGroupSummary_CurrentForum(req.mToken); +// break; default: std::cerr << "GxsForumsDialog::loadRequest() ERROR: INVALID TYPE"; diff --git a/retroshare-gui/src/gui/GxsForumsDialog.h b/retroshare-gui/src/gui/GxsForumsDialog.h index d74601faf..955c1c7ac 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.h +++ b/retroshare-gui/src/gui/GxsForumsDialog.h @@ -32,47 +32,15 @@ #include "util/TokenQueue.h" -#include - #include "gui/gxs/GxsIdTreeWidgetItem.h" class ForumInfo; - - -/* These are all the parameters that are required for thread loading. - * They are kept static for the load duration. - */ - -class GxsForumsThreadLoadParameters -{ -public: - std::string ForumId; - std::string FocusMsgId; - - uint32_t SubscribeFlags; - int ViewType; - uint32_t FilterColumn; - - std::map MsgTokens; - QList Items; - QList ItemToExpand; - - bool FillComplete; - bool FlatView; - bool UseChildTS; - bool ExpandNewMessages; -}; +class RsGxsForumMsg; class GxsForumsDialog : public RsAutoUpdatePage, public TokenResponse { Q_OBJECT - Q_PROPERTY(QColor textColorRead READ textColorRead WRITE setTextColorRead) - Q_PROPERTY(QColor textColorUnread READ textColorUnread WRITE setTextColorUnread) - Q_PROPERTY(QColor textColorUnreadChildren READ textColorUnreadChildren WRITE setTextColorUnreadChildren) - Q_PROPERTY(QColor textColorNotSubscribed READ textColorNotSubscribed WRITE setTextColorNotSubscribed) - Q_PROPERTY(QColor textColorMissing READ textColorMissing WRITE setTextColorMissing) - public: GxsForumsDialog(QWidget *parent = 0); ~GxsForumsDialog(); @@ -87,56 +55,24 @@ public: // Callback for all Loads. virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); - QColor textColorRead() const { return mTextColorRead; } - QColor textColorUnread() const { return mTextColorUnread; } - QColor textColorUnreadChildren() const { return mTextColorUnreadChildren; } - QColor textColorNotSubscribed() const { return mTextColorNotSubscribed; } - QColor textColorMissing() const { return mTextColorMissing; } - - void setTextColorRead(QColor color) { mTextColorRead = color; } - void setTextColorUnread(QColor color) { mTextColorUnread = color; } - void setTextColorUnreadChildren(QColor color) { mTextColorUnreadChildren = color; } - void setTextColorNotSubscribed(QColor color) { mTextColorNotSubscribed = color; } - void setTextColorMissing(QColor color) { mTextColorMissing = color; } - -protected: - bool eventFilter(QObject *obj, QEvent *ev); - void changeEvent(QEvent *e); + // Utility Fns. + static QString titleFromInfo(const RsMsgMetaData &meta); + static QString messageFromInfo(const RsGxsForumMsg &msg); private slots: void forceUpdateDisplay(); // TEMP HACK FN. /** Create the context popup menu and it's submenus */ void forumListCustomPopupMenu( QPoint point ); - void threadListCustomPopupMenu( QPoint point ); + void restoreForumKeys(); void newforum(); void changedForum(const QString &id); - void changedThread(); - void clickedThread (QTreeWidgetItem *item, int column); + void threadTabCloseRequested(int index); + void threadTabChanged(QWidget *widget); - void replytomessage(); - void replyMessageData(const RsGxsForumMsg &msg); - - //void print(); - //void printpreview(); - - //void removemessage(); - void markMsgAsRead(); - void markMsgAsReadChildren(); - void markMsgAsReadAll(); - void markMsgAsUnread(); - void markMsgAsUnreadAll(); - void markMsgAsUnreadChildren(); void copyForumLink(); - void copyMessageLink(); - - /* handle splitter */ - void togglethreadview(); - - void createthread(); - void createmessage(); void subscribeToForum(); void unsubscribeToForum(); @@ -144,110 +80,40 @@ private slots: void showForumDetails(); void editForumDetails(); - void previousMessage (); - void nextMessage (); - void nextUnreadMessage(); - void downloadAllFiles(); - - void changedViewBox(); - - void filterColumnChanged(int column); - void filterItems(const QString &text); - void generateMassData(); - void fillThreadFinished(); - void fillThreadProgress(int current, int count); - void shareKey(); private: void insertForums(); - void insertThreads(); - void insertPost(); - void insertPostData(const RsGxsForumMsg &msg); // Second Half. - - // Utility Fns. - QString titleFromInfo(const RsMsgMetaData &meta); - QString messageFromInfo(const RsGxsForumMsg &msg); - - void forumMsgReadStatusChanged(const QString &forumId, const QString &msgId, int status); + int subscribeFlags(const std::string &forumId); void updateMessageSummaryList(std::string forumId); // void forumInfoToGroupItemInfo(const ForumInfo &forumInfo, GroupItemInfo &groupItemInfo); void forumInfoToGroupItemInfo(const RsGroupMetaData &forumInfo, GroupItemInfo &groupItemInfo); void forumSubscribe(bool subscribe); - void FillThreads(QList &ThreadList, bool bExpandNewMessages, QList &itemToExpand); - void FillChildren(QTreeWidgetItem *Parent, QTreeWidgetItem *NewParent, bool bExpandNewMessages, QList &itemToExpand); - int getSelectedMsgCount(QList *pRows, QList *pRowsRead, QList *pRowsUnread); - void setMsgReadStatus(QList &Rows, bool bRead); - void markMsgAsReadUnread(bool bRead, bool bChildren, bool bForum); - void CalculateIconsAndFonts(QTreeWidgetItem *pItem = NULL); - void CalculateIconsAndFonts(QTreeWidgetItem *pItem, bool &bHasReadChilddren, bool &bHasUnreadChilddren); - - void processSettings(bool bLoad); - void togglethreadview_internal(); - - bool filterItem(QTreeWidgetItem *pItem, const QString &text, int filterColumn); + void processSettings(bool load); // New Request/Response Loading Functions. void insertForumsData(const std::list &forumList); - void insertForumThreads(const RsGroupMetaData &fi); void requestGroupSummary(); void loadGroupSummary(const uint32_t &token); - void requestGroupSummary_CurrentForum(const std::string &forumId); - void loadGroupSummary_CurrentForum(const uint32_t &token); - - void loadCurrentForumThreads(const std::string &forumId); - void requestGroupThreadData_InsertThreads(const std::string &forumId); - void loadGroupThreadData_InsertThreads(const uint32_t &token); - void loadForumBaseThread(const RsGxsForumMsg &msg); - - void requestChildData_InsertThreads(uint32_t &token, const RsGxsGrpMsgIdPair &parentId); - void loadChildData_InsertThreads(const uint32_t &token); - void loadForumChildMsg(const RsGxsForumMsg &msg, QTreeWidgetItem *parent); - - void requestMsgData_InsertPost(const RsGxsGrpMsgIdPair &msgId); - void loadMsgData_InsertPost(const uint32_t &token); - void requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId); - void loadMsgData_ReplyMessage(const uint32_t &token); - - bool convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, bool useChildTS, uint32_t filterColumn, GxsIdTreeWidgetItem *item); -// bool convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, std::string authorName, bool useChildTS, uint32_t filterColumn, QTreeWidgetItem *item); +// void requestGroupSummary_CurrentForum(const std::string &forumId); +// void loadGroupSummary_CurrentForum(const uint32_t &token); + std::string mForumId; + QMap mSubscribeFlags; TokenQueue *mForumQueue; - bool m_bProcessSettings; - bool inMsgAsReadUnread; - QTreeWidgetItem *yourForums; QTreeWidgetItem *subscribedForums; QTreeWidgetItem *popularForums; QTreeWidgetItem *otherForums; - RSTreeWidgetItemCompareRole *threadCompareRole; - std::string mCurrForumId; - std::string mCurrThreadId; - int subscribeFlags; - - int lastViewType; - std::string lastForumID; - - // New Datatypes to replace the FillThread. - bool mThreadLoading; - GxsForumsThreadLoadParameters mThreadLoad; - - /* Color definitions (for standard see qss.default) */ - QColor mTextColorRead; - QColor mTextColorUnread; - QColor mTextColorUnreadChildren; - QColor mTextColorNotSubscribed; - QColor mTextColorMissing; - /** Qt Designer generated object */ Ui::GxsForumsDialog ui; }; diff --git a/retroshare-gui/src/gui/GxsForumsDialog.ui b/retroshare-gui/src/gui/GxsForumsDialog.ui index 9d8f4d4dd..9420b701e 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.ui +++ b/retroshare-gui/src/gui/GxsForumsDialog.ui @@ -97,6 +97,13 @@ + + + + Refresh + + + @@ -161,458 +168,16 @@ - - - Qt::Vertical + + + -1 + + + true + + + true - - - - - - - - - 2 - 0 - - - - - 0 - 0 - - - - - 16777215 - 1677215 - - - - - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse - - - - - - - - Last Post - - - - - Threaded View - - - - - Flat View - - - - - - - - - - - 9 - - - - Qt::CustomContextMenu - - - true - - - true - - - - Title - - - - - - - - - :/images/message-state-header.png:/images/message-state-header.png - - - - - Date - - - - - Author - - - - - Signed - - - - - - - - - - false - - - - 0 - 0 - - - - - 24 - 24 - - - - - 24 - 24 - - - - Qt::NoFocus - - - Previous Thread - - - - - - - :/images/back.png:/images/back.png - - - true - - - - - - - false - - - - 0 - 0 - - - - - 24 - 24 - - - - - 24 - 24 - - - - Qt::NoFocus - - - Next Thread - - - - - - - :/images/forward.png:/images/forward.png - - - true - - - - - - - - 24 - 24 - - - - Qt::NoFocus - - - - - - - :/images/edit_remove24.png:/images/edit_remove24.png - - - true - - - true - - - - - - - - 0 - 0 - - - - Force Refresh - - - - - - - - 24 - 24 - - - - Qt::NoFocus - - - Reply Message - - - - :/images/mail_reply.png:/images/mail_reply.png - - - true - - - - - - - - 10 - - - - - - - - - - - - 10 - - - - - - - - - - - Qt::Vertical - - - - - - - - 24 - 24 - - - - Qt::NoFocus - - - Download all files - - - - :/images/down.png:/images/down.png - - - true - - - - - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - 0 - 32 - - - - QFrame::Box - - - QFrame::Sunken - - - - 2 - - - - - Qt::NoFocus - - - Start new Thread for Selected Forum - - - - :/images/mail_new.png:/images/mail_new.png - - - - 24 - 16 - - - - true - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 40 - 20 - - - - - - - - Search forums - - - - - - - - - - - - - 10 - 75 - true - - - - Loading - - - - - - - - 16777215 - 25 - - - - 1000 - - - 0 - - - - - - - - - true - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse - - - - - - - - - 0 - 10 - - - - - 9 - - - @@ -629,16 +194,6 @@ - - LinkTextBrowser - QTextBrowser -
gui/common/LinkTextBrowser.h
-
- - LineEditClear - QLineEdit -
gui/common/LineEditClear.h
-
GroupTreeWidget QWidget diff --git a/retroshare-gui/src/gui/common/GroupTreeWidget.cpp b/retroshare-gui/src/gui/common/GroupTreeWidget.cpp index 3ae0831cc..da67704d6 100644 --- a/retroshare-gui/src/gui/common/GroupTreeWidget.cpp +++ b/retroshare-gui/src/gui/common/GroupTreeWidget.cpp @@ -68,6 +68,7 @@ GroupTreeWidget::GroupTreeWidget(QWidget *parent) : connect(ui->treeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customContextMenuRequested(QPoint))); connect(ui->treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*))); + connect(ui->treeWidget, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(itemClicked(QTreeWidgetItem*,int))); /* Add own item delegate */ RSItemDelegate *itemDelegate = new RSItemDelegate(this); @@ -201,6 +202,19 @@ void GroupTreeWidget::currentItemChanged(QTreeWidgetItem *current, QTreeWidgetIt emit treeCurrentItemChanged(id); } +void GroupTreeWidget::itemClicked(QTreeWidgetItem *item, int column) +{ + Q_UNUSED(column); + + QString id; + + if (item) { + id = item->data(COLUMN_DATA, ROLE_ID).toString(); + } + + emit treeItemClicked(id); +} + QTreeWidgetItem *GroupTreeWidget::addCategoryItem(const QString &name, const QIcon &icon, bool expand) { QFont font = QFont("ARIAL", 10); diff --git a/retroshare-gui/src/gui/common/GroupTreeWidget.h b/retroshare-gui/src/gui/common/GroupTreeWidget.h index 97cdbf018..3cd72e025 100644 --- a/retroshare-gui/src/gui/common/GroupTreeWidget.h +++ b/retroshare-gui/src/gui/common/GroupTreeWidget.h @@ -82,6 +82,7 @@ public: signals: void treeCustomContextMenuRequested(const QPoint &pos); void treeCurrentItemChanged(const QString &id); + void treeItemClicked(const QString &id); protected: void changeEvent(QEvent *e); @@ -89,6 +90,7 @@ protected: private slots: void customContextMenuRequested(const QPoint &pos); void currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); + void itemClicked(QTreeWidgetItem *item, int column); void filterChanged(); void sort(); diff --git a/retroshare-gui/src/gui/common/LinkTextBrowser.cpp b/retroshare-gui/src/gui/common/LinkTextBrowser.cpp index dddc6124b..e16002761 100644 --- a/retroshare-gui/src/gui/common/LinkTextBrowser.cpp +++ b/retroshare-gui/src/gui/common/LinkTextBrowser.cpp @@ -1,4 +1,5 @@ #include +#include #include "LinkTextBrowser.h" @@ -17,3 +18,27 @@ void LinkTextBrowser::linkClicked(const QUrl &url) // so we handle links by our own QDesktopServices::openUrl(url); } + +void LinkTextBrowser::setPlaceholderText(const QString &text) +{ + placeholderText = text; + viewport()->repaint(); +} + +void LinkTextBrowser::paintEvent(QPaintEvent *event) +{ + QTextBrowser::paintEvent(event); + + if (placeholderText.isEmpty() == false && document()->isEmpty()) { + QWidget *vieportWidget = viewport(); + QPainter painter(vieportWidget); + + QPen pen = painter.pen(); + QColor color = pen.color(); + color.setAlpha(128); + pen.setColor(color); + painter.setPen(pen); + + painter.drawText(QRect(QPoint(), vieportWidget->size()), Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextWordWrap, placeholderText); + } +} diff --git a/retroshare-gui/src/gui/common/LinkTextBrowser.h b/retroshare-gui/src/gui/common/LinkTextBrowser.h index f5c29165a..f0b9e0246 100644 --- a/retroshare-gui/src/gui/common/LinkTextBrowser.h +++ b/retroshare-gui/src/gui/common/LinkTextBrowser.h @@ -10,8 +10,15 @@ class LinkTextBrowser : public QTextBrowser public: explicit LinkTextBrowser(QWidget *parent = 0); + void setPlaceholderText(const QString &text); + private slots: void linkClicked(const QUrl &url); + +protected: + void paintEvent(QPaintEvent *event); + + QString placeholderText; }; #endif // LINKTEXTBROWSER_H diff --git a/retroshare-gui/src/gui/common/RSTreeWidget.cpp b/retroshare-gui/src/gui/common/RSTreeWidget.cpp new file mode 100644 index 000000000..e863e3be2 --- /dev/null +++ b/retroshare-gui/src/gui/common/RSTreeWidget.cpp @@ -0,0 +1,52 @@ +/**************************************************************** + * This file is distributed under the following license: + * + * Copyright (c) 2012, RetroShare Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include + +#include "RSTreeWidget.h" + +RSTreeWidget::RSTreeWidget(QWidget *parent) : QTreeWidget(parent) +{ +} + +void RSTreeWidget::setPlaceholderText(const QString &text) +{ + placeholderText = text; + viewport()->repaint(); +} + +void RSTreeWidget::paintEvent(QPaintEvent *event) +{ + QTreeWidget::paintEvent(event); + + if (placeholderText.isEmpty() == false && model() && model()->rowCount() == 0) { + QWidget *vieportWidget = viewport(); + QPainter painter(vieportWidget); + + QPen pen = painter.pen(); + QColor color = pen.color(); + color.setAlpha(128); + pen.setColor(color); + painter.setPen(pen); + + painter.drawText(QRect(QPoint(), vieportWidget->size()), Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextWordWrap, placeholderText); + } +} diff --git a/retroshare-gui/src/gui/common/RSTreeWidget.h b/retroshare-gui/src/gui/common/RSTreeWidget.h new file mode 100644 index 000000000..80a0f0d05 --- /dev/null +++ b/retroshare-gui/src/gui/common/RSTreeWidget.h @@ -0,0 +1,43 @@ +/**************************************************************** + * This file is distributed under the following license: + * + * Copyright (c) 2012, RetroShare Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#ifndef _RSTREEWIDGET_H +#define _RSTREEWIDGET_H + +#include + +/* Subclassing QTreeWidget */ +class RSTreeWidget : public QTreeWidget +{ + Q_OBJECT + +public: + RSTreeWidget(QWidget *parent = 0); + + void setPlaceholderText(const QString &text); + +protected: + void paintEvent(QPaintEvent *event); + + QString placeholderText; +}; + +#endif diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp new file mode 100644 index 000000000..26db544b0 --- /dev/null +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -0,0 +1,1924 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2012, RetroShare Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include +#include +#include + +#include "GxsForumThreadWidget.h" +#include "ui_GxsForumThreadWidget.h" +#include "gui/GxsForumsDialog.h" +#include "gui/RetroShareLink.h" +#include "gui/common/RSTreeWidgetItem.h" +#include "gui/common/RSItemDelegate.h" +#include "gui/settings/rsharesettings.h" +#include "gui/gxs/GxsIdTreeWidgetItem.h" +#include "util/HandleRichText.h" +#include "gui/gxs/GxsForumGroupDialog.h" +#include "CreateGxsForumMsg.h" +#include "gui/msgs/MessageComposer.h" + +#include +#include +// These should be in retroshare/ folder. +#include "gxs/rsgxsflags.h" + +#include + +/* Images for context menu icons */ +#define IMAGE_MESSAGE ":/images/folder-draft.png" +#define IMAGE_MESSAGEREPLY ":/images/mail_reply.png" +#define IMAGE_MESSAGEREMOVE ":/images/mail_delete.png" +#define IMAGE_DOWNLOAD ":/images/start.png" +#define IMAGE_DOWNLOADALL ":/images/startall.png" +#define IMAGE_COPYLINK ":/images/copyrslink.png" + +#define VIEW_LAST_POST 0 +#define VIEW_THREADED 1 +#define VIEW_FLAT 2 + +/* Thread constants */ +#define COLUMN_THREAD_COUNT 6 +#define COLUMN_THREAD_TITLE 0 +#define COLUMN_THREAD_READ 1 +#define COLUMN_THREAD_DATE 2 +#define COLUMN_THREAD_AUTHOR 3 +#define COLUMN_THREAD_SIGNED 4 +#define COLUMN_THREAD_CONTENT 5 + +#define COLUMN_THREAD_DATA 0 // column for storing the userdata like msgid and parentid + +#define ROLE_THREAD_MSGID Qt::UserRole +#define ROLE_THREAD_STATUS Qt::UserRole + 1 +#define ROLE_THREAD_MISSING Qt::UserRole + 2 +// no need to copy, don't count in ROLE_THREAD_COUNT +#define ROLE_THREAD_READCHILDREN Qt::UserRole + 3 +#define ROLE_THREAD_UNREADCHILDREN Qt::UserRole + 4 +#define ROLE_THREAD_SORT Qt::UserRole + 5 + +#define ROLE_THREAD_COUNT 3 + +GxsForumThreadWidget::GxsForumThreadWidget(const std::string &forumId, QWidget *parent) : + QWidget(parent), + ui(new Ui::GxsForumThreadWidget) +{ + ui->setupUi(this); + + mForumId = forumId; + mSubscribeFlags = 0; + mInProcessSettings = false; + + mThreadQueue = new TokenQueue(rsGxsForums->getTokenService(), this); + + mInMsgAsReadUnread = false; + + mThreadCompareRole = new RSTreeWidgetItemCompareRole; + mThreadCompareRole->setRole(COLUMN_THREAD_DATE, ROLE_THREAD_SORT); + + connect(ui->threadTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(threadListCustomPopupMenu(QPoint))); + + connect(ui->newmessageButton, SIGNAL(clicked()), this, SLOT(createmessage())); + connect(ui->newthreadButton, SIGNAL(clicked()), this, SLOT(createthread())); + + connect(ui->threadTreeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(changedThread())); + connect(ui->threadTreeWidget, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(clickedThread(QTreeWidgetItem*,int))); + connect(ui->viewBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changedViewBox())); + + connect(ui->expandButton, SIGNAL(clicked()), this, SLOT(togglethreadview())); + connect(ui->previousButton, SIGNAL(clicked()), this, SLOT(previousMessage())); + connect(ui->nextButton, SIGNAL(clicked()), this, SLOT(nextMessage())); + connect(ui->nextUnreadButton, SIGNAL(clicked()), this, SLOT(nextUnreadMessage())); + connect(ui->downloadButton, SIGNAL(clicked()), this, SLOT(downloadAllFiles())); + + connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterItems(QString))); + connect(ui->filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterColumnChanged(int))); + + /* Set own item delegate */ + RSItemDelegate *itemDelegate = new RSItemDelegate(this); + itemDelegate->setSpacing(QSize(0, 2)); + ui->threadTreeWidget->setItemDelegate(itemDelegate); + + /* Set header resize modes and initial section sizes */ + QHeaderView * ttheader = ui->threadTreeWidget->header () ; + ttheader->setResizeMode (COLUMN_THREAD_TITLE, QHeaderView::Interactive); + ttheader->resizeSection (COLUMN_THREAD_DATE, 140); + ttheader->resizeSection (COLUMN_THREAD_TITLE, 290); + + ui->threadTreeWidget->sortItems(COLUMN_THREAD_DATE, Qt::DescendingOrder); + + /* Set text of column "Read" to empty - without this the column has a number as header text */ + QTreeWidgetItem *headerItem = ui->threadTreeWidget->headerItem(); + headerItem->setText(COLUMN_THREAD_READ, ""); + +//#AFTER MERGE + setTextColorNotSubscribed(Qt::black); + setTextColorUnread(Qt::black); + setTextColorUnreadChildren(Qt::gray); + setTextColorRead(Qt::gray); + setTextColorMissing(Qt::darkRed); + + /* Initialize group tree */ +//#AFTER MERGE ui.forumTreeWidget->initDisplayMenu(ui.displayButton); + + /* add filter actions */ +//#AFTER MERGE ui.filterLineEdit->addFilter(QIcon(), tr("Title"), COLUMN_THREAD_TITLE, tr("Search Title")); +//#AFTER MERGE ui.filterLineEdit->addFilter(QIcon(), tr("Date"), COLUMN_THREAD_DATE, tr("Search Date")); +//#AFTER MERGE ui.filterLineEdit->addFilter(QIcon(), tr("Author"), COLUMN_THREAD_AUTHOR, tr("Search Author")); +//#AFTER MERGE ui.filterLineEdit->addFilter(QIcon(), tr("Content"), COLUMN_THREAD_CONTENT, tr("Search Content")); +//#AFTER MERGE ui.filterLineEdit->setCurrentFilter(COLUMN_THREAD_TITLE); + + mLastViewType = -1; + + // load settings + processSettings(true); + + /* Set header sizes for the fixed columns and resize modes, must be set after processSettings */ + ttheader->resizeSection (COLUMN_THREAD_READ, 24); + ttheader->setResizeMode (COLUMN_THREAD_READ, QHeaderView::Fixed); + ttheader->hideSection (COLUMN_THREAD_CONTENT); + + ui->progressBar->hide(); + ui->progLayOutTxt->hide(); + ui->progressBarLayOut->setEnabled(false); + + mThreadLoading = false; + + insertThreads(); + + ui->threadTreeWidget->installEventFilter(this); +} + +GxsForumThreadWidget::~GxsForumThreadWidget() +{ + delete ui; + + delete(mThreadQueue); + delete(mThreadCompareRole); +} + +void GxsForumThreadWidget::processSettings(bool load) +{ + mInProcessSettings = true; + + QHeaderView *header = ui->threadTreeWidget->header(); + + Settings->beginGroup(QString("GxsForumsDialog")); + + if (load) { + // load settings + + // expandFiles + bool bValue = Settings->value("expandButton", true).toBool(); + ui->expandButton->setChecked(bValue); + togglethreadview_internal(); + + // filterColumn +//#AFTER MERGE ui.filterLineEdit->setCurrentFilter(Settings->value("filterColumn", COLUMN_THREAD_TITLE).toInt()); + + // index of viewBox + ui->viewBox->setCurrentIndex(Settings->value("viewBox", VIEW_THREADED).toInt()); + + // state of thread tree + header->restoreState(Settings->value("ThreadTree").toByteArray()); + + // state of splitter + ui->threadSplitter->restoreState(Settings->value("threadSplitter").toByteArray()); + } else { + // save settings + + // state of thread tree + Settings->setValue("ThreadTree", header->saveState()); + + // state of splitter + Settings->setValue("threadSplitter", ui->threadSplitter->saveState()); + } + + Settings->endGroup(); + mInProcessSettings = false; +} + +QString GxsForumThreadWidget::forumName() +{ + return ui->forumName->text(); +} + +void GxsForumThreadWidget::changeEvent(QEvent *e) +{ + QWidget::changeEvent(e); + switch (e->type()) { + case QEvent::StyleChange: + calculateIconsAndFonts(); + break; + default: + // remove compiler warnings + break; + } +} + +void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/) +{ + if (mThreadLoading) { + return; + } + + QMenu contextMnu(this); + + QAction *replyAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Reply"), &contextMnu); + connect(replyAct, SIGNAL(triggered()), this, SLOT(createmessage())); + + QAction *newthreadAct = new QAction(QIcon(IMAGE_DOWNLOADALL), tr("Start New Thread"), &contextMnu); + newthreadAct->setEnabled (IS_GROUP_SUBSCRIBED(mSubscribeFlags)); + connect(newthreadAct , SIGNAL(triggered()), this, SLOT(createthread())); + + QAction *replyauthorAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Reply to Author"), &contextMnu); + connect(replyauthorAct, SIGNAL(triggered()), this, SLOT(replytomessage())); + + QAction* expandAll = new QAction(tr("Expand all"), &contextMnu); + connect(expandAll, SIGNAL(triggered()), ui->threadTreeWidget, SLOT(expandAll())); + + QAction* collapseAll = new QAction(tr( "Collapse all"), &contextMnu); + connect(collapseAll, SIGNAL(triggered()), ui->threadTreeWidget, SLOT(collapseAll())); + + QAction *markMsgAsRead = new QAction(QIcon(":/images/message-mail-read.png"), tr("Mark as read"), &contextMnu); + connect(markMsgAsRead, SIGNAL(triggered()), this, SLOT(markMsgAsRead())); + + QAction *markMsgAsReadChildren = new QAction(QIcon(":/images/message-mail-read.png"), tr("Mark as read") + " (" + tr ("with children") + ")", &contextMnu); + connect(markMsgAsReadChildren, SIGNAL(triggered()), this, SLOT(markMsgAsReadChildren())); + + QAction *markMsgAsUnread = new QAction(QIcon(":/images/message-mail.png"), tr("Mark as unread"), &contextMnu); + connect(markMsgAsUnread, SIGNAL(triggered()), this, SLOT(markMsgAsUnread())); + + QAction *markMsgAsUnreadChildren = new QAction(QIcon(":/images/message-mail.png"), tr("Mark as unread") + " (" + tr ("with children") + ")", &contextMnu); + connect(markMsgAsUnreadChildren, SIGNAL(triggered()), this, SLOT(markMsgAsUnreadChildren())); + + if (IS_GROUP_SUBSCRIBED(mSubscribeFlags)) { + QList rows; + QList rowsRead; + QList rowsUnread; + int nCount = getSelectedMsgCount(&rows, &rowsRead, &rowsUnread); + + if (rowsUnread.size() == 0) { + markMsgAsRead->setDisabled(true); + } + if (rowsRead.size() == 0) { + markMsgAsUnread->setDisabled(true); + } + + bool hasUnreadChildren = false; + bool hasReadChildren = false; + int rowCount = rows.count(); + for (int i = 0; i < rowCount; i++) { + if (hasUnreadChildren || rows[i]->data(COLUMN_THREAD_DATA, ROLE_THREAD_UNREADCHILDREN).toBool()) { + hasUnreadChildren = true; + } + if (hasReadChildren || rows[i]->data(COLUMN_THREAD_DATA, ROLE_THREAD_READCHILDREN).toBool()) { + hasReadChildren = true; + } + } + markMsgAsReadChildren->setEnabled(hasUnreadChildren); + markMsgAsUnreadChildren->setEnabled(hasReadChildren); + + if (nCount == 1) { + replyAct->setEnabled (true); + replyauthorAct->setEnabled (true); + } else { + replyAct->setDisabled (true); + replyauthorAct->setDisabled (true); + } + } else { + markMsgAsRead->setDisabled(true); + markMsgAsReadChildren->setDisabled(true); + markMsgAsUnread->setDisabled(true); + markMsgAsUnreadChildren->setDisabled(true); + replyAct->setDisabled (true); + replyauthorAct->setDisabled (true); + } + + contextMnu.addAction(replyAct); + contextMnu.addAction(newthreadAct); + contextMnu.addAction(replyauthorAct); + QAction* action = contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyMessageLink())); + action->setEnabled(!mForumId.empty() && !mThreadId.empty()); + contextMnu.addSeparator(); + contextMnu.addAction(markMsgAsRead); + contextMnu.addAction(markMsgAsReadChildren); + contextMnu.addAction(markMsgAsUnread); + contextMnu.addAction(markMsgAsUnreadChildren); + contextMnu.addSeparator(); + contextMnu.addAction(expandAll); + contextMnu.addAction(collapseAll); + + contextMnu.exec(QCursor::pos()); +} + +bool GxsForumThreadWidget::eventFilter(QObject *obj, QEvent *event) +{ + if (obj == ui->threadTreeWidget) { + if (event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(event); + if (keyEvent && keyEvent->key() == Qt::Key_Space) { + // Space pressed + QTreeWidgetItem *item = ui->threadTreeWidget->currentItem(); + clickedThread (item, COLUMN_THREAD_READ); + return true; // eat event + } + } + } + // pass the event on to the parent class + return QWidget::eventFilter(obj, event); +} + +void GxsForumThreadWidget::togglethreadview() +{ + // save state of button + Settings->setValueToGroup("GxsForumsDialog", "expandButton", ui->expandButton->isChecked()); + + togglethreadview_internal(); +} + +void GxsForumThreadWidget::togglethreadview_internal() +{ + if (ui->expandButton->isChecked()) { + ui->postText->setVisible(true); + ui->expandButton->setIcon(QIcon(QString(":/images/edit_remove24.png"))); + ui->expandButton->setToolTip(tr("Hide")); + } else { + ui->postText->setVisible(false); + ui->expandButton->setIcon(QIcon(QString(":/images/edit_add24.png"))); + ui->expandButton->setToolTip(tr("Expand")); + } +} + +void GxsForumThreadWidget::changedThread() +{ + if (mThreadLoading) { + return; + } + + /* just grab the ids of the current item */ + QTreeWidgetItem *item = ui->threadTreeWidget->currentItem(); + + if (!item || !item->isSelected()) { + mThreadId.clear(); + } else { + mThreadId = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString(); + } + insertPost(); +} + +void GxsForumThreadWidget::clickedThread(QTreeWidgetItem *item, int column) +{ + if (mForumId.empty() || !IS_GROUP_SUBSCRIBED(mSubscribeFlags)) { + return; + } + + if (item == NULL) { + return; + } + + if (column == COLUMN_THREAD_READ) { + QList rows; + rows.append(item); + uint32_t status = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + setMsgReadStatus(rows, IS_MSG_UNREAD(status)); + } +} + +#ifdef TODO +void GxsForumThreadWidget::forumMsgReadStatusChanged(const QString &forumId, const QString &msgId, int status) +{ + if (mInMsgAsReadUnread) { + return; + } + + if (forumId.toStdString() == mCurrForumId) { + /* Search exisiting item */ + QTreeWidgetItemIterator itemIterator(ui->threadTreeWidget); + QTreeWidgetItem *item = NULL; + while ((item = *itemIterator) != NULL) { + itemIterator++; + + if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString() == msgId) { + // update status + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, status); + + QTreeWidgetItem *parentItem = item; + while (parentItem->parent()) { + parentItem = parentItem->parent(); + } + calculateIconsAndFonts(parentItem); + break; + } + } + } + updateMessageSummaryList(forumId.toStdString()); +} +#endif + +void GxsForumThreadWidget::calculateIconsAndFonts(QTreeWidgetItem *item, bool &hasReadChilddren, bool &hasUnreadChilddren) +{ + uint32_t status = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + + bool unread = IS_MSG_UNREAD(status); + bool missing = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING).toBool(); + + // set icon + if (missing) { + item->setIcon(COLUMN_THREAD_READ, QIcon()); + item->setIcon(COLUMN_THREAD_TITLE, QIcon()); + } else { + if (unread) { + item->setIcon(COLUMN_THREAD_READ, QIcon(":/images/message-state-unread.png")); + } else { + item->setIcon(COLUMN_THREAD_READ, QIcon(":/images/message-state-read.png")); + } + if (IS_MSG_UNREAD(status)) { + item->setIcon(COLUMN_THREAD_TITLE, QIcon(":/images/message-state-new.png")); + } else { + item->setIcon(COLUMN_THREAD_TITLE, QIcon()); + } + } + + int index; + int itemCount = item->childCount(); + + bool myReadChilddren = false; + bool myUnreadChilddren = false; + + for (index = 0; index < itemCount; ++index) { + calculateIconsAndFonts(item->child(index), myReadChilddren, myUnreadChilddren); + } + + // set font + for (int i = 0; i < COLUMN_THREAD_COUNT; ++i) { + QFont qf = item->font(i); + + if (!IS_GROUP_SUBSCRIBED(mSubscribeFlags)) { + qf.setBold(false); + item->setTextColor(i, textColorNotSubscribed()); + } else if (unread) { + qf.setBold(true); + item->setTextColor(i, textColorUnread()); + } else if (myUnreadChilddren) { + qf.setBold(true); + item->setTextColor(i, textColorUnreadChildren()); + } else { + qf.setBold(false); + item->setTextColor(i, textColorRead()); + } + if (missing) { + /* Missing message */ + item->setTextColor(i, textColorMissing()); + } + item->setFont(i, qf); + } + + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_READCHILDREN, hasReadChilddren || myReadChilddren); + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_UNREADCHILDREN, hasUnreadChilddren || myUnreadChilddren); + + hasReadChilddren = hasReadChilddren || myReadChilddren || !unread; + hasUnreadChilddren = hasUnreadChilddren || myUnreadChilddren || unread; +} + +void GxsForumThreadWidget::calculateIconsAndFonts(QTreeWidgetItem *item /*= NULL*/) +{ + bool dummy1 = false; + bool dummy2 = false; + + if (item) { + calculateIconsAndFonts(item, dummy1, dummy2); + return; + } + + int index; + int itemCount = ui->threadTreeWidget->topLevelItemCount(); + + for (index = 0; index < itemCount; ++index) { + dummy1 = false; + dummy2 = false; + calculateIconsAndFonts(ui->threadTreeWidget->topLevelItem(index), dummy1, dummy2); + } +} + +#ifdef TODO +void GxsForumsDialog::fillThreadProgress(int current, int count) +{ + // show fill progress + if (count) { + ui.progressBar->setValue(current * ui.progressBar->maximum() / count); + } +} +#endif + +void GxsForumThreadWidget::insertThreads() +{ +#ifdef DEBUG_FORUMS + /* get the current Forum */ + std::cerr << "GxsForumsDialog::insertThreads()" << std::endl; +#endif + + mSubscribeFlags = 0; + + ui->newmessageButton->setEnabled(false); + ui->newthreadButton->setEnabled(false); + + ui->postText->clear(); + ui->threadTitle->clear(); + + if (mForumId.empty()) + { + /* not an actual forum - clear */ + ui->threadTreeWidget->clear(); + /* when no Thread selected - clear */ + ui->forumName->clear(); + /* clear last stored forumID */ + mForumId.erase(); + mLastForumID.erase(); + +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumsDialog::insertThreads() Current Thread Invalid" << std::endl; +#endif + + return; + } + + // Get Current Forum Info... then complete insertForumThreads(). + requestGroupSummary_CurrentForum(mForumId); +} + +void GxsForumThreadWidget::insertForumThreads(const RsGroupMetaData &fi) +{ + mSubscribeFlags = fi.mSubscribeFlags; + QString forumName = QString::fromUtf8(fi.mGroupName.c_str()); + if (forumName != ui->forumName->text()) { + ui->forumName->setText(forumName); + emit forumChanged(this); + } + +// ui->progressBarLayOut->setEnabled(true); + +// ui->progLayOutTxt->show(); +// ui->progressBar->reset(); +// ui->progressBar->show(); + + ui->threadTreeWidget->setPlaceholderText(tr("Loading")); + +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumsDialog::insertThreads() Start filling Forum threads" << std::endl; +#endif + + // Get Forum Threads... then complete fillThreadFinished(). + loadCurrentForumThreads(fi.mGroupId); +} + +static void cleanupItems (QList &items) +{ + QList::iterator item; + for (item = items.begin (); item != items.end (); item++) { + if (*item) { + delete (*item); + } + } + items.clear(); +} + +void GxsForumThreadWidget::fillThreadFinished() +{ +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumsDialog::fillThreadFinished" << std::endl; +#endif + + // This is now only called with a successful Load. + // cleanup of incomplete is handled elsewhere. + + // current thread has finished, hide progressbar and release thread +// ui->progressBar->hide(); +// ui->progLayOutTxt->hide(); +// ui->progressBarLayOut->setEnabled(false); + + ui->threadTreeWidget->setPlaceholderText(""); + +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumsDialog::fillThreadFinished Add messages" << std::endl; +#endif + ui->threadTreeWidget->setSortingEnabled(false); + + /* add all messages in! */ + if (mLastViewType != mThreadLoad.ViewType || mLastForumID != mForumId) + { + ui->threadTreeWidget->clear(); + mLastViewType = mThreadLoad.ViewType; + mLastForumID = mForumId; + ui->threadTreeWidget->insertTopLevelItems(0, mThreadLoad.Items); + + // clear list + mThreadLoad.Items.clear(); + } + else + { + fillThreads(mThreadLoad.Items, mThreadLoad.ExpandNewMessages, mThreadLoad.ItemToExpand); + + // cleanup list + cleanupItems(mThreadLoad.Items); + } + + ui->threadTreeWidget->setSortingEnabled(true); + + if (mThreadLoad.FocusMsgId.empty() == false) + { + /* Search exisiting item */ + QTreeWidgetItemIterator itemIterator(ui->threadTreeWidget); + QTreeWidgetItem *item = NULL; + while ((item = *itemIterator) != NULL) + { + itemIterator++; + + if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString() == mThreadLoad.FocusMsgId) + { + ui->threadTreeWidget->setCurrentItem(item); + ui->threadTreeWidget->setFocus(); + break; + } + } + } + + QList::iterator Item; + for (Item = mThreadLoad.ItemToExpand.begin(); Item != mThreadLoad.ItemToExpand.end(); Item++) + { + if ((*Item)->isHidden() == false) + { + (*Item)->setExpanded(true); + } + } + mThreadLoad.ItemToExpand.clear(); + + if (ui->filterLineEdit->text().isEmpty() == false) { + filterItems(ui->filterLineEdit->text()); + } + + insertPost(); + calculateIconsAndFonts(); + + ui->newthreadButton->setEnabled(IS_GROUP_SUBSCRIBED(mSubscribeFlags)); + + mThreadLoading = false; + +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumsDialog::fillThreadFinished done" << std::endl; +#endif +} + +void GxsForumThreadWidget::fillThreads(QList &threadList, bool expandNewMessages, QList &itemToExpand) +{ +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumsDialog::fillThreads()" << std::endl; +#endif + + int index = 0; + QTreeWidgetItem *threadItem; + QList::iterator newThread; + + // delete not existing + while (index < ui->threadTreeWidget->topLevelItemCount()) { + threadItem = ui->threadTreeWidget->topLevelItem(index); + + // search existing new thread + int found = -1; + for (newThread = threadList.begin (); newThread != threadList.end (); ++newThread) { + if (threadItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == (*newThread)->data (COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { + // found it + found = index; + break; + } + } + if (found >= 0) { + index++; + } else { + delete(ui->threadTreeWidget->takeTopLevelItem(index)); + } + } + + // iterate all new threads + for (newThread = threadList.begin (); newThread != threadList.end (); ++newThread) { + // search existing thread + int found = -1; + int count = ui->threadTreeWidget->topLevelItemCount(); + for (index = 0; index < count; ++index) { + threadItem = ui->threadTreeWidget->topLevelItem(index); + if (threadItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == (*newThread)->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { + // found it + found = index; + break; + } + } + + if (found >= 0) { + // set child data + int i; + for (i = 0; i < COLUMN_THREAD_COUNT; ++i) { + threadItem->setText(i, (*newThread)->text(i)); + } + for (i = 0; i < ROLE_THREAD_COUNT; ++i) { + threadItem->setData(COLUMN_THREAD_DATA, Qt::UserRole + i, (*newThread)->data(COLUMN_THREAD_DATA, Qt::UserRole + i)); + } + + // fill recursive + fillChildren(threadItem, *newThread, expandNewMessages, itemToExpand); + } else { + // add new thread + ui->threadTreeWidget->addTopLevelItem (*newThread); + threadItem = *newThread; + *newThread = NULL; + } + + uint32_t status = threadItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + if (expandNewMessages && IS_MSG_UNREAD(status)) { + QTreeWidgetItem *parentItem = threadItem; + while ((parentItem = parentItem->parent()) != NULL) { + if (std::find(itemToExpand.begin(), itemToExpand.end(), parentItem) == itemToExpand.end()) { + itemToExpand.push_back(parentItem); + } + } + } + } + +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumsDialog::fillThreads() done" << std::endl; +#endif +} + +void GxsForumThreadWidget::fillChildren(QTreeWidgetItem *parentItem, QTreeWidgetItem *newParentItem, bool expandNewMessages, QList &itemToExpand) +{ + int index = 0; + int newIndex; + int newCount = newParentItem->childCount(); + + QTreeWidgetItem *childItem; + QTreeWidgetItem *newChildItem; + + // delete not existing + while (index < parentItem->childCount()) { + childItem = parentItem->child(index); + + // search existing new child + int found = -1; + int count = newParentItem->childCount(); + for (newIndex = 0; newIndex < count; ++newIndex) { + newChildItem = newParentItem->child(newIndex); + if (newChildItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == childItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { + // found it + found = index; + break; + } + } + if (found >= 0) { + index++; + } else { + delete(parentItem->takeChild (index)); + } + } + + // iterate all new children + for (newIndex = 0; newIndex < newCount; ++newIndex) { + newChildItem = newParentItem->child(newIndex); + + // search existing child + int found = -1; + int count = parentItem->childCount(); + for (index = 0; index < count; ++index) { + childItem = parentItem->child(index); + if (childItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID) == newChildItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID)) { + // found it + found = index; + break; + } + } + + if (found >= 0) { + // set child data + int i; + for (i = 0; i < COLUMN_THREAD_COUNT; ++i) { + childItem->setText(i, newChildItem->text(i)); + } + for (i = 0; i < ROLE_THREAD_COUNT; ++i) { + childItem->setData(COLUMN_THREAD_DATA, Qt::UserRole + i, newChildItem->data(COLUMN_THREAD_DATA, Qt::UserRole + i)); + } + + // fill recursive + fillChildren(childItem, newChildItem, expandNewMessages, itemToExpand); + } else { + // add new child + childItem = newParentItem->takeChild(newIndex); + parentItem->addChild(childItem); + newIndex--; + newCount--; + } + + uint32_t status = childItem->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + if (expandNewMessages && IS_MSG_UNREAD(status)) { + QTreeWidgetItem *parentItem = childItem; + while ((parentItem = parentItem->parent()) != NULL) { + if (std::find(itemToExpand.begin(), itemToExpand.end(), parentItem) == itemToExpand.end()) { + itemToExpand.push_back(parentItem); + } + } + } + } +} + +void GxsForumThreadWidget::insertPost() +{ + if (mForumId.empty() || mThreadId.empty()) + { + ui->postText->setText(""); + ui->threadTitle->setText(""); + ui->previousButton->setEnabled(false); + ui->nextButton->setEnabled(false); + ui->newmessageButton->setEnabled (false); + return; + } + + QTreeWidgetItem *item = ui->threadTreeWidget->currentItem(); + if (item) { + QTreeWidgetItem *parentItem = item->parent(); + int index = parentItem ? parentItem->indexOfChild(item) : ui->threadTreeWidget->indexOfTopLevelItem(item); + int count = parentItem ? parentItem->childCount() : ui->threadTreeWidget->topLevelItemCount(); + ui->previousButton->setEnabled(index > 0); + ui->nextButton->setEnabled(index < count - 1); + } else { + // there is something wrong + ui->previousButton->setEnabled(false); + ui->nextButton->setEnabled(false); + return; + } + + ui->postText->setPlaceholderText(tr("Loading")); + ui->threadTitle->setText(tr("Loading")); + + ui->newmessageButton->setEnabled(IS_GROUP_SUBSCRIBED(mSubscribeFlags) && mThreadId.empty() == false); + + /* blank text, incase we get nothing */ + ui->postText->setText(""); + /* request Post */ + + // Get Forum Post ... then complete insertPostData(). + RsGxsGrpMsgIdPair postId = std::make_pair(mForumId, mThreadId); + requestMsgData_InsertPost(postId); +} + +void GxsForumThreadWidget::insertPostData(const RsGxsForumMsg &msg) +{ + /* As some time has elapsed since request - check that this is still the current msg. + * otherwise, another request will fill the data + */ + + ui->postText->setPlaceholderText(""); + ui->threadTitle->setText(""); + + if ((msg.mMeta.mGroupId != mForumId) || (msg.mMeta.mMsgId != mThreadId)) + { + std::cerr << "GxsForumsDialog::insertPostData() Ignoring Invalid Data...."; + std::cerr << std::endl; + std::cerr << "\t CurrForumId: " << mForumId << " != msg.GroupId: " << msg.mMeta.mGroupId; + std::cerr << std::endl; + std::cerr << "\t or CurrThdId: " << mThreadId << " != msg.MsgId: " << msg.mMeta.mMsgId; + std::cerr << std::endl; + std::cerr << std::endl; + return; + } + + QTreeWidgetItem *item = ui->threadTreeWidget->currentItem(); + + bool setToReadOnActive = Settings->getForumMsgSetToReadOnActivate(); + uint32_t status = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + + QList row; + row.append(item); + + if (setToReadOnActive && IS_MSG_UNREAD(status)) + { + setMsgReadStatus(row, true); + } + +//#AFTER MERGE ui.time_label->setText(DateTime::formatLongDateTime(msg.mMeta.mPublishTs)); + + std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); + QString text = QString::fromUtf8(authorName.c_str()); + +//#AFTER MERGE merge from ForumsDialog + if (text.isEmpty()) + { + ui->by_label->setText( tr("By") + " " + tr("Anonymous")); + } + else + { + ui->by_label->setText( tr("By") + " " + text ); + } + + QString extraTxt = RsHtml().formatText(ui->postText->document(), GxsForumsDialog::messageFromInfo(msg), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS); + + ui->postText->setHtml(extraTxt); + ui->threadTitle->setText(GxsForumsDialog::titleFromInfo(msg.mMeta)); +} + +void GxsForumThreadWidget::previousMessage() +{ + QTreeWidgetItem *item = ui->threadTreeWidget->currentItem(); + if (item == NULL) { + return; + } + + QTreeWidgetItem *parentItem = item->parent(); + int index = parentItem ? parentItem->indexOfChild(item) : ui->threadTreeWidget->indexOfTopLevelItem(item); + if (index > 0) { + QTreeWidgetItem *previousItem = parentItem ? parentItem->child(index - 1) : ui->threadTreeWidget->topLevelItem(index - 1); + if (previousItem) { + ui->threadTreeWidget->setCurrentItem(previousItem); + } + } +} + +void GxsForumThreadWidget::nextMessage() +{ + QTreeWidgetItem *item = ui->threadTreeWidget->currentItem(); + if (item == NULL) { + return; + } + + QTreeWidgetItem *parentItem = item->parent(); + int index = parentItem ? parentItem->indexOfChild(item) : ui->threadTreeWidget->indexOfTopLevelItem(item); + int count = parentItem ? parentItem->childCount() : ui->threadTreeWidget->topLevelItemCount(); + if (index < count - 1) { + QTreeWidgetItem *nextItem = parentItem ? parentItem->child(index + 1) : ui->threadTreeWidget->topLevelItem(index + 1); + if (nextItem) { + ui->threadTreeWidget->setCurrentItem(nextItem); + } + } +} + +void GxsForumThreadWidget::downloadAllFiles() +{ + QStringList urls; + if (RsHtml::findAnchors(ui->postText->toHtml(), urls) == false) { + return; + } + + if (urls.count() == 0) { + return; + } + + RetroShareLink::process(urls, RetroShareLink::TYPE_FILE/*, true*/); +} + +void GxsForumThreadWidget::nextUnreadMessage() +{ + QTreeWidgetItem *currentItem = ui->threadTreeWidget->currentItem(); + + while (TRUE) { + QTreeWidgetItemIterator itemIterator = currentItem ? QTreeWidgetItemIterator(currentItem, QTreeWidgetItemIterator::NotHidden) : QTreeWidgetItemIterator(ui->threadTreeWidget, QTreeWidgetItemIterator::NotHidden); + + QTreeWidgetItem *item; + while ((item = *itemIterator) != NULL) { + itemIterator++; + + if (item == currentItem) { + continue; + } + + uint32_t status = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + if (IS_MSG_UNREAD(status)) { + ui->threadTreeWidget->setCurrentItem(item); + ui->threadTreeWidget->scrollToItem(item, QAbstractItemView::EnsureVisible); + return; + } + } + + if (currentItem == NULL) { + break; + } + + /* start from top */ + currentItem = NULL; + } +} + +// TODO +#if 0 +void GxsForumsDialog::removemessage() +{ + //std::cerr << "GxsForumsDialog::removemessage()" << std::endl; + std::string cid, mid; + if (!getCurrentMsg(cid, mid)) + { + //std::cerr << "GxsForumsDialog::removemessage()"; + //std::cerr << " No Message selected" << std::endl; + return; + } + + rsMsgs -> MessageDelete(mid); +} +#endif + +/* get selected messages + the messages tree is single selected, but who knows ... */ +int GxsForumThreadWidget::getSelectedMsgCount(QList *rows, QList *rowsRead, QList *rowsUnread) +{ + if (rowsRead) rowsRead->clear(); + if (rowsUnread) rowsUnread->clear(); + + QList selectedItems = ui->threadTreeWidget->selectedItems(); + for(QList::iterator it = selectedItems.begin(); it != selectedItems.end(); it++) { + if (rows) rows->append(*it); + if (rowsRead || rowsUnread) { + uint32_t status = (*it)->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + if (IS_MSG_UNREAD(status)) { + if (rowsUnread) rowsUnread->append(*it); + } else { + if (rowsRead) rowsRead->append(*it); + } + } + } + + return selectedItems.size(); +} + +void GxsForumThreadWidget::setMsgReadStatus(QList &rows, bool read) +{ + QList::iterator row; + std::list changedItems; + + mInMsgAsReadUnread = true; + + for (row = rows.begin(); row != rows.end(); ++row) { + if ((*row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING).toBool()) { + /* Missing message */ + continue; + } + + uint32_t status = (*row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + + uint32_t statusNew = (status & ~GXS_SERV::GXS_MSG_STATUS_UNREAD); // orig status, without UNREAD. + if (!read) { + statusNew |= GXS_SERV::GXS_MSG_STATUS_UNREAD; + } + + if (IS_MSG_UNREAD(status) == read) // is it different? + { + std::string msgId = (*row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString(); + + // NB: MUST BE PART OF ACTIVE THREAD--- OR ELSE WE MUST STORE GROUPID SOMEWHERE!. + // LIKE THIS BELOW... + //std::string grpId = (*Row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_GROUPID).toString().toStdString(); + + RsGxsGrpMsgIdPair msgPair = std::make_pair(mForumId, msgId); + + uint32_t token; + rsGxsForums->setMessageReadStatus(token, msgPair, read); + + (*row)->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, statusNew); + + QTreeWidgetItem *parentItem = *row; + while (parentItem->parent()) { + parentItem = parentItem->parent(); + } + if (std::find(changedItems.begin(), changedItems.end(), parentItem) == changedItems.end()) { + changedItems.push_back(parentItem); + } + } + } + + mInMsgAsReadUnread = false; + + if (changedItems.size()) { + for (std::list::iterator it = changedItems.begin(); it != changedItems.end(); it++) { + calculateIconsAndFonts(*it); + } +//#TODO updateMessageSummaryList(mForumId); + } +} + +void GxsForumThreadWidget::markMsgAsReadUnread (bool read, bool children, bool forum) +{ + if (mForumId.empty() || !IS_GROUP_SUBSCRIBED(mSubscribeFlags)) { + return; + } + + /* get selected messages */ + QList rows; + if (forum) { + int itemCount = ui->threadTreeWidget->topLevelItemCount(); + for (int item = 0; item < itemCount; item++) { + rows.push_back(ui->threadTreeWidget->topLevelItem(item)); + } + } else { + getSelectedMsgCount (&rows, NULL, NULL); + } + + if (children) { + /* add children */ + QList allRows; + + while (rows.isEmpty() == false) { + QTreeWidgetItem *row = rows.takeFirst(); + + /* add only items with the right state or with not RSGXS_MSG_STATUS_READ */ + uint32_t status = row->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + if (IS_MSG_UNREAD(status) == read) { + allRows.append(row); + } + + for (int i = 0; i < row->childCount(); i++) { + /* add child to main list and let the main loop do the work */ + rows.append(row->child(i)); + } + } + + if (allRows.isEmpty()) { + /* nothing to do */ + return; + } + + setMsgReadStatus(allRows, read); + + return; + } + + setMsgReadStatus(rows, read); +} + +void GxsForumThreadWidget::markMsgAsRead() +{ + markMsgAsReadUnread(true, false, false); +} + +void GxsForumThreadWidget::markMsgAsReadChildren() +{ + markMsgAsReadUnread(true, true, false); +} + +void GxsForumThreadWidget::markMsgAsReadAll() +{ + markMsgAsReadUnread(true, true, true); +} + +void GxsForumThreadWidget::markMsgAsUnread() +{ + markMsgAsReadUnread(false, false, false); +} + +void GxsForumThreadWidget::markMsgAsUnreadChildren() +{ + markMsgAsReadUnread(false, true, false); +} + +void GxsForumThreadWidget::markMsgAsUnreadAll() +{ + markMsgAsReadUnread(false, true, true); +} + +void GxsForumThreadWidget::copyMessageLink() +{ + if (mForumId.empty() || mThreadId.empty()) { + return; + } + +// THIS CODE CALLS getForumInfo() to verify that the Ids are valid. +// As we are switching to Request/Response this is now harder to do... +// So not bothering any more - shouldn't be necessary. +// IF we get errors - fix them, rather than patching here. +#if 0 + ForumInfo fi; + if (rsGxsForums->getForumInfo(mForumId, fi)) { + RetroShareLink link; + if (link.createForum(mForumId, mThreadId)) { + QList urls; + urls.push_back(link); + RSLinkClipboard::copyLinks(urls); + } + } +#endif + + QMessageBox::warning(this, "RetroShare", "ToDo"); +} + +void GxsForumThreadWidget::createmessage() +{ + if (mForumId.empty () || !IS_GROUP_SUBSCRIBED(mSubscribeFlags)) { + return; + } + + CreateGxsForumMsg *cfm = new CreateGxsForumMsg(mForumId, mThreadId); + cfm->show(); + + /* window will destroy itself! */ +} + +void GxsForumThreadWidget::createthread() +{ + if (mForumId.empty ()) { + QMessageBox::information(this, tr("RetroShare"), tr("No Forum Selected!")); + return; + } + + CreateGxsForumMsg *cfm = new CreateGxsForumMsg(mForumId, ""); + cfm->show(); + + /* window will destroy itself! */ +} + +static QString buildReplyHeader(const RsMsgMetaData &meta) +{ + RetroShareLink link; + link.createMessage(meta.mAuthorId, ""); + QString from = link.toHtml(); + + QString header = QString("-----%1-----").arg(QApplication::translate("GxsForumsDialog", "Original Message")); + header += QString("
%1: %2
").arg(QApplication::translate("GxsForumsDialog", "From"), from); + +//#AFTER MERGE header += QString("
%1: %2
").arg(QApplication::translate("GxsForumsDialog", "Sent"), DateTime::formatLongDateTime(meta.mPublishTs)); + header += QString("%1: %2

").arg(QApplication::translate("GxsForumsDialog", "Subject"), QString::fromUtf8(meta.mMsgName.c_str())); + header += "
"; + +//#AFTER MERGE header += QApplication::translate("GxsForumsDialog", "On %1, %2 wrote:").arg(DateTime::formatDateTime(meta.mPublishTs), from); + + return header; +} + +void GxsForumThreadWidget::replytomessage() +{ + if (mForumId.empty() || mThreadId.empty()) { + QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to a non-existant Message")); + return; + } + + // Get Message ... then complete replyMessageData(). + RsGxsGrpMsgIdPair postId = std::make_pair(mForumId, mThreadId); + requestMsgData_ReplyMessage(postId); +} + +void GxsForumThreadWidget::replyMessageData(const RsGxsForumMsg &msg) +{ + if ((msg.mMeta.mGroupId != mForumId) || (msg.mMeta.mMsgId != mThreadId)) + { + std::cerr << "GxsForumsDialog::replyMessageData() ERROR Message Ids have changed!"; + std::cerr << std::endl; + return; + } + + // NB: TODO REMOVE rsPeers references. + if (rsPeers->getPeerName(msg.mMeta.mAuthorId) !="") + { + MessageComposer *msgDialog = MessageComposer::newMsg(); + msgDialog->setTitleText(QString::fromUtf8(msg.mMeta.mMsgName.c_str()), MessageComposer::REPLY); + + msgDialog->setQuotedMsg(QString::fromUtf8(msg.mMsg.c_str()), buildReplyHeader(msg.mMeta)); + + msgDialog->addRecipient(MessageComposer::TO, msg.mMeta.mAuthorId, false); + msgDialog->show(); + msgDialog->activateWindow(); + + /* window will destroy itself! */ + } + else + { + QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to an Anonymous Author")); + } +} + +void GxsForumThreadWidget::changedViewBox() +{ + if (mInProcessSettings) { + return; + } + + // save index + Settings->setValueToGroup("GxsForumsDialog", "viewBox", ui->viewBox->currentIndex()); + + ui->threadTreeWidget->clear(); + + insertThreads(); +} + +void GxsForumThreadWidget::filterColumnChanged(int column) +{ + if (mInProcessSettings) { + return; + } + + if (column == COLUMN_THREAD_CONTENT) { + // need content ... refill + insertThreads(); + } else { + filterItems(ui->filterLineEdit->text()); + } + + // save index + Settings->setValueToGroup("GxsForumsDialog", "filterColumn", column); +} + +void GxsForumThreadWidget::filterItems(const QString& text) +{ +//#AFTER MERGE int filterColumn = ui.filterLineEdit->currentFilter(); + int filterColumn = COLUMN_THREAD_TITLE; + + int count = ui->threadTreeWidget->topLevelItemCount(); + for (int index = 0; index < count; ++index) { + filterItem(ui->threadTreeWidget->topLevelItem(index), text, filterColumn); + } +} + +bool GxsForumThreadWidget::filterItem(QTreeWidgetItem *item, const QString &text, int filterColumn) +{ + bool visible = true; + + if (text.isEmpty() == false) { + if (item->text(filterColumn).contains(text, Qt::CaseInsensitive) == false) { + visible = false; + } + } + + int visibleChildCount = 0; + int count = item->childCount(); + for (int nIndex = 0; nIndex < count; ++nIndex) { + if (filterItem(item->child(nIndex), text, filterColumn)) { + visibleChildCount++; + } + } + + if (visible || visibleChildCount) { + item->setHidden(false); + } else { + item->setHidden(true); + } + + return (visible || visibleChildCount); +} + +/*********************** **** **** **** ***********************/ +/** Request / Response of Data ********************************/ +/*********************** **** **** **** ***********************/ + +#define FORUMSV2DIALOG_LISTING 1 +#define FORUMSV2DIALOG_CURRENTFORUM 2 +#define FORUMSV2DIALOG_INSERTTHREADS 3 +#define FORUMSV2DIALOG_INSERTCHILD 4 +#define FORUMV2DIALOG_INSERT_POST 5 +#define FORUMV2DIALOG_REPLY_MESSAGE 6 + +void GxsForumThreadWidget::requestGroupSummary_CurrentForum(const std::string &forumId) +{ + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; + + std::list grpIds; + grpIds.push_back(forumId); + + std::cerr << "GxsForumsDialog::requestGroupSummary_CurrentForum(" << forumId << ")"; + std::cerr << std::endl; + + uint32_t token; + mThreadQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, FORUMSV2DIALOG_CURRENTFORUM); +} + +void GxsForumThreadWidget::loadGroupSummary_CurrentForum(const uint32_t &token) +{ + std::cerr << "GxsForumsDialog::loadGroupSummary_CurrentForum()"; + std::cerr << std::endl; + + std::list groupInfo; + rsGxsForums->getGroupSummary(token, groupInfo); + + if (groupInfo.size() == 1) + { + RsGroupMetaData fi = groupInfo.front(); + insertForumThreads(fi); + } + else + { + std::cerr << "GxsForumsDialog::loadGroupSummary_CurrentForum() ERROR Invalid Number of Groups..."; + std::cerr << std::endl; + } +} + +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ + +void GxsForumThreadWidget::loadCurrentForumThreads(const std::string &forumId) +{ + std::cerr << "GxsForumsDialog::loadCurrentForumThreads(" << forumId << ")"; + std::cerr << std::endl; + + /* if already active -> kill current loading */ + if (mThreadLoading) + { + /* Cleanup */ + std::cerr << "GxsForumsDialog::loadCurrentForumThreads() Cleanup old Threads"; + std::cerr << std::endl; + + /* Wipe Widget Tree */ + mThreadLoad.Items.clear(); + + /* Stop all active requests */ + std::map::iterator it; + for (it = mThreadLoad.MsgTokens.begin(); it != mThreadLoad.MsgTokens.end(); ++it) + { + std::cerr << "GxsForumsDialog::loadCurrentForumThreads() Canceling Request: " << it->first; + std::cerr << std::endl; + + mThreadQueue->cancelRequest(it->first); + } + + mThreadLoad.MsgTokens.clear(); + mThreadLoad.ItemToExpand.clear(); + } + + /* initiate loading */ + std::cerr << "GxsForumsDialog::loadCurrentForumThreads() Initiating Loading"; + std::cerr << std::endl; + + mThreadLoading = true; + + mThreadLoad.ForumId = mForumId; +//#AFTER MERGE mThreadLoad.FilterColumn = ui.filterLineEdit->currentFilter(); + mThreadLoad.FilterColumn = COLUMN_THREAD_TITLE; +// + mThreadLoad.ViewType = ui->viewBox->currentIndex(); + mThreadLoad.FillComplete = false; + + if (mLastViewType != mThreadLoad.ViewType || mLastForumID != mForumId) { + mThreadLoad.FillComplete = true; + } + + mThreadLoad.FlatView = false; + mThreadLoad.UseChildTS = false; + mThreadLoad.ExpandNewMessages = Settings->getExpandNewMessages(); + mThreadLoad.SubscribeFlags = mSubscribeFlags; + + if (mThreadLoad.ViewType == VIEW_FLAT) { + ui->threadTreeWidget->setRootIsDecorated(false); + } else { + ui->threadTreeWidget->setRootIsDecorated(true); + } + + switch(mThreadLoad.ViewType) + { + case VIEW_LAST_POST: + mThreadLoad.UseChildTS = true; + break; + case VIEW_FLAT: + mThreadLoad.FlatView = true; + break; + case VIEW_THREADED: + break; + } + + requestGroupThreadData_InsertThreads(forumId); +} + +void GxsForumThreadWidget::requestGroupThreadData_InsertThreads(const std::string &forumId) +{ + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + + opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; + + std::list grpIds; + grpIds.push_back(forumId); + + std::cerr << "GxsForumsDialog::requestGroupThreadData_InsertThreads(" << forumId << ")"; + std::cerr << std::endl; + + uint32_t token; + mThreadQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, FORUMSV2DIALOG_INSERTTHREADS); +} + +void GxsForumThreadWidget::loadGroupThreadData_InsertThreads(const uint32_t &token) +{ + std::cerr << "GxsForumsDialog::loadGroupThreadData_InsertThreads()"; + std::cerr << std::endl; + + bool someData = false; + + std::vector msgs; + std::vector::iterator vit; + if (rsGxsForums->getMsgData(token, msgs)) + { + for (vit = msgs.begin(); vit != msgs.end(); ++vit) + { + std::cerr << "GxsForumsDialog::loadGroupThreadData_InsertThreads() MsgId: " << vit->mMeta.mMsgId; + std::cerr << std::endl; + + loadForumBaseThread(*vit); + someData = true; + } + } + + /* completed with no data */ + if (!someData) + { + fillThreadFinished(); + } +} + +bool GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, bool useChildTS, uint32_t filterColumn, GxsIdTreeWidgetItem *item) +{ + QString text; + + { + QDateTime qtime; + QString sort; + + if (useChildTS) + qtime.setTime_t(msgInfo.mMeta.mChildTs); + else + qtime.setTime_t(msgInfo.mMeta.mPublishTs); + +//#AFTER MERGE text = DateTime::formatDateTime(qtime); + sort = qtime.toString("yyyyMMdd_hhmmss"); + + if (useChildTS) + { + qtime.setTime_t(msgInfo.mMeta.mPublishTs); + text += " / "; +//#AFTER MERGE text += DateTime::formatDateTime(qtime); + sort += "_" + qtime.toString("yyyyMMdd_hhmmss"); + } + item->setText(COLUMN_THREAD_DATE, text); + item->setData(COLUMN_THREAD_DATE, ROLE_THREAD_SORT, sort); + } + + item->setText(COLUMN_THREAD_TITLE, GxsForumsDialog::titleFromInfo(msgInfo.mMeta)); + + item->setId(msgInfo.mMeta.mAuthorId, COLUMN_THREAD_AUTHOR); +#if 0 + text = QString::fromUtf8(authorName.c_str()); + + if (text.isEmpty()) + { + item->setText(COLUMN_THREAD_AUTHOR, tr("Anonymous")); + } + else + { + item->setText(COLUMN_THREAD_AUTHOR, text); + } +#endif + +#ifdef TOGXS + if (msgInfo.mMeta.mMsgFlags & RS_DISTRIB_AUTHEN_REQ) + { + item->setText(COLUMN_THREAD_SIGNED, tr("signed")); + item->setIcon(COLUMN_THREAD_SIGNED, QIcon(":/images/mail-signed.png")); + } + else + { + item->setText(COLUMN_THREAD_SIGNED, tr("none")); + item->setIcon(COLUMN_THREAD_SIGNED, QIcon(":/images/mail-signature-unknown.png")); + } +#endif + + if (filterColumn == COLUMN_THREAD_CONTENT) { + // need content for filter + QTextDocument doc; + doc.setHtml(QString::fromUtf8(msgInfo.mMsg.c_str())); + item->setText(COLUMN_THREAD_CONTENT, doc.toPlainText().replace(QString("\n"), QString(" "))); + } + + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID, QString::fromStdString(msgInfo.mMeta.mMsgId)); + +#if 0 + if (IS_GROUP_SUBSCRIBED(subscribeFlags) && !(msginfo.mMsgFlags & RS_DISTRIB_MISSING_MSG)) { + rsGxsForums->getMessageStatus(msginfo.forumId, msginfo.msgId, status); + } else { + // show message as read + status = RSGXS_MSG_STATUS_READ; + } +#endif + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, msgInfo.mMeta.mMsgStatus); + +#ifdef TOGXS + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING, (msgInfo.mMeta.mMsgFlags & RS_DISTRIB_MISSING_MSG) ? true : false); +#endif + + return true; +} + +void GxsForumThreadWidget::loadForumBaseThread(const RsGxsForumMsg &msg) +{ + //std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); + + //QTreeWidgetItem *item = new QTreeWidgetItem(); // no Parent. + GxsIdTreeWidgetItem *item = new GxsIdTreeWidgetItem(mThreadCompareRole); // no Parent. + + //convertMsgToThreadWidget(msg, authorName, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, item); + convertMsgToThreadWidget(msg, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, item); + + /* request Children Data */ + uint32_t token; + RsGxsGrpMsgIdPair parentId = std::make_pair(msg.mMeta.mGroupId, msg.mMeta.mMsgId); + requestChildData_InsertThreads(token, parentId); + + /* store pair of (token, item) */ + mThreadLoad.MsgTokens[token] = item; + + /* add item to final tree */ + mThreadLoad.Items.append(item); +} + +/*********************** **** **** **** ***********************/ + +void GxsForumThreadWidget::requestChildData_InsertThreads(uint32_t &token, const RsGxsGrpMsgIdPair &parentId) +{ + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; + opts.mOptions = RS_TOKREQOPT_MSG_PARENT | RS_TOKREQOPT_MSG_LATEST; + + std::cerr << "GxsForumsDialog::requestChildData_InsertThreads(" << parentId.first << "," << parentId.second << ")"; + std::cerr << std::endl; + + std::vector msgIds; + msgIds.push_back(parentId); + mThreadQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMSV2DIALOG_INSERTCHILD); +} + +void GxsForumThreadWidget::loadChildData_InsertThreads(const uint32_t &token) +{ + std::cerr << "GxsForumsDialog::loadChildData_InsertThreads()"; + std::cerr << std::endl; + + /* find the matching *item */ + std::map::iterator it; + it = mThreadLoad.MsgTokens.find(token); + if (it == mThreadLoad.MsgTokens.end()) + { + std::cerr << "GxsForumsDialog::loadChildData_InsertThreads() ERROR Missing Token->Parent in Map"; + std::cerr << std::endl; + /* finished with this one */ + return; + } + + QTreeWidgetItem *parent = it->second; + // cleanup map. + mThreadLoad.MsgTokens.erase(it); + + std::cerr << "GxsForumsDialog::loadChildData_InsertThreads()"; + std::cerr << std::endl; + + std::vector msgs; + std::vector::iterator vit; + if (rsGxsForums->getRelatedMessages(token, msgs)) + { + for(vit = msgs.begin(); vit != msgs.end(); vit++) + { + std::cerr << "GxsForumsDialog::loadChildData_InsertThreads() MsgId: " << vit->mMeta.mMsgId; + std::cerr << std::endl; + + loadForumChildMsg(*vit, parent); + } + } + else + { + std::cerr << "GxsForumsDialog::loadChildData_InsertThreads() Error getting MsgData"; + std::cerr << std::endl; + } + + /* check for completion */ + if (mThreadLoad.MsgTokens.size() == 0) + { + /* finished */ + /* push data into GUI */ + fillThreadFinished(); + } +} + +void GxsForumThreadWidget::loadForumChildMsg(const RsGxsForumMsg &msg, QTreeWidgetItem *parent) +{ + //std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); + + //QTreeWidgetItem *child = NULL; + GxsIdTreeWidgetItem *child = NULL; + + if (mThreadLoad.FlatView) + { + child = new GxsIdTreeWidgetItem(mThreadCompareRole); // no Parent. + } + else + { + child = new GxsIdTreeWidgetItem(mThreadCompareRole, parent); + } + + convertMsgToThreadWidget(msg, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, child); + //convertMsgToThreadWidget(msg, authorName, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, child); + + /* request Children Data */ + uint32_t token; + RsGxsGrpMsgIdPair parentId = std::make_pair(msg.mMeta.mGroupId, msg.mMeta.mMsgId); + requestChildData_InsertThreads(token, parentId); + + /* store pair of (token, item) */ + mThreadLoad.MsgTokens[token] = child; + + // Leave this here... BUT IT WILL NEED TO BE FIXED. + if (mThreadLoad.FillComplete && mThreadLoad.ExpandNewMessages && IS_MSG_UNREAD(msg.mMeta.mMsgStatus)) + { + QTreeWidgetItem *pParent = child; + while ((pParent = pParent->parent()) != NULL) + { + if (std::find(mThreadLoad.ItemToExpand.begin(), mThreadLoad.ItemToExpand.end(), pParent) == mThreadLoad.ItemToExpand.end()) + { + mThreadLoad.ItemToExpand.push_back(pParent); + } + } + } + + if (mThreadLoad.FlatView) + { + /* add item to final tree */ + mThreadLoad.Items.append(child); + } +} + +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ + +void GxsForumThreadWidget::requestMsgData_InsertPost(const RsGxsGrpMsgIdPair &msgId) +{ +#if 0 + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; + + std::cerr << "GxsForumsDialog::requestMsgData_InsertPost(" << msgId.first << "," << msgId.second << ")"; + std::cerr << std::endl; + + std::vector msgIds; + msgIds.push_back(msgId); + uint32_t token; + mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_INSERT_POST); +#else + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + + std::cerr << "GxsForumsDialog::requestMsgData_InsertPost(" << msgId.first << "," << msgId.second << ")"; + std::cerr << std::endl; + + GxsMsgReq msgIds; + std::vector &vect = msgIds[msgId.first]; + vect.push_back(msgId.second); + + uint32_t token; + mThreadQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_INSERT_POST); +#endif +} + +void GxsForumThreadWidget::loadMsgData_InsertPost(const uint32_t &token) +{ + std::cerr << "GxsForumsDialog::loadMsgData_InsertPost()"; + std::cerr << std::endl; + + std::vector msgs; +#if 0 + if (rsGxsForums->getRelatedMessages(token, msgs)) +#else + if (rsGxsForums->getMsgData(token, msgs)) +#endif + { + if (msgs.size() != 1) + { + std::cerr << "GxsForumsDialog::loadMsgData_InsertPost() ERROR Wrong number of answers"; + std::cerr << std::endl; + return; + } + insertPostData(msgs[0]); + } + else + { + std::cerr << "GxsForumsDialog::loadMsgData_InsertPost() ERROR Missing Message Data..."; + std::cerr << std::endl; + } +} + +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ + +void GxsForumThreadWidget::requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId) +{ +#if 0 + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; + + std::cerr << "GxsForumsDialog::requestMsgData_ReplyMessage(" << msgId.first << "," << msgId.second << ")"; + std::cerr << std::endl; + + std::vector msgIds; + msgIds.push_back(msgId); + uint32_t token; + mThreadQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_REPLY_MESSAGE); +#else + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + + std::cerr << "GxsForumsDialog::requestMsgData_ReplyMessage(" << msgId.first << "," << msgId.second << ")"; + std::cerr << std::endl; + + GxsMsgReq msgIds; + std::vector &vect = msgIds[msgId.first]; + vect.push_back(msgId.second); + + uint32_t token; + mThreadQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_REPLY_MESSAGE); +#endif +} + +void GxsForumThreadWidget::loadMsgData_ReplyMessage(const uint32_t &token) +{ + std::cerr << "GxsForumsDialog::loadMsgData_ReplyMessage()"; + std::cerr << std::endl; + + std::vector msgs; +#if 0 + if (rsGxsForums->getRelatedMessages(token, msgs)) +#else + if (rsGxsForums->getMsgData(token, msgs)) +#endif + { + if (msgs.size() != 1) + { + std::cerr << "GxsForumsDialog::loadMsgData_ReplyMessage() ERROR Wrong number of answers"; + std::cerr << std::endl; + return; + } + + replyMessageData(msgs[0]); + } + else + { + std::cerr << "GxsForumsDialog::loadMsgData_ReplyMessage() ERROR Missing Message Data..."; + std::cerr << std::endl; + } +} + +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ + +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ +/*********************** **** **** **** ***********************/ + +void GxsForumThreadWidget::loadRequest(const TokenQueue *queue, const TokenRequest &req) +{ + std::cerr << "GxsForumsDialog::loadRequest() UserType: " << req.mUserType; + std::cerr << std::endl; + + if (queue == mThreadQueue) + { + /* now switch on req */ + switch(req.mUserType) + { + case FORUMSV2DIALOG_CURRENTFORUM: + loadGroupSummary_CurrentForum(req.mToken); + break; + + case FORUMSV2DIALOG_INSERTTHREADS: + loadGroupThreadData_InsertThreads(req.mToken); + break; + + case FORUMSV2DIALOG_INSERTCHILD: + loadChildData_InsertThreads(req.mToken); + break; + + case FORUMV2DIALOG_INSERT_POST: + loadMsgData_InsertPost(req.mToken); + break; + + case FORUMV2DIALOG_REPLY_MESSAGE: + loadMsgData_ReplyMessage(req.mToken); + break; + + default: + std::cerr << "GxsForumsDialog::loadRequest() ERROR: INVALID TYPE"; + std::cerr << std::endl; + break; + } + } +} diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h new file mode 100644 index 000000000..a14b68f54 --- /dev/null +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h @@ -0,0 +1,191 @@ +#ifndef GXSFORUMTHREADWIDGET_H +#define GXSFORUMTHREADWIDGET_H + +#include + +#include "util/TokenQueue.h" + +class QTreeWidgetItem; +class GxsIdTreeWidgetItem; +class RSTreeWidgetItemCompareRole; +class RsGxsForumMsg; + +namespace Ui { +class GxsForumThreadWidget; +} + +/* These are all the parameters that are required for thread loading. + * They are kept static for the load duration. + */ + +class GxsForumsThreadLoadParameters +{ +public: + std::string ForumId; + std::string FocusMsgId; + + uint32_t SubscribeFlags; + int ViewType; + uint32_t FilterColumn; + + std::map MsgTokens; + QList Items; + QList ItemToExpand; + + bool FillComplete; + bool FlatView; + bool UseChildTS; + bool ExpandNewMessages; +}; + +class GxsForumThreadWidget : public QWidget, public TokenResponse +{ + Q_OBJECT + + Q_PROPERTY(QColor textColorRead READ textColorRead WRITE setTextColorRead) + Q_PROPERTY(QColor textColorUnread READ textColorUnread WRITE setTextColorUnread) + Q_PROPERTY(QColor textColorUnreadChildren READ textColorUnreadChildren WRITE setTextColorUnreadChildren) + Q_PROPERTY(QColor textColorNotSubscribed READ textColorNotSubscribed WRITE setTextColorNotSubscribed) + Q_PROPERTY(QColor textColorMissing READ textColorMissing WRITE setTextColorMissing) + +public: + explicit GxsForumThreadWidget(const std::string &forumId, QWidget *parent = NULL); + ~GxsForumThreadWidget(); + + QColor textColorRead() const { return mTextColorRead; } + QColor textColorUnread() const { return mTextColorUnread; } + QColor textColorUnreadChildren() const { return mTextColorUnreadChildren; } + QColor textColorNotSubscribed() const { return mTextColorNotSubscribed; } + QColor textColorMissing() const { return mTextColorMissing; } + + void setTextColorRead(QColor color) { mTextColorRead = color; } + void setTextColorUnread(QColor color) { mTextColorUnread = color; } + void setTextColorUnreadChildren(QColor color) { mTextColorUnreadChildren = color; } + void setTextColorNotSubscribed(QColor color) { mTextColorNotSubscribed = color; } + void setTextColorMissing(QColor color) { mTextColorMissing = color; } + + std::string forumId() { return mForumId; } + QString forumName(); + + // Callback for all Loads. + virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); + +signals: + void forumChanged(QWidget *widget); + +protected: + bool eventFilter(QObject *obj, QEvent *ev); + void changeEvent(QEvent *e); + +private slots: + /** Create the context popup menu and it's submenus */ + void threadListCustomPopupMenu(QPoint point); + + void changedThread(); + void clickedThread (QTreeWidgetItem *item, int column); + + void replytomessage(); + void replyMessageData(const RsGxsForumMsg &msg); + + //void print(); + //void printpreview(); + + //void removemessage(); + void markMsgAsRead(); + void markMsgAsReadChildren(); + void markMsgAsReadAll(); + void markMsgAsUnread(); + void markMsgAsUnreadAll(); + void markMsgAsUnreadChildren(); + + void copyMessageLink(); + + /* handle splitter */ + void togglethreadview(); + + void createthread(); + void createmessage(); + + void previousMessage(); + void nextMessage(); + void nextUnreadMessage(); + void downloadAllFiles(); + + void changedViewBox(); + + void filterColumnChanged(int column); + void filterItems(const QString &text); + + void fillThreadFinished(); +// void fillThreadProgress(int current, int count); + +private: + void insertForumThreads(const RsGroupMetaData &fi); + void insertPostData(const RsGxsForumMsg &msg); // Second Half. + + void insertThreads(); + void insertPost(); + +// void forumMsgReadStatusChanged(const QString &forumId, const QString &msgId, int status); + + void fillThreads(QList &threadList, bool expandNewMessages, QList &itemToExpand); + void fillChildren(QTreeWidgetItem *parentItem, QTreeWidgetItem *newParentItem, bool expandNewMessages, QList &itemToExpand); + + int getSelectedMsgCount(QList *pRows, QList *pRowsRead, QList *pRowsUnread); + void setMsgReadStatus(QList &rows, bool read); + void markMsgAsReadUnread(bool read, bool children, bool forum); + void calculateIconsAndFonts(QTreeWidgetItem *item = NULL); + void calculateIconsAndFonts(QTreeWidgetItem *item, bool &hasReadChilddren, bool &hasUnreadChilddren); + + void togglethreadview_internal(); + + bool filterItem(QTreeWidgetItem *item, const QString &text, int filterColumn); + + void processSettings(bool bLoad); + + std::string mForumId; + std::string mLastForumID; + std::string mThreadId; + int mSubscribeFlags; + bool mInProcessSettings; + bool mInMsgAsReadUnread; + int mLastViewType; + RSTreeWidgetItemCompareRole *mThreadCompareRole; + TokenQueue *mThreadQueue; + + void requestGroupSummary_CurrentForum(const std::string &forumId); + void loadGroupSummary_CurrentForum(const uint32_t &token); + + void loadCurrentForumThreads(const std::string &forumId); + void requestGroupThreadData_InsertThreads(const std::string &forumId); + void loadGroupThreadData_InsertThreads(const uint32_t &token); + void loadForumBaseThread(const RsGxsForumMsg &msg); + + void requestChildData_InsertThreads(uint32_t &token, const RsGxsGrpMsgIdPair &parentId); + void loadChildData_InsertThreads(const uint32_t &token); + void loadForumChildMsg(const RsGxsForumMsg &msg, QTreeWidgetItem *parent); + + void requestMsgData_InsertPost(const RsGxsGrpMsgIdPair &msgId); + void loadMsgData_InsertPost(const uint32_t &token); + void requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId); + void loadMsgData_ReplyMessage(const uint32_t &token); + + bool convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, bool useChildTS, uint32_t filterColumn, GxsIdTreeWidgetItem *item); +// bool convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, std::string authorName, bool useChildTS, uint32_t filterColumn, QTreeWidgetItem *item); + + + // New Datatypes to replace the FillThread. + bool mThreadLoading; + GxsForumsThreadLoadParameters mThreadLoad; + + /* Color definitions (for standard see qss.default) */ + QColor mTextColorRead; + QColor mTextColorUnread; + QColor mTextColorUnreadChildren; + QColor mTextColorNotSubscribed; + QColor mTextColorMissing; + + Ui::GxsForumThreadWidget *ui; +}; + +#endif // GXSFORUMTHREADWIDGET_H diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.ui b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.ui new file mode 100644 index 000000000..cc2d53656 --- /dev/null +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.ui @@ -0,0 +1,511 @@ + + + GxsForumThreadWidget + + + + 0 + 0 + 622 + 412 + + + + Form + + + + 0 + + + + + Qt::Vertical + + + + + + + + 0 + 32 + + + + QFrame::Box + + + QFrame::Sunken + + + + 2 + + + + + Qt::NoFocus + + + Start new Thread for Selected Forum + + + + :/images/mail_new.png:/images/mail_new.png + + + + 24 + 16 + + + + true + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 40 + 20 + + + + + + + + Search forums + + + + + + + + + + 3 + + + + + + 2 + 0 + + + + + 0 + 0 + + + + + 16777215 + 1677215 + + + + + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + + Last Post + + + + + Threaded View + + + + + Flat View + + + + + + + + + + + 9 + + + + Qt::CustomContextMenu + + + true + + + true + + + + Title + + + + + + + + + :/images/message-state-header.png:/images/message-state-header.png + + + + + Date + + + + + Author + + + + + Signed + + + + + + + + 3 + + + + + + 10 + 75 + true + + + + Loading + + + + + + + + 16777215 + 25 + + + + 1000 + + + 0 + + + + + + + + + 3 + + + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + + + + + + 24 + 24 + + + + Qt::NoFocus + + + Reply Message + + + + :/images/mail_reply.png:/images/mail_reply.png + + + true + + + + + + + false + + + + 0 + 0 + + + + + 24 + 24 + + + + + 24 + 24 + + + + Qt::NoFocus + + + Previous Thread + + + + + + + :/images/back.png:/images/back.png + + + true + + + + + + + false + + + + 0 + 0 + + + + + 24 + 24 + + + + + 24 + 24 + + + + Qt::NoFocus + + + Next Thread + + + + + + + :/images/forward.png:/images/forward.png + + + true + + + + + + + + 24 + 24 + + + + Qt::NoFocus + + + Download all files + + + + :/images/down.png:/images/down.png + + + true + + + + + + + Qt::Vertical + + + + + + + + 10 + + + + + + + + + + + + 10 + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Next unread + + + + + + + + 24 + 24 + + + + Qt::NoFocus + + + + + + + :/images/edit_remove24.png:/images/edit_remove24.png + + + true + + + true + + + + + + + Qt::Vertical + + + + + + + + + + + 0 + 10 + + + + + 9 + + + + + + + + + + LinkTextBrowser + QTextBrowser +
gui/common/LinkTextBrowser.h
+
+ + LineEditClear + QLineEdit +
gui/common/LineEditClear.h
+
+ + RSTreeWidget + QTreeWidget +
gui/common/RSTreeWidget.h
+
+
+ + + + +
From ef9ebf4cf34facd1ccbd11cc3da9c632d036fcc0 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Wed, 28 Nov 2012 12:31:14 +0000 Subject: [PATCH 186/222] Added subscribe flags to GroupTreeWidget. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5906 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/GxsForumsDialog.cpp | 32 ++++++------------- retroshare-gui/src/gui/GxsForumsDialog.h | 2 -- .../src/gui/common/GroupTreeWidget.cpp | 25 +++++++++++---- .../src/gui/common/GroupTreeWidget.h | 4 +++ 4 files changed, 32 insertions(+), 31 deletions(-) diff --git a/retroshare-gui/src/gui/GxsForumsDialog.cpp b/retroshare-gui/src/gui/GxsForumsDialog.cpp index dfe21b81d..6d3a4949f 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/GxsForumsDialog.cpp @@ -133,27 +133,17 @@ void GxsForumsDialog::processSettings(bool bLoad) Settings->endGroup(); } -int GxsForumsDialog::subscribeFlags(const std::string &forumId) -{ - QMap::const_iterator it = mSubscribeFlags.find(mForumId); - if (it != mSubscribeFlags.end()) { - return it.value(); - } - - return 0; -} - void GxsForumsDialog::forumListCustomPopupMenu(QPoint /*point*/) { - int flags = subscribeFlags(mForumId); + int subscribeFlags = ui.forumTreeWidget->subscribeFlags(QString::fromStdString(mForumId)); QMenu contextMnu(this); QAction *action = contextMnu.addAction(QIcon(IMAGE_SUBSCRIBE), tr("Subscribe to Forum"), this, SLOT(subscribeToForum())); - action->setDisabled (mForumId.empty() || IS_GROUP_SUBSCRIBED(flags)); + action->setDisabled (mForumId.empty() || IS_GROUP_SUBSCRIBED(subscribeFlags)); action = contextMnu.addAction(QIcon(IMAGE_UNSUBSCRIBE), tr("Unsubscribe to Forum"), this, SLOT(unsubscribeToForum())); - action->setEnabled (!mForumId.empty() && IS_GROUP_SUBSCRIBED(flags)); + action->setEnabled (!mForumId.empty() && IS_GROUP_SUBSCRIBED(subscribeFlags)); contextMnu.addSeparator(); @@ -163,16 +153,16 @@ void GxsForumsDialog::forumListCustomPopupMenu(QPoint /*point*/) action->setEnabled (!mForumId.empty ()); action = contextMnu.addAction(QIcon(":/images/settings16.png"), tr("Edit Forum Details"), this, SLOT(editForumDetails())); - action->setEnabled (!mForumId.empty () && IS_GROUP_ADMIN(flags)); + action->setEnabled (!mForumId.empty () && IS_GROUP_ADMIN(subscribeFlags)); QAction *shareKeyAct = new QAction(QIcon(":/images/gpgp_key_generate.png"), tr("Share Forum"), &contextMnu); connect( shareKeyAct, SIGNAL( triggered() ), this, SLOT( shareKey() ) ); - shareKeyAct->setEnabled(!mForumId.empty() && IS_GROUP_ADMIN(flags)); + shareKeyAct->setEnabled(!mForumId.empty() && IS_GROUP_ADMIN(subscribeFlags)); contextMnu.addAction( shareKeyAct); QAction *restoreKeysAct = new QAction(QIcon(":/images/settings16.png"), tr("Restore Publish Rights for Forum" ), &contextMnu); connect( restoreKeysAct , SIGNAL( triggered() ), this, SLOT( restoreForumKeys() ) ); - restoreKeysAct->setEnabled(!mForumId.empty() && !IS_GROUP_ADMIN(flags)); + restoreKeysAct->setEnabled(!mForumId.empty() && !IS_GROUP_ADMIN(subscribeFlags)); contextMnu.addAction( restoreKeysAct); action = contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyForumLink())); @@ -181,10 +171,10 @@ void GxsForumsDialog::forumListCustomPopupMenu(QPoint /*point*/) contextMnu.addSeparator(); action = contextMnu.addAction(QIcon(":/images/message-mail-read.png"), tr("Mark all as read"), this, SLOT(markMsgAsReadAll())); - action->setEnabled (!mForumId.empty () && IS_GROUP_SUBSCRIBED(flags)); + action->setEnabled (!mForumId.empty () && IS_GROUP_SUBSCRIBED(subscribeFlags)); action = contextMnu.addAction(QIcon(":/images/message-mail.png"), tr("Mark all as unread"), this, SLOT(markMsgAsUnreadAll())); - action->setEnabled (!mForumId.empty () && IS_GROUP_SUBSCRIBED(flags)); + action->setEnabled (!mForumId.empty () && IS_GROUP_SUBSCRIBED(subscribeFlags)); #ifdef DEBUG_FORUMS contextMnu.addSeparator(); @@ -256,6 +246,7 @@ void GxsForumsDialog::forumInfoToGroupItemInfo(const RsGroupMetaData &forumInfo, //groupItemInfo.description = QString::fromUtf8(forumInfo.forumDesc); groupItemInfo.popularity = forumInfo.mPop; groupItemInfo.lastpost = QDateTime::fromTime_t(forumInfo.mLastPost); + groupItemInfo.subscribeFlags = forumInfo.mSubscribeFlags; #if TOGXS if (forumInfo.mGroupFlags & RS_DISTRIB_AUTHEN_REQ) { @@ -285,8 +276,6 @@ void GxsForumsDialog::forumInfoToGroupItemInfo(const RsGroupMetaData &forumInfo, /***** INSERT FORUM LISTS *****/ void GxsForumsDialog::insertForumsData(const std::list &forumList) { - mSubscribeFlags.clear(); - std::list::const_iterator it; QList adminList; @@ -299,9 +288,6 @@ void GxsForumsDialog::insertForumsData(const std::list &forumLi /* sort it into Publish (Own), Subscribed, Popular and Other */ uint32_t flags = it->mSubscribeFlags; - /* store for later use with poll */ - mSubscribeFlags[it->mGroupId] = flags; - GroupItemInfo groupItemInfo; forumInfoToGroupItemInfo(*it, groupItemInfo); diff --git a/retroshare-gui/src/gui/GxsForumsDialog.h b/retroshare-gui/src/gui/GxsForumsDialog.h index 955c1c7ac..5ddd78c3b 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.h +++ b/retroshare-gui/src/gui/GxsForumsDialog.h @@ -86,7 +86,6 @@ private slots: private: void insertForums(); - int subscribeFlags(const std::string &forumId); void updateMessageSummaryList(std::string forumId); // void forumInfoToGroupItemInfo(const ForumInfo &forumInfo, GroupItemInfo &groupItemInfo); @@ -106,7 +105,6 @@ private: // void loadGroupSummary_CurrentForum(const uint32_t &token); std::string mForumId; - QMap mSubscribeFlags; TokenQueue *mForumQueue; QTreeWidgetItem *yourForums; diff --git a/retroshare-gui/src/gui/common/GroupTreeWidget.cpp b/retroshare-gui/src/gui/common/GroupTreeWidget.cpp index da67704d6..f63282f9c 100644 --- a/retroshare-gui/src/gui/common/GroupTreeWidget.cpp +++ b/retroshare-gui/src/gui/common/GroupTreeWidget.cpp @@ -37,12 +37,13 @@ #define COLUMN_COUNT 2 #define COLUMN_DATA COLUMN_NAME -#define ROLE_ID Qt::UserRole -#define ROLE_NAME Qt::UserRole + 1 -#define ROLE_DESCRIPTION Qt::UserRole + 2 -#define ROLE_POPULARITY Qt::UserRole + 3 -#define ROLE_LASTPOST Qt::UserRole + 4 -#define ROLE_SEARCH_SCORE Qt::UserRole + 5 +#define ROLE_ID Qt::UserRole +#define ROLE_NAME Qt::UserRole + 1 +#define ROLE_DESCRIPTION Qt::UserRole + 2 +#define ROLE_POPULARITY Qt::UserRole + 3 +#define ROLE_LASTPOST Qt::UserRole + 4 +#define ROLE_SEARCH_SCORE Qt::UserRole + 5 +#define ROLE_SUBSCRIBE_FLAGS Qt::UserRole + 6 #define COMBO_NAME_INDEX 0 #define COMBO_DESC_INDEX 1 @@ -299,6 +300,8 @@ void GroupTreeWidget::fillGroupItems(QTreeWidgetItem *categoryItem, const QList< item->setToolTip(COLUMN_NAME, tooltip); item->setToolTip(COLUMN_POPULARITY, tooltip); + item->setData(COLUMN_DATA, ROLE_SUBSCRIBE_FLAGS, itemInfo.subscribeFlags); + /* Set color */ QBrush brush; if (itemInfo.privatekey) { @@ -390,6 +393,16 @@ QTreeWidgetItem *GroupTreeWidget::activateId(const QString &id, bool focus) return item; } +int GroupTreeWidget::subscribeFlags(const QString &id) +{ + QTreeWidgetItem *item = getItemFromId(id); + if (item == NULL) { + return 0; + } + + return item->data(COLUMN_DATA, ROLE_SUBSCRIBE_FLAGS).toInt(); +} + void GroupTreeWidget::calculateScore(QTreeWidgetItem *item, const QString &filterText) { if (item) { diff --git a/retroshare-gui/src/gui/common/GroupTreeWidget.h b/retroshare-gui/src/gui/common/GroupTreeWidget.h index 3cd72e025..0c872a93a 100644 --- a/retroshare-gui/src/gui/common/GroupTreeWidget.h +++ b/retroshare-gui/src/gui/common/GroupTreeWidget.h @@ -42,6 +42,7 @@ public: { popularity = 0; privatekey = false; + subscribeFlags = 0; } public: @@ -52,6 +53,7 @@ public: QDateTime lastpost; QIcon icon; bool privatekey; + int subscribeFlags; }; class GroupTreeWidget : public QWidget @@ -79,6 +81,8 @@ public: QTreeWidgetItem *getItemFromId(const QString &id); QTreeWidgetItem *activateId(const QString &id, bool focus); + int subscribeFlags(const QString &id); + signals: void treeCustomContextMenuRequested(const QPoint &pos); void treeCurrentItemChanged(const QString &id); From 799cf155558c49c77949a4f1de98a4beec3bf0af Mon Sep 17 00:00:00 2001 From: thunder2 Date: Wed, 28 Nov 2012 22:27:19 +0000 Subject: [PATCH 187/222] Fixed crash in GxsGroupDialog in the second constructor. Changed mode on GxsGroupDialog to enum. Added different header text for every mode in PostedGroupDialog, WikiGroupDialog and GxsForumGroupDialog. Removed not needed files of GxsForums. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5908 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/RetroShare.pro | 6 - retroshare-gui/src/gui/GxsForumsDialog.cpp | 22 +-- .../src/gui/Posted/PostedGroupDialog.cpp | 14 +- .../src/gui/Posted/PostedGroupDialog.h | 2 +- .../src/gui/Posted/PostedListDialog.cpp | 2 +- .../src/gui/gxs/GxsForumGroupDialog.cpp | 16 +- .../src/gui/gxs/GxsForumGroupDialog.h | 2 +- retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp | 45 +++-- retroshare-gui/src/gui/gxs/GxsGroupDialog.h | 110 +++++------ .../src/gui/gxs/WikiGroupDialog.cpp | 16 +- .../src/gui/gxsforums/EditGxsForumDetails.cpp | 90 --------- .../src/gui/gxsforums/EditGxsForumDetails.h | 53 ------ .../src/gui/gxsforums/EditGxsForumDetails.ui | 87 --------- .../src/gui/gxsforums/GxsForumDetails.cpp | 120 ------------ .../src/gui/gxsforums/GxsForumDetails.h | 58 ------ .../src/gui/gxsforums/GxsForumDetails.ui | 175 ------------------ 16 files changed, 127 insertions(+), 691 deletions(-) delete mode 100644 retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.cpp delete mode 100644 retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.h delete mode 100644 retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.ui delete mode 100644 retroshare-gui/src/gui/gxsforums/GxsForumDetails.cpp delete mode 100644 retroshare-gui/src/gui/gxsforums/GxsForumDetails.h delete mode 100644 retroshare-gui/src/gui/gxsforums/GxsForumDetails.ui diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index 87ab75547..f91209128 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -967,20 +967,14 @@ identities { gxsforums { HEADERS += gui/GxsForumsDialog.h \ - gui/gxsforums/GxsForumDetails.h \ - gui/gxsforums/EditGxsForumDetails.h \ gui/gxsforums/CreateGxsForumMsg.h \ gui/gxsforums/GxsForumThreadWidget.h FORMS += gui/GxsForumsDialog.ui \ - gui/gxsforums/GxsForumDetails.ui \ - gui/gxsforums/EditGxsForumDetails.ui \ gui/gxsforums/CreateGxsForumMsg.ui \ gui/gxsforums/GxsForumThreadWidget.ui SOURCES += gui/GxsForumsDialog.cpp \ - gui/gxsforums/GxsForumDetails.cpp \ - gui/gxsforums/EditGxsForumDetails.cpp \ gui/gxsforums/CreateGxsForumMsg.cpp \ gui/gxsforums/GxsForumThreadWidget.cpp } diff --git a/retroshare-gui/src/gui/GxsForumsDialog.cpp b/retroshare-gui/src/gui/GxsForumsDialog.cpp index 6d3a4949f..949887a1c 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/GxsForumsDialog.cpp @@ -235,8 +235,6 @@ void GxsForumsDialog::forceUpdateDisplay() /* update Forums List */ insertForums(); - /* update threads as well */ -//#TODO insertThreads(); } void GxsForumsDialog::forumInfoToGroupItemInfo(const RsGroupMetaData &forumInfo, GroupItemInfo &groupItemInfo) @@ -258,19 +256,6 @@ void GxsForumsDialog::forumInfoToGroupItemInfo(const RsGroupMetaData &forumInfo, { groupItemInfo.icon = QIcon(IMAGE_FORUM); } - -// groupItemInfo.id = QString::fromStdString(forumInfo.forumId); -// groupItemInfo.name = QString::fromStdWString(forumInfo.forumName); -// groupItemInfo.description = QString::fromStdWString(forumInfo.forumDesc); -// groupItemInfo.popularity = forumInfo.pop; -// groupItemInfo.lastpost = QDateTime::fromTime_t(forumInfo.lastPost); -// -// if (forumInfo.forumFlags & RS_DISTRIB_AUTHEN_REQ) { -// groupItemInfo.name += " (" + tr("AUTHD") + ")"; -// groupItemInfo.icon = QIcon(IMAGE_FORUMAUTHD); -// } else { -// groupItemInfo.icon = QIcon(IMAGE_FORUM); -// } } /***** INSERT FORUM LISTS *****/ @@ -470,7 +455,7 @@ void GxsForumsDialog::showForumDetails() RsGxsForumGroup grp; grp.mMeta.mGroupId = mForumId; - GxsForumGroupDialog cf(grp, this); + GxsForumGroupDialog cf(grp, GxsGroupDialog::MODE_SHOW, this); cf.exec (); } @@ -483,10 +468,7 @@ void GxsForumsDialog::editForumDetails() RsGxsForumGroup grp; grp.mMeta.mGroupId = mForumId; - GxsForumGroupDialog cf(grp, this); - - //GxsForumGroupDialog cf (mForumQueue, this, mCurrForumId, GXS_GROUP_DIALOG_EDIT_MODE); - + GxsForumGroupDialog cf(grp, GxsGroupDialog::MODE_EDIT, this); cf.exec (); } diff --git a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp index 080447989..bf788971a 100644 --- a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp @@ -46,14 +46,24 @@ PostedGroupDialog::PostedGroupDialog(TokenQueue* tokenQueue, RsPosted* posted, { } -PostedGroupDialog::PostedGroupDialog(const RsPostedGroup& grp, uint32_t mode, QWidget *parent) +PostedGroupDialog::PostedGroupDialog(const RsPostedGroup& grp, Mode mode, QWidget *parent) :GxsGroupDialog(grp.mMeta, mode, parent), mGrp(grp) { } QString PostedGroupDialog::serviceHeader() { - return tr("Create New Posted Topic"); + switch (mode()) + { + case MODE_CREATE: + return tr("Create New Posted Topic"); + case MODE_SHOW: + return tr("Posted Topic"); + case MODE_EDIT: + return tr("Edit Posted Topic"); + } + + return ""; } diff --git a/retroshare-gui/src/gui/Posted/PostedGroupDialog.h b/retroshare-gui/src/gui/Posted/PostedGroupDialog.h index 3ed4faed3..495d1a330 100644 --- a/retroshare-gui/src/gui/Posted/PostedGroupDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedGroupDialog.h @@ -40,7 +40,7 @@ public: /*! * This constructs a show dialog which displays an already existing group */ - PostedGroupDialog(const RsPostedGroup& grp, uint32_t mode, QWidget *parent = NULL); + PostedGroupDialog(const RsPostedGroup& grp, Mode mode, QWidget *parent = NULL); protected: virtual QString serviceHeader(); diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp index 059c356e6..586fb54d3 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp @@ -152,7 +152,7 @@ void PostedListDialog::showGroupDetails() return; } - PostedGroupDialog cf(mGroups[mCurrTopicId], GXS_GROUP_DIALOG_SHOW_MODE, this); + PostedGroupDialog cf(mGroups[mCurrTopicId], GxsGroupDialog::MODE_SHOW, this); cf.exec (); } diff --git a/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.cpp index a9dceae31..d440c6c11 100644 --- a/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.cpp @@ -60,15 +60,25 @@ GxsForumGroupDialog::GxsForumGroupDialog(TokenQueue *tokenQueue, QWidget *parent } -GxsForumGroupDialog::GxsForumGroupDialog(const RsGxsForumGroup &group, QWidget *parent) - :GxsGroupDialog(group.mMeta, GXS_GROUP_DIALOG_SHOW_MODE, parent) +GxsForumGroupDialog::GxsForumGroupDialog(const RsGxsForumGroup &group, Mode mode, QWidget *parent) + :GxsGroupDialog(group.mMeta, mode, parent) { return; } QString GxsForumGroupDialog::serviceHeader() { - return tr("Create New Forum"); + switch (mode()) + { + case MODE_CREATE: + return tr("Create New Forum"); + case MODE_SHOW: + return tr("Forum"); + case MODE_EDIT: + return tr("Edit Forum"); + } + + return ""; } QPixmap GxsForumGroupDialog::serviceImage() diff --git a/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.h b/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.h index 2dc8d1a27..2277b38bd 100644 --- a/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsForumGroupDialog.h @@ -32,7 +32,7 @@ class GxsForumGroupDialog : public GxsGroupDialog public: GxsForumGroupDialog(TokenQueue *tokenQueue, QWidget *parent); - GxsForumGroupDialog(const RsGxsForumGroup &group, QWidget *parent); + GxsForumGroupDialog(const RsGxsForumGroup &group, Mode mode, QWidget *parent); protected: virtual QString serviceHeader(); diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index 0cf782840..3c392201c 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -51,11 +51,25 @@ /** Constructor */ GxsGroupDialog::GxsGroupDialog(TokenQueue *tokenQueue, uint32_t enableFlags, uint16_t defaultFlags, QWidget *parent) -: QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint), mTokenQueue(tokenQueue), mMode(GXS_GROUP_DIALOG_CREATE_MODE), mEnabledFlags(enableFlags), mDefaultsFlags(defaultFlags), mReadonlyFlags(0) + : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint), mTokenQueue(tokenQueue), mMode(MODE_CREATE), mEnabledFlags(enableFlags), mReadonlyFlags(0), mDefaultsFlags(defaultFlags) { /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); + init(); +} + +GxsGroupDialog::GxsGroupDialog(const RsGroupMetaData &grpMeta, Mode mode, QWidget *parent) + : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint), mTokenQueue(NULL), mGrpMeta(grpMeta), mMode(mode), mEnabledFlags(0), mReadonlyFlags(0), mDefaultsFlags(0) +{ + /* Invoke the Qt Designer generated object setup routine */ + ui.setupUi(this); + + init(); +} + +void GxsGroupDialog::init() +{ // connect up the buttons. connect( ui.buttonBox, SIGNAL(accepted()), this, SLOT(submitGroup())); connect( ui.buttonBox, SIGNAL(rejected()), this, SLOT(cancelDialog())); @@ -77,13 +91,9 @@ GxsGroupDialog::GxsGroupDialog(TokenQueue *tokenQueue, uint32_t enableFlags, uin /* Setup Reasonable Defaults */ - ui.idChooser->loadIds(0,""); -} + ui.idChooser->loadIds(0,""); -GxsGroupDialog::GxsGroupDialog(const RsGroupMetaData &grpMeta, uint32_t mode, QWidget *parent) - : QDialog(parent), mMode(mode), mGrpMeta(grpMeta) { - - ui.idChooser->loadIds(0,""); + initMode(); } void GxsGroupDialog::showEvent(QShowEvent*) @@ -94,11 +104,11 @@ void GxsGroupDialog::showEvent(QShowEvent*) ui.headerFrame->setHeaderImage(serviceImage()); } -void GxsGroupDialog::setMode(uint32_t mode) +void GxsGroupDialog::initMode() { - switch(mMode) + switch (mode()) { - case GXS_GROUP_DIALOG_CREATE_MODE: + case MODE_CREATE: { ui.buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); ui.buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Create Group")); @@ -106,14 +116,13 @@ void GxsGroupDialog::setMode(uint32_t mode) } break; - default: - case GXS_GROUP_DIALOG_SHOW_MODE: + case MODE_SHOW: { ui.buttonBox->setStandardButtons(QDialogButtonBox::Close); } break; //TODO -// case GXS_GROUP_DIALOG_EDIT_MODE: +// case MODE_EDIT: // { // ui.createButton->setText(tr("Submit Changes")); // } @@ -129,7 +138,6 @@ void GxsGroupDialog::clearForm() ui.groupName->setFocus(); } - void GxsGroupDialog::setupDefaults() { /* Enable / Show Parts based on Flags */ @@ -267,24 +275,23 @@ void GxsGroupDialog::submitGroup() std::cerr << std::endl; /* switch depending on mode */ - switch(mMode) + switch (mode()) { - case GXS_GROUP_DIALOG_CREATE_MODE: + case MODE_CREATE: { /* just close if down */ createGroup(); } break; - default: - case GXS_GROUP_DIALOG_SHOW_MODE: + case MODE_SHOW: { /* just close if down */ cancelDialog(); } break; - case GXS_GROUP_DIALOG_EDIT_MODE: + case MODE_EDIT: { /* TEMP: just close if down */ cancelDialog(); diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h index 4c89e2ac0..4af920686 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h @@ -92,10 +92,6 @@ public: #define GXS_GROUP_DEFAULTS_COMMENTS_YES 0x00001000 #define GXS_GROUP_DEFAULTS_COMMENTS_NO 0x00002000 -#define GXS_GROUP_DIALOG_CREATE_MODE 1 -#define GXS_GROUP_DIALOG_SHOW_MODE 2 -#define GXS_GROUP_DIALOG_EDIT_MODE 3 - /*! * The aim of this dialog is to be convenient to encapsulate group * creation code for several GXS services such forums, channels @@ -111,67 +107,77 @@ public: */ class GxsGroupDialog : public QDialog { - Q_OBJECT + Q_OBJECT + +public: + enum Mode { + MODE_CREATE, + MODE_SHOW, + MODE_EDIT + }; public: - /*! - * Constructs a GxsGroupDialog for creating group - * @param tokenQueue This should be the TokenQueue of the (parent) service - * in order to receive acknowledgement of group creation, if set to NULL with create mode \n - * creation will not happen - * @param enableFlags This determines what options are enabled such as Icon, Description, publish type and key sharing - * @param defaultFlags This deter - * @param parent The parent dialog - * @param mode - */ - GxsGroupDialog(TokenQueue* tokenQueue, uint32_t enableFlags, uint16_t defaultFlags, QWidget *parent = NULL); + /*! + * Constructs a GxsGroupDialog for creating group + * @param tokenQueue This should be the TokenQueue of the (parent) service + * in order to receive acknowledgement of group creation, if set to NULL with create mode \n + * creation will not happen + * @param enableFlags This determines what options are enabled such as Icon, Description, publish type and key sharing + * @param defaultFlags This deter + * @param parent The parent dialog + * @param mode + */ + GxsGroupDialog(TokenQueue* tokenQueue, uint32_t enableFlags, uint16_t defaultFlags, QWidget *parent = NULL); - /*! - * Contructs a GxsGroupDialog for display a group or editing - * @param grpMeta This is used to fill out the dialog - * @param mode This determines whether the dialog starts in show or edit mode (Edit not supported yet) - * @param parent - */ - GxsGroupDialog(const RsGroupMetaData& grpMeta, uint32_t mode = GXS_GROUP_DIALOG_SHOW_MODE, QWidget *parent = NULL); - void wikitype(); + /*! + * Contructs a GxsGroupDialog for display a group or editing + * @param grpMeta This is used to fill out the dialog + * @param mode This determines whether the dialog starts in show or edit mode (Edit not supported yet) + * @param parent + */ + GxsGroupDialog(const RsGroupMetaData& grpMeta, Mode mode, QWidget *parent = NULL); + void wikitype(); + + uint32_t mode() { return mMode; } private: - void newGroup(); - void setMode(uint32_t mode); + void newGroup(); + void init(); + void initMode(); - // Functions that can be overloaded for specific stuff. + // Functions that can be overloaded for specific stuff. protected slots: - void submitGroup(); - void addGroupLogo(); + void submitGroup(); + void addGroupLogo(); protected: - virtual void showEvent(QShowEvent*); + virtual void showEvent(QShowEvent*); - virtual QString serviceHeader() = 0; - virtual QPixmap serviceImage() = 0; + virtual QString serviceHeader() = 0; + virtual QPixmap serviceImage() = 0; - /*! - * Main purpose is to help tansfer meta data to service - * - * @param token This should be set to the token retrieved - * @param meta The deriving GXS service should set their grp meta to this value - */ - virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) = 0; + /*! + * Main purpose is to help tansfer meta data to service + * + * @param token This should be set to the token retrieved + * @param meta The deriving GXS service should set their grp meta to this value + */ + virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) = 0; - /*! - * This returns a group logo from the ui \n - * Should be calleld by deriving service - * @return The logo for the service - */ - QPixmap getLogo(); + /*! + * This returns a group logo from the ui \n + * Should be calleld by deriving service + * @return The logo for the service + */ + QPixmap getLogo(); - /*! - * This returns a group description string from the ui - * @return group description string - */ - virtual QString getDescription(); + /*! + * This returns a group description string from the ui + * @return group description string + */ + virtual QString getDescription(); private slots: @@ -196,8 +202,8 @@ private: std::list mShareList; QPixmap picture; - TokenQueue *mTokenQueue; - RsGroupMetaData mGrpMeta; + TokenQueue *mTokenQueue; + RsGroupMetaData mGrpMeta; uint32_t mMode; uint32_t mEnabledFlags; diff --git a/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp b/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp index d5f68e084..95a1b4399 100644 --- a/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/WikiGroupDialog.cpp @@ -92,7 +92,7 @@ WikiGroupDialog::WikiGroupDialog(TokenQueue *tokenQueue, QWidget *parent) } WikiGroupDialog::WikiGroupDialog(const RsWikiCollection &collection, QWidget *parent) - :GxsGroupDialog(collection.mMeta, GXS_GROUP_DIALOG_SHOW_MODE, parent) + :GxsGroupDialog(collection.mMeta, MODE_SHOW, parent) { #if 0 @@ -119,12 +119,22 @@ WikiGroupDialog::WikiGroupDialog(const RsWikiCollection &collection, QWidget *pa QString WikiGroupDialog::serviceHeader() { - return tr("Create New Wiki Group"); + switch (mode()) + { + case MODE_CREATE: + return tr("Create New Wiki Group"); + case MODE_SHOW: + return tr("Wiki Group"); + case MODE_EDIT: + return tr("Edit Wiki Group"); + } + + return ""; } QPixmap WikiGroupDialog::serviceImage() { - return QPixmap(":/images/resource-group_64.png"); + return QPixmap(":/images/resource-group_64.png"); } bool WikiGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) diff --git a/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.cpp b/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.cpp deleted file mode 100644 index 840a7f47f..000000000 --- a/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************** - * RetroShare is distributed under the following license: - * - * Copyright (C) 2010 RetroShare Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - ****************************************************************/ - -#include "EditGxsForumDetails.h" - -#include - -#include "util/misc.h" - -#include -#include -#include - - -/** Default constructor */ -EditGxsForumDetails::EditGxsForumDetails(std::string forumId, QWidget *parent) - : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint), m_forumId(forumId) -{ - /* Invoke Qt Designer generated QObject setup routine */ - ui.setupUi(this); - - connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(applyDialog())); - connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(close())); - - loadForum(); -} - -void EditGxsForumDetails::loadForum() -{ - if (!rsGxsForums) { - return; - } - -#warning "EditGxsForumDetails incomplete" -#if 0 - ForumInfo info; - rsGxsForums->getForumInfo(m_forumId, info); - - // set name - ui.nameline->setText(QString::fromStdWString(info.forumName)); - - // set description - ui.DescriptiontextEdit->setText(QString::fromStdWString(info.forumDesc)); -#endif - -} - -void EditGxsForumDetails::applyDialog() -{ - if (!rsGxsForums) { - return; - } - - // if text boxes have not been edited leave alone - if (!ui.nameline->isModified() && !ui.DescriptiontextEdit->document()->isModified()) { - return; - } - -#warning "EditGxsForumDetails incomplete" -#if 0 - - ForumInfo info; - - info.forumName = misc::removeNewLine(ui.nameline->text()).toStdWString(); - info.forumDesc = ui.DescriptiontextEdit->document()->toPlainText().toStdWString(); - - rsGxsForums->setForumInfo(m_forumId, info); -#endif - - /* close the Dialog after the Changes applied */ - close(); -} diff --git a/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.h b/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.h deleted file mode 100644 index b21fadafc..000000000 --- a/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.h +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************** - * RetroShare is distributed under the following license: - * - * Copyright (C) 2010 RetroShare Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - ****************************************************************/ - -#ifndef _EDITGXSFORUMDETAILS_H -#define _EDITGXSFORUMDETAILS_H - -#include - -#include "ui_EditGxsForumDetails.h" - -class EditGxsForumDetails : public QDialog -{ - Q_OBJECT - -public: - /** Default constructor */ - EditGxsForumDetails(std::string forumId = "", QWidget *parent = 0); - -signals: - void configChanged(); - -private slots: - void applyDialog(); - -private: - void loadForum(); - - std::string m_forumId; - - /** Qt Designer generated object */ - Ui::EditGxsForumDetails ui; -}; - -#endif - diff --git a/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.ui b/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.ui deleted file mode 100644 index 483e94a2f..000000000 --- a/retroshare-gui/src/gui/gxsforums/EditGxsForumDetails.ui +++ /dev/null @@ -1,87 +0,0 @@ - - - EditGxsForumDetails - - - - 0 - 0 - 436 - 355 - - - - Forum Details - - - - :/images/rstray3.png:/images/rstray3.png - - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - 0 - - - - - :/images/info16.png:/images/info16.png - - - Edit Forum Details - - - - - - Forum Info - - - - - - Forum Name - - - - - - - - - - Forum Description - - - - - - - - - - - - - - - - - - - - - - diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumDetails.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumDetails.cpp deleted file mode 100644 index ed45f8dfd..000000000 --- a/retroshare-gui/src/gui/gxsforums/GxsForumDetails.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************** - * RetroShare is distributed under the following license: - * - * Copyright (C) 2009 RetroShare Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - ****************************************************************/ -#include "GxsForumDetails.h" -//#AFTER MERGE #include "util/DateTime.h" - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - - -/* Define the format used for displaying the date and time */ -#define DATETIME_FMT "MMM dd hh:mm:ss" - -/** Default constructor */ -GxsForumDetails::GxsForumDetails(QWidget *parent) - : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint) -{ - /* Invoke Qt Designer generated QObject setup routine */ - ui.setupUi(this); - - connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(close())); - - ui.nameline ->setReadOnly(true); - ui.popline ->setReadOnly(true); - ui.postline ->setReadOnly(true); - ui.IDline ->setReadOnly(true); - ui.DescriptiontextEdit ->setReadOnly(true); - - ui.radioButton_authd->setEnabled(false); - ui.radioButton_anonymous->setEnabled(false); -} - - -/** - Overloads the default show() slot so we can set opacity*/ - -void -GxsForumDetails::show() -{ - //loadSettings(); - if(!this->isVisible()) { - QDialog::show(); - - } -} - -void GxsForumDetails::showDetails(std::string mCurrForumId) -{ - fId = mCurrForumId; - loadDialog(); -} - -void GxsForumDetails::loadDialog() -{ - if (!rsGxsForums) - { - return; - } - -#warning "GxsForumDetails Incomplete" -#if 0 - ForumInfo fi; - rsGxsForums->getForumInfo(fId, fi); - - // Set Forum Name - ui.nameline->setText(QString::fromStdWString(fi.forumName)); - - // Set Popularity - ui.popline->setText(QString::number(fi.pop)); - - // Set Last Post Date - if (fi.lastPost) { - ui.postline->setText(DateTime::formatLongDateTime(fi.lastPost)); - } - - // Set Forum ID - ui.IDline->setText(QString::fromStdString(fi.forumId)); - - // Set Forum Description - ui.DescriptiontextEdit->setText(QString::fromStdWString(fi.forumDesc)); - - if (fi.forumFlags & RS_DISTRIB_AUTHEN_REQ) - { - ui.radioButton_authd->setChecked(true); - ui.radioButton_anonymous->setChecked(false); - } - if (fi.forumFlags & RS_DISTRIB_AUTHEN_ANON) - { - ui.radioButton_authd->setChecked(false); - ui.radioButton_anonymous->setChecked(true); - } -#endif - -} diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumDetails.h b/retroshare-gui/src/gui/gxsforums/GxsForumDetails.h deleted file mode 100644 index d7c014262..000000000 --- a/retroshare-gui/src/gui/gxsforums/GxsForumDetails.h +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************** - * RetroShare is distributed under the following license: - * - * Copyright (C) 2009 RetroShare Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - ****************************************************************/ - -#ifndef _GXSFORUMDETAILS_H -#define _GXSFORUMDETAILS_H - -#include - -#include "ui_GxsForumDetails.h" - -class GxsForumDetails : public QDialog -{ - Q_OBJECT - - public: - - /** Default constructor */ - GxsForumDetails(QWidget *parent = 0); - - void showDetails(std::string mCurrForumId); - -signals: - void configChanged() ; - -public slots: - /** Overloaded QWidget.show */ - void show(); - -private: - - void loadDialog(); - - std::string fId; - /** Qt Designer generated object */ - Ui::GxsForumDetails ui; - -}; - -#endif - diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumDetails.ui b/retroshare-gui/src/gui/gxsforums/GxsForumDetails.ui deleted file mode 100644 index b6dfb4c1e..000000000 --- a/retroshare-gui/src/gui/gxsforums/GxsForumDetails.ui +++ /dev/null @@ -1,175 +0,0 @@ - - - GxsForumDetails - - - - 0 - 0 - 436 - 355 - - - - Forum Details - - - - :/images/rstray3.png:/images/rstray3.png - - - - - - 0 - - - - - :/images/info16.png:/images/info16.png - - - Forum Details - - - - - - Forum Info - - - - - - Forum Name - - - - - - - - - - Popularity - - - - - - - true - - - - - - - Last Post - - - - - - - true - - - - - - - Forum ID - - - - - - - - - - Forum Description - - - - - - - - - - - - - - - - - :/images/encrypted22.png:/images/encrypted22.png - - - Security - - - - - - Allowed Messages - - - - - - Authenticated Messages - - - - - - - Anonymous Messages - - - true - - - - - - - - - - Qt::Vertical - - - - 358 - 172 - - - - - - - - - - - - - - QDialogButtonBox::Close - - - - - - - - - - - - From baa949eaac1b5c0506667e9da52d1b0938d90ab9 Mon Sep 17 00:00:00 2001 From: defnax Date: Thu, 29 Nov 2012 12:02:09 +0000 Subject: [PATCH 188/222] Added images for My/Subscribed/Shared Album Set WikiDialog Buttons to flat style. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5909 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/gui/PhotoShare/PhotoShare.ui | 45 +++++++++++- .../src/gui/PhotoShare/Photo_images.qrc | 5 +- .../gui/PhotoShare/images/folder_images.png | Bin 0 -> 3863 bytes .../PhotoShare/images/friends_album_48.png | Bin 0 -> 4755 bytes .../src/gui/PhotoShare/images/my_album_48.png | Bin 0 -> 4590 bytes .../PhotoShare/images/subscribed_album_48.png | Bin 0 -> 4334 bytes retroshare-gui/src/gui/WikiPoos/WikiDialog.ui | 65 ++++++++++++++---- 7 files changed, 98 insertions(+), 17 deletions(-) create mode 100644 retroshare-gui/src/gui/PhotoShare/images/folder_images.png create mode 100644 retroshare-gui/src/gui/PhotoShare/images/friends_album_48.png create mode 100644 retroshare-gui/src/gui/PhotoShare/images/my_album_48.png create mode 100644 retroshare-gui/src/gui/PhotoShare/images/subscribed_album_48.png diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui index f27d948dd..78e3ed538 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui @@ -146,7 +146,17 @@ - Your Albums + My Albums + + + + :/images/my_album_48.png:/images/my_album_48.png + + + + 48 + 48 + true @@ -154,6 +164,9 @@ true + + true + @@ -161,12 +174,25 @@ Subscribed Albums + + + :/images/subscribed_album_48.png:/images/subscribed_album_48.png + + + + 48 + 48 + + true true + + true + @@ -174,6 +200,16 @@ Shared Albums + + + :/images/friends_album_48.png:/images/friends_album_48.png + + + + 48 + 48 + + true @@ -183,6 +219,9 @@ true + + true + @@ -206,7 +245,7 @@ 0 0 804 - 225 + 208 @@ -242,7 +281,7 @@ 0 0 804 - 224 + 208 diff --git a/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc b/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc index 519bf66ee..7919a4500 100644 --- a/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc +++ b/retroshare-gui/src/gui/PhotoShare/Photo_images.qrc @@ -7,6 +7,9 @@ images/album_subscribe.png images/album_unsubscribe.png images/album_create_64.png - images/album_default_128.png + images/album_default_128.png + images/my_album_48.png + images/subscribed_album_48.png + images/friends_album_48.png diff --git a/retroshare-gui/src/gui/PhotoShare/images/folder_images.png b/retroshare-gui/src/gui/PhotoShare/images/folder_images.png new file mode 100644 index 0000000000000000000000000000000000000000..a737b3d5088ed51a2c16be895d2508f70c192688 GIT binary patch literal 3863 zcmV+y59siTP)o3b;p1A-naBN)6>(lNV7_oX3z$*aRpnJO|h0NAQ&g$RAN3+zz4oihNMUcMSxT# z!6_#Yvt(flt~jKioJvTM*f>~5NHP{)kZfr*T1L`XqtUGDp5FW2d-CD+$RpXZEla85 zRK4oA+~xf5Ip=@Qy)#Ng_)U{Nd-kYQDwSGTSXhfmx)?@9*VwQJW)-Wg-aWHKx+E|SS)2!eoxg@p_E^Yil;?&s#_R<;Q8PD@p8)Nzti9}y-Z|`s_m0Fuhr3MEE26_^SM6d7roxbmD&+|}9UFa{s zOtDF^)FcrEtj=q+R(Qs=t(@noEufU@&*gGk>h=0iCX*RXCX<6&>%NhZk%1rxdV?Uy z_`dIJtKx7q=ZbZT)re%mrze-hXhppl;hX@dmF=&}0=stY+PHrG`bT?udis3d zzmlO|B9Rr&6>BWjEUAP~Z$6FE3Mb$!I0p#0OG5V5m*g^%NF*5>8+%u8Z|_wrKU1u8 zcr&vtclY zMNw@uK^&ejIDx?T5CMCwEl{gfc{vIek&E81d|tkP@w>41iG38Nrm?n;0>Z#22tthS zQExVgT1q?O%U&|&RaxLlL_|1v;8{GWGtk>f`|43Z@s8VW<%wfUhzdEo&;*1if`RS; zv2ny&Vi4+OEO1o-thJZ@cJRQn7+YavO+P{B8UWt3^#%^j!grpU=Y{`$fnT4PV`93* z@7>(PCqA^EQq_@88iG)v6+{v%Z$*flU|KXRB!lCC5VCzLTtslT-UsU$_8Mt@% zG%w7ZWa7+uPR>*be4mcC1gXG~OSjRtImfCz1PYX=FbbM3W*!?kq{Tv3KszD2RscTz z=}&#;zWe^>uK+e}c@xji!k<5KhW$qmGhc49RIa16BAX0oOZl{=liaeg9i?Iov=}fD zMG!RvtrShGu%d8Efq}XcA_tKZ#DP^hrlV^CV6f999-oE}{>c-p$_IF&>B=VPNPA?{ z9==JVwcwmaA!wseD3sDDrBJPB=W7fWr4^!EE(1h>vI^@Uifl`7iP`8{0EimZO5nqF zy=gWMr13n>+>&GJe1jm+WCBe(>5~oxPYFsXj8cdKlmcbYIzr>qq=7+j4UG#F;uJOl zr&No1EFuQuIh;hVKNGJM>mW3cNcxz-W3C{)Ww_4WxAk%OY{c`YN{pQ;aCQM2l0p<{ z;}M1)ZOMT41bB%gzOtkO4O$U-4y`m%1WpuITN=(`twt$_bqaA8JJD4HvBPLcdOj)7 zXRKW2!`s?Wo@R5ORhvZU+DH3_s3|lZ zw6(Xw0`9r<*9_N+wEWb5q_@5Kdo(?c34mfAPIiEnsEALSF%EcwI5|jg!CQ?F^ zRuU79wN11Lk*6>cZ*sJPrJAF8%`9NS2ZAtxZwmBuCwcO5M@NT`@xV$0&o?LsPGUdy z5O5ldLOX{tK+|C)E}d)2(zH>`(VoJ}a`mQ(5DGQ-k`2M@j{zJ$pnc77y8+K*u43u$ zFkl7GgmE?%g%$@Q2+KPY2g<_%o>3SrG$X;cnkZ_bwL&>TTFj%Bqfn_)t}ip!H2@$s z?i?6JZ`#tVc?3Z~=sT>5YhTmaN?9=|<#5iTM8}!fITVgae6*<(iNo4D&iN=MIARbA z5Dkk}OJw!6+mTrp2Uifns&IkH!T^cD5qc&LLML(A;1uE_v`*rJ1g=s*M1$vWEs)wM z3dJT)$5x3KIgSynq1F%<%Mm6pIJrhHWJM7G)C+9N3%{5R=*(D>p~E`CIfW<(;vmdY zanM#gf$qMJN}+^cP%id$nb8!`pUYBe##Lj+cLcs^B_KyCn?UCv`Gb2< z*{jb&su^2I%X`5+=YTe1gE> zhaU5dEW@jl6y{1;;%#cxI%dlaoD-at_}97R!>y|WkWQz!v~_gwpWpZa!=A(V9$saE zKuUyE@Ku%cYS8;0B{_eDC&!n#bLaJRx92%OGfiI}wrquttRnEhq z4|}tHS>~QT$fm-R$W6B~w7JfngA?5Q;7?h-%4fU!H1GN77x}Y)`YZ-GehwxM9KkC! zICW}@sl_VVc=%z0&^L&qweo`FRamH{v}!4BTEENXhys*|Xx~rsi+%TT{o3~sreMvg z9(-V-T;$L%p5f>Z|C07>HxKQ5n6nGBES#R<9Xr=C+R@9w%sPJZtv}@_|NLcc{oT9h zo;gd~(h?j0@P2$9kO~E>Kx>1u4rRR70fJmgLKg$rI64}F#cu69=G>D@XsALPw%U({zl*)_je8(sG+1_um(EA{{ z>!0Gro6BT7#<=yCkaLp_wvKLRrkEks=;ei(kZrepoIk$jliYsWHoo+^PjPNymR-Mm z9Ip{^erc8{im(y^meBYZt>dH^FB;<9OO7)ywLrDC+5r%@zAwjvX8CMhMD5sdJ7dqE zW_oFYhkriHE!!TYP=Qq)Fw)jWqxKl%PbvCuXrsSpgvs4!`0=h3U;B2E+WC-F4nFny zFY}R)y`T5)_yFCjJFw2-1tCa8vl$UcT!}94!s0sc6#yI_AD4}zqor0`4@h0)J}m%F zL<1y)B#-{=hq$w_I1TA0%oa7(nI+oI5-9~^^AKd8V{kq6j6&C1@KnIFv-_w|ZKD6N zJ-l_tD!S4GoY5ZDYLi;i5+)L{;!5G1pcH5nMl1757FY&R24-4{=Udje06?5mBEs-U zH+Q`Az2v)}VE)h)2PdX!E;&w@ArV4bH>C2gz6pJ^Z5)ZpEJltt)u1~ICr=#Wu7?lN z)d^dM;KuFmLg^CdD!%Vwn;u^4Jhawy)k4)SErvr!UlG6x5EbA&kOkUWV3v=^HNXQ8 zJiwa4k8tB%f5hgkYcBM+OmXn=f3f?qUr}8+!Q{y?c0G57BL!#_VZ$3>t^%$M@9Kx5 zg~C+qBuX3-2_jze>|$wdzGkM*6`H5#D$zozX6LN%$g2Wqi4SxG9lXd)v|LC5+;PVp z7aA9fMF38mm|${p3e5;xH{VEGHqQ;$zX+~eJH;cv`YC5l9;Q5dfU*70@$9i_7K?Cw zsj;wRS=e`YVIsdeGyVL;+yPBK5gK%zd(+RR#)U-vQhnR_-|(BZBx@BaC^u8xLI6=%zJ zhtRWn{=oOY^~}V?#F?3ynbJ~Wp_%I6{Gqk)`TPfS?V(YU_v@94IOQjZ zq8D_t^t}^bf8X@Wjs1$X(BbiM3(RaB9c>U(>@eUz`^+=@cJAD{ItYSPTp?bZT%stV zQmIg>RF0L)<^7FD<1rC=5|Ja@Zn>qlVZ#P??AXD`b=M_)-%oeta<7}haURgzP)?@ZE$dK z=nG%^(%+7Zj0BUDla$Nl$!fK_ztL#y0`>soH{X17>9Ui1UIQ=!Mgig+PK-z*=cz{V zK5l? z6<_m!%VS1$6Ro-FO+7b${4--q!MUJ5^K|CG-~Y?eryi}pTK_BB6SrKdaLMcMU&$Dk z8Pks3_S;27oIm^P-PuF`_@lAI2QU8zxD|3m7Wn^^4Wn=Hf^2X8!2X|~yOMstF#uk# Z{2#m>QZB(I0Wtsp002ovPDHLkV1g`IZFT?v literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/PhotoShare/images/friends_album_48.png b/retroshare-gui/src/gui/PhotoShare/images/friends_album_48.png new file mode 100644 index 0000000000000000000000000000000000000000..56162c7c1ba4eeaaee3a340c939a1d38e29a6c61 GIT binary patch literal 4755 zcmV;E5^U{>P)Z_j^M4t{|NcBZ}S ze|ELI_uljP&Ue1^uQ}Is@&EAP9LMqNy53^jcG`8FmP)1CZ9!~Hw=_L2aM*wHi{k&4 zg=C;Y#>LpuG_9SUJL&C=X__58&v(kQ+$M=aoae<@zUB%g+mBdK!J*NKe1BKlZ{7iB zAgv%pv6YN#qt|JA&5Z08MX{ZpnWhrlg}(x8PGH zG{<}p$Z*}XywB+1PW}D`IZ&(BmX%7SmlBCYIur_B$faP}%y125&4!;0PbC82$Z%$} zV>8DZX*siG&mWTaIgTAWc6~CLOjDFE$oN@``0z{>HpinW9zc+=Zjr&}g5k^wX1C|V z84g@1glxwP4ZCpT$|rGr=HKsiXk_K#*(#Q{$6ymW>V`=tI}ioIGhCKL&uIH(2F^JD zq8IU*w0x=~r+(IO%*FPdJD|C7*l9mFL4_hqp23t1)T=e{thn7q^x5HDICKX4xwU4=hYuB&C&Ld^GoPw#m={aRt#HUR%T)R=R_JZM@dyye@5ZtS3(IX7 zZ{7-A(IE%yi_?i&Bos=sN=6E@h-}ftm7O|%e|;K7D>OQ%5h^@$Sv zw1%ox+;vrm3X#W(w1XQj&%gt+7emK;U81_!KT^W$$ICdH1IDI#Ow_3BrW{mQ;Zg>4 zsnG+NnGFB7P8#TBFFA+w|IiMwYw=>EQ-YW!ESczNk7M26&R}G+h-7FC&0z^`2?a4f zhfIvas!ku)_C+wzpIC5?8N?x%&3Q0O1PpRjfKH1EH`g*?ii&qL20_L|7qyYGNJ+#n zCMS{<@XARHT@v#gG%19+iiN3ygWbm*{BU~>)!H;=%|Rk6BSo4=5bO9@j}Nzh zB0&yF;3WZ;>3UQe3Ws2tu9pGJ)af(jtWNgfGeDsbS@5Zn9nvj}nkAf=HmNoxh?EtF z=!5BZl~{(smS>n|#Z1o@;aVr>szjf~iXX#s7OE89%?Ap|ME#Idp85jmA<=~_EHD-? zd*?Y9%>lX)*-g@y@rQu!h=#dZ7(uFRh3dfav=5_Ai*8IsNJK6z(4b7IV+7z**Np}p zf|(12uGbP#5b!q&fOTJqvS83T;sW4mvn4lR03xob2rY6iA#QpN~2tTVffA%{tevPKnhu`<9S z$)*5VQK@Ma(cI+28?QQuMu}EM#@z-%N$`whX=h7hMN8RWdVwb|I2Klu8P$-^8d0jr z8UX8FBIjkHQMKeGom(Ua;vduj!!qRg>U=`C3?=H1%!hs9;%N|~2XlZYjCY2~5-Nyn z%|=^P@PvzK+pubRk3o5VguGR~a~hM0!-S7Vt|B=jP=-uWZj#MUZ%o>*N zL5}Gq_9=71n;Php`8oxJ9Apye)Z;95M8(NH`1AXpxoPb+_g=GRWfx>UxMO7dbq~CJ z&*r^jd)K_1fdvPM*;LQo_cU>Z89STYG+;(~NofE~*MJv76?e3d}tp3OpMIq=9&|LML-`^fb#j691i z`*vbJTSv95W4>7BpW3(a9`>El(Omb>UO2wt>kmGQolpHIN+V;~J0~L^BnsX49Fm5C z!5=({!LdPedKV>7E9eA`Mv*cl%C=G1 zu8T?(tT7G2H}wC!?x0*V8mM*79*WP(fGYZG`CJ9nqQ!(0O;bGLOQ~yKF2j_Z_`~1Z z|Kyjx{PED@z7~)6Y}0~9v+MDL$50tN3M6xV@v~~nqN~3P{p~tpj?!+XrM~_kAS*XnypagRm-g^|6b+4qTGzOG7F-;fE zx{GL~C6XGwok%AmAm)Xj65VnQrpXx*^t1v;$170NLC=mlQE8S2qsBzm7>K>c`5?5a zXVvb`=C+xM+*C@8(TqwGA)Jw^TLxk0dvbgB3`MQC<|*=YabgmI=@TV}Qboe_tb^FP zUKB{3k`hLOF5f~c8+=W@@TK~oBs$U5-GSEr)#wZ+5hUY-#DS_3M6JCO_x#r{QJ;JU0|cu_?)^HJ zEC<%C27*mQ42OnE7uAR$CNVZThDtFb|KWGEs#_HV zhC3S~4IEv^ui1E2@5H@%`G?t>IcL5_7mPV_)+>O&Cj|!2|}Lk!9*b^ zh#qtr>vVfhgOF*OvTfVKhUM$G>Cd<&i{}C@W&-m&XljiHkGJ%PCtEYgLT)}Ab$Jyc zMOkD{L|YMV3gSnPeICz!cNeM$kK(iKF$Ae-YoP?5H|O!O>j%)>6UKkMu?1$_KqB6Y zYQ2O3xqz;f%W1$VdIqwBWsqSru|j>tvK?X0p2d24Uk{SY5_AR05Yz}%gPJ*u9fC!t!==(H>K_$Ztx(+YO zzk>gJve4kf!T!H|`m5jCKljF!ZgVY?ULHb!hMEp_&be#_+xKt1ar6JYaAP90V#XDI z8@_M^I;EJ6Wr8n+#MpO{n*VP|qctqyd|0Z)(Huy4Qednyhg}mVu#AX4)=xDOUV`;E z-;Qs7^-&DwhOqkMi;y+ukfdSQc3JGHcm-0m^nJ~7Pj6u7g3wR){N%2G+x7Sp6Y8*_ z$4XvzEaYpXDmjGwKFrNh76Ke1Qh*@wPOAFK+mMY*VTTOJte7ifxcr?L;Sh63F4LS2 zX7wWJwZ^V>!Kk1eGBkq2^jo`;qT<+1)cNOs^G*EG-M8ZA8*W2WYn1I2Q@ydN%OW^i z-nChox+gb~arWM;NO%(--Tu!Hf9jUi!gGfv5G1-1X{aEgfW;G?xn%@eMED&tjJVO# zsKE#%-pVEPENX+Qp1`r!c46h>3pOGT!rpi z_gKg_MTiSOa@dYruUT$6lt>*u&4HQnOsf;t{fb|~%8o8?-==I=QM2maW)+*2MqiUK z^e=HtZjTd`+7asMMx=|BrjMdTuqccj$L``%?5MWl38RWHrpmZARVDQ)5{Bs}NIW6n`iz4T^{L`y10-zpbS)Nf$*k1%EJS5e;P^34;PX+xknL>_ zY(C9_p|PQ5EZg(bbxhT>AO?m(BORNniqjkpd}{^tsZQjE3`lW$pN3hTByw?l0-)uNnk6=hp_Hw8Gc9XqUdLpP zQ^ERZ4H4j*&c4p({8qLEJ4~-5j+j(T?z_7M&T{SSXjBlN9{>9h2 zTC@{4iE>nh8VEuTg_&@nF_wywMkBWCziHy4m<+R{bCnYC9vpX%({lx%7mQGLFOD2nE$&0FqxGn@EyTPp094KBxYcG2Xm z*03~w$Carkn!?I7&T(+(`lX)9iMp=&uDfc8M4`x zRhUJXH3;k)%?~=sU%gf#$6Q3~d(7|r_2Ny5WNb?^)v`4Z2pr;hUOTmM*6Z~EMcW>k zoL&6mJ=%S(%|UY_Th8e=r!H;{4Si-!a$`6YDBwMgbI!yZ4W*JGn{`7C3Z#Qz=x7 z)ba)Bvq#~mVSezS(7$5&xgDTvII=8j%n24WwwZS~K#h$RCtHr!ePwEN0pzDNl%^+;iq?;R z?k43MH-F-a=iko&K@e<~iJ)ICF+dKqyW8%(y5svF#CQ)a=lkC(hGEL1qcfe`cMPvP zaICUsR`d1M5o*$1HRN!T%=(PLnVOHQ=ObKYv^#0j;7IY hI8gd^jJS~Fe*s!id)#77K1s+m*y^nYG`@bg{rxvJG&Hm@%Ad&i2}bE*k5@L$7lY2uA@RLk4_ZvsrEQ*qN7|hd9wpmQ9Q$SP4$en=Q41{ z{qtVLXVUWNj-39U@0g3N+qa?OCSbROASnSDy5 z`wmpMinde&(FKcz8(6#MI&43dhbtKvoiaVAEQ@^FsKd4WinV7Am)v=V&>Vcub_in? zyM&86TcIa9y}woq6dPFej^Y%xPLF~Y7V_UZBSyrHuk^-@XbwQI5l|!1H&^oF;OO_HPlA}2JbDP3qKSO5>d{~_KD#3izhL_+#I}rvSOE256)~Qg5@zFK#2gtS@iIf} z{m=+ez|!pRjwaJq+jEvn_>kdAzaR;Rgaej63!Qn)0P$ENVW2A&#*(%$R8_`g-oeOB z4Z1F)j%PTiA#Au%8FgW_BA7^2rHHVk&_RohNP~$QouF|w84j`JIy9Ufh)jqovsuk9 zGp48x9kA!86N^X~Oml!nD!Pivtcw*LReXL;3l5E1IB>FnzTqsH1*o|p&v02$VHheR zgjF=ahX;btBz9gpE2`F_fig2BVCC=zTeeXnQP{S~8n1MW3%T>+fJmpp=LS^`A)bB3 zA|6;3VIj)6q{YFlSGK_evKK?gd!1ul>>J48?Gt$%&j5pCGKNd+x+w<*QMk-NRr7m* zFjL^)u2KWd^^&tl|Bvl}SW8y@P6;wgR5P)#J%Q`KHjaUjEE*z%Xo_lRO&W-YB(%jP zT+tE4%Ed9PUYeYBP8cL1Gnw&VmJHYEs)8y{A>3T622(Y>hY1J@CYskqCL*PgVN6M- z6bSM!go>5MjhDtf2Tg`BQ?M{P<6w8cgXg!FP%MoxYYvk2I#Sd;idx1ET|xZrZAm(y zLDm#lrt48@BpQKfx?Tn>vŎ|KARp80j+Je&4lGam2->vxU=|^XT$`mqov9N9;Iix1*Exil3xn%5 z#|(r+egTN?t1$~T-lNU}u0$t=LY+4Vv2h|`7^sk^m$xhUWj_!N>z-qx;2cHB4Gp^N zN8TacHAdD`AR-%%k3);EnLEFUu^HI5$&3*;qBFbxkRzl;zQPKbuMCJtiYY)h0&H4Y zG&KgX<4p(k^`uo*aCePRQamF?+Qq4gqGdLOUXba9B*JP6qkQRHA*Gt40f_FUN?sQH zs-=^>H%kW+^9CXQ2nS?hydz3WSP+vX8?E(qyku2pW!O zydw-376|wlF_Z+a=lUTxcA=Clc+4d^KGua3RZBSI)3Y#9I4{bD=)wezcSX~2KRD5x zbEyCN6Wjm$zCT!t&)(MSwe(uGiW*0}N}+_upMB>?HPh9^Qo-sN8sahZXJsVoWEQTB zK!BQu6lpNBfoK?76zJaa4>n4*b!d{sc!hZ$~AUqi(MvGdzOAbY9)M`qs|X1=Rc*@f3M!SFhk2XqCFXDUED$a&P>u{Yzf zfk7O{+o0FCLyate8cv|6qll(v1GluV#Gy$btdwDh9>sfNEip{~Y9D&DJK(NdgN2t= zv1Q)?zWKuISkSCtwe%PG^dEl>U;U3qJc)3892nSp7;2%0lP5OVcoSVu4FRb7kQnI&C$#ll^Oj%JpZ3uQ=w z2$Wzwqu+qKL=dSa%Z>+YT)i7tExjEtJn=NX`@L@=Gjt3Kmvv(B-Q%Y{fkS;=9FIJ3 z2a+uc{%glZn28#ai5?WoIjq)a(7CLa15Va6QWUI!jOgM9$4kq0yy7y>lBM&^@M-8X&~MCUAGV%{QT)M}*?ymnRRrjRvrWUlHx$Eo$hPHtv- z^2Au7IE~xZehC}4K8dN+3y5F78&_RZM6A9K*IjF1e5ghPS7RbqhfpnrQxgVOt@$GU z`r$9()-|i}^+&&q@qsknc>7JLH48KOG!3`Naw7INdk9&IjlpY*LJWFE?3}-djX;3x zhJY;NW7tp__}@XkfbSy}uZ6uU{(Na?7pgJ1~f``~Y5kD~)Sct)t+g ztf(gmL?WnFHsZ)`39VN|(AsnnhBgi37jJ~{{ik!N%oqrfV!!70!6L>^Hk501j<_M^QAXj%+3EE4KL z$2;k5sE+iab>kLXe@inO!fhC)7AlubZ^xR!^bHqVD?-$XqV~VrP|oSVoD=Ie_TBu{ z^Lze$U%Gis{gNJ3Sy(5h$OiRGFkC4v`|3A#mon2)JaGSNeD=oAAlbMbnS&$PH!ub> z?_jVf1|4djMow(x{2n^il8)f8Rm3#$9g%8ii~%S558|Fz53&=pFDwMET747en*uE@ zLt}5TP4<`BFF6RMa>;V@k!0%V`|O=diETT|lRsGhXaDk@*B{B`%tkGef|2Y*ylXKc zsYWg=BRe*M>BIYIrD3GE-Exl*g9hBvY-<%4;ru560hm>EO$4Ep@fAscc%+VnT&hYK~;Y z!}{di%bT8Qi5r7wuIb&p|4@3_{>R?pROO(qq1lT*SfH+K5Pzzt#T_xKGS80KXyx20 zJDho~3Y{o;I}RsC`_E~(pvQ8#Y}LnO{i)`rZ6tv=Ez{f+i^Ya3l}bTXRr8hCHr|~t zB=5>)b;Y(r8mBY2Y|DWKQSH>-E1I5dj2dHSTU%w*P{*g$lv&E7ds#crMI7%`PC+sX zCGl;Edu{gaJZ! zmJ5D0vxCT-axgW?=;f<4&~F~zMk{{pz+4{@d;5Wq0&{8*`GMnzv|ov_G#`pbkDU5pSuv_y+8^U>hB-v`pM6>-nV1d@fCX}7Tw&?yF65%N|1?yv;RH7m$3p$ z-l$4Xa+7(Cyt~u6G=6a1jcdAJ{q5UV{Jf{9_1J|x^lS%Vq|Rh>$z&ov{!#9e&eRsg zVmW;9;K|-Yhewx=PuJShIkcBeAt@x8^0t(ylg1Y$wEnJz@xzy0+Oap0h)#W6qvzxJ YUkC1{M~HCkqyPW_07*qoM6N<$g803z8UO$Q literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/PhotoShare/images/subscribed_album_48.png b/retroshare-gui/src/gui/PhotoShare/images/subscribed_album_48.png new file mode 100644 index 0000000000000000000000000000000000000000..fc76f2e7ff37cabc591a0062ec1b8e5fdfbcde29 GIT binary patch literal 4334 zcmV7;SUv?ZZQ(~@FJ3(SO}P03Jf0|tz-;{}8FRkAHhmbF=LfA`(3-|t=t9Lp@Rm1(Yg z=e|Yvch7gucfNDZPnJB-!|&iBxvm>AO|#K)oMz8+8w-VErwz5Gxv}nXMZ*4xUsV6U zETn-3jZ2BMQmM4@+Rl$#Ez6oF%W}J}>n)n9q-9x6jg~wm=R}Z-8902pZ*)ON%Wofm zFpy`AUTmUqEqvX~*TTq7RaM(~t=BZIfv?liXjJAEk|e!%zu?7S&O)waA*AbQ%E*vq z34^0v{Nm?aH2@mbQms}O(2LXfww*?_31ewcE6)ZR88Zw+qgNr$j|T4He9lC!Y$F`f zP@f7zq2Z=w``_`9F8=+i0#GWI=H_y_mou46b37iunx$Yn!te_66$cR--jInxqT#}3 z*Ac*iuw0t5AMKJ4Il8;MSJu|nHq*;jW&9vLe)N11jwGWl9Yu^>w`s67Znyv;?DjES z0^n*X7=>BRKoYS-jgljGlo4?z^cT53HGqLfJ($tUxy;Fn?itf$gNu0j+k$OJKE6ngd5S07xlV#W8w>v;>V!$ErXJDd8j z>-b@e6fNY7rZ0oZu#R{{Lp&PBlDP?TKd?ad6oCH(UF@nyk4sb?iH1@-MSk!*)Af8c z65eNC`zm$mam4^4niG0`09gId4th{0w`J5OL#TmRmO1MMgLe8x-KKe zGaA+qH9V;Fx-eQ1N+hyUcvw;h&}JdhV4+G7G_EScC6_#xh7*B^gvc_7+3Yc5is}-8 zGc}c1c*0CRy9O;9w`>F_U1Sf zQO5jc7oYh=D|{mRK6L%pIp)Rwo*aI4Dvy&Rz?lIVeI-`i1{Vd9xQu|Q1vNmJDfsW0 z?13g~$z@vqD+VCelGUJ6g36N6EKF-lW7)UPqo+TM+V~mNCp5HV45T6wT2m4hwTH2I zb`nb$WX8b>gCvX$kN7mpM5~0Vz~m_!H_xuZQVsuMf`UScrnHa=Pia&bOH$big!u`n zVh`cgYg0Zzi!K}~*f=-lVo$e=r`{@|SQ=o|Tx4o=G_dDU)G~f=dKh=zo*@7YvZlbc zJYP!Vi8w6F^CMteCciT#RkACO09~O9=QERC_AN8&HS`Wx%uNj{qvBFNME@S5$_U!Z zg3}_Id9}%Fli-S!&uk%rqeC`|bnm7EV`#03KnuyN3+#tf54tk0ShDWl=S~>_E=0T8 z`U?F}(3z}YsFXmAnQbr+Y`^yrvT5_dOhO8|HZFrYLnj2lW7VyRxulr~gX=XW4MZbB z0*LCXF$z`QqmC1oA<5hHCxW%hz0N3<6C3NvJ?A|N~|rU2atv1nycUl+#C z*Im@qP*zo;-BnUa@r@K=7pE$cmeCOXf=m>WaH}PZ3R>q1CDjrIKvXYP@}m%BEkW|$ zECHmaj6(bo0AzB!JwZ#D5W^)0Ej5bYxTuN|R8x9Y7JY!{`S%2qi7Of(UtCp!Q5YeM zotx%}8esXkBMB86S00&O$d)Q7nhMgFSbXIaa)X;ik~Ku>xr)jPtivF29VO^}mGM!^ zp@$`(I&2w4zaT2HhyWL{Jt~i4@+u0J=~GVhOX6Dr!k-#=%Z0MTv6F(JOc4NY{AQiX z)@Y2PH`|Jk?lOUuAPIdB3ZSAjV9Owf*(QYGma+^6EfQ_PI7rbaWpftU6+|Uye1aSi z`v4WH)rF$Ximyza3i)axUYJ?Tql&yaq$3@35H?)jcvl!MED-cDk|+sX&viqtn~qYp z;47Ep23!{)Ok02n9PtyD&)OJyCSL$rH^L5A~v}6ibE80o10F=+4T>#AGI} zj8KR@4<*u|XG4i7v;;6?+uz{CcUR+V?+DU$F@#yY4faF^`zVP6jMzpI-VRZM1un-6 zydKz{JE@en~+iw10ll&QfGwTw;jiKm^&c^R|{bG?%h9$ z#uE3Bu&6xu)2|~GOEH0IsNX)bjW&2?J<#f?n7?=wHb=#NQ$^RjRy5ZpLFI)KVtpW| zHFl>X)g;=R!pII6I12=os!S;zDpq~3yN(xJU3b!^!4&}zJ8|)v8vM_XpG7;9QDN(# zmPVm_1sEu?Sd|fN;^Nz1MtI~Xb{@;K*I9_VL(1;VoW{Y4c5N+uwulKfM`EjT)9pe}Oyh{}#UauMhhz!pZYM z&%UEj3ssyx-H-kYWq)?i7%GF56gm)WD^8}+uK_sm!ukiX@6F|E4V!?pm_Ym%MsiIW zeb$vkv8k4+7{mFwh0G$n+4wFNcHRMl$7Hs|2rg-b$EXJMtXAy zqh|)O;`SMsUDJU5u^D*r@vq^i*Sk)bC)bDep4tZ z>Ns`058hVUv;K~KpO|ytT4@&D8BdbXwd~XwYc&SHYAwjJo8owtzW^_rN4akoPX1RI ziynUr&-~NR@WUTHf|1@6nAX*SGw+_f=m{L^nIjLcy&IWk1<&l<0xMlbCOs3yat=%N zF?4jzlax`z9;FD3 zoeY|Og&FEp#a0`m-N>ug-^sNV9MWZ_n0}|=tDCn9!htt^*%wn1iU3ol7#SqU5O{axuc(uwoK-B}| z$4N8^fZBg>zEmOR3g4`H1ZZ7D0G#=9JAuAufm8nr6!XD$L5aU7=D&jIQ9KOp`45aX z>_tag7uw26Cf*UWbMiXhTcv?Z@${baXw>33OAp_?{3}>GrxP2VdkVKK`xMrH`-eC< zas;3J^b8DFhfvF5*ztt#9o7(bwJZ!3*ZcJXb~y?uG1+yh>^;bFX|BH@*NIJLa>=D-mB=OkARw%wgjjLs)Y2%WSyVRxo(8;&D_fTX1ZTgqB5dwA9Z+ z@76xN@LB|q{Va#dn1KlE!=L~4dVJ~2pT(WGeGYX^HDafjj1yCr%}LCrss){>H?e_? z$$PIs4v^+nC8+x93qOFY|A74GSF@J^%O7Qve?4&L0mgO-ob9_AZc1q-7`o5&9)^34 z&DH>w$O49PGRlK_B$PZj3gZX^sV5JhjXtTL4b*mu?m@>pL)&5Y&qK?WZMfyOM$|@I z(Z^n>T(RA~qNxis#rOARli1?JZBjgP&o>}mCL^yA^it448-d{h3v;X?EvKe0d!!CO_NXGXN{^;!IHtIt*f6paV0xcJojiNBMvY zL>-r^sH0At>OO>fHy&aorbbKyu3x&6DJQsDhQ`|BSgbGOf8=0)RW8|HKAvefJ{bUk zjZ%Cx(juI^hOSx>oL%3Bx8tjDpZ>Z((@I?rL0$bMihuiQTp0F{CxBFA7ruJ$H!z>- zGjTW|n8Uxs)-AhH9_>c&sUvvpKp&1$$f`NunmOR?KsFNS$`+;?b1T~)kVNRVC#WoG zR-tSTLpAypNj@Vf@@P#&8J<}m-82~h5i;3P=A!aXA3(V6yNE1V3uEzvkZvM{>o zzJ|~@?}5^EE9`lTQ8>H8iP8GWY?qd2q=M|K^+J0}KkfwwQQ+|hhl87)?no?0z5U})xuZs?_|;~EiNF5Ugf zhJSC*gicHbkcHp33dO9R$wH~*VZZwjq9$g+yU$-r5Z!($e zt5hllRaLDQH*HyyFJxBdvby3p5slNCS9au3Q$jnt=EnLBbqQnOa%=klL_&&vd5`a+ zxBM9-Jp*mVz0m5{!g>2iAAmZ26(sXf@^%19q8+i8IHbNDimr57gG;57xQcM^ibkVb zQmNF=a5#KamgUOC@0q3@A5jVy@ z$T>cMDvPXPh7Wd~1 zP9l*|dV70Cm)c7McSRzR*V5_qwooW^jLlu)gC4GFT9whD$DKeLJ%10?v*oZlw^7~q z`Na(z!r@Ty!=md0h%C6}4Rf1<+}N3G!lXu9tDJulV#@e|YgpZsEDgC|K*@;fZCpvnHWoM|a++ ziD6o77mL99I}7mtWa94*+nyvUaCGLPy{$JcdFyJ7zxW`H)Uj+XlS!w}|0efIzoY-% c=3^iK2c0C;O{MF9)Bpeg07*qoM6N<$f|ZjT-v9sr literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui index 7a28c7002..88ddd18bd 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui @@ -87,6 +87,9 @@ Qt::ToolButtonTextBesideIcon + + true + @@ -111,6 +114,15 @@ + + 0 + + + 0 + + + 0 + @@ -147,6 +159,9 @@ + + 0 + @@ -203,6 +218,9 @@ 24 + + true + @@ -223,6 +241,9 @@ 24 + + true + @@ -232,19 +253,6 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -266,6 +274,9 @@ Qt::ToolButtonTextBesideIcon + + true + @@ -286,6 +297,9 @@ Qt::ToolButtonTextBesideIcon + + true + @@ -306,6 +320,9 @@ Qt::ToolButtonTextBesideIcon + + true + @@ -329,6 +346,9 @@ Qt::ToolButtonTextBesideIcon + + true + @@ -356,6 +376,9 @@ Qt::ToolButtonTextBesideIcon + + true + @@ -379,8 +402,24 @@ Qt::ToolButtonTextBesideIcon + + true + + + + + Qt::Horizontal + + + + 40 + 20 + + + + From 5a55c1b5d67ea7e0df8640870d270361286ca804 Mon Sep 17 00:00:00 2001 From: drbob Date: Thu, 29 Nov 2012 22:48:28 +0000 Subject: [PATCH 189/222] * Added the basics of GxsCircles service to libretroshare. - Defined the control group stuff. - Background task to determine friend membership. - Caching of Circle info, - Added GXS interface class to gxs/rsgixs.h - TODO: Serialiser is incomplete. - TODO: SubCircles to be done in Phase 2. * Improvements to RsMemCache: - Added Value& ref(Key) to avoid data copying. - Added Statistics to check cache performance. - Fixed up bugs in tracking membership. * Improvements to RsTickEvent: - Added additional string parameter for more specificity. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5910 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/gxstokenqueue.h | 2 + libretroshare/src/gxs/rsgixs.h | 188 +-- libretroshare/src/libretroshare.pro | 10 + libretroshare/src/retroshare/rsgxscircles.h | 105 ++ libretroshare/src/retroshare/rsidentity.h | 2 +- .../src/serialiser/rsgxscircleitems.cc | 408 ++++++ .../src/serialiser/rsgxscircleitems.h | 93 ++ libretroshare/src/serialiser/rsserviceids.h | 14 +- libretroshare/src/services/p3circles.h | 208 --- libretroshare/src/services/p3gxscircles.cc | 1305 +++++++++++++++++ libretroshare/src/services/p3gxscircles.h | 224 +++ libretroshare/src/services/p3gxsforums.cc | 2 +- libretroshare/src/services/p3gxsforums.h | 9 +- libretroshare/src/services/p3idservice.cc | 12 +- libretroshare/src/services/p3idservice.h | 13 +- libretroshare/src/util/rsmemcache.h | 109 +- libretroshare/src/util/rstickevent.cc | 53 +- libretroshare/src/util/rstickevent.h | 23 +- 18 files changed, 2353 insertions(+), 427 deletions(-) create mode 100644 libretroshare/src/retroshare/rsgxscircles.h create mode 100644 libretroshare/src/serialiser/rsgxscircleitems.cc create mode 100644 libretroshare/src/serialiser/rsgxscircleitems.h delete mode 100644 libretroshare/src/services/p3circles.h create mode 100644 libretroshare/src/services/p3gxscircles.cc create mode 100644 libretroshare/src/services/p3gxscircles.h diff --git a/libretroshare/src/gxs/gxstokenqueue.h b/libretroshare/src/gxs/gxstokenqueue.h index b77f9247f..5787c1f28 100644 --- a/libretroshare/src/gxs/gxstokenqueue.h +++ b/libretroshare/src/gxs/gxstokenqueue.h @@ -58,6 +58,8 @@ bool queueRequest(uint32_t token, uint32_t req_type); void checkRequests(); // must be called by + protected: + // This must be overloaded to complete the functionality. virtual void handleResponse(uint32_t token, uint32_t req_type); diff --git a/libretroshare/src/gxs/rsgixs.h b/libretroshare/src/gxs/rsgixs.h index b7f37768d..6a3d91372 100644 --- a/libretroshare/src/gxs/rsgixs.h +++ b/libretroshare/src/gxs/rsgixs.h @@ -29,6 +29,8 @@ #include "gxs/rsgxs.h" #include "gxs/rsgenexchange.h" +#include "retroshare/rsgxscircles.h" + #include "serialiser/rstlvkeys.h" /*! @@ -94,9 +96,9 @@ * as these will be used very frequently. *****/ -//typedef std::string GxsId; - -typedef std::string PeerId; +typedef std::string PeerId; // SHOULD BE REMOVED => RsPeerId (SSLID) +typedef std::string RsPgpId; +typedef std::string RsGxsId; // //// External Interface - @@ -119,7 +121,6 @@ typedef std::string PeerId; /* Identity Interface for GXS Message Verification. */ -typedef std::string RsGxsId; class RsGixs { public: @@ -185,8 +186,8 @@ class RsGxsIdExchange: public RsGixs { public: - RsGxsIdExchange(RsGeneralDataService* gds, RsNetworkExchangeService* ns, RsSerialType* serviceSerialiser, uint16_t mServType) - :RsGenExchange(gds,ns,serviceSerialiser,mServType, this) { return; } + RsGxsIdExchange(RsGeneralDataService* gds, RsNetworkExchangeService* ns, RsSerialType* serviceSerialiser, uint16_t mServType) + :RsGenExchange(gds,ns,serviceSerialiser,mServType, this) { return; } virtual ~RsGxsIdExchange() { return; } }; @@ -194,180 +195,31 @@ virtual ~RsGxsIdExchange() { return; } +/* For Circles Too */ -// BELOW IS OLD - WILL DELETE SHORTLY - -#if 0 - - -/*! - * Storage class for private and public publish keys - * - */ -class GixsKey +class RsGcxs { - KeyRef mKeyId; + public: - /// public key - EVP_PKEY *mPubKey; - - /// NULL if non-existant */ - EVP_PKEY *mPrivKey; -}; - -/*! - * - * - */ -class KeyRef { - - std::string refId; + /* GXS Interface - for working out who can receive */ + virtual bool isLoaded(const RsGxsCircleId &circleId) = 0; + virtual bool loadCircle(const RsGxsCircleId &circleId) = 0; + virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id) = 0; + virtual bool recipients(const RsGxsCircleId &circleId, std::list &friendlist) = 0; }; -class KeyRefSet { - std::set mKeyRefSet; -}; -class SignatureSet { - std::set mSignatureSet; -}; - -/*! - * - * - */ -class RsGxsSignature { - - KeyRef mKeyRef; -}; - -/*! - * This is the actual identity \n - * In a sense the group description with the GixsKey the "message" - */ -class RsGixsProfile { - -public: - - KeyRef mKeyRef; - std::string name; - - /// may be superseded by newer timestamps - time_t mTimeStamp; - uint32_t mProfileType; - - // TODO: add permissions members - - RsGxsSignature mSignature; - -}; - -/*! - * Retroshare general identity exchange service - * - * Purpose: \n - * Provides a means to distribute identities among peers \n - * Also provides encyption, decryption, verification, \n - * and signing functionality using any created or received identities \n - * - * This may best be implemented as a singleton like current AuthGPG? \n - * - */ -class RsIdentityExchangeService : RsGxsService +class RsGxsCircleExchange: public RsGenExchange, public RsGcxs { public: - - enum IdentityType { Pseudonym, Signed, Anonymous }; - - RsGixs(); - - /*! - * creates gixs profile and shares it - * @param profile - * @param type the type of profile to create, self signed, anonymous, and GPG signed - */ - virtual bool createKey(RsGixsProfile& profile, uint32_t type) = 0; /* fills in mKeyId, and signature */ - - /*! - * Use to query a whether given key is available by its key reference - * @param keyref the keyref of key that is being checked for - * @return true if available, false otherwise - */ - virtual bool haveKey(const KeyRef& keyref) = 0; - - /*! - * Use to query whether private key member of the given key reference is available - * @param keyref the KeyRef of the key being checked for - * @return true if private key is held here, false otherwise - */ - virtual bool havePrivateKey(const KeyRef& keyref) = 0; - - /*! - * Use to request a given key reference - * @param keyref the KeyRef of the key being requested - * @return will - */ - virtual bool requestKey(const KeyRef& keyref) = 0; - - /*! - * Retrieves a key identity - * @param keyref - * @return a pointer to a valid profile if successful, otherwise NULL - * - */ - virtual RsGixsProfile* getProfile(const KeyRef& keyref) = 0; - - - /*** process data ***/ - - /*! - * Use to sign data with a given key - * @param keyref the key to sign the data with - * @param data the data to be signed - * @param dataLen the length of the data - * @param signature is set with the signature from signing with keyref - * @return false if signing failed, true otherwise - */ - virtual bool sign(const KeyRef& keyref, unsigned char* data, uint32_t dataLen, std::string& signature) = 0; - - /*! - * Verify that the data is signed by the key owner - * @param keyref - * @param data - * @param dataLen - * @param signature - * @return false if verification failed, false otherwise - */ - virtual bool verify(const KeyRef& keyref, unsigned char* data, int dataLen, std::string& signature) = 0; - - /*! - * Attempt to decrypt data with a given key - * @param keyref - * @param data data to be decrypted - * @param dataLen length of data - * @param decryptedData decrypted data - * @param decryptDataLen length of decrypted data - * @return false - */ - virtual bool decrypt(const KeyRef& keyref, unsigned char* data, int dataLen, - unsigned char*& decryptedData, uint32_t& decyptDataLen) = 0; - - /*! - * Attempt to encrypt data with a given key - * @param keyref - * @param data data to be encrypted - * @param dataLen length of data - * @param encryptedData encrypted data - * @param encryptDataLen length of encrypted data - */ - virtual bool encrypt(const KeyRef& keyref, unsigned char* data, int dataLen, - unsigned char*& encryptedData, uint32_t& encryptDataLen) = 0; + RsGxsCircleExchange(RsGeneralDataService* gds, RsNetworkExchangeService* ns, RsSerialType* serviceSerialiser, + uint16_t mServType, RsGixs* gixs, uint32_t authenPolicy) + :RsGenExchange(gds,ns,serviceSerialiser,mServType, gixs, authenPolicy) { return; } +virtual ~RsGxsCircleExchange() { return; } }; -#endif // END OF #if 0 - #endif // RSGIXS_H diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 62c97a810..15e803a6a 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -640,6 +640,16 @@ HEADERS += retroshare/rsgame.h SOURCES += services/p3idservice.cc \ serialiser/rsgxsiditems.cc \ + # GxsCircles Service + HEADERS += services/p3gxscircles.h \ + +# serialiser/rsgxscircleitems.h +# retroshare/rsgxscircles.h \ + + SOURCES += services/p3gxscircles.cc \ + +# serialiser/rsgxscircleitems.cc \ + # GxsForums Service HEADERS += retroshare/rsgxsforums.h \ services/p3gxsforums.h \ diff --git a/libretroshare/src/retroshare/rsgxscircles.h b/libretroshare/src/retroshare/rsgxscircles.h new file mode 100644 index 000000000..741c7bea0 --- /dev/null +++ b/libretroshare/src/retroshare/rsgxscircles.h @@ -0,0 +1,105 @@ +#ifndef RETROSHARE_GXSCIRCLES_INTERFACE_H +#define RETROSHARE_GXSCIRCLES_INTERFACE_H + +/* + * libretroshare/src/retroshare: rsgxscircles.h + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include +#include +#include + +#include "gxs/rstokenservice.h" +#include "gxs/rsgxsifaceimpl.h" + +#include "retroshare/rsidentity.h" + + +/* The Main Interface Class - for information about your Peers */ +class RsGxsCircles; +extern RsGxsCircles *rsGxsCircles; + + +typedef std::string RsGxsCircleId; +typedef std::string RsPeerId; // SSL ID. +typedef std::string RsPgpId; +typedef std::string RsCircleInternalId; + +#define GXS_PERM_TYPE_PUBLIC 0x0001 +#define GXS_PERM_TYPE_EXTERNAL 0x0002 +#define GXS_PERM_TYPE_YOUREYESONLY 0x0003 + +/* Permissions is part of GroupMetaData + */ + +class GxsPermissions +{ +public: + uint32_t mCircleType; // PUBLIC, EXTERNAL or YOUREYESONLY. + RsGxsCircleId mCircleId; // If EXTERNAL, otherwise Blank. + + // BELOW IS NOT SERIALISED - BUT MUST BE STORED LOCALLY BY GXS. (If YOUREYESONLY) + RsPeerId mOriginator; + RsCircleInternalId mInternalCircle; // if Originator == ownId, otherwise blank. +}; + + +class RsGxsCircleGroup +{ + public: + RsGroupMetaData mMeta; // includes GxsPermissions, for control of group distribution. + + std::list mInvitedMembers; + std::list mSubCircles; + + // Not Serialised. + // Internally inside rsCircles, this will be turned into: + // std::list mAllowedFriends; +}; + +class RsGxsCircleMsg +{ + public: + RsMsgMetaData mMeta; + + // Signature by user signifying that they want to be part of the group. + // maybe Phase 3. +}; + + + + +class RsGxsCircles: public RsGxsIfaceImpl +{ + public: + + RsGxsCircles(RsGenExchange *gxs) + :RsGxsIfaceImpl(gxs) { return; } +virtual ~RsGxsCircles() { return; } + +}; + + + +#endif diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index ca1ada8a6..87a2d2ad1 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -82,7 +82,7 @@ class RsGxsIdGroup std::string mPgpIdHash; std::string mPgpIdSign; // Need a signature as proof - otherwise anyone could add others Hashes. - // Serialised - for GUI's benefit. + // Not Serialised - for GUI's benefit. bool mPgpKnown; std::string mPgpId; }; diff --git a/libretroshare/src/serialiser/rsgxscircleitems.cc b/libretroshare/src/serialiser/rsgxscircleitems.cc new file mode 100644 index 000000000..baf8e01f7 --- /dev/null +++ b/libretroshare/src/serialiser/rsgxscircleitems.cc @@ -0,0 +1,408 @@ +/* + * libretroshare/src/serialiser: rswikiitems.cc + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include + +#include "rswireitems.h" +#include "serialiser/rstlvbase.h" +#include "serialiser/rsbaseserial.h" + +#define CIRCLE_DEBUG 1 + + +uint32_t RsGxsCircleSerialiser::size(RsItem *item) +{ + RsGxsCircleGroupItem* grp_item = NULL; + RsGxsCircleMsgItem* snap_item = NULL; + + if((grp_item = dynamic_cast(item)) != NULL) + { + return sizeGxsCircleGroupItem(grp_item); + } + else if((snap_item = dynamic_cast(item)) != NULL) + { + return sizeGxsCircleMsgItem(snap_item); + } + return NULL; +} + +bool RsGxsCircleSerialiser::serialise(RsItem *item, void *data, uint32_t *size) +{ + RsGxsCircleGroupItem* grp_item = NULL; + RsGxsCircleMsgItem* snap_item = NULL; + + if((grp_item = dynamic_cast(item)) != NULL) + { + return serialiseGxsCircleGroupItem(grp_item, data, size); + } + else if((snap_item = dynamic_cast(item)) != NULL) + { + return serialiseGxsCircleMsgItem(snap_item, data, size); + } + return false; +} + +RsItem* RsGxsCircleSerialiser::deserialise(void* data, uint32_t* size) +{ + +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::deserialise()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_GXSCIRCLE != getRsItemService(rstype))) + { + return NULL; /* wrong type */ + } + + switch(getRsItemSubType(rstype)) + { + + case RS_PKT_SUBTYPE_GXSCIRCLE_GROUP_ITEM: + return deserialiseGxsCircleGroupItem(data, size); + break; + case RS_PKT_SUBTYPE_GXSCIRCLE_MSG_ITEM: + return deserialiseGxsCircleMsgItem(data, size); + break; + default: +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::deserialise(): unknown subtype"; + std::cerr << std::endl; +#endif + break; + } + return NULL; +} + + + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + + +void RsGxsCircleGroupItem::clear() +{ + group.mDescription.clear(); +} + +std::ostream& RsGxsCircleGroupItem::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsGxsCircleGroupItem", indent); + uint16_t int_Indent = indent + 2; + + printIndent(out, int_Indent); + out << "Description: " << group.mDescription << std::endl; + + printRsItemEnd(out ,"RsGxsCircleGroupItem", indent); + return out; +} + + +uint32_t RsGxsCircleSerialiser::sizeGxsCircleGroupItem(RsGxsCircleGroupItem *item) +{ + + const RsCircleGroup& group = item->group; + uint32_t s = 8; // header + + s += GetTlvStringSize(group.mDescription); + + return s; +} + +bool RsGxsCircleSerialiser::serialiseGxsCircleGroupItem(RsGxsCircleGroupItem *item, void *data, uint32_t *size) +{ + +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::serialiseGxsCircleGroupItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsCircleGroupItem(item); + uint32_t offset = 0; + + if(*size < tlvsize) + { +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::serialiseGxsCircleGroupItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsCircleGroupItem */ + ok &= SetTlvString(data, tlvsize, &offset, 1, item->group.mDescription); + + if(offset != tlvsize) + { +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::serialiseGxsCircleGroupItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef CIRCLE_DEBUG + if (!ok) + { + std::cerr << "RsGxsCircleSerialiser::serialiseGxsCircleGroupItem() NOK" << std::endl; + } +#endif + + return ok; + } + +RsGxsCircleGroupItem* RsGxsCircleSerialiser::deserialiseGxsCircleGroupItem(void *data, uint32_t *size) +{ + +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::deserialiseGxsCircleGroupItem()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_GXSCIRCLE != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_GXSCIRCLE_GROUP_ITEM != getRsItemSubType(rstype))) + { +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::deserialiseGxsCircleGroupItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::deserialiseGxsCircleGroupItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsCircleGroupItem* item = new RsGxsCircleGroupItem(); + /* skip the header */ + offset += 8; + + ok &= GetTlvString(data, rssize, &offset, 1, item->group.mDescription); + + if (offset != rssize) + { +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::deserialiseGxsCircleGroupItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::deserialiseGxsCircleGroupItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + + + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + + +void RsGxsCircleMsgItem::clear() +{ + pulse.mPulseText.clear(); + pulse.mHashTags.clear(); +} + +std::ostream& RsGxsCircleMsgItem::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsGxsCircleMsgItem", indent); + uint16_t int_Indent = indent + 2; + + printIndent(out, int_Indent); + out << "Page: " << pulse.mPulseText << std::endl; + + printIndent(out, int_Indent); + out << "HashTags: " << pulse.mHashTags << std::endl; + + printRsItemEnd(out ,"RsGxsCircleMsgItem", indent); + return out; +} + + +uint32_t RsGxsCircleSerialiser::sizeGxsCircleMsgItem(RsGxsCircleMsgItem *item) +{ + + const RsCircleMsg& pulse = item->pulse; + uint32_t s = 8; // header + + s += GetTlvStringSize(pulse.mPulseText); + s += GetTlvStringSize(pulse.mHashTags); + + return s; +} + +bool RsGxsCircleSerialiser::serialiseGxsCircleMsgItem(RsGxsCircleMsgItem *item, void *data, uint32_t *size) +{ + +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::serialiseGxsCircleMsgItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsCircleMsgItem(item); + uint32_t offset = 0; + + if(*size < tlvsize) + { +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::serialiseGxsCircleMsgItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsCircleMsgItem */ + ok &= SetTlvString(data, tlvsize, &offset, 1, item->pulse.mPulseText); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->pulse.mHashTags); + + if(offset != tlvsize) + { +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::serialiseGxsCircleMsgItem() FAIL Size Error! " << std::endl; +#endif + ok = false; + } + +#ifdef CIRCLE_DEBUG + if (!ok) + { + std::cerr << "RsGxsCircleSerialiser::serialiseGxsCircleMsgItem() NOK" << std::endl; + } +#endif + + return ok; + } + +RsGxsCircleMsgItem* RsGxsCircleSerialiser::deserialiseGxsCircleMsgItem(void *data, uint32_t *size) +{ + +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::deserialiseGxsCircleMsgItem()" << std::endl; +#endif + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_GXSV1_TYPE_GXSCIRCLE != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_GXSCIRCLE_MSG_ITEM != getRsItemSubType(rstype))) + { +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::deserialiseGxsCircleMsgItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::deserialiseGxsCircleMsgItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsCircleMsgItem* item = new RsGxsCircleMsgItem(); + /* skip the header */ + offset += 8; + + ok &= GetTlvString(data, rssize, &offset, 1, item->pulse.mPulseText); + ok &= GetTlvString(data, rssize, &offset, 1, item->pulse.mHashTags); + + if (offset != rssize) + { +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::deserialiseGxsCircleMsgItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::deserialiseGxsCircleMsgItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} + + +/*****************************************************************************************/ +/*****************************************************************************************/ +/*****************************************************************************************/ + diff --git a/libretroshare/src/serialiser/rsgxscircleitems.h b/libretroshare/src/serialiser/rsgxscircleitems.h new file mode 100644 index 000000000..457dae5f3 --- /dev/null +++ b/libretroshare/src/serialiser/rsgxscircleitems.h @@ -0,0 +1,93 @@ +/* + * libretroshare/src/serialiser: rsgxscircleitems.h + * + * RetroShare C++ Interface. + * + * Copyright 2012-2012 by Robert Fernie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#ifndef RS_GXSCIRCLE_ITEMS_H +#define RS_GXSCIRCLE_ITEMS_H + +#include + +#include "serialiser/rsserviceids.h" +#include "serialiser/rsserial.h" +#include "serialiser/rstlvtypes.h" + +#include "rsgxsitems.h" +#include "retroshare/rsgxscircles.h" + +const uint8_t RS_PKT_SUBTYPE_GXSCIRCLE_GROUP_ITEM = 0x02; +const uint8_t RS_PKT_SUBTYPE_GXSCIRCLE_MSG_ITEM = 0x03; + +class RsGxsCircleGroupItem : public RsGxsGrpItem +{ + +public: + + RsGxsCircleGroupItem(): RsGxsGrpItem(RS_SERVICE_GXSV1_TYPE_GXSCIRCLE, + RS_PKT_SUBTYPE_GXSCIRCLE_GROUP_ITEM) { return;} + virtual ~RsGxsCircleGroupItem() { return;} + + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + + RsGxsCircleGroup group; +}; + +class RsGxsCircleMsgItem : public RsGxsMsgItem +{ +public: + + RsGxsCircleMsgItem(): RsGxsMsgItem(RS_SERVICE_GXSV1_TYPE_GXSCIRCLE, + RS_PKT_SUBTYPE_GXSCIRCLE_MSG_ITEM) {return; } + virtual ~RsGxsCircleMsgItem() { return;} + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + RsGxsCircleMsg msg; +}; + +class RsGxsCircleSerialiser : public RsSerialType +{ +public: + + RsGxsCircleSerialiser() + :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXSV1_TYPE_GXSCIRCLE) + { return; } + virtual ~RsGxsCircleSerialiser() { return; } + + uint32_t size(RsItem *item); + bool serialise (RsItem *item, void *data, uint32_t *size); + RsItem * deserialise(void *data, uint32_t *size); + + private: + + uint32_t sizeGxsCircleGroupItem(RsGxsCircleGroupItem *item); + bool serialiseGxsCircleGroupItem (RsGxsCircleGroupItem *item, void *data, uint32_t *size); + RsGxsCircleGroupItem * deserialiseGxsCircleGroupItem(void *data, uint32_t *size); + + uint32_t sizeGxsCircleMsgItem(RsGxsCircleMsgItem *item); + bool serialiseGxsCircleMsgItem (RsGxsCircleMsgItem *item, void *data, uint32_t *size); + RsGxsCircleMsgItem * deserialiseGxsCircleMsgItem(void *data, uint32_t *size); +}; + +#endif /* RS_GXSCIRCLE_ITEMS_H */ diff --git a/libretroshare/src/serialiser/rsserviceids.h b/libretroshare/src/serialiser/rsserviceids.h index 24a3e3779..c47dba6a4 100644 --- a/libretroshare/src/serialiser/rsserviceids.h +++ b/libretroshare/src/serialiser/rsserviceids.h @@ -138,14 +138,16 @@ const uint16_t RS_SERVICE_GXSV1_TYPE_WIRE = 0xf304; const uint16_t RS_SERVICE_GXSV1_TYPE_FORUMS = 0xf305; const uint16_t RS_SERVICE_GXSV1_TYPE_POSTED = 0xf306; const uint16_t RS_SERVICE_GXSV1_TYPE_CHANNELS = 0xf307; +const uint16_t RS_SERVICE_GXSV1_TYPE_GXSCIRCLE = 0xf307; const uint16_t RS_SERVICE_GXSV2_TYPE_GXSID = 0xf311; -const uint16_t RS_SERVICE_GXSV2_TYPE_PHOTO = 0xf312; -const uint16_t RS_SERVICE_GXSV2_TYPE_WIKI = 0xf313; -const uint16_t RS_SERVICE_GXSV2_TYPE_WIRE = 0xf314; -const uint16_t RS_SERVICE_GXSV2_TYPE_FORUMS = 0xf315; -const uint16_t RS_SERVICE_GXSV2_TYPE_POSTED = 0xf316; -const uint16_t RS_SERVICE_GXSV2_TYPE_CHANNELS = 0xf317; +const uint16_t RS_SERVICE_GXSV2_TYPE_GXSCIRCLE = 0xf312; +const uint16_t RS_SERVICE_GXSV2_TYPE_PHOTO = 0xf313; +const uint16_t RS_SERVICE_GXSV2_TYPE_WIKI = 0xf314; +const uint16_t RS_SERVICE_GXSV2_TYPE_WIRE = 0xf315; +const uint16_t RS_SERVICE_GXSV2_TYPE_FORUMS = 0xf316; +const uint16_t RS_SERVICE_GXSV2_TYPE_POSTED = 0xf317; +const uint16_t RS_SERVICE_GXSV2_TYPE_CHANNELS = 0xf318; /* Example Versions (VEG) of New Cache Services */ const uint16_t RS_SERVICE_VEG_TYPE_IDENTITY = 0xf320; diff --git a/libretroshare/src/services/p3circles.h b/libretroshare/src/services/p3circles.h deleted file mode 100644 index 2eceea528..000000000 --- a/libretroshare/src/services/p3circles.h +++ /dev/null @@ -1,208 +0,0 @@ -/* - * libretroshare/src/services: p3circles.h - * - * Identity interface for RetroShare. - * - * Copyright 2012-2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#ifndef P3_CIRCLES_SERVICE_HEADER -#define P3_CIRCLES_SERVICE_HEADER - - -#include "retroshare/rscircles.h" // External Interfaces. -#include "gxs/rsgenexchange.h" // GXS service. -#include "gxs/rsgixs.h" // Internal Interfaces. - -#include -#include - -/* - * Circles Identity Service - * - * A collection of notes: - * - * We want to be able to express the following types of Circles. - * - * - Public - * - Groups & Messages can be passed onto anyone. ( No Restrictions. ) - * - GXS Notes: - * - This is what we have currently. - * - * - External Circle - * - List of Identities that can receive the Group / Messages. - * - This list will be defined via a set of RsIdentities - which have PGPHashes set. - * - We need the PGPHashes to be able to identify which peers can receive msgs. - * - Messages are passed to the Intersection of (Identified PGPHashes & Friends) - * - Distribution of Circle Definitions can be also be restricted via circles. - * - You can have Public External Groups, or Groups that only the Members know about. - * - Control of these External Groups is determined by Admin / Publish Keys. - * - The Danger with External Groups, is your ID wll be associated with other people... - * - Leaking information!!! - * - GXS Notes: - * - p3Circles will provide a distrib list for a given Circle Group. - * - * - Personal Circle or "Your Eyes Only". - * - Same as an Internal Circle Definition. (What will be used for File Sharing initially) - * - Each peer will have a bunch of these, Friends, Family, etc. - * - * - The list is not publically shared, only the originator of the message will distribute. - * - You can communicate back to the originator, who will share with the other members. - * but you mustn't discuss / share content with anyone else. - * - This is quite a Weak / Fragile Group, as there is only one distributor. - * - GXS NOTES: - * - TO make this work, we need GXS or RsCircles to maintain extra info: - * - GXS stores the original source, so communications can go back there. - * - If Originator, GXS store a REFERENCE, Circles turn this into a distrib list of peers. - * - * - * - * Like RsIdentities are used to validation messages, - * RsCircles will be used to determine if a peer can receive a group / messages. - * - * bool RsCircles::canSend(RsCircleId, RsPeerId) - * bool RsCircles::canSend(RsCircleInternalId, RsPeerId) - * - * or maybe just: - * - * bool RsCircles::recipients(GxsPermission &perms, std::list friendlist); - * - */ - - -/* Permissions is part of GroupMetaData - */ - -#define GXS_PERM_TYPE_PUBLIC 0x0001 -#define GXS_PERM_TYPE_EXTERNAL 0x0002 -#define GXS_PERM_TYPE_YOUREYESONLY 0x0003 - -class GxsPermissions -{ -public: - uint32_t mType; // PUBLIC, EXTERNAL or YOUREYESONLY, Mutually exclusive. - RsCircleId mCircleId; // If EXTERNAL, otherwise Blank. - - // BELOW IS NOT SERIALISED - BUT MUST BE STORED LOCALLY BY GXS. (If YOUREYESONLY) - RsPeerId mOriginator; - RsCircleInternalId mInternalCircle; // if Originator == ownId, otherwise blank. -}; - - -class RsGxsCircleGroup -{ - public: - GroupMetaData mMeta; // includes GxsPermissions, for control of group distribution. - - std::list mMembers; - std::list mCircleMembers; - - - // Not Serialised. - // Internally inside rsCircles, this will be turned into: - // std::list mAllowedFriends; -}; - - - - - -class rsCircle -{ -public: - - /* GXS Interface - for working out who can receive */ - - bool canSend(RsCircleId, RsPeerId) - bool canSend(RsCircleInternalId, RsPeerId) - bool recipients(GxsPermission &perms, std::list friendlist); - - /* Functions to handle Local / Internal Circles == Same as for file permissions. */ - createLocalCircle() - addToLocalCircle() - removeFromLocalCircle() - getLocalCirclePeers() - getListOfLocalCircles() - - /* similar functions for External Groups */ - virtual bool createGroup(uint32_t& token, RsGxsCircleGroup &group); - virtual bool getGroupData(const uint32_t &token, std::vector &groups); - - - -} - - - - - - -/*** IGNORE BELOW HERE *****/ - -class p3Circles: public RsGxsCircleExchange, public RsCircles -{ - public: - p3Circles(RsGeneralDataService* gds, RsNetworkExchangeService* nes); - - virtual void service_tick(); // needed for background processing. - - - /* General Interface is provided by RsIdentity / RsGxsIfaceImpl. */ - - /* Data Specific Interface */ - - // These are exposed via RsIdentity. -virtual bool getGroupData(const uint32_t &token, std::vector &groups); - - // These are local - and not exposed via RsIdentity. -virtual bool getMsgData(const uint32_t &token, std::vector &opinions); -virtual bool createGroup(uint32_t& token, RsGxsIdGroup &group); -virtual bool createMsg(uint32_t& token, RsGxsIdOpinion &opinion); - - /**************** RsIdentity External Interface. - * Notes: - */ - - /**************** RsGixs Implementation - * Notes: - * Interface is only suggestion at the moment, will be changed as necessary. - * Results should be cached / preloaded for maximum speed. - * - */ - - /**************** RsGixsReputation Implementation - * Notes: - * Again should be cached if possible. - */ - - - protected: - - /** Notifications **/ - virtual void notifyChanges(std::vector& changes); - - private: - -}; - -#endif // P3_IDENTITY_SERVICE_HEADER - - - diff --git a/libretroshare/src/services/p3gxscircles.cc b/libretroshare/src/services/p3gxscircles.cc new file mode 100644 index 000000000..ae2525639 --- /dev/null +++ b/libretroshare/src/services/p3gxscircles.cc @@ -0,0 +1,1305 @@ +/* + * libretroshare/src/services p3gxscircles.cc + * + * Circles Interface for RetroShare. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#include "services/p3gxscircles.h" +#include "serialiser/rsgxscircleitems.h" +#include "gxs/rsgxsflags.h" +#include "util/rsrandom.h" +#include "util/rsstring.h" + +#include "pqi/authgpg.h" + +#include + +#include +#include + +/**** + * #define ID_DEBUG 1 + ****/ + +RsGxsCircles *rsGxsCircles = NULL; + +/****** + * + * GxsCircles are used to limit the spread of Gxs Groups and Messages. + * + * This is done via GxsCircle parameters in GroupMetaData: + * mCircleType (ALL, External, Internal). + * mCircleId. + * + * The Circle Group contains the definition of who is allowed access to the Group. + * and GXS asks this service before forwarding any data. + * + * The CircleGroup contains: + * list of GxsId's + * list of GxsCircleId's (subcircles also allowed). + * + * This service runs a background task to transform the CircleGroups + * into a list of friends/peers who are allowed access. + * These results are cached to provide GXS with quick access to the information. + * This involves: + * - fetching the GroupData via GXS. + * - querying the list of GxsId to see if they are known. + * (NB: this will cause caching of GxsId in p3IdService. + * - recursively loading subcircles to complete Circle definition. + * - saving the result into Cache. + * + * For Phase 1, we will only use the list of GxsIds. No subcircles will be allowed. + * Recursively determining membership via sub-circles is complex and needs more thought. + * The data-types for the full system, however, will be in-place. + */ + + +#define CIRCLEREQ_CACHELOAD 0x0001 +#define CIRCLEREQ_CACHEOWNIDS 0x0002 + +#define CIRCLEREQ_PGPHASH 0x0010 +#define CIRCLEREQ_REPUTATION 0x0020 + +#define CIRCLEREQ_CACHETEST 0x1000 + +// Events. +#define CIRCLE_EVENT_CACHEOWNIDS 0x0001 +#define CIRCLE_EVENT_CACHELOAD 0x0002 +#define CIRCLE_EVENT_RELOADIDS 0x0003 + + +#define CIRCLE_EVENT_CACHETEST 0x1000 +#define CACHETEST_PERIOD 60 +#define OWNID_RELOAD_DELAY 10 + +#define GXSID_LOAD_CYCLE 10 // GXSID completes a load in this period. + +#define MIN_CIRCLE_LOAD_GAP 5 + +/********************************************************************************/ +/******************* Startup / Tick ******************************************/ +/********************************************************************************/ + +p3GxsCircles::p3GxsCircles(RsGeneralDataService *gds, RsNetworkExchangeService *nes, p3IdService *identities) + : RsGxsCircleExchange(gds, nes, new RsGxsCircleSerialiser(), + RS_SERVICE_GXSV1_TYPE_GXSCIRCLE, identities, circleAuthenPolicy()), + RsGxsCircles(this), GxsTokenQueue(this), RsTickEvent(), mIdentities(identities), + mCircleMtx("p3GxsCircles"), + mCircleCache(DEFAULT_MEM_CACHE_SIZE, "GxsCircleCache") + +{ + // Kick off Cache Testing, + Others. + RsTickEvent::schedule_in(CIRCLE_EVENT_CACHETEST, CACHETEST_PERIOD); + //RsTickEvent::schedule_now(CIRCLE_EVENT_CACHEOWNIDS); +} + + +uint32_t p3GxsCircles::circleAuthenPolicy() +{ + return 0; +} + +void p3GxsCircles::service_tick() +{ + RsTickEvent::tick_events(); + GxsTokenQueue::checkRequests(); // GxsTokenQueue handles all requests. + return; +} + +void p3GxsCircles::notifyChanges(std::vector &changes) +{ + std::cerr << "p3GxsCircles::notifyChanges()"; + std::cerr << std::endl; + + receiveChanges(changes); +} + +/********************************************************************************/ +/******************* RsCircles Interface ***************************************/ +/********************************************************************************/ + + +#if 0 +bool p3GxsCircles:: getNickname(const RsGxsId &id, std::string &nickname) +{ + return false; +} + +bool p3GxsCircles:: getIdDetails(const RsGxsId &id, RsIdentityDetails &details) +{ + std::cerr << "p3GxsCircles::getIdDetails(" << id << ")"; + std::cerr << std::endl; + + { + RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ + RsGxsIdCache data; + if (mPublicKeyCache.fetch(id, data)) + { + details = data.details; + return true; + } + + /* try private cache too */ + if (mPrivateKeyCache.fetch(id, data)) + { + details = data.details; + return true; + } + } + + /* it isn't there - add to public requests */ + cache_request_load(id); + + return false; +} + + +bool p3GxsCircles:: getOwnIds(std::list &ownIds) +{ + RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ + ownIds = mOwnIds; + + return true; +} + + +// +bool p3GxsCircles::submitOpinion(uint32_t& token, RsIdOpinion &opinion) +{ + return false; +} + +bool p3GxsCircles::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) +{ + + RsGxsIdGroup id; + + id.mMeta.mGroupName = params.nickname; + if (params.isPgpLinked) + { + id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID; + } + else + { + id.mMeta.mGroupFlags = 0; + } + + createGroup(token, id); + + return true; +} +#endif + + +/********************************************************************************/ +/******************* RsGixs Interface ***************************************/ +/********************************************************************************/ + +bool p3GxsCircles::isLoaded(const RsGxsCircleId &circleId) +{ + RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ + return mCircleCache.is_cached(circleId); +} + +bool p3GxsCircles::loadCircle(const RsGxsCircleId &circleId) +{ + return cache_request_load(circleId); +} + +int p3GxsCircles::canSend(const RsGxsCircleId &circleId, const RsPgpId &id) +{ + RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ + if (mCircleCache.is_cached(circleId)) + { + RsGxsCircleCache &data = mCircleCache.ref(circleId); + if (data.isAllowedPeer(id)) + { + return 1; + } + return 0; + } + return -1; +} + +bool p3GxsCircles::recipients(const RsGxsCircleId &circleId, std::list &friendlist) +{ + RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ + if (mCircleCache.is_cached(circleId)) + { + RsGxsCircleCache &data = mCircleCache.ref(circleId); + data.getAllowedPeersList(friendlist); + return true; + } + return false; +} + +/********************************************************************************/ +/******************* Get/Set Data ******************************************/ +/********************************************************************************/ + +bool p3GxsCircles::getGroupData(const uint32_t &token, std::vector &groups) +{ + + std::vector grpData; + bool ok = RsGenExchange::getGroupData(token, grpData); + + if(ok) + { + std::vector::iterator vit = grpData.begin(); + + for(; vit != grpData.end(); vit++) + { + RsGxsCircleGroupItem* item = dynamic_cast(*vit); + RsGxsCircleGroup group = item->group; + group.mMeta = item->meta; + + // If its cached - add that info (TODO). + groups.push_back(group); + } + } + + return ok; +} + +/********************************************************************************/ +/********************************************************************************/ +/********************************************************************************/ + +bool p3GxsCircles::createGroup(uint32_t& token, RsGxsCircleGroup &group) +{ + RsGxsCircleGroupItem* item = new RsGxsCircleGroupItem(); + item->group = group; + item->meta = group.mMeta; + RsGenExchange::publishGroup(token, item); + return true; +} + +void p3GxsCircles::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& /*keySet*/) +{ + RsGxsCircleGroupItem *item = dynamic_cast(grpItem); + if (!item) + { + std::cerr << "p3GxsCircles::service_CreateGroup() ERROR invalid cast"; + std::cerr << std::endl; + return; + } + + // Now copy the GroupId into the mCircleId, and set the mode. + // TODO. +#ifdef HAVE_CIRCLE_META_DATA + grpItem->meta.mCircleType = EXTERNAL; + grpItem->meta.mCircleId = grpItem->meta.mGroupId; + + grpItem->group.mMeta.mCircleType = grpItem->meta.mCircleType; + grpItem->group.mMeta.mCircleId = grpItem->meta.mCircleId; +#endif + +} + + + +/************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ + +/* + * Cache of recently used circles. + */ + +RsGxsCircleCache::RsGxsCircleCache() +{ + return; +} + + +bool RsGxsCircleCache::loadBaseCircle(const RsGxsCircleGroup &circle) +{ + + mCircleId = circle.mMeta.mGroupId; + mUpdateTime = time(NULL); + mProcessedCircles.insert(mCircleId); + + std::cerr << "RsGxsCircleCache::loadBaseCircle(" << mCircleId << ")"; + std::cerr << std::endl; + + return true; +} + +bool RsGxsCircleCache::loadSubCircle(const RsGxsCircleCache &subcircle) +{ + /* copy across all the lists */ + + /* should not be any unprocessed circles or peers */ + std::cerr << "RsGxsCircleCache::loadSubCircle(" << subcircle.mCircleId << ") TODO"; + std::cerr << std::endl; + + return true; +} + +bool RsGxsCircleCache::getAllowedPeersList(std::list &friendlist) +{ + std::map >::iterator it; + for(mAllowedPeers.begin(); it != mAllowedPeers.end(); it++) + { + friendlist.push_back(it->first); + } + return true; +} + +bool RsGxsCircleCache::isAllowedPeer(const RsPgpId &id) +{ + std::map >::iterator it = mAllowedPeers.find(id); + if (it != mAllowedPeers.end()) + { + return true; + } + return false; +} + +bool RsGxsCircleCache::addAllowedPeer(const RsPgpId &pgpId, const RsGxsId &gxsId) +{ + /* created if doesn't exist */ + std::list &gxsList = mAllowedPeers[pgpId]; + gxsList.push_back(gxsId); + return true; +} + + + + +/****************************************************************************/ +// ID STUFF. \/ \/ \/ \/ \/ \/ \/ :) +/****************************************************************************/ +#if 0 + +/************************************************************************************/ +/************************************************************************************/ + +bool p3GxsCircles::cache_request_ownids() +{ + /* trigger request to load missing ids into cache */ + std::list groupIds; + std::cerr << "p3GxsCircles::cache_request_ownids()"; + std::cerr << std::endl; + + uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + //opts.mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; + + uint32_t token = 0; + + RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts); + GxsTokenQueue::queueRequest(token, CIRCLEREQ_CACHEOWNIDS); + return 1; +} + + +bool p3GxsCircles::cache_load_ownids(uint32_t token) +{ + std::cerr << "p3GxsCircles::cache_load_ownids() : " << token; + std::cerr << std::endl; + + std::vector grpData; + bool ok = RsGenExchange::getGroupData(token, grpData); + + if(ok) + { + std::vector::iterator vit = grpData.begin(); + + // Save List + { + RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ + + mOwnIds.clear(); + for(vit = grpData.begin(); vit != grpData.end(); vit++) + { + RsGxsIdGroupItem* item = dynamic_cast(*vit); + + + if (item->meta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) + { + mOwnIds.push_back(item->meta.mGroupId); + } + } + } + + // Cache Items too. + for(vit = grpData.begin(); vit != grpData.end(); vit++) + { + RsGxsIdGroupItem* item = dynamic_cast(*vit); + if (item->meta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) + { + + std::cerr << "p3GxsCircles::cache_load_ownids() Loaded Id with Meta: "; + std::cerr << item->meta; + std::cerr << std::endl; + + /* cache the data */ + cache_store(item); + } + delete item; + } + + } + else + { + std::cerr << "p3GxsCircles::cache_load_ownids() ERROR no data"; + std::cerr << std::endl; + + return false; + } + return true; +} + + +/************************************************************************************/ +/************************************************************************************/ + +bool p3GxsCircles::cachetest_getlist() +{ + std::cerr << "p3GxsCircles::cachetest_getlist() making request"; + std::cerr << std::endl; + + uint32_t ansType = RS_TOKREQ_ANSTYPE_LIST; + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; + uint32_t token = 0; + + RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts); + GxsTokenQueue::queueRequest(token, CIRCLEREQ_CACHETEST); + + // Schedule Next Event. + RsTickEvent::schedule_in(CIRCLE_EVENT_CACHETEST, CACHETEST_PERIOD); + return true; +} + +bool p3GxsCircles::cachetest_handlerequest(uint32_t token) +{ + std::cerr << "p3GxsCircles::cachetest_handlerequest() token: " << token; + std::cerr << std::endl; + + std::list grpIds; + bool ok = RsGenExchange::getGroupList(token, grpIds); + + if(ok) + { + std::list::iterator vit = grpIds.begin(); + for(; vit != grpIds.end(); vit++) + { + /* 5% chance of checking it! */ + if (RSRandom::random_f32() < 0.25) + { + std::cerr << "p3GxsCircles::cachetest_request() Testing Id: " << *vit; + std::cerr << std::endl; + + /* try the cache! */ + if (!haveKey(*vit)) + { + std::list nullpeers; + requestKey(*vit, nullpeers); + + std::cerr << "p3GxsCircles::cachetest_request() Requested Key Id: " << *vit; + std::cerr << std::endl; + } + else + { + RsTlvSecurityKey seckey; + if (getKey(*vit, seckey)) + { + std::cerr << "p3GxsCircles::cachetest_request() Got Key OK Id: " << *vit; + std::cerr << std::endl; + + // success! + seckey.print(std::cerr, 10); + std::cerr << std::endl; + + + } + else + { + std::cerr << "p3GxsCircles::cachetest_request() ERROR no Key for Id: " << *vit; + std::cerr << std::endl; + } + } + + /* try private key too! */ + if (!havePrivateKey(*vit)) + { + requestPrivateKey(*vit); + std::cerr << "p3GxsCircles::cachetest_request() Requested PrivateKey Id: " << *vit; + std::cerr << std::endl; + } + else + { + RsTlvSecurityKey seckey; + if (getPrivateKey(*vit, seckey)) + { + // success! + std::cerr << "p3GxsCircles::cachetest_request() Got PrivateKey OK Id: " << *vit; + std::cerr << std::endl; + } + else + { + std::cerr << "p3GxsCircles::cachetest_request() ERROR no PrivateKey for Id: " << *vit; + std::cerr << std::endl; + } + } + } + } + } + else + { + std::cerr << "p3GxsCircles::cache_load_for_token() ERROR no data"; + std::cerr << std::endl; + + return false; + } + return true; +} + +/****************************************************************************/ +// ID STUFF. /\ /\ /\ /\ /\ /\ /\ /\ :) +/****************************************************************************/ +#endif + + + +/************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ +// Complicated deal of loading Circles. + + +bool p3GxsCircles::cache_request_load(const RsGxsCircleId &id) +{ + std::cerr << "p3GxsCircles::cache_request_load(" << id << ")"; + std::cerr << std::endl; + + { + RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ + + /* check its not loaded */ + if (mCircleCache.is_cached(id)) + return true; + + /* check it is not already being loaded */ + std::map::iterator it; + it = mLoadingCache.find(id); + if (it != mLoadingCache.end()) + { + // Already loading. + return true; + } + // Put it into the Loading Cache - so we will detect it later. + mLoadingCache[id] = RsGxsCircleCache(); + mCacheLoad_ToCache.push_back(id); + } + + if (RsTickEvent::event_count(CIRCLE_EVENT_CACHELOAD) > 0) + { + /* its already scheduled */ + return true; + } + + int32_t age = 0; + if (RsTickEvent::prev_event_ago(CIRCLE_EVENT_CACHELOAD, age)) + { + if (age < MIN_CIRCLE_LOAD_GAP) + { + RsTickEvent::schedule_in(CIRCLE_EVENT_CACHELOAD, + MIN_CIRCLE_LOAD_GAP - age); + return true; + } + } + + RsTickEvent::schedule_now(CIRCLE_EVENT_CACHELOAD); + return true; +} + + +bool p3GxsCircles::cache_start_load() +{ + /* trigger request to load missing ids into cache */ + std::list groupIds; + { + RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ + + /* now we process the modGroupList -> a map so we can use it easily later, and create id list too */ + std::list::iterator it; + for(it = mCacheLoad_ToCache.begin(); it != mCacheLoad_ToCache.end(); it++) + { + std::cerr << "p3GxsCircles::cache_start_load() GroupId: " << *it; + std::cerr << std::endl; + groupIds.push_back(*it); // might need conversion? + } + + mCacheLoad_ToCache.clear(); + } + + if (groupIds.size() > 0) + { + std::cerr << "p3GxsCircles::cache_start_load() #Groups: " << groupIds.size(); + std::cerr << std::endl; + + uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + uint32_t token = 0; + + RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts, groupIds); + GxsTokenQueue::queueRequest(token, CIRCLEREQ_CACHELOAD); + } + return 1; +} + + +bool p3GxsCircles::cache_load_for_token(uint32_t token) +{ + std::cerr << "p3GxsCircles::cache_load_for_token() : " << token; + std::cerr << std::endl; + + std::vector grpData; + bool ok = RsGenExchange::getGroupData(token, grpData); + + if(ok) + { + std::vector::iterator vit = grpData.begin(); + + for(; vit != grpData.end(); vit++) + { + RsGxsCircleGroupItem *item = dynamic_cast(*vit); + RsGxsCircleGroup group = item->group; + group.mMeta = item->meta; + + std::cerr << "p3GxsCircles::cache_load_for_token() Loaded Id with Meta: "; + std::cerr << item->meta; + std::cerr << std::endl; + + + RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ + + /* should already have a LoadingCache entry */ + RsGxsCircleId id = item->meta.mGroupId; + std::map::iterator it; + it = mLoadingCache.find(id); + if (it == mLoadingCache.end()) + { + // ERROR. + continue; + } + + RsGxsCircleCache &cache = it->second; + cache.loadBaseCircle(group); + delete item; + + bool isComplete = true; + bool isUnprocessedPeers = false; + + std::list &peers = group.mInvitedMembers; + std::list::const_iterator pit; + + // need to trigger the searches. + for(pit = peers.begin(); pit != peers.end(); pit++) + { + /* check cache */ + if (mIdentities->haveKey(*pit)) + { + /* we can process now! */ + RsIdentityDetails details; + if (mIdentities->getIdDetails(*pit, details)) + { + if (details.mPgpLinked && details.mPgpKnown) + { + cache.addAllowedPeer(details.mPgpId, *pit); + } + else + { + cache.mUnknownPeers.insert(*pit); + } + } + else + { + // ERROR. + } + } + else + { + /* store in to_process queue. */ + cache.mUnprocessedPeers.insert(*pit); + + isComplete = false; + isUnprocessedPeers = true; + } + } + +#ifdef HANDLE_SUBCIRCLES +#if 0 + std::list &circles = group.mSubCircles; + std::list::const_iterator cit; + for(cit = circles.begin(); cit != circles.end(); cit++) + { + /* if its cached already -> then its complete. */ + if (mCircleCache.is_loaded(*cit)) + { + RsGxsCircleCache cachedCircle; + if (mCircleCache.fetch(&cit, cachedCircle)) + { + /* copy cached circle into circle */ + cache.loadSubCircle(cachedCircle); + } + else + { + /* error */ + continue; + } + } + else + { + /* push into secondary processing queues */ + std::list &proc_circles = mCacheLoad_SubCircle[*cit]; + proc_circles.push_back(id); + + subCirclesToLoad.push_back(*cit); + + isComplete = false; + isUnprocessedCircles = true; + } + } +#endif +#endif + + if (isComplete) + { + /* move straight into the cache */ + mCircleCache.store(id, cache); + mCircleCache.resize(); + + /* remove from loading queue */ + mLoadingCache.erase(it); + } + + if (isUnprocessedPeers) + { + /* schedule event to try reload gxsIds */ + RsTickEvent::schedule_in(CIRCLE_EVENT_RELOADIDS, GXSID_LOAD_CYCLE, id); + } + } + } + else + { + std::cerr << "p3GxsCircles::cache_load_for_token() ERROR no data"; + std::cerr << std::endl; + + return false; + } + +#ifdef HANDLE_SUBCIRCLES +#if 0 + if (!subCirclesToLoad.empty()) + { + /* request load of subcircles */ + + + } +#endif +#endif + return true; +} + + +bool p3GxsCircles::cache_reloadids(const std::string &circleId) +{ + RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ + + /* fetch from loadMap */ + std::map::iterator it; + it = mLoadingCache.find(circleId); + if (it == mLoadingCache.end()) + { + // ERROR + return false; + } + + RsGxsCircleCache &cache = it->second; + + /* try reload Ids */ + std::set::const_iterator pit; + for(pit = cache.mUnprocessedPeers.begin(); + pit != cache.mUnprocessedPeers.end(); pit++) + { + /* check cache */ + if (mIdentities->haveKey(*pit)) + { + /* we can process now! */ + RsIdentityDetails details; + if (mIdentities->getIdDetails(*pit, details)) + { + if (details.mPgpLinked && details.mPgpKnown) + { + cache.addAllowedPeer(details.mPgpId, *pit); + } + else + { + cache.mUnknownPeers.insert(*pit); + } + } + else + { + // ERROR. + } + } + else + { + // UNKNOWN ID. + } + } + + // clear unprocessed List. + cache.mUnprocessedPeers.clear(); + + // If sub-circles are complete too. + if (cache.mUnprocessedCircles.empty()) + { + + // Push to Cache. + mCircleCache.store(circleId, cache); + mCircleCache.resize(); + + /* remove from loading queue */ + mLoadingCache.erase(it); + } + return true; +} + + + +#ifdef HANDLE_SUBCIRCLES +#if 0 +/**** TODO BELOW ****/ + +bool p3GxsCircles::cache_load_subcircles(uint32_t token) +{ + std::cerr << "p3GxsCircles::cache_load_subcircles() : " << token; + std::cerr << std::endl; + + std::vector grpData; + bool ok = RsGenExchange::getGroupData(token, grpData); + + if(ok) + { + std::vector::iterator vit = grpData.begin(); + + for(; vit != grpData.end(); vit++) + { + RsGxsIdGroupItem* item = dynamic_cast(*vit); + + RsGxsCircleId id = item->meta.mGroupId; + RsGxsCircleGroup group = item->group; + group.mMeta = item->meta; + delete item; + + std::cerr << "p3GxsCircles::cache_load_subcircles() Loaded Id with Meta: "; + std::cerr << item->meta; + std::cerr << std::endl; + + + RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ + + /* stage 2 of loading, load subcircles */ + std::map >::iterator sit; + sit = mCacheLoad_SubCircle.find(id) + if (sit == mCacheLoad_SubCircle.end()) + { + /* ERROR */ + continue; + } + + std::list updateCaches = sit->second; + // cleanup while we're here. + mCacheLoad_SubCircle.erase(sit); + + /* Now iterate through peers / subcircles, and apply + * - similarly to base load function + */ + + + RsGxsCircleCache &cache = it->second; + cache.loadBaseCircle(group); + + bool isComplete = true; + + std::list &peers = group.peers; + std::list::const_iterator pit; + + // need to trigger the searches. + for(pit = peers.begin(); pit != peers.end(); pit++) + { + /* check cache */ + if (mIdentities->is_cached(*pit)) + { + /* we can process now! */ + RsIdentityDetails details; + if (mIdentities->getDetails(*pit, details)) + { + if (details.isPgpKnown) + { + // Problem - could have multiple GxsIds here! + // TODO. + //cache.mAllowedPeers[details.mPgpId] = *pit; + + for(uit = updateCaches.begin(); uit != updateCaches.end(); uit++) + { + /* fetch the cache - and update */ + mLoadingCache[id] = RsGxsCircleCache(); + std::map::iterator it; + it = mLoadingCache.find(id); + } + + } + else + { + //cache.mUnknownPeers.push_back(*pit); + } + } + else + { + // ERROR. + } + } + else + { + /* store in to_process queue. */ + cache.mUnprocessedPeers.push_back(*pit); + + if (isComplete) + { + /* store reference to update */ + isComplete = false; + mCacheLoad_KeyWait.push_back(id); + } + } + } + + std::list &circles = group.circles; + std::list::const_iterator cit; + for(cit = circles.begin(); cit != circles.end(); cit++) + { + /* if its cached already -> then its complete. */ + if (mCircleCache.is_loaded(*cit)) + { + RsGxsCircleCache cachedCircle; + if (mCircleCache.fetch(&cit, cachedCircle)) + { + /* copy cached circle into circle */ + cache.loadSubCircle(cachedCircle); + } + else + { + /* error */ + continue; + } + } + else + { + /* push into secondary processing queues */ + std::list &proc_circles = mCacheLoad_SubCircle[id]; + proc_circles.push_back(id); + + subCirclesToLoad.push_back(id); + + isComplete = false; + } + } + + if (isComplete) + { + /* move straight into the cache */ + mCircleCache.store(id, cache); + + /* remove from loading queue */ + mLoadingCache.erase(it); + } + } + } + else + { + std::cerr << "p3GxsCircles::cache_load_for_token() ERROR no data"; + std::cerr << std::endl; + + return false; + } + + if (!keysToLoad.empty()) + { + /* schedule event to try reload gxsIds */ + + } + + if (!subCirclesToLoad.empty()) + { + /* request load of subcircles */ + + + } + return true; +} + +#endif +#endif + + +/************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ + +std::string p3GxsCircles::genRandomId() +{ + std::string randomId; + for(int i = 0; i < 20; i++) + { + randomId += (char) ('a' + (RSRandom::random_u32() % 26)); + } + + return randomId; +} + +void p3GxsCircles::generateDummyData() +{ + RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ + +#if 0 + /* grab all the gpg ids... and make some ids */ + + std::list gpgids; + std::list::iterator it; + + rsPeers->getGPGAllList(gpgids); + + std::string ownId = rsPeers->getGPGOwnId(); + gpgids.push_back(ownId); + + int genCount = 0; + int i; + for(it = gpgids.begin(); it != gpgids.end(); it++) + { + /* create one or two for each one */ + int nIds = 1 + (RSRandom::random_u32() % 2); + for(i = 0; i < nIds; i++) + { + RsGxsIdGroup id; + + RsPeerDetails details; + + //id.mKeyId = genRandomId(); + id.mMeta.mGroupId = genRandomId(); + id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID; + id.mPgpIdHash = genRandomId(); + id.mPgpIdSign = genRandomId(); + + if (rsPeers->getPeerDetails(*it, details)) + { + std::ostringstream out; + out << details.name << "_" << i + 1; + + //id.mNickname = out.str(); + id.mMeta.mGroupName = out.str(); + + + } + else + { + std::cerr << "p3GxsCircles::generateDummyData() missing" << std::endl; + std::cerr << std::endl; + + //id.mNickname = genRandomId(); + id.mMeta.mGroupName = genRandomId(); + } + + uint32_t dummyToken = 0; + createGroup(dummyToken, id); + +// LIMIT - AS GENERATION IS BROKEN. +#define MAX_TEST_GEN 5 + if (++genCount > MAX_TEST_GEN) + { + return; + } + } + } + return; + +#define MAX_RANDOM_GPGIDS 10 //1000 +#define MAX_RANDOM_PSEUDOIDS 50 //5000 + + int nFakeGPGs = (RSRandom::random_u32() % MAX_RANDOM_GPGIDS); + int nFakePseudoIds = (RSRandom::random_u32() % MAX_RANDOM_PSEUDOIDS); + + /* make some fake gpg ids */ + for(i = 0; i < nFakeGPGs; i++) + { + RsGxsCircleGroup id; + + RsPeerDetails details; + + id.mMeta.mGroupName = genRandomId(); + + id.mMeta.mGroupId = genRandomId(); + id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID; + id.mPgpIdHash = genRandomId(); + id.mPgpIdSign = genRandomId(); + + uint32_t dummyToken = 0; + createGroup(dummyToken, id); + } + + /* make lots of pseudo ids */ + for(i = 0; i < nFakePseudoIds; i++) + { + RsGxsIdGroup id; + + RsPeerDetails details; + + id.mMeta.mGroupName = genRandomId(); + + id.mMeta.mGroupId = genRandomId(); + id.mMeta.mGroupFlags = 0; + id.mPgpIdHash = ""; + id.mPgpIdSign = ""; + + + uint32_t dummyToken = 0; + createGroup(dummyToken, id); + } + + //mUpdated = true; +#endif + return; +} + + + +/************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ +/************************************************************************************/ + + +std::ostream &operator<<(std::ostream &out, const RsGxsIdGroup &grp) +{ + out << "RsGxsIdGroup: Meta: " << grp.mMeta; + out << " PgpIdHash: " << grp.mPgpIdHash; + out << " PgpIdSign: [binary]"; // << grp.mPgpIdSign; + out << std::endl; + + return out; +} + +std::ostream &operator<<(std::ostream &out, const RsGxsIdOpinion &opinion) +{ + out << "RsGxsIdOpinion: Meta: " << opinion.mMeta; + out << std::endl; + + return out; +} + + + + + + + + + + + // Overloaded from GxsTokenQueue for Request callbacks. +void p3GxsCircles::handleResponse(uint32_t token, uint32_t req_type) +{ + std::cerr << "p3GxsCircles::handleResponse(" << token << "," << req_type << ")"; + std::cerr << std::endl; + + // stuff. + switch(req_type) + { +#if 0 + case CIRCLEREQ_CACHEOWNIDS: + cache_load_ownids(token); + break; +#endif + case CIRCLEREQ_CACHELOAD: + cache_load_for_token(token); + break; + +#if 0 + case CIRCLEREQ_CACHETEST: + cachetest_handlerequest(token); + break; +#endif + + default: + /* error */ + std::cerr << "p3GxsCircles::handleResponse() Unknown Request Type: " << req_type; + std::cerr << std::endl; + break; + } +} + + + // Overloaded from RsTickEvent for Event callbacks. +void p3GxsCircles::handle_event(uint32_t event_type, const std::string &elabel) +{ + std::cerr << "p3GxsCircles::handle_event(" << event_type << ")"; + std::cerr << std::endl; + + // stuff. + switch(event_type) + { +#if 0 + case CIRCLE_EVENT_CACHEOWNIDS: + cache_request_ownids(); + break; +#endif + + case CIRCLE_EVENT_CACHELOAD: + cache_start_load(); + break; + + case CIRCLE_EVENT_RELOADIDS: + cache_reloadids(elabel); + break; + +#if 0 + case CIRCLE_EVENT_CACHETEST: + cachetest_getlist(); + break; +#endif + + default: + /* error */ + std::cerr << "p3GxsCircles::handle_event() Unknown Event Type: " << event_type; + std::cerr << std::endl; + break; + } +} + + + diff --git a/libretroshare/src/services/p3gxscircles.h b/libretroshare/src/services/p3gxscircles.h new file mode 100644 index 000000000..733c5d42c --- /dev/null +++ b/libretroshare/src/services/p3gxscircles.h @@ -0,0 +1,224 @@ +/* + * libretroshare/src/services: p3circles.h + * + * Identity interface for RetroShare. + * + * Copyright 2012-2012 by Robert Fernie. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "retroshare@lunamutt.com". + * + */ + +#ifndef P3_CIRCLES_SERVICE_HEADER +#define P3_CIRCLES_SERVICE_HEADER + + +#include "retroshare/rsgxscircles.h" // External Interfaces. +#include "gxs/rsgenexchange.h" // GXS service. +#include "gxs/rsgixs.h" // Internal Interfaces. + +#include "services/p3idservice.h" // For constructing Caches + +#include "gxs/gxstokenqueue.h" +#include "util/rstickevent.h" +#include "util/rsmemcache.h" + +#include +#include + +/* + * Circles Identity Service + * + * A collection of notes: + * + * We want to be able to express the following types of Circles. + * + * - Public + * - Groups & Messages can be passed onto anyone. ( No Restrictions. ) + * - GXS Notes: + * - This is what we have currently. + * + * - External Circle + * - List of Identities that can receive the Group / Messages. + * - This list will be defined via a set of RsIdentities - which have PGPHashes set. + * - We need the PGPHashes to be able to identify which peers can receive msgs. + * - Messages are passed to the Intersection of (Identified PGPHashes & Friends) + * - Distribution of Circle Definitions can be also be restricted via circles. + * - You can have Public External Groups, or Groups that only the Members know about. + * - Control of these External Groups is determined by Admin / Publish Keys. + * - The Danger with External Groups, is your ID wll be associated with other people... + * - Leaking information!!! + * - GXS Notes: + * - p3Circles will provide a distrib list for a given Circle Group. + * + * - Personal Circle or "Your Eyes Only". + * - Same as an Internal Circle Definition. (What will be used for File Sharing initially) + * - Each peer will have a bunch of these, Friends, Family, etc. + * + * - The list is not publically shared, only the originator of the message will distribute. + * - You can communicate back to the originator, who will share with the other members. + * but you mustn't discuss / share content with anyone else. + * - This is quite a Weak / Fragile Group, as there is only one distributor. + * - GXS NOTES: + * - TO make this work, we need GXS or RsCircles to maintain extra info: + * - GXS stores the original source, so communications can go back there. + * - If Originator, GXS store a REFERENCE, Circles turn this into a distrib list of peers. + * + * + * + * Like RsIdentities are used to validation messages, + * RsCircles will be used to determine if a peer can receive a group / messages. + * + * bool RsCircles::canSend(RsGxsCircleId, RsPeerId) + * bool RsCircles::canSend(RsCircleInternalId, RsPeerId) + * + * or maybe just: + * + * bool RsCircles::recipients(GxsPermission &perms, std::list friendlist); + * + */ + +/* Permissions is part of GroupMetaData + */ + +class RsGxsCircleCache +{ + public: + + RsGxsCircleCache(); + bool loadBaseCircle(const RsGxsCircleGroup &circle); + bool loadSubCircle(const RsGxsCircleCache &subcircle); + + bool getAllowedPeersList(std::list &friendlist); + bool isAllowedPeer(const RsPgpId &id); + bool addAllowedPeer(const RsPgpId &pgpid, const RsGxsId &gxsId); + + RsGxsCircleId mCircleId; + + time_t mUpdateTime; + std::set mUnprocessedCircles; + std::set mUnprocessedPeers; + + std::set mProcessedCircles; + std::set mUnknownPeers; + std::map > mAllowedPeers; +}; + + + +class RsCircles +{ + /* Functions to handle Local / Internal Circles == Same as for file permissions. */ +public: + virtual void createLocalCircle() = 0; + virtual void addToLocalCircle() = 0; + virtual void removeFromLocalCircle() = 0; + virtual void getLocalCirclePeers() = 0; + virtual void getListOfLocalCircles() = 0; + + /* similar functions for External Groups */ + virtual bool createGroup(uint32_t& token, RsGxsCircleGroup &group) = 0; + virtual bool getGroupData(const uint32_t &token, std::vector &groups) = 0; + +}; + + +class p3GxsCircles: public RsGxsCircleExchange, public RsGxsCircles, + public GxsTokenQueue, public RsTickEvent +{ + public: + p3GxsCircles(RsGeneralDataService* gds, RsNetworkExchangeService* nes, + p3IdService *identities); + + virtual void service_tick(); // needed for background processing. + + protected: + + static uint32_t circleAuthenPolicy(); + + /** Notifications **/ + virtual void notifyChanges(std::vector& changes); + + /** Overloaded to add PgpIdHash to Group Definition **/ + virtual void service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet); + + // Overloaded from GxsTokenQueue for Request callbacks. + virtual void handleResponse(uint32_t token, uint32_t req_type); + + // Overloaded from RsTickEvent. + virtual void handle_event(uint32_t event_type, const std::string &elabel); + + public: + + + virtual bool isLoaded(const RsGxsCircleId &circleId); + virtual bool loadCircle(const RsGxsCircleId &circleId); + + virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id); + virtual bool recipients(const RsGxsCircleId &circleId, std::list &friendlist); + + /*** External Interface */ + + virtual void createLocalCircle(); + virtual void addToLocalCircle(); + virtual void removeFromLocalCircle(); + virtual void getLocalCirclePeers(); + virtual void getListOfLocalCircles(); + + /* similar functions for External Groups */ + virtual bool createGroup(uint32_t& token, RsGxsCircleGroup &group); + virtual bool getGroupData(const uint32_t &token, std::vector &groups); + + private: + + // Need some crazy arsed cache to store the circle info. + // so we don't have to keep loading groups. + + int cache_tick(); + + bool cache_request_load(const RsGxsCircleId &id); + bool cache_start_load(); + bool cache_load_for_token(uint32_t token); + bool cache_reloadids(const std::string &circleId); + + + p3IdService *mIdentities; // Needed for constructing Circle Info, + + RsMutex mCircleMtx; /* Locked Below Here */ + + /***** Caching Circle Info, *****/ + // initial load queue + std::list mCacheLoad_ToCache; + + // waiting for subcircle to load. (first is part of each of the second list) + // TODO. + //std::map > mCacheLoad_SubCircle; + + // Circles that are being loaded. + std::map mLoadingCache; + + // actual cache. + RsMemCache mCircleCache; + + private: + +virtual void generateDummyData(); +std::string genRandomId(); + +}; + +#endif // P3_CIRCLES_SERVICE_HEADER diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index 6d301e9b1..67a34bba6 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -447,7 +447,7 @@ bool p3GxsForums::generateGroup(uint32_t &token, std::string groupName) // Overloaded from RsTickEvent for Event callbacks. -void p3GxsForums::handle_event(uint32_t event_type) +void p3GxsForums::handle_event(uint32_t event_type, const std::string &elabel) { std::cerr << "p3GxsForums::handle_event(" << event_type << ")"; std::cerr << std::endl; diff --git a/libretroshare/src/services/p3gxsforums.h b/libretroshare/src/services/p3gxsforums.h index 3b0a2f8d6..6205a229d 100644 --- a/libretroshare/src/services/p3gxsforums.h +++ b/libretroshare/src/services/p3gxsforums.h @@ -46,10 +46,15 @@ class p3GxsForums: public RsGenExchange, public RsGxsForums, p3GxsForums(RsGeneralDataService* gds, RsNetworkExchangeService* nes); +virtual void service_tick(); + protected: + virtual void notifyChanges(std::vector& changes); -virtual void service_tick(); + + // Overloaded from RsTickEvent. +virtual void handle_event(uint32_t event_type, const std::string &elabel); public: @@ -70,8 +75,6 @@ virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group); virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg); - // Overloaded from RsTickEvent. -virtual void handle_event(uint32_t event_type); private: diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index d8ec68db1..b8a1cac4f 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -109,7 +109,9 @@ RsIdentity *rsIdentity = NULL; p3IdService::p3IdService(RsGeneralDataService *gds, RsNetworkExchangeService *nes) : RsGxsIdExchange(gds, nes, new RsGxsIdSerialiser(), RS_SERVICE_GXSV1_TYPE_GXSID), - RsIdentity(this), GxsTokenQueue(this), RsTickEvent(), mIdMtx("p3IdService") + RsIdentity(this), GxsTokenQueue(this), RsTickEvent(), mIdMtx("p3IdService"), + mPublicKeyCache(DEFAULT_MEM_CACHE_SIZE, "GxsIdPublicKeyCache"), + mPrivateKeyCache(DEFAULT_MEM_CACHE_SIZE, "GxsIdPrivateKeyCache") { mBgSchedule_Mode = 0; mBgSchedule_Active = false; @@ -702,11 +704,13 @@ bool p3IdService::cache_store(const RsGxsIdGroupItem *item) // Create Cache Data. RsGxsIdCache pubcache(item, pubkey); mPublicKeyCache.store(id, pubcache); + mPublicKeyCache.resize(); if (full_key_ok) { RsGxsIdCache fullcache(item, fullkey); mPrivateKeyCache.store(id, fullcache); + mPrivateKeyCache.resize(); } return true; @@ -809,10 +813,6 @@ bool p3IdService::cache_load_for_token(uint32_t token) cache_store(item); delete item; } - - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mPrivateKeyCache.resize(); - mPublicKeyCache.resize(); } else { @@ -2430,7 +2430,7 @@ void p3IdService::handleResponse(uint32_t token, uint32_t req_type) // Overloaded from RsTickEvent for Event callbacks. -void p3IdService::handle_event(uint32_t event_type) +void p3IdService::handle_event(uint32_t event_type, const std::string &elabel) { std::cerr << "p3IdService::handle_event(" << event_type << ")"; std::cerr << std::endl; diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index 1a21e6d16..388afe7a3 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -221,13 +221,6 @@ virtual int getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key); virtual bool getReputation(const RsGxsId &id, const GixsReputation &rep); - - // Overloaded from GxsTokenQueue for Request callbacks. -virtual void handleResponse(uint32_t token, uint32_t req_type); - - // Overloaded from RsTickEvent. -virtual void handle_event(uint32_t event_type); - protected: /** Notifications **/ @@ -236,6 +229,12 @@ virtual void notifyChanges(std::vector& changes); /** Overloaded to add PgpIdHash to Group Definition **/ virtual void service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet); + // Overloaded from GxsTokenQueue for Request callbacks. +virtual void handleResponse(uint32_t token, uint32_t req_type); + + // Overloaded from RsTickEvent. +virtual void handle_event(uint32_t event_type, const std::string &elabel); + private: /************************************************************************ diff --git a/libretroshare/src/util/rsmemcache.h b/libretroshare/src/util/rsmemcache.h index cd7e96d21..283a50923 100644 --- a/libretroshare/src/util/rsmemcache.h +++ b/libretroshare/src/util/rsmemcache.h @@ -29,6 +29,7 @@ #include #include #include +#include /************************************************************************************/ /************************************************************************************/ @@ -49,11 +50,16 @@ template class RsMemCache { public: - RsMemCache(uint32_t max_size = DEFAULT_MEM_CACHE_SIZE) - :mDataCount(0), mMaxSize(max_size) { return; } + RsMemCache(uint32_t max_size = DEFAULT_MEM_CACHE_SIZE, std::string name = "UnknownMemCache") + :mDataCount(0), mMaxSize(max_size), mName(name) + { + clearStats(); + return; + } bool is_cached(const Key &key) const; bool fetch(const Key &key, Value &data); + Value &ref(const Key &key); // like map[] installs empty one if non-existent. bool store(const Key &key, const Value &data); bool resize(); // should be called periodically to cleanup old entries. @@ -80,6 +86,18 @@ template class RsMemCache std::multimap mLruMap; uint32_t mDataCount; uint32_t mMaxSize; + std::string mName; + + // some statistics. + void printStats(std::ostream &out); + void clearStats(); + + mutable uint32_t mStats_inserted; + mutable uint32_t mStats_dropped; + mutable uint32_t mStats_iscached; + mutable uint32_t mStats_cachemiss; + mutable uint32_t mStats_access; + mutable uint32_t mStats_accessmiss; }; @@ -92,10 +110,12 @@ template bool RsMemCache::is_cached(const Ke std::cerr << "RsMemCache::is_cached(" << key << ") false"; std::cerr << std::endl; + mStats_cachemiss++; return false; } std::cerr << "RsMemCache::is_cached(" << key << ") false"; std::cerr << std::endl; + mStats_iscached++; return true; } @@ -103,6 +123,7 @@ template bool RsMemCache::is_cached(const Ke template bool RsMemCache::fetch(const Key &key, Value &data) { + printStats(std::cerr); typename std::map::iterator it; it = mDataMap.find(key); if (it == mDataMap.end()) @@ -110,6 +131,7 @@ template bool RsMemCache::fetch(const Key &k std::cerr << "RsMemCache::fetch(" << key << ") false"; std::cerr << std::endl; + mStats_accessmiss++; return false; } @@ -125,13 +147,54 @@ template bool RsMemCache::fetch(const Key &k update_lrumap(key, old_ts, new_ts); + mStats_access++; return true; } + +template Value &RsMemCache::ref(const Key &key) +{ + printStats(std::cerr); + typename std::map::iterator it; + it = mDataMap.find(key); + if (it == mDataMap.end()) + { + std::cerr << "RsMemCache::ref(" << key << ") ERROR missing Key inserting Empty Data in LRU slot"; + std::cerr << std::endl; + + // insert operation. + time_t new_ts = 0; + Value data; + mDataMap[key] = cache_data(key, data, new_ts); + mDataCount++; + + update_lrumap(key, 0, new_ts); + it = mDataMap.find(key); + + mStats_accessmiss++; + } + else + { + std::cerr << "RsMemCache::ref(" << key << ") OK"; + std::cerr << std::endl; + + /* update ts on data */ + time_t old_ts = it->second.ts; + time_t new_ts = time(NULL); + it->second.ts = new_ts; + + update_lrumap(key, old_ts, new_ts); + + mStats_access++; + } + return it->second.data; +} + template bool RsMemCache::store(const Key &key, const Value &data) { std::cerr << "RsMemCache::store()"; std::cerr << std::endl; + printStats(std::cerr); /* update lrumap entry */ time_t old_ts = 0; @@ -148,13 +211,16 @@ template bool RsMemCache::store(const Key &k old_ts = it->second.ts; } - + else + { + mDataCount++; + } mDataMap[key] = cache_data(key, data, new_ts); - mDataCount++; update_lrumap(key, old_ts, new_ts); + mStats_inserted++; return true; } @@ -203,6 +269,7 @@ template bool RsMemCache::resize() { std::cerr << "RsMemCache::resize()"; std::cerr << std::endl; + printStats(std::cerr); int count_to_clear = 0; { @@ -259,6 +326,7 @@ template bool RsMemCache::discard_LRU(int co std::cerr << std::endl; mDataMap.erase(it); mDataCount--; + mStats_dropped++; } } else @@ -273,6 +341,39 @@ template bool RsMemCache::discard_LRU(int co return true; } +// These aren't templated functions. +template void RsMemCache::printStats(std::ostream &out) +{ + typename std::multimap::iterator mit = mLruMap.begin(); + time_t age = 0; + if (mit != mLruMap.end()) + { + age = time(NULL) - mit->first; + } + + out << "RsMemCache<" << mName << ">::printStats() Size: " << mDataCount << " Size2: " << mDataMap.size() << " Size3: " << mLruMap.size() << " MaxSize: " << mMaxSize << " LRU Age: " << age; + out << std::endl; + + out << "\tInsertions: " << mStats_inserted << " Drops: " << mStats_dropped; + out << std::endl; + + out << "\tCache Hits: " << mStats_iscached << " Misses: " << mStats_cachemiss; + out << std::endl; + + out << "\tAccess Hits: " << mStats_access << " Misses: " << mStats_accessmiss; + out << std::endl; +} + +template void RsMemCache::clearStats() +{ + mStats_inserted = 0; + mStats_dropped = 0; + mStats_iscached = 0; + mStats_cachemiss = 0; + mStats_access = 0; + mStats_accessmiss = 0; +} + diff --git a/libretroshare/src/util/rstickevent.cc b/libretroshare/src/util/rstickevent.cc index d0d39e9b0..f91b2edf5 100644 --- a/libretroshare/src/util/rstickevent.cc +++ b/libretroshare/src/util/rstickevent.cc @@ -67,16 +67,16 @@ void RsTickEvent::tick_events() } } - std::list toProcess; - std::list::iterator it; + std::list toProcess; + std::list::iterator it; { RsStackMutex stack(mEventMtx); /********** STACK LOCKED MTX ******/ while((!mEvents.empty()) && (mEvents.begin()->first <= now)) { - std::multimap::iterator it = mEvents.begin(); - uint32_t event_type = it->second; - toProcess.push_back(event_type); + std::multimap::iterator it = mEvents.begin(); + uint32_t event_type = it->second.mEventType; + toProcess.push_back(it->second); mEvents.erase(it); count_adjust_locked(event_type, -1); @@ -86,40 +86,53 @@ void RsTickEvent::tick_events() for(it = toProcess.begin(); it != toProcess.end(); it++) { std::cerr << "RsTickEvent::tick_events() calling handle_event("; - std::cerr << *it << ")"; + std::cerr << it->mEventType << ", " << it->mEventLabel << ")"; std::cerr << std::endl; - handle_event(*it); + handle_event(it->mEventType, it->mEventLabel); } } void RsTickEvent::schedule_now(uint32_t event_type) { - RsTickEvent::schedule_in(event_type, 0); + std::string elabel; + RsTickEvent::schedule_in(event_type, 0, elabel); } -void RsTickEvent::schedule_event(uint32_t event_type, time_t when) + +void RsTickEvent::schedule_now(uint32_t event_type, const std::string &elabel) +{ + RsTickEvent::schedule_in(event_type, 0, elabel); +} + +void RsTickEvent::schedule_event(uint32_t event_type, time_t when, const std::string &elabel) { RsStackMutex stack(mEventMtx); /********** STACK LOCKED MTX ******/ - mEvents.insert(std::make_pair(when, event_type)); + mEvents.insert(std::make_pair(when, EventData(event_type, elabel))); count_adjust_locked(event_type, 1); } void RsTickEvent::schedule_in(uint32_t event_type, uint32_t in_secs) { - std::cerr << "RsTickEvent::schedule_in(" << event_type << ") in " << in_secs << " secs"; - std::cerr << std::endl; - - RsStackMutex stack(mEventMtx); /********** STACK LOCKED MTX ******/ - time_t event_time = time(NULL) + in_secs; - mEvents.insert(std::make_pair(event_time, event_type)); - - count_adjust_locked(event_type, 1); + std::string elabel; + RsTickEvent::schedule_in(event_type, in_secs, elabel); } -void RsTickEvent::handle_event(uint32_t event_type) + +void RsTickEvent::schedule_in(uint32_t event_type, uint32_t in_secs, const std::string &elabel) { - std::cerr << "RsTickEvent::handle_event(" << event_type << ") ERROR Not Handled"; + std::cerr << "RsTickEvent::schedule_in(" << event_type << ", " << elabel << ") in " << in_secs << " secs"; + std::cerr << std::endl; + + time_t event_time = time(NULL) + in_secs; + RsTickEvent::schedule_event(event_type, event_time, elabel); +} + + +void RsTickEvent::handle_event(uint32_t event_type, const std::string &elabel) +{ + std::cerr << "RsTickEvent::handle_event(" << event_type << ", " << elabel; + std::cerr << ") ERROR Not Handled"; std::cerr << std::endl; } diff --git a/libretroshare/src/util/rstickevent.h b/libretroshare/src/util/rstickevent.h index 73786fe77..1b26c6b43 100644 --- a/libretroshare/src/util/rstickevent.h +++ b/libretroshare/src/util/rstickevent.h @@ -44,24 +44,41 @@ class RsTickEvent void tick_events(); void schedule_now(uint32_t event_type); -void schedule_event(uint32_t event_type, time_t when); +void schedule_now(uint32_t event_type, const std::string &elabel); + +void schedule_event(uint32_t event_type, time_t when, const std::string &elabel); + void schedule_in(uint32_t event_type, uint32_t in_secs); +void schedule_in(uint32_t event_type, uint32_t in_secs, const std::string &elabel); int32_t event_count(uint32_t event_type); bool prev_event_ago(uint32_t event_type, int32_t &age); + protected: + // Overloaded to handle the events. -virtual void handle_event(uint32_t event_type); +virtual void handle_event(uint32_t event_type, const std::string &event_label); private: + class EventData + { + public: + EventData() :mEventType(0) { return; } + EventData(uint32_t etype) :mEventType(etype) { return; } + EventData(uint32_t etype, std::string elabel) :mEventLabel(elabel), mEventType(etype) { return; } + + std::string mEventLabel; + uint32_t mEventType; + }; + void count_adjust_locked(uint32_t event_type, int32_t change); void note_event_locked(uint32_t event_type); RsMutex mEventMtx; std::map mEventCount; std::map mPreviousEvent; - std::multimap mEvents; + std::multimap mEvents; }; #endif // RS_UTIL_TICK_EVENT From 44d32626bcfa01b0e76b0bf13ffde7abe6aded12 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Fri, 30 Nov 2012 18:54:25 +0000 Subject: [PATCH 190/222] Added logic for rank calculation and interface methods Disabled posting when no post is selected Added notes section when viewing post (tres basic) fix for comment item serialisation fix for subscription token option not in this commit ;) git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5913 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/retroshare/rsposted.h | 37 +++- libretroshare/src/serialiser/rsposteditems.cc | 2 +- libretroshare/src/services/p3posted.cc | 127 ++++++++++++- libretroshare/src/services/p3posted.h | 51 ++++- .../src/gui/Posted/PostedComments.cpp | 14 +- .../src/gui/Posted/PostedComments.h | 6 +- .../src/gui/Posted/PostedComments.ui | 54 ++---- .../src/gui/gxs/GxsCommentTreeWidget.cpp | 177 +++++++++--------- .../src/gui/gxs/GxsCommentTreeWidget.h | 18 +- 9 files changed, 304 insertions(+), 182 deletions(-) diff --git a/libretroshare/src/retroshare/rsposted.h b/libretroshare/src/retroshare/rsposted.h index a10de0fef..3d0eb20fd 100644 --- a/libretroshare/src/retroshare/rsposted.h +++ b/libretroshare/src/retroshare/rsposted.h @@ -70,6 +70,7 @@ typedef std::map > PostedCommentResul typedef std::map > PostedVoteResult; typedef std::map > PostedRelatedCommentResult; typedef std::pair GroupRank; +typedef std::map PostedRanking; std::ostream &operator<<(std::ostream &out, const RsPostedGroup &group); std::ostream &operator<<(std::ostream &out, const RsPostedPost &post); @@ -81,6 +82,8 @@ class RsPosted : public RsGxsIfaceImpl { public: + enum RankType {TopRankType, BestRankType, NewRankType }; + static const uint32_t FLAG_MSGTYPE_POST; static const uint32_t FLAG_MSGTYPE_VOTE; static const uint32_t FLAG_MSGTYPE_COMMENT; @@ -91,19 +94,33 @@ virtual ~RsPosted() { return; } /* Specific Service Data */ -virtual bool getGroup(const uint32_t &token, std::vector &group) = 0; -virtual bool getPost(const uint32_t &token, PostedPostResult &post) = 0; -virtual bool getComment(const uint32_t &token, PostedCommentResult &comment) = 0; -virtual bool getRelatedComment(const uint32_t& token, PostedRelatedCommentResult& comments) = 0; -virtual bool getGroupRank(const uint32_t &token, GroupRank& grpRank) = 0; + virtual bool getGroup(const uint32_t &token, std::vector &group) = 0; + virtual bool getPost(const uint32_t &token, PostedPostResult &post) = 0; + virtual bool getComment(const uint32_t &token, PostedCommentResult &comment) = 0; + virtual bool getRelatedComment(const uint32_t& token, PostedRelatedCommentResult& comments) = 0; + virtual bool getRanking(const uint32_t& token, PostedRanking& ranking) = 0; -virtual bool submitGroup(uint32_t &token, RsPostedGroup &group) = 0; -virtual bool submitPost(uint32_t &token, RsPostedPost &post) = 0; -virtual bool submitVote(uint32_t &token, RsPostedVote &vote) = 0; -virtual bool submitComment(uint32_t &token, RsPostedComment &comment) = 0; + virtual bool submitGroup(uint32_t &token, RsPostedGroup &group) = 0; + virtual bool submitPost(uint32_t &token, RsPostedPost &post) = 0; + virtual bool submitVote(uint32_t &token, RsPostedVote &vote) = 0; + virtual bool submitComment(uint32_t &token, RsPostedComment &comment) = 0; // Special Ranking Request. -virtual bool requestRanking(uint32_t &token, RsGxsGroupId groupId) = 0; + /*! + * Makes request for posts of a topic + * @param token + * @param rType + * @param groupId + */ + virtual bool requestMessageRankings(uint32_t &token, const RankType& rType, const RsGxsGroupId& groupId) = 0; + + /*! + * Makes request for ranking of comments for a post + * @param token + * @param rType type of ranking to collect + * @param msgId message id of post as groupid-messageid pair + */ + virtual bool requestCommentRankings(uint32_t &token, const RankType& rType, const RsGxsGrpMsgIdPair& msgId) = 0; }; diff --git a/libretroshare/src/serialiser/rsposteditems.cc b/libretroshare/src/serialiser/rsposteditems.cc index 38421a8eb..5edc827ec 100644 --- a/libretroshare/src/serialiser/rsposteditems.cc +++ b/libretroshare/src/serialiser/rsposteditems.cc @@ -435,7 +435,7 @@ RsGxsPostedCommentItem* RsGxsPostedSerialiser::deserialiseGxsPostedCommentItem(v if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || (RS_SERVICE_GXSV1_TYPE_POSTED != getRsItemService(rstype)) || - (RS_PKT_SUBTYPE_POSTED_POST_ITEM != getRsItemSubType(rstype))) + (RS_PKT_SUBTYPE_POSTED_COMMENT_ITEM != getRsItemSubType(rstype))) { #ifdef GXS_POSTED_SERIAL_DEBUG std::cerr << "RsGxsPostedSerialiser::deserialiseGxsPostedCommentItem() FAIL wrong type" << std::endl; diff --git a/libretroshare/src/services/p3posted.cc b/libretroshare/src/services/p3posted.cc index d34e8f5ea..b67d334e7 100644 --- a/libretroshare/src/services/p3posted.cc +++ b/libretroshare/src/services/p3posted.cc @@ -14,7 +14,7 @@ RsPostedComment::RsPostedComment(const RsGxsPostedCommentItem & item) } p3Posted::p3Posted(RsGeneralDataService *gds, RsNetworkExchangeService *nes) - : RsGenExchange(gds, nes, new RsGxsPostedSerialiser(), RS_SERVICE_GXSV1_TYPE_POSTED), RsPosted(this) + : RsGenExchange(gds, nes, new RsGxsPostedSerialiser(), RS_SERVICE_GXSV1_TYPE_POSTED), RsPosted(this), mPostedMutex("Posted") { } @@ -129,11 +129,6 @@ bool p3Posted::getRelatedComment(const uint32_t& token, PostedRelatedCommentResu return RsGenExchange::getMsgRelatedDataT(token, comments); } -bool p3Posted::getGroupRank(const uint32_t &token, GroupRank &grpRank) -{ - -} - bool p3Posted::submitGroup(uint32_t &token, RsPostedGroup &group) { RsGxsPostedGroupItem* grpItem = new RsGxsPostedGroupItem(); @@ -177,7 +172,125 @@ bool p3Posted::submitComment(uint32_t &token, RsPostedComment &comment) } // Special Ranking Request. -bool p3Posted::requestRanking(uint32_t &token, RsGxsGroupId groupId) +bool p3Posted::requestCommentRankings(uint32_t &token, const RankType &rType, const RsGxsGrpMsgIdPair &msgId) +{ + token = RsGenExchange::generatePublicToken(); + + RsStackMutex stack(mPostedMutex); + + GxsPostedCommentRanking* gpc = new GxsPostedCommentRanking(); + gpc->msgId = msgId; + gpc->rType = rType; + gpc->pubToken = token; + + mPendingCommentRanks.insert(std::make_pair(token, gpc)); + + return true; +} + +bool p3Posted::requestMessageRankings(uint32_t &token, const RankType &rType, const RsGxsGroupId &groupId) +{ + token = RsGenExchange::generatePublicToken(); + + RsStackMutex stack(mPostedMutex); + GxsPostedPostRanking* gp = new GxsPostedPostRanking(); + gp->grpId = groupId; + gp->rType = rType; + gp->pubToken = token; + + mPendingPostRanks.insert(std::make_pair(token, gp)); + + return true; +} + +bool p3Posted::getRanking(const uint32_t &token, PostedRanking &ranking) +{ + +} + +void p3Posted::processRankings() +{ + processMessageRanks(); + + processCommentRanks(); +} + +void p3Posted::processMessageRanks() +{ + + RsStackMutex stack(mPostedMutex); + std::map::iterator mit =mPendingPostRanks.begin(); + + for(; mit !=mPendingPostRanks.begin(); mit++) + { + uint32_t token; + std::list grpL; + grpL.push_back(mit->second->grpId); + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST | RS_TOKREQOPT_MSG_THREAD; + RsGenExchange::getTokenService()->requestMsgInfo(token, GXS_REQUEST_TYPE_GROUP_DATA, opts, grpL); + GxsPostedPostRanking* gp = mit->second; + gp->reqToken = token; + + while(true) + { + uint32_t status = RsGenExchange::getTokenService()->requestStatus(token); + + if(RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE + == status) + { + completePostedPostCalc(gp); + break; + } + else if(RsTokenService::GXS_REQUEST_V2_STATUS_FAILED + == status) + { + discardCalc(token); + break; + } + } + } + + mPendingPostRanks.clear(); + + +} + +void p3Posted::discardCalc(const uint32_t &token) +{ + +} + +void p3Posted::completePostedPostCalc(GxsPostedPostRanking *gpp) +{ + GxsMsgMetaMap msgMetas; + getMsgMeta(gpp->reqToken, msgMetas); + + GxsMsgMetaMap::iterator mit = msgMetas.begin(); + + for(; mit != msgMetas.end(); mit++ ) + { + RsGxsMsgMetaData* m = NULL; + //retrieveScores(m->mServiceString, upVotes, downVotes, nComments); + + // then dependent on rank request type process for that way + } + + +} + +bool p3Posted::retrieveScores(const std::string &serviceString, uint32_t &upVotes, uint32_t downVotes, uint32_t nComments) +{ + if (2 == sscanf(serviceString.c_str(), "%d %d %d", &upVotes, &downVotes, &nComments)) + { + return true; + } + + return false; +} + +void p3Posted::processCommentRanks() { } diff --git a/libretroshare/src/services/p3posted.h b/libretroshare/src/services/p3posted.h index 78e6c9ea5..62d7b789b 100644 --- a/libretroshare/src/services/p3posted.h +++ b/libretroshare/src/services/p3posted.h @@ -1,9 +1,34 @@ #ifndef P3POSTED_H #define P3POSTED_H +#include + #include "retroshare/rsposted.h" #include "gxs/rsgenexchange.h" + +class GxsPostedPostRanking +{ +public: + + uint32_t pubToken; + uint32_t reqToken; + RsPosted::RankType rType; + RsGxsGroupId grpId; + PostedRanking result; +}; + +class GxsPostedCommentRanking +{ +public: + + uint32_t pubToken; + uint32_t reqToken; + RsPosted::RankType rType; + RsGxsGrpMsgIdPair msgId; + PostedRanking result; +}; + class p3Posted : public RsGenExchange, public RsPosted { public: @@ -30,20 +55,34 @@ public: bool getPost(const uint32_t &token, PostedPostResult& posts) ; bool getComment(const uint32_t &token, PostedCommentResult& comments) ; bool getRelatedComment(const uint32_t& token, PostedRelatedCommentResult &comments); - bool getGroupRank(const uint32_t& token, GroupRank& grpRank); + bool getRanking(const uint32_t &token, PostedRanking &ranking); bool submitGroup(uint32_t &token, RsPostedGroup &group); bool submitPost(uint32_t &token, RsPostedPost &post); bool submitVote(uint32_t &token, RsPostedVote &vote); bool submitComment(uint32_t &token, RsPostedComment &comment) ; // Special Ranking Request. - bool requestRanking(uint32_t &token, RsGxsGroupId groupId) ; + bool requestMessageRankings(uint32_t &token, const RankType &rType, const RsGxsGroupId &groupId); + bool requestCommentRankings(uint32_t &token, const RankType &rType, const RsGxsGrpMsgIdPair &msgId); - // Control Ranking Calculations. -// bool setViewMode(uint32_t mode); -// bool setViewPeriod(uint32_t period); -// bool setViewRange(uint32_t first, uint32_t count); +private: + void processRankings(); + void processMessageRanks(); + void processCommentRanks(); + void discardCalc(const uint32_t& token); + void completePostedPostCalc(GxsPostedPostRanking* gpp); + bool retrieveScores(const std::string& serviceString, uint32_t& upVotes, uint32_t downVotes, uint32_t nComments); + +private: + + std::map mPendingPostRanks; + std::map mPendingCalculationPostRanks; + + std::map mPendingCommentRanks; + std::map mPendingCalculationCommentRanks; + + RsMutex mPostedMutex; }; #endif // P3POSTED_H diff --git a/retroshare-gui/src/gui/Posted/PostedComments.cpp b/retroshare-gui/src/gui/Posted/PostedComments.cpp index 04c07e467..7ef6be1d7 100644 --- a/retroshare-gui/src/gui/Posted/PostedComments.cpp +++ b/retroshare-gui/src/gui/Posted/PostedComments.cpp @@ -63,14 +63,10 @@ PostedComments::PostedComments(QWidget *parent) ui.setupUi(this); ui.postFrame->setVisible(false); ui.treeWidget->setup(rsPosted->getTokenService()); - connect(ui.treeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(test(QPoint))); } -void PostedComments::test(QPoint p) +void PostedComments::loadRequest(const TokenQueue *queue, const TokenRequest &req) { - int x = p.x(); - int y = p.y(); - int c= x+y; } @@ -84,8 +80,8 @@ void PostedComments::loadComments(const RsPostedPost& post) RsGxsGrpMsgIdPair threadId; - threadId.first = post.mMeta.mOrigMsgId; - threadId.second = post.mMeta.mGroupId; + threadId.first = post.mMeta.mGroupId; + threadId.second = post.mMeta.mOrigMsgId; ui.treeWidget->requestComments(threadId); } @@ -107,7 +103,9 @@ void PostedComments::setUpPostFrame() ">" + QString::fromStdString(mCurrentPost.mLink) + ""); - ui.scoreLabel->setText(QString("1")); + ui.scoreLabel->setText(QString("0")); + + ui.notesBrowser->setPlainText(QString::fromStdString(mCurrentPost.mNotes)); } diff --git a/retroshare-gui/src/gui/Posted/PostedComments.h b/retroshare-gui/src/gui/Posted/PostedComments.h index 5bf557364..3053f18e1 100644 --- a/retroshare-gui/src/gui/Posted/PostedComments.h +++ b/retroshare-gui/src/gui/Posted/PostedComments.h @@ -44,12 +44,8 @@ public slots: void loadComments(const RsPostedPost& ); - private slots: - - void test(QPoint p); - private: - void loadRequest(const TokenQueue *queue, const TokenRequest &req) { return; } + void loadRequest(const TokenQueue *queue, const TokenRequest &req); void setUpPostFrame(); RsPostedPost mCurrentPost; diff --git a/retroshare-gui/src/gui/Posted/PostedComments.ui b/retroshare-gui/src/gui/Posted/PostedComments.ui index d06b8d0c1..817cc6ff7 100644 --- a/retroshare-gui/src/gui/Posted/PostedComments.ui +++ b/retroshare-gui/src/gui/Posted/PostedComments.ui @@ -23,10 +23,7 @@ - QFrame#frame{border: 2px solid #CCCCCC; -background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #EEEEEE, stop: 1 #CCCCCC); -border-radius: 10px} + background-color: rgb(203, 203, 203); QFrame::StyledPanel @@ -244,6 +241,13 @@ border-radius: 10px} + + + + background-color: rgb(203, 203, 203); + + + @@ -337,6 +341,11 @@ border-radius: 10px} Author + + + Date + + Points @@ -344,43 +353,6 @@ border-radius: 10px} - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Make Comment - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp index 4f32e04e0..5332e57e6 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp @@ -48,7 +48,7 @@ GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent) { // QTreeWidget* widget = this; - + setContextMenuPolicy(Qt::CustomContextMenu); // QFont font = QFont("ARIAL", 10); // font.setBold(true); @@ -73,34 +73,32 @@ void GxsCommentTreeWidget::setCurrentMsgId(QTreeWidgetItem *current, QTreeWidget if(current) { mCurrentMsgId = current->text(PCITEM_COLUMN_MSGID).toStdString(); - }else{ - mCurrentMsgId = ""; } } void GxsCommentTreeWidget::customPopUpMenu(const QPoint& point) { QMenu contextMnu( this ); - contextMnu.addAction(QIcon(IMAGE_MESSAGE), tr("Submit Comment"), this, SLOT(makeComment())); + QAction* action = contextMnu.addAction(QIcon(IMAGE_MESSAGE), tr("Reply to Comment"), this, SLOT(replyToComment())); + action->setDisabled(mCurrentMsgId.empty()); + action = contextMnu.addAction(QIcon(IMAGE_MESSAGE), tr("Submit Comment"), this, SLOT(makeComment())); + action->setDisabled(mThreadId.first.empty()); contextMnu.exec(QCursor::pos()); } void GxsCommentTreeWidget::makeComment() { + PostedCreateCommentDialog pcc(mTokenQueue, mThreadId, mThreadId.second, this); + pcc.exec(); +} - if(mCurrentMsgId.empty()) - { - PostedCreateCommentDialog pcc(mTokenQueue, mThreadId, mThreadId.second, this); - pcc.exec(); - } - else - { - RsGxsGrpMsgIdPair msgId; - msgId.first = mThreadId.first; - msgId.second = mCurrentMsgId; - PostedCreateCommentDialog pcc(mTokenQueue, msgId, mThreadId.second, this); - pcc.exec(); - } +void GxsCommentTreeWidget::replyToComment() +{ + RsGxsGrpMsgIdPair msgId; + msgId.first = mThreadId.first; + msgId.second = mCurrentMsgId; + PostedCreateCommentDialog pcc(mTokenQueue, msgId, mThreadId.second, this); + pcc.exec(); } void GxsCommentTreeWidget::setup(RsTokenService *service) @@ -125,100 +123,100 @@ void GxsCommentTreeWidget::requestComments(const RsGxsGrpMsgIdPair& threadId) void GxsCommentTreeWidget::service_requestComments(const RsGxsGrpMsgIdPair& threadId) { - /* request comments */ - std::cerr << "GxsCommentTreeWidget::service_requestComments(" << threadId.second << ")"; - std::cerr << std::endl; - - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; - - std::vector msgIds; - msgIds.push_back(threadId); - - uint32_t token; - mTokenQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, GXSCOMMENTS_LOADTHREAD); + /* request comments */ + std::cerr << "GxsCommentTreeWidget::service_requestComments(" << threadId.second << ")"; + std::cerr << std::endl; + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; + opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; + + std::vector msgIds; + msgIds.push_back(threadId); + + uint32_t token; + mTokenQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, GXSCOMMENTS_LOADTHREAD); } /* Generic Handling */ void GxsCommentTreeWidget::clearItems() { - mPendingInsertMap.clear(); - mLoadingMap.clear(); + mPendingInsertMap.clear(); + mLoadingMap.clear(); } void GxsCommentTreeWidget::completeItems() { - /* handle pending items */ - std::string parentId; - QTreeWidgetItem *parent = NULL; - QList topLevelItems; + /* handle pending items */ + std::string parentId; + QTreeWidgetItem *parent = NULL; + QList topLevelItems; - std::map::iterator lit; - std::multimap::iterator pit; + std::map::iterator lit; + std::multimap::iterator pit; - std::cerr << "GxsCommentTreeWidget::completeItems() " << mPendingInsertMap.size(); - std::cerr << " PendingItems"; - std::cerr << std::endl; + std::cerr << "GxsCommentTreeWidget::completeItems() " << mPendingInsertMap.size(); + std::cerr << " PendingItems"; + std::cerr << std::endl; - for(pit = mPendingInsertMap.begin(); pit != mPendingInsertMap.end(); pit++) - { - std::cerr << "GxsCommentTreeWidget::completeItems() item->parent: " << pit->first; - std::cerr << std::endl; + for(pit = mPendingInsertMap.begin(); pit != mPendingInsertMap.end(); pit++) + { + std::cerr << "GxsCommentTreeWidget::completeItems() item->parent: " << pit->first; + std::cerr << std::endl; - if (pit->first != parentId) - { - /* find parent */ - parentId = pit->first; - lit = mLoadingMap.find(pit->first); - if (lit != mLoadingMap.end()) - { - parent = lit->second; - } - else - { - parent = NULL; - } - } + if (pit->first != parentId) + { + /* find parent */ + parentId = pit->first; + lit = mLoadingMap.find(pit->first); + if (lit != mLoadingMap.end()) + { + parent = lit->second; + } + else + { + parent = NULL; + } + } - if (parent) - { - std::cerr << "GxsCommentTreeWidget::completeItems() Added to Parent"; - std::cerr << std::endl; + if (parent) + { + std::cerr << "GxsCommentTreeWidget::completeItems() Added to Parent"; + std::cerr << std::endl; - parent->addChild(pit->second); - } - else if (parentId == mThreadId.second) - { - std::cerr << "GxsCommentTreeWidget::completeItems() Added to topLevelItems"; - std::cerr << std::endl; + parent->addChild(pit->second); + } + else if (parentId == mThreadId.second) + { + std::cerr << "GxsCommentTreeWidget::completeItems() Added to topLevelItems"; + std::cerr << std::endl; - topLevelItems.append(pit->second); - } - else - { + topLevelItems.append(pit->second); + } + else + { - /* missing parent -> insert At Top Level */ - QTreeWidgetItem *missingItem = service_createMissingItem(pit->first); + /* missing parent -> insert At Top Level */ + QTreeWidgetItem *missingItem = service_createMissingItem(pit->first); - std::cerr << "GxsCommentTreeWidget::completeItems() Added MissingItem"; - std::cerr << std::endl; + std::cerr << "GxsCommentTreeWidget::completeItems() Added MissingItem"; + std::cerr << std::endl; - parent = missingItem; - parent->addChild(pit->second); - topLevelItems.append(parent); - } - } + parent = missingItem; + parent->addChild(pit->second); + topLevelItems.append(parent); + } + } - /* now push final tree into Tree */ - clear(); - insertTopLevelItems(0, topLevelItems); + /* now push final tree into Tree */ + clear(); + insertTopLevelItems(0, topLevelItems); - /* cleanup temp stuff */ - mLoadingMap.clear(); - mPendingInsertMap.clear(); + /* cleanup temp stuff */ + mLoadingMap.clear(); + mPendingInsertMap.clear(); } @@ -316,7 +314,8 @@ void GxsCommentTreeWidget::service_loadThread(const uint32_t &token) text = QString::fromUtf8(comment.mMeta.mParentId.c_str()); item->setText(PCITEM_COLUMN_PARENTID, text); - text = QString::fromUtf8(comment.mMeta.mServiceString.c_str()); + text = QString::fromUtf8("0"); + //text = QString::fromUtf8(comment.mMeta.mServiceString.c_str()); item->setText(PCITEM_COLUMN_SERVSTRING, text); addItem(comment.mMeta.mMsgId, comment.mMeta.mParentId, item); diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h index 448c2e324..f494e25e3 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h @@ -26,19 +26,6 @@ #include "util/TokenQueue.h" -/* indicies for search results item columns SR_ = Search Result */ -#define SR_NAME_COL 0 -#define SR_SIZE_COL 1 -#define SR_ID_COL 2 -#define SR_TYPE_COL 3 -#define SR_AGE_COL 4 -#define SR_HASH_COL 5 -#define SR_SEARCH_ID_COL 6 -#define SR_UID_COL 7 -#define SR_DATA_COL SR_NAME_COL - -#define SR_ROLE_LOCAL Qt::UserRole - class GxsCommentTreeWidget : public QTreeWidget, public TokenResponse { Q_OBJECT @@ -49,7 +36,7 @@ public: void requestComments(const RsGxsGrpMsgIdPair& threadId); void getCurrentMsgId(RsGxsMessageId& parentId); - void setCurrentMsgId(QTreeWidgetItem* current, QTreeWidgetItem* previous); + void applyRankings(std::map& positions); void loadRequest(const TokenQueue *queue, const TokenRequest &req); @@ -70,10 +57,11 @@ protected: public slots: void customPopUpMenu(const QPoint& point); -private slots: + void setCurrentMsgId(QTreeWidgetItem* current, QTreeWidgetItem* previous); void makeComment(); + void replyToComment(); protected: From 4438303d554c9cb83787458db6e4656a1e6b7215 Mon Sep 17 00:00:00 2001 From: drbob Date: Sat, 1 Dec 2012 00:16:24 +0000 Subject: [PATCH 191/222] * Got GxsCircles running in libretroshare. - Completed serialiser. - added dummy interface fns. & cleaned-up other linking issues. - Added into rsinit.cc * Improved GxsIdentity DummyData to fake Ids from friends - #define to enable, must be switched off for real usage. - cleaned up rsIdentity interface. - removed genDummyData from public interface. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5915 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/libretroshare.pro | 8 +- libretroshare/src/retroshare/rsgxscircles.h | 1 + libretroshare/src/retroshare/rsidentity.h | 110 +----- libretroshare/src/rsserver/rsinit.cc | 21 ++ .../src/serialiser/rsgxscircleitems.cc | 60 ++-- .../src/serialiser/rsgxscircleitems.h | 13 +- libretroshare/src/services/p3gxscircles.cc | 91 ++--- libretroshare/src/services/p3idservice.cc | 315 ++++++++++++------ libretroshare/src/services/p3idservice.h | 6 +- 9 files changed, 349 insertions(+), 276 deletions(-) diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 15e803a6a..09b6cf021 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -642,13 +642,11 @@ HEADERS += retroshare/rsgame.h # GxsCircles Service HEADERS += services/p3gxscircles.h \ - -# serialiser/rsgxscircleitems.h -# retroshare/rsgxscircles.h \ + serialiser/rsgxscircleitems.h \ + retroshare/rsgxscircles.h \ SOURCES += services/p3gxscircles.cc \ - -# serialiser/rsgxscircleitems.cc \ + serialiser/rsgxscircleitems.cc \ # GxsForums Service HEADERS += retroshare/rsgxsforums.h \ diff --git a/libretroshare/src/retroshare/rsgxscircles.h b/libretroshare/src/retroshare/rsgxscircles.h index 741c7bea0..99ac571bf 100644 --- a/libretroshare/src/retroshare/rsgxscircles.h +++ b/libretroshare/src/retroshare/rsgxscircles.h @@ -85,6 +85,7 @@ class RsGxsCircleMsg // Signature by user signifying that they want to be part of the group. // maybe Phase 3. + std::string stuff; }; diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index 87a2d2ad1..b5eee52d9 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -206,62 +206,6 @@ public: RsIdentity(RsGenExchange *gxs): RsGxsIfaceImpl(gxs) { return; } virtual ~RsIdentity() { return; } - /* Specific Service Data */ - - /*! - * @param token token to be redeemed for album request - * @param album the album returned for given request token - * @return false if request token is invalid, check token status for error report - */ -// virtual bool getAlbum(const uint32_t &token, std::vector &album) = 0; - - /*! - * @param token token to be redeemed for photo request - * @param photo the photo returned for given request token - * @return false if request token is invalid, check token status for error report - */ -// virtual bool getPhoto(const uint32_t &token, -// PhotoResult &photo) = 0; - - /* details are updated in album - to choose Album ID, and storage path */ - - /*! - * @param token token to be redeemed for photo request - * @param photo the photo returned for given request token - * @return false if request token is invalid, check token status for error report - */ -// virtual bool getPhotoComment(const uint32_t &token, -// PhotoCommentResult& comments) = 0; - - /*! - * submits album, which returns a token that needs - * to be acknowledge to get album grp id - * @param token token to redeem for acknowledgement - * @param album album to be submitted - */ -// virtual bool submitAlbumDetails(uint32_t& token, RsPhotoAlbum &album) = 0; - - /*! - * submits photo, which returns a token that needs - * to be acknowledged to get photo msg-grp id pair - * @param token token to redeem for acknowledgement - * @param photo photo to be submitted - */ -// virtual bool submitPhoto(uint32_t& token, RsPhotoPhoto &photo) = 0; - - /*! - * submits photo comment, which returns a token that needs - * to be acknowledged to get photo msg-grp id pair - * The mParentId needs to be set to an existing msg for which - * commenting is enabled - * @param token token to redeem for acknowledgement - * @param comment comment to be submitted - */ -// virtual bool submitComment(uint32_t& token, RsPhotoComment &photo) = 0; - -/********************************************************************************************/ -/********************************************************************************************/ -/********************************************************************************************/ /********************************************************************************************/ /********************************************************************************************/ @@ -284,61 +228,9 @@ virtual bool createIdentity(uint32_t& token, RsIdentityParameters ¶ms) = 0; /* Specific Service Data */ /* We expose these initially for testing / GUI purposes. */ + virtual bool getGroupData(const uint32_t &token, std::vector &groups) = 0; - /* In the Identity System - You don't access the Messages Directly. - * as they represent idividuals opinions.... - * This is reflected in the TokenService calls returning false. - * - * Below is the additional interface to look at reputation. - */ - - /* So we will want to cache much of the identity stuff, so that we have quick access to the results. - * The following bits of data will not use the request/response interface, and should be available immediately. - * - * ID => Nickname, knownGPG, reputation. - * - * This will require quite a bit of data... - * 20 Bytes + 50 + 1 + 4 Bytes? (< 100 Bytes). - * x 10,000 IDs. => ~1 MB of cache (Good). - * x 100,000 IDs. => ~10 MB of cache (Good). - * x 1,000,000 IDs. => ~100 MB of cache (Too Big). - * - * We also need to store quick access to your OwnIds. - */ - -//virtual uint32_t getIdDetails(const std::string &id, std::string &nickname, bool &isGpgKnown, -// uint32_t &ownOpinion, float &reputation); -//virtual uint32_t getOwnIds(std::list &ownIds); -//virtual bool setOpinion(const std::string &id, uint32_t opinion); - - -virtual void generateDummyData() = 0; - -#if 0 - - /* Data Requests */ -virtual bool requestIdentityList(uint32_t &token) = 0; -virtual bool requestIdentities(uint32_t &token, const std::list &ids) = 0; -virtual bool requestIdReputations(uint32_t &token, const std::list &ids) = 0; -virtual bool requestIdPeerOpinion(uint32_t &token, const std::string &aboutId, const std::string &peerId) = 0; -//virtual bool requestIdGpgDetails(uint32_t &token, const std::list &ids) = 0; - - /* Poll */ -virtual uint32_t requestStatus(const uint32_t token) = 0; - - /* Retrieve Data */ -virtual bool getIdentityList(const uint32_t token, std::list &ids) = 0; -virtual bool getIdentity(const uint32_t token, RsIdData &data) = 0; -virtual bool getIdReputation(const uint32_t token, RsIdReputation &reputation) = 0; -virtual bool getIdPeerOpinion(const uint32_t token, RsIdOpinion &opinion) = 0; - - /* Updates */ -virtual bool updateIdentity(RsIdData &data) = 0; -virtual bool updateOpinion(RsIdOpinion &opinion) = 0; - -#endif - }; #endif // RETROSHARE_IDENTITY_GUI_INTERFACE_H diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 874f60f24..6e4e4411a 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1825,6 +1825,7 @@ RsTurtle *rsTurtle = NULL ; #ifdef ENABLE_GXS_SERVICES #include "services/p3idservice.h" +#include "services/p3gxscircles.h" #include "services/p3wiki.h" #include "services/p3posted.h" #include "services/p3photoservice.h" @@ -2315,6 +2316,22 @@ int RsServer::StartupRetroShare() RsGxsNetService* gxsid_ns = new RsGxsNetService( RS_SERVICE_GXSV1_TYPE_GXSID, gxsid_ds, nxsMgr, mGxsIdService); + /**** GxsCircle service ****/ + + p3GxsCircles *mGxsCircles = NULL; + + RsGeneralDataService* gxscircles_ds = new RsDataService(currGxsDir + "/", "gxscircles_db", + RS_SERVICE_GXSV1_TYPE_GXSCIRCLE, NULL); + + gxscircles_ds->resetDataStore(); + + // init gxs services + mGxsCircles = new p3GxsCircles(gxscircles_ds, NULL, mGxsIdService); + + // create GXS Circle service + RsGxsNetService* gxscircles_ns = new RsGxsNetService( + RS_SERVICE_GXSV1_TYPE_GXSCIRCLE, gxscircles_ds, nxsMgr, mGxsCircles); + #if ENABLE_OTHER_GXS_SERVICES /**** Photo service ****/ @@ -2424,6 +2441,7 @@ int RsServer::StartupRetroShare() /*** start up GXS core runner ***/ #if ENABLE_OTHER_GXS_SERVICES createThread(*mGxsIdService); + createThread(*mGxsCircles); createThread(*mPhoto); createThread(*mPosted); createThread(*mWiki); @@ -2433,6 +2451,7 @@ int RsServer::StartupRetroShare() // cores ready start up GXS net servers createThread(*gxsid_ns); + createThread(*gxscircles_ns); #if ENABLE_OTHER_GXS_SERVICES createThread(*photo_ns); createThread(*posted_ns); @@ -2443,6 +2462,7 @@ int RsServer::StartupRetroShare() // now add to p3service pqih->addService(gxsid_ns); + pqih->addService(gxscircles_ns); #if ENABLE_OTHER_GXS_SERVICES pqih->addService(photo_ns); pqih->addService(posted_ns); @@ -2713,6 +2733,7 @@ int RsServer::StartupRetroShare() // Testing of new cache system interfaces. rsIdentity = mGxsIdService; + rsGxsCircles = mGxsCircles; #if ENABLE_OTHER_GXS_SERVICES rsWiki = mWiki; rsPosted = mPosted; diff --git a/libretroshare/src/serialiser/rsgxscircleitems.cc b/libretroshare/src/serialiser/rsgxscircleitems.cc index baf8e01f7..6fddb2d92 100644 --- a/libretroshare/src/serialiser/rsgxscircleitems.cc +++ b/libretroshare/src/serialiser/rsgxscircleitems.cc @@ -25,7 +25,7 @@ #include -#include "rswireitems.h" +#include "rsgxscircleitems.h" #include "serialiser/rstlvbase.h" #include "serialiser/rsbaseserial.h" @@ -107,17 +107,37 @@ RsItem* RsGxsCircleSerialiser::deserialise(void* data, uint32_t* size) void RsGxsCircleGroupItem::clear() { - group.mDescription.clear(); + gxsIdSet.TlvClear(); + subCircleSet.TlvClear(); } +bool RsGxsCircleGroupItem::convertFrom(const RsGxsCircleGroup &group) +{ + clear(); + + meta = group.mMeta; + gxsIdSet.ids = group.mInvitedMembers; + subCircleSet.ids = group.mSubCircles; + return true; +} + +bool RsGxsCircleGroupItem::convertTo(RsGxsCircleGroup &group) const +{ + group.mMeta = meta; + group.mInvitedMembers = gxsIdSet.ids; + group.mSubCircles = subCircleSet.ids; + return true; +} + + std::ostream& RsGxsCircleGroupItem::print(std::ostream& out, uint16_t indent) { printRsItemBase(out, "RsGxsCircleGroupItem", indent); uint16_t int_Indent = indent + 2; - printIndent(out, int_Indent); - out << "Description: " << group.mDescription << std::endl; - + gxsIdSet.print(out, int_Indent); + subCircleSet.print(out, int_Indent); + printRsItemEnd(out ,"RsGxsCircleGroupItem", indent); return out; } @@ -125,11 +145,10 @@ std::ostream& RsGxsCircleGroupItem::print(std::ostream& out, uint16_t indent) uint32_t RsGxsCircleSerialiser::sizeGxsCircleGroupItem(RsGxsCircleGroupItem *item) { - - const RsCircleGroup& group = item->group; uint32_t s = 8; // header - s += GetTlvStringSize(group.mDescription); + s += item->gxsIdSet.TlvSize(); + s += item->subCircleSet.TlvSize(); return s; } @@ -162,7 +181,8 @@ bool RsGxsCircleSerialiser::serialiseGxsCircleGroupItem(RsGxsCircleGroupItem *it offset += 8; /* GxsCircleGroupItem */ - ok &= SetTlvString(data, tlvsize, &offset, 1, item->group.mDescription); + ok &= item->gxsIdSet.SetTlv(data, tlvsize, &offset); + ok &= item->subCircleSet.SetTlv(data, tlvsize, &offset); if(offset != tlvsize) { @@ -222,7 +242,8 @@ RsGxsCircleGroupItem* RsGxsCircleSerialiser::deserialiseGxsCircleGroupItem(void /* skip the header */ offset += 8; - ok &= GetTlvString(data, rssize, &offset, 1, item->group.mDescription); + ok &= item->gxsIdSet.GetTlv(data, rssize, &offset); + ok &= item->subCircleSet.GetTlv(data, rssize, &offset); if (offset != rssize) { @@ -255,8 +276,7 @@ RsGxsCircleGroupItem* RsGxsCircleSerialiser::deserialiseGxsCircleGroupItem(void void RsGxsCircleMsgItem::clear() { - pulse.mPulseText.clear(); - pulse.mHashTags.clear(); + msg.stuff.clear(); } std::ostream& RsGxsCircleMsgItem::print(std::ostream& out, uint16_t indent) @@ -265,10 +285,7 @@ std::ostream& RsGxsCircleMsgItem::print(std::ostream& out, uint16_t indent) uint16_t int_Indent = indent + 2; printIndent(out, int_Indent); - out << "Page: " << pulse.mPulseText << std::endl; - - printIndent(out, int_Indent); - out << "HashTags: " << pulse.mHashTags << std::endl; + out << "Stuff: " << msg.stuff << std::endl; printRsItemEnd(out ,"RsGxsCircleMsgItem", indent); return out; @@ -278,11 +295,10 @@ std::ostream& RsGxsCircleMsgItem::print(std::ostream& out, uint16_t indent) uint32_t RsGxsCircleSerialiser::sizeGxsCircleMsgItem(RsGxsCircleMsgItem *item) { - const RsCircleMsg& pulse = item->pulse; + const RsGxsCircleMsg &msg = item->msg; uint32_t s = 8; // header - s += GetTlvStringSize(pulse.mPulseText); - s += GetTlvStringSize(pulse.mHashTags); + s += GetTlvStringSize(msg.stuff); return s; } @@ -315,8 +331,7 @@ bool RsGxsCircleSerialiser::serialiseGxsCircleMsgItem(RsGxsCircleMsgItem *item, offset += 8; /* GxsCircleMsgItem */ - ok &= SetTlvString(data, tlvsize, &offset, 1, item->pulse.mPulseText); - ok &= SetTlvString(data, tlvsize, &offset, 1, item->pulse.mHashTags); + ok &= SetTlvString(data, tlvsize, &offset, 1, item->msg.stuff); if(offset != tlvsize) { @@ -376,8 +391,7 @@ RsGxsCircleMsgItem* RsGxsCircleSerialiser::deserialiseGxsCircleMsgItem(void *dat /* skip the header */ offset += 8; - ok &= GetTlvString(data, rssize, &offset, 1, item->pulse.mPulseText); - ok &= GetTlvString(data, rssize, &offset, 1, item->pulse.mHashTags); + ok &= GetTlvString(data, rssize, &offset, 1, item->msg.stuff); if (offset != rssize) { diff --git a/libretroshare/src/serialiser/rsgxscircleitems.h b/libretroshare/src/serialiser/rsgxscircleitems.h index 457dae5f3..1bfca6a35 100644 --- a/libretroshare/src/serialiser/rsgxscircleitems.h +++ b/libretroshare/src/serialiser/rsgxscircleitems.h @@ -38,20 +38,29 @@ const uint8_t RS_PKT_SUBTYPE_GXSCIRCLE_GROUP_ITEM = 0x02; const uint8_t RS_PKT_SUBTYPE_GXSCIRCLE_MSG_ITEM = 0x03; +const uint16_t GXSCIRCLE_GXSIDSET = 0x0001; +const uint16_t GXSCIRCLE_SUBCIRCLESET = 0x0002; + class RsGxsCircleGroupItem : public RsGxsGrpItem { public: RsGxsCircleGroupItem(): RsGxsGrpItem(RS_SERVICE_GXSV1_TYPE_GXSCIRCLE, - RS_PKT_SUBTYPE_GXSCIRCLE_GROUP_ITEM) { return;} + RS_PKT_SUBTYPE_GXSCIRCLE_GROUP_ITEM), + gxsIdSet(GXSCIRCLE_GXSIDSET), + subCircleSet(GXSCIRCLE_SUBCIRCLESET) { return;} virtual ~RsGxsCircleGroupItem() { return;} void clear(); std::ostream &print(std::ostream &out, uint16_t indent = 0); + bool convertFrom(const RsGxsCircleGroup &group); + bool convertTo(RsGxsCircleGroup &group) const; - RsGxsCircleGroup group; + // DIFFERENT FROM OTHER ONES, as stupid serialisation otherwise. + RsTlvStringSet gxsIdSet; + RsTlvStringSet subCircleSet; }; class RsGxsCircleMsgItem : public RsGxsMsgItem diff --git a/libretroshare/src/services/p3gxscircles.cc b/libretroshare/src/services/p3gxscircles.cc index ae2525639..6f80658d3 100644 --- a/libretroshare/src/services/p3gxscircles.cc +++ b/libretroshare/src/services/p3gxscircles.cc @@ -137,6 +137,31 @@ void p3GxsCircles::notifyChanges(std::vector &changes) /******************* RsCircles Interface ***************************************/ /********************************************************************************/ +void p3GxsCircles::createLocalCircle() +{ + return; +} + +void p3GxsCircles::addToLocalCircle() +{ + return; +} + +void p3GxsCircles::removeFromLocalCircle() +{ + return; +} + +void p3GxsCircles::getLocalCirclePeers() +{ + return; +} + +void p3GxsCircles::getListOfLocalCircles() +{ + return; +} + #if 0 bool p3GxsCircles:: getNickname(const RsGxsId &id, std::string &nickname) @@ -181,35 +206,8 @@ bool p3GxsCircles:: getOwnIds(std::list &ownIds) return true; } - -// -bool p3GxsCircles::submitOpinion(uint32_t& token, RsIdOpinion &opinion) -{ - return false; -} - -bool p3GxsCircles::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) -{ - - RsGxsIdGroup id; - - id.mMeta.mGroupName = params.nickname; - if (params.isPgpLinked) - { - id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID; - } - else - { - id.mMeta.mGroupFlags = 0; - } - - createGroup(token, id); - - return true; -} #endif - /********************************************************************************/ /******************* RsGixs Interface ***************************************/ /********************************************************************************/ @@ -269,8 +267,8 @@ bool p3GxsCircles::getGroupData(const uint32_t &token, std::vector(*vit); - RsGxsCircleGroup group = item->group; - group.mMeta = item->meta; + RsGxsCircleGroup group; + item->convertTo(group); // If its cached - add that info (TODO). groups.push_back(group); @@ -287,8 +285,7 @@ bool p3GxsCircles::getGroupData(const uint32_t &token, std::vectorgroup = group; - item->meta = group.mMeta; + item->convertFrom(group); RsGenExchange::publishGroup(token, item); return true; } @@ -688,8 +685,8 @@ bool p3GxsCircles::cache_load_for_token(uint32_t token) for(; vit != grpData.end(); vit++) { RsGxsCircleGroupItem *item = dynamic_cast(*vit); - RsGxsCircleGroup group = item->group; - group.mMeta = item->meta; + RsGxsCircleGroup group; + item->convertTo(group); std::cerr << "p3GxsCircles::cache_load_for_token() Loaded Id with Meta: "; std::cerr << item->meta; @@ -1204,19 +1201,33 @@ void p3GxsCircles::generateDummyData() /************************************************************************************/ -std::ostream &operator<<(std::ostream &out, const RsGxsIdGroup &grp) +std::ostream &operator<<(std::ostream &out, const RsGxsCircleGroup &grp) { - out << "RsGxsIdGroup: Meta: " << grp.mMeta; - out << " PgpIdHash: " << grp.mPgpIdHash; - out << " PgpIdSign: [binary]"; // << grp.mPgpIdSign; + out << "RsGxsCircleGroup: Meta: " << grp.mMeta; + out << "InvitedMembers: "; out << std::endl; - + + std::list::const_iterator it; + std::list::const_iterator sit; + for(it = grp.mInvitedMembers.begin(); + it != grp.mInvitedMembers.begin(); it++) + { + out << "\t" << *it; + out << std::endl; + } + + for(sit = grp.mSubCircles.begin(); + sit != grp.mSubCircles.begin(); sit++) + { + out << "\t" << *it; + out << std::endl; + } return out; } -std::ostream &operator<<(std::ostream &out, const RsGxsIdOpinion &opinion) +std::ostream &operator<<(std::ostream &out, const RsGxsCircleMsg &msg) { - out << "RsGxsIdOpinion: Meta: " << opinion.mMeta; + out << "RsGxsCircleMsg: Meta: " << msg.mMeta; out << std::endl; return out; diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index b8a1cac4f..be00cdaf2 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -39,6 +39,9 @@ /**** * #define ID_DEBUG 1 ****/ +#define GXSID_GEN_DUMMY_DATA 1 + + #define ID_REQUEST_LIST 0x0001 #define ID_REQUEST_IDENTITY 0x0002 @@ -91,6 +94,15 @@ RsIdentity *rsIdentity = NULL; #define GXSID_EVENT_CACHETEST 0x1000 +#define GXSID_EVENT_DUMMYDATA 0x2000 +#define GXSID_EVENT_DUMMY_OWNIDS 0x2001 +#define GXSID_EVENT_DUMMY_PGPID 0x2002 +#define GXSID_EVENT_DUMMY_UNKNOWN_PGPID 0x2003 +#define GXSID_EVENT_DUMMY_PSEUDOID 0x2004 + + +/* delays */ + #define CACHETEST_PERIOD 60 #define OWNID_RELOAD_DELAY 10 @@ -121,6 +133,11 @@ p3IdService::p3IdService(RsGeneralDataService *gds, RsNetworkExchangeService *ne RsTickEvent::schedule_in(GXSID_EVENT_PGPHASH, PGPHASH_PERIOD); RsTickEvent::schedule_in(GXSID_EVENT_REPUTATION, REPUTATION_PERIOD); RsTickEvent::schedule_now(GXSID_EVENT_CACHEOWNIDS); + +#ifdef GXSID_GEN_DUMMY_DATA + RsTickEvent::schedule_now(GXSID_EVENT_DUMMYDATA); +#endif + } @@ -1129,6 +1146,7 @@ typedef t_RsGenericIdType GxsIdPgpHash; static void calcPGPHash(const RsGxsId &id, const PGPFingerprintType &pgp, GxsIdPgpHash &hash); +// Must Use meta. void p3IdService::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet) { RsGxsIdGroupItem *item = dynamic_cast(grpItem); @@ -1138,7 +1156,7 @@ void p3IdService::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet std::cerr << std::endl; return; } - + /********************* TEMP HACK UNTIL GXS FILLS IN GROUP_ID *****************/ // find private admin key std::map::iterator mit = keySet.keys.begin(); @@ -1163,19 +1181,61 @@ void p3IdService::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet /********************* TEMP HACK UNTIL GXS FILLS IN GROUP_ID *****************/ + // SANITY CHECK. + if (item->group.mMeta.mAuthorId != item->meta.mAuthorId) + { + std::cerr << "p3IdService::service_CreateGroup() AuthorId mismatch("; + std::cerr << item->group.mMeta.mAuthorId; + std::cerr << " vs "; + std::cerr << item->meta.mAuthorId; + std::cerr << std::endl; + } + + if (item->group.mMeta.mGroupId != item->meta.mGroupId) + { + std::cerr << "p3IdService::service_CreateGroup() GroupId mismatch("; + std::cerr << item->group.mMeta.mGroupId; + std::cerr << " vs "; + std::cerr << item->meta.mGroupId; + std::cerr << std::endl; + } + + + if (item->group.mMeta.mGroupFlags != item->meta.mGroupFlags) + { + std::cerr << "p3IdService::service_CreateGroup() GroupFlags mismatch("; + std::cerr << item->group.mMeta.mGroupFlags; + std::cerr << " vs "; + std::cerr << item->meta.mGroupFlags; + std::cerr << std::endl; + } + + + + + + std::cerr << "p3IdService::service_CreateGroup() for : " << item->group.mMeta.mGroupId; std::cerr << std::endl; std::cerr << "p3IdService::service_CreateGroup() Alt GroupId : " << item->meta.mGroupId; std::cerr << std::endl; - if (item->group.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID) +#ifdef GXSID_GEN_DUMMY_DATA + if ((item->group.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID) && (item->group.mMeta.mAuthorId != "")) +#else + if (item->group.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID) +#endif { /* create the hash */ GxsIdPgpHash hash; /* */ PGPFingerprintType ownFinger; +#ifdef GXSID_GEN_DUMMY_DATA + PGPIdType ownId(item->group.mMeta.mAuthorId); +#else PGPIdType ownId(AuthGPG::getAuthGPG()->getGPGOwnId()); +#endif if (!AuthGPG::getAuthGPG()->getKeyFingerprint(ownId,ownFinger)) { @@ -1215,6 +1275,12 @@ void p3IdService::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet } + // Enforce no AuthorId. + item->meta.mAuthorId = ""; + item->group.mMeta.mAuthorId = ""; + // copy meta data to be sure its all the same. + //item->group.mMeta = item->meta; + // Reload in a little bit. // HACK to get it to work. RsTickEvent::schedule_in(GXSID_EVENT_CACHEOWNIDS, OWNID_RELOAD_DELAY); @@ -1567,130 +1633,167 @@ void calcPGPHash(const RsGxsId &id, const PGPFingerprintType &pgp, GxsIdPgpHash /************************************************************************************/ /************************************************************************************/ -std::string p3IdService::genRandomId() + +std::string p3IdService::genRandomId(int len) { std::string randomId; - for(int i = 0; i < 20; i++) + for(int i = 0; i < len; i++) { - randomId += (char) ('a' + (RSRandom::random_u32() % 26)); + int val = RSRandom::random_u32() % 16; + if (val < 10) + { + randomId += (char) ('0' + val); + } + else + { + randomId += (char) ('a' + (val - 10)); + } } return randomId; } +#define MAX_KNOWN_PGPIDS 50 +#define MAX_UNKNOWN_PGPIDS 50 +#define MAX_PSEUDOIDS 100 + +#define DUMMY_GXSID_DELAY 5 + void p3IdService::generateDummyData() +{ + + generateDummy_OwnIds(); + + time_t age = 0; + for(int i = 0; i < MAX_KNOWN_PGPIDS; i++) + { + age += DUMMY_GXSID_DELAY; + RsTickEvent::schedule_in(GXSID_EVENT_DUMMY_PGPID, age); + } + + for(int i = 0; i < MAX_PSEUDOIDS; i++) + { + age += DUMMY_GXSID_DELAY; + RsTickEvent::schedule_in(GXSID_EVENT_DUMMY_PSEUDOID, age); + } + + for(int i = 0; i < MAX_UNKNOWN_PGPIDS; i++) + { + age += DUMMY_GXSID_DELAY; + RsTickEvent::schedule_in(GXSID_EVENT_DUMMY_UNKNOWN_PGPID, age); + } +} + + + + + +void p3IdService::generateDummy_OwnIds() { RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ /* grab all the gpg ids... and make some ids */ - std::list gpgids; - std::list::iterator it; - - rsPeers->getGPGAllList(gpgids); - std::string ownId = rsPeers->getGPGOwnId(); - gpgids.push_back(ownId); + // generate some ownIds. int genCount = 0; int i; - for(it = gpgids.begin(); it != gpgids.end(); it++) - { - /* create one or two for each one */ - int nIds = 1 + (RSRandom::random_u32() % 2); - for(i = 0; i < nIds; i++) - { - RsGxsIdGroup id; - RsPeerDetails details; - - //id.mKeyId = genRandomId(); - id.mMeta.mGroupId = genRandomId(); - id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID; - id.mPgpIdHash = genRandomId(); - id.mPgpIdSign = genRandomId(); - - if (rsPeers->getPeerDetails(*it, details)) - { - std::ostringstream out; - out << details.name << "_" << i + 1; - - //id.mNickname = out.str(); - id.mMeta.mGroupName = out.str(); - - - } - else - { - std::cerr << "p3IdService::generateDummyData() missing" << std::endl; - std::cerr << std::endl; - - //id.mNickname = genRandomId(); - id.mMeta.mGroupName = genRandomId(); - } - - uint32_t dummyToken = 0; - createGroup(dummyToken, id); - -// LIMIT - AS GENERATION IS BROKEN. -#define MAX_TEST_GEN 5 - if (++genCount > MAX_TEST_GEN) - { - return; - } - } - } - return; - -#define MAX_RANDOM_GPGIDS 10 //1000 -#define MAX_RANDOM_PSEUDOIDS 50 //5000 - - int nFakeGPGs = (RSRandom::random_u32() % MAX_RANDOM_GPGIDS); - int nFakePseudoIds = (RSRandom::random_u32() % MAX_RANDOM_PSEUDOIDS); - - /* make some fake gpg ids */ - for(i = 0; i < nFakeGPGs; i++) + int nIds = 2 + (RSRandom::random_u32() % 2); + for(i = 0; i < nIds; i++) { RsGxsIdGroup id; + RsPeerDetails details; - RsPeerDetails details; - - id.mMeta.mGroupName = genRandomId(); - - id.mMeta.mGroupId = genRandomId(); id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID; - id.mPgpIdHash = genRandomId(); - id.mPgpIdSign = genRandomId(); + + // HACK FOR DUMMY GENERATION. + id.mMeta.mAuthorId = ownId; + if (rsPeers->getPeerDetails(ownId, details)) + { + std::ostringstream out; + out << details.name << "_" << i + 1; + + id.mMeta.mGroupName = out.str(); + } uint32_t dummyToken = 0; createGroup(dummyToken, id); } - - /* make lots of pseudo ids */ - for(i = 0; i < nFakePseudoIds; i++) - { - RsGxsIdGroup id; - - RsPeerDetails details; - - id.mMeta.mGroupName = genRandomId(); - - id.mMeta.mGroupId = genRandomId(); - id.mMeta.mGroupFlags = 0; - id.mPgpIdHash = ""; - id.mPgpIdSign = ""; - - - uint32_t dummyToken = 0; - createGroup(dummyToken, id); - } - - //mUpdated = true; - - return; } +void p3IdService::generateDummy_FriendPGP() +{ + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + // Now Generate for friends. + std::list gpgids; + std::list::iterator it; + rsPeers->getGPGAllList(gpgids); + + RsGxsIdGroup id; + + id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID; + + int idx = RSRandom::random_f32() * (gpgids.size() - 1); + it = gpgids.begin(); + for(int j = 0; j < idx; j++, it++); + + // HACK FOR DUMMY GENERATION. + id.mMeta.mAuthorId = *it; + + RsPeerDetails details; + if (rsPeers->getPeerDetails(*it, details)) + { + std::ostringstream out; + out << details.name << "_" << RSRandom::random_u32() % 1000; + id.mMeta.mGroupName = out.str(); + } + else + { + std::cerr << "p3IdService::generateDummy_FriendPGP() missing" << std::endl; + std::cerr << std::endl; + id.mMeta.mGroupName = genRandomId(); + } + + uint32_t dummyToken = 0; + createGroup(dummyToken, id); +} + + +void p3IdService::generateDummy_UnknownPGP() +{ + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + RsGxsIdGroup id; + + // FAKE DATA. + id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID; + id.mPgpIdHash = genRandomId(40); + id.mPgpIdSign = genRandomId(40); + id.mMeta.mGroupName = genRandomId(); + + uint32_t dummyToken = 0; + createGroup(dummyToken, id); +} + + +void p3IdService::generateDummy_UnknownPseudo() +{ + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + RsGxsIdGroup id; + + // FAKE DATA. + id.mMeta.mGroupFlags = 0; + id.mMeta.mGroupName = genRandomId(); + + uint32_t dummyToken = 0; + createGroup(dummyToken, id); +} + std::string rsIdTypeToString(uint32_t idtype) { @@ -2462,6 +2565,26 @@ void p3IdService::handle_event(uint32_t event_type, const std::string &elabel) pgphash_process(); break; + case GXSID_EVENT_DUMMYDATA: + generateDummyData(); + break; + + case GXSID_EVENT_DUMMY_OWNIDS: + generateDummy_OwnIds(); + break; + + case GXSID_EVENT_DUMMY_PGPID: + generateDummy_FriendPGP(); + break; + + case GXSID_EVENT_DUMMY_UNKNOWN_PGPID: + generateDummy_UnknownPGP(); + break; + + case GXSID_EVENT_DUMMY_PSEUDOID: + generateDummy_UnknownPseudo(); + break; + default: /* error */ std::cerr << "p3IdService::handle_event() Unknown Event Type: " << event_type; diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index 388afe7a3..85118556a 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -307,8 +307,12 @@ virtual void handle_event(uint32_t event_type, const std::string &elabel); */ virtual void generateDummyData(); + void generateDummy_OwnIds(); + void generateDummy_FriendPGP(); + void generateDummy_UnknownPGP(); + void generateDummy_UnknownPseudo(); -std::string genRandomId(); +std::string genRandomId(int len = 20); bool reputation_start(); bool reputation_continue(); From 30ea727333160593b5ec1c523535925b44029c6a Mon Sep 17 00:00:00 2001 From: drbob Date: Sat, 1 Dec 2012 00:16:28 +0000 Subject: [PATCH 192/222] removed generateDummyData() call from GUI (now handled in libretroshare) git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5916 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/Identity/IdDialog.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 0fcb8591d..a3a4a69a9 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -79,9 +79,7 @@ IdDialog::IdDialog(QWidget *parent) timer->connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate())); timer->start(1000); - rsIdentity->generateDummyData(); mIdQueue = new TokenQueue(rsIdentity->getTokenService(), this); - } void IdDialog::ListTypeToggled(bool checked) From c955e3b5a424fefff5db95a3bdd36050e2c6f9fb Mon Sep 17 00:00:00 2001 From: drbob Date: Sat, 1 Dec 2012 17:23:25 +0000 Subject: [PATCH 193/222] Reworked Wiki Edit Dialog. - Added EditHistory SideBar (Will remove from main page). - Added Preview / Edit modes. (to add renderer) - changed layout a bit. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5923 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/gui/WikiPoos/WikiEditDialog.cpp | 346 ++++++++++++++++-- .../src/gui/WikiPoos/WikiEditDialog.h | 18 + .../src/gui/WikiPoos/WikiEditDialog.ui | 335 +++++++++-------- 3 files changed, 529 insertions(+), 170 deletions(-) diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp index 6422c7a76..dbbab0c98 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp @@ -26,22 +26,100 @@ #include + +#define WIKIEDITDIALOG_GROUP 0x0001 +#define WIKIEDITDIALOG_PAGE 0x0002 +#define WIKIEDITDIALOG_BASEHISTORY 0x0003 +#define WIKIEDITDIALOG_EDITTREE 0x0005 + /** Constructor */ WikiEditDialog::WikiEditDialog(QWidget *parent) : QWidget(parent) { - ui.setupUi(this); - - + ui.setupUi(this); connect(ui.pushButton_Cancel, SIGNAL( clicked( void ) ), this, SLOT( cancelEdit( void ) ) ); connect(ui.pushButton_Revert, SIGNAL( clicked( void ) ), this, SLOT( revertEdit( void ) ) ); connect(ui.pushButton_Submit, SIGNAL( clicked( void ) ), this, SLOT( submitEdit( void ) ) ); + connect(ui.pushButton_Preview, SIGNAL( clicked( void ) ), this, SLOT( previewToggle( void ) ) ); + connect(ui.pushButton_History, SIGNAL( clicked( void ) ), this, SLOT( historyToggle( void ) ) ); mWikiQueue = new TokenQueue(rsWiki->getTokenService(), this); mRepublishMode = false; + mPreviewMode = false; + mPageLoading = false; + mCurrentText = ""; + + ui.groupBox_History->hide(); } +void WikiEditDialog::historyToggle() +{ + std::cerr << "WikiEditDialog::historyToggle()"; + std::cerr << std::endl; + if (ui.groupBox_History->isHidden()) + { + ui.groupBox_History->show(); + ui.pushButton_History->setText(tr("Hide Edit History")); + } + else + { + ui.groupBox_History->hide(); + ui.pushButton_History->setText(tr("Show Edit History")); + } +} + + +void WikiEditDialog::previewToggle() +{ + std::cerr << "WikiEditDialog::previewToggle()"; + std::cerr << std::endl; + + if (mPreviewMode) + { + mPreviewMode = false; + ui.pushButton_Preview->setText(tr("Preview")); + } + else + { + // Save existing Text into buffer. + mCurrentText = ui.textEdit->toPlainText(); + mPreviewMode = true; + ui.pushButton_Preview->setText(tr("Edit Page")); + } + if (!mPageLoading) + { + redrawPage(); + } +} + + +void WikiEditDialog::redrawPage() +{ + std::cerr << "WikiEditDialog::redrawPage()"; + std::cerr << std::endl; + + if (mPreviewMode) + { + /* render as HTML */ + QString renderedText = "RENDERED TEXT:\n"; + renderedText += mCurrentText; + ui.textEdit->setPlainText(renderedText); + + /* disable edit */ + ui.textEdit->setReadOnly(true); + } + else + { + /* plain text - for editing */ + ui.textEdit->setPlainText(mCurrentText); + + /* enable edit */ + ui.textEdit->setReadOnly(false); + } +} + + void WikiEditDialog::setGroup(RsWikiCollection &group) { std::cerr << "WikiEditDialog::setGroup(): " << group; @@ -63,7 +141,8 @@ void WikiEditDialog::setPreviousPage(RsWikiSnapshot &page) ui.lineEdit_Page->setText(QString::fromStdString(mWikiSnapshot.mMeta.mMsgName)); ui.lineEdit_PrevVersion->setText(QString::fromStdString(mWikiSnapshot.mMeta.mMsgId)); - ui.textEdit->setPlainText(QString::fromStdString(mWikiSnapshot.mPage)); + mCurrentText = QString::fromUtf8(mWikiSnapshot.mPage.c_str()); + redrawPage(); } @@ -73,11 +152,17 @@ void WikiEditDialog::setNewPage() mRepublishMode = false; ui.lineEdit_Page->setText(""); ui.lineEdit_PrevVersion->setText(""); - ui.textEdit->setPlainText(""); - + + mCurrentText = ""; + redrawPage(); + ui.treeWidget_History->clear(); + ui.groupBox_History->hide(); + ui.pushButton_History->setText(tr("Show Edit History")); + ui.headerFrame->setHeaderImage(QPixmap(":/images/appointment-new_64.png")); - ui.headerFrame->setHeaderText(tr("Create New Wiki Page")); - setWindowTitle(tr("Create New Wiki Page")); + ui.headerFrame->setHeaderText(tr("Create New Wiki Page")); + setWindowTitle(tr("Create New Wiki Page")); + } @@ -99,12 +184,14 @@ void WikiEditDialog::revertEdit() { if (mNewPage) { - ui.textEdit->setPlainText(""); + mCurrentText = ""; } else { ui.textEdit->setPlainText(QString::fromStdString(mWikiSnapshot.mPage)); + mCurrentText = QString::fromUtf8(mWikiSnapshot.mPage.c_str()); } + redrawPage(); } @@ -224,7 +311,7 @@ void WikiEditDialog::requestGroup(const std::string &groupId) RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; uint32_t token; - mWikiQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, 0); + mWikiQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, WIKIEDITDIALOG_GROUP); } void WikiEditDialog::loadGroup(const uint32_t &token) @@ -258,7 +345,8 @@ void WikiEditDialog::requestPage(const RsGxsGrpMsgIdPair &msgId) vect_msgIds.push_back(msgId.second); uint32_t token; - mWikiQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, 0); + mWikiQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, WIKIEDITDIALOG_PAGE); + mPageLoading = true; } void WikiEditDialog::loadPage(const uint32_t &token) @@ -276,10 +364,210 @@ void WikiEditDialog::loadPage(const uint32_t &token) std::cerr << std::endl; return; } - setPreviousPage(snapshots[0]); + + RsWikiSnapshot &page = snapshots[0]; + setPreviousPage(page); + + /* request the history now */ + mThreadMsgIdPair.first = page.mMeta.mGroupId; + if (page.mMeta.mThreadId.empty()) + { + mThreadMsgIdPair.second = page.mMeta.mOrigMsgId; + } + else + { + mThreadMsgIdPair.second = page.mMeta.mThreadId; + } + requestBaseHistory(mThreadMsgIdPair); + } + mPageLoading = false; +} + + +/*********************** LOAD EDIT HISTORY **********************/ + +#define WIKIEDITTREE_COL_ORIGPAGEID 0 +#define WIKIEDITTREE_COL_PAGEID 1 +#define WIKIEDITTREE_COL_PARENTID 2 + +void WikiEditDialog::requestBaseHistory(const RsGxsGrpMsgIdPair &origMsgId) +{ + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; + opts.mOptions = RS_TOKREQOPT_MSG_VERSIONS; + std::vector msgIds; + msgIds.push_back(origMsgId); + uint32_t token; + mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, WIKIEDITDIALOG_BASEHISTORY); + ui.treeWidget_History->clear(); +} + +void WikiEditDialog::loadBaseHistory(const uint32_t &token) +{ + std::cerr << "WikiEditDialog::loadBaseHistory()"; + std::cerr << std::endl; + + + std::vector snapshots; + std::vector::iterator vit; + if (!rsWiki->getRelatedSnapshots(token, snapshots)) + { + // ERROR + std::cerr << "WikiEditDialog::loadBaseHistory() ERROR"; + std::cerr << std::endl; + return; + } + + for(vit = snapshots.begin(); vit != snapshots.end(); vit++) + { + RsWikiSnapshot &page = *vit; + + std::cerr << "WikiEditDialog::loadBaseHistory() TopLevel Result: PageTitle: " << page.mMeta.mMsgName; + std::cerr << " GroupId: " << page.mMeta.mGroupId; + std::cerr << std::endl; + std::cerr << "\tOrigMsgId: " << page.mMeta.mOrigMsgId; + std::cerr << " MsgId: " << page.mMeta.mMsgId; + std::cerr << std::endl; + std::cerr << "\tThreadId: " << page.mMeta.mThreadId; + std::cerr << " ParentId: " << page.mMeta.mParentId; + std::cerr << std::endl; + + QTreeWidgetItem *modItem = new QTreeWidgetItem(); + modItem->setText(WIKIEDITTREE_COL_ORIGPAGEID, QString::fromStdString(page.mMeta.mOrigMsgId)); + modItem->setText(WIKIEDITTREE_COL_PAGEID, QString::fromStdString(page.mMeta.mMsgId)); + modItem->setText(WIKIEDITTREE_COL_PARENTID, QString::fromStdString(page.mMeta.mParentId)); + ui.treeWidget_History->addTopLevelItem(modItem); + } + + /* then we need to request all pages from this thread */ + requestEditTreeData(); +} + + +void WikiEditDialog::requestEditTreeData() //const RsGxsGroupId &groupId) +{ + // SWITCH THIS TO A THREAD REQUEST - WHEN WE CAN! + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST; + + std::list groupIds; + groupIds.push_back(mThreadMsgIdPair.first); + + uint32_t token; + mWikiQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, WIKIEDITDIALOG_EDITTREE); +} + + +void WikiEditDialog::loadEditTreeData(const uint32_t &token) +{ + std::cerr << "WikiEditDialog::loadEditTreeData()"; + std::cerr << std::endl; + + + std::vector snapshots; + std::vector::iterator vit; + if (!rsWiki->getSnapshots(token, snapshots)) + { + // ERROR + std::cerr << "WikiEditDialog::loadEditTreeData() ERROR"; + std::cerr << std::endl; + return; + } + + std::cerr << "WikiEditDialog::loadEditTreeData() Loaded " << snapshots.size(); + std::cerr << std::endl; + std::cerr << "WikiEditDialog::loadEditTreeData() Using ThreadId: " << mThreadMsgIdPair.second; + std::cerr << std::endl; + + + std::map items; + std::map::iterator iit; + std::list unparented; + std::list::iterator uit; + + // Grab the existing TopLevelItems, and insert into map. + int itemCount = ui.treeWidget_History->topLevelItemCount(); + for (int nIndex = 0; nIndex < itemCount; nIndex++) + { + QTreeWidgetItem *item = ui.treeWidget_History->topLevelItem(nIndex); + + /* index by MsgId --> ONLY For Wiki Thread Head Items... SPECIAL HACK FOR HERE! */ + std::string msgId = item->text(WIKIEDITTREE_COL_PAGEID).toStdString(); + items[msgId] = item; + } + + + for(vit = snapshots.begin(); vit != snapshots.end(); vit++) + { + RsWikiSnapshot &snapshot = *vit; + + std::cerr << "Result: PageTitle: " << snapshot.mMeta.mMsgName; + std::cerr << " GroupId: " << snapshot.mMeta.mGroupId; + std::cerr << std::endl; + std::cerr << "\tOrigMsgId: " << snapshot.mMeta.mOrigMsgId; + std::cerr << " MsgId: " << snapshot.mMeta.mMsgId; + std::cerr << std::endl; + std::cerr << "\tThreadId: " << snapshot.mMeta.mThreadId; + std::cerr << " ParentId: " << snapshot.mMeta.mParentId; + std::cerr << std::endl; + + if (snapshot.mMeta.mParentId == "") + { + /* Ignore! */ + std::cerr << "Ignoring ThreadHead Item"; + std::cerr << std::endl; + continue; + } + + if (snapshot.mMeta.mThreadId != mThreadMsgIdPair.second) + { + /* Ignore! */ + std::cerr << "Ignoring Different Thread Item"; + std::cerr << std::endl; + continue; + } + + /* create an Entry */ + QTreeWidgetItem *modItem = new QTreeWidgetItem(); + modItem->setText(WIKIEDITTREE_COL_ORIGPAGEID, QString::fromStdString(snapshot.mMeta.mOrigMsgId)); + modItem->setText(WIKIEDITTREE_COL_PAGEID, QString::fromStdString(snapshot.mMeta.mMsgId)); + modItem->setText(WIKIEDITTREE_COL_PARENTID, QString::fromStdString(snapshot.mMeta.mParentId)); + + /* find the parent */ + iit = items.find(snapshot.mMeta.mParentId); + if (iit != items.end()) + { + (iit->second)->addChild(modItem); + } + else + { + unparented.push_back(modItem); + } + items[snapshot.mMeta.mOrigMsgId] = modItem; + } + + for(uit = unparented.begin(); uit != unparented.end(); uit++) + { + std::string parentId = (*uit)->text(WIKIEDITTREE_COL_PARENTID).toStdString(); + + iit = items.find(parentId); + if (iit != items.end()) + { + (iit->second)->addChild(*uit); + } + else + { + /* ERROR */ + std::cerr << "Unparented!!!"; + std::cerr << std::endl; + } } } + + void WikiEditDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) { std::cerr << "WikiEditDialog::loadRequest()"; @@ -287,19 +575,27 @@ void WikiEditDialog::loadRequest(const TokenQueue *queue, const TokenRequest &re if (queue == mWikiQueue) { - /* now switch on req */ - switch(req.mType) + switch(req.mUserType) { - case TOKENREQ_GROUPINFO: - loadGroup(req.mToken); + case WIKIEDITDIALOG_GROUP: + loadGroup(req.mToken); + break; + + case WIKIEDITDIALOG_PAGE: + loadPage(req.mToken); + break; + + case WIKIEDITDIALOG_BASEHISTORY: + loadBaseHistory(req.mToken); + break; + + case WIKIEDITDIALOG_EDITTREE: + loadEditTreeData(req.mToken); + break; + default: + std::cerr << "WikiEditDialog::loadRequest() ERROR: INVALID TYPE"; + std::cerr << std::endl; break; - case TOKENREQ_MSGINFO: - loadPage(req.mToken); - break; - default: - std::cerr << "WikiEditDialog::loadRequest() ERROR: INVALID TYPE"; - std::cerr << std::endl; - break; } } } @@ -307,3 +603,7 @@ void WikiEditDialog::loadRequest(const TokenQueue *queue, const TokenRequest &re + + + + diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h index 851777b73..a3d692af0 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h @@ -48,9 +48,13 @@ private slots: void cancelEdit(); void revertEdit(); void submitEdit(); +void previewToggle(); +void historyToggle(); private: +void redrawPage(); + void setGroup(RsWikiCollection &group); void setPreviousPage(RsWikiSnapshot &page); @@ -59,9 +63,23 @@ void loadPage(const uint32_t &token); void requestGroup(const std::string &groupId); void loadGroup(const uint32_t &token); +void requestBaseHistory(const RsGxsGrpMsgIdPair &origMsgId); +void loadBaseHistory(const uint32_t &token); +void requestEditTreeData(); +void loadEditTreeData(const uint32_t &token); + + + bool mNewPage; + bool mPreviewMode; + bool mPageLoading; + bool mRepublishMode; + + QString mCurrentText; + + RsGxsGrpMsgIdPair mThreadMsgIdPair; RsGxsMessageId mRepublishOrigId; RsWikiCollection mWikiCollection; diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui index f64b82c6a..5be35a7e5 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui @@ -6,8 +6,8 @@ 0 0 - 647 - 618 + 731 + 701 @@ -28,6 +28,9 @@ QFrame::Raised + frame + frame + frame @@ -38,154 +41,192 @@ QFrame::Raised - - - - - Wiki Page + + + + + + 0 + 0 + - - - - - Wiki Group: - - - groupBox - - - - - - - true - - - - - - - Qt::Horizontal - - - - 168 - 20 - - - - - - - - Page Name: - - - - - - - - 10 - 0 - - - - - - - - Edit ID - - - - - - - - - - Previous Version - - - - - - - - 10 - 0 - - - - true - - - - - - - Prev ID - - - - - - - - 1 - 0 - - - - true - - - - + + Qt::Horizontal + + + + + 75 + true + + + + Page Edit History + + + + + + + By + + + + + When + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Wiki Page + + + + + + Wiki Group: + + + groupBox + + + + + + + true + + + + + + + Page Name: + + + + + + + + 10 + 0 + + + + + + + + Previous Version + + + + + + + + 10 + 0 + + + + true + + + + + + + + + + + + Show Edit History + + + + + + + Qt::Horizontal + + + + 178 + 20 + + + + + + + + Preview + + + + + + + + + + + + + + Cancel + + + + + + + Revert + + + + + + + Qt::Horizontal + + + + 228 + 20 + + + + + + + + Submit + + + + + + + - - - - - - - - - Cancel - - - - - - - Revert - - - - - - - Qt::Horizontal - - - - 228 - 20 - - - - - - - - Submit - - - - - From e1423919aa4784ff12ecbdffd194a5db87c8a695 Mon Sep 17 00:00:00 2001 From: drbob Date: Sat, 1 Dec 2012 22:53:50 +0000 Subject: [PATCH 194/222] Improvements to WikiEditDialog - Make Details togglable - Keep track of Modified state. - Add peg-markdown Renderer (disabled until I sort out support library). - Fix up Submit to submit correct text and handle Utf8 git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5925 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/gui/WikiPoos/WikiEditDialog.cpp | 93 +++++++- .../src/gui/WikiPoos/WikiEditDialog.h | 4 + .../src/gui/WikiPoos/WikiEditDialog.ui | 206 ++++++++++++------ 3 files changed, 232 insertions(+), 71 deletions(-) diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp index dbbab0c98..1214fda38 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp @@ -26,6 +26,12 @@ #include +//#define USE_PEGMMD_RENDERER 1 + +#ifdef USE_PEGMMD_RENDERER +#include "markdown_lib.h" +#endif + #define WIKIEDITDIALOG_GROUP 0x0001 #define WIKIEDITDIALOG_PAGE 0x0002 @@ -43,14 +49,68 @@ WikiEditDialog::WikiEditDialog(QWidget *parent) connect(ui.pushButton_Submit, SIGNAL( clicked( void ) ), this, SLOT( submitEdit( void ) ) ); connect(ui.pushButton_Preview, SIGNAL( clicked( void ) ), this, SLOT( previewToggle( void ) ) ); connect(ui.pushButton_History, SIGNAL( clicked( void ) ), this, SLOT( historyToggle( void ) ) ); + connect(ui.toolButton_Show, SIGNAL( clicked( void ) ), this, SLOT( detailsToggle( void ) ) ); + connect(ui.toolButton_Hide, SIGNAL( clicked( void ) ), this, SLOT( detailsToggle( void ) ) ); + connect(ui.textEdit, SIGNAL( textChanged( void ) ), this, SLOT( textChanged( void ) ) ); mWikiQueue = new TokenQueue(rsWiki->getTokenService(), this); mRepublishMode = false; mPreviewMode = false; mPageLoading = false; + mTextChanged = false; mCurrentText = ""; ui.groupBox_History->hide(); + detailsToggle(); +} + +void WikiEditDialog::textChanged() +{ + mTextChanged = true; + ui.pushButton_Revert->setEnabled(true); + ui.pushButton_Submit->setEnabled(true); + ui.label_Status->setText("Modified"); +} + + +void WikiEditDialog::textReset() +{ + mTextChanged = false; + ui.pushButton_Revert->setEnabled(false); + ui.pushButton_Submit->setEnabled(false); + ui.label_Status->setText("Original"); +} + + + +void WikiEditDialog::detailsToggle() +{ + std::cerr << "WikiEditDialog::detailsToggle()"; + std::cerr << std::endl; + if (ui.toolButton_Hide->isHidden()) + { + ui.toolButton_Hide->show(); + ui.toolButton_Show->hide(); + + ui.label_PrevVersion->show(); + ui.label_Group->show(); + ui.label_Tags->show(); + ui.lineEdit_PrevVersion->show(); + ui.lineEdit_Group->show(); + ui.lineEdit_Tags->show(); + } + else + { + ui.toolButton_Hide->hide(); + ui.toolButton_Show->show(); + + ui.label_PrevVersion->hide(); + ui.label_Group->hide(); + ui.label_Tags->hide(); + ui.lineEdit_PrevVersion->hide(); + ui.lineEdit_Group->hide(); + ui.lineEdit_Tags->hide(); + } } void WikiEditDialog::historyToggle() @@ -101,10 +161,25 @@ void WikiEditDialog::redrawPage() if (mPreviewMode) { +#ifdef USE_PEGMMD_RENDERER /* render as HTML */ - QString renderedText = "RENDERED TEXT:\n"; + QByteArray byte_array = mCurrentText.toUtf8(); + + int extensions = 0; + char *answer = markdown_to_string(byte_array.data(), extensions, HTML_FORMAT); + + QString renderedText = QString::fromUtf8(answer); + ui.textEdit->setHtml(renderedText); + + // free answer. + free(answer); +#else + /* render as HTML */ + QString renderedText = "IN (dummy) RENDERED TEXT MODE:\n"; renderedText += mCurrentText; ui.textEdit->setPlainText(renderedText); +#endif + /* disable edit */ ui.textEdit->setReadOnly(true); @@ -143,6 +218,7 @@ void WikiEditDialog::setPreviousPage(RsWikiSnapshot &page) ui.lineEdit_PrevVersion->setText(QString::fromStdString(mWikiSnapshot.mMeta.mMsgId)); mCurrentText = QString::fromUtf8(mWikiSnapshot.mPage.c_str()); redrawPage(); + textReset(); } @@ -163,6 +239,7 @@ void WikiEditDialog::setNewPage() ui.headerFrame->setHeaderText(tr("Create New Wiki Page")); setWindowTitle(tr("Create New Wiki Page")); + textReset(); } @@ -192,6 +269,7 @@ void WikiEditDialog::revertEdit() mCurrentText = QString::fromUtf8(mWikiSnapshot.mPage.c_str()); } redrawPage(); + textReset(); } @@ -255,7 +333,18 @@ void WikiEditDialog::submitEdit() mWikiSnapshot.mMeta.mMsgName = ui.lineEdit_Page->text().toStdString(); - mWikiSnapshot.mPage = ui.textEdit->toPlainText().toStdString(); + + if (!mPreviewMode) + { + /* can just use the current text */ + mCurrentText = ui.textEdit->toPlainText(); + } + + { + // complicated way of preserving Utf8 text */ + QByteArray byte_array = mCurrentText.toUtf8(); + mWikiSnapshot.mPage = std::string(byte_array.data()); + } std::cerr << "WikiEditDialog::submitEdit() PageTitle: " << mWikiSnapshot.mMeta.mMsgName; std::cerr << std::endl; diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h index a3d692af0..4ed4dd6d1 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h @@ -50,6 +50,9 @@ void revertEdit(); void submitEdit(); void previewToggle(); void historyToggle(); +void detailsToggle(); +void textChanged(); +void textReset(); private: @@ -76,6 +79,7 @@ void loadEditTreeData(const uint32_t &token); bool mPageLoading; bool mRepublishMode; + bool mTextChanged; QString mCurrentText; diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui index 5be35a7e5..48ce285cb 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui @@ -28,9 +28,6 @@ QFrame::Raised - frame - frame - frame @@ -54,12 +51,6 @@ Qt::Horizontal - - - 75 - true - - Page Edit History @@ -87,69 +78,139 @@ QFrame::Raised - + - - - Wiki Page - - - - - - Wiki Group: + + + + + + + \/ + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 10 + 0 + + + + + + + + /\ + + + + + + + + + + 0 + 0 + + + + + 0 - - groupBox + + 0 - - - - - - true - - - - - - - Page Name: - - - - - - - - 10 - 0 - - - - - - - - Previous Version - - - - - - - - 10 - 0 - - - - true - - - - - + + + + Wiki Group: + + + frame + + + + + + + true + + + + + + + Page Name: + + + + + + + + 10 + 0 + + + + + + + + Previous Version + + + + + + + + 10 + 0 + + + + true + + + + + + + Tags + + + + + + + + 10 + 0 + + + + + + + true + + + + + + + @@ -173,6 +234,13 @@ + + + + Status + + + From 700c6e316e169e5917230cd8e185b952d1d4551b Mon Sep 17 00:00:00 2001 From: defnax Date: Sun, 2 Dec 2012 14:04:41 +0000 Subject: [PATCH 195/222] fixed background of the icons git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5927 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../gui/PhotoShare/images/album_subscribe.png | Bin 1813 -> 2250 bytes .../PhotoShare/images/album_unsubscribe.png | Bin 1761 -> 2193 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/retroshare-gui/src/gui/PhotoShare/images/album_subscribe.png b/retroshare-gui/src/gui/PhotoShare/images/album_subscribe.png index 3ba182fe52e8c9695325fb6dab004874d4f519e7..fa66be123b83b17e57da04bb8d1d944ab4d1f17c 100644 GIT binary patch delta 2213 zcmV;W2wL}*4$2Xb85;%w009JjN@4&200(qQO+^RX3<3@U77DGYr;#)#e+XGgL_t(| z+TB-sa8y?r|DAL1KC{`~unC(d6jBL&SQ`jw+M#A@1X|IlL|UXZV=D}Gnzo3jQw0Zv zkkQ&Hr5(|V&h&*;YNcq}4imr%BLcyO0+K*TlaPb}d2g~w_Hpm=JLhha(sW7{$3HyD z?%sRuIp6m?-{bdv7x>6ve^pggt$%F2Ia_Cd&@||Bc2@orOuP6Ll8+y>CSI-N_^koV ze5D=}27Bm*7NMH}=X9sppci~L3m0Bqi@Rt26Qz|+z-@~ma*H8^X^QvmWkRXNCk&!4Ql_q3*`%Sa6d=g-V4CI!@wISBBH!vtDwc=mrG|0(en=>`f7x^9wHKn35E=a zqC#LYttigrcsT0@e|YEIf$sND!oT9+m5ARgz^ZuLULjg`iTDS*#iy{sr?gY)_CWSc zSx%4zV3Mx{MT=lUxq&hA8DxMk`e)GTUQoa>Q^SGvd6q9r=44}fsvV{gBOgnLC!~|5 zgphtGA+%X4kaJR~X|nNXnVyr1OfM%56f-o>T~0U-JcZ`ze=Cp?AY>HXOd^uc=ueRC zIM--r+!8P&7)QV@ffCes4B2OQAazzA%2yX+OL-%ZcQX*{A$3l2STE4gix5qtC}IhC zYxQ!ZWMm;2%)pGPZs2o8*t+9o++UJ|(EAPWmOeu+cz`y1n|!qzp>h{`qtb&kq!Fb< zKkn1I^J#JVe{M>FkxtRG+)AVFm70k6H;Lo-jt0V2#+h$2b4o5_x{uDRF~o;V40oD% z^@wfP69*!t|CLy{_CUHO0n!kKKRQME1(}l+ffR`pdxl8~N+-xq^r%Y7WS4uS421G{TFvF&h;jN$|W*AM|G>yl<|=Nb%nb8zU)MO1_w z(B@>4k>n9$z;*P~*@=bIhSAWIHhzSulag?@;Vgds$a2&jJE{)-=zWV|CK=E&?+5ZX z5CY1?s+mChFrwW+*$pa{pe(WN2WxTWjVhGffBt#=>Gf)S@3FP;XWWXR0m^RE1)Qn` zenRH|ay=rBObk$FH+99v5!4P;g7^geeZcvyN{A3ZdvVdjko?+n2rPLLj&%lxR&lsD zo2dH&N7$?z7f`c1_OW65!9zB<^5=r5PD8AAGqlo`fDwT+jp18&K8cpA#d*ua1m;%- ze>|jT})?W+F5rxtG7er6&M`w>I z?t0rOzV=-He;AUF#DawjVMgQsbLG|5dlVhDk@D=jHlD+0((S}&8adXG*c89X{AS#= z?nj4d^*B61AF`0jdrk77Dx}t0Q^>uPf1@OmscR{dsBGB8?;g!mYxGf>NiGMHoGwx= zh1!)C0gGj&IE%cjZ$5fOS~)2g>oSNtZQNo#37E?^Kr)*oVkUW1AWmy^laHNc41mX< z47-P`9)jrHqGT!D;wVMe+$!C48WKwUIQq=OLeFVJSiG&s+z?hjBI#3tlz>cHe-qWU zi2(dQCwv~&#;EF`SuKqvNGhj}fjNALIyhYM2pnXwaL)jk&XFL}G46%}AuJ0j0Q8Yy zs40q*kC@$N`SHU5QoRJgD=cO5p#fEX3~IGBqU$*Ip|0H<;STpA92-H!&SpGa^ESE~ zh3d#u!QedM8mL}KS&io1$#g*Ke~q2Qry(k37uqlpK)|oT?~&0(=8=t)u>5RG*U-E7 zAd*h+#F2Uf=|MLhUq)FIeh0RV1^CW_%V1IJxRZT^FqO0gNU8_w1ZF=lM9h1>7vkgq zhTCI!Zac%~?qodCceoTklXzX!7Kqmn~)B1Gk+{WYNZ9UwfQaA1f^{h$H&5b)RnhWGx^ zGcg8^R=tS&6E!%z?=7TG&qh`t4egggD7<9`xxfYwwH3+CiTwOLta@-U(6tLAp%#j0 z0e#yNs^LrM^dxS^T;R?vf50s-kqL=gcHaTx zEV>D{kvIj+AOb0%E~6VmLs3MGK6pGn6VH!zqoe1D>y97=gsfW`~wXmH?e}%f-bozv%=Rn~h z`v)Y``;40?BAJAIh1Nx>D38#o;%gp+YjPPlHJ(ZHzXz=QMeQJrCA6#pPKJ7+0mmP=Ez7L^I z^Wghw6S#LO+P>>Yf4Dt_y0k?h+n1Jwa3#O~dt*ZeW|u9}j!n`H*yunuIvKr*fF&iU z(ikI77-6y!SxS)gItJ|c*^cP^7y3|rO#nv6*2$QYl8HjuTWYeDxDwr{d{ZOEQTmNX n!NSzEoWF$HANSzUhxh*r4~0iPI%wkw00000NkvXXu0mjf#t$w( delta 1773 zcmVbrlRmB~iHa0+a|U)Tbg*s6Z%O zgrEhrB~pn%RnrGZcqkzemnfm7EsmgW!PG4U6Kp53o79f&#I<*A@6PV*&dfRd|Ew*V zKH-PFaCUX(%;kLFfBz5De_F%!9Q?YX|6dRoy}iBHm%#J9-Fx<^N^m{U`}+QD*tU)6 ziThsLyw>In7>nL0P)y-cg}?+;O6ka&7;zj2gc=wJt#GOFUUPiRAf$Ji;hko)MKSdF zdeWdu_5SwshK#A15D)?|BESo$X-OCb1cSUdX<7?lp^kv@B@t?lf3na5x3jsDS~5}f zB86cHGvp|@LC8ErWfX3Yun|oY8Hvv{J|}HL&LlDst)|Zy4S`xRra0rAUqfJ;!jeXa z)Ph9<8G?j`C<$pI7+R7Ms+lP?DHE9#g~q2kVy7vQEWQNAapCBy*ZQ5`Rfo<8spgD{ zy`gsP=GjRRKKEE=>}6T2Sv}*DNt0<`d!sNjJ#~3{E;pO)zp(h_8UMcoahux?CaZ|7 zOZYMaxj**R&Y$fY2{Vo2#%&vJ?Hv8tPkvCB{KA$Of9~JiHNxsS!T?! zq^zxTe^?AI{QAjErui@D-W)i0@q0&qF@EXl?cHtNT`lv4tIW%R2e9`?(0n)ebFla- zOdf+v&w-n#N>&V@prC*Wp=%f3S|Vs%m1#`K^5X1UQ&Xo;oH_HmXNKPxprQ#CbVg%C z(*qyxHnn+ncsRjl!V1G&Wmg6uz8(^rq5cl~f49C4FMSTqpQo}|1iu7+09I5IXq@`_ zqa%X@{k^|$Xlrh&U-kCP;>Ygj5w?so!vZ@e{0*I31}BEQJ8tbz8~wRs7&peLgWNm_ zjsY8Y!fl5j*#&#fLa-zJ>uUjniU)xL;Ve6O>gA!1)~)OIZERh$wuE75=QcGqwRF5M ze{RR0ec`mdn0fN|GRfA^7(=4N$10N%Jv@JheVmquc7Yzz>1;CfJF zjjqOQEP@VTr~o&_p{318SwRBT&qApP{O|*@8-D2Q*l%tB2K(S4+*UgBE&IE7iZwk! z=k~&IKcwD~XfO>I8Q5vaPm4qU0goPZoaA_y^cEibjNJTVdDB;&4}a19%}?R8Wvi`6)-qMm6bsefzk-v(=vWJuGy`h7zrxIV z*?x~)y+8c>Q6wwEGy^rei zCk!_bg=v^L$+E+C4Akf^b=`YoF$isFUf0T2dib3le7$^ldz}$t$CnP^F@!2J9Rij* zc<54?XcMOMrg!)06(1efZ0#CJfBwoM_Z=40aKBaraTzAeAZ=EX(z6WDM;1lNFT2)o z-6uBh`pAkkSaS701{Th}DzTkm+Z5613A;-`#YF`gbGT;xP0hFLz%Ty;iR|K}N?DzQ P00000NkvXXu0mjftM+c3 diff --git a/retroshare-gui/src/gui/PhotoShare/images/album_unsubscribe.png b/retroshare-gui/src/gui/PhotoShare/images/album_unsubscribe.png index 0f4348d4bdbe7c6b27f0033bac3f8baab744344f..0f84b52af1f24fcd8be234785507af5096c3b295 100644 GIT binary patch delta 2156 zcmV-y2$T2W4UrL$85;%w009JjN@4&200(qQO+^RX3<3@SDEa!c_nzmY!n$~7Aoz%>j zRAXn1P9-x<$LZLK60D^nb&6UgX;V@#sBKbWgMua?i=fDx1zC3Q>37ZrNlL5EgvlSh zaQB{b&$-|CJKy*F9>9NGe^PaIb^D?Ay8@~NFhzmN-{$6|V(vl-!=o@>ys=G&%LQ!u zlMmA_sd#rAQ*}U=X{Kn97kyzClK%NCEFd|DwygpdKMIz<3~VY*fLThd0 zzJLxLs!UVHpAbqUCL0?H(<4}!8-y>xkFKA*fTpriWEU0VgO4sve;0X*WbAjl*$_Ri zJ^W3ETV1yVDJ|RF!qSt?G}Ix1L6PW}0IGEFdfW%qpXz}(UY^_!MP`s_QIU;z@|>U( zsVNR5G#^0Q&Tn9L(1rB$I9&MPsPRo@;~0B->uVe>`}S8JV$q_<*^eJt&&Z5yY;2rK z@PjSM2a;%qJ5@zoe|-w(|NRo0N}SlStLM{*k7eh0&XS}fZtK1pdfw6ow{rt=GHM9O@I~RVai9b>I*vf|Z{f|&MA47FjPdqXbXJz*`%OdWKePv5%FD)v75C$@ z-)zSZ4jeOV@ajutfq4Hc_!U;wkZ`U?Puj8tXKf2xd;{o?!!l5MZ-ge-NFZv03mQLc4&-^Q_1O6B8n! zDrpE$Y!Cvh4vl^_p_hnCS{Y=M4N`QJv>U<{PGiAkS;T@%k*5T>oMyps(oImKh`4OH zy15XUFCRy^Z)_@%_zyv#6T##r0eu225N|Od&Z@v=SKyvwLu%DVJn+cQ8UL1Ilw?X` z%w63%xfOOguQI+Wc+%5}T4$;Pl>Yx}cjUk9Dr;b4~yAUzUf3QZ! zU?z)&dxs#YvM{e~7{n+90t7QGC;-sS!BA5aB_By9&G6$V0eGDRz{w0{d@%-5eqz*W zDU`0G)Q4IRZ-Fh`hw%7yY^`X;j?+hR?IIH$nJ5^tJmDIMUPxGt-rM5nfYjPsEWjX@ zvdbY%2jFp2EpTvlk$HII#0)=cf5{5^-h2o44=d1cE{0^E4I92gQ4>Cf9Zzn-+D+er z{f||cU$6j5!3yZ()LzlSLzI0QYu-Yr?l5A1J_NsHLTjQ6?IQ!Y+&6${E?)UG0Oxo+ z95FLYRvXNkhWG^P>a5fX{c+&*ZVad&eq3u@ig9j z>j=DQ0nG9wqT|XS@)u-~3p6;Wt%#E>$jQmX#x;+kvAqdzRQ(k{4Eli;`RFFM#G7r1 zq}+i%*^TQ%o$xm_pnGr-f8C4cA(8yP%I(Jbt{!}E(bDMvT3TPk-S=c7Ysq|Q*P}$3 zVR+&}T}BT^Mj{xC^~2$CAt;ZcTW-RLr31^p%CNTU4EisrC{rxxAL>Wfa6gpNokAw( zx>w{81siNS9(clmCq@VT8#Yd3{mJXc6}ICmk1tO<^jC(%W7s_6)*CiJ_k7}&k1L$O$9rW)3I zove{?P;cpILSM#w^DwRv*ARa5@4-<;DFO@|uC8kU00004 delta 1721 zcmV;q21faj5#bGx85;rs008_L?V|ty00(qQO+^RX3lt1F0dX3`Wsx)|e+F<#L_t(| z+TB)bY*a-QJ~MM)yWMWL+ikaxrRCX{f}jOzL;)KT(bN~wsPT`)9~u**iP6OP&-hA= ziSb2Zq6SH91f!sViqZm75U`L6)RqbqDSf)#-R`sdxOc`gch|@2A2H#Nv&r1Kb7#Kq zobQ}7vqT61*Rs)TivGVKe^7dQdaf-&I-TCs(ZRFkwLtIf{Z26q1JO&joLpLKPy&S5 zUpR2WamXzojBw6{ttMt1#RirDLP2mG3Vat7rwLf{n;`fm$V`e2zP?y`kf&O`$g`wc z6NE9a0Ei^O2bEpH7!DE!d9f36%z#+J2F8z)P*Ai*4sbgO&GCXnfBA>X6oqLPMY|P= zOf7VV<8~Vx(S#(E<`aSQ(i@8s6`3Thkjsc{480_TQ$i^%BG5FZtBQrxjMxS#Od1Pz z5z0=&$e|P=UztouXKYE)Xq*)`yX;JSWQz$DhsrbsedCrTH&aE5k_ShtEGc=uAv}{~ zDs@8Syg!IcP<;F`f9a(uGy{qV4BcQFWfVieIGU9=NRnXBxrzvaqQat3IC)R<^4LL_ zRB{`#p%aSGrCom^kocOtSD|)9i4@sJ6EgHnFkR%*=)R3^+mCCB>=9g-t7OZELRiAk zizRaCsza0B3g8TEw=vMznK`1nvpRK}8QtqnhT}w$EYzkUeGR-r^ubQkP{ZtDFl<^_1pD!!;B8d@ZetJF=#A(bk>4+j@^T)~RoIyf+q~uAJZU z>!E{iuK&>&-%5SAPc`FfZ))p!@Ugz1ethe$J4Ja_^K)B@kBVGa<+|o@>Z)4qb)vuL zKi^tie;xRKc%*Om(u*H&AN^%|!}^8mSJnSIq09v7%N3sA~&azs{ncX#)?bsP2!bAPFtiOpP|4xjqrz=7SJL;Zd7(1a`o z!|$uRuf0tZ+IV*8n-e3!cfZnp8HPQ(tP(F=a9RTs z8ke3Oo9Vl4Wr5)F=U+W{rtf&qUf;q%T}9>ibgXSfBQsPNQFJgOEO%?mb!V;&wKjPJ zuGJ5{@WQEv+GWE(2XkrAot3_d$UXO_Cnsx8oCwBZkV;l+>Sd2-!BlAf*SiZ6O&l3) zf11Cd;qJ!yHMMh?hDM~>UsvC>+-11BzTIQQ!od(Tpzh3&Z^SWv^Rl%!p6WhpsI{rs z@m!W9W> zW?i*qj=-EnweaY8G$E!gMr!Ak-&n&pf9y|mmb&8c#1z2A^Fv^tiavltls#F_?zlfw z6y&4FMSSj@!-W?Em}y9+p+vt>h1Hk>VZvYn=DDDLp;D%s!Uricq7rDk4|bgPJ}_A^ zF?Kok`yIKU(!ayUm){T^8YnI_n1o9N3=hP|fjObt2~$}JF^B+^y1}VIItsI+f96jV zq6Ewglv41{hsUqvGMOx{QEl^60I^K^p19}Hei*w_OpwX^VZ^^}{qq_!!HM$%ngA+o zf=PgIEV?+E`ZVib6Dph)GK;PjT5wJ_Z+53rK_SWkDlmkttB9_-jvd2zL;(VdHe2S% zZ0}^cu58@6@v6{svr*W#?Z;#if0b!KEPyVLr=?{Hl$7)h58f4yUIYl5SzjnS@5AlJ zyKmz0aMkUw&wU2q0tySzSyef;tT{hFv1V1LzZ(BwjbNs_OHS5Q%bVgq5MVoqLNzb# zY;F!V)cVyKi0p$Lnt+6Az^VEP3`_ P00000NkvXXu0mjfB-Ko~ From bcd67a865192a5b4212f748e692af1548d6094e6 Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 2 Dec 2012 19:01:51 +0000 Subject: [PATCH 196/222] Added random AuthorId to Dummy Wiki pages. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5928 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/services/p3wiki.cc | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/libretroshare/src/services/p3wiki.cc b/libretroshare/src/services/p3wiki.cc index 9b3f01aa4..ea13ef672 100644 --- a/libretroshare/src/services/p3wiki.cc +++ b/libretroshare/src/services/p3wiki.cc @@ -407,6 +407,30 @@ bool generateNextDummyPage(const RsGxsMessageId &threadId, const int lines, cons } +#include + +std::string chooseRandomAuthorId() +{ + /* chose a random Id to sign with */ + std::list ownIds; + std::list::iterator it; + + rsIdentity->getOwnIds(ownIds); + + uint32_t idx = (uint32_t) (ownIds.size() * RSRandom::random_f32()); + int i = 0; + for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); it++, i++); + + std::string answer; + if (it != ownIds.end()) + { + answer = *it; + } + return answer; +} + + + void p3Wiki::dummyTick() { if (mAboutActive) @@ -437,6 +461,7 @@ void p3Wiki::dummyTick() page.mMeta.mGroupId = groupId; page.mPage = "Baseline page... a placeholder for About Wiki"; page.mMeta.mMsgName = "About RsWiki"; + page.mMeta.mAuthorId = chooseRandomAuthorId(); submitSnapshot(mAboutToken, page); mAboutLines++; @@ -459,6 +484,7 @@ void p3Wiki::dummyTick() RsWikiSnapshot page; page.mMeta.mMsgName = "About RsWiki"; + page.mMeta.mAuthorId = chooseRandomAuthorId(); if (!generateNextDummyPage(mAboutThreadId, mAboutLines, msgId, about_txt, about_len, page)) { std::cerr << "About Pages Done"; @@ -502,6 +528,7 @@ void p3Wiki::dummyTick() page.mMeta.mGroupId = groupId; page.mPage = "Baseline page... a placeholder for Improv Wiki"; page.mMeta.mMsgName = "Improv RsWiki"; + page.mMeta.mAuthorId = chooseRandomAuthorId(); submitSnapshot(mImprovToken, page); mImprovLines++; @@ -524,6 +551,7 @@ void p3Wiki::dummyTick() RsWikiSnapshot page; page.mMeta.mMsgName = "Improv RsWiki"; + page.mMeta.mAuthorId = chooseRandomAuthorId(); if (!generateNextDummyPage(mImprovThreadId, mImprovLines, msgId, improvements_txt, improvements_len, page)) { std::cerr << "Improv Pages Done"; From 083c4411b8939072a96f87d639a422c57594451e Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 2 Dec 2012 19:06:43 +0000 Subject: [PATCH 197/222] More improvements to Wiki, mainly EditMode. - Fixed display of Edit History. (Date, Author, PageId) - Added GxsId for Author Display. - Enabled/Disabled History depending on Modification & oldHistory flags. - Fixed bug where preview triggered Modification Flag. - Switched WikiDialog to Rendered Mode, and removed spacer. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5929 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/gui/WikiPoos/WikiDialog.cpp | 25 ++- retroshare-gui/src/gui/WikiPoos/WikiDialog.ui | 30 +-- .../src/gui/WikiPoos/WikiEditDialog.cpp | 179 ++++++++++++++++-- .../src/gui/WikiPoos/WikiEditDialog.h | 13 ++ .../src/gui/WikiPoos/WikiEditDialog.ui | 16 +- 5 files changed, 221 insertions(+), 42 deletions(-) diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp index 74624dee4..71cbc6fb4 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp @@ -28,7 +28,7 @@ #include "gui/WikiPoos/WikiAddDialog.h" #include "gui/WikiPoos/WikiEditDialog.h" -#include "gui/gxs/WikiGroupDialog.h" +#include "gui/gxs/WikiGroupDialog.h" #include @@ -37,6 +37,12 @@ #include +//#define USE_PEGMMD_RENDERER 1 + +#ifdef USE_PEGMMD_RENDERER +#include "markdown_lib.h" +#endif + /****** * #define WIKI_DEBUG 1 *****/ @@ -318,7 +324,22 @@ void WikiDialog::modTreeChanged() void WikiDialog::updateWikiPage(const RsWikiSnapshot &page) { - ui.textBrowser->setPlainText(QString::fromStdString(page.mPage)); +#ifdef USE_PEGMMD_RENDERER + /* render as HTML */ + int extensions = 0; + char *answer = markdown_to_string((char *) page.mPage.c_str(), extensions, HTML_FORMAT); + + QString renderedText = QString::fromUtf8(answer); + ui.textBrowser->setHtml(renderedText); + + // free answer. + free(answer); +#else + /* render as HTML */ + QString renderedText = "IN (dummy) RENDERED TEXT MODE:\n"; + renderedText += QString::fromStdString(page.mPage); + ui.textBrowser->setPlainText(renderedText); +#endif } diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui index 88ddd18bd..b8e2e6341 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui @@ -6,7 +6,7 @@ 0 0 - 902 + 918 669 @@ -109,8 +109,8 @@ 0 0 - 271 - 302 + 241 + 307 @@ -154,8 +154,8 @@ 0 0 - 271 - 302 + 241 + 294 @@ -436,8 +436,8 @@ 0 0 - 600 - 611 + 645 + 609 @@ -455,22 +455,6 @@ - - - - Qt::Vertical - - - QSizePolicy::MinimumExpanding - - - - 0 - 0 - - - - diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp index 1214fda38..4661f960d 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp @@ -21,7 +21,9 @@ * */ +#include +#include "gui/gxs/GxsIdTreeWidgetItem.h" #include "gui/WikiPoos/WikiEditDialog.h" #include @@ -36,7 +38,21 @@ #define WIKIEDITDIALOG_GROUP 0x0001 #define WIKIEDITDIALOG_PAGE 0x0002 #define WIKIEDITDIALOG_BASEHISTORY 0x0003 -#define WIKIEDITDIALOG_EDITTREE 0x0005 +#define WIKIEDITDIALOG_EDITTREE 0x0004 + + +#define WET_COL_DATE 0 +#define WET_COL_AUTHORID 1 +#define WET_COL_PAGEID 2 + +#define WET_DATA_COLUMN 0 + +#define WET_ROLE_ORIGPAGEID Qt::UserRole +#define WET_ROLE_PAGEID Qt::UserRole + 1 +#define WET_ROLE_PARENTID Qt::UserRole + 2 + +#define WET_ROLE_SORT Qt::UserRole + 3 + /** Constructor */ WikiEditDialog::WikiEditDialog(QWidget *parent) @@ -52,36 +68,126 @@ WikiEditDialog::WikiEditDialog(QWidget *parent) connect(ui.toolButton_Show, SIGNAL( clicked( void ) ), this, SLOT( detailsToggle( void ) ) ); connect(ui.toolButton_Hide, SIGNAL( clicked( void ) ), this, SLOT( detailsToggle( void ) ) ); connect(ui.textEdit, SIGNAL( textChanged( void ) ), this, SLOT( textChanged( void ) ) ); + connect(ui.checkBox_OldHistory, SIGNAL( clicked( void ) ), this, SLOT( oldHistoryChanged( void ) ) ); + connect(ui.treeWidget_History, SIGNAL( itemSelectionChanged( void ) ), this, SLOT( historySelected( void ) ) ); mWikiQueue = new TokenQueue(rsWiki->getTokenService(), this); + + mThreadCompareRole = new RSTreeWidgetItemCompareRole; + mThreadCompareRole->setRole(WET_COL_DATE, WET_ROLE_SORT); + mRepublishMode = false; mPreviewMode = false; mPageLoading = false; mTextChanged = false; mCurrentText = ""; + ui.checkBox_OldHistory->setChecked(false); + mOldHistoryEnabled = false; ui.groupBox_History->hide(); detailsToggle(); } +WikiEditDialog::~WikiEditDialog() +{ + delete (mThreadCompareRole); +} + void WikiEditDialog::textChanged() { + std::cerr << "WikiEditDialog::textChanged()" << std::endl; + mTextChanged = true; ui.pushButton_Revert->setEnabled(true); ui.pushButton_Submit->setEnabled(true); ui.label_Status->setText("Modified"); + + // Disable Selection in Edit History. + ui.treeWidget_History->setSelectionMode(QAbstractItemView::NoSelection); + updateHistoryStatus(); + + // unselect anything. } void WikiEditDialog::textReset() { + std::cerr << "WikiEditDialog::textReset()" << std::endl; + mTextChanged = false; ui.pushButton_Revert->setEnabled(false); ui.pushButton_Submit->setEnabled(false); ui.label_Status->setText("Original"); + + // Enable Selection in Edit History. + ui.treeWidget_History->setSelectionMode(QAbstractItemView::SingleSelection); + updateHistoryStatus(); +} + +void WikiEditDialog::historySelected() +{ + std::cerr << "WikiEditDialog::historySelected()" << std::endl; } +void WikiEditDialog::oldHistoryChanged() +{ + mOldHistoryEnabled = ui.checkBox_OldHistory->isChecked(); + updateHistoryStatus(); +} + + +void WikiEditDialog::updateHistoryStatus() +{ + /* iterate through every History Item */ + int count = ui.treeWidget_History->topLevelItemCount(); + for(int i = 0; i < count; i++) + { + QTreeWidgetItem *item = ui.treeWidget_History->topLevelItem(i); + bool isLatest = (i==count-1); + updateHistoryChildren(item, isLatest); + updateHistoryItem(item, isLatest); + } +} + +void WikiEditDialog::updateHistoryChildren(QTreeWidgetItem *item, bool isLatest) +{ + int count = item->childCount(); + for(int i = 0; i < count; i++) + { + QTreeWidgetItem *child = item->child(i); + + if (child->childCount() > 0) + { + updateHistoryChildren(child, isLatest); + } + updateHistoryItem(child, isLatest); + } +} + + +void WikiEditDialog::updateHistoryItem(QTreeWidgetItem *item, bool isLatest) +{ + bool isSelectable = true; + if (mTextChanged) + { + isSelectable = false; + } + else if ((!mOldHistoryEnabled) && (!isLatest)) + { + isSelectable = false; + } + + if (isSelectable) + { + item->setFlags(Qt::ItemIsSelectable | + Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); + } + else + { + item->setFlags(0); + } +} void WikiEditDialog::detailsToggle() { @@ -135,6 +241,8 @@ void WikiEditDialog::previewToggle() std::cerr << "WikiEditDialog::previewToggle()"; std::cerr << std::endl; + bool prevTextChanged = mTextChanged; + if (mPreviewMode) { mPreviewMode = false; @@ -151,6 +259,15 @@ void WikiEditDialog::previewToggle() { redrawPage(); } + + /* fix textChanged signal - if we have caused it to change */ + if (!prevTextChanged) + { + textReset(); + } + + std::cerr << "WikiEditDialog::previewToggle() END"; + std::cerr << std::endl; } @@ -475,10 +592,6 @@ void WikiEditDialog::loadPage(const uint32_t &token) /*********************** LOAD EDIT HISTORY **********************/ -#define WIKIEDITTREE_COL_ORIGPAGEID 0 -#define WIKIEDITTREE_COL_PAGEID 1 -#define WIKIEDITTREE_COL_PARENTID 2 - void WikiEditDialog::requestBaseHistory(const RsGxsGrpMsgIdPair &origMsgId) { RsTokReqOptions opts; @@ -521,10 +634,27 @@ void WikiEditDialog::loadBaseHistory(const uint32_t &token) std::cerr << " ParentId: " << page.mMeta.mParentId; std::cerr << std::endl; - QTreeWidgetItem *modItem = new QTreeWidgetItem(); - modItem->setText(WIKIEDITTREE_COL_ORIGPAGEID, QString::fromStdString(page.mMeta.mOrigMsgId)); - modItem->setText(WIKIEDITTREE_COL_PAGEID, QString::fromStdString(page.mMeta.mMsgId)); - modItem->setText(WIKIEDITTREE_COL_PARENTID, QString::fromStdString(page.mMeta.mParentId)); + GxsIdTreeWidgetItem *modItem = new GxsIdTreeWidgetItem(mThreadCompareRole); + modItem->setData(WET_DATA_COLUMN, WET_ROLE_ORIGPAGEID, QString::fromStdString(page.mMeta.mOrigMsgId)); + modItem->setData(WET_DATA_COLUMN, WET_ROLE_PAGEID, QString::fromStdString(page.mMeta.mMsgId)); + + modItem->setData(WET_DATA_COLUMN, WET_ROLE_PARENTID, QString::fromStdString(page.mMeta.mParentId)); + + { + // From Forum stuff. + QDateTime qtime; + QString text; + QString sort; + qtime.setTime_t(page.mMeta.mPublishTs); + sort = qtime.toString("yyyyMMdd_hhmmss"); + text = qtime.toString("dd/MM/yy hh:mm"); + + modItem->setText(WET_COL_DATE, text); + modItem->setData(WET_COL_DATE, WET_ROLE_SORT, sort); + } + modItem->setId(page.mMeta.mAuthorId, WET_COL_AUTHORID); + modItem->setText(WET_COL_PAGEID, QString::fromStdString(page.mMeta.mMsgId)); + ui.treeWidget_History->addTopLevelItem(modItem); } @@ -583,7 +713,7 @@ void WikiEditDialog::loadEditTreeData(const uint32_t &token) QTreeWidgetItem *item = ui.treeWidget_History->topLevelItem(nIndex); /* index by MsgId --> ONLY For Wiki Thread Head Items... SPECIAL HACK FOR HERE! */ - std::string msgId = item->text(WIKIEDITTREE_COL_PAGEID).toStdString(); + std::string msgId = item->data(WET_DATA_COLUMN, WET_ROLE_PAGEID).toString().toStdString(); items[msgId] = item; } @@ -619,10 +749,25 @@ void WikiEditDialog::loadEditTreeData(const uint32_t &token) } /* create an Entry */ - QTreeWidgetItem *modItem = new QTreeWidgetItem(); - modItem->setText(WIKIEDITTREE_COL_ORIGPAGEID, QString::fromStdString(snapshot.mMeta.mOrigMsgId)); - modItem->setText(WIKIEDITTREE_COL_PAGEID, QString::fromStdString(snapshot.mMeta.mMsgId)); - modItem->setText(WIKIEDITTREE_COL_PARENTID, QString::fromStdString(snapshot.mMeta.mParentId)); + GxsIdTreeWidgetItem *modItem = new GxsIdTreeWidgetItem(mThreadCompareRole); + modItem->setData(WET_DATA_COLUMN, WET_ROLE_ORIGPAGEID, QString::fromStdString(snapshot.mMeta.mOrigMsgId)); + modItem->setData(WET_DATA_COLUMN, WET_ROLE_PAGEID, QString::fromStdString(snapshot.mMeta.mMsgId)); + modItem->setData(WET_DATA_COLUMN, WET_ROLE_PARENTID, QString::fromStdString(snapshot.mMeta.mParentId)); + + { + // From Forum stuff. + QDateTime qtime; + QString text; + QString sort; + qtime.setTime_t(snapshot.mMeta.mPublishTs); + sort = qtime.toString("yyyyMMdd_hhmmss"); + text = qtime.toString("dd/MM/yy hh:mm"); + + modItem->setText(WET_COL_DATE, text); + modItem->setData(WET_COL_DATE, WET_ROLE_SORT, sort); + } + modItem->setId(snapshot.mMeta.mAuthorId, WET_COL_AUTHORID); + modItem->setText(WET_COL_PAGEID, QString::fromStdString(snapshot.mMeta.mMsgId)); /* find the parent */ iit = items.find(snapshot.mMeta.mParentId); @@ -639,7 +784,8 @@ void WikiEditDialog::loadEditTreeData(const uint32_t &token) for(uit = unparented.begin(); uit != unparented.end(); uit++) { - std::string parentId = (*uit)->text(WIKIEDITTREE_COL_PARENTID).toStdString(); + std::string parentId = (*uit)->data(WET_DATA_COLUMN, WET_ROLE_PARENTID).toString().toStdString(); + iit = items.find(parentId); if (iit != items.end()) @@ -653,6 +799,9 @@ void WikiEditDialog::loadEditTreeData(const uint32_t &token) std::cerr << std::endl; } } + + // Enable / Disable Items. + updateHistoryStatus(); } diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h index 4ed4dd6d1..903e9b601 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h @@ -29,12 +29,15 @@ #include #include "util/TokenQueue.h" +class RSTreeWidgetItemCompareRole; + class WikiEditDialog : public QWidget, public TokenResponse { Q_OBJECT public: WikiEditDialog(QWidget *parent = 0); + ~WikiEditDialog(); void setNewPage(); @@ -54,8 +57,15 @@ void detailsToggle(); void textChanged(); void textReset(); +void historySelected(); +void oldHistoryChanged(); + private: +void updateHistoryStatus(); +void updateHistoryChildren(QTreeWidgetItem *item, bool isLatest); +void updateHistoryItem(QTreeWidgetItem *item, bool isLatest); + void redrawPage(); void setGroup(RsWikiCollection &group); @@ -77,6 +87,7 @@ void loadEditTreeData(const uint32_t &token); bool mPreviewMode; bool mPageLoading; + bool mOldHistoryEnabled; bool mRepublishMode; bool mTextChanged; @@ -91,6 +102,8 @@ void loadEditTreeData(const uint32_t &token); Ui::WikiEditDialog ui; + RSTreeWidgetItemCompareRole *mThreadCompareRole; + TokenQueue *mWikiQueue; }; diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui index 48ce285cb..db2c0df5f 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui @@ -54,9 +54,21 @@ Page Edit History - + + + + + Enable Obsolete Edits + + + + + + Publish Date + + By @@ -64,7 +76,7 @@ - When + PageId From bcf9f443b41bbd68a6ceea03574754f0e6b93a3a Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sun, 2 Dec 2012 19:40:17 +0000 Subject: [PATCH 198/222] added option to RsTokReqOptions for group subscription filter added code for rank calculation best,top, and newest (not enabled, not working yet...) added variables for circles to grp meta type and modified storage and serialisation accordingly git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5930 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsdataservice.cc | 27 +- libretroshare/src/gxs/rsgenexchange.cc | 5 +- libretroshare/src/gxs/rsgenexchange.h | 2 +- libretroshare/src/gxs/rsgxsdata.cc | 15 +- libretroshare/src/gxs/rsgxsdata.h | 7 +- libretroshare/src/gxs/rsgxsdataaccess.cc | 104 ++++- libretroshare/src/gxs/rsgxsdataaccess.h | 27 ++ libretroshare/src/gxs/rstokenservice.h | 3 +- libretroshare/src/retroshare/rsposted.h | 18 +- libretroshare/src/serialiser/rsgxsitems.cc | 4 + libretroshare/src/serialiser/rsgxsitems.h | 12 + libretroshare/src/serialiser/rsposteditems.cc | 6 +- libretroshare/src/services/p3posted.cc | 424 +++++++++++++++++- libretroshare/src/services/p3posted.h | 55 ++- 14 files changed, 660 insertions(+), 49 deletions(-) diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index 7f2bb6242..075894e5b 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -51,6 +51,10 @@ #define KEY_KEY_SET std::string("keySet") #define KEY_GRP_NAME std::string("grpName") #define KEY_GRP_SIGN_FLAGS std::string("signFlags") +#define KEY_GRP_CIRCLE_ID std::string("circleId") +#define KEY_GRP_CIRCLE_TYPE std::string("circleType") +#define KEY_GRP_INTERNAL_CIRCLE std::string("internalCircle") +#define KEY_GRP_ORIGINATOR std::string("originator") // grp local #define KEY_GRP_SUBCR_FLAG std::string("subscribeFlag") @@ -98,6 +102,11 @@ #define COL_ORIG_GRP_ID 12 #define COL_GRP_SERV_STRING 13 #define COL_GRP_SIGN_FLAGS 14 +#define COL_GRP_CIRCLE_ID 15 +#define COL_GRP_CIRCL_TYPE 16 +#define COL_GRP_INTERN_CIRCLE 17 +#define COL_GRP_ORIGINATOR 18 + // msg col numbers #define COL_MSG_ID 5 @@ -150,7 +159,8 @@ RsDataService::RsDataService(const std::string &serviceDir, const std::string &d grpMetaColumns.push_back(KEY_KEY_SET); grpMetaColumns.push_back(KEY_GRP_SUBCR_FLAG); grpMetaColumns.push_back(KEY_GRP_POP); grpMetaColumns.push_back(KEY_MSG_COUNT); grpMetaColumns.push_back(KEY_GRP_STATUS); grpMetaColumns.push_back(KEY_GRP_NAME); grpMetaColumns.push_back(KEY_GRP_LAST_POST); grpMetaColumns.push_back(KEY_ORIG_GRP_ID); grpMetaColumns.push_back(KEY_NXS_SERV_STRING); - grpMetaColumns.push_back(KEY_GRP_SIGN_FLAGS); + grpMetaColumns.push_back(KEY_GRP_SIGN_FLAGS); grpMetaColumns.push_back(KEY_GRP_CIRCLE_ID); grpMetaColumns.push_back(KEY_GRP_CIRCLE_TYPE); + grpMetaColumns.push_back(KEY_GRP_INTERNAL_CIRCLE); grpMetaColumns.push_back(KEY_GRP_ORIGINATOR); // for retrieving actual grp data grpColumns.push_back(KEY_GRP_ID); grpColumns.push_back(KEY_NXS_FILE); grpColumns.push_back(KEY_NXS_FILE_OFFSET); @@ -209,6 +219,10 @@ void RsDataService::initialise(){ KEY_NXS_SERV_STRING + " TEXT," + KEY_NXS_FLAGS + " INT," + KEY_GRP_SIGN_FLAGS + " INT," + + KEY_GRP_CIRCLE_ID + " TEXT," + + KEY_GRP_CIRCLE_TYPE + " INT," + + KEY_GRP_INTERNAL_CIRCLE + " TEXT," + + KEY_GRP_ORIGINATOR + " TEXT," + KEY_SIGN_SET + " BLOB);"); } @@ -235,7 +249,7 @@ RsGxsGrpMetaData* RsDataService::getGrpMeta(RetroCursor &c) c.getString(COL_GRP_NAME, grpMeta->mGroupName); c.getString(COL_ORIG_GRP_ID, grpMeta->mOrigGrpId); c.getString(COL_GRP_SERV_STRING, grpMeta->mServiceString); - grpMeta->mSignFlags = c.getInt32(COL_GRP_SIGN_FLAGS); + grpMeta->mSignFlags = c.getInt32(COL_GRP_SIGN_FLAGS); grpMeta->mPublishTs = c.getInt32(COL_TIME_STAMP); grpMeta->mGroupFlags = c.getInt32(COL_NXS_FLAGS); @@ -256,6 +270,11 @@ RsGxsGrpMetaData* RsDataService::getGrpMeta(RetroCursor &c) grpMeta->mLastPost = c.getInt32(COL_GRP_LAST_POST); grpMeta->mGroupStatus = c.getInt32(COL_GRP_STATUS); + c.getString(COL_GRP_CIRCLE_ID, grpMeta->mCircleId); + grpMeta->mCircleType = c.getInt32(COL_GRP_CIRCL_TYPE); + c.getString(COL_GRP_INTERN_CIRCLE, grpMeta->mInternalCircle); + c.getString(COL_GRP_ORIGINATOR, grpMeta->mOriginator); + if(ok) return grpMeta; @@ -539,6 +558,10 @@ int RsDataService::storeGroup(std::map &grp) cv.put(KEY_NXS_FLAGS, (int32_t)grpMetaPtr->mGroupFlags); cv.put(KEY_TIME_STAMP, (int32_t)grpMetaPtr->mPublishTs); cv.put(KEY_GRP_SIGN_FLAGS, (int32_t)grpMetaPtr->mSignFlags); + cv.put(KEY_GRP_CIRCLE_ID, grpMetaPtr->mCircleId); + cv.put(KEY_GRP_CIRCLE_TYPE, (int32_t)grpMetaPtr->mCircleType); + cv.put(KEY_GRP_INTERNAL_CIRCLE, grpMetaPtr->mInternalCircle); + cv.put(KEY_GRP_ORIGINATOR, grpMetaPtr->mOriginator); if(! (grpMetaPtr->mAuthorId.empty()) ){ cv.put(KEY_NXS_IDENTITY, grpMetaPtr->mAuthorId); diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 6a662cc72..2aef41746 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -1570,6 +1570,7 @@ void RsGenExchange::processRecvdMessages() RsGxsMsgMetaData* meta = new RsGxsMsgMetaData(); bool ok = meta->deserialise(msg->meta.bin_data, &(msg->meta.bin_len)); + if(ok) { std::map::iterator mit = grpMetas.find(msg->grpId); @@ -1578,7 +1579,9 @@ void RsGenExchange::processRecvdMessages() if(mit != grpMetas.end()){ RsGxsGrpMetaData* grpMeta = mit->second; ok = true; - //&= validateMsg(msg, grpMeta->mGroupFlags, grpMeta->keys); +// msg->metaData = meta; + // ok &= validateMsg(msg, grpMeta->mGroupFlags, grpMeta->keys); + // msg->metaData = NULL; } else ok = false; diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 06df6ba9e..4d52786d4 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -306,7 +306,7 @@ protected: /*! * Retrieve keys for a given group, \n - * call is blocking retrieval for underlying db + * call is blocking retrieval from underlying db * @warning under normal circumstance a service should not need this * @param grpId the id of the group to retrieve keys for * @param keys this is set to the retrieved keys diff --git a/libretroshare/src/gxs/rsgxsdata.cc b/libretroshare/src/gxs/rsgxsdata.cc index 3e5ee08fa..d60e5f24a 100644 --- a/libretroshare/src/gxs/rsgxsdata.cc +++ b/libretroshare/src/gxs/rsgxsdata.cc @@ -46,7 +46,8 @@ uint32_t RsGxsGrpMetaData::serial_size() s += GetTlvStringSize(mServiceString); s += signSet.TlvSize(); s += keys.TlvSize(); - + s += 4; // for mCircleType + s += GetTlvStringSize(mCircleId); return s; } @@ -67,6 +68,10 @@ void RsGxsGrpMetaData::clear(){ mSubscribeFlags = 0; signSet.TlvClear(); keys.TlvClear(); + mCircleId.clear(); + mInternalCircle.clear(); + mOriginator.clear(); + mCircleType = 0; } @@ -99,8 +104,10 @@ bool RsGxsGrpMetaData::serialise(void *data, uint32_t &pktsize) ok &= SetTlvString(data, tlvsize, &offset, 0, mGroupName); ok &= setRawUInt32(data, tlvsize, &offset, mGroupFlags); ok &= setRawUInt32(data, tlvsize, &offset, mPublishTs); + ok &= setRawUInt32(data, tlvsize, &offset, mCircleType); ok &= SetTlvString(data, tlvsize, &offset, 0, mAuthorId); ok &= SetTlvString(data, tlvsize, &offset, 0, mServiceString); + ok &= SetTlvString(data, tlvsize, &offset, 0, mCircleId); ok &= signSet.SetTlv(data, tlvsize, &offset); ok &= keys.SetTlv(data, tlvsize, &offset); @@ -125,8 +132,10 @@ bool RsGxsGrpMetaData::deserialise(void *data, uint32_t &pktsize) ok &= GetTlvString(data, pktsize, &offset, 0, mGroupName); ok &= getRawUInt32(data, pktsize, &offset, &mGroupFlags); ok &= getRawUInt32(data, pktsize, &offset, &mPublishTs); + ok &= getRawUInt32(data, pktsize, &offset, &mCircleType); ok &= GetTlvString(data, pktsize, &offset, 0, mAuthorId); ok &= GetTlvString(data, pktsize, &offset, 0, mServiceString); + ok &= GetTlvString(data, pktsize, &offset, 0, mCircleId); ok &= signSet.GetTlv(data, pktsize, &offset); ok &= keys.GetTlv(data, pktsize, &offset); @@ -257,6 +266,10 @@ void RsGxsGrpMetaData::operator =(const RsGroupMetaData& rMeta) this->mGroupName = rMeta.mGroupName; this->mServiceString = rMeta.mServiceString; this->mSignFlags = rMeta.mSignFlags; + this->mCircleId = rMeta.mCircleId; + this->mCircleType = rMeta.mCircleType; + this->mInternalCircle = rMeta.mInternalCircle; + this->mOriginator = rMeta.mOriginator; } void RsGxsMsgMetaData::operator =(const RsMsgMetaData& rMeta) diff --git a/libretroshare/src/gxs/rsgxsdata.h b/libretroshare/src/gxs/rsgxsdata.h index 88d4044f1..9452c364b 100644 --- a/libretroshare/src/gxs/rsgxsdata.h +++ b/libretroshare/src/gxs/rsgxsdata.h @@ -27,7 +27,6 @@ */ #include - #include "serialiser/rsserial.h" #include "serialiser/rstlvtypes.h" #include "serialiser/rstlvkeys.h" @@ -59,6 +58,9 @@ public: uint32_t mSignFlags; std::string mAuthorId; + std::string mCircleId; + uint32_t mCircleType; + RsTlvKeySignatureSet signSet; RsTlvSecurityKeySet keys; @@ -74,7 +76,8 @@ public: time_t mLastPost; // ??? uint32_t mGroupStatus; - + std::string mOriginator; + std::string mInternalCircle; }; diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index af45bbdca..3a62b7559 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -771,9 +771,15 @@ void RsGxsDataAccess::processRequests() bool RsGxsDataAccess::getGroupData(GroupDataReq* req) { std::map grpData; + std::list grpIdsOut; - std::list::iterator lit = req->mGroupIds.begin(), - lit_end = req->mGroupIds.end(); + getGroupList(req->mGroupIds, req->Options, grpIdsOut); + + if(grpIdsOut.empty()) + return true; + + std::list::iterator lit = grpIdsOut.begin(), + lit_end = grpIdsOut.end(); for(; lit != lit_end; lit++) { @@ -794,9 +800,16 @@ bool RsGxsDataAccess::getGroupSummary(GroupMetaReq* req) std::map grpMeta; - std::list::const_iterator lit = req->mGroupIds.begin(); + std::list grpIdsOut; - for(; lit != req->mGroupIds.end(); lit++) + getGroupList(req->mGroupIds, req->Options, grpIdsOut); + + if(grpIdsOut.empty()) + return true; + + std::list::const_iterator lit = grpIdsOut.begin(); + + for(; lit != grpIdsOut.end(); lit++) grpMeta[*lit] = NULL; mDataStore->retrieveGxsGrpMetaData(grpMeta); @@ -811,24 +824,37 @@ bool RsGxsDataAccess::getGroupSummary(GroupMetaReq* req) bool RsGxsDataAccess::getGroupList(GroupIdReq* req) { - std::map grpMeta; + getGroupList(req->mGroupIds, req->Options, req->mGroupIdResult); - std::list::const_iterator lit = req->mGroupIds.begin(); + return true; +} - for(; lit != req->mGroupIds.end(); lit++) - grpMeta[*lit] = NULL; +bool RsGxsDataAccess::getGroupList(const std::list& grpIdsIn, const RsTokReqOptions& opts, std::list& grpIdsOut) +{ + std::map grpMeta; - mDataStore->retrieveGxsGrpMetaData(grpMeta); + std::list::const_iterator lit = grpIdsIn.begin(); - std::map::iterator mit = grpMeta.begin(); + for(; lit != grpIdsIn.end(); lit++) + grpMeta[*lit] = NULL; - for(; mit != grpMeta.end(); mit++) - { - req->mGroupIdResult.push_back(mit->first); - delete mit->second; // so wasteful!! - } + mDataStore->retrieveGxsGrpMetaData(grpMeta); - return true; + std::map::iterator mit = grpMeta.begin(); + + for(; mit != grpMeta.end(); mit++) + { + grpIdsOut.push_back(mit->first); + } + + filterGrpList(grpIdsOut, opts, grpMeta); + + for(mit = grpMeta.begin(); mit != grpMeta.end(); mit++) + { + delete mit->second; // so wasteful!! + } + + return true; } bool RsGxsDataAccess::getMsgData(MsgDataReq* req) @@ -1394,6 +1420,32 @@ void RsGxsDataAccess::filterMsgList(GxsMsgIdResult& msgIds, const RsTokReqOption } } +void RsGxsDataAccess::filterGrpList(std::list &grpIds, const RsTokReqOptions &opts, const GrpMetaFilter &meta) const +{ + std::list::iterator lit = grpIds.begin(); + + for(; lit != grpIds.end(); ) + { + GrpMetaFilter::const_iterator cit = meta.find(*lit); + + bool keep = false; + + if(cit != meta.end()) + { + keep = checkGrpFilter(opts, cit->second); + } + + if(keep) + { + lit++; + }else + { + lit = grpIds.erase(lit); + } + + } +} + bool RsGxsDataAccess::checkRequestStatus(const uint32_t& token, uint32_t& status, uint32_t& reqtype, uint32_t& anstype, time_t& ts) @@ -1516,6 +1568,26 @@ bool RsGxsDataAccess::disposeOfPublicToken(const uint32_t& token) return true; } +bool RsGxsDataAccess::checkGrpFilter(const RsTokReqOptions &opts, const RsGxsGrpMetaData *meta) const +{ + + bool subscribeMatch = false; + + if(opts.mSubscribeMask) + { + // Exact Flags match required. + if ((opts.mSubscribeMask & opts.mSubscribeFilter) == (opts.mSubscribeMask & meta->mSubscribeFlags)) + { + subscribeMatch = true; + } + } + else + { + subscribeMatch = true; + } + + return subscribeMatch; +} bool RsGxsDataAccess::checkMsgFilter(const RsTokReqOptions& opts, const RsGxsMsgMetaData* meta) const { bool statusMatch = false; diff --git a/libretroshare/src/gxs/rsgxsdataaccess.h b/libretroshare/src/gxs/rsgxsdataaccess.h index f8703477d..5f1e09975 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.h +++ b/libretroshare/src/gxs/rsgxsdataaccess.h @@ -32,6 +32,7 @@ typedef std::map< RsGxsGroupId, std::map > MsgMetaFilter; +typedef std::map< RsGxsGroupId, RsGxsGrpMetaData* > GrpMetaFilter; class RsGxsDataAccess : public RsTokenService { @@ -304,6 +305,14 @@ private: */ bool getGroupList(GroupIdReq* req); + /*! + * convenience function for filtering grpIds + * @param grpIdsIn The ids to filter with opts + * @param opts the filter options + * @param grpIdsOut grpIdsIn filtered with opts + */ + bool getGroupList(const std::list& grpIdsIn, const RsTokReqOptions& opts, std::list& grpIdsOut); + /*! * Attempts to retrieve msg id list from data store * Computationally/CPU-Bandwidth expensive @@ -358,6 +367,14 @@ private: */ void filterMsgList(GxsMsgIdResult& msgIds, const RsTokReqOptions& opts, const MsgMetaFilter& meta) const; + /*! + * This filter msgs based of options supplied (at the moment just status masks) + * @param grpIds The group ids to filter + * @param opts the request options containing mask set by user + * @param meta The accompanying meta information for group ids + */ + void filterGrpList(std::list& msgIds, const RsTokReqOptions& opts, const GrpMetaFilter& meta) const; + /*! * This applies the options to the meta to find out if the given message satisfies @@ -368,6 +385,16 @@ private: */ bool checkMsgFilter(const RsTokReqOptions& opts, const RsGxsMsgMetaData* meta) const; + /*! + * This applies the options to the meta to find out if the given group satisfies + * them + * @param opts options containing filters to check + * @param meta meta containing currently defined options for group + * @return true if group meta passes all options + */ + bool checkGrpFilter(const RsTokReqOptions& opts, const RsGxsGrpMetaData* meta) const; + + /*! * This is a filter method which applies the request options to the list of ids * requested diff --git a/libretroshare/src/gxs/rstokenservice.h b/libretroshare/src/gxs/rstokenservice.h index c2e768ade..655666104 100644 --- a/libretroshare/src/gxs/rstokenservice.h +++ b/libretroshare/src/gxs/rstokenservice.h @@ -79,6 +79,7 @@ RsTokReqOptions() { mOptions = 0; mStatusFilter = 0; mStatusMask = 0; mSubscribeFilter = 0; + mSubscribeMask = 0; mMsgFlagMask = 0; mMsgFlagFilter = 0; mBefore = 0; mAfter = 0; mReqType = 0; } @@ -95,7 +96,7 @@ uint32_t mMsgFlagMask, mMsgFlagFilter; uint32_t mReqType; -uint32_t mSubscribeFilter; // Only for Groups. +uint32_t mSubscribeFilter, mSubscribeMask; // Only for Groups. // Time range... again applied after Options. time_t mBefore; diff --git a/libretroshare/src/retroshare/rsposted.h b/libretroshare/src/retroshare/rsposted.h index 3d0eb20fd..2094ce89b 100644 --- a/libretroshare/src/retroshare/rsposted.h +++ b/libretroshare/src/retroshare/rsposted.h @@ -87,6 +87,7 @@ class RsPosted : public RsGxsIfaceImpl static const uint32_t FLAG_MSGTYPE_POST; static const uint32_t FLAG_MSGTYPE_VOTE; static const uint32_t FLAG_MSGTYPE_COMMENT; + static const uint32_t FLAG_MSGTYPE_MASK; RsPosted(RsGenExchange* gxs) : RsGxsIfaceImpl(gxs) { return; } @@ -138,17 +139,20 @@ class RsPostedPost std::string mNotes; }; +class RsGxsPostedVoteItem; class RsPostedVote { - public: - RsPostedVote() - { - mMeta.mMsgFlags = RsPosted::FLAG_MSGTYPE_VOTE; - return; - } +public: - RsMsgMetaData mMeta; + RsPostedVote(const RsGxsPostedVoteItem&); + RsPostedVote() + { + mMeta.mMsgFlags = RsPosted::FLAG_MSGTYPE_VOTE; + return; + } + uint8_t mDirection; + RsMsgMetaData mMeta; }; class RsGxsPostedCommentItem; diff --git a/libretroshare/src/serialiser/rsgxsitems.cc b/libretroshare/src/serialiser/rsgxsitems.cc index 9f62c6da1..00fc2b100 100644 --- a/libretroshare/src/serialiser/rsgxsitems.cc +++ b/libretroshare/src/serialiser/rsgxsitems.cc @@ -42,6 +42,10 @@ this->mGroupName = rGxsMeta.mGroupName; this->mServiceString = rGxsMeta.mServiceString; this->mSignFlags = rGxsMeta.mSignFlags; + this->mCircleId = rGxsMeta.mCircleId; + this->mCircleType = rGxsMeta.mCircleType; + this->mInternalCircle = rGxsMeta.mInternalCircle; + this->mOriginator = rGxsMeta.mOriginator; } diff --git a/libretroshare/src/serialiser/rsgxsitems.h b/libretroshare/src/serialiser/rsgxsitems.h index 2726e21b9..346cc14a1 100644 --- a/libretroshare/src/serialiser/rsgxsitems.h +++ b/libretroshare/src/serialiser/rsgxsitems.h @@ -34,6 +34,7 @@ class RsGxsGrpMetaData; class RsGxsMsgMetaData; + class RsGroupMetaData { public: @@ -48,6 +49,7 @@ public: mLastPost = 0; mGroupStatus = 0; + mCircleType = 0; //mPublishTs = 0; } @@ -62,6 +64,10 @@ public: time_t mPublishTs; // Mandatory. std::string mAuthorId; // Optional. + // for circles + std::string mCircleId; + uint32_t mCircleType; + // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. uint32_t mSubscribeFlags; @@ -72,6 +78,12 @@ public: uint32_t mGroupStatus; std::string mServiceString; // Service Specific Free-Form extra storage. + std::string mOriginator; + std::string mInternalCircle; + + + + }; diff --git a/libretroshare/src/serialiser/rsposteditems.cc b/libretroshare/src/serialiser/rsposteditems.cc index 5edc827ec..99280b634 100644 --- a/libretroshare/src/serialiser/rsposteditems.cc +++ b/libretroshare/src/serialiser/rsposteditems.cc @@ -25,6 +25,7 @@ */ #include "serialiser/rsposteditems.h" +#include "rsbaseserial.h" uint32_t RsGxsPostedSerialiser::size(RsItem *item) @@ -154,6 +155,7 @@ uint32_t RsGxsPostedSerialiser::sizeGxsPostedVoteItem(RsGxsPostedVoteItem* item) RsPostedVote& v = item->mVote; uint32_t s = 8; + s += 1; // for vote direction return s; } @@ -289,7 +291,7 @@ bool RsGxsPostedSerialiser::serialiseGxsPostedVoteItem(RsGxsPostedVoteItem* item /* skip the header */ offset += 8; - /* GxsPhotoAlbumItem */ + ok &= setRawUInt32(data, tlvsize, &offset, item->mVote.mDirection); if(offset != tlvsize) { @@ -525,6 +527,8 @@ RsGxsPostedVoteItem* RsGxsPostedSerialiser::deserialiseGxsPostedVoteItem(void *d /* skip the header */ offset += 8; + ok &= getRawUInt8(data, rssize, &offset, &(item->mVote.mDirection)); + if (offset != rssize) { #ifdef GXS_POSTED_SERIAL_DEBUG diff --git a/libretroshare/src/services/p3posted.cc b/libretroshare/src/services/p3posted.cc index b67d334e7..cc9e695cc 100644 --- a/libretroshare/src/services/p3posted.cc +++ b/libretroshare/src/services/p3posted.cc @@ -1,9 +1,17 @@ + +#include +#include + #include "p3posted.h" +#include "gxs/rsgxsflags.h" #include "serialiser/rsposteditems.h" const uint32_t RsPosted::FLAG_MSGTYPE_COMMENT = 0x0001; const uint32_t RsPosted::FLAG_MSGTYPE_POST = 0x0002; const uint32_t RsPosted::FLAG_MSGTYPE_VOTE = 0x0004; +const uint32_t RsPosted::FLAG_MSGTYPE_MASK = 0x000f; + +#define POSTED_MAX_SERVICE_STRING 50 RsPosted *rsPosted = NULL; @@ -13,9 +21,17 @@ RsPostedComment::RsPostedComment(const RsGxsPostedCommentItem & item) mMeta = item.meta; } -p3Posted::p3Posted(RsGeneralDataService *gds, RsNetworkExchangeService *nes) - : RsGenExchange(gds, nes, new RsGxsPostedSerialiser(), RS_SERVICE_GXSV1_TYPE_POSTED), RsPosted(this), mPostedMutex("Posted") +RsPostedVote::RsPostedVote(const RsGxsPostedVoteItem& item) { + mDirection = item.mVote.mDirection; + mMeta = item.meta; +} + +p3Posted::p3Posted(RsGeneralDataService *gds, RsNetworkExchangeService *nes) + : RsGenExchange(gds, nes, new RsGxsPostedSerialiser(), RS_SERVICE_GXSV1_TYPE_POSTED), RsPosted(this), mPostedMutex("Posted"), + mTokenService(NULL) +{ + mTokenService = RsGenExchange::getTokenService(); } void p3Posted::notifyChanges(std::vector &changes) @@ -154,7 +170,7 @@ bool p3Posted::submitVote(uint32_t &token, RsPostedVote &vote) RsGxsPostedVoteItem* voteItem = new RsGxsPostedVoteItem(); voteItem->mVote = vote; voteItem->meta = vote.mMeta; - voteItem->meta.mMsgFlags |= FLAG_MSGTYPE_POST; + voteItem->meta.mMsgFlags |= FLAG_MSGTYPE_VOTE; RsGenExchange::publishMsg(token, voteItem); return true; @@ -221,6 +237,7 @@ void p3Posted::processMessageRanks() RsStackMutex stack(mPostedMutex); std::map::iterator mit =mPendingPostRanks.begin(); + // go through all pending posts for(; mit !=mPendingPostRanks.begin(); mit++) { uint32_t token; @@ -235,7 +252,7 @@ void p3Posted::processMessageRanks() while(true) { - uint32_t status = RsGenExchange::getTokenService()->requestStatus(token); + uint32_t status = mTokenService->requestStatus(token); if(RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE == status) @@ -259,38 +276,417 @@ void p3Posted::processMessageRanks() void p3Posted::discardCalc(const uint32_t &token) { + mTokenService->cancelRequest(token); +} +bool PostedTopScoreComp(const PostedScore& i, const PostedScore& j) +{ + if((i.upVotes + (-i.downVotes)) == (j.upVotes + (-j.downVotes))){ + return i.date < j.date; + }else + return (i.upVotes + (-i.downVotes)) < (j.upVotes + (-j.downVotes)); +} + +bool PostedNewScoreComp(const PostedScore& i, const PostedScore& j) +{ + return i.date < j.date; +} + +bool PostedBestScoreComp(const PostedScore& i, const PostedScore& j) +{ + +// n = ups + downs if n == 0: return 0 z = 1.0 +// #1.0 = 85%, 1.6 = 95% phat = float(ups) +// / n return sqrt(phat+z*z/(2*n)-z*((phat*(1-phat)+z*z/(4*n))/n))/(1+z*z/n) +// def confidence(ups, downs): if ups + downs == 0: return 0 else: +// return _confidence(ups, downs) + // very expensive!! + + static float z = 1.0; + float phat; + + float i_score; + int n = i.upVotes + (-i.downVotes); + if(n==0) + i_score = 0.; + else + { + phat = float(i.upVotes); + i_score = sqrt(phat+z*z/(2*n)-z*((phat*(1-phat)+z*z/(4*n))/n))/(1+z*z/n); + } + + float j_score; + n = j.upVotes + (-j.downVotes); + if(n==0) + j_score = 0.; + else + { + phat = float(j.upVotes); + j_score = sqrt(phat+z*z/(2*n)-z*((phat*(1-phat)+z*z/(4*n))/n))/(1+z*z/n); + } + + if(j_score == i_score) + return i.date < j.date; + else + return i_score < j_score; } void p3Posted::completePostedPostCalc(GxsPostedPostRanking *gpp) { GxsMsgMetaMap msgMetas; - getMsgMeta(gpp->reqToken, msgMetas); - GxsMsgMetaMap::iterator mit = msgMetas.begin(); - - for(; mit != msgMetas.end(); mit++ ) + if(getMsgMeta(gpp->reqToken, msgMetas)) { - RsGxsMsgMetaData* m = NULL; - //retrieveScores(m->mServiceString, upVotes, downVotes, nComments); + std::vector msgMetaV = msgMetas[gpp->grpId]; + switch(gpp->rType) + { + case NewRankType: + calcPostedPostRank(msgMetaV, gpp->rankingResult, PostedNewScoreComp); + break; + case TopRankType: + calcPostedPostRank(msgMetaV, gpp->rankingResult, PostedTopScoreComp); + break; + default: + std::cerr << "Unknown ranking tpye: " << gpp->rType << std::endl; + } + } +} - // then dependent on rank request type process for that way + +void p3Posted::calcPostedPostRank(const std::vector msgMeta, PostedRanking &ranking, + bool comp(const PostedScore &, const PostedScore &)) const +{ + + std::vector::const_iterator cit = msgMeta.begin(); + std::vector scores; + + for(; cit != msgMeta.begin(); ) + { + const RsMsgMetaData& m = *cit; + uint32_t upVotes, downVotes, nComments; + retrieveScores(m.mServiceString, upVotes, downVotes, nComments); + + PostedScore c; + c.upVotes = upVotes; + c.downVotes = downVotes; + c.date = m.mPublishTs; + scores.push_back(c); } + std::sort(scores.begin(), scores.end(), comp); + + std::vector::iterator vit = scores.begin(); + + int i = 1; + for(; vit != scores.end(); vit) + { + const PostedScore& p = *vit; + ranking.insert(std::make_pair(p.msgId, i++)); + } +} + +void p3Posted::calcPostedCommentsRank(const std::map > &msgBranches, + std::map& msgMetas, PostedRanking &ranking, bool comp(const PostedScore &, const PostedScore &)) const +{ + + std::map >::const_iterator cit = msgBranches.begin(); + + for(; cit != msgBranches.end(); cit++) + { + const std::vector& branch = cit->second; + std::vector scores; + + std::vector::const_iterator vit = branch.begin(); + + for(; vit != branch.end(); vit++) + { + + std::map::iterator mit = + msgMetas.find(*vit); + + if(mit != msgMetas.end()) + { + uint32_t upVotes, downVotes, nComments; + + const RsMsgMetaData& m = mit->second; + retrieveScores(m.mServiceString, upVotes, downVotes, nComments); + + PostedScore c; + c.upVotes = upVotes; + c.downVotes = downVotes; + c.date = m.mPublishTs; + scores.push_back(c); + } + } + + std::sort(scores.begin(), scores.end(), comp); + + std::vector::iterator cvit = scores.begin(); + + int i = 1; + for(; cvit != scores.end(); cvit) + { + const PostedScore& p = *cvit; + ranking.insert(std::make_pair(p.msgId, i++)); + } + } } -bool p3Posted::retrieveScores(const std::string &serviceString, uint32_t &upVotes, uint32_t downVotes, uint32_t nComments) +void p3Posted::completePostedCommentRanking(GxsPostedCommentRanking *gpc) { - if (2 == sscanf(serviceString.c_str(), "%d %d %d", &upVotes, &downVotes, &nComments)) + GxsMsgRelatedMetaMap msgMetas; + + if(getMsgRelatedMeta(gpc->reqToken, msgMetas)) { - return true; + + // create map of msgs + std::vector& msgV = msgMetas[gpc->msgId]; + std::map > msgBranches; + std::map remappedMsgMeta; + + std::vector::iterator vit = msgV.begin(); + + for(; vit != msgV.end(); vit++) + { + const RsMsgMetaData& m = *vit; + + if(!m.mParentId.empty()) + { + msgBranches[m.mParentId].push_back(m.mMsgId); + } + + remappedMsgMeta.insert(std::make_pair(m.mMsgId, m)); + } + + switch(gpc->rType) + { + case BestRankType: + calcPostedCommentsRank(msgBranches, remappedMsgMeta, gpc->result, PostedBestScoreComp); + break; + case TopRankType: + calcPostedCommentsRank(msgBranches, remappedMsgMeta, gpc->result, PostedTopScoreComp); + break; + case NewRankType: + calcPostedCommentsRank(msgBranches, remappedMsgMeta, gpc->result, PostedNewScoreComp); + break; + default: + std::cerr << "Unknown Rank type" << gpc->rType << std::endl; + break; + } + } +} + +bool p3Posted::retrieveScores(const std::string &serviceString, uint32_t &upVotes, uint32_t downVotes, uint32_t nComments) const +{ + if (3 == sscanf(serviceString.c_str(), "%d %d %d", &upVotes, &downVotes, &nComments)) + { + return true; } return false; } +bool p3Posted::storeScores(std::string &serviceString, uint32_t &upVotes, uint32_t downVotes, uint32_t nComments) const +{ + char line[POSTED_MAX_SERVICE_STRING]; + + bool ok = snprintf(line, POSTED_MAX_SERVICE_STRING, "%d %d %d", upVotes, downVotes, nComments) > -1; + + serviceString = line; + return ok; +} void p3Posted::processCommentRanks() { } + + +void p3Posted::updateVotes() +{ + if(!mUpdateTokenQueued) + { + mUpdateTokenQueued = true; + + switch(mUpdatePhase) + { +// case UPDATE_PHASE_GRP_REQUEST: +// { +// updateRequestGroups(mUpda); +// break; +// } +// case UPDATE_PHASE_GRP_MSG_REQUEST: +// { +// updateRequestMessages(mVoteUpdataToken); +// break; +// } +// case UPDATE_VOTE_COMMENT_REQUEST: +// { +// updateRequestVotesComments(mVoteUpdataToken); +// break; +// } +// case UPDATE_COMPLETE_UPDATE: +// { +// updateCompleteUpdate(); +// break; +// } +// default: +// break; + } + + // first get all msgs for groups for which you are subscribed to. + // then request comments for them + + } +} + +bool p3Posted::updateRequestGroups(uint32_t &token) +{ + + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; + opts.mSubscribeMask = GXS_SERV::GROUP_SUBSCRIBE_MASK; + opts.mSubscribeFilter = GXS_SERV::GROUP_SUBSCRIBE_ADMIN | + GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED; + mTokenService->requestGroupInfo(token, 0, opts); + + mUpdatePhase = UPDATE_PHASE_GRP_MSG_REQUEST; +} + +bool p3Posted::updateRequestMessages(uint32_t &token) +{ + + uint32_t status = mTokenService->requestStatus(token); + + if(status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + { + std::list grpIds; + RsGenExchange::getGroupList(token, grpIds); + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST | RS_TOKREQOPT_MSG_THREAD; + mTokenService->requestMsgInfo(token, 0, opts, grpIds); + mUpdatePhase = UPDATE_VOTE_COMMENT_REQUEST; + return true; + } + else if(status == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED) + { + mTokenService->cancelRequest(token); + return false; + } +} + +bool p3Posted::updateRequestVotesComments(uint32_t &token) +{ + + uint32_t status = mTokenService->requestStatus(token); + + if(status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + { + + GxsMsgIdResult result; + RsGenExchange::getMsgList(token, result); + + std::vector msgIds; + + GxsMsgIdResult::iterator mit = result.begin(); + + for(; mit != result.end(); mit++) + { + std::vector& msgIdV = mit->second; + std::vector::const_iterator cit = msgIdV.begin(); + + for(; cit != msgIdV.end(); cit++) + msgIds.push_back(std::make_pair(mit->first, *cit)); + } + + // only need ids for comments + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST | RS_TOKREQOPT_MSG_PARENT; + opts.mMsgFlagMask = RsPosted::FLAG_MSGTYPE_MASK; + opts.mMsgFlagFilter = RsPosted::FLAG_MSGTYPE_COMMENT; + mTokenService->requestMsgRelatedInfo(mCommentToken, 0, opts, msgIds); + + // need actual data from votes + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST | RS_TOKREQOPT_MSG_PARENT; + opts.mMsgFlagMask = RsPosted::FLAG_MSGTYPE_MASK; + opts.mMsgFlagFilter = RsPosted::FLAG_MSGTYPE_VOTE; + mTokenService->requestMsgRelatedInfo(mVoteToken, 0, opts, msgIds); + + mUpdatePhase = UPDATE_COMPLETE_UPDATE; + mMsgsPendingUpdate = msgIds; + + return true; + } + else if(status == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED) + { + mTokenService->cancelRequest(token); + return false; + } +} + +bool p3Posted::updateCompleteUpdate() +{ + uint32_t commentStatus = mTokenService->requestStatus(mCommentToken); + uint32_t voteStatus = mTokenService->requestStatus(mVoteToken); + + bool ready = commentStatus == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE; + ready &= voteStatus == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE; + + bool failed = commentStatus == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED; + failed &= voteStatus == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED; + + if(ready) + { + std::map > msgCommentIds; + std::map > votes; + getMsgRelatedDataT(mVoteToken, votes); + std::vector::iterator vit = mMsgsPendingUpdate.begin(); + + for(; vit != mMsgsPendingUpdate.end();vit++) + { + updateMsg(*vit, votes[*vit], msgCommentIds[*vit]); + } + mUpdatePhase = 0; + } + else if(failed) + { + mTokenService->cancelRequest(mCommentToken); + mTokenService->cancelRequest(mVoteToken); + return false; + }else + { + return true; + } +} + +bool p3Posted::updateMsg(const RsGxsGrpMsgIdPair& msgId, const std::vector &msgVotes, + const std::vector& msgCommentIds) +{ + + uint32_t nComments = msgCommentIds.size(); + uint32_t nUp = 0, nDown = 0; + + std::vector::const_iterator cit = msgVotes.begin(); + + for(; cit != msgVotes.end(); cit++) + { + const RsPostedVote& v = *cit; + + if(v.mDirection == 0) + { + nDown++; + }else + { + nUp++; + } + } + std::string servStr; + storeScores(servStr, nUp, nDown, nComments); + uint32_t token; + setMsgServiceString(token, msgId, servStr); +} + diff --git a/libretroshare/src/services/p3posted.h b/libretroshare/src/services/p3posted.h index 62d7b789b..7a5e9d42b 100644 --- a/libretroshare/src/services/p3posted.h +++ b/libretroshare/src/services/p3posted.h @@ -15,7 +15,7 @@ public: uint32_t reqToken; RsPosted::RankType rType; RsGxsGroupId grpId; - PostedRanking result; + PostedRanking rankingResult; }; class GxsPostedCommentRanking @@ -29,6 +29,19 @@ public: PostedRanking result; }; +class PostedScore { +public: + int32_t upVotes, downVotes; + time_t date; + RsGxsMessageId msgId; +}; + + +#define UPDATE_PHASE_GRP_REQUEST 1 +#define UPDATE_PHASE_GRP_MSG_REQUEST 2 +#define UPDATE_VOTE_COMMENT_REQUEST 3 +#define UPDATE_COMPLETE_UPDATE 4 + class p3Posted : public RsGenExchange, public RsPosted { public: @@ -67,21 +80,57 @@ public: private: + /* Functions for processing rankings */ + void processRankings(); void processMessageRanks(); void processCommentRanks(); void discardCalc(const uint32_t& token); void completePostedPostCalc(GxsPostedPostRanking* gpp); - bool retrieveScores(const std::string& serviceString, uint32_t& upVotes, uint32_t downVotes, uint32_t nComments); + void completePostedCommentRanking(GxsPostedCommentRanking* gpc); + bool retrieveScores(const std::string& serviceString, uint32_t& upVotes, uint32_t downVotes, uint32_t nComments) const; + bool storeScores(std::string& serviceString, uint32_t& upVotes, uint32_t downVotes, uint32_t nComments) const; + + // for posts + void calcPostedPostRank(const std::vector, PostedRanking& ranking, bool com(const PostedScore& i, const PostedScore &j)) const; + + // for comments + void calcPostedCommentsRank(const std::map >& msgBranches, std::map& msgMetas, + PostedRanking& ranking, bool com(const PostedScore& i, const PostedScore &j)) const; + + /* Functions for maintaing vote counts in meta data */ + + /*! + * Update votes should only be called when a vote comes in + * Several phases to calculating votes. + * First get all messages for groups which you are subscribed + * Then for these messages get all the votes accorded to them + * Then do the calculation and update messages + * Also stores updates for messages which have new scores + */ + void updateVotes(); + bool updateRequestGroups(uint32_t& token); + bool updateRequestMessages(uint32_t& token); + bool updateRequestVotesComments(uint32_t& token); + bool updateCompleteUpdate(); + bool updateMsg(const RsGxsGrpMsgIdPair& msgId, const std::vector& msgVotes, + const std::vector& msgCommentIds); private: + // for calculating ranks std::map mPendingPostRanks; std::map mPendingCalculationPostRanks; - std::map mPendingCommentRanks; std::map mPendingCalculationCommentRanks; + // for maintaining vote counts in msg meta + uint32_t mVoteUpdataToken, mVoteToken, mCommentToken; + bool mUpdateTokenQueued; + uint32_t mUpdatePhase; + std::vector mMsgsPendingUpdate; + + RsTokenService* mTokenService; RsMutex mPostedMutex; }; From c1702fc13a41e3241781b68fe780cb4f834f0a2f Mon Sep 17 00:00:00 2001 From: drbob Date: Tue, 4 Dec 2012 00:47:34 +0000 Subject: [PATCH 199/222] Improvements to Wiki. - Enabled Selection of Snapshots in WikiEditDialog - Added CheckBoxes for Merge selection. (TODO). - Fixed up bugs related to text reload. - Removed Edits from main Wiki Page. - Added a Search Bar (TODO). git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5937 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- .../src/gui/WikiPoos/WikiDialog.cpp | 337 +----------------- retroshare-gui/src/gui/WikiPoos/WikiDialog.h | 15 - retroshare-gui/src/gui/WikiPoos/WikiDialog.ui | 213 ++++------- .../src/gui/WikiPoos/WikiEditDialog.cpp | 110 ++++-- .../src/gui/WikiPoos/WikiEditDialog.h | 5 + .../src/gui/WikiPoos/WikiEditDialog.ui | 24 +- 6 files changed, 179 insertions(+), 525 deletions(-) diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp index 71cbc6fb4..76b493259 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.cpp @@ -78,7 +78,6 @@ WikiDialog::WikiDialog(QWidget *parent) connect( ui.toolButton_Delete, SIGNAL(clicked()), this, SLOT(insertWikiGroups())); connect( ui.treeWidget_Pages, SIGNAL(itemSelectionChanged()), this, SLOT(groupTreeChanged())); - connect( ui.treeWidget_Mods, SIGNAL(itemSelectionChanged()), this, SLOT(modTreeChanged())); QTimer *timer = new QTimer(this); timer->connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate())); @@ -123,17 +122,6 @@ void WikiDialog::OpenOrShowAddPageDialog() std::cerr << "WikiDialog::OpenOrShowAddPageDialog() GroupId: " << groupId; std::cerr << std::endl; -#if 0 - RsWikiCollection group; - if (!rsWiki->getGroup(groupId, group)) - { - std::cerr << "WikiDialog::OpenOrShowAddPageDialog() Failed to Get Group"; - std::cerr << std::endl; - } - - mEditDialog->setGroup(group); -#endif - mEditDialog->setupData(groupId, ""); mEditDialog->setNewPage(); @@ -144,18 +132,6 @@ void WikiDialog::OpenOrShowAddPageDialog() void WikiDialog::OpenOrShowAddGroupDialog() { -#if 0 - if (mAddGroupDialog) - { - mAddGroupDialog->show(); - } - else - { - mAddGroupDialog = new WikiAddDialog(NULL); - mAddGroupDialog->show(); - } -#endif - newGroup(); } @@ -166,8 +142,7 @@ void WikiDialog::OpenOrShowAddGroupDialog() void WikiDialog::newGroup() { WikiGroupDialog cf(mWikiQueue, this); - //cf.newGroup(); - cf.wikitype(); + cf.wikitype(); cf.exec (); } @@ -181,11 +156,6 @@ void WikiDialog::showGroupDetails() std::cerr << std::endl; return; } - - - //RsWikiCollection collection; - //WikiGroupDialog cf (collection, this); - //cf.exec (); } void WikiDialog::editGroupDetails() @@ -223,25 +193,12 @@ void WikiDialog::OpenOrShowEditDialog() std::cerr << "WikiDialog::OpenOrShowAddPageDialog()"; std::cerr << std::endl; - std::string modId = getSelectedMod(); - std::string realPageId; - - if (modId == "") - { - realPageId = pageId; - } - else - { - realPageId = modId; - } - - if (!mEditDialog) { mEditDialog = new WikiEditDialog(NULL); } - mEditDialog->setupData(groupId, realPageId); + mEditDialog->setupData(groupId, pageId); mEditDialog->show(); } @@ -285,43 +242,14 @@ void WikiDialog::groupTreeChanged() { /* clear Mods */ clearGroupTree(); - clearModsTree(); - return; } - - clearModsTree(); - - RsGxsGrpMsgIdPair origPagePair = std::make_pair(groupId, origPageId); RsGxsGrpMsgIdPair pagepair = std::make_pair(groupId, pageId); - - insertModsForPage(origPagePair); requestWikiPage(pagepair); } -void WikiDialog::modTreeChanged() -{ - /* */ - std::string groupId = getSelectedGroup(); - std::string pageId = getSelectedMod(); - if (pageId == mModSelected) - { - return; /* nothing changed */ - } - - if ((pageId == "") || (groupId == "")) - { - clearWikiPage(); - return; - } - - RsGxsGrpMsgIdPair pagepair = std::make_pair(groupId, pageId); - requestWikiPage(pagepair); -} - - void WikiDialog::updateWikiPage(const RsWikiSnapshot &page) { #ifdef USE_PEGMMD_RENDERER @@ -354,12 +282,6 @@ void WikiDialog::clearGroupTree() ui.treeWidget_Pages->clear(); } -void WikiDialog::clearModsTree() -{ - ui.treeWidget_Mods->clear(); -} - - #define WIKI_GROUP_COL_GROUPNAME 0 #define WIKI_GROUP_COL_GROUPID 1 @@ -448,37 +370,6 @@ std::string WikiDialog::getSelectedGroup() return groupId; } -#define WIKI_MODS_COL_ORIGPAGEID 0 -#define WIKI_MODS_COL_PAGEID 1 -#define WIKI_MODS_COL_PARENTID 2 - - -std::string WikiDialog::getSelectedMod() -{ - std::string pageId; -#ifdef WIKI_DEBUG - std::cerr << "WikiDialog::getSelectedMod()" << std::endl; -#endif - - /* get current item */ - QTreeWidgetItem *item = ui.treeWidget_Mods->currentItem(); - - if (!item) - { - /* leave current list */ -#ifdef WIKI_DEBUG - std::cerr << "WikiDialog::getSelectedMod() Nothing selected" << std::endl; -#endif - return pageId; - } - - pageId = item->text(WIKI_MODS_COL_PAGEID).toStdString(); -#ifdef WIKI_DEBUG - std::cerr << "WikiDialog::getSelectedMod() PageId: " << pageId << std::endl; -#endif - return pageId; -} - /************************** Request / Response *************************/ /*** Loading Main Index ***/ @@ -615,223 +506,8 @@ void WikiDialog::loadPages(const uint32_t &token) } } - -/***** Mods *****/ - -void WikiDialog::insertModsForPage(const RsGxsGrpMsgIdPair &origPageId) -{ - requestModPages(origPageId); -} - -void WikiDialog::requestModPages(const RsGxsGrpMsgIdPair &origMsgId) -{ - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; - opts.mOptions = RS_TOKREQOPT_MSG_VERSIONS; - std::vector msgIds; - msgIds.push_back(origMsgId); - uint32_t token; - mWikiQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, WIKIDIALOG_MOD_PAGES); -} - -void WikiDialog::loadModPages(const uint32_t &token) -{ - std::cerr << "WikiDialog::loadModPages()"; - std::cerr << std::endl; - - - std::vector snapshots; - std::vector::iterator vit; - if (!rsWiki->getRelatedSnapshots(token, snapshots)) - { - // ERROR - std::cerr << "WikiDialog::loadModPages() ERROR"; - std::cerr << std::endl; - return; - } - - for(vit = snapshots.begin(); vit != snapshots.end(); vit++) - { - RsWikiSnapshot &page = *vit; - - std::cerr << "WikiDialog::loadModPages() TopLevel Result: PageTitle: " << page.mMeta.mMsgName; - std::cerr << " GroupId: " << page.mMeta.mGroupId; - std::cerr << std::endl; - std::cerr << "\tOrigMsgId: " << page.mMeta.mOrigMsgId; - std::cerr << " MsgId: " << page.mMeta.mMsgId; - std::cerr << std::endl; - std::cerr << "\tThreadId: " << page.mMeta.mThreadId; - std::cerr << " ParentId: " << page.mMeta.mParentId; - std::cerr << std::endl; - - QTreeWidgetItem *modItem = new QTreeWidgetItem(); - modItem->setText(WIKI_MODS_COL_ORIGPAGEID, QString::fromStdString(page.mMeta.mOrigMsgId)); - modItem->setText(WIKI_MODS_COL_PAGEID, QString::fromStdString(page.mMeta.mMsgId)); - modItem->setText(WIKI_MODS_COL_PARENTID, QString::fromStdString(page.mMeta.mParentId)); - ui.treeWidget_Mods->addTopLevelItem(modItem); - } - - /* then we need to request all pages from this thread */ - requestEditTreeData(); -} - - -void WikiDialog::requestEditTreeData() //const RsGxsGroupId &groupId) -{ - std::string groupId = getSelectedGroup(); - - // SWITCH THIS TO A THREAD REQUEST - WHEN WE CAN! - - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - - std::list groupIds; - groupIds.push_back(groupId); - - uint32_t token; - mWikiQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, WIKIDIALOG_EDITTREE_DATA); -} - - - -void WikiDialog::loadEditTreeData(const uint32_t &token) -{ - std::cerr << "WikiDialog::loadEditTreeData()"; - std::cerr << std::endl; - - - std::vector snapshots; - std::vector::iterator vit; - if (!rsWiki->getSnapshots(token, snapshots)) - { - // ERROR - std::cerr << "WikiDialog::loadEditTreeData() ERROR"; - std::cerr << std::endl; - return; - } - - std::string groupId; - std::string pageId; - std::string origPageId; - if (!getSelectedPage(groupId, pageId, origPageId)) - { - // ERROR - std::cerr << "WikiDialog::loadEditTreeData() ERROR 2"; - std::cerr << std::endl; - return; - } - - std::cerr << "WikiDialog::loadEditTreeData() Loaded " << snapshots.size(); - std::cerr << std::endl; - std::cerr << "WikiDialog::loadEditTreeData() Using ThreadId: " << origPageId; - std::cerr << std::endl; - - - - - - std::map items; - std::map::iterator iit; - std::list unparented; - std::list::iterator uit; - - // Grab the existing TopLevelItems, and insert into map. - int itemCount = ui.treeWidget_Mods->topLevelItemCount(); - for (int nIndex = 0; nIndex < itemCount; nIndex++) - { - QTreeWidgetItem *item = ui.treeWidget_Mods->topLevelItem(nIndex); - - /* index by MsgId --> ONLY For Wiki Thread Head Items... SPECIAL HACK FOR HERE! */ - std::string msgId = item->text(WIKI_MODS_COL_PAGEID).toStdString(); - items[msgId] = item; - } - - - for(vit = snapshots.begin(); vit != snapshots.end(); vit++) - { - RsWikiSnapshot &snapshot = *vit; - - std::cerr << "Result: PageTitle: " << snapshot.mMeta.mMsgName; - std::cerr << " GroupId: " << snapshot.mMeta.mGroupId; - std::cerr << std::endl; - std::cerr << "\tOrigMsgId: " << snapshot.mMeta.mOrigMsgId; - std::cerr << " MsgId: " << snapshot.mMeta.mMsgId; - std::cerr << std::endl; - std::cerr << "\tThreadId: " << snapshot.mMeta.mThreadId; - std::cerr << " ParentId: " << snapshot.mMeta.mParentId; - std::cerr << std::endl; - - if (snapshot.mMeta.mParentId == "") - { - /* Ignore! */ - std::cerr << "Ignoring ThreadHead Item"; - std::cerr << std::endl; - continue; - } - - if (snapshot.mMeta.mThreadId != origPageId) - { - /* Ignore! */ - std::cerr << "Ignoring Different Thread Item"; - std::cerr << std::endl; - continue; - } - - /* create an Entry */ - QTreeWidgetItem *modItem = new QTreeWidgetItem(); - modItem->setText(WIKI_MODS_COL_ORIGPAGEID, QString::fromStdString(snapshot.mMeta.mOrigMsgId)); - modItem->setText(WIKI_MODS_COL_PAGEID, QString::fromStdString(snapshot.mMeta.mMsgId)); - modItem->setText(WIKI_MODS_COL_PARENTID, QString::fromStdString(snapshot.mMeta.mParentId)); - -#if 0 - /* if no parentId */ - if (snapshot.mMeta.mParentId == "") - { - /* we've found one the missing ones */ - ui.treeWidget_Mods->addTopLevelItem(modItem); - - /* index by MsgId --> SPECIAL HACK FOR HERE! */ - items[snapshot.mMeta.mMsgId] = modItem; - continue; - } -#endif - - /* find the parent */ - iit = items.find(snapshot.mMeta.mParentId); - if (iit != items.end()) - { - (iit->second)->addChild(modItem); - } - else - { - unparented.push_back(modItem); - } - items[snapshot.mMeta.mOrigMsgId] = modItem; - } - - for(uit = unparented.begin(); uit != unparented.end(); uit++) - { - std::string parentId = (*uit)->text(WIKI_MODS_COL_PARENTID).toStdString(); - - iit = items.find(parentId); - if (iit != items.end()) - { - (iit->second)->addChild(*uit); - } - else - { - /* ERROR */ - std::cerr << "Unparented!!!"; - std::cerr << std::endl; - } - } -} - - /***** Wiki *****/ - void WikiDialog::requestWikiPage(const RsGxsGrpMsgIdPair &msgId) { std::cerr << "WikiDialog::requestWikiPage(" << msgId.first << "," << msgId.second << ")"; @@ -907,17 +583,10 @@ void WikiDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) loadPages(req.mToken); break; - case WIKIDIALOG_MOD_PAGES: - loadModPages(req.mToken); - break; - - case WIKIDIALOG_EDITTREE_DATA: - loadEditTreeData(req.mToken); - break; - case WIKIDIALOG_WIKI_PAGE: loadWikiPage(req.mToken); break; + #define GXSGROUP_NEWGROUPID 1 case GXSGROUP_NEWGROUPID: insertWikiGroups(); diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.h b/retroshare-gui/src/gui/WikiPoos/WikiDialog.h index c9a1663a7..39fc80339 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.h +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.h @@ -54,7 +54,6 @@ private slots: void OpenOrShowRepublishDialog(); void groupTreeChanged(); - void modTreeChanged(); void newGroup(); void showGroupDetails(); @@ -66,20 +65,12 @@ private: void clearWikiPage(); void clearGroupTree(); -void clearModsTree(); - -void insertModsForPage(const std::string &origPageId); - -void insertModsForPage(const RsGxsGrpMsgIdPair &origPageId); void updateWikiPage(const RsWikiSnapshot &page); bool getSelectedPage(std::string &groupId, std::string &pageId, std::string &origPageId); std::string getSelectedPage(); std::string getSelectedGroup(); -std::string getSelectedMod(); - - void requestGroupList(); void loadGroupData(const uint32_t &token); @@ -87,12 +78,6 @@ void loadGroupData(const uint32_t &token); void requestPages(const std::list &groupIds); void loadPages(const uint32_t &token); -void requestModPages(const RsGxsGrpMsgIdPair &origMsgId); -void loadModPages(const uint32_t &token); - -void requestEditTreeData(); -void loadEditTreeData(const uint32_t &token); - void requestWikiPage(const RsGxsGrpMsgIdPair &msgId); void loadWikiPage(const uint32_t &token); diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui index b8e2e6341..dc2f0b6a2 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui @@ -6,24 +6,21 @@ 0 0 - 918 - 669 + 764 + 514 - - - + + + Qt::Horizontal - - - - 0 - + + @@ -96,88 +93,40 @@ - - - Qt::Vertical + + + true - - - true + + + + 0 + 0 + 241 + 448 + - - - - 0 - 0 - 241 - 307 - - - - - 0 - - - 0 - - - 0 - - - - - - Wiki Group - - - - - Page - - - - - Id - - - - - - - - - - true - - - - - 0 - 0 - 241 - 294 - - - - - 0 - - - - - - Page Modification - - - - - By - - - - - - + + + + + + Wiki Group + + + + + Page + + + + + Id + + + + + @@ -253,32 +202,6 @@ - - - - false - - - Mod - - - - :/images/arrow-left.png:/images/arrow-left.png - - - - 24 - 24 - - - - Qt::ToolButtonTextBesideIcon - - - true - - - @@ -325,32 +248,6 @@ - - - - false - - - Mod - - - - :/images/arrow-right.png:/images/arrow-right.png - - - - 24 - 24 - - - - Qt::ToolButtonTextBesideIcon - - - true - - - @@ -436,27 +333,37 @@ 0 0 - 645 - 609 + 491 + 454 QWidget#scrollAreaWidgetContents{border: none;} - - - 0 - - - 0 - + - + - + + + + 75 + true + + + + Search + + + + + + + + diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp index 4661f960d..d57e243bc 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp @@ -69,6 +69,8 @@ WikiEditDialog::WikiEditDialog(QWidget *parent) connect(ui.toolButton_Hide, SIGNAL( clicked( void ) ), this, SLOT( detailsToggle( void ) ) ); connect(ui.textEdit, SIGNAL( textChanged( void ) ), this, SLOT( textChanged( void ) ) ); connect(ui.checkBox_OldHistory, SIGNAL( clicked( void ) ), this, SLOT( oldHistoryChanged( void ) ) ); + connect(ui.checkBox_Merge, SIGNAL( clicked( void ) ), this, SLOT( mergeModeToggle( void ) ) ); + connect(ui.pushButton_Merge, SIGNAL( clicked( void ) ), this, SLOT( generateMerge( void ) ) ); connect(ui.treeWidget_History, SIGNAL( itemSelectionChanged( void ) ), this, SLOT( historySelected( void ) ) ); mWikiQueue = new TokenQueue(rsWiki->getTokenService(), this); @@ -79,9 +81,14 @@ WikiEditDialog::WikiEditDialog(QWidget *parent) mRepublishMode = false; mPreviewMode = false; mPageLoading = false; + + mIgnoreTextChange = false; mTextChanged = false; mCurrentText = ""; + mHistoryLoaded = false; + mHistoryMergeMode = false; + ui.checkBox_OldHistory->setChecked(false); mOldHistoryEnabled = false; ui.groupBox_History->hide(); @@ -93,8 +100,25 @@ WikiEditDialog::~WikiEditDialog() delete (mThreadCompareRole); } +void WikiEditDialog::mergeModeToggle() +{ + mHistoryMergeMode = ui.checkBox_Merge->isChecked(); + updateHistoryStatus(); +} + +void WikiEditDialog::generateMerge() +{ + std::cerr << "WikiEditDialog::generateMerge() TODO" << std::endl; + +} + void WikiEditDialog::textChanged() { + if (mIgnoreTextChange) + { + std::cerr << "WikiEditDialog::textChanged() Ignored" << std::endl; + return; + } std::cerr << "WikiEditDialog::textChanged()" << std::endl; mTextChanged = true; @@ -127,6 +151,23 @@ void WikiEditDialog::textReset() void WikiEditDialog::historySelected() { std::cerr << "WikiEditDialog::historySelected()" << std::endl; + + QList selected = ui.treeWidget_History->selectedItems(); + if (selected.empty()) + { + std::cerr << "WikiEditDialog::historySelected() ERROR Nothing selected" << std::endl; + return; + } + QTreeWidgetItem *item = *(selected.begin()); + + RsGxsGrpMsgIdPair newSnapshot = mThreadMsgIdPair; + std::string pageId = item->data(WET_DATA_COLUMN, WET_ROLE_PAGEID).toString().toStdString(); + newSnapshot.second = pageId; + + std::cerr << "WikiEditDialog::historySelected() New PageId: " << pageId; + std::cerr << std::endl; + + requestPage(newSnapshot); } @@ -139,6 +180,9 @@ void WikiEditDialog::oldHistoryChanged() void WikiEditDialog::updateHistoryStatus() { + std::cerr << "WikiEditDialog::updateHistoryStatus()"; + std::cerr << std::endl; + /* iterate through every History Item */ int count = ui.treeWidget_History->topLevelItemCount(); for(int i = 0; i < count; i++) @@ -180,12 +224,35 @@ void WikiEditDialog::updateHistoryItem(QTreeWidgetItem *item, bool isLatest) if (isSelectable) { + std::cerr << "WikiEditDialog::updateHistoryItem() isSelectable"; + std::cerr << std::endl; + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); + + if (mHistoryMergeMode) + { + QVariant qvar = item->data(WET_COL_PAGEID, Qt::CheckStateRole); + std::cerr << "WikiEditDialog::CheckStateRole:: VariantType: " << (int) qvar.type(); + std::cerr << std::endl; + if (!qvar.isValid()) + { + item->setData(WET_COL_PAGEID, Qt::CheckStateRole, Qt::Unchecked); + } + + } + else + { + item->setData(WET_COL_PAGEID, Qt::CheckStateRole, QVariant()); + } } else { - item->setFlags(0); + std::cerr << "WikiEditDialog::updateHistoryItem() NOT isSelectable"; + std::cerr << std::endl; + + item->setData(WET_COL_PAGEID, Qt::CheckStateRole, QVariant()); + item->setFlags(Qt::ItemIsUserCheckable); } } @@ -241,8 +308,6 @@ void WikiEditDialog::previewToggle() std::cerr << "WikiEditDialog::previewToggle()"; std::cerr << std::endl; - bool prevTextChanged = mTextChanged; - if (mPreviewMode) { mPreviewMode = false; @@ -255,16 +320,11 @@ void WikiEditDialog::previewToggle() mPreviewMode = true; ui.pushButton_Preview->setText(tr("Edit Page")); } - if (!mPageLoading) - { - redrawPage(); - } - /* fix textChanged signal - if we have caused it to change */ - if (!prevTextChanged) - { - textReset(); - } + + mIgnoreTextChange = true; + redrawPage(); + mIgnoreTextChange = false; std::cerr << "WikiEditDialog::previewToggle() END"; std::cerr << std::endl; @@ -334,7 +394,11 @@ void WikiEditDialog::setPreviousPage(RsWikiSnapshot &page) ui.lineEdit_Page->setText(QString::fromStdString(mWikiSnapshot.mMeta.mMsgName)); ui.lineEdit_PrevVersion->setText(QString::fromStdString(mWikiSnapshot.mMeta.mMsgId)); mCurrentText = QString::fromUtf8(mWikiSnapshot.mPage.c_str()); - redrawPage(); + + mIgnoreTextChange = true; + redrawPage(); + mIgnoreTextChange = false; + textReset(); } @@ -343,6 +407,7 @@ void WikiEditDialog::setNewPage() { mNewPage = true; mRepublishMode = false; + mHistoryLoaded = false; ui.lineEdit_Page->setText(""); ui.lineEdit_PrevVersion->setText(""); @@ -364,6 +429,7 @@ void WikiEditDialog::setRepublishMode(RsGxsMessageId &origMsgId) { mRepublishMode = true; mRepublishOrigId = origMsgId; + ui.pushButton_Submit->setText(tr("Republish")); } @@ -486,6 +552,7 @@ void WikiEditDialog::submitEdit() void WikiEditDialog::setupData(const std::string &groupId, const std::string &pageId) { mRepublishMode = false; + mHistoryLoaded = false; if (groupId != "") { requestGroup(groupId); @@ -495,12 +562,11 @@ void WikiEditDialog::setupData(const std::string &groupId, const std::string &pa { RsGxsGrpMsgIdPair msgId = std::make_pair(groupId, pageId); requestPage(msgId); - } - - - ui.headerFrame->setHeaderImage(QPixmap(":/images/story-editor_48.png")); - ui.headerFrame->setHeaderText(tr("Edit Wiki Page")); - setWindowTitle(tr("Edit Wiki Page")); + } + + ui.headerFrame->setHeaderImage(QPixmap(":/images/story-editor_48.png")); + ui.headerFrame->setHeaderText(tr("Edit Wiki Page")); + setWindowTitle(tr("Edit Wiki Page")); } @@ -584,7 +650,10 @@ void WikiEditDialog::loadPage(const uint32_t &token) { mThreadMsgIdPair.second = page.mMeta.mThreadId; } - requestBaseHistory(mThreadMsgIdPair); + if (!mHistoryLoaded) + { + requestBaseHistory(mThreadMsgIdPair); + } } mPageLoading = false; } @@ -801,6 +870,7 @@ void WikiEditDialog::loadEditTreeData(const uint32_t &token) } // Enable / Disable Items. + mHistoryLoaded = true; updateHistoryStatus(); } diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h index 903e9b601..0898d285d 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.h @@ -59,6 +59,8 @@ void textReset(); void historySelected(); void oldHistoryChanged(); +void mergeModeToggle(); +void generateMerge(); private: @@ -87,9 +89,12 @@ void loadEditTreeData(const uint32_t &token); bool mPreviewMode; bool mPageLoading; + bool mHistoryLoaded; + bool mHistoryMergeMode; bool mOldHistoryEnabled; bool mRepublishMode; + bool mIgnoreTextChange; // when we do it programmatically. bool mTextChanged; QString mCurrentText; diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui index db2c0df5f..9ec209d8c 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui @@ -6,8 +6,8 @@ 0 0 - 731 - 701 + 946 + 568 @@ -28,6 +28,7 @@ QFrame::Raised + splitter_History @@ -54,7 +55,7 @@ Page Edit History - + @@ -62,6 +63,23 @@ + + + + Chose for Merge + + + + + + + false + + + Merge for Republish (TODO) + + + From 385b37bc010c1e7c3917de6db219d70227f12129 Mon Sep 17 00:00:00 2001 From: defnax Date: Tue, 4 Dec 2012 10:37:15 +0000 Subject: [PATCH 200/222] fixed layout git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5938 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/WikiPoos/WikiDialog.ui | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui index dc2f0b6a2..3db94846c 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui @@ -19,8 +19,11 @@ Qt::Horizontal - + + + 0 + @@ -102,11 +105,14 @@ 0 0 - 241 - 448 + 268 + 456 + + 0 + @@ -333,8 +339,8 @@ 0 0 - 491 - 454 + 465 + 456 From 694885963ed6d572adddba98efed6a15003f3128 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Tue, 4 Dec 2012 16:06:21 +0000 Subject: [PATCH 201/222] Added CancelRequest on second request. Added new icon for the forum thread tab for the state loading. Started to lock the gui when data is loaded. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5940 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/gui/GxsForumsDialog.cpp | 35 ++++- retroshare-gui/src/gui/GxsForumsDialog.h | 2 + .../gui/gxsforums/GxsForumThreadWidget.cpp | 145 ++++++++++++++++-- .../src/gui/gxsforums/GxsForumThreadWidget.h | 24 ++- .../src/gui/gxsforums/GxsForumThreadWidget.ui | 11 +- 5 files changed, 187 insertions(+), 30 deletions(-) diff --git a/retroshare-gui/src/gui/GxsForumsDialog.cpp b/retroshare-gui/src/gui/GxsForumsDialog.cpp index 949887a1c..a5eb7b007 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/GxsForumsDialog.cpp @@ -69,6 +69,8 @@ GxsForumsDialog::GxsForumsDialog(QWidget *parent) /* Setup Queue */ mForumQueue = new TokenQueue(rsGxsForums->getTokenService(), this); + mTokenGroupSummary = 0; + mRequestGroupSummary = false; connect(ui.forumTreeWidget, SIGNAL(treeCustomContextMenuRequested(QPoint)), this, SLOT(forumListCustomPopupMenu(QPoint))); connect(ui.newForumButton, SIGNAL(clicked()), this, SLOT(newforum())); @@ -222,8 +224,6 @@ void GxsForumsDialog::updateDisplay() { /* update Forums List */ insertForums(); - /* update threads as well */ -//#TODO insertThreads(); } } @@ -342,7 +342,8 @@ void GxsForumsDialog::changedForum(const QString &id) if (!threadWidget) { /* create a thread widget */ threadWidget = new GxsForumThreadWidget(id.toStdString()); - ui.threadTabWidget->addTab(threadWidget, tr("Loading")); + int index = ui.threadTabWidget->addTab(threadWidget, threadWidget->forumName()); + ui.threadTabWidget->setTabIcon(index, threadWidget->forumIcon()); connect(threadWidget, SIGNAL(forumChanged(QWidget*)), this, SLOT(threadTabChanged(QWidget*))); } @@ -370,6 +371,7 @@ void GxsForumsDialog::threadTabChanged(QWidget *widget) } ui.threadTabWidget->setTabText(index, threadWidget->forumName()); + ui.threadTabWidget->setTabIcon(index, threadWidget->forumIcon()); } QString GxsForumsDialog::titleFromInfo(const RsMsgMetaData &meta) @@ -608,11 +610,20 @@ void GxsForumsDialog::requestGroupSummary() std::cerr << "GxsForumsDialog::requestGroupSummary()"; std::cerr << std::endl; + if (mRequestGroupSummary) { + std::cerr << "GxsForumsDialog::requestGroupSummary() Canceling Request: " << mTokenGroupSummary; + std::cerr << std::endl; + + mForumQueue->cancelRequest(mTokenGroupSummary); + mTokenGroupSummary = 0; + mRequestGroupSummary = false; + } + RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; - uint32_t token; - mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, FORUMSV2DIALOG_LISTING); + mForumQueue->requestGroupInfo(mTokenGroupSummary, RS_TOKREQ_ANSTYPE_SUMMARY, opts, FORUMSV2DIALOG_LISTING); + mRequestGroupSummary = true; } void GxsForumsDialog::loadGroupSummary(const uint32_t &token) @@ -620,6 +631,18 @@ void GxsForumsDialog::loadGroupSummary(const uint32_t &token) std::cerr << "GxsForumsDialog::loadGroupSummary()"; std::cerr << std::endl; + if (!mRequestGroupSummary) { + std::cerr << "GxsForumsDialog::loadGroupSummary()) No waiting request got token: " << token; + std::cerr << std::endl; + return; + } + + if (token != mTokenGroupSummary) { + std::cerr << "GxsForumsDialog::loadGroupSummary()) Wrong token - want: " << mTokenGroupSummary << " got: " << token; + std::cerr << std::endl; + return; + } + std::list groupInfo; rsGxsForums->getGroupSummary(token, groupInfo); @@ -632,6 +655,8 @@ void GxsForumsDialog::loadGroupSummary(const uint32_t &token) std::cerr << "GxsForumsDialog::loadGroupSummary() ERROR No Groups..."; std::cerr << std::endl; } + mTokenGroupSummary = 0; + mRequestGroupSummary = false; } /*********************** **** **** **** ***********************/ diff --git a/retroshare-gui/src/gui/GxsForumsDialog.h b/retroshare-gui/src/gui/GxsForumsDialog.h index 5ddd78c3b..d6bccbc41 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.h +++ b/retroshare-gui/src/gui/GxsForumsDialog.h @@ -106,6 +106,8 @@ private: std::string mForumId; TokenQueue *mForumQueue; + uint32_t mTokenGroupSummary; + bool mRequestGroupSummary; QTreeWidgetItem *yourForums; QTreeWidgetItem *subscribedForums; diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index 26db544b0..674e306e5 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -87,6 +87,9 @@ GxsForumThreadWidget::GxsForumThreadWidget(const std::string &forumId, QWidget * mInProcessSettings = false; mThreadQueue = new TokenQueue(rsGxsForums->getTokenService(), this); + mTokenGroupSummary = 0; + mTokenPost = 0; + mRequestGroupSummary = false; mInMsgAsReadUnread = false; @@ -108,6 +111,9 @@ GxsForumThreadWidget::GxsForumThreadWidget(const std::string &forumId, QWidget * connect(ui->nextUnreadButton, SIGNAL(clicked()), this, SLOT(nextUnreadMessage())); connect(ui->downloadButton, SIGNAL(clicked()), this, SLOT(downloadAllFiles())); + // HACK - TEMPORARY HIJACKING THIS BUTTON FOR REFRESH. + connect(ui->refreshButton, SIGNAL(clicked()), this, SLOT(forceUpdateDisplay())); + connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterItems(QString))); connect(ui->filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterColumnChanged(int))); @@ -159,8 +165,17 @@ GxsForumThreadWidget::GxsForumThreadWidget(const std::string &forumId, QWidget * ui->progLayOutTxt->hide(); ui->progressBarLayOut->setEnabled(false); +// mTimer = new QTimer; +// mTimer->setInterval(1000); +// mTimer->setSingleShot(true); + +// QObject::connect(mTimer, SIGNAL(timeout()), this, SLOT(updateDisplay())); + +// mTimer->start(); + mThreadLoading = false; + ui->forumName->setText(tr("Loading")); insertThreads(); ui->threadTreeWidget->installEventFilter(this); @@ -170,6 +185,7 @@ GxsForumThreadWidget::~GxsForumThreadWidget() { delete ui; +// delete(mTimer); delete(mThreadQueue); delete(mThreadCompareRole); } @@ -220,6 +236,25 @@ QString GxsForumThreadWidget::forumName() return ui->forumName->text(); } +QIcon GxsForumThreadWidget::forumIcon() +{ + if (mRequestGroupSummary || mThreadLoading) { + return QIcon(":/images/kalarm.png"); + } + +//#TODO +// if (has new messages) { +// return QIcon(nice icon); +// } + + return QIcon(); +} + +void GxsForumThreadWidget::updateInterface() +{ + emit forumChanged(this); +} + void GxsForumThreadWidget::changeEvent(QEvent *e) { QWidget::changeEvent(e); @@ -233,6 +268,39 @@ void GxsForumThreadWidget::changeEvent(QEvent *e) } } +#ifdef TODO +void GxsForumThreadWidget::updateDisplay() +{ + std::list forumIds; + std::list::iterator it; + if (!rsGxsForums) + return; + +#if 0 + // TODO groupsChanged... HACK XXX. + if ((rsGxsForums->groupsChanged(forumIds)) || (rsGxsForums->updated())) + { + /* update Forums List */ + insertForums(); + + it = std::find(forumIds.begin(), forumIds.end(), mCurrForumId); + if (it != forumIds.end()) + { + /* update threads as well */ + insertThreads(); + } + } +#endif + + /* The proper version (above) can be done with a data request -> TODO */ + if (rsGxsForums->updated()) + { + /* update Forums List */ + insertThreads(); + } +} +#endif + void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/) { if (mThreadLoading) { @@ -369,10 +437,6 @@ void GxsForumThreadWidget::togglethreadview_internal() void GxsForumThreadWidget::changedThread() { - if (mThreadLoading) { - return; - } - /* just grab the ids of the current item */ QTreeWidgetItem *item = ui->threadTreeWidget->currentItem(); @@ -381,11 +445,20 @@ void GxsForumThreadWidget::changedThread() } else { mThreadId = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString(); } + + if (mThreadLoading) { + return; + } + insertPost(); } void GxsForumThreadWidget::clickedThread(QTreeWidgetItem *item, int column) { + if (mThreadLoading) { + return; + } + if (mForumId.empty() || !IS_GROUP_SUBSCRIBED(mSubscribeFlags)) { return; } @@ -528,6 +601,16 @@ void GxsForumsDialog::fillThreadProgress(int current, int count) } #endif +// HACK until update works. +void GxsForumThreadWidget::forceUpdateDisplay() +{ + std::cerr << "GxsForumThreadWidget::forceUpdateDisplay()"; + std::cerr << std::endl; + + /* update Thread List */ + insertThreads(); +} + void GxsForumThreadWidget::insertThreads() { #ifdef DEBUG_FORUMS @@ -560,6 +643,8 @@ void GxsForumThreadWidget::insertThreads() return; } +// ui->threadTitle->setText(tr("Loading")); + // Get Current Forum Info... then complete insertForumThreads(). requestGroupSummary_CurrentForum(mForumId); } @@ -570,7 +655,7 @@ void GxsForumThreadWidget::insertForumThreads(const RsGroupMetaData &fi) QString forumName = QString::fromUtf8(fi.mGroupName.c_str()); if (forumName != ui->forumName->text()) { ui->forumName->setText(forumName); - emit forumChanged(this); + updateInterface(); } // ui->progressBarLayOut->setEnabled(true); @@ -680,6 +765,7 @@ void GxsForumThreadWidget::fillThreadFinished() ui->newthreadButton->setEnabled(IS_GROUP_SUBSCRIBED(mSubscribeFlags)); mThreadLoading = false; + updateInterface(); #ifdef DEBUG_FORUMS std::cerr << "GxsForumsDialog::fillThreadFinished done" << std::endl; @@ -1388,14 +1474,24 @@ void GxsForumThreadWidget::requestGroupSummary_CurrentForum(const std::string &f RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; + if (mRequestGroupSummary) { + std::cerr << "GxsForumThreadWidget::requestGroupSummary() Canceling Request: " << mTokenGroupSummary; + std::cerr << std::endl; + + mThreadQueue->cancelRequest(mTokenGroupSummary); + mTokenGroupSummary = 0; + mRequestGroupSummary = false; + } + std::list grpIds; grpIds.push_back(forumId); std::cerr << "GxsForumsDialog::requestGroupSummary_CurrentForum(" << forumId << ")"; std::cerr << std::endl; - uint32_t token; - mThreadQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, FORUMSV2DIALOG_CURRENTFORUM); + mThreadQueue->requestGroupInfo(mTokenGroupSummary, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, FORUMSV2DIALOG_CURRENTFORUM); + mRequestGroupSummary = true; + updateInterface(); } void GxsForumThreadWidget::loadGroupSummary_CurrentForum(const uint32_t &token) @@ -1403,8 +1499,23 @@ void GxsForumThreadWidget::loadGroupSummary_CurrentForum(const uint32_t &token) std::cerr << "GxsForumsDialog::loadGroupSummary_CurrentForum()"; std::cerr << std::endl; + if (!mRequestGroupSummary) { + std::cerr << "GxsForumThreadWidget::loadGroupSummary_CurrentForum()) No waiting request got token: " << token; + std::cerr << std::endl; + return; + } + + if (token != mTokenGroupSummary) { + std::cerr << "GxsForumThreadWidget::loadGroupSummary()) Wrong token - want: " << mTokenGroupSummary << " got: " << token; + std::cerr << std::endl; + return; + } + std::list groupInfo; rsGxsForums->getGroupSummary(token, groupInfo); + mTokenGroupSummary = 0; + mRequestGroupSummary = false; + updateInterface(); if (groupInfo.size() == 1) { @@ -1418,8 +1529,6 @@ void GxsForumThreadWidget::loadGroupSummary_CurrentForum(const uint32_t &token) } } -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ /*********************** **** **** **** ***********************/ /*********************** **** **** **** ***********************/ @@ -1457,6 +1566,7 @@ void GxsForumThreadWidget::loadCurrentForumThreads(const std::string &forumId) std::cerr << std::endl; mThreadLoading = true; + updateInterface(); mThreadLoad.ForumId = mForumId; //#AFTER MERGE mThreadLoad.FilterColumn = ui.filterLineEdit->currentFilter(); @@ -1774,6 +1884,14 @@ void GxsForumThreadWidget::requestMsgData_InsertPost(const RsGxsGrpMsgIdPair &ms uint32_t token; mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_INSERT_POST); #else + if (mTokenPost) { + std::cerr << "GxsForumThreadWidget::requestMsgData_InsertPost() Canceling Request: " << mTokenPost; + std::cerr << std::endl; + + mThreadQueue->cancelRequest(mTokenPost); + mTokenPost = 0; + } + RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; @@ -1784,8 +1902,7 @@ void GxsForumThreadWidget::requestMsgData_InsertPost(const RsGxsGrpMsgIdPair &ms std::vector &vect = msgIds[msgId.first]; vect.push_back(msgId.second); - uint32_t token; - mThreadQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_INSERT_POST); + mThreadQueue->requestMsgInfo(mTokenPost, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_INSERT_POST); #endif } @@ -1814,6 +1931,7 @@ void GxsForumThreadWidget::loadMsgData_InsertPost(const uint32_t &token) std::cerr << "GxsForumsDialog::loadMsgData_InsertPost() ERROR Missing Message Data..."; std::cerr << std::endl; } + mTokenPost = 0; } /*********************** **** **** **** ***********************/ @@ -1880,11 +1998,6 @@ void GxsForumThreadWidget::loadMsgData_ReplyMessage(const uint32_t &token) /*********************** **** **** **** ***********************/ /*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ - void GxsForumThreadWidget::loadRequest(const TokenQueue *queue, const TokenRequest &req) { std::cerr << "GxsForumsDialog::loadRequest() UserType: " << req.mUserType; diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h index a14b68f54..d24beed95 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h @@ -51,12 +51,12 @@ class GxsForumThreadWidget : public QWidget, public TokenResponse public: explicit GxsForumThreadWidget(const std::string &forumId, QWidget *parent = NULL); ~GxsForumThreadWidget(); - - QColor textColorRead() const { return mTextColorRead; } - QColor textColorUnread() const { return mTextColorUnread; } - QColor textColorUnreadChildren() const { return mTextColorUnreadChildren; } - QColor textColorNotSubscribed() const { return mTextColorNotSubscribed; } - QColor textColorMissing() const { return mTextColorMissing; } + + QColor textColorRead() const { return mTextColorRead; } + QColor textColorUnread() const { return mTextColorUnread; } + QColor textColorUnreadChildren() const { return mTextColorUnreadChildren; } + QColor textColorNotSubscribed() const { return mTextColorNotSubscribed; } + QColor textColorMissing() const { return mTextColorMissing; } void setTextColorRead(QColor color) { mTextColorRead = color; } void setTextColorUnread(QColor color) { mTextColorUnread = color; } @@ -66,6 +66,7 @@ public: std::string forumId() { return mForumId; } QString forumName(); + QIcon forumIcon(); // Callback for all Loads. virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); @@ -78,6 +79,10 @@ protected: void changeEvent(QEvent *e); private slots: + void forceUpdateDisplay(); // TEMP HACK FN. + +// void updateDisplay(); + /** Create the context popup menu and it's submenus */ void threadListCustomPopupMenu(QPoint point); @@ -143,6 +148,8 @@ private: void processSettings(bool bLoad); + void updateInterface(); + std::string mForumId; std::string mLastForumID; std::string mThreadId; @@ -152,6 +159,10 @@ private: int mLastViewType; RSTreeWidgetItemCompareRole *mThreadCompareRole; TokenQueue *mThreadQueue; + uint32_t mTokenGroupSummary; + uint32_t mTokenPost; + bool mRequestGroupSummary; +// QTimer *mTimer; void requestGroupSummary_CurrentForum(const std::string &forumId); void loadGroupSummary_CurrentForum(const uint32_t &token); @@ -173,7 +184,6 @@ private: bool convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, bool useChildTS, uint32_t filterColumn, GxsIdTreeWidgetItem *item); // bool convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, std::string authorName, bool useChildTS, uint32_t filterColumn, QTreeWidgetItem *item); - // New Datatypes to replace the FillThread. bool mThreadLoading; GxsForumsThreadLoadParameters mThreadLoad; diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.ui b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.ui index cc2d53656..57d65c158 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.ui +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.ui @@ -420,7 +420,7 @@ - + @@ -433,7 +433,7 @@ - + @@ -466,6 +466,13 @@ + + + + Refresh + + + From de757cfcae63934532b6b8c938bb19a666b417e8 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Wed, 5 Dec 2012 22:45:44 +0000 Subject: [PATCH 202/222] Added user type interogation of tokenQueue fix for posteditem serialisation added voting to gui, but no feedback yet post and topic generation code added for testing git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5945 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/serialiser/rsposteditems.cc | 2 +- libretroshare/src/services/p3posted.cc | 119 +++- libretroshare/src/services/p3posted.h | 20 + .../src/tests/gxs/genexchangetester.cpp | 11 +- .../src/tests/gxs/genexchangetester.h | 6 + retroshare-gui/src/RetroShare.pro | 7 +- .../src/gui/Posted/PostedCreatePostDialog.cpp | 2 +- .../src/gui/Posted/PostedCreatePostDialog.h | 2 + retroshare-gui/src/gui/Posted/PostedItem.cpp | 56 +- retroshare-gui/src/gui/Posted/PostedItem.h | 5 + .../src/gui/Posted/PostedListDialog.cpp | 100 +++- .../src/gui/Posted/PostedListDialog.h | 13 +- .../src/gui/Posted/PostedListDialog.ui | 540 +++++++++--------- .../src/gui/Posted/PostedUserTypes.h | 8 + retroshare-gui/src/util/TokenQueue.cpp | 42 ++ retroshare-gui/src/util/TokenQueue.h | 6 +- 16 files changed, 621 insertions(+), 318 deletions(-) create mode 100644 retroshare-gui/src/gui/Posted/PostedUserTypes.h diff --git a/libretroshare/src/serialiser/rsposteditems.cc b/libretroshare/src/serialiser/rsposteditems.cc index 99280b634..3b8269628 100644 --- a/libretroshare/src/serialiser/rsposteditems.cc +++ b/libretroshare/src/serialiser/rsposteditems.cc @@ -291,7 +291,7 @@ bool RsGxsPostedSerialiser::serialiseGxsPostedVoteItem(RsGxsPostedVoteItem* item /* skip the header */ offset += 8; - ok &= setRawUInt32(data, tlvsize, &offset, item->mVote.mDirection); + ok &= setRawUInt8(data, tlvsize, &offset, item->mVote.mDirection); if(offset != tlvsize) { diff --git a/libretroshare/src/services/p3posted.cc b/libretroshare/src/services/p3posted.cc index cc9e695cc..0f26845bf 100644 --- a/libretroshare/src/services/p3posted.cc +++ b/libretroshare/src/services/p3posted.cc @@ -1,11 +1,16 @@ #include #include +#include #include "p3posted.h" #include "gxs/rsgxsflags.h" #include "serialiser/rsposteditems.h" +#define NUM_TOPICS_TO_GENERATE 7 +#define NUM_POSTS_TO_GENERATE 8 +#define NUM_VOTES_TO_GENERATE 23 + const uint32_t RsPosted::FLAG_MSGTYPE_COMMENT = 0x0001; const uint32_t RsPosted::FLAG_MSGTYPE_POST = 0x0002; const uint32_t RsPosted::FLAG_MSGTYPE_VOTE = 0x0004; @@ -29,7 +34,7 @@ RsPostedVote::RsPostedVote(const RsGxsPostedVoteItem& item) p3Posted::p3Posted(RsGeneralDataService *gds, RsNetworkExchangeService *nes) : RsGenExchange(gds, nes, new RsGxsPostedSerialiser(), RS_SERVICE_GXSV1_TYPE_POSTED), RsPosted(this), mPostedMutex("Posted"), - mTokenService(NULL) + mTokenService(NULL), mGeneratingTopics(true), mGeneratingPosts(false) { mTokenService = RsGenExchange::getTokenService(); } @@ -41,6 +46,118 @@ void p3Posted::notifyChanges(std::vector &changes) void p3Posted::service_tick() { + generateTopics(); + + //generatePosts(); +} + +void p3Posted::generatePosts() +{ + if(mGeneratingPosts) + { + // request topics then chose at random which one to use to generate a post about + uint32_t token; + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; + mTokenService->requestGroupInfo(token, 0, opts); + double timeDelta = 2.; // slow tick + while(mTokenService->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + { +#ifndef WINDOWS_SYS + usleep((int) (timeDelta * 1000000)); +#else + Sleep((int) (timeDelta * 1000)); +#endif + } + + std::list grpIds; + RsGenExchange::getGroupList(token, grpIds); + + + // for each group generate NUM_POSTS_TO_GENERATE posts + std::list::iterator lit = grpIds.begin(); + + for(; lit != grpIds.end(); lit++) + { + RsGxsGroupId& grpId = *lit; + + std::vector tokens; + + for(int i=0; i < NUM_POSTS_TO_GENERATE; i++) + { + std::ostringstream ostrm; + ostrm << i; + std::string link = "link" + ostrm.str(); + + RsPostedPost post; + post.mLink = link; + post.mNotes = link; + post.mMeta.mMsgName = link; + post.mMeta.mGroupId = grpId; + + submitPost(token, post); + tokens.push_back(token); + } + + while(!tokens.empty()) + { + std::vector::iterator vit = tokens.begin(); + + for(; vit != tokens.end(); ) + { + if(mTokenService->requestStatus(*vit) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + vit = tokens.erase(vit); + else + vit++; + } + } + } + + + + + // stop generating posts after acknowledging all the ones you created + mGeneratingPosts = false; + } +} + +void p3Posted::generateTopics() +{ + if(mGeneratingTopics) + { + std::vector tokens; + + for(int i=0; i < NUM_TOPICS_TO_GENERATE; i++) + { + std::ostringstream strm; + strm << i; + std::string topicName = "Topic " + strm.str(); + + RsPostedGroup topic; + topic.mMeta.mGroupName = topicName; + + uint32_t token; + submitGroup(token, topic); + tokens.push_back(token); + } + + + while(!tokens.empty()) + { + std::vector::iterator vit = tokens.begin(); + + for(; vit != tokens.end(); ) + { + if(mTokenService->requestStatus(*vit) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + vit = tokens.erase(vit); + else + vit++; + } + } + + mGeneratingTopics = false; + mGeneratingPosts = true; + } } diff --git a/libretroshare/src/services/p3posted.h b/libretroshare/src/services/p3posted.h index 7a5e9d42b..f0df0ba19 100644 --- a/libretroshare/src/services/p3posted.h +++ b/libretroshare/src/services/p3posted.h @@ -62,6 +62,21 @@ protected: void service_tick(); +public: + + void generateTopics(); + /*! + * Exists solely for testing + */ + void generatePosts(); + + /*! + * Exists solely for testing + * Generates random votes to existing posts + * in the system + */ + void generateVotes(); + public: bool getGroup(const uint32_t &token, std::vector &group); @@ -132,6 +147,11 @@ private: RsTokenService* mTokenService; RsMutex mPostedMutex; + + + // for data generation + + bool mGeneratingPosts, mGeneratingTopics; }; #endif // P3POSTED_H diff --git a/libretroshare/src/tests/gxs/genexchangetester.cpp b/libretroshare/src/tests/gxs/genexchangetester.cpp index 15afd5135..203b57bc0 100644 --- a/libretroshare/src/tests/gxs/genexchangetester.cpp +++ b/libretroshare/src/tests/gxs/genexchangetester.cpp @@ -20,7 +20,16 @@ void GenExchangeTester::setUp() RsGixsDummy* gixsDummy = new RsGixsDummy("incoming", "outgoing"); - mTestService = new GenExchangeTestService(mDataStore, mNxs, gixsDummy, 0); + uint32_t serviceAuthenPolicy = 0; + + uint8_t flag = 0; + + flag = GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN; + RsGenExchange::setAuthenPolicyFlag(flag, serviceAuthenPolicy, + RsGenExchange::RESTRICTED_GRP_BITS); + + + mTestService = new GenExchangeTestService(mDataStore, mNxs, gixsDummy, serviceAuthenPolicy); mTokenService = mTestService->getTokenService(); mTestService->start(); } diff --git a/libretroshare/src/tests/gxs/genexchangetester.h b/libretroshare/src/tests/gxs/genexchangetester.h index 7dfc1d2e2..fac83a02d 100644 --- a/libretroshare/src/tests/gxs/genexchangetester.h +++ b/libretroshare/src/tests/gxs/genexchangetester.h @@ -49,6 +49,12 @@ public: bool testGrpMetaModRequest(); bool testMsgMetaModRequest(); + + // testing verification (publish). + // Strategy is + // inject a group which you only have the public signature for + // The injection can be done via + private: // to be called at start diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index f91209128..daaee05e4 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -197,8 +197,8 @@ bitdht { LIBS += ../../libbitdht/src/lib/libbitdht.a PRE_TARGETDEPS *= ../../libbitdht/src/lib/libbitdht.a - #LIBS += C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a - #PRE_TARGETDEPS *= C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a +# LIBS += C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a + # PRE_TARGETDEPS *= C:\Development\Rs\v0.5-gxs-b1\libbitdht\libbitdht-build-desktop\lib\libbitdht.a # Chris version. #LIBS += ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a @@ -988,7 +988,8 @@ posted { gui/Posted/PostedComments.h \ gui/Posted/PostedGroupDialog.h \ gui/Posted/PostedCreatePostDialog.h \ - gui/Posted/PostedCreateCommentDialog.h + gui/Posted/PostedCreateCommentDialog.h \ + gui/Posted/PostedUserTypes.h FORMS += gui/Posted/PostedDialog.ui \ gui/Posted/PostedListDialog.ui \ diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp index 00512379e..c9eebf008 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp @@ -19,7 +19,7 @@ void PostedCreatePostDialog::createPost() uint32_t token; mPosted->submitPost(token, post); - mTokenQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, 0); + mTokenQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, TOKEN_USER_TYPE_POST); close(); } diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h index 0c5ba887e..9a06042b8 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h @@ -3,6 +3,8 @@ #include #include "retroshare/rsposted.h" +#include "PostedUserTypes.h" + #include "util/TokenQueue.h" namespace Ui { diff --git a/retroshare-gui/src/gui/Posted/PostedItem.cpp b/retroshare-gui/src/gui/Posted/PostedItem.cpp index 449f54fc5..daf77a365 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.cpp +++ b/retroshare-gui/src/gui/Posted/PostedItem.cpp @@ -40,26 +40,28 @@ PostedItem::PostedItem(PostedHolder *postHolder, const RsPostedPost &post) :QWidget(NULL), mPostHolder(postHolder), mPost(post) { - setupUi(this); - setAttribute ( Qt::WA_DeleteOnClose, true ); + setupUi(this); + setAttribute ( Qt::WA_DeleteOnClose, true ); - QDateTime qtime; - qtime.setTime_t(mPost.mMeta.mPublishTs); - QString timestamp = qtime.toString("dd.MMMM yyyy hh:mm"); - dateLabel->setText(timestamp); - fromLabel->setText(QString::fromUtf8(post.mMeta.mAuthorId.c_str())); - titleLabel->setText("" + - QString::fromStdString(post.mMeta.mMsgName) + ""); - siteLabel->setText("" + - QString::fromStdString(post.mLink) + ""); + QDateTime qtime; + qtime.setTime_t(mPost.mMeta.mPublishTs); + QString timestamp = qtime.toString("dd.MMMM yyyy hh:mm"); + dateLabel->setText(timestamp); + fromLabel->setText(QString::fromUtf8(post.mMeta.mAuthorId.c_str())); + titleLabel->setText("" + + QString::fromStdString(post.mMeta.mMsgName) + ""); + siteLabel->setText("" + + QString::fromStdString(post.mLink) + ""); - scoreLabel->setText(QString("1")); + scoreLabel->setText(QString("1")); - connect( commentButton, SIGNAL( clicked() ), this, SLOT( loadComments() ) ); + connect( commentButton, SIGNAL( clicked() ), this, SLOT( loadComments() ) ); + connect( voteUpButton, SIGNAL(clicked()), this, SLOT(makeUpVote())); + connect( voteDownButton, SIGNAL(clicked()), this, SLOT( makeDownVote())); - return; + return; } RsPostedPost PostedItem::getPost() const @@ -67,9 +69,25 @@ RsPostedPost PostedItem::getPost() const return mPost; } +void PostedItem::makeDownVote() +{ + RsGxsGrpMsgIdPair msgId; + msgId.first = mPost.mMeta.mMsgId; + msgId.second = mPost.mMeta.mGroupId; + emit vote(msgId, false); +} + +void PostedItem::makeUpVote() +{ + RsGxsGrpMsgIdPair msgId; + msgId.first = mPost.mMeta.mMsgId; + msgId.second = mPost.mMeta.mGroupId; + emit vote(msgId, true); +} + void PostedItem::loadComments() { - std::cerr << "PostedItem::loadComments() Requesting for " << mThreadId; - std::cerr << std::endl; - mPostHolder->showComments(mPost); + std::cerr << "PostedItem::loadComments() Requesting for " << mThreadId; + std::cerr << std::endl; + mPostHolder->showComments(mPost); } diff --git a/retroshare-gui/src/gui/Posted/PostedItem.h b/retroshare-gui/src/gui/Posted/PostedItem.h index 6ed65ac9e..a78865040 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.h +++ b/retroshare-gui/src/gui/Posted/PostedItem.h @@ -50,6 +50,11 @@ public: private slots: void loadComments(); + void makeUpVote(); + void makeDownVote(); + +signals: + void vote(const RsGxsGrpMsgIdPair& msgId, bool up); private: uint32_t mType; diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp index 586fb54d3..6e632f791 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.cpp @@ -63,6 +63,9 @@ #define IMAGE_FORUMAUTHD ":/images/konv_message2.png" #define IMAGE_COPYLINK ":/images/copyrslink.png" +// token types to deal with + + /** Constructor */ PostedListDialog::PostedListDialog(CommentHolder *commentHolder, QWidget *parent) : RsAutoUpdatePage(1000,parent), mCommentHolder(commentHolder) @@ -87,8 +90,19 @@ PostedListDialog::PostedListDialog(CommentHolder *commentHolder, QWidget *parent mSortButton = ui.hotSortButton; connect( ui.newTopicButton, SIGNAL( clicked() ), this, SLOT( newTopic() ) ); + connect(ui.refreshButton, SIGNAL(clicked()), this, SLOT(refreshTopics())); } +void PostedListDialog::refreshTopics() +{ + std::cerr << "PostedListDialog::requestGroupSummary()"; + std::cerr << std::endl; + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; + uint32_t token; + mPostedQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, TOKEN_USER_TYPE_TOPIC); +} void PostedListDialog::groupListCustomPopupMenu( QPoint /*point*/ ) { @@ -106,6 +120,19 @@ void PostedListDialog::newPost() cp.exec(); } +void PostedListDialog::submitVote(const RsGxsGrpMsgIdPair &msgId, bool up) +{ + uint32_t token; + RsPostedVote vote; + + vote.mMeta.mGroupId = msgId.first; + vote.mMeta.mParentId = msgId.second; + vote.mDirection = (uint8_t)up; + rsPosted->submitVote(token, vote); + + mPostedQueue->queueRequest(token, 0 , RS_TOKREQ_ANSTYPE_ACK, TOKEN_USER_TYPE_VOTE); +} + void PostedListDialog::showComments(const RsPostedPost& post) { mCommentHolder->commentLoad(post); @@ -167,10 +194,10 @@ void PostedListDialog::requestGroupSummary() std::cerr << "PostedListDialog::requestGroupSummary()"; std::cerr << std::endl; - std::list ids; RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; uint32_t token; - mPostedQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, ids, POSTEDDIALOG_LISTING); + mPostedQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, TOKEN_USER_TYPE_TOPIC); } void PostedListDialog::acknowledgeGroup(const uint32_t &token) @@ -180,17 +207,15 @@ void PostedListDialog::acknowledgeGroup(const uint32_t &token) if(!grpId.empty()) { - std::list grpIds; - grpIds.push_back(grpId); RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; uint32_t reqToken; - mPostedQueue->requestGroupInfo(reqToken, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, 0); + mPostedQueue->requestGroupInfo(reqToken, RS_TOKREQ_ANSTYPE_SUMMARY, opts, TOKEN_USER_TYPE_TOPIC); } } -void PostedListDialog::acknowledgeMsg(const uint32_t &token) +void PostedListDialog::acknowledgePostMsg(const uint32_t &token) { RsGxsGrpMsgIdPair msgId; @@ -222,6 +247,18 @@ void PostedListDialog::loadPostData(const uint32_t &token) loadGroupThreadData_InsertThreads(token); } +void PostedListDialog::acknowledgeVoteMsg(const uint32_t &token) +{ + RsGxsGrpMsgIdPair msgId; + + rsPosted->acknowledgeMsg(token, msgId); +} + +void PostedListDialog::loadVoteData(const uint32_t &token) +{ + return; +} + /*********************** **** **** **** ***********************/ /*********************** **** **** **** ***********************/ @@ -307,7 +344,7 @@ void PostedListDialog::requestGroupThreadData_InsertThreads(const std::string &g std::cerr << std::endl; uint32_t token; - mPostedQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, POSTEDDIALOG_INSERTTHREADS); + mPostedQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, TOKEN_USER_TYPE_POST); } @@ -332,6 +369,7 @@ void PostedListDialog::loadGroupThreadData_InsertThreads(const uint32_t &token) void PostedListDialog::loadPost(const RsPostedPost &post) { PostedItem *item = new PostedItem(this, post); + connect(item, SIGNAL(vote(RsGxsGrpMsgIdPair,bool)), this, SLOT(submitVote(RsGxsGrpMsgIdPair,bool))); QLayout *alayout = ui.scrollAreaWidgetContents->layout(); alayout->addWidget(item); } @@ -391,16 +429,14 @@ void PostedListDialog::loadRequest(const TokenQueue *queue, const TokenRequest & std::cerr << std::endl; if (queue == mPostedQueue) - { + { /* now switch on req */ - switch(req.mType) + switch(req.mUserType) { - case TOKENREQ_GROUPINFO: + + case TOKEN_USER_TYPE_TOPIC: switch(req.mAnsType) { - case RS_TOKREQ_ANSTYPE_ACK: - acknowledgeGroup(req.mToken); - break; case RS_TOKREQ_ANSTYPE_SUMMARY: loadGroupSummary(req.mToken); break; @@ -409,11 +445,11 @@ void PostedListDialog::loadRequest(const TokenQueue *queue, const TokenRequest & break; } break; - case TOKENREQ_MSGINFO: + case TOKEN_USER_TYPE_POST: switch(req.mAnsType) { case RS_TOKREQ_ANSTYPE_ACK: - acknowledgeMsg(req.mToken); + acknowledgePostMsg(req.mToken); break; case RS_TOKREQ_ANSTYPE_DATA: loadPostData(req.mToken); @@ -422,13 +458,37 @@ void PostedListDialog::loadRequest(const TokenQueue *queue, const TokenRequest & std::cerr << "Error, unexpected anstype:" << req.mAnsType << std::endl; break; } - + break; + case TOKEN_USER_TYPE_VOTE: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgeVoteMsg(req.mToken); + break; + default: + std::cerr << "Error, unexpected anstype:" << req.mAnsType << std::endl; + break; + } + break; default: std::cerr << "PostedListDialog::loadRequest() ERROR: INVALID TYPE"; std::cerr << std::endl; break; } } + + /* now switch on req */ + switch(req.mType) + { + case TOKENREQ_GROUPINFO: + switch(req.mAnsType) + { + case RS_TOKREQ_ANSTYPE_ACK: + acknowledgeGroup(req.mToken); + break; + } + break; + } } @@ -442,10 +502,10 @@ void PostedListDialog::loadRequest(const TokenQueue *queue, const TokenRequest & void PostedListDialog::groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo &groupItemInfo) { groupItemInfo.id = QString::fromStdString(groupInfo.mGroupId); -groupItemInfo.name = QString::fromUtf8(groupInfo.mGroupName.c_str()); -//groupItemInfo.description = QString::fromUtf8(groupInfo.forumDesc); -groupItemInfo.popularity = groupInfo.mPop; -groupItemInfo.lastpost = QDateTime::fromTime_t(groupInfo.mLastPost); + groupItemInfo.name = QString::fromUtf8(groupInfo.mGroupName.c_str()); + //groupItemInfo.description = QString::fromUtf8(groupInfo.forumDesc); + groupItemInfo.popularity = groupInfo.mPop; + groupItemInfo.lastpost = QDateTime::fromTime_t(groupInfo.mLastPost); } diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.h b/retroshare-gui/src/gui/Posted/PostedListDialog.h index 0f61aefc1..0609a5406 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.h @@ -37,6 +37,7 @@ #include "util/TokenQueue.h" #include "retroshare-gui/RsAutoUpdatePage.h" +#include "PostedUserTypes.h" class CommentHolder; @@ -69,6 +70,9 @@ private slots: void newTopic(); void showGroupDetails(); void newPost(); + void refreshTopics(); + + void submitVote(const RsGxsGrpMsgIdPair& msgId, bool up); private: @@ -86,13 +90,20 @@ private: void loadGroupSummary_CurrentForum(const uint32_t &token); - void acknowledgeMsg(const uint32_t &token); + // posts + void acknowledgePostMsg(const uint32_t &token); void loadPostData(const uint32_t &token); void insertThreads(); void loadCurrentTopicThreads(const std::string &forumId); void requestGroupThreadData_InsertThreads(const std::string &forumId); void loadGroupThreadData_InsertThreads(const uint32_t &token); + // votes + + void acknowledgeVoteMsg(const uint32_t& token); + void loadVoteData(const uint32_t &token); + + void insertGroupData(const std::list &groupList); void groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, GroupItemInfo &groupItemInfo); diff --git a/retroshare-gui/src/gui/Posted/PostedListDialog.ui b/retroshare-gui/src/gui/Posted/PostedListDialog.ui index a685a6d99..32192f8d8 100644 --- a/retroshare-gui/src/gui/Posted/PostedListDialog.ui +++ b/retroshare-gui/src/gui/Posted/PostedListDialog.ui @@ -1,270 +1,270 @@ - - - PostedListDialog - - - - 0 - 0 - 792 - 426 - - - - Form - - - - - - - - false - - - - -1 - - - 0 - - - - - Hot - - - true - - - true - - - - - - - New - - - true - - - true - - - - - - - Top - - - true - - - false - - - true - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - Today - - - - - Yesterday - - - - - This Week - - - - - This Month - - - - - This Year - - - - - - - - - - Qt::Horizontal - - - - - - - New Topic - - - - - - - Submit Post - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - - - - - - - - - - Refresh - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Showing 1-100 - - - - - - - Prev - - - - - - - Next - - - - - - - - - true - - - - - 0 - 0 - 406 - 333 - - - - - 0 - 0 - - - - - - - Qt::Vertical - - - QSizePolicy::Minimum - - - - 20 - 309 - - - - - - - - - - - - - - - - - GroupTreeWidget - QWidget -
gui/common/GroupTreeWidget.h
- 1 -
-
- - -
+ + + PostedListDialog + + + + 0 + 0 + 792 + 426 + + + + Form + + + + + + + + false + + + + 6 + + + 0 + + + + + Hot + + + true + + + true + + + + + + + New + + + true + + + true + + + + + + + Top + + + true + + + false + + + true + + + + + + + + + + Refresh + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + Today + + + + + Yesterday + + + + + This Week + + + + + This Month + + + + + This Year + + + + + + + + + + Qt::Horizontal + + + + + + + New Topic + + + + + + + Submit Post + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Showing 1-100 + + + + + + + Prev + + + + + + + Next + + + + + + + + + true + + + + + 0 + 0 + 472 + 327 + + + + + 0 + 0 + + + + + + + Qt::Vertical + + + QSizePolicy::Minimum + + + + 20 + 309 + + + + + + + + + + + + + + + + + GroupTreeWidget + QWidget +
gui/common/GroupTreeWidget.h
+ 1 +
+
+ + +
diff --git a/retroshare-gui/src/gui/Posted/PostedUserTypes.h b/retroshare-gui/src/gui/Posted/PostedUserTypes.h new file mode 100644 index 000000000..aa05682ef --- /dev/null +++ b/retroshare-gui/src/gui/Posted/PostedUserTypes.h @@ -0,0 +1,8 @@ +#ifndef POSTEDUSERTYPES_H +#define POSTEDUSERTYPES_H + +#define TOKEN_USER_TYPE_POST 4 +#define TOKEN_USER_TYPE_VOTE 5 +#define TOKEN_USER_TYPE_TOPIC 6 + +#endif // POSTEDUSERTYPES_H diff --git a/retroshare-gui/src/util/TokenQueue.cpp b/retroshare-gui/src/util/TokenQueue.cpp index 43b3b419d..592448892 100644 --- a/retroshare-gui/src/util/TokenQueue.cpp +++ b/retroshare-gui/src/util/TokenQueue.cpp @@ -98,7 +98,9 @@ void TokenQueue::queueRequest(uint32_t token, uint32_t basictype, uint32_t ansty gettimeofday(&req.mRequestTs, NULL); req.mPollTs = req.mRequestTs; + mTokenMtx.lock(); mRequests.push_back(req); + mTokenMtx.unlock(); if (mRequests.size() == 1) { @@ -123,8 +125,11 @@ void TokenQueue::pollRequests() } TokenRequest req; + + mTokenMtx.lock(); req = mRequests.front(); mRequests.pop_front(); + mTokenMtx.unlock(); if (checkForRequest(req.mToken)) { @@ -139,7 +144,9 @@ void TokenQueue::pollRequests() /* drop old requests too */ if (time(NULL) - req.mRequestTs.tv_sec < MAX_REQUEST_AGE) { + mTokenMtx.lock(); mRequests.push_back(req); + mTokenMtx.unlock(); } else { @@ -163,6 +170,39 @@ bool TokenQueue::checkForRequest(uint32_t token) (RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE == status) ); } +bool TokenQueue::activeRequestExist(const uint32_t& userType) +{ + mTokenMtx.lock(); + + std::list::const_iterator lit = mRequests.begin(); + + for(; lit != mRequests.end(); lit++) + { + const TokenRequest& req = *lit; + + if(req.mUserType == userType) + return true; + } + + mTokenMtx.unlock(); +} + +void TokenQueue::activeRequestTokens(const uint32_t& userType, std::list& tokens) +{ + mTokenMtx.lock(); + + std::list::const_iterator lit = mRequests.begin(); + + for(; lit != mRequests.end(); lit++) + { + const TokenRequest& req = *lit; + + if(req.mUserType == userType) + tokens.push_back(req.mToken); + } + + mTokenMtx.unlock(); +} void TokenQueue::loadRequest(const TokenRequest &req) { @@ -181,6 +221,7 @@ bool TokenQueue::cancelRequest(const uint32_t token) std::list::iterator it; + mTokenMtx.lock(); for(it = mRequests.begin(); it != mRequests.end(); it++) { if (it->mToken == token) @@ -193,6 +234,7 @@ bool TokenQueue::cancelRequest(const uint32_t token) return true; } } + mTokenMtx.unlock(); std::cerr << "TokenQueue::cancelRequest() Failed to Find Request: " << token; std::cerr << std::endl; diff --git a/retroshare-gui/src/util/TokenQueue.h b/retroshare-gui/src/util/TokenQueue.h index f69b81d37..309c2647e 100644 --- a/retroshare-gui/src/util/TokenQueue.h +++ b/retroshare-gui/src/util/TokenQueue.h @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -37,7 +38,7 @@ #define TOKENREQ_GROUPINFO 1 #define TOKENREQ_MSGINFO 2 -#define TOKENREQ_MSGRELATEDINFO 3 +#define TOKENREQ_MSGRELATEDINFO 3 class TokenQueue; @@ -99,6 +100,8 @@ public: bool checkForRequest(uint32_t token); void loadRequest(const TokenRequest &req); + bool activeRequestExist(const uint32_t& userType); + void activeRequestTokens(const uint32_t& userType, std::list& tokens); protected: void doPoll(float dt); @@ -111,6 +114,7 @@ private: RsTokenService *mService; TokenResponse *mResponder; + QMutex mTokenMtx; QTimer *mTrigger; }; From 0c49fba4d8e09ec13fcdea213059fa9d5225bcfe Mon Sep 17 00:00:00 2001 From: thunder2 Date: Thu, 6 Dec 2012 17:51:07 +0000 Subject: [PATCH 203/222] Switched base class of TokenQueue from QWidget to QObject. Fixed unlock of the mutex in TokenQueue. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5949 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- retroshare-gui/src/util/TokenQueue.cpp | 61 ++++++++++++++------------ retroshare-gui/src/util/TokenQueue.h | 9 ++-- 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/retroshare-gui/src/util/TokenQueue.cpp b/retroshare-gui/src/util/TokenQueue.cpp index 592448892..d8a35f7a1 100644 --- a/retroshare-gui/src/util/TokenQueue.cpp +++ b/retroshare-gui/src/util/TokenQueue.cpp @@ -32,7 +32,7 @@ /** Constructor */ TokenQueue::TokenQueue(RsTokenService *service, TokenResponse *resp) - : QWidget(NULL), mService(service), mResponder(resp) + : QObject(NULL), mService(service), mResponder(resp) { } @@ -98,9 +98,9 @@ void TokenQueue::queueRequest(uint32_t token, uint32_t basictype, uint32_t ansty gettimeofday(&req.mRequestTs, NULL); req.mPollTs = req.mRequestTs; - mTokenMtx.lock(); + mTokenMtx.lock(); mRequests.push_back(req); - mTokenMtx.unlock(); + mTokenMtx.unlock(); if (mRequests.size() == 1) { @@ -126,10 +126,10 @@ void TokenQueue::pollRequests() TokenRequest req; - mTokenMtx.lock(); + mTokenMtx.lock(); req = mRequests.front(); mRequests.pop_front(); - mTokenMtx.unlock(); + mTokenMtx.unlock(); if (checkForRequest(req.mToken)) { @@ -144,9 +144,9 @@ void TokenQueue::pollRequests() /* drop old requests too */ if (time(NULL) - req.mRequestTs.tv_sec < MAX_REQUEST_AGE) { - mTokenMtx.lock(); + mTokenMtx.lock(); mRequests.push_back(req); - mTokenMtx.unlock(); + mTokenMtx.unlock(); } else { @@ -172,36 +172,41 @@ bool TokenQueue::checkForRequest(uint32_t token) bool TokenQueue::activeRequestExist(const uint32_t& userType) { - mTokenMtx.lock(); + mTokenMtx.lock(); - std::list::const_iterator lit = mRequests.begin(); + std::list::const_iterator lit = mRequests.begin(); - for(; lit != mRequests.end(); lit++) - { - const TokenRequest& req = *lit; + for(; lit != mRequests.end(); lit++) + { + const TokenRequest& req = *lit; - if(req.mUserType == userType) - return true; - } + if(req.mUserType == userType) + { + mTokenMtx.unlock(); + return true; + } + } - mTokenMtx.unlock(); + mTokenMtx.unlock(); + + return false; } void TokenQueue::activeRequestTokens(const uint32_t& userType, std::list& tokens) { - mTokenMtx.lock(); + mTokenMtx.lock(); - std::list::const_iterator lit = mRequests.begin(); + std::list::const_iterator lit = mRequests.begin(); - for(; lit != mRequests.end(); lit++) - { - const TokenRequest& req = *lit; + for(; lit != mRequests.end(); lit++) + { + const TokenRequest& req = *lit; - if(req.mUserType == userType) - tokens.push_back(req.mToken); - } + if(req.mUserType == userType) + tokens.push_back(req.mToken); + } - mTokenMtx.unlock(); + mTokenMtx.unlock(); } void TokenQueue::loadRequest(const TokenRequest &req) @@ -221,7 +226,7 @@ bool TokenQueue::cancelRequest(const uint32_t token) std::list::iterator it; - mTokenMtx.lock(); + mTokenMtx.lock(); for(it = mRequests.begin(); it != mRequests.end(); it++) { if (it->mToken == token) @@ -231,10 +236,12 @@ bool TokenQueue::cancelRequest(const uint32_t token) std::cerr << "TokenQueue::cancelRequest() Cleared Request: " << token; std::cerr << std::endl; + mTokenMtx.unlock(); + return true; } } - mTokenMtx.unlock(); + mTokenMtx.unlock(); std::cerr << "TokenQueue::cancelRequest() Failed to Find Request: " << token; std::cerr << std::endl; diff --git a/retroshare-gui/src/util/TokenQueue.h b/retroshare-gui/src/util/TokenQueue.h index 309c2647e..0e39efb47 100644 --- a/retroshare-gui/src/util/TokenQueue.h +++ b/retroshare-gui/src/util/TokenQueue.h @@ -67,7 +67,7 @@ public: * An important thing to note is that all requests are stacked (so FIFO) * This is to prevent overlapped loads on GXS UIs */ -class TokenQueue: public QWidget +class TokenQueue: public QObject { Q_OBJECT @@ -100,8 +100,9 @@ public: bool checkForRequest(uint32_t token); void loadRequest(const TokenRequest &req); - bool activeRequestExist(const uint32_t& userType); - void activeRequestTokens(const uint32_t& userType, std::list& tokens); + bool activeRequestExist(const uint32_t& userType); + void activeRequestTokens(const uint32_t& userType, std::list& tokens); + protected: void doPoll(float dt); @@ -114,7 +115,7 @@ private: RsTokenService *mService; TokenResponse *mResponder; - QMutex mTokenMtx; + QMutex mTokenMtx; QTimer *mTrigger; }; From 6527aaf2d86c319f3517c7b12a7176fecb51fe32 Mon Sep 17 00:00:00 2001 From: chrisparker126 Date: Sat, 8 Dec 2012 21:50:13 +0000 Subject: [PATCH 204/222] Recommiting from old repo: commit msg from last: Fixed minor bug in group creation msg now set to unread and unprocessed on creation (added read flag in gxsflags.h also) Got topic and post generation working Additional changes: Voting update now working git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5951 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/gxs/rsgenexchange.cc | 5 +- libretroshare/src/gxs/rsgenexchange.h | 22 +- libretroshare/src/gxs/rsgxsflags.h | 2 + libretroshare/src/retroshare/rsposted.h | 3 + libretroshare/src/services/p3posted.cc | 443 +++++++++++-------- libretroshare/src/services/p3posted.h | 46 +- retroshare-gui/src/gui/Posted/PostedItem.cpp | 15 +- retroshare-gui/src/gui/Posted/PostedItem.ui | 2 +- 8 files changed, 323 insertions(+), 215 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 2aef41746..a81c7341e 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -1264,6 +1264,7 @@ void RsGenExchange::publishMsgs() msg->metaData->serialise(metaDataBuff, &size); msg->meta.setBinData(metaDataBuff, size); + msg->metaData->mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_UNREAD; msgId = msg->msgId; grpId = msg->grpId; mDataAccess->addMsgData(msg); @@ -1322,9 +1323,11 @@ void RsGenExchange::publishGrps() int i = 0; for(; mit != mGrpsToPublish.end(); mit++) { + + if(i > GEN_EXCH_GRP_CHUNK-1) break; + toRemove.push_back(mit->first); i++; - if(i > GEN_EXCH_GRP_CHUNK) break; RsNxsGrp* grp = new RsNxsGrp(mServType); RsGxsGrpItem* grpItem = mit->second; diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 4d52786d4..115738920 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -403,20 +403,20 @@ public: void setGroupServiceString(uint32_t& token, const RsGxsGroupId& grpId, const std::string& servString); /*! - * sets the msg status flag - * @param token this is set to token value associated to this request - * @param grpId Id of group whose subscribe file will be changed - * @param status - * @param mask Mask to apply to status flag - */ + * sets the msg status flag + * @param token this is set to token value associated to this request + * @param grpId Id of group whose subscribe file will be changed + * @param status + * @param mask Mask to apply to status flag + */ void setMsgStatusFlags(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const uint32_t& status, const uint32_t& mask); /*! - * sets the message service string - * @param token this is set to token value associated to this request - * @param msgId Id of message whose service string will be changed - * @param servString The service string to set msg to - */ + * sets the message service string + * @param token this is set to token value associated to this request + * @param msgId Id of message whose service string will be changed + * @param servString The service string to set msg to + */ void setMsgServiceString(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const std::string& servString ); protected: diff --git a/libretroshare/src/gxs/rsgxsflags.h b/libretroshare/src/gxs/rsgxsflags.h index 3b4d22897..a30c663d9 100644 --- a/libretroshare/src/gxs/rsgxsflags.h +++ b/libretroshare/src/gxs/rsgxsflags.h @@ -91,6 +91,8 @@ namespace GXS_SERV { static const uint32_t GXS_MSG_STATUS_UNREAD = 0x00000200; + static const uint32_t GXS_MSG_STATUS_READ = 0x00000400; + /** END GXS Msg status flags **/ /** START GXS Grp status flags **/ diff --git a/libretroshare/src/retroshare/rsposted.h b/libretroshare/src/retroshare/rsposted.h index 2094ce89b..e6ced7349 100644 --- a/libretroshare/src/retroshare/rsposted.h +++ b/libretroshare/src/retroshare/rsposted.h @@ -78,6 +78,7 @@ std::ostream &operator<<(std::ostream &out, const RsPostedVote &vote); std::ostream &operator<<(std::ostream &out, const RsPostedComment &comment); + class RsPosted : public RsGxsIfaceImpl { public: @@ -106,6 +107,8 @@ virtual ~RsPosted() { return; } virtual bool submitVote(uint32_t &token, RsPostedVote &vote) = 0; virtual bool submitComment(uint32_t &token, RsPostedComment &comment) = 0; + virtual bool retrieveScores(const std::string& serviceString, uint32_t& upVotes, uint32_t& downVotes, uint32_t& nComments) const = 0; + // Special Ranking Request. /*! * Makes request for posts of a topic diff --git a/libretroshare/src/services/p3posted.cc b/libretroshare/src/services/p3posted.cc index 0f26845bf..20736ee6c 100644 --- a/libretroshare/src/services/p3posted.cc +++ b/libretroshare/src/services/p3posted.cc @@ -7,10 +7,19 @@ #include "gxs/rsgxsflags.h" #include "serialiser/rsposteditems.h" -#define NUM_TOPICS_TO_GENERATE 7 -#define NUM_POSTS_TO_GENERATE 8 +#define UPDATE_PHASE_GRP_REQUEST 1 +#define UPDATE_PHASE_MSG_REQUEST 2 +#define UPDATE_PHASE_VOTE_COMMENT_REQUEST 3 +#define UPDATE_PHASE_VOTE_COUNT 4 +#define UPDATE_PHASE_COMMENT_COUNT 5 +#define UPDATE_PHASE_COMPLETE 6 + +#define NUM_TOPICS_TO_GENERATE 1 +#define NUM_POSTS_TO_GENERATE 1 #define NUM_VOTES_TO_GENERATE 23 +#define VOTE_UPDATE_PERIOD 20 // 20 seconds + const uint32_t RsPosted::FLAG_MSGTYPE_COMMENT = 0x0001; const uint32_t RsPosted::FLAG_MSGTYPE_POST = 0x0002; const uint32_t RsPosted::FLAG_MSGTYPE_VOTE = 0x0004; @@ -34,8 +43,12 @@ RsPostedVote::RsPostedVote(const RsGxsPostedVoteItem& item) p3Posted::p3Posted(RsGeneralDataService *gds, RsNetworkExchangeService *nes) : RsGenExchange(gds, nes, new RsGxsPostedSerialiser(), RS_SERVICE_GXSV1_TYPE_POSTED), RsPosted(this), mPostedMutex("Posted"), - mTokenService(NULL), mGeneratingTopics(true), mGeneratingPosts(false) + mTokenService(NULL), mGeneratingTopics(true), mGeneratingPosts(false), mRequestPhase1(true), mRequestPhase2(false), mRequestPhase3(false) { + mPostUpdate = false; + mLastUpdate = time(NULL); + mUpdatePhase = UPDATE_PHASE_GRP_REQUEST; + mTokenService = RsGenExchange::getTokenService(); } @@ -46,78 +59,100 @@ void p3Posted::notifyChanges(std::vector &changes) void p3Posted::service_tick() { - generateTopics(); - //generatePosts(); + generateTopics(); + generatePosts(); + + time_t now = time(NULL); + + if((now > (time_t) (VOTE_UPDATE_PERIOD + mLastUpdate)) && + (mUpdatePhase == UPDATE_PHASE_GRP_REQUEST)) + { + mPostUpdate = true; + mLastUpdate = time(NULL); + } + + updateVotes(); } void p3Posted::generatePosts() { if(mGeneratingPosts) { - // request topics then chose at random which one to use to generate a post about - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; - mTokenService->requestGroupInfo(token, 0, opts); - double timeDelta = 2.; // slow tick - while(mTokenService->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + + + if(mRequestPhase1) { -#ifndef WINDOWS_SYS - usleep((int) (timeDelta * 1000000)); -#else - Sleep((int) (timeDelta * 1000)); -#endif + // request topics then chose at random which one to use to generate a post about + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; + mTokenService->requestGroupInfo(mToken, 0, opts); + mRequestPhase1 = false; + return; + } + else if(!mRequestPhase2) + { + if(mTokenService->requestStatus(mToken) == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + { + RsGenExchange::getGroupList(mToken, mGrpIds); + + mRequestPhase2 = true; + } } - std::list grpIds; - RsGenExchange::getGroupList(token, grpIds); - - - // for each group generate NUM_POSTS_TO_GENERATE posts - std::list::iterator lit = grpIds.begin(); - - for(; lit != grpIds.end(); lit++) + if(mRequestPhase2) { - RsGxsGroupId& grpId = *lit; + // for each group generate NUM_POSTS_TO_GENERATE posts + std::list::iterator lit = mGrpIds.begin(); - std::vector tokens; - - for(int i=0; i < NUM_POSTS_TO_GENERATE; i++) + for(; lit != mGrpIds.end(); lit++) { - std::ostringstream ostrm; - ostrm << i; - std::string link = "link" + ostrm.str(); + RsGxsGroupId& grpId = *lit; - RsPostedPost post; - post.mLink = link; - post.mNotes = link; - post.mMeta.mMsgName = link; - post.mMeta.mGroupId = grpId; + for(int i=0; i < NUM_POSTS_TO_GENERATE; i++) + { + std::ostringstream ostrm; + ostrm << i; + std::string link = "link " + ostrm.str(); - submitPost(token, post); - tokens.push_back(token); + RsPostedPost post; + post.mLink = link; + post.mNotes = link; + post.mMeta.mMsgName = link; + post.mMeta.mGroupId = grpId; + + uint32_t token; + submitPost(token, post); + mTokens.push_back(token); + } } - while(!tokens.empty()) - { - std::vector::iterator vit = tokens.begin(); + mRequestPhase2 = false; + mRequestPhase3 = true; - for(; vit != tokens.end(); ) + } + else if(mRequestPhase3) + { + + if(!mTokens.empty()) + { + std::vector::iterator vit = mTokens.begin(); + + for(; vit != mTokens.end(); ) { - if(mTokenService->requestStatus(*vit) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) - vit = tokens.erase(vit); + if(mTokenService->requestStatus(*vit) == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + vit = mTokens.erase(vit); else vit++; } + }else + { + // stop generating posts after acknowledging all the ones you created + mGeneratingPosts = false; + mRequestPhase3 = false; } + } - - - - - // stop generating posts after acknowledging all the ones you created - mGeneratingPosts = false; } } @@ -125,40 +160,53 @@ void p3Posted::generateTopics() { if(mGeneratingTopics) { - std::vector tokens; - - for(int i=0; i < NUM_TOPICS_TO_GENERATE; i++) + if(mRequestPhase1) { - std::ostringstream strm; - strm << i; - std::string topicName = "Topic " + strm.str(); - - RsPostedGroup topic; - topic.mMeta.mGroupName = topicName; - - uint32_t token; - submitGroup(token, topic); - tokens.push_back(token); - } - while(!tokens.empty()) - { - std::vector::iterator vit = tokens.begin(); - - for(; vit != tokens.end(); ) + for(int i=0; i < NUM_TOPICS_TO_GENERATE; i++) { - if(mTokenService->requestStatus(*vit) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) - vit = tokens.erase(vit); - else - vit++; + std::ostringstream strm; + strm << i; + std::string topicName = "Topic " + strm.str(); + + RsPostedGroup topic; + topic.mMeta.mGroupName = topicName; + + uint32_t token; + submitGroup(token, topic); + mTokens.push_back(token); + } + + mRequestPhase1 = false; + } + else + { + + if(!mTokens.empty()) + { + std::vector::iterator vit = mTokens.begin(); + + for(; vit != mTokens.end(); ) + { + if(mTokenService->requestStatus(*vit) == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + { + RsGxsGroupId grpId; + RsGenExchange::acknowledgeTokenGrp(*vit, grpId); + vit = mTokens.erase(vit); + } + else + vit++; + } + } + else + { + mGeneratingPosts = true; + mGeneratingTopics = false; + mRequestPhase1 = true; } } - - mGeneratingTopics = false; - mGeneratingPosts = true; } - } bool p3Posted::getGroup(const uint32_t &token, std::vector &groups) @@ -594,7 +642,7 @@ void p3Posted::completePostedCommentRanking(GxsPostedCommentRanking *gpc) } } -bool p3Posted::retrieveScores(const std::string &serviceString, uint32_t &upVotes, uint32_t downVotes, uint32_t nComments) const +bool p3Posted::retrieveScores(const std::string &serviceString, uint32_t &upVotes, uint32_t& downVotes, uint32_t& nComments) const { if (3 == sscanf(serviceString.c_str(), "%d %d %d", &upVotes, &downVotes, &nComments)) { @@ -619,191 +667,222 @@ void p3Posted::processCommentRanks() } + void p3Posted::updateVotes() { - if(!mUpdateTokenQueued) - { - mUpdateTokenQueued = true; + // any request failure stops update process + if(mPostUpdate) + { switch(mUpdatePhase) { -// case UPDATE_PHASE_GRP_REQUEST: -// { -// updateRequestGroups(mUpda); -// break; -// } -// case UPDATE_PHASE_GRP_MSG_REQUEST: -// { -// updateRequestMessages(mVoteUpdataToken); -// break; -// } -// case UPDATE_VOTE_COMMENT_REQUEST: -// { -// updateRequestVotesComments(mVoteUpdataToken); -// break; -// } -// case UPDATE_COMPLETE_UPDATE: -// { -// updateCompleteUpdate(); -// break; -// } -// default: -// break; + case UPDATE_PHASE_GRP_REQUEST: + { + mPostUpdate = updateRequestGroups(); + break; + } + case UPDATE_PHASE_MSG_REQUEST: + { + mPostUpdate = updateRequestMessages(); + break; + } + case UPDATE_PHASE_VOTE_COMMENT_REQUEST: + { + mPostUpdate = updateRequestVotesComments(); + break; + } + case UPDATE_PHASE_VOTE_COUNT: + { + mPostUpdate = updateCompleteVotes(); + break; + } + case UPDATE_PHASE_COMPLETE: + { + updateComplete(); + break; + } + default: + { + std::cerr << "Unknown update phase, we should not be here!" << std::endl; + break; + } } - - // first get all msgs for groups for which you are subscribed to. - // then request comments for them - } } -bool p3Posted::updateRequestGroups(uint32_t &token) +bool p3Posted::updateRequestGroups() { RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; - opts.mSubscribeMask = GXS_SERV::GROUP_SUBSCRIBE_MASK; - opts.mSubscribeFilter = GXS_SERV::GROUP_SUBSCRIBE_ADMIN | - GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED; - mTokenService->requestGroupInfo(token, 0, opts); + // opts.mSubscribeMask = GXS_SERV::GROUP_SUBSCRIBE_MASK; +// opts.mSubscribeFilter = GXS_SERV::GROUP_SUBSCRIBE_ADMIN | +// GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED; + mTokenService->requestGroupInfo(mUpdateRequestGroup, 0, opts); - mUpdatePhase = UPDATE_PHASE_GRP_MSG_REQUEST; + mUpdatePhase = UPDATE_PHASE_MSG_REQUEST; } -bool p3Posted::updateRequestMessages(uint32_t &token) +bool p3Posted::updateRequestMessages() { - uint32_t status = mTokenService->requestStatus(token); + uint32_t status = mTokenService->requestStatus(mUpdateRequestGroup); if(status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) { std::list grpIds; - RsGenExchange::getGroupList(token, grpIds); + RsGenExchange::getGroupList(mUpdateRequestGroup, grpIds); RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; + opts.mReqType = GXS_REQUEST_TYPE_MSG_META; opts.mOptions = RS_TOKREQOPT_MSG_LATEST | RS_TOKREQOPT_MSG_THREAD; - mTokenService->requestMsgInfo(token, 0, opts, grpIds); - mUpdatePhase = UPDATE_VOTE_COMMENT_REQUEST; + mTokenService->requestMsgInfo(mUpdateRequestMessages, 0, opts, grpIds); + mUpdatePhase = UPDATE_PHASE_VOTE_COMMENT_REQUEST; return true; } else if(status == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED) { - mTokenService->cancelRequest(token); + mTokenService->cancelRequest(mUpdateRequestGroup); return false; } + + return true; } -bool p3Posted::updateRequestVotesComments(uint32_t &token) +bool p3Posted::updateRequestVotesComments() { - uint32_t status = mTokenService->requestStatus(token); + uint32_t status = mTokenService->requestStatus(mUpdateRequestMessages); if(status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) { - GxsMsgIdResult result; - RsGenExchange::getMsgList(token, result); + RsGenExchange::getMsgMeta(mUpdateRequestMessages, mMsgMetaUpdate); std::vector msgIds; - GxsMsgIdResult::iterator mit = result.begin(); + GxsMsgMetaMap::iterator mit = mMsgMetaUpdate.begin(); - for(; mit != result.end(); mit++) + for(; mit != mMsgMetaUpdate.end(); mit++) { - std::vector& msgIdV = mit->second; - std::vector::const_iterator cit = msgIdV.begin(); + std::vector& msgIdV = mit->second; + std::vector::const_iterator cit = msgIdV.begin(); for(; cit != msgIdV.end(); cit++) - msgIds.push_back(std::make_pair(mit->first, *cit)); + msgIds.push_back(std::make_pair(mit->first, cit->mMsgId)); } - // only need ids for comments RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST | RS_TOKREQOPT_MSG_PARENT; - opts.mMsgFlagMask = RsPosted::FLAG_MSGTYPE_MASK; - opts.mMsgFlagFilter = RsPosted::FLAG_MSGTYPE_COMMENT; - mTokenService->requestMsgRelatedInfo(mCommentToken, 0, opts, msgIds); +// // only need ids for comments +// +// opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS; +// opts.mOptions = RS_TOKREQOPT_MSG_LATEST | RS_TOKREQOPT_MSG_PARENT; +// opts.mMsgFlagMask = RsPosted::FLAG_MSGTYPE_MASK; +// opts.mMsgFlagFilter = RsPosted::FLAG_MSGTYPE_COMMENT; +// mTokenService->requestMsgRelatedInfo(mCommentToken, 0, opts, msgIds); - // need actual data from votes - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + // need actual data for votes + opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; opts.mOptions = RS_TOKREQOPT_MSG_LATEST | RS_TOKREQOPT_MSG_PARENT; opts.mMsgFlagMask = RsPosted::FLAG_MSGTYPE_MASK; opts.mMsgFlagFilter = RsPosted::FLAG_MSGTYPE_VOTE; - mTokenService->requestMsgRelatedInfo(mVoteToken, 0, opts, msgIds); + mTokenService->requestMsgRelatedInfo(mUpdateRequestVotes, 0, opts, msgIds); - mUpdatePhase = UPDATE_COMPLETE_UPDATE; - mMsgsPendingUpdate = msgIds; + mUpdatePhase = UPDATE_PHASE_VOTE_COUNT; return true; } else if(status == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED) { - mTokenService->cancelRequest(token); + mTokenService->cancelRequest(mUpdateRequestMessages); return false; } + + return true; } -bool p3Posted::updateCompleteUpdate() + +bool p3Posted::updateCompleteVotes() { - uint32_t commentStatus = mTokenService->requestStatus(mCommentToken); - uint32_t voteStatus = mTokenService->requestStatus(mVoteToken); + uint32_t status = mTokenService->requestStatus(mUpdateRequestVotes); - bool ready = commentStatus == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE; - ready &= voteStatus == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE; - - bool failed = commentStatus == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED; - failed &= voteStatus == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED; - - if(ready) + if(status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) { - std::map > msgCommentIds; std::map > votes; - getMsgRelatedDataT(mVoteToken, votes); - std::vector::iterator vit = mMsgsPendingUpdate.begin(); + getMsgRelatedDataT(mUpdateRequestVotes, + votes); - for(; vit != mMsgsPendingUpdate.end();vit++) + // now for each msg count the number of votes and thats it + + std::map >::iterator mit = votes.begin(); + + for(; mit != votes.end(); mit++) { - updateMsg(*vit, votes[*vit], msgCommentIds[*vit]); + const std::vector& v = mit->second; + std::vector::const_iterator cit = v.begin(); + + for(; cit != v.end(); cit++) + { + const RsPostedVote& vote = *cit; + + if(vote.mDirection) + { + mMsgCounts[mit->first].upVotes++; + }else + { + mMsgCounts[mit->first].downVotes++; + } + } } - mUpdatePhase = 0; + mUpdatePhase = UPDATE_PHASE_COMPLETE; } - else if(failed) + else if(status == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED) { - mTokenService->cancelRequest(mCommentToken); - mTokenService->cancelRequest(mVoteToken); + mTokenService->cancelRequest(mUpdateRequestVotes); return false; - }else - { - return true; } + return true; } -bool p3Posted::updateMsg(const RsGxsGrpMsgIdPair& msgId, const std::vector &msgVotes, - const std::vector& msgCommentIds) +bool p3Posted::updateComplete() { + // now compare with msg meta to see what currently store there - uint32_t nComments = msgCommentIds.size(); - uint32_t nUp = 0, nDown = 0; + GxsMsgMetaMap::iterator mit = mMsgMetaUpdate.begin(); - std::vector::const_iterator cit = msgVotes.begin(); - - for(; cit != msgVotes.end(); cit++) + for(; mit != mMsgMetaUpdate.end(); mit++) { - const RsPostedVote& v = *cit; + const std::vector& msgMetaV = mit->second; + std::vector::const_iterator cit = msgMetaV.begin(); - if(v.mDirection == 0) + for(; cit != msgMetaV.end(); cit++) { - nDown++; - }else - { - nUp++; + const RsMsgMetaData& msgMeta = *cit; + uint32_t upVotes, downVotes, nComments; + retrieveScores(msgMeta.mServiceString, upVotes, downVotes, nComments); + + RsGxsGrpMsgIdPair msgId; + msgId.first = mit->first; + msgId.second = msgMeta.mMsgId; + PostedScore& sc = mMsgCounts[msgId]; + + bool changed = (sc.upVotes != upVotes) || (sc.downVotes != downVotes); + + if(changed) + { + std::string servStr; + storeScores(servStr, sc.upVotes, sc.downVotes, 0); + uint32_t token; + setMsgServiceString(token, msgId, servStr); + mChangeTokens.push_back(token); + } + else + { + mMsgCounts.erase(msgId); + } } } - std::string servStr; - storeScores(servStr, nUp, nDown, nComments); - uint32_t token; - setMsgServiceString(token, msgId, servStr); -} + mPostUpdate = false; + mUpdatePhase = UPDATE_PHASE_GRP_REQUEST; +} diff --git a/libretroshare/src/services/p3posted.h b/libretroshare/src/services/p3posted.h index f0df0ba19..e006ba69d 100644 --- a/libretroshare/src/services/p3posted.h +++ b/libretroshare/src/services/p3posted.h @@ -31,16 +31,15 @@ public: class PostedScore { public: - int32_t upVotes, downVotes; + + PostedScore() : upVotes(0), downVotes(0), commentCount(0), date(0) {} + uint32_t upVotes, downVotes; + uint32_t commentCount; time_t date; RsGxsMessageId msgId; }; -#define UPDATE_PHASE_GRP_REQUEST 1 -#define UPDATE_PHASE_GRP_MSG_REQUEST 2 -#define UPDATE_VOTE_COMMENT_REQUEST 3 -#define UPDATE_COMPLETE_UPDATE 4 class p3Posted : public RsGenExchange, public RsPosted { @@ -93,6 +92,8 @@ public: bool requestMessageRankings(uint32_t &token, const RankType &rType, const RsGxsGroupId &groupId); bool requestCommentRankings(uint32_t &token, const RankType &rType, const RsGxsGrpMsgIdPair &msgId); + bool retrieveScores(const std::string& serviceString, uint32_t& upVotes, uint32_t& downVotes, uint32_t& nComments) const; + private: /* Functions for processing rankings */ @@ -103,7 +104,7 @@ private: void discardCalc(const uint32_t& token); void completePostedPostCalc(GxsPostedPostRanking* gpp); void completePostedCommentRanking(GxsPostedCommentRanking* gpc); - bool retrieveScores(const std::string& serviceString, uint32_t& upVotes, uint32_t downVotes, uint32_t nComments) const; + bool storeScores(std::string& serviceString, uint32_t& upVotes, uint32_t downVotes, uint32_t nComments) const; // for posts @@ -124,12 +125,19 @@ private: * Also stores updates for messages which have new scores */ void updateVotes(); - bool updateRequestGroups(uint32_t& token); - bool updateRequestMessages(uint32_t& token); - bool updateRequestVotesComments(uint32_t& token); - bool updateCompleteUpdate(); - bool updateMsg(const RsGxsGrpMsgIdPair& msgId, const std::vector& msgVotes, - const std::vector& msgCommentIds); + bool updateRequestGroups(); + bool updateRequestMessages(); + bool updateRequestVotesComments(); + bool updateCompleteVotes(); + bool updateCompleteComments(); + + /*! + * The aim of this is create notifications + * for the UI of changes to a post if their vote + * or comment count has changed + */ + bool updateComplete(); + private: @@ -140,10 +148,14 @@ private: std::map mPendingCalculationCommentRanks; // for maintaining vote counts in msg meta - uint32_t mVoteUpdataToken, mVoteToken, mCommentToken; - bool mUpdateTokenQueued; + uint32_t mUpdateRequestGroup, mUpdateRequestMessages, mUpdateRequestComments, mUpdateRequestVotes; + bool mPostUpdate; uint32_t mUpdatePhase; std::vector mMsgsPendingUpdate; + time_t mLastUpdate; + GxsMsgMetaMap mMsgMetaUpdate; + std::map mMsgCounts; + std::vector mChangeTokens; RsTokenService* mTokenService; RsMutex mPostedMutex; @@ -151,7 +163,11 @@ private: // for data generation - bool mGeneratingPosts, mGeneratingTopics; + bool mGeneratingPosts, mGeneratingTopics, mRequestPhase1, mRequestPhase2, mRequestPhase3; + std::vector mTokens; + uint32_t mToken; + std::list mGrpIds; + }; #endif // P3POSTED_H diff --git a/retroshare-gui/src/gui/Posted/PostedItem.cpp b/retroshare-gui/src/gui/Posted/PostedItem.cpp index daf77a365..8fd80b09b 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.cpp +++ b/retroshare-gui/src/gui/Posted/PostedItem.cpp @@ -55,7 +55,12 @@ PostedItem::PostedItem(PostedHolder *postHolder, const RsPostedPost &post) ">" + QString::fromStdString(post.mLink) + ""); - scoreLabel->setText(QString("1")); + uint32_t up, down, nComments; + + rsPosted->retrieveScores(mPost.mMeta.mServiceString, up, down, nComments); + + int32_t vote = up - down; + scoreLabel->setText(QString::number(vote)); connect( commentButton, SIGNAL( clicked() ), this, SLOT( loadComments() ) ); connect( voteUpButton, SIGNAL(clicked()), this, SLOT(makeUpVote())); @@ -72,16 +77,16 @@ RsPostedPost PostedItem::getPost() const void PostedItem::makeDownVote() { RsGxsGrpMsgIdPair msgId; - msgId.first = mPost.mMeta.mMsgId; - msgId.second = mPost.mMeta.mGroupId; + msgId.first = mPost.mMeta.mGroupId; + msgId.second = mPost.mMeta.mMsgId; emit vote(msgId, false); } void PostedItem::makeUpVote() { RsGxsGrpMsgIdPair msgId; - msgId.first = mPost.mMeta.mMsgId; - msgId.second = mPost.mMeta.mGroupId; + msgId.first = mPost.mMeta.mGroupId; + msgId.second = mPost.mMeta.mMsgId; emit vote(msgId, true); } diff --git a/retroshare-gui/src/gui/Posted/PostedItem.ui b/retroshare-gui/src/gui/Posted/PostedItem.ui index 1d0fe0307..aa7c37aa2 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.ui +++ b/retroshare-gui/src/gui/Posted/PostedItem.ui @@ -53,7 +53,7 @@ border-radius: 10px} - 1 + 0 From 4413536926f07704fffa6c31157dc3ffe13a0640 Mon Sep 17 00:00:00 2001 From: thunder2 Date: Sun, 9 Dec 2012 02:32:47 +0000 Subject: [PATCH 205/222] Forums: - Switched from own token member to the new methods on TokenQueue. - Reactivated thread from the old forum to fill the messages. - Load all messages at once. - Added processing of missing messages. - Fixed new/read/unread status. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5952 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/retroshare/rsgxsforums.h | 1 + libretroshare/src/services/p3gxsforums.cc | 8 +- retroshare-gui/src/RetroShare.pro | 6 +- retroshare-gui/src/gui/GxsForumsDialog.cpp | 116 +-- retroshare-gui/src/gui/GxsForumsDialog.h | 12 +- .../gui/gxsforums/GxsForumThreadWidget.cpp | 926 ++++++++---------- .../src/gui/gxsforums/GxsForumThreadWidget.h | 63 +- .../src/gui/gxsforums/GxsForumThreadWidget.ui | 4 +- .../src/gui/gxsforums/GxsForumsFillThread.cpp | 260 +++++ .../src/gui/gxsforums/GxsForumsFillThread.h | 46 + 10 files changed, 781 insertions(+), 661 deletions(-) create mode 100644 retroshare-gui/src/gui/gxsforums/GxsForumsFillThread.cpp create mode 100644 retroshare-gui/src/gui/gxsforums/GxsForumsFillThread.h diff --git a/libretroshare/src/retroshare/rsgxsforums.h b/libretroshare/src/retroshare/rsgxsforums.h index bab7f9556..cf51dce06 100644 --- a/libretroshare/src/retroshare/rsgxsforums.h +++ b/libretroshare/src/retroshare/rsgxsforums.h @@ -34,6 +34,7 @@ #include "gxs/rsgxsifaceimpl.h" +#define IS_MSG_NEW(status) (status & GXS_SERV::GXS_MSG_STATUS_UNPROCESSED) #define IS_MSG_UNREAD(status) (status & GXS_SERV::GXS_MSG_STATUS_UNREAD) #define IS_GROUP_ADMIN(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) #define IS_GROUP_SUBSCRIBED(subscribeFlags) (subscribeFlags & (GXS_SERV::GROUP_SUBSCRIBE_ADMIN | GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)) diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index 67a34bba6..bbfcdc628 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -228,7 +228,7 @@ bool p3GxsForums::createMsg(uint32_t &token, RsGxsForumMsg &msg) void p3GxsForums::setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) { - uint32_t mask = GXS_SERV::GXS_MSG_STATUS_UNREAD; + uint32_t mask = GXS_SERV::GXS_MSG_STATUS_UNREAD | GXS_SERV::GXS_MSG_STATUS_UNPROCESSED; uint32_t status = GXS_SERV::GXS_MSG_STATUS_UNREAD; if (read) { @@ -285,9 +285,9 @@ void p3GxsForums::dummy_tick() if (mGenActive) { - std::cerr << "p3Wiki::dummyTick() AboutActive"; + std::cerr << "p3GxsForums::dummyTick() AboutActive"; std::cerr << std::endl; - + uint32_t status = RsGenExchange::getTokenService()->requestStatus(mGenToken); if (status != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) { @@ -406,6 +406,8 @@ bool p3GxsForums::generateMessage(uint32_t &token, const RsGxsGroupId &grpId, co msg.mMeta.mThreadId = threadId; msg.mMeta.mParentId = parentId; + msg.mMeta.mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_UNREAD; + /* chose a random Id to sign with */ std::list ownIds; std::list::iterator it; diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index daaee05e4..895ac8366 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -968,7 +968,8 @@ gxsforums { HEADERS += gui/GxsForumsDialog.h \ gui/gxsforums/CreateGxsForumMsg.h \ - gui/gxsforums/GxsForumThreadWidget.h + gui/gxsforums/GxsForumThreadWidget.h \ + gui/gxsforums/GxsForumsFillThread.h FORMS += gui/GxsForumsDialog.ui \ gui/gxsforums/CreateGxsForumMsg.ui \ @@ -976,7 +977,8 @@ gxsforums { SOURCES += gui/GxsForumsDialog.cpp \ gui/gxsforums/CreateGxsForumMsg.cpp \ - gui/gxsforums/GxsForumThreadWidget.cpp + gui/gxsforums/GxsForumThreadWidget.cpp \ + gui/gxsforums/GxsForumsFillThread.cpp } diff --git a/retroshare-gui/src/gui/GxsForumsDialog.cpp b/retroshare-gui/src/gui/GxsForumsDialog.cpp index a5eb7b007..02928e0c4 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/GxsForumsDialog.cpp @@ -69,8 +69,6 @@ GxsForumsDialog::GxsForumsDialog(QWidget *parent) /* Setup Queue */ mForumQueue = new TokenQueue(rsGxsForums->getTokenService(), this); - mTokenGroupSummary = 0; - mRequestGroupSummary = false; connect(ui.forumTreeWidget, SIGNAL(treeCustomContextMenuRequested(QPoint)), this, SLOT(forumListCustomPopupMenu(QPoint))); connect(ui.newForumButton, SIGNAL(clicked()), this, SLOT(newforum())); @@ -172,10 +170,10 @@ void GxsForumsDialog::forumListCustomPopupMenu(QPoint /*point*/) contextMnu.addSeparator(); - action = contextMnu.addAction(QIcon(":/images/message-mail-read.png"), tr("Mark all as read"), this, SLOT(markMsgAsReadAll())); + action = contextMnu.addAction(QIcon(":/images/message-mail-read.png"), tr("Mark all as read"), this, SLOT(markMsgAsRead())); action->setEnabled (!mForumId.empty () && IS_GROUP_SUBSCRIBED(subscribeFlags)); - action = contextMnu.addAction(QIcon(":/images/message-mail.png"), tr("Mark all as unread"), this, SLOT(markMsgAsUnreadAll())); + action = contextMnu.addAction(QIcon(":/images/message-mail.png"), tr("Mark all as unread"), this, SLOT(markMsgAsUnread())); action->setEnabled (!mForumId.empty () && IS_GROUP_SUBSCRIBED(subscribeFlags)); #ifdef DEBUG_FORUMS @@ -319,6 +317,20 @@ void GxsForumsDialog::insertForumsData(const std::list &forumLi updateMessageSummaryList(""); } +GxsForumThreadWidget *GxsForumsDialog::forumThreadWidget(const std::string &id) +{ + int tabCount = ui.threadTabWidget->count(); + for (int index = 0; index < tabCount; ++index) { + GxsForumThreadWidget *childWidget = dynamic_cast(ui.threadTabWidget->widget(index)); + if (childWidget && childWidget->forumId() == id) { + return childWidget; + break; + } + } + + return NULL; +} + void GxsForumsDialog::changedForum(const QString &id) { mForumId = id.toStdString(); @@ -329,20 +341,12 @@ void GxsForumsDialog::changedForum(const QString &id) // requestGroupSummary_CurrentForum(mForumId); /* search exisiting tab */ - GxsForumThreadWidget *threadWidget = NULL; - int tabCount = ui.threadTabWidget->count(); - for (int index = 0; index < tabCount; ++index) { - GxsForumThreadWidget *childWidget = dynamic_cast(ui.threadTabWidget->widget(index)); - if (childWidget && childWidget->forumId() == id.toStdString()) { - threadWidget = childWidget; - break; - } - } + GxsForumThreadWidget *threadWidget = forumThreadWidget(id.toStdString()); if (!threadWidget) { /* create a thread widget */ threadWidget = new GxsForumThreadWidget(id.toStdString()); - int index = ui.threadTabWidget->addTab(threadWidget, threadWidget->forumName()); + int index = ui.threadTabWidget->addTab(threadWidget, threadWidget->forumName(true)); ui.threadTabWidget->setTabIcon(index, threadWidget->forumIcon()); connect(threadWidget, SIGNAL(forumChanged(QWidget*)), this, SLOT(threadTabChanged(QWidget*))); } @@ -370,33 +374,10 @@ void GxsForumsDialog::threadTabChanged(QWidget *widget) return; } - ui.threadTabWidget->setTabText(index, threadWidget->forumName()); + ui.threadTabWidget->setTabText(index, threadWidget->forumName(true)); ui.threadTabWidget->setTabIcon(index, threadWidget->forumIcon()); } -QString GxsForumsDialog::titleFromInfo(const RsMsgMetaData &meta) -{ - // NOTE - NOTE SURE HOW THIS WILL WORK! -#ifdef TOGXS - if (meta.mMsgStatus & RS_DISTRIB_MISSING_MSG) { - return QApplication::translate("GxsForumsDialog", "[ ... Missing Message ... ]"); - } -#endif - - return QString::fromUtf8(meta.mMsgName.c_str()); -} - -QString GxsForumsDialog::messageFromInfo(const RsGxsForumMsg &msg) -{ -#ifdef TOGXS - if (msg.mMeta.mMsgStatus & RS_DISTRIB_MISSING_MSG) { - return QApplication::translate("GxsForumsDialog", "Placeholder for missing Message"); - } -#endif - - return QString::fromUtf8(msg.mMsg.c_str()); -} - void GxsForumsDialog::copyForumLink() { if (mForumId.empty()) { @@ -422,6 +403,22 @@ void GxsForumsDialog::copyForumLink() QMessageBox::warning(this, "RetroShare", "ToDo"); } +void GxsForumsDialog::markMsgAsRead() +{ + GxsForumThreadWidget *threadWidget = forumThreadWidget(mForumId); + if (threadWidget) { + threadWidget->setAllMsgReadStatus(true); + } +} + +void GxsForumsDialog::markMsgAsUnread() +{ + GxsForumThreadWidget *threadWidget = forumThreadWidget(mForumId); + if (threadWidget) { + threadWidget->setAllMsgReadStatus(false); + } +} + void GxsForumsDialog::newforum() { GxsForumGroupDialog cf(mForumQueue, this); @@ -597,8 +594,8 @@ void GxsForumsDialog::generateMassData() /** Request / Response of Data ********************************/ /*********************** **** **** **** ***********************/ -#define FORUMSV2DIALOG_LISTING 1 -//#define FORUMSV2DIALOG_CURRENTFORUM 2 +#define TOKEN_TYPE_LISTING 1 +//#define TOKEN_TYPE_CURRENTFORUM 2 void GxsForumsDialog::insertForums() { @@ -610,20 +607,23 @@ void GxsForumsDialog::requestGroupSummary() std::cerr << "GxsForumsDialog::requestGroupSummary()"; std::cerr << std::endl; - if (mRequestGroupSummary) { - std::cerr << "GxsForumsDialog::requestGroupSummary() Canceling Request: " << mTokenGroupSummary; - std::cerr << std::endl; + std::list tokens; + mForumQueue->activeRequestTokens(TOKEN_TYPE_LISTING, tokens); + if (!tokens.empty()) { + std::list::iterator tokenIt; + for (tokenIt = tokens.begin(); tokenIt != tokens.end(); ++tokenIt) { + std::cerr << "GxsForumsDialog::requestGroupSummary() Canceling Request: " << *tokenIt; + std::cerr << std::endl; - mForumQueue->cancelRequest(mTokenGroupSummary); - mTokenGroupSummary = 0; - mRequestGroupSummary = false; + mForumQueue->cancelRequest(*tokenIt); + } } RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; - mForumQueue->requestGroupInfo(mTokenGroupSummary, RS_TOKREQ_ANSTYPE_SUMMARY, opts, FORUMSV2DIALOG_LISTING); - mRequestGroupSummary = true; + uint32_t token; + mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, TOKEN_TYPE_LISTING); } void GxsForumsDialog::loadGroupSummary(const uint32_t &token) @@ -631,18 +631,6 @@ void GxsForumsDialog::loadGroupSummary(const uint32_t &token) std::cerr << "GxsForumsDialog::loadGroupSummary()"; std::cerr << std::endl; - if (!mRequestGroupSummary) { - std::cerr << "GxsForumsDialog::loadGroupSummary()) No waiting request got token: " << token; - std::cerr << std::endl; - return; - } - - if (token != mTokenGroupSummary) { - std::cerr << "GxsForumsDialog::loadGroupSummary()) Wrong token - want: " << mTokenGroupSummary << " got: " << token; - std::cerr << std::endl; - return; - } - std::list groupInfo; rsGxsForums->getGroupSummary(token, groupInfo); @@ -655,8 +643,6 @@ void GxsForumsDialog::loadGroupSummary(const uint32_t &token) std::cerr << "GxsForumsDialog::loadGroupSummary() ERROR No Groups..."; std::cerr << std::endl; } - mTokenGroupSummary = 0; - mRequestGroupSummary = false; } /*********************** **** **** **** ***********************/ @@ -674,7 +660,7 @@ void GxsForumsDialog::loadGroupSummary(const uint32_t &token) // std::cerr << std::endl; // uint32_t token; -// mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, FORUMSV2DIALOG_CURRENTFORUM); +// mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, TOKEN_TYPE_CURRENTFORUM); //} //void GxsForumsDialog::loadGroupSummary_CurrentForum(const uint32_t &token) @@ -713,11 +699,11 @@ void GxsForumsDialog::loadRequest(const TokenQueue *queue, const TokenRequest &r /* now switch on req */ switch(req.mUserType) { - case FORUMSV2DIALOG_LISTING: + case TOKEN_TYPE_LISTING: loadGroupSummary(req.mToken); break; -// case FORUMSV2DIALOG_CURRENTFORUM: +// case TOKEN_TYPE_CURRENTFORUM: // loadGroupSummary_CurrentForum(req.mToken); // break; diff --git a/retroshare-gui/src/gui/GxsForumsDialog.h b/retroshare-gui/src/gui/GxsForumsDialog.h index d6bccbc41..aead3f0f5 100644 --- a/retroshare-gui/src/gui/GxsForumsDialog.h +++ b/retroshare-gui/src/gui/GxsForumsDialog.h @@ -36,6 +36,7 @@ class ForumInfo; class RsGxsForumMsg; +class GxsForumThreadWidget; class GxsForumsDialog : public RsAutoUpdatePage, public TokenResponse { @@ -55,10 +56,6 @@ public: // Callback for all Loads. virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); - // Utility Fns. - static QString titleFromInfo(const RsMsgMetaData &meta); - static QString messageFromInfo(const RsGxsForumMsg &msg); - private slots: void forceUpdateDisplay(); // TEMP HACK FN. @@ -80,6 +77,9 @@ private slots: void showForumDetails(); void editForumDetails(); + void markMsgAsRead(); + void markMsgAsUnread(); + void generateMassData(); void shareKey(); @@ -101,13 +101,13 @@ private: void requestGroupSummary(); void loadGroupSummary(const uint32_t &token); + GxsForumThreadWidget *forumThreadWidget(const std::string &id); + // void requestGroupSummary_CurrentForum(const std::string &forumId); // void loadGroupSummary_CurrentForum(const uint32_t &token); std::string mForumId; TokenQueue *mForumQueue; - uint32_t mTokenGroupSummary; - bool mRequestGroupSummary; QTreeWidgetItem *yourForums; QTreeWidgetItem *subscribedForums; diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index 674e306e5..95104d008 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -25,6 +25,7 @@ #include "GxsForumThreadWidget.h" #include "ui_GxsForumThreadWidget.h" +#include "GxsForumsFillThread.h" #include "gui/GxsForumsDialog.h" #include "gui/RetroShareLink.h" #include "gui/common/RSTreeWidgetItem.h" @@ -43,6 +44,8 @@ #include +#define DEBUG_FORUMS + /* Images for context menu icons */ #define IMAGE_MESSAGE ":/images/folder-draft.png" #define IMAGE_MESSAGEREPLY ":/images/mail_reply.png" @@ -76,6 +79,10 @@ #define ROLE_THREAD_COUNT 3 +#define TOKEN_TYPE_CURRENTFORUM 1 +#define TOKEN_TYPE_INSERT_POST 2 +#define TOKEN_TYPE_REPLY_MESSAGE 3 + GxsForumThreadWidget::GxsForumThreadWidget(const std::string &forumId, QWidget *parent) : QWidget(parent), ui(new Ui::GxsForumThreadWidget) @@ -85,11 +92,10 @@ GxsForumThreadWidget::GxsForumThreadWidget(const std::string &forumId, QWidget * mForumId = forumId; mSubscribeFlags = 0; mInProcessSettings = false; + mUnreadCount = 0; + mNewCount = 0; mThreadQueue = new TokenQueue(rsGxsForums->getTokenService(), this); - mTokenGroupSummary = 0; - mTokenPost = 0; - mRequestGroupSummary = false; mInMsgAsReadUnread = false; @@ -162,8 +168,8 @@ GxsForumThreadWidget::GxsForumThreadWidget(const std::string &forumId, QWidget * ttheader->hideSection (COLUMN_THREAD_CONTENT); ui->progressBar->hide(); - ui->progLayOutTxt->hide(); - ui->progressBarLayOut->setEnabled(false); + ui->progressText->hide(); + ui->progressBarLayout->setEnabled(false); // mTimer = new QTimer; // mTimer->setInterval(1000); @@ -173,7 +179,7 @@ GxsForumThreadWidget::GxsForumThreadWidget(const std::string &forumId, QWidget * // mTimer->start(); - mThreadLoading = false; + mFillThread = NULL; ui->forumName->setText(tr("Loading")); insertThreads(); @@ -183,6 +189,12 @@ GxsForumThreadWidget::GxsForumThreadWidget(const std::string &forumId, QWidget * GxsForumThreadWidget::~GxsForumThreadWidget() { + if (mFillThread) { + mFillThread->stop(); + delete(mFillThread); + mFillThread = NULL; + } + delete ui; // delete(mTimer); @@ -231,27 +243,42 @@ void GxsForumThreadWidget::processSettings(bool load) mInProcessSettings = false; } -QString GxsForumThreadWidget::forumName() +QString GxsForumThreadWidget::forumName(bool withUnreadCount) { - return ui->forumName->text(); + QString name = ui->forumName->text(); + + if (withUnreadCount && mUnreadCount) { + name += QString(" (%1)").arg(mUnreadCount); + } + + return name; } QIcon GxsForumThreadWidget::forumIcon() { - if (mRequestGroupSummary || mThreadLoading) { + if (mThreadQueue->activeRequestExist(TOKEN_TYPE_CURRENTFORUM) || mFillThread) { return QIcon(":/images/kalarm.png"); } -//#TODO -// if (has new messages) { -// return QIcon(nice icon); -// } + if (mNewCount) { + return QIcon(":/images/message-state-new.png"); + } return QIcon(); } void GxsForumThreadWidget::updateInterface() { + if (mFillThread) { + ui->newthreadButton->setEnabled(false); + } else { + if (mThreadQueue->activeRequestExist(TOKEN_TYPE_CURRENTFORUM)) { + ui->newthreadButton->setEnabled(false); + } else { + ui->newthreadButton->setEnabled (IS_GROUP_SUBSCRIBED(mSubscribeFlags)); + } + } + emit forumChanged(this); } @@ -303,7 +330,7 @@ void GxsForumThreadWidget::updateDisplay() void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/) { - if (mThreadLoading) { + if (mFillThread) { return; } @@ -446,7 +473,7 @@ void GxsForumThreadWidget::changedThread() mThreadId = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString(); } - if (mThreadLoading) { + if (mFillThread) { return; } @@ -455,7 +482,7 @@ void GxsForumThreadWidget::changedThread() void GxsForumThreadWidget::clickedThread(QTreeWidgetItem *item, int column) { - if (mThreadLoading) { + if (mFillThread) { return; } @@ -510,6 +537,7 @@ void GxsForumThreadWidget::calculateIconsAndFonts(QTreeWidgetItem *item, bool &h { uint32_t status = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + bool isNew = IS_MSG_NEW(status); bool unread = IS_MSG_UNREAD(status); bool missing = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING).toBool(); @@ -523,7 +551,7 @@ void GxsForumThreadWidget::calculateIconsAndFonts(QTreeWidgetItem *item, bool &h } else { item->setIcon(COLUMN_THREAD_READ, QIcon(":/images/message-state-read.png")); } - if (IS_MSG_UNREAD(status)) { + if (isNew) { item->setIcon(COLUMN_THREAD_TITLE, QIcon(":/images/message-state-new.png")); } else { item->setIcon(COLUMN_THREAD_TITLE, QIcon()); @@ -547,7 +575,7 @@ void GxsForumThreadWidget::calculateIconsAndFonts(QTreeWidgetItem *item, bool &h if (!IS_GROUP_SUBSCRIBED(mSubscribeFlags)) { qf.setBold(false); item->setTextColor(i, textColorNotSubscribed()); - } else if (unread) { + } else if (unread || isNew) { qf.setBold(true); item->setTextColor(i, textColorUnread()); } else if (myUnreadChilddren) { @@ -571,6 +599,40 @@ void GxsForumThreadWidget::calculateIconsAndFonts(QTreeWidgetItem *item, bool &h hasUnreadChilddren = hasUnreadChilddren || myUnreadChilddren || unread; } +void GxsForumThreadWidget::calculateUnreadCount() +{ + unsigned int unreadCount = 0; + unsigned int newCount = 0; + + QTreeWidgetItemIterator itemIterator(ui->threadTreeWidget); + QTreeWidgetItem *item = NULL; + while ((item = *itemIterator) != NULL) { + itemIterator++; + + uint32_t status = item->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); + if (IS_MSG_UNREAD(status)) { + ++unreadCount; + } + if (IS_MSG_NEW(status)) { + ++newCount; + } + } + + bool changed = false; + if (mUnreadCount != unreadCount) { + mUnreadCount = unreadCount; + changed = true; + } + if (mNewCount != newCount) { + mNewCount = newCount; + changed = true; + } + + if (changed) { + updateInterface(); + } +} + void GxsForumThreadWidget::calculateIconsAndFonts(QTreeWidgetItem *item /*= NULL*/) { bool dummy1 = false; @@ -591,15 +653,124 @@ void GxsForumThreadWidget::calculateIconsAndFonts(QTreeWidgetItem *item /*= NULL } } -#ifdef TODO -void GxsForumsDialog::fillThreadProgress(int current, int count) +static void cleanupItems (QList &items) +{ + QList::iterator item; + for (item = items.begin (); item != items.end (); item++) { + if (*item) { + delete (*item); + } + } + items.clear(); +} + +void GxsForumThreadWidget::fillThreadFinished() +{ +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumThreadWidget::fillThreadFinished" << std::endl; +#endif + + // thread has finished + GxsForumsFillThread *thread = dynamic_cast(sender()); + if (thread) { + if (thread == mFillThread) { + // current thread has finished, hide progressbar and release thread + ui->progressBar->hide(); + ui->progressText->hide(); + ui->progressBarLayout->setEnabled(false); + mFillThread = NULL; + updateInterface(); + + ui->threadTreeWidget->setPlaceholderText(""); + } + + if (thread->wasStopped()) { + // thread was stopped +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumThreadWidget::fillThreadFinished Thread was stopped" << std::endl; +#endif + } else { +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumThreadWidget::fillThreadFinished Add messages" << std::endl; +#endif + + ui->threadTreeWidget->setSortingEnabled(false); + + /* add all messages in! */ + if (mLastViewType != thread->mViewType || mLastForumID != mForumId) { + ui->threadTreeWidget->clear(); + mLastViewType = thread->mViewType; + mLastForumID = mForumId; + ui->threadTreeWidget->insertTopLevelItems(0, thread->mItems); + + // clear list + thread->mItems.clear(); + } else { + fillThreads (thread->mItems, thread->mExpandNewMessages, thread->mItemToExpand); + + // cleanup list + cleanupItems (thread->mItems); + } + + ui->threadTreeWidget->setSortingEnabled(true); + + if (thread->mFocusMsgId.empty() == false) { + /* Search exisiting item */ + QTreeWidgetItemIterator itemIterator(ui->threadTreeWidget); + QTreeWidgetItem *item = NULL; + while ((item = *itemIterator) != NULL) { + itemIterator++; + + if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString() == thread->mFocusMsgId) { + ui->threadTreeWidget->setCurrentItem(item); + ui->threadTreeWidget->setFocus(); + break; + } + } + } + + QList::iterator itemIt; + for (itemIt = thread->mItemToExpand.begin(); itemIt != thread->mItemToExpand.end(); ++itemIt) { + if ((*itemIt)->isHidden() == false) { + (*itemIt)->setExpanded(true); + } + } + thread->mItemToExpand.clear(); + + if (ui->filterLineEdit->text().isEmpty() == false) { + filterItems(ui->filterLineEdit->text()); + } + insertPost (); + calculateIconsAndFonts(); + calculateUnreadCount(); + updateInterface(); + } + +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumThreadWidget::fillThreadFinished Delete thread" << std::endl; +#endif + + thread->deleteLater(); + thread = NULL; + } + +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumThreadWidget::fillThreadFinished done" << std::endl; +#endif +} + +void GxsForumThreadWidget::fillThreadProgress(int current, int count) { // show fill progress if (count) { - ui.progressBar->setValue(current * ui.progressBar->maximum() / count); + ui->progressBar->setValue(current * ui->progressBar->maximum() / count); } } -#endif + +void GxsForumThreadWidget::fillThreadStatus(QString text) +{ + ui->progressText->setText(text); +} // HACK until update works. void GxsForumThreadWidget::forceUpdateDisplay() @@ -611,6 +782,96 @@ void GxsForumThreadWidget::forceUpdateDisplay() insertThreads(); } +QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForumMsg &msg, bool useChildTS, uint32_t filterColumn) +{ + GxsIdTreeWidgetItem *item = new GxsIdTreeWidgetItem(mThreadCompareRole); + QString text; + + item->setText(COLUMN_THREAD_TITLE, QString::fromUtf8(msg.mMeta.mMsgName.c_str())); + + QDateTime qtime; + QString sort; + + if (useChildTS) + qtime.setTime_t(msg.mMeta.mChildTs); + else + qtime.setTime_t(msg.mMeta.mPublishTs); + +//#AFTER MERGE text = DateTime::formatDateTime(qtime); + sort = qtime.toString("yyyyMMdd_hhmmss"); + + if (useChildTS) + { + qtime.setTime_t(msg.mMeta.mPublishTs); + text += " / "; +//#AFTER MERGE text += DateTime::formatDateTime(qtime); + sort += "_" + qtime.toString("yyyyMMdd_hhmmss"); + } + item->setText(COLUMN_THREAD_DATE, text); + item->setData(COLUMN_THREAD_DATE, ROLE_THREAD_SORT, sort); + + item->setId(msg.mMeta.mAuthorId, COLUMN_THREAD_AUTHOR); +//#TODO +#if 0 + text = QString::fromUtf8(authorName.c_str()); + + if (text.isEmpty()) + { + item->setText(COLUMN_THREAD_AUTHOR, tr("Anonymous")); + } + else + { + item->setText(COLUMN_THREAD_AUTHOR, text); + } +#endif +//#TODO +#ifdef TOGXS + if (msgInfo.mMeta.mMsgFlags & RS_DISTRIB_AUTHEN_REQ) + { + item->setText(COLUMN_THREAD_SIGNED, tr("signed")); + item->setIcon(COLUMN_THREAD_SIGNED, QIcon(":/images/mail-signed.png")); + } + else + { + item->setText(COLUMN_THREAD_SIGNED, tr("none")); + item->setIcon(COLUMN_THREAD_SIGNED, QIcon(":/images/mail-signature-unknown.png")); + } +#endif + + if (filterColumn == COLUMN_THREAD_CONTENT) { + // need content for filter + QTextDocument doc; + doc.setHtml(QString::fromUtf8(msg.mMsg.c_str())); + item->setText(COLUMN_THREAD_CONTENT, doc.toPlainText().replace(QString("\n"), QString(" "))); + } + + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID, QString::fromStdString(msg.mMeta.mMsgId)); +//#TODO +#if 0 + if (IS_GROUP_SUBSCRIBED(subscribeFlags) && !(msginfo.mMsgFlags & RS_DISTRIB_MISSING_MSG)) { + rsGxsForums->getMessageStatus(msginfo.forumId, msginfo.msgId, status); + } else { + // show message as read + status = RSGXS_MSG_STATUS_READ; + } +#endif + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, msg.mMeta.mMsgStatus); + + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING, false); + + return item; +} + +QTreeWidgetItem *GxsForumThreadWidget::generateMissingItem(const std::string &msgId) +{ + GxsIdTreeWidgetItem *item = new GxsIdTreeWidgetItem(mThreadCompareRole); + item->setText(COLUMN_THREAD_TITLE, tr("[ ... Missing Message ... ]")); + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID, QString::fromStdString(msgId)); + item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING, true); + + return item; +} + void GxsForumThreadWidget::insertThreads() { #ifdef DEBUG_FORUMS @@ -618,6 +879,20 @@ void GxsForumThreadWidget::insertThreads() std::cerr << "GxsForumsDialog::insertThreads()" << std::endl; #endif + if (mFillThread) { +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumThreadWidget::insertThreads() stop current fill thread" << std::endl; +#endif + // stop current fill thread + GxsForumsFillThread *thread = mFillThread; + mFillThread = NULL; + thread->stop(); + delete(thread); + + ui->progressBar->hide(); + ui->progressText->hide(); + } + mSubscribeFlags = 0; ui->newmessageButton->setEnabled(false); @@ -643,6 +918,7 @@ void GxsForumThreadWidget::insertThreads() return; } +//#TODO // ui->threadTitle->setText(tr("Loading")); // Get Current Forum Info... then complete insertForumThreads(). @@ -652,17 +928,13 @@ void GxsForumThreadWidget::insertThreads() void GxsForumThreadWidget::insertForumThreads(const RsGroupMetaData &fi) { mSubscribeFlags = fi.mSubscribeFlags; - QString forumName = QString::fromUtf8(fi.mGroupName.c_str()); - if (forumName != ui->forumName->text()) { - ui->forumName->setText(forumName); - updateInterface(); - } + ui->forumName->setText(QString::fromUtf8(fi.mGroupName.c_str())); -// ui->progressBarLayOut->setEnabled(true); + ui->progressBarLayout->setEnabled(true); -// ui->progLayOutTxt->show(); -// ui->progressBar->reset(); -// ui->progressBar->show(); + ui->progressText->show(); + ui->progressBar->reset(); + ui->progressBar->show(); ui->threadTreeWidget->setPlaceholderText(tr("Loading")); @@ -670,106 +942,49 @@ void GxsForumThreadWidget::insertForumThreads(const RsGroupMetaData &fi) std::cerr << "GxsForumsDialog::insertThreads() Start filling Forum threads" << std::endl; #endif - // Get Forum Threads... then complete fillThreadFinished(). - loadCurrentForumThreads(fi.mGroupId); -} + // create fill thread + mFillThread = new GxsForumsFillThread(this); -static void cleanupItems (QList &items) -{ - QList::iterator item; - for (item = items.begin (); item != items.end (); item++) { - if (*item) { - delete (*item); - } + // set data + mFillThread->mCompareRole = mThreadCompareRole; + mFillThread->mForumId = mForumId; +//#AFTER MERGE mFillThread->mFilterColumn = ui->filterLineEdit->currentFilter(); + mFillThread->mFilterColumn = COLUMN_THREAD_TITLE; + mFillThread->mSubscribeFlags = mSubscribeFlags; + mFillThread->mExpandNewMessages = Settings->getExpandNewMessages(); + mFillThread->mViewType = ui->viewBox->currentIndex(); + if (mLastViewType != mFillThread->mViewType || mLastForumID != mForumId) { + mFillThread->mFillComplete = true; } - items.clear(); -} -void GxsForumThreadWidget::fillThreadFinished() -{ -#ifdef DEBUG_FORUMS - std::cerr << "GxsForumsDialog::fillThreadFinished" << std::endl; -#endif + mFillThread->mFlatView = false; + mFillThread->mUseChildTS = false; - // This is now only called with a successful Load. - // cleanup of incomplete is handled elsewhere. + switch (mFillThread->mViewType) { + case VIEW_LAST_POST: + mFillThread->mUseChildTS = true; + break; + case VIEW_FLAT: + mFillThread->mFlatView = true; + break; + case VIEW_THREADED: + break; + } - // current thread has finished, hide progressbar and release thread -// ui->progressBar->hide(); -// ui->progLayOutTxt->hide(); -// ui->progressBarLayOut->setEnabled(false); + ui->threadTreeWidget->setRootIsDecorated(!mFillThread->mFlatView); - ui->threadTreeWidget->setPlaceholderText(""); + // connect thread + connect(mFillThread, SIGNAL(finished()), this, SLOT(fillThreadFinished()), Qt::BlockingQueuedConnection); + connect(mFillThread, SIGNAL(status(QString)), this, SLOT(fillThreadStatus(QString))); + connect(mFillThread, SIGNAL(progress(int,int)), this, SLOT(fillThreadProgress(int,int))); #ifdef DEBUG_FORUMS - std::cerr << "GxsForumsDialog::fillThreadFinished Add messages" << std::endl; + std::cerr << "ForumsDialog::insertThreads() Start fill thread" << std::endl; #endif - ui->threadTreeWidget->setSortingEnabled(false); - /* add all messages in! */ - if (mLastViewType != mThreadLoad.ViewType || mLastForumID != mForumId) - { - ui->threadTreeWidget->clear(); - mLastViewType = mThreadLoad.ViewType; - mLastForumID = mForumId; - ui->threadTreeWidget->insertTopLevelItems(0, mThreadLoad.Items); - - // clear list - mThreadLoad.Items.clear(); - } - else - { - fillThreads(mThreadLoad.Items, mThreadLoad.ExpandNewMessages, mThreadLoad.ItemToExpand); - - // cleanup list - cleanupItems(mThreadLoad.Items); - } - - ui->threadTreeWidget->setSortingEnabled(true); - - if (mThreadLoad.FocusMsgId.empty() == false) - { - /* Search exisiting item */ - QTreeWidgetItemIterator itemIterator(ui->threadTreeWidget); - QTreeWidgetItem *item = NULL; - while ((item = *itemIterator) != NULL) - { - itemIterator++; - - if (item->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString() == mThreadLoad.FocusMsgId) - { - ui->threadTreeWidget->setCurrentItem(item); - ui->threadTreeWidget->setFocus(); - break; - } - } - } - - QList::iterator Item; - for (Item = mThreadLoad.ItemToExpand.begin(); Item != mThreadLoad.ItemToExpand.end(); Item++) - { - if ((*Item)->isHidden() == false) - { - (*Item)->setExpanded(true); - } - } - mThreadLoad.ItemToExpand.clear(); - - if (ui->filterLineEdit->text().isEmpty() == false) { - filterItems(ui->filterLineEdit->text()); - } - - insertPost(); - calculateIconsAndFonts(); - - ui->newthreadButton->setEnabled(IS_GROUP_SUBSCRIBED(mSubscribeFlags)); - - mThreadLoading = false; + // start thread + mFillThread->start(); updateInterface(); - -#ifdef DEBUG_FORUMS - std::cerr << "GxsForumsDialog::fillThreadFinished done" << std::endl; -#endif } void GxsForumThreadWidget::fillThreads(QList &threadList, bool expandNewMessages, QList &itemToExpand) @@ -999,9 +1214,19 @@ void GxsForumThreadWidget::insertPostData(const RsGxsForumMsg &msg) QList row; row.append(item); - if (setToReadOnActive && IS_MSG_UNREAD(status)) - { - setMsgReadStatus(row, true); + if (IS_MSG_NEW(status)) { + if (setToReadOnActive) { + /* set to read */ + setMsgReadStatus(row, true); + } else { + /* set to unread by user */ + setMsgReadStatus(row, false); + } + } else { + if (setToReadOnActive && IS_MSG_UNREAD(status)) { + /* set to read */ + setMsgReadStatus(row, true); + } } //#AFTER MERGE ui.time_label->setText(DateTime::formatLongDateTime(msg.mMeta.mPublishTs)); @@ -1019,10 +1244,10 @@ void GxsForumThreadWidget::insertPostData(const RsGxsForumMsg &msg) ui->by_label->setText( tr("By") + " " + text ); } - QString extraTxt = RsHtml().formatText(ui->postText->document(), GxsForumsDialog::messageFromInfo(msg), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS); + QString extraTxt = RsHtml().formatText(ui->postText->document(), QString::fromUtf8(msg.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS); ui->postText->setHtml(extraTxt); - ui->threadTitle->setText(GxsForumsDialog::titleFromInfo(msg.mMeta)); + ui->threadTitle->setText(QString::fromUtf8(msg.mMeta.mMsgName.c_str())); } void GxsForumThreadWidget::previousMessage() @@ -1161,12 +1386,12 @@ void GxsForumThreadWidget::setMsgReadStatus(QList &rows, bool uint32_t status = (*row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - uint32_t statusNew = (status & ~GXS_SERV::GXS_MSG_STATUS_UNREAD); // orig status, without UNREAD. + uint32_t statusNew = (status & ~(GXS_SERV::GXS_MSG_STATUS_UNREAD | GXS_SERV::GXS_MSG_STATUS_UNPROCESSED)); // orig status, without UNREAD and UNPROCESSED. if (!read) { statusNew |= GXS_SERV::GXS_MSG_STATUS_UNREAD; } - if (IS_MSG_UNREAD(status) == read) // is it different? + if (status != statusNew) // is it different? { std::string msgId = (*row)->data(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID).toString().toStdString(); @@ -1198,6 +1423,7 @@ void GxsForumThreadWidget::setMsgReadStatus(QList &rows, bool calculateIconsAndFonts(*it); } //#TODO updateMessageSummaryList(mForumId); + calculateUnreadCount(); } } @@ -1227,7 +1453,8 @@ void GxsForumThreadWidget::markMsgAsReadUnread (bool read, bool children, bool f /* add only items with the right state or with not RSGXS_MSG_STATUS_READ */ uint32_t status = row->data(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS).toUInt(); - if (IS_MSG_UNREAD(status) == read) { + bool isUnread = IS_MSG_UNREAD(status); + if (isUnread == read || IS_MSG_NEW(status)) { allRows.append(row); } @@ -1260,11 +1487,6 @@ void GxsForumThreadWidget::markMsgAsReadChildren() markMsgAsReadUnread(true, true, false); } -void GxsForumThreadWidget::markMsgAsReadAll() -{ - markMsgAsReadUnread(true, true, true); -} - void GxsForumThreadWidget::markMsgAsUnread() { markMsgAsReadUnread(false, false, false); @@ -1275,9 +1497,9 @@ void GxsForumThreadWidget::markMsgAsUnreadChildren() markMsgAsReadUnread(false, true, false); } -void GxsForumThreadWidget::markMsgAsUnreadAll() +void GxsForumThreadWidget::setAllMsgReadStatus(bool read) { - markMsgAsReadUnread(false, true, true); + markMsgAsReadUnread(read, true, true); } void GxsForumThreadWidget::copyMessageLink() @@ -1462,25 +1684,21 @@ bool GxsForumThreadWidget::filterItem(QTreeWidgetItem *item, const QString &text /** Request / Response of Data ********************************/ /*********************** **** **** **** ***********************/ -#define FORUMSV2DIALOG_LISTING 1 -#define FORUMSV2DIALOG_CURRENTFORUM 2 -#define FORUMSV2DIALOG_INSERTTHREADS 3 -#define FORUMSV2DIALOG_INSERTCHILD 4 -#define FORUMV2DIALOG_INSERT_POST 5 -#define FORUMV2DIALOG_REPLY_MESSAGE 6 - void GxsForumThreadWidget::requestGroupSummary_CurrentForum(const std::string &forumId) { RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; - if (mRequestGroupSummary) { - std::cerr << "GxsForumThreadWidget::requestGroupSummary() Canceling Request: " << mTokenGroupSummary; - std::cerr << std::endl; + std::list tokens; + mThreadQueue->activeRequestTokens(TOKEN_TYPE_CURRENTFORUM, tokens); + if (!tokens.empty()) { + std::list::iterator tokenIt; + for (tokenIt = tokens.begin(); tokenIt != tokens.end(); ++tokenIt) { + std::cerr << "GxsForumThreadWidget::requestGroupSummary() Canceling Request: " << *tokenIt; + std::cerr << std::endl; - mThreadQueue->cancelRequest(mTokenGroupSummary); - mTokenGroupSummary = 0; - mRequestGroupSummary = false; + mThreadQueue->cancelRequest(*tokenIt); + } } std::list grpIds; @@ -1489,9 +1707,8 @@ void GxsForumThreadWidget::requestGroupSummary_CurrentForum(const std::string &f std::cerr << "GxsForumsDialog::requestGroupSummary_CurrentForum(" << forumId << ")"; std::cerr << std::endl; - mThreadQueue->requestGroupInfo(mTokenGroupSummary, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, FORUMSV2DIALOG_CURRENTFORUM); - mRequestGroupSummary = true; - updateInterface(); + uint32_t token; + mThreadQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, TOKEN_TYPE_CURRENTFORUM); } void GxsForumThreadWidget::loadGroupSummary_CurrentForum(const uint32_t &token) @@ -1499,23 +1716,8 @@ void GxsForumThreadWidget::loadGroupSummary_CurrentForum(const uint32_t &token) std::cerr << "GxsForumsDialog::loadGroupSummary_CurrentForum()"; std::cerr << std::endl; - if (!mRequestGroupSummary) { - std::cerr << "GxsForumThreadWidget::loadGroupSummary_CurrentForum()) No waiting request got token: " << token; - std::cerr << std::endl; - return; - } - - if (token != mTokenGroupSummary) { - std::cerr << "GxsForumThreadWidget::loadGroupSummary()) Wrong token - want: " << mTokenGroupSummary << " got: " << token; - std::cerr << std::endl; - return; - } - std::list groupInfo; rsGxsForums->getGroupSummary(token, groupInfo); - mTokenGroupSummary = 0; - mRequestGroupSummary = false; - updateInterface(); if (groupInfo.size() == 1) { @@ -1526,344 +1728,8 @@ void GxsForumThreadWidget::loadGroupSummary_CurrentForum(const uint32_t &token) { std::cerr << "GxsForumsDialog::loadGroupSummary_CurrentForum() ERROR Invalid Number of Groups..."; std::cerr << std::endl; - } -} -/*********************** **** **** **** ***********************/ -/*********************** **** **** **** ***********************/ - -void GxsForumThreadWidget::loadCurrentForumThreads(const std::string &forumId) -{ - std::cerr << "GxsForumsDialog::loadCurrentForumThreads(" << forumId << ")"; - std::cerr << std::endl; - - /* if already active -> kill current loading */ - if (mThreadLoading) - { - /* Cleanup */ - std::cerr << "GxsForumsDialog::loadCurrentForumThreads() Cleanup old Threads"; - std::cerr << std::endl; - - /* Wipe Widget Tree */ - mThreadLoad.Items.clear(); - - /* Stop all active requests */ - std::map::iterator it; - for (it = mThreadLoad.MsgTokens.begin(); it != mThreadLoad.MsgTokens.end(); ++it) - { - std::cerr << "GxsForumsDialog::loadCurrentForumThreads() Canceling Request: " << it->first; - std::cerr << std::endl; - - mThreadQueue->cancelRequest(it->first); - } - - mThreadLoad.MsgTokens.clear(); - mThreadLoad.ItemToExpand.clear(); - } - - /* initiate loading */ - std::cerr << "GxsForumsDialog::loadCurrentForumThreads() Initiating Loading"; - std::cerr << std::endl; - - mThreadLoading = true; - updateInterface(); - - mThreadLoad.ForumId = mForumId; -//#AFTER MERGE mThreadLoad.FilterColumn = ui.filterLineEdit->currentFilter(); - mThreadLoad.FilterColumn = COLUMN_THREAD_TITLE; -// - mThreadLoad.ViewType = ui->viewBox->currentIndex(); - mThreadLoad.FillComplete = false; - - if (mLastViewType != mThreadLoad.ViewType || mLastForumID != mForumId) { - mThreadLoad.FillComplete = true; - } - - mThreadLoad.FlatView = false; - mThreadLoad.UseChildTS = false; - mThreadLoad.ExpandNewMessages = Settings->getExpandNewMessages(); - mThreadLoad.SubscribeFlags = mSubscribeFlags; - - if (mThreadLoad.ViewType == VIEW_FLAT) { - ui->threadTreeWidget->setRootIsDecorated(false); - } else { - ui->threadTreeWidget->setRootIsDecorated(true); - } - - switch(mThreadLoad.ViewType) - { - case VIEW_LAST_POST: - mThreadLoad.UseChildTS = true; - break; - case VIEW_FLAT: - mThreadLoad.FlatView = true; - break; - case VIEW_THREADED: - break; - } - - requestGroupThreadData_InsertThreads(forumId); -} - -void GxsForumThreadWidget::requestGroupThreadData_InsertThreads(const std::string &forumId) -{ - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - - opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; - - std::list grpIds; - grpIds.push_back(forumId); - - std::cerr << "GxsForumsDialog::requestGroupThreadData_InsertThreads(" << forumId << ")"; - std::cerr << std::endl; - - uint32_t token; - mThreadQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds, FORUMSV2DIALOG_INSERTTHREADS); -} - -void GxsForumThreadWidget::loadGroupThreadData_InsertThreads(const uint32_t &token) -{ - std::cerr << "GxsForumsDialog::loadGroupThreadData_InsertThreads()"; - std::cerr << std::endl; - - bool someData = false; - - std::vector msgs; - std::vector::iterator vit; - if (rsGxsForums->getMsgData(token, msgs)) - { - for (vit = msgs.begin(); vit != msgs.end(); ++vit) - { - std::cerr << "GxsForumsDialog::loadGroupThreadData_InsertThreads() MsgId: " << vit->mMeta.mMsgId; - std::cerr << std::endl; - - loadForumBaseThread(*vit); - someData = true; - } - } - - /* completed with no data */ - if (!someData) - { - fillThreadFinished(); - } -} - -bool GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, bool useChildTS, uint32_t filterColumn, GxsIdTreeWidgetItem *item) -{ - QString text; - - { - QDateTime qtime; - QString sort; - - if (useChildTS) - qtime.setTime_t(msgInfo.mMeta.mChildTs); - else - qtime.setTime_t(msgInfo.mMeta.mPublishTs); - -//#AFTER MERGE text = DateTime::formatDateTime(qtime); - sort = qtime.toString("yyyyMMdd_hhmmss"); - - if (useChildTS) - { - qtime.setTime_t(msgInfo.mMeta.mPublishTs); - text += " / "; -//#AFTER MERGE text += DateTime::formatDateTime(qtime); - sort += "_" + qtime.toString("yyyyMMdd_hhmmss"); - } - item->setText(COLUMN_THREAD_DATE, text); - item->setData(COLUMN_THREAD_DATE, ROLE_THREAD_SORT, sort); - } - - item->setText(COLUMN_THREAD_TITLE, GxsForumsDialog::titleFromInfo(msgInfo.mMeta)); - - item->setId(msgInfo.mMeta.mAuthorId, COLUMN_THREAD_AUTHOR); -#if 0 - text = QString::fromUtf8(authorName.c_str()); - - if (text.isEmpty()) - { - item->setText(COLUMN_THREAD_AUTHOR, tr("Anonymous")); - } - else - { - item->setText(COLUMN_THREAD_AUTHOR, text); - } -#endif - -#ifdef TOGXS - if (msgInfo.mMeta.mMsgFlags & RS_DISTRIB_AUTHEN_REQ) - { - item->setText(COLUMN_THREAD_SIGNED, tr("signed")); - item->setIcon(COLUMN_THREAD_SIGNED, QIcon(":/images/mail-signed.png")); - } - else - { - item->setText(COLUMN_THREAD_SIGNED, tr("none")); - item->setIcon(COLUMN_THREAD_SIGNED, QIcon(":/images/mail-signature-unknown.png")); - } -#endif - - if (filterColumn == COLUMN_THREAD_CONTENT) { - // need content for filter - QTextDocument doc; - doc.setHtml(QString::fromUtf8(msgInfo.mMsg.c_str())); - item->setText(COLUMN_THREAD_CONTENT, doc.toPlainText().replace(QString("\n"), QString(" "))); - } - - item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID, QString::fromStdString(msgInfo.mMeta.mMsgId)); - -#if 0 - if (IS_GROUP_SUBSCRIBED(subscribeFlags) && !(msginfo.mMsgFlags & RS_DISTRIB_MISSING_MSG)) { - rsGxsForums->getMessageStatus(msginfo.forumId, msginfo.msgId, status); - } else { - // show message as read - status = RSGXS_MSG_STATUS_READ; - } -#endif - item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, msgInfo.mMeta.mMsgStatus); - -#ifdef TOGXS - item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING, (msgInfo.mMeta.mMsgFlags & RS_DISTRIB_MISSING_MSG) ? true : false); -#endif - - return true; -} - -void GxsForumThreadWidget::loadForumBaseThread(const RsGxsForumMsg &msg) -{ - //std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); - - //QTreeWidgetItem *item = new QTreeWidgetItem(); // no Parent. - GxsIdTreeWidgetItem *item = new GxsIdTreeWidgetItem(mThreadCompareRole); // no Parent. - - //convertMsgToThreadWidget(msg, authorName, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, item); - convertMsgToThreadWidget(msg, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, item); - - /* request Children Data */ - uint32_t token; - RsGxsGrpMsgIdPair parentId = std::make_pair(msg.mMeta.mGroupId, msg.mMeta.mMsgId); - requestChildData_InsertThreads(token, parentId); - - /* store pair of (token, item) */ - mThreadLoad.MsgTokens[token] = item; - - /* add item to final tree */ - mThreadLoad.Items.append(item); -} - -/*********************** **** **** **** ***********************/ - -void GxsForumThreadWidget::requestChildData_InsertThreads(uint32_t &token, const RsGxsGrpMsgIdPair &parentId) -{ - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; - opts.mOptions = RS_TOKREQOPT_MSG_PARENT | RS_TOKREQOPT_MSG_LATEST; - - std::cerr << "GxsForumsDialog::requestChildData_InsertThreads(" << parentId.first << "," << parentId.second << ")"; - std::cerr << std::endl; - - std::vector msgIds; - msgIds.push_back(parentId); - mThreadQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMSV2DIALOG_INSERTCHILD); -} - -void GxsForumThreadWidget::loadChildData_InsertThreads(const uint32_t &token) -{ - std::cerr << "GxsForumsDialog::loadChildData_InsertThreads()"; - std::cerr << std::endl; - - /* find the matching *item */ - std::map::iterator it; - it = mThreadLoad.MsgTokens.find(token); - if (it == mThreadLoad.MsgTokens.end()) - { - std::cerr << "GxsForumsDialog::loadChildData_InsertThreads() ERROR Missing Token->Parent in Map"; - std::cerr << std::endl; - /* finished with this one */ - return; - } - - QTreeWidgetItem *parent = it->second; - // cleanup map. - mThreadLoad.MsgTokens.erase(it); - - std::cerr << "GxsForumsDialog::loadChildData_InsertThreads()"; - std::cerr << std::endl; - - std::vector msgs; - std::vector::iterator vit; - if (rsGxsForums->getRelatedMessages(token, msgs)) - { - for(vit = msgs.begin(); vit != msgs.end(); vit++) - { - std::cerr << "GxsForumsDialog::loadChildData_InsertThreads() MsgId: " << vit->mMeta.mMsgId; - std::cerr << std::endl; - - loadForumChildMsg(*vit, parent); - } - } - else - { - std::cerr << "GxsForumsDialog::loadChildData_InsertThreads() Error getting MsgData"; - std::cerr << std::endl; - } - - /* check for completion */ - if (mThreadLoad.MsgTokens.size() == 0) - { - /* finished */ - /* push data into GUI */ - fillThreadFinished(); - } -} - -void GxsForumThreadWidget::loadForumChildMsg(const RsGxsForumMsg &msg, QTreeWidgetItem *parent) -{ - //std::string authorName = rsPeers->getPeerName(msg.mMeta.mAuthorId); - - //QTreeWidgetItem *child = NULL; - GxsIdTreeWidgetItem *child = NULL; - - if (mThreadLoad.FlatView) - { - child = new GxsIdTreeWidgetItem(mThreadCompareRole); // no Parent. - } - else - { - child = new GxsIdTreeWidgetItem(mThreadCompareRole, parent); - } - - convertMsgToThreadWidget(msg, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, child); - //convertMsgToThreadWidget(msg, authorName, mThreadLoad.UseChildTS, mThreadLoad.FilterColumn, child); - - /* request Children Data */ - uint32_t token; - RsGxsGrpMsgIdPair parentId = std::make_pair(msg.mMeta.mGroupId, msg.mMeta.mMsgId); - requestChildData_InsertThreads(token, parentId); - - /* store pair of (token, item) */ - mThreadLoad.MsgTokens[token] = child; - - // Leave this here... BUT IT WILL NEED TO BE FIXED. - if (mThreadLoad.FillComplete && mThreadLoad.ExpandNewMessages && IS_MSG_UNREAD(msg.mMeta.mMsgStatus)) - { - QTreeWidgetItem *pParent = child; - while ((pParent = pParent->parent()) != NULL) - { - if (std::find(mThreadLoad.ItemToExpand.begin(), mThreadLoad.ItemToExpand.end(), pParent) == mThreadLoad.ItemToExpand.end()) - { - mThreadLoad.ItemToExpand.push_back(pParent); - } - } - } - - if (mThreadLoad.FlatView) - { - /* add item to final tree */ - mThreadLoad.Items.append(child); + updateInterface(); } } @@ -1882,14 +1748,20 @@ void GxsForumThreadWidget::requestMsgData_InsertPost(const RsGxsGrpMsgIdPair &ms std::vector msgIds; msgIds.push_back(msgId); uint32_t token; - mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_INSERT_POST); + mForumQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, TOKEN_TYPE_INSERT_POST); #else - if (mTokenPost) { - std::cerr << "GxsForumThreadWidget::requestMsgData_InsertPost() Canceling Request: " << mTokenPost; - std::cerr << std::endl; - mThreadQueue->cancelRequest(mTokenPost); - mTokenPost = 0; + std::list tokens; + mThreadQueue->activeRequestTokens(TOKEN_TYPE_INSERT_POST, tokens); + if (!tokens.empty()) { + std::list::iterator tokenIt; + for (tokenIt = tokens.begin(); tokenIt != tokens.end(); ++tokenIt) { +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumThreadWidget::requestMsgData_InsertPost() Canceling Request: " << *tokenIt; + std::cerr << std::endl; +#endif + mThreadQueue->cancelRequest(*tokenIt); + } } RsTokReqOptions opts; @@ -1902,7 +1774,8 @@ void GxsForumThreadWidget::requestMsgData_InsertPost(const RsGxsGrpMsgIdPair &ms std::vector &vect = msgIds[msgId.first]; vect.push_back(msgId.second); - mThreadQueue->requestMsgInfo(mTokenPost, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_INSERT_POST); + uint32_t token; + mThreadQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, TOKEN_TYPE_INSERT_POST); #endif } @@ -1912,26 +1785,17 @@ void GxsForumThreadWidget::loadMsgData_InsertPost(const uint32_t &token) std::cerr << std::endl; std::vector msgs; -#if 0 - if (rsGxsForums->getRelatedMessages(token, msgs)) -#else - if (rsGxsForums->getMsgData(token, msgs)) -#endif - { - if (msgs.size() != 1) - { + if (rsGxsForums->getMsgData(token, msgs)) { + if (msgs.size() != 1) { std::cerr << "GxsForumsDialog::loadMsgData_InsertPost() ERROR Wrong number of answers"; std::cerr << std::endl; return; } insertPostData(msgs[0]); - } - else - { + } else { std::cerr << "GxsForumsDialog::loadMsgData_InsertPost() ERROR Missing Message Data..."; std::cerr << std::endl; } - mTokenPost = 0; } /*********************** **** **** **** ***********************/ @@ -1949,7 +1813,7 @@ void GxsForumThreadWidget::requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair & std::vector msgIds; msgIds.push_back(msgId); uint32_t token; - mThreadQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_REPLY_MESSAGE); + mThreadQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, TOKEN_TYPE_REPLY_MESSAGE); #else RsTokReqOptions opts; @@ -1963,7 +1827,7 @@ void GxsForumThreadWidget::requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair & vect.push_back(msgId.second); uint32_t token; - mThreadQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, FORUMV2DIALOG_REPLY_MESSAGE); + mThreadQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, TOKEN_TYPE_REPLY_MESSAGE); #endif } @@ -2008,23 +1872,15 @@ void GxsForumThreadWidget::loadRequest(const TokenQueue *queue, const TokenReque /* now switch on req */ switch(req.mUserType) { - case FORUMSV2DIALOG_CURRENTFORUM: + case TOKEN_TYPE_CURRENTFORUM: loadGroupSummary_CurrentForum(req.mToken); break; - case FORUMSV2DIALOG_INSERTTHREADS: - loadGroupThreadData_InsertThreads(req.mToken); - break; - - case FORUMSV2DIALOG_INSERTCHILD: - loadChildData_InsertThreads(req.mToken); - break; - - case FORUMV2DIALOG_INSERT_POST: + case TOKEN_TYPE_INSERT_POST: loadMsgData_InsertPost(req.mToken); break; - case FORUMV2DIALOG_REPLY_MESSAGE: + case TOKEN_TYPE_REPLY_MESSAGE: loadMsgData_ReplyMessage(req.mToken); break; diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h index d24beed95..7aefac457 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h @@ -6,38 +6,14 @@ #include "util/TokenQueue.h" class QTreeWidgetItem; -class GxsIdTreeWidgetItem; class RSTreeWidgetItemCompareRole; class RsGxsForumMsg; +class GxsForumsFillThread; namespace Ui { class GxsForumThreadWidget; } -/* These are all the parameters that are required for thread loading. - * They are kept static for the load duration. - */ - -class GxsForumsThreadLoadParameters -{ -public: - std::string ForumId; - std::string FocusMsgId; - - uint32_t SubscribeFlags; - int ViewType; - uint32_t FilterColumn; - - std::map MsgTokens; - QList Items; - QList ItemToExpand; - - bool FillComplete; - bool FlatView; - bool UseChildTS; - bool ExpandNewMessages; -}; - class GxsForumThreadWidget : public QWidget, public TokenResponse { Q_OBJECT @@ -65,8 +41,15 @@ public: void setTextColorMissing(QColor color) { mTextColorMissing = color; } std::string forumId() { return mForumId; } - QString forumName(); + QString forumName(bool withUnreadCount); QIcon forumIcon(); + unsigned int newCount() { return mNewCount; } + unsigned int unreadCount() { return mUnreadCount; } + + QTreeWidgetItem *convertMsgToThreadWidget(const RsGxsForumMsg &msg, bool useChildTS, uint32_t filterColumn); + QTreeWidgetItem *generateMissingItem(const std::string &msgId); + + void setAllMsgReadStatus(bool read); // Callback for all Loads. virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); @@ -98,9 +81,7 @@ private slots: //void removemessage(); void markMsgAsRead(); void markMsgAsReadChildren(); - void markMsgAsReadAll(); void markMsgAsUnread(); - void markMsgAsUnreadAll(); void markMsgAsUnreadChildren(); void copyMessageLink(); @@ -122,7 +103,8 @@ private slots: void filterItems(const QString &text); void fillThreadFinished(); -// void fillThreadProgress(int current, int count); + void fillThreadProgress(int current, int count); + void fillThreadStatus(QString text); private: void insertForumThreads(const RsGroupMetaData &fi); @@ -141,6 +123,7 @@ private: void markMsgAsReadUnread(bool read, bool children, bool forum); void calculateIconsAndFonts(QTreeWidgetItem *item = NULL); void calculateIconsAndFonts(QTreeWidgetItem *item, bool &hasReadChilddren, bool &hasUnreadChilddren); + void calculateUnreadCount(); void togglethreadview_internal(); @@ -159,35 +142,19 @@ private: int mLastViewType; RSTreeWidgetItemCompareRole *mThreadCompareRole; TokenQueue *mThreadQueue; - uint32_t mTokenGroupSummary; - uint32_t mTokenPost; - bool mRequestGroupSummary; // QTimer *mTimer; + GxsForumsFillThread *mFillThread; + unsigned int mUnreadCount; + unsigned int mNewCount; void requestGroupSummary_CurrentForum(const std::string &forumId); void loadGroupSummary_CurrentForum(const uint32_t &token); - void loadCurrentForumThreads(const std::string &forumId); - void requestGroupThreadData_InsertThreads(const std::string &forumId); - void loadGroupThreadData_InsertThreads(const uint32_t &token); - void loadForumBaseThread(const RsGxsForumMsg &msg); - - void requestChildData_InsertThreads(uint32_t &token, const RsGxsGrpMsgIdPair &parentId); - void loadChildData_InsertThreads(const uint32_t &token); - void loadForumChildMsg(const RsGxsForumMsg &msg, QTreeWidgetItem *parent); - void requestMsgData_InsertPost(const RsGxsGrpMsgIdPair &msgId); void loadMsgData_InsertPost(const uint32_t &token); void requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId); void loadMsgData_ReplyMessage(const uint32_t &token); - bool convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, bool useChildTS, uint32_t filterColumn, GxsIdTreeWidgetItem *item); -// bool convertMsgToThreadWidget(const RsGxsForumMsg &msgInfo, std::string authorName, bool useChildTS, uint32_t filterColumn, QTreeWidgetItem *item); - - // New Datatypes to replace the FillThread. - bool mThreadLoading; - GxsForumsThreadLoadParameters mThreadLoad; - /* Color definitions (for standard see qss.default) */ QColor mTextColorRead; QColor mTextColorUnread; diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.ui b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.ui index 57d65c158..9e2e6b664 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.ui +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.ui @@ -193,12 +193,12 @@ - + 3 - + 10 diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsFillThread.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumsFillThread.cpp new file mode 100644 index 000000000..ef00b6c3b --- /dev/null +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsFillThread.cpp @@ -0,0 +1,260 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2012, RetroShare Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include +#include + +#include "GxsForumsFillThread.h" +#include "GxsForumThreadWidget.h" + +#include + +#include + +#define DEBUG_FORUMS + +GxsForumsFillThread::GxsForumsFillThread(GxsForumThreadWidget *parent) + : QThread(parent), mParent(parent) +{ + mStopped = false; + mCompareRole = NULL; + + mExpandNewMessages = true; + mFillComplete = false; + + mFilterColumn = 0; + mSubscribeFlags = 0; + + mViewType = 0; + mFlatView = false; + mUseChildTS = false; +} + +GxsForumsFillThread::~GxsForumsFillThread() +{ +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumsFillThread::~GxsForumsFillThread" << std::endl; +#endif + + // remove all items (when items are available, the thread was terminated) + QList::iterator item; + for (item = mItems.begin (); item != mItems.end (); item++) { + if (*item) { + delete (*item); + } + } + mItems.clear(); + + mItemToExpand.clear(); +} + +void GxsForumsFillThread::stop() +{ + disconnect(); + mStopped = true; + QApplication::processEvents(); + wait(); +} + +void GxsForumsFillThread::run() +{ + RsTokenService *service = rsGxsForums->getTokenService(); + + emit status(tr("Waiting")); + + /* get all messages of the forum */ + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + opts.mOptions = RS_TOKREQOPT_MSG_LATEST; + + std::list grpIds; + grpIds.push_back(mForumId); + +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumsFillThread::run() forum id " << mForumId << std::endl; +#endif + + uint32_t token; + service->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds); + + /* wait for the answer */ + uint32_t requestStatus; + while (!wasStopped()) { + requestStatus = service->requestStatus(token); + if (requestStatus == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED || + requestStatus == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) { + break; + } + msleep(100); + } + + if (wasStopped()) { +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumsFillThread::run() thread stopped, cancel request" << std::endl; +#endif + + /* cancel request */ + service->cancelRequest(token); + return; + } + + if (requestStatus == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED) { +//#TODO + return; + } + +//#TODO +// if (failed) { +// mService->cancelRequest(token); +// return; +// } + + emit status(tr("Retrieving")); + + /* get messages */ + std::vector msgs; + if (!rsGxsForums->getMsgData(token, msgs)) { + return; + } + + emit status(tr("Loading")); + + int count = msgs.size(); + int pos = 0; + QList > threadList; + QPair threadPair; + + /* add all threads */ + std::vector::iterator msgIt; + for (msgIt = msgs.begin(); msgIt != msgs.end(); ) { + if (wasStopped()) { + break; + } + + const RsGxsForumMsg &msg = *msgIt; + + if (!msg.mMeta.mParentId.empty()) { + ++msgIt; + continue; + } + +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumsFillThread::run() Adding TopLevel Thread: mId: " << msg.mMeta.mMsgId << std::endl; +#endif + + QTreeWidgetItem *item = mParent->convertMsgToThreadWidget(msg, mUseChildTS, mFilterColumn); + threadList.push_back(QPair(msg.mMeta.mMsgId, item)); + + mItems.append(item); + emit progress(++pos, count); + + msgIt = msgs.erase(msgIt); + } + + /* process messages */ + while (msgs.size()) { + while (threadList.size() > 0) { + if (wasStopped()) { + break; + } + + threadPair = threadList.front(); + threadList.pop_front(); + +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumsFillThread::run() Getting Children of : " << threadPair.first << std::endl; +#endif + /* iterate through child */ + for (msgIt = msgs.begin(); msgIt != msgs.end(); ) { + const RsGxsForumMsg &msg = *msgIt; + + if (msg.mMeta.mParentId != threadPair.first) { + ++msgIt; + continue; + } + +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumsFillThread::run() adding " << msg.mMeta.mMsgId << std::endl; +#endif + + QTreeWidgetItem *item = mParent->convertMsgToThreadWidget(msg, mUseChildTS, mFilterColumn); + if (mFlatView) { + mItems.append(item); + } else { + threadPair.second->addChild(item); + } + + + /* add item to process list */ + threadList.push_back(QPair(msg.mMeta.mMsgId, item)); + + emit progress(++pos, count); + msgIt = msgs.erase(msgIt); + } + } + + if (wasStopped()) { + break; + } + + /* process missing messages */ + + /* search for a message with missing parent */ + for (msgIt = msgs.begin(); msgIt != msgs.end(); ++msgIt) { + const RsGxsForumMsg &msg = *msgIt; + + /* search for parent */ + std::vector::iterator msgIt1; + for (msgIt1 = msgs.begin(); msgIt1 != msgs.end(); ++msgIt1) { + if (wasStopped()) { + break; + } + + const RsGxsForumMsg &msg1 = *msgIt1; + + if (msg.mMeta.mParentId == msg1.mMeta.mMsgId) { + /* found parent */ + break; + } + } + + if (wasStopped()) { + break; + } + + if (msgIt1 != msgs.end()) { + /* parant found */ + continue; + } + + /* add dummy item */ + QTreeWidgetItem *item = mParent->generateMissingItem(msg.mMeta.mParentId); + threadList.push_back(QPair(msg.mMeta.mParentId, item)); + + mItems.append(item); + break; + } + } + +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumsFillThread::run() stopped: " << (wasStopped() ? "yes" : "no") << std::endl; +#endif +} diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsFillThread.h b/retroshare-gui/src/gui/gxsforums/GxsForumsFillThread.h new file mode 100644 index 000000000..7bc2a8123 --- /dev/null +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsFillThread.h @@ -0,0 +1,46 @@ +#ifndef GXSFORUMSFILLTHREAD_H +#define GXSFORUMSFILLTHREAD_H + +#include + +class GxsForumThreadWidget; +class RSTreeWidgetItemCompareRole; +class QTreeWidgetItem; + +class GxsForumsFillThread : public QThread +{ + Q_OBJECT + +public: + GxsForumsFillThread(GxsForumThreadWidget *parent); + ~GxsForumsFillThread(); + + void run(); + void stop(); + bool wasStopped() { return mStopped; } + +signals: + void progress(int current, int count); + void status(QString text); + +public: + std::string mForumId; + int mFilterColumn; + int mSubscribeFlags; + bool mFillComplete; + int mViewType; + bool mFlatView; + bool mUseChildTS; + bool mExpandNewMessages; + std::string mFocusMsgId; + RSTreeWidgetItemCompareRole *mCompareRole; + + QList mItems; + QList mItemToExpand; + +private: + GxsForumThreadWidget *mParent; + volatile bool mStopped; +}; + +#endif // GXSFORUMSFILLTHREAD_H From 3be22536df310a105342b85f64685fa2b412a368 Mon Sep 17 00:00:00 2001 From: drbob Date: Sun, 9 Dec 2012 12:12:57 +0000 Subject: [PATCH 206/222] adding pegmarkdown support library. git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5953 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/services/p3posted.cc | 1 + supportlibs/pegmarkdown/GLibFacade.c | 208 + supportlibs/pegmarkdown/GLibFacade.h | 67 + supportlibs/pegmarkdown/LICENSE | 88 + supportlibs/pegmarkdown/Makefile.orig | 42 + .../MarkdownTest_1.0.3/MarkdownTest.pl | 176 + .../Tests/Amps and angle encoding.html | 17 + .../Tests/Amps and angle encoding.text | 21 + .../MarkdownTest_1.0.3/Tests/Auto links.html | 18 + .../MarkdownTest_1.0.3/Tests/Auto links.text | 13 + .../Tests/Backslash escapes.html | 118 + .../Tests/Backslash escapes.text | 120 + .../Tests/Blockquotes with code blocks.html | 15 + .../Tests/Blockquotes with code blocks.text | 11 + .../MarkdownTest_1.0.3/Tests/Code Blocks.html | 18 + .../MarkdownTest_1.0.3/Tests/Code Blocks.text | 14 + .../MarkdownTest_1.0.3/Tests/Code Spans.html | 6 + .../MarkdownTest_1.0.3/Tests/Code Spans.text | 6 + ...apped paragraphs with list-like lines.html | 8 + ...apped paragraphs with list-like lines.text | 8 + .../Tests/Horizontal rules.html | 71 + .../Tests/Horizontal rules.text | 67 + .../Tests/Inline HTML (Advanced).html | 15 + .../Tests/Inline HTML (Advanced).text | 15 + .../Tests/Inline HTML (Simple).html | 72 + .../Tests/Inline HTML (Simple).text | 69 + .../Tests/Inline HTML comments.html | 13 + .../Tests/Inline HTML comments.text | 13 + .../Tests/Links, inline style.html | 11 + .../Tests/Links, inline style.text | 12 + .../Tests/Links, reference style.html | 52 + .../Tests/Links, reference style.text | 71 + .../Tests/Links, shortcut references.html | 9 + .../Tests/Links, shortcut references.text | 20 + .../Tests/Literal quotes in titles.html | 3 + .../Tests/Literal quotes in titles.text | 7 + .../Markdown Documentation - Basics.html | 314 + .../Markdown Documentation - Basics.text | 306 + .../Markdown Documentation - Syntax.html | 942 +++ .../Markdown Documentation - Syntax.text | 888 +++ .../Tests/Nested blockquotes.html | 9 + .../Tests/Nested blockquotes.text | 5 + .../Tests/Ordered and unordered lists.html | 148 + .../Tests/Ordered and unordered lists.text | 131 + .../Tests/Strong and em together.html | 7 + .../Tests/Strong and em together.text | 7 + .../MarkdownTest_1.0.3/Tests/Tabs.html | 25 + .../MarkdownTest_1.0.3/Tests/Tabs.text | 21 + .../MarkdownTest_1.0.3/Tests/Tidyness.html | 8 + .../MarkdownTest_1.0.3/Tests/Tidyness.text | 5 + supportlibs/pegmarkdown/README.markdown | 225 + supportlibs/pegmarkdown/glib.h | 11 + supportlibs/pegmarkdown/markdown.c | 183 + supportlibs/pegmarkdown/markdown_lib.c | 181 + supportlibs/pegmarkdown/markdown_lib.h | 38 + supportlibs/pegmarkdown/markdown_output.c | 1121 +++ supportlibs/pegmarkdown/markdown_parser.c | 6665 +++++++++++++++++ supportlibs/pegmarkdown/markdown_parser.leg | 770 ++ supportlibs/pegmarkdown/markdown_peg.h | 72 + supportlibs/pegmarkdown/odf.c | 181 + supportlibs/pegmarkdown/odf.h | 11 + supportlibs/pegmarkdown/parsing_functions.c | 117 + supportlibs/pegmarkdown/parsing_functions.h | 17 + supportlibs/pegmarkdown/peg-0.1.9/Makefile | 65 + supportlibs/pegmarkdown/peg-0.1.9/compile.c | 717 ++ .../pegmarkdown/peg-0.1.9/examples/Makefile | 88 + .../pegmarkdown/peg-0.1.9/examples/accept.c | 11 + .../pegmarkdown/peg-0.1.9/examples/accept.peg | 8 + .../pegmarkdown/peg-0.1.9/examples/accept.ref | 32 + .../pegmarkdown/peg-0.1.9/examples/basic.leg | 361 + .../pegmarkdown/peg-0.1.9/examples/basic.ref | 10 + .../pegmarkdown/peg-0.1.9/examples/bench.bas | 8 + .../pegmarkdown/peg-0.1.9/examples/calc.leg | 46 + .../pegmarkdown/peg-0.1.9/examples/calc.ref | 3 + .../pegmarkdown/peg-0.1.9/examples/dc.c | 17 + .../pegmarkdown/peg-0.1.9/examples/dc.peg | 27 + .../pegmarkdown/peg-0.1.9/examples/dc.ref | 1 + .../pegmarkdown/peg-0.1.9/examples/dcv.c | 20 + .../pegmarkdown/peg-0.1.9/examples/dcv.peg | 34 + .../pegmarkdown/peg-0.1.9/examples/dcv.ref | 3 + .../peg-0.1.9/examples/fibonacci.bas | 17 + .../pegmarkdown/peg-0.1.9/examples/left.c | 17 + .../pegmarkdown/peg-0.1.9/examples/left.peg | 3 + .../pegmarkdown/peg-0.1.9/examples/localctx.c | 13 + .../peg-0.1.9/examples/localctx.ref | 10 + .../pegmarkdown/peg-0.1.9/examples/rule.c | 11 + .../pegmarkdown/peg-0.1.9/examples/rule.peg | 8 + .../pegmarkdown/peg-0.1.9/examples/rule.ref | 32 + .../pegmarkdown/peg-0.1.9/examples/test.bas | 12 + .../pegmarkdown/peg-0.1.9/examples/test.c | 8 + .../pegmarkdown/peg-0.1.9/examples/test.peg | 13 + .../pegmarkdown/peg-0.1.9/examples/test.ref | 10 + .../peg-0.1.9/examples/username.leg | 14 + .../pegmarkdown/peg-0.1.9/examples/wc.leg | 22 + .../pegmarkdown/peg-0.1.9/examples/wc.ref | 55 + supportlibs/pegmarkdown/peg-0.1.9/leg.c | 1209 +++ supportlibs/pegmarkdown/peg-0.1.9/leg.leg | 292 + supportlibs/pegmarkdown/peg-0.1.9/peg.1 | 933 +++ supportlibs/pegmarkdown/peg-0.1.9/peg.c | 173 + supportlibs/pegmarkdown/peg-0.1.9/peg.peg | 77 + supportlibs/pegmarkdown/peg-0.1.9/peg.peg-c | 912 +++ supportlibs/pegmarkdown/peg-0.1.9/tree.c | 352 + supportlibs/pegmarkdown/peg-0.1.9/tree.h | 108 + supportlibs/pegmarkdown/peg-0.1.9/version.h | 3 + supportlibs/pegmarkdown/pegmarkdown.pro | 100 + supportlibs/pegmarkdown/utility_functions.c | 206 + supportlibs/pegmarkdown/utility_functions.h | 74 + 107 files changed, 20038 insertions(+) create mode 100644 supportlibs/pegmarkdown/GLibFacade.c create mode 100644 supportlibs/pegmarkdown/GLibFacade.h create mode 100644 supportlibs/pegmarkdown/LICENSE create mode 100644 supportlibs/pegmarkdown/Makefile.orig create mode 100755 supportlibs/pegmarkdown/MarkdownTest_1.0.3/MarkdownTest.pl create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Amps and angle encoding.html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Amps and angle encoding.text create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Auto links.html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Auto links.text create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Backslash escapes.html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Backslash escapes.text create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.text create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Code Blocks.html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Code Blocks.text create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Code Spans.html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Code Spans.text create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.text create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Horizontal rules.html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Horizontal rules.text create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).text create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).text create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML comments.html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML comments.text create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, inline style.html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, inline style.text create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, reference style.html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, reference style.text create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, shortcut references.html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, shortcut references.text create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Literal quotes in titles.html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Literal quotes in titles.text create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.text create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.text create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Nested blockquotes.html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Nested blockquotes.text create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.text create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Strong and em together.html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Strong and em together.text create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Tabs.html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Tabs.text create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Tidyness.html create mode 100644 supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Tidyness.text create mode 100644 supportlibs/pegmarkdown/README.markdown create mode 100644 supportlibs/pegmarkdown/glib.h create mode 100644 supportlibs/pegmarkdown/markdown.c create mode 100644 supportlibs/pegmarkdown/markdown_lib.c create mode 100644 supportlibs/pegmarkdown/markdown_lib.h create mode 100644 supportlibs/pegmarkdown/markdown_output.c create mode 100644 supportlibs/pegmarkdown/markdown_parser.c create mode 100644 supportlibs/pegmarkdown/markdown_parser.leg create mode 100644 supportlibs/pegmarkdown/markdown_peg.h create mode 100644 supportlibs/pegmarkdown/odf.c create mode 100644 supportlibs/pegmarkdown/odf.h create mode 100644 supportlibs/pegmarkdown/parsing_functions.c create mode 100644 supportlibs/pegmarkdown/parsing_functions.h create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/Makefile create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/compile.c create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/Makefile create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/accept.c create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/accept.peg create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/accept.ref create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/basic.leg create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/basic.ref create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/bench.bas create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/calc.leg create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/calc.ref create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/dc.c create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/dc.peg create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/dc.ref create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/dcv.c create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/dcv.peg create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/dcv.ref create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/fibonacci.bas create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/left.c create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/left.peg create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/localctx.c create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/localctx.ref create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/rule.c create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/rule.peg create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/rule.ref create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/test.bas create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/test.c create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/test.peg create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/test.ref create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/username.leg create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/wc.leg create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/examples/wc.ref create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/leg.c create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/leg.leg create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/peg.1 create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/peg.c create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/peg.peg create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/peg.peg-c create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/tree.c create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/tree.h create mode 100644 supportlibs/pegmarkdown/peg-0.1.9/version.h create mode 100644 supportlibs/pegmarkdown/pegmarkdown.pro create mode 100644 supportlibs/pegmarkdown/utility_functions.c create mode 100644 supportlibs/pegmarkdown/utility_functions.h diff --git a/libretroshare/src/services/p3posted.cc b/libretroshare/src/services/p3posted.cc index 20736ee6c..0ad470653 100644 --- a/libretroshare/src/services/p3posted.cc +++ b/libretroshare/src/services/p3posted.cc @@ -2,6 +2,7 @@ #include #include #include +#include #include "p3posted.h" #include "gxs/rsgxsflags.h" diff --git a/supportlibs/pegmarkdown/GLibFacade.c b/supportlibs/pegmarkdown/GLibFacade.c new file mode 100644 index 000000000..f60c1443b --- /dev/null +++ b/supportlibs/pegmarkdown/GLibFacade.c @@ -0,0 +1,208 @@ +/* + * GLibFacade.c + * MultiMarkdown + * + * Created by Daniel Jalkut on 7/26/11. + * Modified by Fletcher T. Penney on 9/15/11. + * Modified by Dan Lowe on 1/3/12. + * Copyright 2011 __MyCompanyName__. All rights reserved. + */ + +#include "GLibFacade.h" + +#include +#include +#include +#include + +/* + * The following section came from: + * + * http://lists-archives.org/mingw-users/12649-asprintf-missing-vsnprintf- + * behaving-differently-and-_vsncprintf-undefined.html + * + * and + * + * http://groups.google.com/group/jansson-users/browse_thread/thread/ + * 76a88d63d9519978/041a7d0570de2d48?lnk=raot + */ + +/* Solaris and Windows do not provide vasprintf() or asprintf(). */ +#if defined(__WIN32) || (defined(__SVR4) && defined(__sun)) +int vasprintf( char **sptr, char *fmt, va_list argv ) +{ + int wanted = vsnprintf( *sptr = NULL, 0, fmt, argv ); + if( (wanted > 0) && ((*sptr = malloc( 1 + wanted )) != NULL) ) + return vsprintf( *sptr, fmt, argv ); + + return wanted; +} + +int asprintf( char **sptr, char *fmt, ... ) +{ + int retval; + va_list argv; + va_start( argv, fmt ); + retval = vasprintf( sptr, fmt, argv ); + va_end( argv ); + return retval; +} +#endif + + +/* GString */ + +#define kStringBufferStartingSize 1024 +#define kStringBufferGrowthMultiplier 2 + +GString* g_string_new(char *startingString) +{ + GString* newString = malloc(sizeof(GString)); + + if (startingString == NULL) startingString = ""; + + size_t startingBufferSize = kStringBufferStartingSize; + size_t startingStringSize = strlen(startingString); + while (startingBufferSize < (startingStringSize + 1)) + { + startingBufferSize *= kStringBufferGrowthMultiplier; + } + + newString->str = malloc(startingBufferSize); + newString->currentStringBufferSize = startingBufferSize; + strncpy(newString->str, startingString, startingStringSize); + newString->str[startingStringSize] = '\0'; + newString->currentStringLength = startingStringSize; + + return newString; +} + +char* g_string_free(GString* ripString, bool freeCharacterData) +{ + char* returnedString = ripString->str; + if (freeCharacterData) + { + if (ripString->str != NULL) + { + free(ripString->str); + } + returnedString = NULL; + } + + free(ripString); + + return returnedString; +} + +static void ensureStringBufferCanHold(GString* baseString, size_t newStringSize) +{ + size_t newBufferSizeNeeded = newStringSize + 1; + if (newBufferSizeNeeded > baseString->currentStringBufferSize) + { + size_t newBufferSize = baseString->currentStringBufferSize; + + while (newBufferSizeNeeded > newBufferSize) + { + newBufferSize *= kStringBufferGrowthMultiplier; + } + + baseString->str = realloc(baseString->str, newBufferSize); + baseString->currentStringBufferSize = newBufferSize; + } +} + +void g_string_append(GString* baseString, char* appendedString) +{ + if ((appendedString != NULL) && (strlen(appendedString) > 0)) + { + size_t appendedStringLength = strlen(appendedString); + size_t newStringLength = baseString->currentStringLength + appendedStringLength; + ensureStringBufferCanHold(baseString, newStringLength); + + /* We already know where the current string ends, so pass that as the starting address for strncat */ + strncat(baseString->str + baseString->currentStringLength, appendedString, appendedStringLength); + baseString->currentStringLength = newStringLength; + } +} + +void g_string_append_c(GString* baseString, char appendedCharacter) +{ + size_t newSizeNeeded = baseString->currentStringLength + 1; + ensureStringBufferCanHold(baseString, newSizeNeeded); + + baseString->str[baseString->currentStringLength] = appendedCharacter; + baseString->currentStringLength++; + baseString->str[baseString->currentStringLength] = '\0'; +} + +void g_string_append_printf(GString* baseString, char* format, ...) +{ + va_list args; + va_start(args, format); + + char* formattedString = NULL; + vasprintf(&formattedString, format, args); + if (formattedString != NULL) + { + g_string_append(baseString, formattedString); + free(formattedString); + } +} + +void g_string_prepend(GString* baseString, char* prependedString) +{ + if ((prependedString != NULL) && (strlen(prependedString) > 0)) + { + size_t prependedStringLength = strlen(prependedString); + size_t newStringLength = baseString->currentStringLength + prependedStringLength; + ensureStringBufferCanHold(baseString, newStringLength); + + memmove(baseString->str + prependedStringLength, baseString->str, baseString->currentStringLength); + strncpy(baseString->str, prependedString, prependedStringLength); + baseString->currentStringLength = newStringLength; + baseString->str[baseString->currentStringLength] = '\0'; + } +} + +/* GSList */ + +void g_slist_free(GSList* ripList) +{ + GSList* thisListItem = ripList; + while (thisListItem != NULL) + { + GSList* nextItem = thisListItem->next; + + /* I guess we don't release the data? Non-retained memory management is hard... let's figure it out later. */ + free(thisListItem); + + thisListItem = nextItem; + } +} + +/* Currently only used for markdown_output.c endnotes printing */ +GSList* g_slist_reverse(GSList* theList) +{ + GSList* lastNodeSeen = NULL; + + /* Iterate the list items, tacking them on to our new reversed List as we find them */ + GSList* listWalker = theList; + while (listWalker != NULL) + { + GSList* nextNode = listWalker->next; + listWalker->next = lastNodeSeen; + lastNodeSeen = listWalker; + listWalker = nextNode; + } + + return lastNodeSeen; +} + +GSList* g_slist_prepend(GSList* targetElement, void* newElementData) +{ + GSList* newElement = malloc(sizeof(GSList)); + newElement->data = newElementData; + newElement->next = targetElement; + return newElement; +} + diff --git a/supportlibs/pegmarkdown/GLibFacade.h b/supportlibs/pegmarkdown/GLibFacade.h new file mode 100644 index 000000000..30651ac54 --- /dev/null +++ b/supportlibs/pegmarkdown/GLibFacade.h @@ -0,0 +1,67 @@ +/* + * GLibFacade.h + * MultiMarkdown + * + * Created by Daniel Jalkut on 7/26/11. + * Copyright 2011 __MyCompanyName__. All rights reserved. + */ + +#ifndef __MARKDOWN_GLIB_FACADE__ +#define __MARKDOWN_GLIB_FACADE__ + +/* peg_markdown uses the link symbol for its own purposes */ +#define link MARKDOWN_LINK_IGNORED +#include +#undef link + +#include +#include + +typedef int gboolean; +typedef char gchar; + +/* This style of bool is used in shared source code */ +#define FALSE false +#define TRUE true + +/* WE implement minimal mirror implementations of GLib's GString and GSList + * sufficient to cover the functionality required by MultiMarkdown. + * + * NOTE: THese are 100% clean, from-scratch implementations using only the + * GLib function prototype as guide for behavior. + */ + +typedef struct +{ + /* Current UTF8 byte stream this string represents */ + char* str; + + /* Where in the str buffer will we add new characters */ + /* or append new strings? */ + int currentStringBufferSize; + int currentStringLength; +} GString; + +GString* g_string_new(char *startingString); +char* g_string_free(GString* ripString, bool freeCharacterData); + +void g_string_append_c(GString* baseString, char appendedCharacter); +void g_string_append(GString* baseString, char *appendedString); + +void g_string_prepend(GString* baseString, char* prependedString); + +void g_string_append_printf(GString* baseString, char* format, ...); + +/* Just implement a very simple singly linked list. */ + +typedef struct _GSList +{ + void* data; + struct _GSList* next; +} GSList; + +void g_slist_free(GSList* ripList); +GSList* g_slist_prepend(GSList* targetElement, void* newElementData); +GSList* g_slist_reverse(GSList* theList); + +#endif diff --git a/supportlibs/pegmarkdown/LICENSE b/supportlibs/pegmarkdown/LICENSE new file mode 100644 index 000000000..878252980 --- /dev/null +++ b/supportlibs/pegmarkdown/LICENSE @@ -0,0 +1,88 @@ +markdown in c, implemented using PEG grammar +Copyright (c) 2008-2011 John MacFarlane +ODF output code (c) 2011 Fletcher T. Penney + +peg-markdown is released under both the GPL and MIT licenses. +You may pick the license that best fits your needs. + +The GPL + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +The MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +peg-0.1.4 (included for convenience - http://piumarta.com/software/peg/) + +Copyright (c) 2007 by Ian Piumarta +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the 'Software'), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, provided that the above copyright notice(s) and this +permission notice appear in all copies of the Software. Acknowledgement +of the use of this Software in supporting documentation would be +appreciated but is not required. + +THE SOFTWARE IS PROVIDED 'AS IS'. USE ENTIRELY AT YOUR OWN RISK. + +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +my_getopt (included for convenience - http://www.geocities.com/bsittler/) + +Copyright 1997, 2000, 2001, 2002, 2006, Benjamin Sittler + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, copy, +modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + diff --git a/supportlibs/pegmarkdown/Makefile.orig b/supportlibs/pegmarkdown/Makefile.orig new file mode 100644 index 000000000..1e8c7a003 --- /dev/null +++ b/supportlibs/pegmarkdown/Makefile.orig @@ -0,0 +1,42 @@ +uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') +ifneq (,$(findstring MINGW,$(uname_S))) + X = .exe +endif + +export X + +PROGRAM=markdown$(X) +CFLAGS ?= -Wall -O3 -ansi -D_GNU_SOURCE # -flto for newer GCC versions +OBJS=markdown_parser.o markdown_output.o markdown_lib.o utility_functions.o parsing_functions.o odf.o +PEGDIR=peg-0.1.9 +LEG=$(PEGDIR)/leg$(X) +PKG_CONFIG = pkg-config + +ALL : $(PROGRAM) + +$(LEG): $(PEGDIR) + CC=gcc make -C $(PEGDIR) + +%.o : %.c markdown_peg.h + $(CC) -c `$(PKG_CONFIG) --cflags glib-2.0` $(CFLAGS) -o $@ $< + +$(PROGRAM) : markdown.c $(OBJS) + $(CC) `$(PKG_CONFIG) --cflags glib-2.0` $(CFLAGS) -o $@ $< $(OBJS) `$(PKG_CONFIG) --libs glib-2.0` + +markdown_parser.c : markdown_parser.leg $(LEG) markdown_peg.h parsing_functions.c utility_functions.c + $(LEG) -o $@ $< + +.PHONY: clean test + +clean: + rm -f markdown_parser.c $(PROGRAM) $(OBJS) + +distclean: clean + make -C $(PEGDIR) clean +\ +test: $(PROGRAM) + cd MarkdownTest_1.0.3; \ + ./MarkdownTest.pl --script=../$(PROGRAM) --tidy + +leak-check: $(PROGRAM) + valgrind --leak-check=full ./markdown README diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/MarkdownTest.pl b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/MarkdownTest.pl new file mode 100755 index 000000000..55553d09c --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/MarkdownTest.pl @@ -0,0 +1,176 @@ +#!/usr/bin/perl + +# +# MarkdownTester -- Run tests for Markdown implementations +# +# Copyright (c) 2004-2005 John Gruber +# +# + +use strict; +use warnings; +use Getopt::Long; +use Benchmark; + +our $VERSION = '1.0.2'; +# Sat 24 Dec 2005 + +my $time_start = new Benchmark; +my $test_dir = "Tests"; +my $script = "./Markdown.pl"; +my $use_tidy = 0; +my ($flag_version); + +GetOptions ( + "script=s" => \$script, + "testdir=s" => \$test_dir, + "tidy" => \$use_tidy, + "version" => \$flag_version, + ); + +if($flag_version) { + my $progname = $0; + $progname =~ s{.*/}{}; + die "$progname version $VERSION\n"; +} + +unless (-d $test_dir) { die "'$test_dir' is not a directory.\n"; } +unless (-f $script) { die "$script does not exist.\n"; } +unless (-x $script) { die "$script is not executable.\n"; } + +my $tests_passed = 0; +my $tests_failed = 0; + +TEST: +foreach my $testfile (glob "$test_dir/*.text") { + my $testname = $testfile; + $testname =~ s{.*/(.+)\.text$}{$1}i; + print "$testname ... "; + + # Look for a corresponding .html file for each .text file: + my $resultfile = $testfile; + $resultfile =~ s{\.text$}{\.html}i; + unless (-f $resultfile) { + print "'$resultfile' does not exist.\n\n"; + next TEST; + } + + # open(TEST, $testfile) || die("Can't open testfile: $!"); + open(RESULT, $resultfile) || die("Can't open resultfile: $!"); + undef $/; + # my $t_input = ; + my $t_result = ; + + my $t_output = `'$script' '$testfile'`; + + # Normalize the output and expected result strings: + $t_result =~ s/\s+\z//; # trim trailing whitespace + $t_output =~ s/\s+\z//; # trim trailing whitespace + if ($use_tidy) { + # Escape the strings, pass them through to CLI tidy tool for tag-level equivalency + $t_result =~ s{'}{'\\''}g; # escape ' chars for shell + $t_output =~ s{'}{'\\''}g; + $t_result = `echo '$t_result' | tidy --show-body-only 1 --quiet 1 --show-warnings 0`; + $t_output = `echo '$t_output' | tidy --show-body-only 1 --quiet 1 --show-warnings 0`; + } + + if ($t_output eq $t_result) { + print "OK\n"; + $tests_passed++; + } + else { + print "FAILED\n\n"; +# This part added by JM to print diffs + open(OUT, '>tmp1') or die $!; + print OUT $t_output or die $!; + open(RES, '>tmp2') or die $!; + print RES $t_result or die $!; + print `diff tmp1 tmp2`; + close RES; + close OUT; + print "\n"; + `rm tmp?`; +# End of added part + $tests_failed++; + } +} + +print "\n\n"; +print "$tests_passed passed; $tests_failed failed.\n"; + +my $time_end = new Benchmark; +my $time_diff = timediff($time_end, $time_start); +print "Benchmark: ", timestr($time_diff), "\n"; + + +__END__ + +=pod + +=head1 NAME + +B + + +=head1 SYNOPSIS + +B [ B<--options> ] [ I ... ] + + +=head1 DESCRIPTION + + +=head1 OPTIONS + +Use "--" to end switch parsing. For example, to open a file named "-z", use: + + MarkdownTest.pl -- -z + +=over 4 + +=item B<--script> + +Specify the path to the Markdown script to test. Defaults to +"./Markdown.pl". Example: + + ./MarkdownTest.pl --script ./PHP-Markdown/php-markdown + +=item B<--testdir> + +Specify the path to a directory containing test data. Defaults to "Tests". + +=item B<--tidy> + +Flag to turn on using the command line 'tidy' tool to normalize HTML +output before comparing script output to the expected test result. +Assumes that the 'tidy' command is available in your PATH. Defaults to +off. + +=back + + + +=head1 BUGS + + + +=head1 VERSION HISTORY + +1.0 Mon 13 Dec 2004-2005 + +1.0.1 Mon 19 Sep 2005 + + + Better handling of case when foo.text exists, but foo.html doesn't. + It now prints a message and moves on, rather than dying. + + +=head1 COPYRIGHT AND LICENSE + +Copyright (c) 2004-2005 John Gruber + +All rights reserved. + +This is free software; you may redistribute it and/or modify it under +the same terms as Perl itself. + +=cut diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Amps and angle encoding.html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Amps and angle encoding.html new file mode 100644 index 000000000..9606860b6 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Amps and angle encoding.html @@ -0,0 +1,17 @@ +

AT&T has an ampersand in their name.

+ +

AT&T is another way to write it.

+ +

This & that.

+ +

4 < 5.

+ +

6 > 5.

+ +

Here's a link with an ampersand in the URL.

+ +

Here's a link with an amersand in the link text: AT&T.

+ +

Here's an inline link.

+ +

Here's an inline link.

diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Amps and angle encoding.text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Amps and angle encoding.text new file mode 100644 index 000000000..0e9527f93 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Amps and angle encoding.text @@ -0,0 +1,21 @@ +AT&T has an ampersand in their name. + +AT&T is another way to write it. + +This & that. + +4 < 5. + +6 > 5. + +Here's a [link] [1] with an ampersand in the URL. + +Here's a link with an amersand in the link text: [AT&T] [2]. + +Here's an inline [link](/script?foo=1&bar=2). + +Here's an inline [link](). + + +[1]: http://example.com/?foo=1&bar=2 +[2]: http://att.com/ "AT&T" \ No newline at end of file diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Auto links.html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Auto links.html new file mode 100644 index 000000000..f8df9852c --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Auto links.html @@ -0,0 +1,18 @@ +

Link: http://example.com/.

+ +

With an ampersand: http://example.com/?foo=1&bar=2

+ + + +
+

Blockquoted: http://example.com/

+
+ +

Auto-links should not occur here: <http://example.com/>

+ +
or here: <http://example.com/>
+
diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Auto links.text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Auto links.text new file mode 100644 index 000000000..abbc48869 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Auto links.text @@ -0,0 +1,13 @@ +Link: . + +With an ampersand: + +* In a list? +* +* It should. + +> Blockquoted: + +Auto-links should not occur here: `` + + or here: \ No newline at end of file diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Backslash escapes.html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Backslash escapes.html new file mode 100644 index 000000000..29870dac5 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Backslash escapes.html @@ -0,0 +1,118 @@ +

These should all get escaped:

+ +

Backslash: \

+ +

Backtick: `

+ +

Asterisk: *

+ +

Underscore: _

+ +

Left brace: {

+ +

Right brace: }

+ +

Left bracket: [

+ +

Right bracket: ]

+ +

Left paren: (

+ +

Right paren: )

+ +

Greater-than: >

+ +

Hash: #

+ +

Period: .

+ +

Bang: !

+ +

Plus: +

+ +

Minus: -

+ +

These should not, because they occur within a code block:

+ +
Backslash: \\
+
+Backtick: \`
+
+Asterisk: \*
+
+Underscore: \_
+
+Left brace: \{
+
+Right brace: \}
+
+Left bracket: \[
+
+Right bracket: \]
+
+Left paren: \(
+
+Right paren: \)
+
+Greater-than: \>
+
+Hash: \#
+
+Period: \.
+
+Bang: \!
+
+Plus: \+
+
+Minus: \-
+
+ +

Nor should these, which occur in code spans:

+ +

Backslash: \\

+ +

Backtick: \`

+ +

Asterisk: \*

+ +

Underscore: \_

+ +

Left brace: \{

+ +

Right brace: \}

+ +

Left bracket: \[

+ +

Right bracket: \]

+ +

Left paren: \(

+ +

Right paren: \)

+ +

Greater-than: \>

+ +

Hash: \#

+ +

Period: \.

+ +

Bang: \!

+ +

Plus: \+

+ +

Minus: \-

+ + +

These should get escaped, even though they're matching pairs for +other Markdown constructs:

+ +

*asterisks*

+ +

_underscores_

+ +

`backticks`

+ +

This is a code span with a literal backslash-backtick sequence: \`

+ +

This is a tag with unescaped backticks bar.

+ +

This is a tag with backslashes bar.

diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Backslash escapes.text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Backslash escapes.text new file mode 100644 index 000000000..5b014cb33 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Backslash escapes.text @@ -0,0 +1,120 @@ +These should all get escaped: + +Backslash: \\ + +Backtick: \` + +Asterisk: \* + +Underscore: \_ + +Left brace: \{ + +Right brace: \} + +Left bracket: \[ + +Right bracket: \] + +Left paren: \( + +Right paren: \) + +Greater-than: \> + +Hash: \# + +Period: \. + +Bang: \! + +Plus: \+ + +Minus: \- + + + +These should not, because they occur within a code block: + + Backslash: \\ + + Backtick: \` + + Asterisk: \* + + Underscore: \_ + + Left brace: \{ + + Right brace: \} + + Left bracket: \[ + + Right bracket: \] + + Left paren: \( + + Right paren: \) + + Greater-than: \> + + Hash: \# + + Period: \. + + Bang: \! + + Plus: \+ + + Minus: \- + + +Nor should these, which occur in code spans: + +Backslash: `\\` + +Backtick: `` \` `` + +Asterisk: `\*` + +Underscore: `\_` + +Left brace: `\{` + +Right brace: `\}` + +Left bracket: `\[` + +Right bracket: `\]` + +Left paren: `\(` + +Right paren: `\)` + +Greater-than: `\>` + +Hash: `\#` + +Period: `\.` + +Bang: `\!` + +Plus: `\+` + +Minus: `\-` + + +These should get escaped, even though they're matching pairs for +other Markdown constructs: + +\*asterisks\* + +\_underscores\_ + +\`backticks\` + +This is a code span with a literal backslash-backtick sequence: `` \` `` + +This is a tag with unescaped backticks bar. + +This is a tag with backslashes bar. diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.html new file mode 100644 index 000000000..990202a1b --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.html @@ -0,0 +1,15 @@ +
+

Example:

+ +
sub status {
+    print "working";
+}
+
+ +

Or:

+ +
sub status {
+    return "working";
+}
+
+
diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.text new file mode 100644 index 000000000..c31d17104 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.text @@ -0,0 +1,11 @@ +> Example: +> +> sub status { +> print "working"; +> } +> +> Or: +> +> sub status { +> return "working"; +> } diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Code Blocks.html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Code Blocks.html new file mode 100644 index 000000000..32703f5cb --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Code Blocks.html @@ -0,0 +1,18 @@ +
code block on the first line
+
+ +

Regular text.

+ +
code block indented by spaces
+
+ +

Regular text.

+ +
the lines in this block  
+all contain trailing spaces  
+
+ +

Regular Text.

+ +
code block on the last line
+
diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Code Blocks.text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Code Blocks.text new file mode 100644 index 000000000..b54b09285 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Code Blocks.text @@ -0,0 +1,14 @@ + code block on the first line + +Regular text. + + code block indented by spaces + +Regular text. + + the lines in this block + all contain trailing spaces + +Regular Text. + + code block on the last line \ No newline at end of file diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Code Spans.html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Code Spans.html new file mode 100644 index 000000000..4b8afbb70 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Code Spans.html @@ -0,0 +1,6 @@ +

<test a=" content of attribute ">

+ +

Fix for backticks within HTML tag: like this

+ +

Here's how you put `backticks` in a code span.

+ diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Code Spans.text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Code Spans.text new file mode 100644 index 000000000..750a1973d --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Code Spans.text @@ -0,0 +1,6 @@ +`` + +Fix for backticks within HTML tag: like this + +Here's how you put `` `backticks` `` in a code span. + diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.html new file mode 100644 index 000000000..e21ac79a2 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.html @@ -0,0 +1,8 @@ +

In Markdown 1.0.0 and earlier. Version +8. This line turns into a list item. +Because a hard-wrapped line in the +middle of a paragraph looked like a +list item.

+ +

Here's one with a bullet. +* criminey.

diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.text new file mode 100644 index 000000000..f8a5b27bf --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.text @@ -0,0 +1,8 @@ +In Markdown 1.0.0 and earlier. Version +8. This line turns into a list item. +Because a hard-wrapped line in the +middle of a paragraph looked like a +list item. + +Here's one with a bullet. +* criminey. diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Horizontal rules.html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Horizontal rules.html new file mode 100644 index 000000000..2dc2ab656 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Horizontal rules.html @@ -0,0 +1,71 @@ +

Dashes:

+ +
+ +
+ +
+ +
+ +
---
+
+ +
+ +
+ +
+ +
+ +
- - -
+
+ +

Asterisks:

+ +
+ +
+ +
+ +
+ +
***
+
+ +
+ +
+ +
+ +
+ +
* * *
+
+ +

Underscores:

+ +
+ +
+ +
+ +
+ +
___
+
+ +
+ +
+ +
+ +
+ +
_ _ _
+
diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Horizontal rules.text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Horizontal rules.text new file mode 100644 index 000000000..1594bda27 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Horizontal rules.text @@ -0,0 +1,67 @@ +Dashes: + +--- + + --- + + --- + + --- + + --- + +- - - + + - - - + + - - - + + - - - + + - - - + + +Asterisks: + +*** + + *** + + *** + + *** + + *** + +* * * + + * * * + + * * * + + * * * + + * * * + + +Underscores: + +___ + + ___ + + ___ + + ___ + + ___ + +_ _ _ + + _ _ _ + + _ _ _ + + _ _ _ + + _ _ _ diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).html new file mode 100644 index 000000000..3af9cafb1 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).html @@ -0,0 +1,15 @@ +

Simple block on one line:

+ +
foo
+ +

And nested without indentation:

+ +
+
+
+foo +
+
+
+
bar
+
diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).text new file mode 100644 index 000000000..86b7206d2 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).text @@ -0,0 +1,15 @@ +Simple block on one line: + +
foo
+ +And nested without indentation: + +
+
+
+foo +
+
+
+
bar
+
diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).html new file mode 100644 index 000000000..6bf78f8fc --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).html @@ -0,0 +1,72 @@ +

Here's a simple block:

+ +
+ foo +
+ +

This should be a code block, though:

+ +
<div>
+    foo
+</div>
+
+ +

As should this:

+ +
<div>foo</div>
+
+ +

Now, nested:

+ +
+
+
+ foo +
+
+
+ +

This should just be an HTML comment:

+ + + +

Multiline:

+ + + +

Code block:

+ +
<!-- Comment -->
+
+ +

Just plain comment, with trailing spaces on the line:

+ + + +

Code:

+ +
<hr />
+
+ +

Hr's:

+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).text new file mode 100644 index 000000000..14aa2dc27 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML (Simple).text @@ -0,0 +1,69 @@ +Here's a simple block: + +
+ foo +
+ +This should be a code block, though: + +
+ foo +
+ +As should this: + +
foo
+ +Now, nested: + +
+
+
+ foo +
+
+
+ +This should just be an HTML comment: + + + +Multiline: + + + +Code block: + + + +Just plain comment, with trailing spaces on the line: + + + +Code: + +
+ +Hr's: + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML comments.html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML comments.html new file mode 100644 index 000000000..3f167a161 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML comments.html @@ -0,0 +1,13 @@ +

Paragraph one.

+ + + + + +

Paragraph two.

+ + + +

The end.

diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML comments.text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML comments.text new file mode 100644 index 000000000..41d830d03 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Inline HTML comments.text @@ -0,0 +1,13 @@ +Paragraph one. + + + + + +Paragraph two. + + + +The end. diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, inline style.html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, inline style.html new file mode 100644 index 000000000..f36607ddd --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, inline style.html @@ -0,0 +1,11 @@ +

Just a URL.

+ +

URL and title.

+ +

URL and title.

+ +

URL and title.

+ +

URL and title.

+ +

Empty.

diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, inline style.text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, inline style.text new file mode 100644 index 000000000..09017a90c --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, inline style.text @@ -0,0 +1,12 @@ +Just a [URL](/url/). + +[URL and title](/url/ "title"). + +[URL and title](/url/ "title preceded by two spaces"). + +[URL and title](/url/ "title preceded by a tab"). + +[URL and title](/url/ "title has spaces afterward" ). + + +[Empty](). diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, reference style.html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, reference style.html new file mode 100644 index 000000000..8e70c32f4 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, reference style.html @@ -0,0 +1,52 @@ +

Foo bar.

+ +

Foo bar.

+ +

Foo bar.

+ +

With embedded [brackets].

+ +

Indented once.

+ +

Indented twice.

+ +

Indented thrice.

+ +

Indented [four][] times.

+ +
[four]: /url
+
+ +
+ +

this should work

+ +

So should this.

+ +

And this.

+ +

And this.

+ +

And this.

+ +

But not [that] [].

+ +

Nor [that][].

+ +

Nor [that].

+ +

[Something in brackets like this should work]

+ +

[Same with this.]

+ +

In this case, this points to something else.

+ +

Backslashing should suppress [this] and [this].

+ +
+ +

Here's one where the link +breaks across lines.

+ +

Here's another where the link +breaks across lines, but with a line-ending space.

diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, reference style.text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, reference style.text new file mode 100644 index 000000000..341ec88e3 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, reference style.text @@ -0,0 +1,71 @@ +Foo [bar] [1]. + +Foo [bar][1]. + +Foo [bar] +[1]. + +[1]: /url/ "Title" + + +With [embedded [brackets]] [b]. + + +Indented [once][]. + +Indented [twice][]. + +Indented [thrice][]. + +Indented [four][] times. + + [once]: /url + + [twice]: /url + + [thrice]: /url + + [four]: /url + + +[b]: /url/ + +* * * + +[this] [this] should work + +So should [this][this]. + +And [this] []. + +And [this][]. + +And [this]. + +But not [that] []. + +Nor [that][]. + +Nor [that]. + +[Something in brackets like [this][] should work] + +[Same with [this].] + +In this case, [this](/somethingelse/) points to something else. + +Backslashing should suppress \[this] and [this\]. + +[this]: foo + + +* * * + +Here's one where the [link +breaks] across lines. + +Here's another where the [link +breaks] across lines, but with a line-ending space. + + +[link breaks]: /url/ diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, shortcut references.html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, shortcut references.html new file mode 100644 index 000000000..bf81e939f --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, shortcut references.html @@ -0,0 +1,9 @@ +

This is the simple case.

+ +

This one has a line +break.

+ +

This one has a line +break with a line-ending space.

+ +

this and the other

diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, shortcut references.text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, shortcut references.text new file mode 100644 index 000000000..8c44c98fe --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Links, shortcut references.text @@ -0,0 +1,20 @@ +This is the [simple case]. + +[simple case]: /simple + + + +This one has a [line +break]. + +This one has a [line +break] with a line-ending space. + +[line break]: /foo + + +[this] [that] and the [other] + +[this]: /this +[that]: /that +[other]: /other diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Literal quotes in titles.html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Literal quotes in titles.html new file mode 100644 index 000000000..611c1ac61 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Literal quotes in titles.html @@ -0,0 +1,3 @@ +

Foo bar.

+ +

Foo bar.

diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Literal quotes in titles.text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Literal quotes in titles.text new file mode 100644 index 000000000..29d0e4235 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Literal quotes in titles.text @@ -0,0 +1,7 @@ +Foo [bar][]. + +Foo [bar](/url/ "Title with "quotes" inside"). + + + [bar]: /url/ "Title with "quotes" inside" + diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.html new file mode 100644 index 000000000..d5bdbb29a --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.html @@ -0,0 +1,314 @@ +

Markdown: Basics

+ + + +

Getting the Gist of Markdown's Formatting Syntax

+ +

This page offers a brief overview of what it's like to use Markdown. +The syntax page provides complete, detailed documentation for +every feature, but Markdown should be very easy to pick up simply by +looking at a few examples of it in action. The examples on this page +are written in a before/after style, showing example syntax and the +HTML output produced by Markdown.

+ +

It's also helpful to simply try Markdown out; the Dingus is a +web application that allows you type your own Markdown-formatted text +and translate it to XHTML.

+ +

Note: This document is itself written using Markdown; you +can see the source for it by adding '.text' to the URL.

+ +

Paragraphs, Headers, Blockquotes

+ +

A paragraph is simply one or more consecutive lines of text, separated +by one or more blank lines. (A blank line is any line that looks like a +blank line -- a line containing nothing spaces or tabs is considered +blank.) Normal paragraphs should not be intended with spaces or tabs.

+ +

Markdown offers two styles of headers: Setext and atx. +Setext-style headers for <h1> and <h2> are created by +"underlining" with equal signs (=) and hyphens (-), respectively. +To create an atx-style header, you put 1-6 hash marks (#) at the +beginning of the line -- the number of hashes equals the resulting +HTML header level.

+ +

Blockquotes are indicated using email-style '>' angle brackets.

+ +

Markdown:

+ +
A First Level Header
+====================
+
+A Second Level Header
+---------------------
+
+Now is the time for all good men to come to
+the aid of their country. This is just a
+regular paragraph.
+
+The quick brown fox jumped over the lazy
+dog's back.
+
+### Header 3
+
+> This is a blockquote.
+> 
+> This is the second paragraph in the blockquote.
+>
+> ## This is an H2 in a blockquote
+
+ +

Output:

+ +
<h1>A First Level Header</h1>
+
+<h2>A Second Level Header</h2>
+
+<p>Now is the time for all good men to come to
+the aid of their country. This is just a
+regular paragraph.</p>
+
+<p>The quick brown fox jumped over the lazy
+dog's back.</p>
+
+<h3>Header 3</h3>
+
+<blockquote>
+    <p>This is a blockquote.</p>
+
+    <p>This is the second paragraph in the blockquote.</p>
+
+    <h2>This is an H2 in a blockquote</h2>
+</blockquote>
+
+ +

Phrase Emphasis

+ +

Markdown uses asterisks and underscores to indicate spans of emphasis.

+ +

Markdown:

+ +
Some of these words *are emphasized*.
+Some of these words _are emphasized also_.
+
+Use two asterisks for **strong emphasis**.
+Or, if you prefer, __use two underscores instead__.
+
+ +

Output:

+ +
<p>Some of these words <em>are emphasized</em>.
+Some of these words <em>are emphasized also</em>.</p>
+
+<p>Use two asterisks for <strong>strong emphasis</strong>.
+Or, if you prefer, <strong>use two underscores instead</strong>.</p>
+
+ +

Lists

+ +

Unordered (bulleted) lists use asterisks, pluses, and hyphens (*, ++, and -) as list markers. These three markers are +interchangable; this:

+ +
*   Candy.
+*   Gum.
+*   Booze.
+
+ +

this:

+ +
+   Candy.
++   Gum.
++   Booze.
+
+ +

and this:

+ +
-   Candy.
+-   Gum.
+-   Booze.
+
+ +

all produce the same output:

+ +
<ul>
+<li>Candy.</li>
+<li>Gum.</li>
+<li>Booze.</li>
+</ul>
+
+ +

Ordered (numbered) lists use regular numbers, followed by periods, as +list markers:

+ +
1.  Red
+2.  Green
+3.  Blue
+
+ +

Output:

+ +
<ol>
+<li>Red</li>
+<li>Green</li>
+<li>Blue</li>
+</ol>
+
+ +

If you put blank lines between items, you'll get <p> tags for the +list item text. You can create multi-paragraph list items by indenting +the paragraphs by 4 spaces or 1 tab:

+ +
*   A list item.
+
+    With multiple paragraphs.
+
+*   Another item in the list.
+
+ +

Output:

+ +
<ul>
+<li><p>A list item.</p>
+<p>With multiple paragraphs.</p></li>
+<li><p>Another item in the list.</p></li>
+</ul>
+
+ +

Links

+ +

Markdown supports two styles for creating links: inline and +reference. With both styles, you use square brackets to delimit the +text you want to turn into a link.

+ +

Inline-style links use parentheses immediately after the link text. +For example:

+ +
This is an [example link](http://example.com/).
+
+ +

Output:

+ +
<p>This is an <a href="http://example.com/">
+example link</a>.</p>
+
+ +

Optionally, you may include a title attribute in the parentheses:

+ +
This is an [example link](http://example.com/ "With a Title").
+
+ +

Output:

+ +
<p>This is an <a href="http://example.com/" title="With a Title">
+example link</a>.</p>
+
+ +

Reference-style links allow you to refer to your links by names, which +you define elsewhere in your document:

+ +
I get 10 times more traffic from [Google][1] than from
+[Yahoo][2] or [MSN][3].
+
+[1]: http://google.com/        "Google"
+[2]: http://search.yahoo.com/  "Yahoo Search"
+[3]: http://search.msn.com/    "MSN Search"
+
+ +

Output:

+ +
<p>I get 10 times more traffic from <a href="http://google.com/"
+title="Google">Google</a> than from <a href="http://search.yahoo.com/"
+title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/"
+title="MSN Search">MSN</a>.</p>
+
+ +

The title attribute is optional. Link names may contain letters, +numbers and spaces, but are not case sensitive:

+ +
I start my morning with a cup of coffee and
+[The New York Times][NY Times].
+
+[ny times]: http://www.nytimes.com/
+
+ +

Output:

+ +
<p>I start my morning with a cup of coffee and
+<a href="http://www.nytimes.com/">The New York Times</a>.</p>
+
+ +

Images

+ +

Image syntax is very much like link syntax.

+ +

Inline (titles are optional):

+ +
![alt text](/path/to/img.jpg "Title")
+
+ +

Reference-style:

+ +
![alt text][id]
+
+[id]: /path/to/img.jpg "Title"
+
+ +

Both of the above examples produce the same output:

+ +
<img src="/path/to/img.jpg" alt="alt text" title="Title" />
+
+ +

Code

+ +

In a regular paragraph, you can create code span by wrapping text in +backtick quotes. Any ampersands (&) and angle brackets (< or +>) will automatically be translated into HTML entities. This makes +it easy to use Markdown to write about HTML example code:

+ +
I strongly recommend against using any `<blink>` tags.
+
+I wish SmartyPants used named entities like `&mdash;`
+instead of decimal-encoded entites like `&#8212;`.
+
+ +

Output:

+ +
<p>I strongly recommend against using any
+<code>&lt;blink&gt;</code> tags.</p>
+
+<p>I wish SmartyPants used named entities like
+<code>&amp;mdash;</code> instead of decimal-encoded
+entites like <code>&amp;#8212;</code>.</p>
+
+ +

To specify an entire block of pre-formatted code, indent every line of +the block by 4 spaces or 1 tab. Just like with code spans, &, <, +and > characters will be escaped automatically.

+ +

Markdown:

+ +
If you want your page to validate under XHTML 1.0 Strict,
+you've got to put paragraph tags in your blockquotes:
+
+    <blockquote>
+        <p>For example.</p>
+    </blockquote>
+
+ +

Output:

+ +
<p>If you want your page to validate under XHTML 1.0 Strict,
+you've got to put paragraph tags in your blockquotes:</p>
+
+<pre><code>&lt;blockquote&gt;
+    &lt;p&gt;For example.&lt;/p&gt;
+&lt;/blockquote&gt;
+</code></pre>
+
diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.text new file mode 100644 index 000000000..486055ca7 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.text @@ -0,0 +1,306 @@ +Markdown: Basics +================ + + + + +Getting the Gist of Markdown's Formatting Syntax +------------------------------------------------ + +This page offers a brief overview of what it's like to use Markdown. +The [syntax page] [s] provides complete, detailed documentation for +every feature, but Markdown should be very easy to pick up simply by +looking at a few examples of it in action. The examples on this page +are written in a before/after style, showing example syntax and the +HTML output produced by Markdown. + +It's also helpful to simply try Markdown out; the [Dingus] [d] is a +web application that allows you type your own Markdown-formatted text +and translate it to XHTML. + +**Note:** This document is itself written using Markdown; you +can [see the source for it by adding '.text' to the URL] [src]. + + [s]: /projects/markdown/syntax "Markdown Syntax" + [d]: /projects/markdown/dingus "Markdown Dingus" + [src]: /projects/markdown/basics.text + + +## Paragraphs, Headers, Blockquotes ## + +A paragraph is simply one or more consecutive lines of text, separated +by one or more blank lines. (A blank line is any line that looks like a +blank line -- a line containing nothing spaces or tabs is considered +blank.) Normal paragraphs should not be intended with spaces or tabs. + +Markdown offers two styles of headers: *Setext* and *atx*. +Setext-style headers for `

` and `

` are created by +"underlining" with equal signs (`=`) and hyphens (`-`), respectively. +To create an atx-style header, you put 1-6 hash marks (`#`) at the +beginning of the line -- the number of hashes equals the resulting +HTML header level. + +Blockquotes are indicated using email-style '`>`' angle brackets. + +Markdown: + + A First Level Header + ==================== + + A Second Level Header + --------------------- + + Now is the time for all good men to come to + the aid of their country. This is just a + regular paragraph. + + The quick brown fox jumped over the lazy + dog's back. + + ### Header 3 + + > This is a blockquote. + > + > This is the second paragraph in the blockquote. + > + > ## This is an H2 in a blockquote + + +Output: + +

A First Level Header

+ +

A Second Level Header

+ +

Now is the time for all good men to come to + the aid of their country. This is just a + regular paragraph.

+ +

The quick brown fox jumped over the lazy + dog's back.

+ +

Header 3

+ +
+

This is a blockquote.

+ +

This is the second paragraph in the blockquote.

+ +

This is an H2 in a blockquote

+
+ + + +### Phrase Emphasis ### + +Markdown uses asterisks and underscores to indicate spans of emphasis. + +Markdown: + + Some of these words *are emphasized*. + Some of these words _are emphasized also_. + + Use two asterisks for **strong emphasis**. + Or, if you prefer, __use two underscores instead__. + +Output: + +

Some of these words are emphasized. + Some of these words are emphasized also.

+ +

Use two asterisks for strong emphasis. + Or, if you prefer, use two underscores instead.

+ + + +## Lists ## + +Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`, +`+`, and `-`) as list markers. These three markers are +interchangable; this: + + * Candy. + * Gum. + * Booze. + +this: + + + Candy. + + Gum. + + Booze. + +and this: + + - Candy. + - Gum. + - Booze. + +all produce the same output: + +
    +
  • Candy.
  • +
  • Gum.
  • +
  • Booze.
  • +
+ +Ordered (numbered) lists use regular numbers, followed by periods, as +list markers: + + 1. Red + 2. Green + 3. Blue + +Output: + +
    +
  1. Red
  2. +
  3. Green
  4. +
  5. Blue
  6. +
+ +If you put blank lines between items, you'll get `

` tags for the +list item text. You can create multi-paragraph list items by indenting +the paragraphs by 4 spaces or 1 tab: + + * A list item. + + With multiple paragraphs. + + * Another item in the list. + +Output: + +

    +
  • A list item.

    +

    With multiple paragraphs.

  • +
  • Another item in the list.

  • +
+ + + +### Links ### + +Markdown supports two styles for creating links: *inline* and +*reference*. With both styles, you use square brackets to delimit the +text you want to turn into a link. + +Inline-style links use parentheses immediately after the link text. +For example: + + This is an [example link](http://example.com/). + +Output: + +

This is an + example link.

+ +Optionally, you may include a title attribute in the parentheses: + + This is an [example link](http://example.com/ "With a Title"). + +Output: + +

This is an + example link.

+ +Reference-style links allow you to refer to your links by names, which +you define elsewhere in your document: + + I get 10 times more traffic from [Google][1] than from + [Yahoo][2] or [MSN][3]. + + [1]: http://google.com/ "Google" + [2]: http://search.yahoo.com/ "Yahoo Search" + [3]: http://search.msn.com/ "MSN Search" + +Output: + +

I get 10 times more traffic from Google than from Yahoo or MSN.

+ +The title attribute is optional. Link names may contain letters, +numbers and spaces, but are *not* case sensitive: + + I start my morning with a cup of coffee and + [The New York Times][NY Times]. + + [ny times]: http://www.nytimes.com/ + +Output: + +

I start my morning with a cup of coffee and + The New York Times.

+ + +### Images ### + +Image syntax is very much like link syntax. + +Inline (titles are optional): + + ![alt text](/path/to/img.jpg "Title") + +Reference-style: + + ![alt text][id] + + [id]: /path/to/img.jpg "Title" + +Both of the above examples produce the same output: + + alt text + + + +### Code ### + +In a regular paragraph, you can create code span by wrapping text in +backtick quotes. Any ampersands (`&`) and angle brackets (`<` or +`>`) will automatically be translated into HTML entities. This makes +it easy to use Markdown to write about HTML example code: + + I strongly recommend against using any `` tags. + + I wish SmartyPants used named entities like `—` + instead of decimal-encoded entites like `—`. + +Output: + +

I strongly recommend against using any + <blink> tags.

+ +

I wish SmartyPants used named entities like + &mdash; instead of decimal-encoded + entites like &#8212;.

+ + +To specify an entire block of pre-formatted code, indent every line of +the block by 4 spaces or 1 tab. Just like with code spans, `&`, `<`, +and `>` characters will be escaped automatically. + +Markdown: + + If you want your page to validate under XHTML 1.0 Strict, + you've got to put paragraph tags in your blockquotes: + +
+

For example.

+
+ +Output: + +

If you want your page to validate under XHTML 1.0 Strict, + you've got to put paragraph tags in your blockquotes:

+ +
<blockquote>
+        <p>For example.</p>
+    </blockquote>
+    
diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.html new file mode 100644 index 000000000..5c01306cc --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.html @@ -0,0 +1,942 @@ +

Markdown: Syntax

+ + + + + +

Note: This document is itself written using Markdown; you +can see the source for it by adding '.text' to the URL.

+ +
+ +

Overview

+ +

Philosophy

+ +

Markdown is intended to be as easy-to-read and easy-to-write as is feasible.

+ +

Readability, however, is emphasized above all else. A Markdown-formatted +document should be publishable as-is, as plain text, without looking +like it's been marked up with tags or formatting instructions. While +Markdown's syntax has been influenced by several existing text-to-HTML +filters -- including Setext, atx, Textile, reStructuredText, +Grutatext, and EtText -- the single biggest source of +inspiration for Markdown's syntax is the format of plain text email.

+ +

To this end, Markdown's syntax is comprised entirely of punctuation +characters, which punctuation characters have been carefully chosen so +as to look like what they mean. E.g., asterisks around a word actually +look like *emphasis*. Markdown lists look like, well, lists. Even +blockquotes look like quoted passages of text, assuming you've ever +used email.

+ +

Inline HTML

+ +

Markdown's syntax is intended for one purpose: to be used as a +format for writing for the web.

+ +

Markdown is not a replacement for HTML, or even close to it. Its +syntax is very small, corresponding only to a very small subset of +HTML tags. The idea is not to create a syntax that makes it easier +to insert HTML tags. In my opinion, HTML tags are already easy to +insert. The idea for Markdown is to make it easy to read, write, and +edit prose. HTML is a publishing format; Markdown is a writing +format. Thus, Markdown's formatting syntax only addresses issues that +can be conveyed in plain text.

+ +

For any markup that is not covered by Markdown's syntax, you simply +use HTML itself. There's no need to preface it or delimit it to +indicate that you're switching from Markdown to HTML; you just use +the tags.

+ +

The only restrictions are that block-level HTML elements -- e.g. <div>, +<table>, <pre>, <p>, etc. -- must be separated from surrounding +content by blank lines, and the start and end tags of the block should +not be indented with tabs or spaces. Markdown is smart enough not +to add extra (unwanted) <p> tags around HTML block-level tags.

+ +

For example, to add an HTML table to a Markdown article:

+ +
This is a regular paragraph.
+
+<table>
+    <tr>
+        <td>Foo</td>
+    </tr>
+</table>
+
+This is another regular paragraph.
+
+ +

Note that Markdown formatting syntax is not processed within block-level +HTML tags. E.g., you can't use Markdown-style *emphasis* inside an +HTML block.

+ +

Span-level HTML tags -- e.g. <span>, <cite>, or <del> -- can be +used anywhere in a Markdown paragraph, list item, or header. If you +want, you can even use HTML tags instead of Markdown formatting; e.g. if +you'd prefer to use HTML <a> or <img> tags instead of Markdown's +link or image syntax, go right ahead.

+ +

Unlike block-level HTML tags, Markdown syntax is processed within +span-level tags.

+ +

Automatic Escaping for Special Characters

+ +

In HTML, there are two characters that demand special treatment: < +and &. Left angle brackets are used to start tags; ampersands are +used to denote HTML entities. If you want to use them as literal +characters, you must escape them as entities, e.g. &lt;, and +&amp;.

+ +

Ampersands in particular are bedeviling for web writers. If you want to +write about 'AT&T', you need to write 'AT&amp;T'. You even need to +escape ampersands within URLs. Thus, if you want to link to:

+ +
http://images.google.com/images?num=30&q=larry+bird
+
+ +

you need to encode the URL as:

+ +
http://images.google.com/images?num=30&amp;q=larry+bird
+
+ +

in your anchor tag href attribute. Needless to say, this is easy to +forget, and is probably the single most common source of HTML validation +errors in otherwise well-marked-up web sites.

+ +

Markdown allows you to use these characters naturally, taking care of +all the necessary escaping for you. If you use an ampersand as part of +an HTML entity, it remains unchanged; otherwise it will be translated +into &amp;.

+ +

So, if you want to include a copyright symbol in your article, you can write:

+ +
&copy;
+
+ +

and Markdown will leave it alone. But if you write:

+ +
AT&T
+
+ +

Markdown will translate it to:

+ +
AT&amp;T
+
+ +

Similarly, because Markdown supports inline HTML, if you use +angle brackets as delimiters for HTML tags, Markdown will treat them as +such. But if you write:

+ +
4 < 5
+
+ +

Markdown will translate it to:

+ +
4 &lt; 5
+
+ +

However, inside Markdown code spans and blocks, angle brackets and +ampersands are always encoded automatically. This makes it easy to use +Markdown to write about HTML code. (As opposed to raw HTML, which is a +terrible format for writing about HTML syntax, because every single < +and & in your example code needs to be escaped.)

+ +
+ +

Block Elements

+ +

Paragraphs and Line Breaks

+ +

A paragraph is simply one or more consecutive lines of text, separated +by one or more blank lines. (A blank line is any line that looks like a +blank line -- a line containing nothing but spaces or tabs is considered +blank.) Normal paragraphs should not be intended with spaces or tabs.

+ +

The implication of the "one or more consecutive lines of text" rule is +that Markdown supports "hard-wrapped" text paragraphs. This differs +significantly from most other text-to-HTML formatters (including Movable +Type's "Convert Line Breaks" option) which translate every line break +character in a paragraph into a <br /> tag.

+ +

When you do want to insert a <br /> break tag using Markdown, you +end a line with two or more spaces, then type return.

+ +

Yes, this takes a tad more effort to create a <br />, but a simplistic +"every line break is a <br />" rule wouldn't work for Markdown. +Markdown's email-style blockquoting and multi-paragraph list items +work best -- and look better -- when you format them with hard breaks.

+ + + +

Markdown supports two styles of headers, Setext and atx.

+ +

Setext-style headers are "underlined" using equal signs (for first-level +headers) and dashes (for second-level headers). For example:

+ +
This is an H1
+=============
+
+This is an H2
+-------------
+
+ +

Any number of underlining ='s or -'s will work.

+ +

Atx-style headers use 1-6 hash characters at the start of the line, +corresponding to header levels 1-6. For example:

+ +
# This is an H1
+
+## This is an H2
+
+###### This is an H6
+
+ +

Optionally, you may "close" atx-style headers. This is purely +cosmetic -- you can use this if you think it looks better. The +closing hashes don't even need to match the number of hashes +used to open the header. (The number of opening hashes +determines the header level.) :

+ +
# This is an H1 #
+
+## This is an H2 ##
+
+### This is an H3 ######
+
+ +

Blockquotes

+ +

Markdown uses email-style > characters for blockquoting. If you're +familiar with quoting passages of text in an email message, then you +know how to create a blockquote in Markdown. It looks best if you hard +wrap the text and put a > before every line:

+ +
> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
+> consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
+> Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
+> 
+> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
+> id sem consectetuer libero luctus adipiscing.
+
+ +

Markdown allows you to be lazy and only put the > before the first +line of a hard-wrapped paragraph:

+ +
> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
+consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
+Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
+
+> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
+id sem consectetuer libero luctus adipiscing.
+
+ +

Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by +adding additional levels of >:

+ +
> This is the first level of quoting.
+>
+> > This is nested blockquote.
+>
+> Back to the first level.
+
+ +

Blockquotes can contain other Markdown elements, including headers, lists, +and code blocks:

+ +
> ## This is a header.
+> 
+> 1.   This is the first list item.
+> 2.   This is the second list item.
+> 
+> Here's some example code:
+> 
+>     return shell_exec("echo $input | $markdown_script");
+
+ +

Any decent text editor should make email-style quoting easy. For +example, with BBEdit, you can make a selection and choose Increase +Quote Level from the Text menu.

+ +

Lists

+ +

Markdown supports ordered (numbered) and unordered (bulleted) lists.

+ +

Unordered lists use asterisks, pluses, and hyphens -- interchangably +-- as list markers:

+ +
*   Red
+*   Green
+*   Blue
+
+ +

is equivalent to:

+ +
+   Red
++   Green
++   Blue
+
+ +

and:

+ +
-   Red
+-   Green
+-   Blue
+
+ +

Ordered lists use numbers followed by periods:

+ +
1.  Bird
+2.  McHale
+3.  Parish
+
+ +

It's important to note that the actual numbers you use to mark the +list have no effect on the HTML output Markdown produces. The HTML +Markdown produces from the above list is:

+ +
<ol>
+<li>Bird</li>
+<li>McHale</li>
+<li>Parish</li>
+</ol>
+
+ +

If you instead wrote the list in Markdown like this:

+ +
1.  Bird
+1.  McHale
+1.  Parish
+
+ +

or even:

+ +
3. Bird
+1. McHale
+8. Parish
+
+ +

you'd get the exact same HTML output. The point is, if you want to, +you can use ordinal numbers in your ordered Markdown lists, so that +the numbers in your source match the numbers in your published HTML. +But if you want to be lazy, you don't have to.

+ +

If you do use lazy list numbering, however, you should still start the +list with the number 1. At some point in the future, Markdown may support +starting ordered lists at an arbitrary number.

+ +

List markers typically start at the left margin, but may be indented by +up to three spaces. List markers must be followed by one or more spaces +or a tab.

+ +

To make lists look nice, you can wrap items with hanging indents:

+ +
*   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+    Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
+    viverra nec, fringilla in, laoreet vitae, risus.
+*   Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
+    Suspendisse id sem consectetuer libero luctus adipiscing.
+
+ +

But if you want to be lazy, you don't have to:

+ +
*   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
+viverra nec, fringilla in, laoreet vitae, risus.
+*   Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
+Suspendisse id sem consectetuer libero luctus adipiscing.
+
+ +

If list items are separated by blank lines, Markdown will wrap the +items in <p> tags in the HTML output. For example, this input:

+ +
*   Bird
+*   Magic
+
+ +

will turn into:

+ +
<ul>
+<li>Bird</li>
+<li>Magic</li>
+</ul>
+
+ +

But this:

+ +
*   Bird
+
+*   Magic
+
+ +

will turn into:

+ +
<ul>
+<li><p>Bird</p></li>
+<li><p>Magic</p></li>
+</ul>
+
+ +

List items may consist of multiple paragraphs. Each subsequent +paragraph in a list item must be intended by either 4 spaces +or one tab:

+ +
1.  This is a list item with two paragraphs. Lorem ipsum dolor
+    sit amet, consectetuer adipiscing elit. Aliquam hendrerit
+    mi posuere lectus.
+
+    Vestibulum enim wisi, viverra nec, fringilla in, laoreet
+    vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
+    sit amet velit.
+
+2.  Suspendisse id sem consectetuer libero luctus adipiscing.
+
+ +

It looks nice if you indent every line of the subsequent +paragraphs, but here again, Markdown will allow you to be +lazy:

+ +
*   This is a list item with two paragraphs.
+
+    This is the second paragraph in the list item. You're
+only required to indent the first line. Lorem ipsum dolor
+sit amet, consectetuer adipiscing elit.
+
+*   Another item in the same list.
+
+ +

To put a blockquote within a list item, the blockquote's > +delimiters need to be indented:

+ +
*   A list item with a blockquote:
+
+    > This is a blockquote
+    > inside a list item.
+
+ +

To put a code block within a list item, the code block needs +to be indented twice -- 8 spaces or two tabs:

+ +
*   A list item with a code block:
+
+        <code goes here>
+
+ +

It's worth noting that it's possible to trigger an ordered list by +accident, by writing something like this:

+ +
1986. What a great season.
+
+ +

In other words, a number-period-space sequence at the beginning of a +line. To avoid this, you can backslash-escape the period:

+ +
1986\. What a great season.
+
+ +

Code Blocks

+ +

Pre-formatted code blocks are used for writing about programming or +markup source code. Rather than forming normal paragraphs, the lines +of a code block are interpreted literally. Markdown wraps a code block +in both <pre> and <code> tags.

+ +

To produce a code block in Markdown, simply indent every line of the +block by at least 4 spaces or 1 tab. For example, given this input:

+ +
This is a normal paragraph:
+
+    This is a code block.
+
+ +

Markdown will generate:

+ +
<p>This is a normal paragraph:</p>
+
+<pre><code>This is a code block.
+</code></pre>
+
+ +

One level of indentation -- 4 spaces or 1 tab -- is removed from each +line of the code block. For example, this:

+ +
Here is an example of AppleScript:
+
+    tell application "Foo"
+        beep
+    end tell
+
+ +

will turn into:

+ +
<p>Here is an example of AppleScript:</p>
+
+<pre><code>tell application "Foo"
+    beep
+end tell
+</code></pre>
+
+ +

A code block continues until it reaches a line that is not indented +(or the end of the article).

+ +

Within a code block, ampersands (&) and angle brackets (< and >) +are automatically converted into HTML entities. This makes it very +easy to include example HTML source code using Markdown -- just paste +it and indent it, and Markdown will handle the hassle of encoding the +ampersands and angle brackets. For example, this:

+ +
    <div class="footer">
+        &copy; 2004 Foo Corporation
+    </div>
+
+ +

will turn into:

+ +
<pre><code>&lt;div class="footer"&gt;
+    &amp;copy; 2004 Foo Corporation
+&lt;/div&gt;
+</code></pre>
+
+ +

Regular Markdown syntax is not processed within code blocks. E.g., +asterisks are just literal asterisks within a code block. This means +it's also easy to use Markdown to write about Markdown's own syntax.

+ +

Horizontal Rules

+ +

You can produce a horizontal rule tag (<hr />) by placing three or +more hyphens, asterisks, or underscores on a line by themselves. If you +wish, you may use spaces between the hyphens or asterisks. Each of the +following lines will produce a horizontal rule:

+ +
* * *
+
+***
+
+*****
+
+- - -
+
+---------------------------------------
+
+_ _ _
+
+ +
+ +

Span Elements

+ + + +

Markdown supports two style of links: inline and reference.

+ +

In both styles, the link text is delimited by [square brackets].

+ +

To create an inline link, use a set of regular parentheses immediately +after the link text's closing square bracket. Inside the parentheses, +put the URL where you want the link to point, along with an optional +title for the link, surrounded in quotes. For example:

+ +
This is [an example](http://example.com/ "Title") inline link.
+
+[This link](http://example.net/) has no title attribute.
+
+ +

Will produce:

+ +
<p>This is <a href="http://example.com/" title="Title">
+an example</a> inline link.</p>
+
+<p><a href="http://example.net/">This link</a> has no
+title attribute.</p>
+
+ +

If you're referring to a local resource on the same server, you can +use relative paths:

+ +
See my [About](/about/) page for details.
+
+ +

Reference-style links use a second set of square brackets, inside +which you place a label of your choosing to identify the link:

+ +
This is [an example][id] reference-style link.
+
+ +

You can optionally use a space to separate the sets of brackets:

+ +
This is [an example] [id] reference-style link.
+
+ +

Then, anywhere in the document, you define your link label like this, +on a line by itself:

+ +
[id]: http://example.com/  "Optional Title Here"
+
+ +

That is:

+ +
    +
  • Square brackets containing the link identifier (optionally +indented from the left margin using up to three spaces);
  • +
  • followed by a colon;
  • +
  • followed by one or more spaces (or tabs);
  • +
  • followed by the URL for the link;
  • +
  • optionally followed by a title attribute for the link, enclosed +in double or single quotes.
  • +
+ +

The link URL may, optionally, be surrounded by angle brackets:

+ +
[id]: <http://example.com/>  "Optional Title Here"
+
+ +

You can put the title attribute on the next line and use extra spaces +or tabs for padding, which tends to look better with longer URLs:

+ +
[id]: http://example.com/longish/path/to/resource/here
+    "Optional Title Here"
+
+ +

Link definitions are only used for creating links during Markdown +processing, and are stripped from your document in the HTML output.

+ +

Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are not case sensitive. E.g. these two links:

+ +
[link text][a]
+[link text][A]
+
+ +

are equivalent.

+ +

The implicit link name shortcut allows you to omit the name of the +link, in which case the link text itself is used as the name. +Just use an empty set of square brackets -- e.g., to link the word +"Google" to the google.com web site, you could simply write:

+ +
[Google][]
+
+ +

And then define the link:

+ +
[Google]: http://google.com/
+
+ +

Because link names may contain spaces, this shortcut even works for +multiple words in the link text:

+ +
Visit [Daring Fireball][] for more information.
+
+ +

And then define the link:

+ +
[Daring Fireball]: http://daringfireball.net/
+
+ +

Link definitions can be placed anywhere in your Markdown document. I +tend to put them immediately after each paragraph in which they're +used, but if you want, you can put them all at the end of your +document, sort of like footnotes.

+ +

Here's an example of reference links in action:

+ +
I get 10 times more traffic from [Google] [1] than from
+[Yahoo] [2] or [MSN] [3].
+
+  [1]: http://google.com/        "Google"
+  [2]: http://search.yahoo.com/  "Yahoo Search"
+  [3]: http://search.msn.com/    "MSN Search"
+
+ +

Using the implicit link name shortcut, you could instead write:

+ +
I get 10 times more traffic from [Google][] than from
+[Yahoo][] or [MSN][].
+
+  [google]: http://google.com/        "Google"
+  [yahoo]:  http://search.yahoo.com/  "Yahoo Search"
+  [msn]:    http://search.msn.com/    "MSN Search"
+
+ +

Both of the above examples will produce the following HTML output:

+ +
<p>I get 10 times more traffic from <a href="http://google.com/"
+title="Google">Google</a> than from
+<a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a>
+or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>
+
+ +

For comparison, here is the same paragraph written using +Markdown's inline link style:

+ +
I get 10 times more traffic from [Google](http://google.com/ "Google")
+than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or
+[MSN](http://search.msn.com/ "MSN Search").
+
+ +

The point of reference-style links is not that they're easier to +write. The point is that with reference-style links, your document +source is vastly more readable. Compare the above examples: using +reference-style links, the paragraph itself is only 81 characters +long; with inline-style links, it's 176 characters; and as raw HTML, +it's 234 characters. In the raw HTML, there's more markup than there +is text.

+ +

With Markdown's reference-style links, a source document much more +closely resembles the final output, as rendered in a browser. By +allowing you to move the markup-related metadata out of the paragraph, +you can add links without interrupting the narrative flow of your +prose.

+ +

Emphasis

+ +

Markdown treats asterisks (*) and underscores (_) as indicators of +emphasis. Text wrapped with one * or _ will be wrapped with an +HTML <em> tag; double *'s or _'s will be wrapped with an HTML +<strong> tag. E.g., this input:

+ +
*single asterisks*
+
+_single underscores_
+
+**double asterisks**
+
+__double underscores__
+
+ +

will produce:

+ +
<em>single asterisks</em>
+
+<em>single underscores</em>
+
+<strong>double asterisks</strong>
+
+<strong>double underscores</strong>
+
+ +

You can use whichever style you prefer; the lone restriction is that +the same character must be used to open and close an emphasis span.

+ +

Emphasis can be used in the middle of a word:

+ +
un*fucking*believable
+
+ +

But if you surround an * or _ with spaces, it'll be treated as a +literal asterisk or underscore.

+ +

To produce a literal asterisk or underscore at a position where it +would otherwise be used as an emphasis delimiter, you can backslash +escape it:

+ +
\*this text is surrounded by literal asterisks\*
+
+ +

Code

+ +

To indicate a span of code, wrap it with backtick quotes (`). +Unlike a pre-formatted code block, a code span indicates code within a +normal paragraph. For example:

+ +
Use the `printf()` function.
+
+ +

will produce:

+ +
<p>Use the <code>printf()</code> function.</p>
+
+ +

To include a literal backtick character within a code span, you can use +multiple backticks as the opening and closing delimiters:

+ +
``There is a literal backtick (`) here.``
+
+ +

which will produce this:

+ +
<p><code>There is a literal backtick (`) here.</code></p>
+
+ +

The backtick delimiters surrounding a code span may include spaces -- +one after the opening, one before the closing. This allows you to place +literal backtick characters at the beginning or end of a code span:

+ +
A single backtick in a code span: `` ` ``
+
+A backtick-delimited string in a code span: `` `foo` ``
+
+ +

will produce:

+ +
<p>A single backtick in a code span: <code>`</code></p>
+
+<p>A backtick-delimited string in a code span: <code>`foo`</code></p>
+
+ +

With a code span, ampersands and angle brackets are encoded as HTML +entities automatically, which makes it easy to include example HTML +tags. Markdown will turn this:

+ +
Please don't use any `<blink>` tags.
+
+ +

into:

+ +
<p>Please don't use any <code>&lt;blink&gt;</code> tags.</p>
+
+ +

You can write this:

+ +
`&#8212;` is the decimal-encoded equivalent of `&mdash;`.
+
+ +

to produce:

+ +
<p><code>&amp;#8212;</code> is the decimal-encoded
+equivalent of <code>&amp;mdash;</code>.</p>
+
+ +

Images

+ +

Admittedly, it's fairly difficult to devise a "natural" syntax for +placing images into a plain text document format.

+ +

Markdown uses an image syntax that is intended to resemble the syntax +for links, allowing for two styles: inline and reference.

+ +

Inline image syntax looks like this:

+ +
![Alt text](/path/to/img.jpg)
+
+![Alt text](/path/to/img.jpg "Optional title")
+
+ +

That is:

+ +
    +
  • An exclamation mark: !;
  • +
  • followed by a set of square brackets, containing the alt +attribute text for the image;
  • +
  • followed by a set of parentheses, containing the URL or path to +the image, and an optional title attribute enclosed in double +or single quotes.
  • +
+ +

Reference-style image syntax looks like this:

+ +
![Alt text][id]
+
+ +

Where "id" is the name of a defined image reference. Image references +are defined using syntax identical to link references:

+ +
[id]: url/to/image  "Optional title attribute"
+
+ +

As of this writing, Markdown has no syntax for specifying the +dimensions of an image; if this is important to you, you can simply +use regular HTML <img> tags.

+ +
+ +

Miscellaneous

+ + + +

Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this:

+ +
<http://example.com/>
+
+ +

Markdown will turn this into:

+ +
<a href="http://example.com/">http://example.com/</a>
+
+ +

Automatic links for email addresses work similarly, except that +Markdown will also perform a bit of randomized decimal and hex +entity-encoding to help obscure your address from address-harvesting +spambots. For example, Markdown will turn this:

+ +
<address@example.com>
+
+ +

into something like this:

+ +
<a href="&#x6D;&#x61;i&#x6C;&#x74;&#x6F;:&#x61;&#x64;&#x64;&#x72;&#x65;
+&#115;&#115;&#64;&#101;&#120;&#x61;&#109;&#x70;&#x6C;e&#x2E;&#99;&#111;
+&#109;">&#x61;&#x64;&#x64;&#x72;&#x65;&#115;&#115;&#64;&#101;&#120;&#x61;
+&#109;&#x70;&#x6C;e&#x2E;&#99;&#111;&#109;</a>
+
+ +

which will render in a browser as a clickable link to "address@example.com".

+ +

(This sort of entity-encoding trick will indeed fool many, if not +most, address-harvesting bots, but it definitely won't fool all of +them. It's better than nothing, but an address published in this way +will probably eventually start receiving spam.)

+ +

Backslash Escapes

+ +

Markdown allows you to use backslash escapes to generate literal +characters which would otherwise have special meaning in Markdown's +formatting syntax. For example, if you wanted to surround a word with +literal asterisks (instead of an HTML <em> tag), you can backslashes +before the asterisks, like this:

+ +
\*literal asterisks\*
+
+ +

Markdown provides backslash escapes for the following characters:

+ +
\   backslash
+`   backtick
+*   asterisk
+_   underscore
+{}  curly braces
+[]  square brackets
+()  parentheses
+#   hash mark
++   plus sign
+-   minus sign (hyphen)
+.   dot
+!   exclamation mark
+
diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.text new file mode 100644 index 000000000..57360a16c --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.text @@ -0,0 +1,888 @@ +Markdown: Syntax +================ + + + + +* [Overview](#overview) + * [Philosophy](#philosophy) + * [Inline HTML](#html) + * [Automatic Escaping for Special Characters](#autoescape) +* [Block Elements](#block) + * [Paragraphs and Line Breaks](#p) + * [Headers](#header) + * [Blockquotes](#blockquote) + * [Lists](#list) + * [Code Blocks](#precode) + * [Horizontal Rules](#hr) +* [Span Elements](#span) + * [Links](#link) + * [Emphasis](#em) + * [Code](#code) + * [Images](#img) +* [Miscellaneous](#misc) + * [Backslash Escapes](#backslash) + * [Automatic Links](#autolink) + + +**Note:** This document is itself written using Markdown; you +can [see the source for it by adding '.text' to the URL][src]. + + [src]: /projects/markdown/syntax.text + +* * * + +

Overview

+ +

Philosophy

+ +Markdown is intended to be as easy-to-read and easy-to-write as is feasible. + +Readability, however, is emphasized above all else. A Markdown-formatted +document should be publishable as-is, as plain text, without looking +like it's been marked up with tags or formatting instructions. While +Markdown's syntax has been influenced by several existing text-to-HTML +filters -- including [Setext] [1], [atx] [2], [Textile] [3], [reStructuredText] [4], +[Grutatext] [5], and [EtText] [6] -- the single biggest source of +inspiration for Markdown's syntax is the format of plain text email. + + [1]: http://docutils.sourceforge.net/mirror/setext.html + [2]: http://www.aaronsw.com/2002/atx/ + [3]: http://textism.com/tools/textile/ + [4]: http://docutils.sourceforge.net/rst.html + [5]: http://www.triptico.com/software/grutatxt.html + [6]: http://ettext.taint.org/doc/ + +To this end, Markdown's syntax is comprised entirely of punctuation +characters, which punctuation characters have been carefully chosen so +as to look like what they mean. E.g., asterisks around a word actually +look like \*emphasis\*. Markdown lists look like, well, lists. Even +blockquotes look like quoted passages of text, assuming you've ever +used email. + + + +

Inline HTML

+ +Markdown's syntax is intended for one purpose: to be used as a +format for *writing* for the web. + +Markdown is not a replacement for HTML, or even close to it. Its +syntax is very small, corresponding only to a very small subset of +HTML tags. The idea is *not* to create a syntax that makes it easier +to insert HTML tags. In my opinion, HTML tags are already easy to +insert. The idea for Markdown is to make it easy to read, write, and +edit prose. HTML is a *publishing* format; Markdown is a *writing* +format. Thus, Markdown's formatting syntax only addresses issues that +can be conveyed in plain text. + +For any markup that is not covered by Markdown's syntax, you simply +use HTML itself. There's no need to preface it or delimit it to +indicate that you're switching from Markdown to HTML; you just use +the tags. + +The only restrictions are that block-level HTML elements -- e.g. `
`, +``, `
`, `

`, etc. -- must be separated from surrounding +content by blank lines, and the start and end tags of the block should +not be indented with tabs or spaces. Markdown is smart enough not +to add extra (unwanted) `

` tags around HTML block-level tags. + +For example, to add an HTML table to a Markdown article: + + This is a regular paragraph. + +

+ + + +
Foo
+ + This is another regular paragraph. + +Note that Markdown formatting syntax is not processed within block-level +HTML tags. E.g., you can't use Markdown-style `*emphasis*` inside an +HTML block. + +Span-level HTML tags -- e.g. ``, ``, or `` -- can be +used anywhere in a Markdown paragraph, list item, or header. If you +want, you can even use HTML tags instead of Markdown formatting; e.g. if +you'd prefer to use HTML `` or `` tags instead of Markdown's +link or image syntax, go right ahead. + +Unlike block-level HTML tags, Markdown syntax *is* processed within +span-level tags. + + +

Automatic Escaping for Special Characters

+ +In HTML, there are two characters that demand special treatment: `<` +and `&`. Left angle brackets are used to start tags; ampersands are +used to denote HTML entities. If you want to use them as literal +characters, you must escape them as entities, e.g. `<`, and +`&`. + +Ampersands in particular are bedeviling for web writers. If you want to +write about 'AT&T', you need to write '`AT&T`'. You even need to +escape ampersands within URLs. Thus, if you want to link to: + + http://images.google.com/images?num=30&q=larry+bird + +you need to encode the URL as: + + http://images.google.com/images?num=30&q=larry+bird + +in your anchor tag `href` attribute. Needless to say, this is easy to +forget, and is probably the single most common source of HTML validation +errors in otherwise well-marked-up web sites. + +Markdown allows you to use these characters naturally, taking care of +all the necessary escaping for you. If you use an ampersand as part of +an HTML entity, it remains unchanged; otherwise it will be translated +into `&`. + +So, if you want to include a copyright symbol in your article, you can write: + + © + +and Markdown will leave it alone. But if you write: + + AT&T + +Markdown will translate it to: + + AT&T + +Similarly, because Markdown supports [inline HTML](#html), if you use +angle brackets as delimiters for HTML tags, Markdown will treat them as +such. But if you write: + + 4 < 5 + +Markdown will translate it to: + + 4 < 5 + +However, inside Markdown code spans and blocks, angle brackets and +ampersands are *always* encoded automatically. This makes it easy to use +Markdown to write about HTML code. (As opposed to raw HTML, which is a +terrible format for writing about HTML syntax, because every single `<` +and `&` in your example code needs to be escaped.) + + +* * * + + +

Block Elements

+ + +

Paragraphs and Line Breaks

+ +A paragraph is simply one or more consecutive lines of text, separated +by one or more blank lines. (A blank line is any line that looks like a +blank line -- a line containing nothing but spaces or tabs is considered +blank.) Normal paragraphs should not be intended with spaces or tabs. + +The implication of the "one or more consecutive lines of text" rule is +that Markdown supports "hard-wrapped" text paragraphs. This differs +significantly from most other text-to-HTML formatters (including Movable +Type's "Convert Line Breaks" option) which translate every line break +character in a paragraph into a `
` tag. + +When you *do* want to insert a `
` break tag using Markdown, you +end a line with two or more spaces, then type return. + +Yes, this takes a tad more effort to create a `
`, but a simplistic +"every line break is a `
`" rule wouldn't work for Markdown. +Markdown's email-style [blockquoting][bq] and multi-paragraph [list items][l] +work best -- and look better -- when you format them with hard breaks. + + [bq]: #blockquote + [l]: #list + + + + + +Markdown supports two styles of headers, [Setext] [1] and [atx] [2]. + +Setext-style headers are "underlined" using equal signs (for first-level +headers) and dashes (for second-level headers). For example: + + This is an H1 + ============= + + This is an H2 + ------------- + +Any number of underlining `=`'s or `-`'s will work. + +Atx-style headers use 1-6 hash characters at the start of the line, +corresponding to header levels 1-6. For example: + + # This is an H1 + + ## This is an H2 + + ###### This is an H6 + +Optionally, you may "close" atx-style headers. This is purely +cosmetic -- you can use this if you think it looks better. The +closing hashes don't even need to match the number of hashes +used to open the header. (The number of opening hashes +determines the header level.) : + + # This is an H1 # + + ## This is an H2 ## + + ### This is an H3 ###### + + +

Blockquotes

+ +Markdown uses email-style `>` characters for blockquoting. If you're +familiar with quoting passages of text in an email message, then you +know how to create a blockquote in Markdown. It looks best if you hard +wrap the text and put a `>` before every line: + + > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, + > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. + > Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. + > + > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse + > id sem consectetuer libero luctus adipiscing. + +Markdown allows you to be lazy and only put the `>` before the first +line of a hard-wrapped paragraph: + + > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet, + consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. + Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus. + + > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse + id sem consectetuer libero luctus adipiscing. + +Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by +adding additional levels of `>`: + + > This is the first level of quoting. + > + > > This is nested blockquote. + > + > Back to the first level. + +Blockquotes can contain other Markdown elements, including headers, lists, +and code blocks: + + > ## This is a header. + > + > 1. This is the first list item. + > 2. This is the second list item. + > + > Here's some example code: + > + > return shell_exec("echo $input | $markdown_script"); + +Any decent text editor should make email-style quoting easy. For +example, with BBEdit, you can make a selection and choose Increase +Quote Level from the Text menu. + + +

Lists

+ +Markdown supports ordered (numbered) and unordered (bulleted) lists. + +Unordered lists use asterisks, pluses, and hyphens -- interchangably +-- as list markers: + + * Red + * Green + * Blue + +is equivalent to: + + + Red + + Green + + Blue + +and: + + - Red + - Green + - Blue + +Ordered lists use numbers followed by periods: + + 1. Bird + 2. McHale + 3. Parish + +It's important to note that the actual numbers you use to mark the +list have no effect on the HTML output Markdown produces. The HTML +Markdown produces from the above list is: + +
    +
  1. Bird
  2. +
  3. McHale
  4. +
  5. Parish
  6. +
+ +If you instead wrote the list in Markdown like this: + + 1. Bird + 1. McHale + 1. Parish + +or even: + + 3. Bird + 1. McHale + 8. Parish + +you'd get the exact same HTML output. The point is, if you want to, +you can use ordinal numbers in your ordered Markdown lists, so that +the numbers in your source match the numbers in your published HTML. +But if you want to be lazy, you don't have to. + +If you do use lazy list numbering, however, you should still start the +list with the number 1. At some point in the future, Markdown may support +starting ordered lists at an arbitrary number. + +List markers typically start at the left margin, but may be indented by +up to three spaces. List markers must be followed by one or more spaces +or a tab. + +To make lists look nice, you can wrap items with hanging indents: + + * Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, + viverra nec, fringilla in, laoreet vitae, risus. + * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. + Suspendisse id sem consectetuer libero luctus adipiscing. + +But if you want to be lazy, you don't have to: + + * Lorem ipsum dolor sit amet, consectetuer adipiscing elit. + Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, + viverra nec, fringilla in, laoreet vitae, risus. + * Donec sit amet nisl. Aliquam semper ipsum sit amet velit. + Suspendisse id sem consectetuer libero luctus adipiscing. + +If list items are separated by blank lines, Markdown will wrap the +items in `

` tags in the HTML output. For example, this input: + + * Bird + * Magic + +will turn into: + +

    +
  • Bird
  • +
  • Magic
  • +
+ +But this: + + * Bird + + * Magic + +will turn into: + +
    +
  • Bird

  • +
  • Magic

  • +
+ +List items may consist of multiple paragraphs. Each subsequent +paragraph in a list item must be intended by either 4 spaces +or one tab: + + 1. This is a list item with two paragraphs. Lorem ipsum dolor + sit amet, consectetuer adipiscing elit. Aliquam hendrerit + mi posuere lectus. + + Vestibulum enim wisi, viverra nec, fringilla in, laoreet + vitae, risus. Donec sit amet nisl. Aliquam semper ipsum + sit amet velit. + + 2. Suspendisse id sem consectetuer libero luctus adipiscing. + +It looks nice if you indent every line of the subsequent +paragraphs, but here again, Markdown will allow you to be +lazy: + + * This is a list item with two paragraphs. + + This is the second paragraph in the list item. You're + only required to indent the first line. Lorem ipsum dolor + sit amet, consectetuer adipiscing elit. + + * Another item in the same list. + +To put a blockquote within a list item, the blockquote's `>` +delimiters need to be indented: + + * A list item with a blockquote: + + > This is a blockquote + > inside a list item. + +To put a code block within a list item, the code block needs +to be indented *twice* -- 8 spaces or two tabs: + + * A list item with a code block: + + + + +It's worth noting that it's possible to trigger an ordered list by +accident, by writing something like this: + + 1986. What a great season. + +In other words, a *number-period-space* sequence at the beginning of a +line. To avoid this, you can backslash-escape the period: + + 1986\. What a great season. + + + +

Code Blocks

+ +Pre-formatted code blocks are used for writing about programming or +markup source code. Rather than forming normal paragraphs, the lines +of a code block are interpreted literally. Markdown wraps a code block +in both `
` and `` tags.
+
+To produce a code block in Markdown, simply indent every line of the
+block by at least 4 spaces or 1 tab. For example, given this input:
+
+    This is a normal paragraph:
+
+        This is a code block.
+
+Markdown will generate:
+
+    

This is a normal paragraph:

+ +
This is a code block.
+    
+ +One level of indentation -- 4 spaces or 1 tab -- is removed from each +line of the code block. For example, this: + + Here is an example of AppleScript: + + tell application "Foo" + beep + end tell + +will turn into: + +

Here is an example of AppleScript:

+ +
tell application "Foo"
+        beep
+    end tell
+    
+ +A code block continues until it reaches a line that is not indented +(or the end of the article). + +Within a code block, ampersands (`&`) and angle brackets (`<` and `>`) +are automatically converted into HTML entities. This makes it very +easy to include example HTML source code using Markdown -- just paste +it and indent it, and Markdown will handle the hassle of encoding the +ampersands and angle brackets. For example, this: + + + +will turn into: + +
<div class="footer">
+        &copy; 2004 Foo Corporation
+    </div>
+    
+ +Regular Markdown syntax is not processed within code blocks. E.g., +asterisks are just literal asterisks within a code block. This means +it's also easy to use Markdown to write about Markdown's own syntax. + + + +

Horizontal Rules

+ +You can produce a horizontal rule tag (`
`) by placing three or +more hyphens, asterisks, or underscores on a line by themselves. If you +wish, you may use spaces between the hyphens or asterisks. Each of the +following lines will produce a horizontal rule: + + * * * + + *** + + ***** + + - - - + + --------------------------------------- + + _ _ _ + + +* * * + +

Span Elements

+ + + +Markdown supports two style of links: *inline* and *reference*. + +In both styles, the link text is delimited by [square brackets]. + +To create an inline link, use a set of regular parentheses immediately +after the link text's closing square bracket. Inside the parentheses, +put the URL where you want the link to point, along with an *optional* +title for the link, surrounded in quotes. For example: + + This is [an example](http://example.com/ "Title") inline link. + + [This link](http://example.net/) has no title attribute. + +Will produce: + +

This is + an example inline link.

+ +

This link has no + title attribute.

+ +If you're referring to a local resource on the same server, you can +use relative paths: + + See my [About](/about/) page for details. + +Reference-style links use a second set of square brackets, inside +which you place a label of your choosing to identify the link: + + This is [an example][id] reference-style link. + +You can optionally use a space to separate the sets of brackets: + + This is [an example] [id] reference-style link. + +Then, anywhere in the document, you define your link label like this, +on a line by itself: + + [id]: http://example.com/ "Optional Title Here" + +That is: + +* Square brackets containing the link identifier (optionally + indented from the left margin using up to three spaces); +* followed by a colon; +* followed by one or more spaces (or tabs); +* followed by the URL for the link; +* optionally followed by a title attribute for the link, enclosed + in double or single quotes. + +The link URL may, optionally, be surrounded by angle brackets: + + [id]: "Optional Title Here" + +You can put the title attribute on the next line and use extra spaces +or tabs for padding, which tends to look better with longer URLs: + + [id]: http://example.com/longish/path/to/resource/here + "Optional Title Here" + +Link definitions are only used for creating links during Markdown +processing, and are stripped from your document in the HTML output. + +Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are *not* case sensitive. E.g. these two links: + + [link text][a] + [link text][A] + +are equivalent. + +The *implicit link name* shortcut allows you to omit the name of the +link, in which case the link text itself is used as the name. +Just use an empty set of square brackets -- e.g., to link the word +"Google" to the google.com web site, you could simply write: + + [Google][] + +And then define the link: + + [Google]: http://google.com/ + +Because link names may contain spaces, this shortcut even works for +multiple words in the link text: + + Visit [Daring Fireball][] for more information. + +And then define the link: + + [Daring Fireball]: http://daringfireball.net/ + +Link definitions can be placed anywhere in your Markdown document. I +tend to put them immediately after each paragraph in which they're +used, but if you want, you can put them all at the end of your +document, sort of like footnotes. + +Here's an example of reference links in action: + + I get 10 times more traffic from [Google] [1] than from + [Yahoo] [2] or [MSN] [3]. + + [1]: http://google.com/ "Google" + [2]: http://search.yahoo.com/ "Yahoo Search" + [3]: http://search.msn.com/ "MSN Search" + +Using the implicit link name shortcut, you could instead write: + + I get 10 times more traffic from [Google][] than from + [Yahoo][] or [MSN][]. + + [google]: http://google.com/ "Google" + [yahoo]: http://search.yahoo.com/ "Yahoo Search" + [msn]: http://search.msn.com/ "MSN Search" + +Both of the above examples will produce the following HTML output: + +

I get 10 times more traffic from Google than from + Yahoo + or MSN.

+ +For comparison, here is the same paragraph written using +Markdown's inline link style: + + I get 10 times more traffic from [Google](http://google.com/ "Google") + than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or + [MSN](http://search.msn.com/ "MSN Search"). + +The point of reference-style links is not that they're easier to +write. The point is that with reference-style links, your document +source is vastly more readable. Compare the above examples: using +reference-style links, the paragraph itself is only 81 characters +long; with inline-style links, it's 176 characters; and as raw HTML, +it's 234 characters. In the raw HTML, there's more markup than there +is text. + +With Markdown's reference-style links, a source document much more +closely resembles the final output, as rendered in a browser. By +allowing you to move the markup-related metadata out of the paragraph, +you can add links without interrupting the narrative flow of your +prose. + + +

Emphasis

+ +Markdown treats asterisks (`*`) and underscores (`_`) as indicators of +emphasis. Text wrapped with one `*` or `_` will be wrapped with an +HTML `` tag; double `*`'s or `_`'s will be wrapped with an HTML +`` tag. E.g., this input: + + *single asterisks* + + _single underscores_ + + **double asterisks** + + __double underscores__ + +will produce: + + single asterisks + + single underscores + + double asterisks + + double underscores + +You can use whichever style you prefer; the lone restriction is that +the same character must be used to open and close an emphasis span. + +Emphasis can be used in the middle of a word: + + un*fucking*believable + +But if you surround an `*` or `_` with spaces, it'll be treated as a +literal asterisk or underscore. + +To produce a literal asterisk or underscore at a position where it +would otherwise be used as an emphasis delimiter, you can backslash +escape it: + + \*this text is surrounded by literal asterisks\* + + + +

Code

+ +To indicate a span of code, wrap it with backtick quotes (`` ` ``). +Unlike a pre-formatted code block, a code span indicates code within a +normal paragraph. For example: + + Use the `printf()` function. + +will produce: + +

Use the printf() function.

+ +To include a literal backtick character within a code span, you can use +multiple backticks as the opening and closing delimiters: + + ``There is a literal backtick (`) here.`` + +which will produce this: + +

There is a literal backtick (`) here.

+ +The backtick delimiters surrounding a code span may include spaces -- +one after the opening, one before the closing. This allows you to place +literal backtick characters at the beginning or end of a code span: + + A single backtick in a code span: `` ` `` + + A backtick-delimited string in a code span: `` `foo` `` + +will produce: + +

A single backtick in a code span: `

+ +

A backtick-delimited string in a code span: `foo`

+ +With a code span, ampersands and angle brackets are encoded as HTML +entities automatically, which makes it easy to include example HTML +tags. Markdown will turn this: + + Please don't use any `` tags. + +into: + +

Please don't use any <blink> tags.

+ +You can write this: + + `—` is the decimal-encoded equivalent of `—`. + +to produce: + +

&#8212; is the decimal-encoded + equivalent of &mdash;.

+ + + +

Images

+ +Admittedly, it's fairly difficult to devise a "natural" syntax for +placing images into a plain text document format. + +Markdown uses an image syntax that is intended to resemble the syntax +for links, allowing for two styles: *inline* and *reference*. + +Inline image syntax looks like this: + + ![Alt text](/path/to/img.jpg) + + ![Alt text](/path/to/img.jpg "Optional title") + +That is: + +* An exclamation mark: `!`; +* followed by a set of square brackets, containing the `alt` + attribute text for the image; +* followed by a set of parentheses, containing the URL or path to + the image, and an optional `title` attribute enclosed in double + or single quotes. + +Reference-style image syntax looks like this: + + ![Alt text][id] + +Where "id" is the name of a defined image reference. Image references +are defined using syntax identical to link references: + + [id]: url/to/image "Optional title attribute" + +As of this writing, Markdown has no syntax for specifying the +dimensions of an image; if this is important to you, you can simply +use regular HTML `` tags. + + +* * * + + +

Miscellaneous

+ + + +Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this: + + + +Markdown will turn this into: + + http://example.com/ + +Automatic links for email addresses work similarly, except that +Markdown will also perform a bit of randomized decimal and hex +entity-encoding to help obscure your address from address-harvesting +spambots. For example, Markdown will turn this: + + + +into something like this: + + address@exa + mple.com + +which will render in a browser as a clickable link to "address@example.com". + +(This sort of entity-encoding trick will indeed fool many, if not +most, address-harvesting bots, but it definitely won't fool all of +them. It's better than nothing, but an address published in this way +will probably eventually start receiving spam.) + + + +

Backslash Escapes

+ +Markdown allows you to use backslash escapes to generate literal +characters which would otherwise have special meaning in Markdown's +formatting syntax. For example, if you wanted to surround a word with +literal asterisks (instead of an HTML `` tag), you can backslashes +before the asterisks, like this: + + \*literal asterisks\* + +Markdown provides backslash escapes for the following characters: + + \ backslash + ` backtick + * asterisk + _ underscore + {} curly braces + [] square brackets + () parentheses + # hash mark + + plus sign + - minus sign (hyphen) + . dot + ! exclamation mark + diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Nested blockquotes.html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Nested blockquotes.html new file mode 100644 index 000000000..d8ec7f8e0 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Nested blockquotes.html @@ -0,0 +1,9 @@ +
+

foo

+ +
+

bar

+
+ +

foo

+
diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Nested blockquotes.text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Nested blockquotes.text new file mode 100644 index 000000000..ed3c624ff --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Nested blockquotes.text @@ -0,0 +1,5 @@ +> foo +> +> > bar +> +> foo diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.html new file mode 100644 index 000000000..ba71eab39 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.html @@ -0,0 +1,148 @@ +

Unordered

+ +

Asterisks tight:

+ +
    +
  • asterisk 1
  • +
  • asterisk 2
  • +
  • asterisk 3
  • +
+ +

Asterisks loose:

+ +
    +
  • asterisk 1

  • +
  • asterisk 2

  • +
  • asterisk 3

  • +
+ +
+ +

Pluses tight:

+ +
    +
  • Plus 1
  • +
  • Plus 2
  • +
  • Plus 3
  • +
+ +

Pluses loose:

+ +
    +
  • Plus 1

  • +
  • Plus 2

  • +
  • Plus 3

  • +
+ +
+ +

Minuses tight:

+ +
    +
  • Minus 1
  • +
  • Minus 2
  • +
  • Minus 3
  • +
+ +

Minuses loose:

+ +
    +
  • Minus 1

  • +
  • Minus 2

  • +
  • Minus 3

  • +
+ +

Ordered

+ +

Tight:

+ +
    +
  1. First
  2. +
  3. Second
  4. +
  5. Third
  6. +
+ +

and:

+ +
    +
  1. One
  2. +
  3. Two
  4. +
  5. Three
  6. +
+ +

Loose using tabs:

+ +
    +
  1. First

  2. +
  3. Second

  4. +
  5. Third

  6. +
+ +

and using spaces:

+ +
    +
  1. One

  2. +
  3. Two

  4. +
  5. Three

  6. +
+ +

Multiple paragraphs:

+ +
    +
  1. Item 1, graf one.

    + +

    Item 2. graf two. The quick brown fox jumped over the lazy dog's +back.

  2. +
  3. Item 2.

  4. +
  5. Item 3.

  6. +
+ +

Nested

+ +
    +
  • Tab +
      +
    • Tab +
        +
      • Tab
      • +
    • +
  • +
+ +

Here's another:

+ +
    +
  1. First
  2. +
  3. Second: +
      +
    • Fee
    • +
    • Fie
    • +
    • Foe
    • +
  4. +
  5. Third
  6. +
+ +

Same thing but with paragraphs:

+ +
    +
  1. First

  2. +
  3. Second:

    + +
      +
    • Fee
    • +
    • Fie
    • +
    • Foe
    • +
  4. +
  5. Third

  6. +
+ + +

This was an error in Markdown 1.0.1:

+ +
    +
  • this

    + +
    • sub
    + +

    that

  • +
diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.text new file mode 100644 index 000000000..7f3b49777 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Ordered and unordered lists.text @@ -0,0 +1,131 @@ +## Unordered + +Asterisks tight: + +* asterisk 1 +* asterisk 2 +* asterisk 3 + + +Asterisks loose: + +* asterisk 1 + +* asterisk 2 + +* asterisk 3 + +* * * + +Pluses tight: + ++ Plus 1 ++ Plus 2 ++ Plus 3 + + +Pluses loose: + ++ Plus 1 + ++ Plus 2 + ++ Plus 3 + +* * * + + +Minuses tight: + +- Minus 1 +- Minus 2 +- Minus 3 + + +Minuses loose: + +- Minus 1 + +- Minus 2 + +- Minus 3 + + +## Ordered + +Tight: + +1. First +2. Second +3. Third + +and: + +1. One +2. Two +3. Three + + +Loose using tabs: + +1. First + +2. Second + +3. Third + +and using spaces: + +1. One + +2. Two + +3. Three + +Multiple paragraphs: + +1. Item 1, graf one. + + Item 2. graf two. The quick brown fox jumped over the lazy dog's + back. + +2. Item 2. + +3. Item 3. + + + +## Nested + +* Tab + * Tab + * Tab + +Here's another: + +1. First +2. Second: + * Fee + * Fie + * Foe +3. Third + +Same thing but with paragraphs: + +1. First + +2. Second: + * Fee + * Fie + * Foe + +3. Third + + +This was an error in Markdown 1.0.1: + +* this + + * sub + + that diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Strong and em together.html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Strong and em together.html new file mode 100644 index 000000000..71ec78c70 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Strong and em together.html @@ -0,0 +1,7 @@ +

This is strong and em.

+ +

So is this word.

+ +

This is strong and em.

+ +

So is this word.

diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Strong and em together.text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Strong and em together.text new file mode 100644 index 000000000..95ee690db --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Strong and em together.text @@ -0,0 +1,7 @@ +***This is strong and em.*** + +So is ***this*** word. + +___This is strong and em.___ + +So is ___this___ word. diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Tabs.html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Tabs.html new file mode 100644 index 000000000..3301ba803 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Tabs.html @@ -0,0 +1,25 @@ +
    +
  • this is a list item +indented with tabs

  • +
  • this is a list item +indented with spaces

  • +
+ +

Code:

+ +
this code block is indented by one tab
+
+ +

And:

+ +
    this code block is indented by two tabs
+
+ +

And:

+ +
+   this is an example list item
+    indented with tabs
+
++   this is an example list item
+    indented with spaces
+
diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Tabs.text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Tabs.text new file mode 100644 index 000000000..589d1136e --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Tabs.text @@ -0,0 +1,21 @@ ++ this is a list item + indented with tabs + ++ this is a list item + indented with spaces + +Code: + + this code block is indented by one tab + +And: + + this code block is indented by two tabs + +And: + + + this is an example list item + indented with tabs + + + this is an example list item + indented with spaces diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Tidyness.html b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Tidyness.html new file mode 100644 index 000000000..f2a8ce70f --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Tidyness.html @@ -0,0 +1,8 @@ +
+

A list within a blockquote:

+
    +
  • asterisk 1
  • +
  • asterisk 2
  • +
  • asterisk 3
  • +
+
diff --git a/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Tidyness.text b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Tidyness.text new file mode 100644 index 000000000..5f18b8da2 --- /dev/null +++ b/supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Tidyness.text @@ -0,0 +1,5 @@ +> A list within a blockquote: +> +> * asterisk 1 +> * asterisk 2 +> * asterisk 3 diff --git a/supportlibs/pegmarkdown/README.markdown b/supportlibs/pegmarkdown/README.markdown new file mode 100644 index 000000000..409c5e3fe --- /dev/null +++ b/supportlibs/pegmarkdown/README.markdown @@ -0,0 +1,225 @@ + +This a forked version of peg-markdown.... only minor changes: + + * Switch to Qt .pro make system for easy x-platform. + + * build a library instead of exec. + + * Add GLibFacade from multimarkdown to allow Win32 compilations. + + * Added ifdefs for C++ linking, + + +What is this? +============= + +This is an implementation of John Gruber's [markdown][] in C. It uses a +[parsing expression grammar (PEG)][] to define the syntax. This should +allow easy modification and extension. It currently supports output in +HTML, LaTeX, ODF, or groff_mm formats, and adding new formats is +relatively easy. + +[parsing expression grammar (PEG)]: http://en.wikipedia.org/wiki/Parsing_expression_grammar +[markdown]: http://daringfireball.net/projects/markdown/ + +It is pretty fast. A 179K text file that takes 5.7 seconds for +Markdown.pl (v. 1.0.1) to parse takes less than 0.2 seconds for this +markdown. It does, however, use a lot of memory (up to 4M of heap space +while parsing the 179K file, and up to 80K for a 4K file). (Note that +the memory leaks in earlier versions of this program have now been +plugged.) + +Both a library and a standalone program are provided. + +peg-markdown is written and maintained by John MacFarlane (jgm on +github), with significant contributions by Ryan Tomayko (rtomayko). +It is released under both the GPL and the MIT license; see LICENSE for +details. + +Installing +========== + +On a linux or unix-based system +------------------------------- + +This program is written in portable ANSI C. It requires +[glib2](http://www.gtk.org/download/index.php). Most *nix systems will have +this installed already. The build system requires GNU make. + +The other required dependency, [Ian Piumarta's peg/leg PEG parser +generator](http://piumarta.com/software/peg/), is included in the source +directory. It will be built automatically. (However, it is not as portable +as peg-markdown itself, and seems to require gcc.) + +To make the 'markdown' executable: + + make + +(Or, on some systems, `gmake`.) Then, for usage instructions: + + ./markdown --help + +To run John Gruber's Markdown 1.0.3 test suite: + + make test + +The test suite will fail on one of the list tests. Here's why. +Markdown.pl encloses "item one" in the following list in `

` tags: + + 1. item one + * subitem + * subitem + + 2. item two + + 3. item three + +peg-markdown does not enclose "item one" in `

` tags unless it has a +following blank line. This is consistent with the official markdown +syntax description, and lets the author of the document choose whether +`

` tags are desired. + +Cross-compiling for Windows with MinGW on a linux box +----------------------------------------------------- + +Prerequisites: + +* Linux system with MinGW cross compiler For Ubuntu: + + sudo apt-get install mingw32 + +* [Windows glib-2.0 binary & development files](http://www.gtk.org/download-windows.html). + Unzip files into cross-compiler directory tree (e.g., `/usr/i586-mingw32msvc`). + +Steps: + +1. Create the markdown parser using Linux-compiled `leg` from peg-0.1.4: + + ./peg-0.1.4/leg markdown_parser.leg >markdown_parser.c + + (Note: The same thing could be accomplished by cross-compiling leg, + executing it on Windows, and copying the resulting C file to the Linux + cross-compiler host.) + +2. Run the cross compiler with include flag for the Windows glib-2.0 headers: + for example, + + /usr/bin/i586-mingw32msvc-cc -c \ + -I/usr/i586-mingw32msvc/include/glib-2.0 \ + -I/usr/i586-mingw32msvc/lib/glib-2.0/include -Wall -O3 -ansi markdown*.c + +3. Link against Windows glib-2.0 headers: for example, + + /usr/bin/i586-mingw32msvc-cc markdown*.o \ + -Wl,-L/usr/i586-mingw32msvc/lib/glib,--dy,--warn-unresolved-symbols,-lglib-2.0 \ + -o markdown.exe + +The resulting executable depends on the glib dll file, so be sure to +load the glib binary on the Windows host. + +Compiling with MinGW on Windows +------------------------------- + +These directions assume that MinGW is installed in `c:\MinGW` and glib-2.0 +is installed in the MinGW directory hierarchy (with the mingw bin directory +in the system path). + +Unzip peg-markdown in a temp directory. From the directory with the +peg-markdown source, execute: + + cd peg-0.1.4 + make PKG_CONFIG=c:/path/to/glib/bin/pkg-config.exe + +Extensions +========== + +peg-markdown supports extensions to standard markdown syntax. +These can be turned on using the command line flag `-x` or +`--extensions`. `-x` by itself turns on all extensions. Extensions +can also be turned on selectively, using individual command-line +options. To see the available extensions: + + ./markdown --help-extensions + +The `--smart` extension provides "smart quotes", dashes, and ellipses. + +The `--notes` extension provides a footnote syntax like that of +Pandoc or PHP Markdown Extra. + +Using the library +================= + +The library exports two functions: + + GString * markdown_to_g_string(char *text, int extensions, int output_format); + char * markdown_to_string(char *text, int extensions, int output_format); + +The only difference between these is that `markdown_to_g_string` returns a +`GString` (glib's automatically resizable string), while `markdown_to_string` +returns a regular character pointer. The memory allocated for these must be +freed by the calling program, using `g_string_free()` or `free()`. + +`text` is the markdown-formatted text to be converted. Note that tabs will +be converted to spaces, using a four-space tab stop. Character encodings are +ignored. + +`extensions` is a bit-field specifying which syntax extensions should be used. +If `extensions` is 0, no extensions will be used. If it is `0xFFFFFF`, +all extensions will be used. To set extensions selectively, use the +bitwise `&` operator and the following constants: + + - `EXT_SMART` turns on smart quotes, dashes, and ellipses. + - `EXT_NOTES` turns on footnote syntax. [Pandoc's footnote syntax][] is used here. + - `EXT_FILTER_HTML` filters out raw HTML (except for styles). + - `EXT_FILTER_STYLES` filters out styles in HTML. + + [Pandoc's footnote syntax]: http://johnmacfarlane.net/pandoc/README.html#footnotes + +`output_format` is either `HTML_FORMAT`, `LATEX_FORMAT`, `ODF_FORMAT`, +or `GROFF_MM_FORMAT`. + +To use the library, include `markdown_lib.h`. See `markdown.c` for an example. + +Hacking +======= + +It should be pretty easy to modify the program to produce other formats, +and to parse syntax extensions. A quick guide: + + * `markdown_parser.leg` contains the grammar itself. + + * `markdown_output.c` contains functions for printing the `Element` + structure in various output formats. + + * To add an output format, add the format to `markdown_formats` in + `markdown_lib.h`. Then modify `print_element` in `markdown_output.c`, + and add functions `print_XXXX_string`, `print_XXXX_element`, and + `print_XXXX_element_list`. Also add an option in the main program + that selects the new format. Don't forget to add it to the list of + formats in the usage message. + + * To add syntax extensions, define them in the PEG grammar + (`markdown_parser.leg`), using existing extensions as a guide. New + inline elements will need to be added to `Inline =`; new block + elements will need to be added to `Block =`. (Note: the order + of the alternatives does matter in PEG grammars.) + + * If you need to add new types of elements, modify the `keys` + enum in `markdown_peg.h`. + + * By using `&{ }` rules one can selectively disable extensions + depending on command-line options. For example, + `&{ extension(EXT_SMART) }` succeeds only if the `EXT_SMART` bit + of the global `syntax_extensions` is set. Add your option to + `markdown_extensions` in `markdown_lib.h`, and add an option in + `markdown.c` to turn on your extension. + + * Note: Avoid using `[^abc]` character classes in the grammar, because + they cause problems with non-ascii input. Instead, use: `( !'a' !'b' + !'c' . )` + +Acknowledgements +================ + +Support for ODF output was added by Fletcher T. Penney. + diff --git a/supportlibs/pegmarkdown/glib.h b/supportlibs/pegmarkdown/glib.h new file mode 100644 index 000000000..eafb859ff --- /dev/null +++ b/supportlibs/pegmarkdown/glib.h @@ -0,0 +1,11 @@ +/* + * glib.h + * MultiMarkdown + * + * Created by Daniel Jalkut on 7/26/11. + * Copyright 2011 __MyCompanyName__. All rights reserved. + * + */ + +/* Just a dummy file to keep the glib-dependent sources compiling as we would hope */ +#include "GLibFacade.h" diff --git a/supportlibs/pegmarkdown/markdown.c b/supportlibs/pegmarkdown/markdown.c new file mode 100644 index 000000000..ca277e529 --- /dev/null +++ b/supportlibs/pegmarkdown/markdown.c @@ -0,0 +1,183 @@ +/********************************************************************** + + markdown.c - markdown in C using a PEG grammar. + (c) 2008 John MacFarlane (jgm at berkeley dot edu). + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License or the MIT + license. See LICENSE for details. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + ***********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include "markdown_peg.h" + +static int extensions; + +/********************************************************************** + + The main program is just a wrapper around the library functions in + markdown_lib.c. It parses command-line options, reads the text to + be converted from input files or stdin, converts the text, and sends + the output to stdout or a file. Character encodings are ignored. + + ***********************************************************************/ + +#define VERSION "0.4.14" +#define COPYRIGHT "Copyright (c) 2008-2009 John MacFarlane. License GPLv2+ or MIT.\n" \ + "This is free software: you are free to change and redistribute it.\n" \ + "There is NO WARRANTY, to the extent permitted by law." + +/* print version and copyright information */ +void version(const char *progname) +{ + printf("peg-markdown version %s\n" + "%s\n", + VERSION, + COPYRIGHT); +} + +int main(int argc, char * argv[]) { + + int numargs; /* number of filename arguments */ + int i; + + GString *inputbuf; + char *out; /* string containing processed output */ + + FILE *input; + FILE *output; + char curchar; + char *progname = argv[0]; + + int output_format = HTML_FORMAT; + + /* Code for command-line option parsing. */ + + static gboolean opt_version = FALSE; + static gchar *opt_output = 0; + static gchar *opt_to = 0; + static gboolean opt_smart = FALSE; + static gboolean opt_notes = FALSE; + static gboolean opt_filter_html = FALSE; + static gboolean opt_filter_styles = FALSE; + static gboolean opt_allext = FALSE; + + static GOptionEntry entries[] = + { + { "version", 'v', 0, G_OPTION_ARG_NONE, &opt_version, "print version and exit", NULL }, + { "output", 'o', 0, G_OPTION_ARG_STRING, &opt_output, "send output to FILE (default is stdout)", "FILE" }, + { "to", 't', 0, G_OPTION_ARG_STRING, &opt_to, "convert to FORMAT (default is html)", "FORMAT" }, + { "extensions", 'x', 0, G_OPTION_ARG_NONE, &opt_allext, "use all syntax extensions", NULL }, + { "filter-html", 0, 0, G_OPTION_ARG_NONE, &opt_filter_html, "filter out raw HTML (except styles)", NULL }, + { "filter-styles", 0, 0, G_OPTION_ARG_NONE, &opt_filter_styles, "filter out HTML styles", NULL }, + { NULL } + }; + + /* Options to active syntax extensions. These appear separately in --help. */ + static GOptionEntry ext_entries[] = + { + { "smart", 0, 0, G_OPTION_ARG_NONE, &opt_smart, "use smart typography extension", NULL }, + { "notes", 0, 0, G_OPTION_ARG_NONE, &opt_notes, "use notes extension", NULL }, + { NULL } + }; + + GError *error = NULL; + GOptionContext *context; + GOptionGroup *ext_group; + + context = g_option_context_new ("[FILE...]"); + g_option_context_add_main_entries (context, entries, NULL); + ext_group = g_option_group_new ("extensions", "Syntax extensions", "show available syntax extensions", NULL, NULL); + g_option_group_add_entries (ext_group, ext_entries); + g_option_context_add_group (context, ext_group); + g_option_context_set_description (context, "Converts text in specified files (or stdin) from markdown to FORMAT.\n" + "Available FORMATs: html, latex, groff-mm, odf"); + if (!g_option_context_parse (context, &argc, &argv, &error)) { + g_print ("option parsing failed: %s\n", error->message); + exit (1); + } + g_option_context_free(context); + + /* Process command-line options and arguments. */ + + if (opt_version) { + version(progname); + return EXIT_SUCCESS; + } + + extensions = 0; + if (opt_allext) + extensions = 0xFFFFFF; /* turn on all extensions */ + if (opt_smart) + extensions = extensions | EXT_SMART; + if (opt_notes) + extensions = extensions | EXT_NOTES; + if (opt_filter_html) + extensions = extensions | EXT_FILTER_HTML; + if (opt_filter_styles) + extensions = extensions | EXT_FILTER_STYLES; + + if (opt_to == NULL) + output_format = HTML_FORMAT; + else if (strcmp(opt_to, "html") == 0) + output_format = HTML_FORMAT; + else if (strcmp(opt_to, "latex") == 0) + output_format = LATEX_FORMAT; + else if (strcmp(opt_to, "groff-mm") == 0) + output_format = GROFF_MM_FORMAT; + else if (strcmp(opt_to, "odf") == 0) + output_format = ODF_FORMAT; + else { + fprintf(stderr, "%s: Unknown output format '%s'\n", progname, opt_to); + exit(EXIT_FAILURE); + } + + /* we allow "-" as a synonym for stdout here */ + if (opt_output == NULL || strcmp(opt_output, "-") == 0) + output = stdout; + else if (!(output = fopen(opt_output, "w"))) { + perror(opt_output); + return 1; + } + + inputbuf = g_string_new(""); /* string for concatenated input */ + + /* Read input from stdin or input files into inputbuf */ + + numargs = argc - 1; + if (numargs == 0) { /* use stdin if no files specified */ + while ((curchar = fgetc(stdin)) != EOF) + g_string_append_c(inputbuf, curchar); + fclose(stdin); + } + else { /* open all the files on command line */ + for (i = 0; i < numargs; i++) { + if ((input = fopen(argv[i+1], "r")) == NULL) { + perror(argv[i+1]); + exit(EXIT_FAILURE); + } + while ((curchar = fgetc(input)) != EOF) + g_string_append_c(inputbuf, curchar); + fclose(input); + } + } + + out = markdown_to_string(inputbuf->str, extensions, output_format); + fprintf(output, "%s\n", out); + free(out); + + g_string_free(inputbuf, true); + + return(EXIT_SUCCESS); +} diff --git a/supportlibs/pegmarkdown/markdown_lib.c b/supportlibs/pegmarkdown/markdown_lib.c new file mode 100644 index 000000000..628fce29f --- /dev/null +++ b/supportlibs/pegmarkdown/markdown_lib.c @@ -0,0 +1,181 @@ +/********************************************************************** + + markdown_lib.c - markdown in C using a PEG grammar. + (c) 2008 John MacFarlane (jgm at berkeley dot edu). + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License or the MIT + license. See LICENSE for details. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + ***********************************************************************/ + +#include +#include +#include +#include "markdown_peg.h" + +#define TABSTOP 4 + +/* preformat_text - allocate and copy text buffer while + * performing tab expansion. */ +static GString *preformat_text(char *text) { + GString *buf; + char next_char; + int charstotab; + + int len = 0; + + buf = g_string_new(""); + + charstotab = TABSTOP; + while ((next_char = *text++) != '\0') { + switch (next_char) { + case '\t': + while (charstotab > 0) + g_string_append_c(buf, ' '), len++, charstotab--; + break; + case '\n': + g_string_append_c(buf, '\n'), len++, charstotab = TABSTOP; + break; + default: + g_string_append_c(buf, next_char), len++, charstotab--; + } + if (charstotab == 0) + charstotab = TABSTOP; + } + g_string_append(buf, "\n\n"); + return(buf); +} + +/* print_tree - print tree of elements, for debugging only. */ +static void print_tree(element * elt, int indent) { + int i; + char * key; + while (elt != NULL) { + for (i = 0; i < indent; i++) + fputc(' ', stderr); + switch (elt->key) { + case LIST: key = "LIST"; break; + case RAW: key = "RAW"; break; + case SPACE: key = "SPACE"; break; + case LINEBREAK: key = "LINEBREAK"; break; + case ELLIPSIS: key = "ELLIPSIS"; break; + case EMDASH: key = "EMDASH"; break; + case ENDASH: key = "ENDASH"; break; + case APOSTROPHE: key = "APOSTROPHE"; break; + case SINGLEQUOTED: key = "SINGLEQUOTED"; break; + case DOUBLEQUOTED: key = "DOUBLEQUOTED"; break; + case STR: key = "STR"; break; + case LINK: key = "LINK"; break; + case IMAGE: key = "IMAGE"; break; + case CODE: key = "CODE"; break; + case HTML: key = "HTML"; break; + case EMPH: key = "EMPH"; break; + case STRONG: key = "STRONG"; break; + case PLAIN: key = "PLAIN"; break; + case PARA: key = "PARA"; break; + case LISTITEM: key = "LISTITEM"; break; + case BULLETLIST: key = "BULLETLIST"; break; + case ORDEREDLIST: key = "ORDEREDLIST"; break; + case H1: key = "H1"; break; + case H2: key = "H2"; break; + case H3: key = "H3"; break; + case H4: key = "H4"; break; + case H5: key = "H5"; break; + case H6: key = "H6"; break; + case BLOCKQUOTE: key = "BLOCKQUOTE"; break; + case VERBATIM: key = "VERBATIM"; break; + case HTMLBLOCK: key = "HTMLBLOCK"; break; + case HRULE: key = "HRULE"; break; + case REFERENCE: key = "REFERENCE"; break; + case NOTE: key = "NOTE"; break; + default: key = "?"; + } + if ( elt->key == STR ) { + fprintf(stderr, "0x%p: %s '%s'\n", (void *)elt, key, elt->contents.str); + } else { + fprintf(stderr, "0x%p: %s\n", (void *)elt, key); + } + if (elt->children) + print_tree(elt->children, indent + 4); + elt = elt->next; + } +} + +/* process_raw_blocks - traverses an element list, replacing any RAW elements with + * the result of parsing them as markdown text, and recursing into the children + * of parent elements. The result should be a tree of elements without any RAWs. */ +static element * process_raw_blocks(element *input, int extensions, element *references, element *notes) { + element *current = NULL; + element *last_child = NULL; + char *contents; + current = input; + + while (current != NULL) { + if (current->key == RAW) { + /* \001 is used to indicate boundaries between nested lists when there + * is no blank line. We split the string by \001 and parse + * each chunk separately. */ + contents = strtok(current->contents.str, "\001"); + current->key = LIST; + current->children = parse_markdown(contents, extensions, references, notes); + last_child = current->children; + while ((contents = strtok(NULL, "\001"))) { + while (last_child->next != NULL) + last_child = last_child->next; + last_child->next = parse_markdown(contents, extensions, references, notes); + } + free(current->contents.str); + current->contents.str = NULL; + } + if (current->children != NULL) + current->children = process_raw_blocks(current->children, extensions, references, notes); + current = current->next; + } + return input; +} + +/* markdown_to_gstring - convert markdown text to the output format specified. + * Returns a GString, which must be freed after use using g_string_free(). */ +GString * markdown_to_g_string(char *text, int extensions, int output_format) { + element *result; + element *references; + element *notes; + GString *formatted_text; + GString *out; + out = g_string_new(""); + + formatted_text = preformat_text(text); + + references = parse_references(formatted_text->str, extensions); + notes = parse_notes(formatted_text->str, extensions, references); + result = parse_markdown(formatted_text->str, extensions, references, notes); + + result = process_raw_blocks(result, extensions, references, notes); + + g_string_free(formatted_text, TRUE); + + print_element_list(out, result, output_format, extensions); + + free_element_list(result); + free_element_list(references); + return out; +} + +/* markdown_to_string - convert markdown text to the output format specified. + * Returns a null-terminated string, which must be freed after use. */ +char * markdown_to_string(char *text, int extensions, int output_format) { + GString *out; + char *char_out; + out = markdown_to_g_string(text, extensions, output_format); + char_out = out->str; + g_string_free(out, FALSE); + return char_out; +} + +/* vim:set ts=4 sw=4: */ diff --git a/supportlibs/pegmarkdown/markdown_lib.h b/supportlibs/pegmarkdown/markdown_lib.h new file mode 100644 index 000000000..c13a567d3 --- /dev/null +++ b/supportlibs/pegmarkdown/markdown_lib.h @@ -0,0 +1,38 @@ +#ifndef MARKDOWN_LIB_H +#define MARKDOWN_LIB_H + +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +enum markdown_extensions { + EXT_SMART = 0x01, + EXT_NOTES = 0x02, + EXT_FILTER_HTML = 0x04, + EXT_FILTER_STYLES = 0x08 +}; + +enum markdown_formats { + HTML_FORMAT, + LATEX_FORMAT, + GROFF_MM_FORMAT, + ODF_FORMAT +}; + +GString * markdown_to_g_string(char *text, int extensions, int output_format); +char * markdown_to_string(char *text, int extensions, int output_format); + + +#ifdef __cplusplus +} +#endif + +/* vim: set ts=4 sw=4 : */ +#endif + diff --git a/supportlibs/pegmarkdown/markdown_output.c b/supportlibs/pegmarkdown/markdown_output.c new file mode 100644 index 000000000..99cbb6bb7 --- /dev/null +++ b/supportlibs/pegmarkdown/markdown_output.c @@ -0,0 +1,1121 @@ +/********************************************************************** + + markdown_output.c - functions for printing Elements parsed by + markdown_peg. + (c) 2008 John MacFarlane (jgm at berkeley dot edu). + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License or the MIT + license. See LICENSE for details. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + ***********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include "markdown_peg.h" +#include "odf.h" + +static int extensions; +static int odf_type = 0; + +static void print_html_string(GString *out, char *str, bool obfuscate); +static void print_html_element_list(GString *out, element *list, bool obfuscate); +static void print_html_element(GString *out, element *elt, bool obfuscate); +static void print_latex_string(GString *out, char *str); +static void print_latex_element_list(GString *out, element *list); +static void print_latex_element(GString *out, element *elt); +static void print_groff_string(GString *out, char *str); +static void print_groff_mm_element_list(GString *out, element *list); +static void print_groff_mm_element(GString *out, element *elt, int count); +static void print_odf_code_string(GString *out, char *str); +static void print_odf_string(GString *out, char *str); +static void print_odf_element_list(GString *out, element *list); +static void print_odf_element(GString *out, element *elt); +static bool list_contains_key(element *list, int key); + +/********************************************************************** + + Utility functions for printing + + ***********************************************************************/ + +static int padded = 2; /* Number of newlines after last output. + Starts at 2 so no newlines are needed at start. + */ + +static GSList *endnotes = NULL; /* List of endnotes to print after main content. */ +static int notenumber = 0; /* Number of footnote. */ + +/* pad - add newlines if needed */ +static void pad(GString *out, int num) { + while (num-- > padded) + g_string_append_printf(out, "\n");; + padded = num; +} + +/* determine whether a certain element is contained within a given list */ +static bool list_contains_key(element *list, int key) { + element *step = NULL; + + step = list; + while ( step != NULL ) { + if (step->key == key) { + return TRUE; + } + if (step->children != NULL) { + if (list_contains_key(step->children, key)) { + return TRUE; + } + } + step = step->next; + } + return FALSE; +} + +/********************************************************************** + + Functions for printing Elements as HTML + + ***********************************************************************/ + +/* print_html_string - print string, escaping for HTML + * If obfuscate selected, convert characters to hex or decimal entities at random */ +static void print_html_string(GString *out, char *str, bool obfuscate) { + while (*str != '\0') { + switch (*str) { + case '&': + g_string_append_printf(out, "&"); + break; + case '<': + g_string_append_printf(out, "<"); + break; + case '>': + g_string_append_printf(out, ">"); + break; + case '"': + g_string_append_printf(out, """); + break; + default: + if (obfuscate) { + if (rand() % 2 == 0) + g_string_append_printf(out, "&#%d;", (int) *str); + else + g_string_append_printf(out, "&#x%x;", (unsigned int) *str); + } + else + g_string_append_c(out, *str); + } + str++; + } +} + +/* print_html_element_list - print a list of elements as HTML */ +static void print_html_element_list(GString *out, element *list, bool obfuscate) { + while (list != NULL) { + print_html_element(out, list, obfuscate); + list = list->next; + } +} + +/* add_endnote - add an endnote to global endnotes list. */ +static void add_endnote(element *elt) { + endnotes = g_slist_prepend(endnotes, elt); +} + +/* print_html_element - print an element as HTML */ +static void print_html_element(GString *out, element *elt, bool obfuscate) { + int lev; + switch (elt->key) { + case SPACE: + g_string_append_printf(out, "%s", elt->contents.str); + break; + case LINEBREAK: + g_string_append_printf(out, "
\n"); + break; + case STR: + print_html_string(out, elt->contents.str, obfuscate); + break; + case ELLIPSIS: + g_string_append_printf(out, "…"); + break; + case EMDASH: + g_string_append_printf(out, "—"); + break; + case ENDASH: + g_string_append_printf(out, "–"); + break; + case APOSTROPHE: + g_string_append_printf(out, "’"); + break; + case SINGLEQUOTED: + g_string_append_printf(out, "‘"); + print_html_element_list(out, elt->children, obfuscate); + g_string_append_printf(out, "’"); + break; + case DOUBLEQUOTED: + g_string_append_printf(out, "“"); + print_html_element_list(out, elt->children, obfuscate); + g_string_append_printf(out, "”"); + break; + case CODE: + g_string_append_printf(out, ""); + print_html_string(out, elt->contents.str, obfuscate); + g_string_append_printf(out, ""); + break; + case HTML: + g_string_append_printf(out, "%s", elt->contents.str); + break; + case LINK: + if (strstr(elt->contents.link->url, "mailto:") == elt->contents.link->url) + obfuscate = true; /* obfuscate mailto: links */ + g_string_append_printf(out, "contents.link->url, obfuscate); + g_string_append_printf(out, "\""); + if (strlen(elt->contents.link->title) > 0) { + g_string_append_printf(out, " title=\""); + print_html_string(out, elt->contents.link->title, obfuscate); + g_string_append_printf(out, "\""); + } + g_string_append_printf(out, ">"); + print_html_element_list(out, elt->contents.link->label, obfuscate); + g_string_append_printf(out, ""); + break; + case IMAGE: + g_string_append_printf(out, "contents.link->url, obfuscate); + g_string_append_printf(out, "\" alt=\""); + print_html_element_list(out, elt->contents.link->label, obfuscate); + g_string_append_printf(out, "\""); + if (strlen(elt->contents.link->title) > 0) { + g_string_append_printf(out, " title=\""); + print_html_string(out, elt->contents.link->title, obfuscate); + g_string_append_printf(out, "\""); + } + g_string_append_printf(out, " />"); + break; + case EMPH: + g_string_append_printf(out, ""); + print_html_element_list(out, elt->children, obfuscate); + g_string_append_printf(out, ""); + break; + case STRONG: + g_string_append_printf(out, ""); + print_html_element_list(out, elt->children, obfuscate); + g_string_append_printf(out, ""); + break; + case LIST: + print_html_element_list(out, elt->children, obfuscate); + break; + case RAW: + /* Shouldn't occur - these are handled by process_raw_blocks() */ + assert(elt->key != RAW); + break; + case H1: case H2: case H3: case H4: case H5: case H6: + lev = elt->key - H1 + 1; /* assumes H1 ... H6 are in order */ + pad(out, 2); + g_string_append_printf(out, "", lev); + print_html_element_list(out, elt->children, obfuscate); + g_string_append_printf(out, "", lev); + padded = 0; + break; + case PLAIN: + pad(out, 1); + print_html_element_list(out, elt->children, obfuscate); + padded = 0; + break; + case PARA: + pad(out, 2); + g_string_append_printf(out, "

"); + print_html_element_list(out, elt->children, obfuscate); + g_string_append_printf(out, "

"); + padded = 0; + break; + case HRULE: + pad(out, 2); + g_string_append_printf(out, "
"); + padded = 0; + break; + case HTMLBLOCK: + pad(out, 2); + g_string_append_printf(out, "%s", elt->contents.str); + padded = 0; + break; + case VERBATIM: + pad(out, 2); + g_string_append_printf(out, "%s", "
");
+        print_html_string(out, elt->contents.str, obfuscate);
+        g_string_append_printf(out, "%s", "
"); + padded = 0; + break; + case BULLETLIST: + pad(out, 2); + g_string_append_printf(out, "%s", "
    "); + padded = 0; + print_html_element_list(out, elt->children, obfuscate); + pad(out, 1); + g_string_append_printf(out, "%s", "
"); + padded = 0; + break; + case ORDEREDLIST: + pad(out, 2); + g_string_append_printf(out, "%s", "
    "); + padded = 0; + print_html_element_list(out, elt->children, obfuscate); + pad(out, 1); + g_string_append_printf(out, "
"); + padded = 0; + break; + case LISTITEM: + pad(out, 1); + g_string_append_printf(out, "
  • "); + padded = 2; + print_html_element_list(out, elt->children, obfuscate); + g_string_append_printf(out, "
  • "); + padded = 0; + break; + case BLOCKQUOTE: + pad(out, 2); + g_string_append_printf(out, "
    \n"); + padded = 2; + print_html_element_list(out, elt->children, obfuscate); + pad(out, 1); + g_string_append_printf(out, "
    "); + padded = 0; + break; + case REFERENCE: + /* Nonprinting */ + break; + case NOTE: + /* if contents.str == 0, then print note; else ignore, since this + * is a note block that has been incorporated into the notes list */ + if (elt->contents.str == 0) { + add_endnote(elt); + ++notenumber; + g_string_append_printf(out, "[%d]", + notenumber, notenumber, notenumber, notenumber); + } + break; + default: + fprintf(stderr, "print_html_element encountered unknown element key = %d\n", elt->key); + exit(EXIT_FAILURE); + } +} + +static void print_html_endnotes(GString *out) { + int counter = 0; + GSList *note; + element *note_elt; + if (endnotes == NULL) + return; + note = g_slist_reverse(endnotes); + g_string_append_printf(out, "
    \n
      "); + while (note != NULL) { + note_elt = note->data; + counter++; + pad(out, 1); + g_string_append_printf(out, "
    1. \n", counter); + padded = 2; + print_html_element_list(out, note_elt->children, false); + g_string_append_printf(out, " [back]", counter); + pad(out, 1); + g_string_append_printf(out, "
    2. "); + note = note->next; + } + pad(out, 1); + g_string_append_printf(out, "
    "); + g_slist_free(endnotes); +} + +/********************************************************************** + + Functions for printing Elements as LaTeX + + ***********************************************************************/ + +/* print_latex_string - print string, escaping for LaTeX */ +static void print_latex_string(GString *out, char *str) { + while (*str != '\0') { + switch (*str) { + case '{': case '}': case '$': case '%': + case '&': case '_': case '#': + g_string_append_printf(out, "\\%c", *str); + break; + case '^': + g_string_append_printf(out, "\\^{}"); + break; + case '\\': + g_string_append_printf(out, "\\textbackslash{}"); + break; + case '~': + g_string_append_printf(out, "\\ensuremath{\\sim}"); + break; + case '|': + g_string_append_printf(out, "\\textbar{}"); + break; + case '<': + g_string_append_printf(out, "\\textless{}"); + break; + case '>': + g_string_append_printf(out, "\\textgreater{}"); + break; + default: + g_string_append_c(out, *str); + } + str++; + } +} + +/* print_latex_element_list - print a list of elements as LaTeX */ +static void print_latex_element_list(GString *out, element *list) { + while (list != NULL) { + print_latex_element(out, list); + list = list->next; + } +} + +/* print_latex_element - print an element as LaTeX */ +static void print_latex_element(GString *out, element *elt) { + int lev; + int i; + switch (elt->key) { + case SPACE: + g_string_append_printf(out, "%s", elt->contents.str); + break; + case LINEBREAK: + g_string_append_printf(out, "\\\\\n"); + break; + case STR: + print_latex_string(out, elt->contents.str); + break; + case ELLIPSIS: + g_string_append_printf(out, "\\ldots{}"); + break; + case EMDASH: + g_string_append_printf(out, "---"); + break; + case ENDASH: + g_string_append_printf(out, "--"); + break; + case APOSTROPHE: + g_string_append_printf(out, "'"); + break; + case SINGLEQUOTED: + g_string_append_printf(out, "`"); + print_latex_element_list(out, elt->children); + g_string_append_printf(out, "'"); + break; + case DOUBLEQUOTED: + g_string_append_printf(out, "``"); + print_latex_element_list(out, elt->children); + g_string_append_printf(out, "''"); + break; + case CODE: + g_string_append_printf(out, "\\texttt{"); + print_latex_string(out, elt->contents.str); + g_string_append_printf(out, "}"); + break; + case HTML: + /* don't print HTML */ + break; + case LINK: + g_string_append_printf(out, "\\href{%s}{", elt->contents.link->url); + print_latex_element_list(out, elt->contents.link->label); + g_string_append_printf(out, "}"); + break; + case IMAGE: + g_string_append_printf(out, "\\includegraphics{%s}", elt->contents.link->url); + break; + case EMPH: + g_string_append_printf(out, "\\emph{"); + print_latex_element_list(out, elt->children); + g_string_append_printf(out, "}"); + break; + case STRONG: + g_string_append_printf(out, "\\textbf{"); + print_latex_element_list(out, elt->children); + g_string_append_printf(out, "}"); + break; + case LIST: + print_latex_element_list(out, elt->children); + break; + case RAW: + /* Shouldn't occur - these are handled by process_raw_blocks() */ + assert(elt->key != RAW); + break; + case H1: case H2: case H3: + pad(out, 2); + lev = elt->key - H1 + 1; /* assumes H1 ... H6 are in order */ + g_string_append_printf(out, "\\"); + for (i = elt->key; i > H1; i--) + g_string_append_printf(out, "sub"); + g_string_append_printf(out, "section{"); + print_latex_element_list(out, elt->children); + g_string_append_printf(out, "}"); + padded = 0; + break; + case H4: case H5: case H6: + pad(out, 2); + g_string_append_printf(out, "\\noindent\\textbf{"); + print_latex_element_list(out, elt->children); + g_string_append_printf(out, "}"); + padded = 0; + break; + case PLAIN: + pad(out, 1); + print_latex_element_list(out, elt->children); + padded = 0; + break; + case PARA: + pad(out, 2); + print_latex_element_list(out, elt->children); + padded = 0; + break; + case HRULE: + pad(out, 2); + g_string_append_printf(out, "\\begin{center}\\rule{3in}{0.4pt}\\end{center}\n"); + padded = 0; + break; + case HTMLBLOCK: + /* don't print HTML block */ + break; + case VERBATIM: + pad(out, 1); + g_string_append_printf(out, "\\begin{verbatim}\n"); + print_latex_string(out, elt->contents.str); + g_string_append_printf(out, "\n\\end{verbatim}"); + padded = 0; + break; + case BULLETLIST: + pad(out, 1); + g_string_append_printf(out, "\\begin{itemize}"); + padded = 0; + print_latex_element_list(out, elt->children); + pad(out, 1); + g_string_append_printf(out, "\\end{itemize}"); + padded = 0; + break; + case ORDEREDLIST: + pad(out, 1); + g_string_append_printf(out, "\\begin{enumerate}"); + padded = 0; + print_latex_element_list(out, elt->children); + pad(out, 1); + g_string_append_printf(out, "\\end{enumerate}"); + padded = 0; + break; + case LISTITEM: + pad(out, 1); + g_string_append_printf(out, "\\item "); + padded = 2; + print_latex_element_list(out, elt->children); + g_string_append_printf(out, "\n"); + break; + case BLOCKQUOTE: + pad(out, 1); + g_string_append_printf(out, "\\begin{quote}"); + padded = 0; + print_latex_element_list(out, elt->children); + pad(out, 1); + g_string_append_printf(out, "\\end{quote}"); + padded = 0; + break; + case NOTE: + /* if contents.str == 0, then print note; else ignore, since this + * is a note block that has been incorporated into the notes list */ + if (elt->contents.str == 0) { + g_string_append_printf(out, "\\footnote{"); + padded = 2; + print_latex_element_list(out, elt->children); + g_string_append_printf(out, "}"); + padded = 0; + } + break; + case REFERENCE: + /* Nonprinting */ + break; + default: + fprintf(stderr, "print_latex_element encountered unknown element key = %d\n", elt->key); + exit(EXIT_FAILURE); + } +} + +/********************************************************************** + + Functions for printing Elements as groff (mm macros) + + ***********************************************************************/ + +static bool in_list_item = false; /* True if we're parsing contents of a list item. */ + +/* print_groff_string - print string, escaping for groff */ +static void print_groff_string(GString *out, char *str) { + while (*str != '\0') { + switch (*str) { + case '\\': + g_string_append_printf(out, "\\e"); + break; + default: + g_string_append_c(out, *str); + } + str++; + } +} + +/* print_groff_mm_element_list - print a list of elements as groff ms */ +static void print_groff_mm_element_list(GString *out, element *list) { + int count = 1; + while (list != NULL) { + print_groff_mm_element(out, list, count); + list = list->next; + count++; + } +} + +/* print_groff_mm_element - print an element as groff ms */ +static void print_groff_mm_element(GString *out, element *elt, int count) { + int lev; + switch (elt->key) { + case SPACE: + g_string_append_printf(out, "%s", elt->contents.str); + padded = 0; + break; + case LINEBREAK: + pad(out, 1); + g_string_append_printf(out, ".br\n"); + padded = 0; + break; + case STR: + print_groff_string(out, elt->contents.str); + padded = 0; + break; + case ELLIPSIS: + g_string_append_printf(out, "..."); + break; + case EMDASH: + g_string_append_printf(out, "\\[em]"); + break; + case ENDASH: + g_string_append_printf(out, "\\[en]"); + break; + case APOSTROPHE: + g_string_append_printf(out, "'"); + break; + case SINGLEQUOTED: + g_string_append_printf(out, "`"); + print_groff_mm_element_list(out, elt->children); + g_string_append_printf(out, "'"); + break; + case DOUBLEQUOTED: + g_string_append_printf(out, "\\[lq]"); + print_groff_mm_element_list(out, elt->children); + g_string_append_printf(out, "\\[rq]"); + break; + case CODE: + g_string_append_printf(out, "\\fC"); + print_groff_string(out, elt->contents.str); + g_string_append_printf(out, "\\fR"); + padded = 0; + break; + case HTML: + /* don't print HTML */ + break; + case LINK: + print_groff_mm_element_list(out, elt->contents.link->label); + g_string_append_printf(out, " (%s)", elt->contents.link->url); + padded = 0; + break; + case IMAGE: + g_string_append_printf(out, "[IMAGE: "); + print_groff_mm_element_list(out, elt->contents.link->label); + g_string_append_printf(out, "]"); + padded = 0; + /* not supported */ + break; + case EMPH: + g_string_append_printf(out, "\\fI"); + print_groff_mm_element_list(out, elt->children); + g_string_append_printf(out, "\\fR"); + padded = 0; + break; + case STRONG: + g_string_append_printf(out, "\\fB"); + print_groff_mm_element_list(out, elt->children); + g_string_append_printf(out, "\\fR"); + padded = 0; + break; + case LIST: + print_groff_mm_element_list(out, elt->children); + padded = 0; + break; + case RAW: + /* Shouldn't occur - these are handled by process_raw_blocks() */ + assert(elt->key != RAW); + break; + case H1: case H2: case H3: case H4: case H5: case H6: + lev = elt->key - H1 + 1; + pad(out, 1); + g_string_append_printf(out, ".H %d \"", lev); + print_groff_mm_element_list(out, elt->children); + g_string_append_printf(out, "\""); + padded = 0; + break; + case PLAIN: + pad(out, 1); + print_groff_mm_element_list(out, elt->children); + padded = 0; + break; + case PARA: + pad(out, 1); + if (!in_list_item || count != 1) + g_string_append_printf(out, ".P\n"); + print_groff_mm_element_list(out, elt->children); + padded = 0; + break; + case HRULE: + pad(out, 1); + g_string_append_printf(out, "\\l'\\n(.lu*8u/10u'"); + padded = 0; + break; + case HTMLBLOCK: + /* don't print HTML block */ + break; + case VERBATIM: + pad(out, 1); + g_string_append_printf(out, ".VERBON 2\n"); + print_groff_string(out, elt->contents.str); + g_string_append_printf(out, ".VERBOFF"); + padded = 0; + break; + case BULLETLIST: + pad(out, 1); + g_string_append_printf(out, ".BL"); + padded = 0; + print_groff_mm_element_list(out, elt->children); + pad(out, 1); + g_string_append_printf(out, ".LE 1"); + padded = 0; + break; + case ORDEREDLIST: + pad(out, 1); + g_string_append_printf(out, ".AL"); + padded = 0; + print_groff_mm_element_list(out, elt->children); + pad(out, 1); + g_string_append_printf(out, ".LE 1"); + padded = 0; + break; + case LISTITEM: + pad(out, 1); + g_string_append_printf(out, ".LI\n"); + in_list_item = true; + padded = 2; + print_groff_mm_element_list(out, elt->children); + in_list_item = false; + break; + case BLOCKQUOTE: + pad(out, 1); + g_string_append_printf(out, ".DS I\n"); + padded = 2; + print_groff_mm_element_list(out, elt->children); + pad(out, 1); + g_string_append_printf(out, ".DE"); + padded = 0; + break; + case NOTE: + /* if contents.str == 0, then print note; else ignore, since this + * is a note block that has been incorporated into the notes list */ + if (elt->contents.str == 0) { + g_string_append_printf(out, "\\*F\n"); + g_string_append_printf(out, ".FS\n"); + padded = 2; + print_groff_mm_element_list(out, elt->children); + pad(out, 1); + g_string_append_printf(out, ".FE\n"); + padded = 1; + } + break; + case REFERENCE: + /* Nonprinting */ + break; + default: + fprintf(stderr, "print_groff_mm_element encountered unknown element key = %d\n", elt->key); + exit(EXIT_FAILURE); + } +} + +/********************************************************************** + + Functions for printing Elements as ODF + + ***********************************************************************/ + +/* print_odf_code_string - print string, escaping for HTML and saving newlines +*/ +static void print_odf_code_string(GString *out, char *str) { + char *tmp; + while (*str != '\0') { + switch (*str) { + case '&': + g_string_append_printf(out, "&"); + break; + case '<': + g_string_append_printf(out, "<"); + break; + case '>': + g_string_append_printf(out, ">"); + break; + case '"': + g_string_append_printf(out, """); + break; + case '\n': + g_string_append_printf(out, ""); + break; + case ' ': + tmp = str; + tmp++; + if (*tmp == ' ') { + tmp++; + if (*tmp == ' ') { + tmp++; + if (*tmp == ' ') { + g_string_append_printf(out, ""); + str = tmp; + } else { + g_string_append_printf(out, " "); + } + } else { + g_string_append_printf(out, " "); + } + } else { + g_string_append_printf(out, " "); + } + break; + default: + g_string_append_c(out, *str); + } + str++; + } +} + +/* print_odf_string - print string, escaping for HTML and saving newlines */ +static void print_odf_string(GString *out, char *str) { + char *tmp; + while (*str != '\0') { + switch (*str) { + case '&': + g_string_append_printf(out, "&"); + break; + case '<': + g_string_append_printf(out, "<"); + break; + case '>': + g_string_append_printf(out, ">"); + break; + case '"': + g_string_append_printf(out, """); + break; + case '\n': + tmp = str; + tmp--; + if (*tmp == ' ') { + tmp--; + if (*tmp == ' ') { + g_string_append_printf(out, ""); + } else { + g_string_append_printf(out, "\n"); + } + } else { + g_string_append_printf(out, "\n"); + } + break; + case ' ': + tmp = str; + tmp++; + if (*tmp == ' ') { + tmp++; + if (*tmp == ' ') { + tmp++; + if (*tmp == ' ') { + g_string_append_printf(out, ""); + str = tmp; + } else { + g_string_append_printf(out, " "); + } + } else { + g_string_append_printf(out, " "); + } + } else { + g_string_append_printf(out, " "); + } + break; + default: + g_string_append_c(out, *str); + } + str++; + } +} + +/* print_odf_element_list - print an element list as ODF */ +static void print_odf_element_list(GString *out, element *list) { + while (list != NULL) { + print_odf_element(out, list); + list = list->next; + } +} + +/* print_odf_element - print an element as ODF */ +static void print_odf_element(GString *out, element *elt) { + int lev; + int old_type = 0; + switch (elt->key) { + case SPACE: + g_string_append_printf(out, "%s", elt->contents.str); + break; + case LINEBREAK: + g_string_append_printf(out, ""); + break; + case STR: + print_html_string(out, elt->contents.str, 0); + break; + case ELLIPSIS: + g_string_append_printf(out, "…"); + break; + case EMDASH: + g_string_append_printf(out, "—"); + break; + case ENDASH: + g_string_append_printf(out, "–"); + break; + case APOSTROPHE: + g_string_append_printf(out, "’"); + break; + case SINGLEQUOTED: + g_string_append_printf(out, "‘"); + print_odf_element_list(out, elt->children); + g_string_append_printf(out, "’"); + break; + case DOUBLEQUOTED: + g_string_append_printf(out, "“"); + print_odf_element_list(out, elt->children); + g_string_append_printf(out, "”"); + break; + case CODE: + g_string_append_printf(out, ""); + print_html_string(out, elt->contents.str, 0); + g_string_append_printf(out, ""); + break; + case HTML: + break; + case LINK: + g_string_append_printf(out, "contents.link->url, 0); + g_string_append_printf(out, "\""); + if (strlen(elt->contents.link->title) > 0) { + g_string_append_printf(out, " office:name=\""); + print_html_string(out, elt->contents.link->title, 0); + g_string_append_printf(out, "\""); + } + g_string_append_printf(out, ">"); + print_odf_element_list(out, elt->contents.link->label); + g_string_append_printf(out, ""); + break; + case IMAGE: + g_string_append_printf(out, "\ncontents.link->url); + g_string_append_printf(out,"\" xlink:type=\"simple\" xlink:show=\"embed\" xlink:actuate=\"onLoad\" draw:filter-name=\"<All formats>\"/>\n"); + g_string_append_printf(out, "\n"); + break; + case EMPH: + g_string_append_printf(out, + ""); + print_odf_element_list(out, elt->children); + g_string_append_printf(out, ""); + break; + case STRONG: + g_string_append_printf(out, + ""); + print_odf_element_list(out, elt->children); + g_string_append_printf(out, ""); + break; + case LIST: + print_odf_element_list(out, elt->children); + break; + case RAW: + /* Shouldn't occur - these are handled by process_raw_blocks() */ + assert(elt->key != RAW); + break; + case H1: case H2: case H3: case H4: case H5: case H6: + lev = elt->key - H1 + 1; /* assumes H1 ... H6 are in order */ + g_string_append_printf(out, "", lev); + print_odf_element_list(out, elt->children); + g_string_append_printf(out, "\n"); + padded = 0; + break; + case PLAIN: + print_odf_element_list(out, elt->children); + padded = 0; + break; + case PARA: + g_string_append_printf(out, ""); + print_odf_element_list(out, elt->children); + g_string_append_printf(out, "\n"); + break; + case HRULE: + g_string_append_printf(out,"\n"); + break; + case HTMLBLOCK: + /* don't print HTML block */ + /* but do print HTML comments for raw ODF */ + if (strncmp(elt->contents.str,"" from end */ + elt->contents.str[strlen(elt->contents.str)-3] = '\0'; + g_string_append_printf(out, "%s", &elt->contents.str[4]); + } + break; + case VERBATIM: + old_type = odf_type; + odf_type = VERBATIM; + g_string_append_printf(out, ""); + print_odf_code_string(out, elt->contents.str); + g_string_append_printf(out, "\n"); + odf_type = old_type; + break; + case BULLETLIST: + if ((odf_type == BULLETLIST) || + (odf_type == ORDEREDLIST)) { + /* I think this was made unnecessary by another change. + Same for ORDEREDLIST below */ + /* g_string_append_printf(out, ""); */ + } + old_type = odf_type; + odf_type = BULLETLIST; + g_string_append_printf(out, "%s", ""); + print_odf_element_list(out, elt->children); + g_string_append_printf(out, "%s", ""); + odf_type = old_type; + break; + case ORDEREDLIST: + if ((odf_type == BULLETLIST) || + (odf_type == ORDEREDLIST)) { + /* g_string_append_printf(out, ""); */ + } + old_type = odf_type; + odf_type = ORDEREDLIST; + g_string_append_printf(out, "%s", "\n"); + print_odf_element_list(out, elt->children); + g_string_append_printf(out, "%s", "\n"); + odf_type = old_type; + break; + case LISTITEM: + g_string_append_printf(out, "\n"); + if (elt->children->children->key != PARA) { + g_string_append_printf(out, ""); + } + print_odf_element_list(out, elt->children); + + if ((list_contains_key(elt->children,BULLETLIST) || + (list_contains_key(elt->children,ORDEREDLIST)))) { + } else { + if (elt->children->children->key != PARA) { + g_string_append_printf(out, ""); + } + } + g_string_append_printf(out, "\n"); + break; + case BLOCKQUOTE: + old_type = odf_type; + odf_type = BLOCKQUOTE; + print_odf_element_list(out, elt->children); + odf_type = old_type; + break; + case REFERENCE: + break; + case NOTE: + old_type = odf_type; + odf_type = NOTE; + /* if contents.str == 0 then print; else ignore - like above */ + if (elt->contents.str == 0) { + g_string_append_printf(out, "\n"); + print_odf_element_list(out, elt->children); + g_string_append_printf(out, "\n\n"); + } + elt->children = NULL; + odf_type = old_type; + break; + break; default: + fprintf(stderr, "print_odf_element encountered unknown element key = %d\n", elt->key); + exit(EXIT_FAILURE); + } +} + +/********************************************************************** + + Parameterized function for printing an Element. + + ***********************************************************************/ + +void print_element_list(GString *out, element *elt, int format, int exts) { + /* Initialize globals */ + endnotes = NULL; + notenumber = 0; + + extensions = exts; + padded = 2; /* set padding to 2, so no extra blank lines at beginning */ + switch (format) { + case HTML_FORMAT: + print_html_element_list(out, elt, false); + if (endnotes != NULL) { + pad(out, 2); + print_html_endnotes(out); + } + break; + case LATEX_FORMAT: + print_latex_element_list(out, elt); + break; + case GROFF_MM_FORMAT: + print_groff_mm_element_list(out, elt); + break; + case ODF_FORMAT: + print_odf_header(out); + g_string_append_printf(out, "\n\n"); + if (elt != NULL) print_odf_element_list(out,elt); + print_odf_footer(out); + break; + default: + fprintf(stderr, "print_element - unknown format = %d\n", format); + exit(EXIT_FAILURE); + } +} diff --git a/supportlibs/pegmarkdown/markdown_parser.c b/supportlibs/pegmarkdown/markdown_parser.c new file mode 100644 index 000000000..582b35c3c --- /dev/null +++ b/supportlibs/pegmarkdown/markdown_parser.c @@ -0,0 +1,6665 @@ +/* A recursive-descent parser generated by peg 0.1.9 */ + +#include +#include +#include +#define YYRULECOUNT 237 + +/********************************************************************** + + markdown_parser.leg - markdown parser in C using a PEG grammar. + (c) 2008 John MacFarlane (jgm at berkeley dot edu). + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License or the MIT + license. See LICENSE for details. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + ***********************************************************************/ + +#include +#include +#include "markdown_peg.h" +#include "utility_functions.h" + + + +/********************************************************************** + + Definitions for leg parser generator. + YY_INPUT is the function the parser calls to get new input. + We take all new input from (static) charbuf. + + ***********************************************************************/ + + + +# define YYSTYPE element * +#ifdef __DEBUG__ +# define YY_DEBUG 1 +#endif + +#define YY_INPUT(buf, result, max_size) \ +{ \ + int yyc; \ + if (charbuf && *charbuf != '\0') { \ + yyc= *charbuf++; \ + } else { \ + yyc= EOF; \ + } \ + result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \ +} + +#define YY_RULE(T) T + + +/********************************************************************** + + PEG grammar and parser actions for markdown syntax. + + ***********************************************************************/ + + +#ifndef YY_LOCAL +#define YY_LOCAL(T) static T +#endif +#ifndef YY_ACTION +#define YY_ACTION(T) static T +#endif +#ifndef YY_RULE +#define YY_RULE(T) static T +#endif +#ifndef YY_PARSE +#define YY_PARSE(T) T +#endif +#ifndef YYPARSE +#define YYPARSE yyparse +#endif +#ifndef YYPARSEFROM +#define YYPARSEFROM yyparsefrom +#endif +#ifndef YY_INPUT +#define YY_INPUT(buf, result, max_size) \ + { \ + int yyc= getchar(); \ + result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \ + yyprintf((stderr, "<%c>", yyc)); \ + } +#endif +#ifndef YY_BEGIN +#define YY_BEGIN ( ctx->begin= ctx->pos, 1) +#endif +#ifndef YY_END +#define YY_END ( ctx->end= ctx->pos, 1) +#endif +#ifdef YY_DEBUG +# define yyprintf(args) fprintf args +#else +# define yyprintf(args) +#endif +#ifndef YYSTYPE +#define YYSTYPE int +#endif + +#ifndef YY_PART + +typedef struct _yycontext yycontext; +typedef void (*yyaction)(yycontext *ctx, char *yytext, int yyleng); +typedef struct _yythunk { int begin, end; yyaction action; struct _yythunk *next; } yythunk; + +struct _yycontext { + char *buf; + int buflen; + int pos; + int limit; + char *text; + int textlen; + int begin; + int end; + int textmax; + yythunk *thunks; + int thunkslen; + int thunkpos; + YYSTYPE yy; + YYSTYPE *val; + YYSTYPE *vals; + int valslen; +#ifdef YY_CTX_MEMBERS + YY_CTX_MEMBERS +#endif +}; + +#ifdef YY_CTX_LOCAL +#define YY_CTX_PARAM_ yycontext *yyctx, +#define YY_CTX_PARAM yycontext *yyctx +#define YY_CTX_ARG_ yyctx, +#define YY_CTX_ARG yyctx +#else +#define YY_CTX_PARAM_ +#define YY_CTX_PARAM +#define YY_CTX_ARG_ +#define YY_CTX_ARG +yycontext yyctx0; +yycontext *yyctx= &yyctx0; +#endif + +YY_LOCAL(int) yyrefill(yycontext *ctx) +{ + int yyn; + while (ctx->buflen - ctx->pos < 512) + { + ctx->buflen *= 2; + ctx->buf= (char *)realloc(ctx->buf, ctx->buflen); + } + YY_INPUT((ctx->buf + ctx->pos), yyn, (ctx->buflen - ctx->pos)); + if (!yyn) return 0; + ctx->limit += yyn; + return 1; +} + +YY_LOCAL(int) yymatchDot(yycontext *ctx) +{ + if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0; + ++ctx->pos; + return 1; +} + +YY_LOCAL(int) yymatchChar(yycontext *ctx, int c) +{ + if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0; + if ((unsigned char)ctx->buf[ctx->pos] == c) + { + ++ctx->pos; + yyprintf((stderr, " ok yymatchChar(ctx, %c) @ %s\n", c, ctx->buf+ctx->pos)); + return 1; + } + yyprintf((stderr, " fail yymatchChar(ctx, %c) @ %s\n", c, ctx->buf+ctx->pos)); + return 0; +} + +YY_LOCAL(int) yymatchString(yycontext *ctx, char *s) +{ + int yysav= ctx->pos; + while (*s) + { + if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0; + if (ctx->buf[ctx->pos] != *s) + { + ctx->pos= yysav; + return 0; + } + ++s; + ++ctx->pos; + } + return 1; +} + +YY_LOCAL(int) yymatchClass(yycontext *ctx, unsigned char *bits) +{ + int c; + if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0; + c= (unsigned char)ctx->buf[ctx->pos]; + if (bits[c >> 3] & (1 << (c & 7))) + { + ++ctx->pos; + yyprintf((stderr, " ok yymatchClass @ %s\n", ctx->buf+ctx->pos)); + return 1; + } + yyprintf((stderr, " fail yymatchClass @ %s\n", ctx->buf+ctx->pos)); + return 0; +} + +YY_LOCAL(void) yyDo(yycontext *ctx, yyaction action, int begin, int end) +{ + while (ctx->thunkpos >= ctx->thunkslen) + { + ctx->thunkslen *= 2; + ctx->thunks= (yythunk *)realloc(ctx->thunks, sizeof(yythunk) * ctx->thunkslen); + } + ctx->thunks[ctx->thunkpos].begin= begin; + ctx->thunks[ctx->thunkpos].end= end; + ctx->thunks[ctx->thunkpos].action= action; + ++ctx->thunkpos; +} + +YY_LOCAL(int) yyText(yycontext *ctx, int begin, int end) +{ + int yyleng= end - begin; + if (yyleng <= 0) + yyleng= 0; + else + { + while (ctx->textlen < (yyleng + 1)) + { + ctx->textlen *= 2; + ctx->text= (char *)realloc(ctx->text, ctx->textlen); + } + memcpy(ctx->text, ctx->buf + begin, yyleng); + } + ctx->text[yyleng]= '\0'; + return yyleng; +} + +YY_LOCAL(void) yyDone(yycontext *ctx) +{ + int pos; + for (pos= 0; pos < ctx->thunkpos; ++pos) + { + yythunk *thunk= &ctx->thunks[pos]; + int yyleng= thunk->end ? yyText(ctx, thunk->begin, thunk->end) : thunk->begin; + yyprintf((stderr, "DO [%d] %p %s\n", pos, thunk->action, ctx->text)); + thunk->action(ctx, ctx->text, yyleng); + } + ctx->thunkpos= 0; +} + +YY_LOCAL(void) yyCommit(yycontext *ctx) +{ + if ((ctx->limit -= ctx->pos)) + { + memmove(ctx->buf, ctx->buf + ctx->pos, ctx->limit); + } + ctx->begin -= ctx->pos; + ctx->end -= ctx->pos; + ctx->pos= ctx->thunkpos= 0; +} + +YY_LOCAL(int) yyAccept(yycontext *ctx, int tp0) +{ + if (tp0) + { + fprintf(stderr, "accept denied at %d\n", tp0); + return 0; + } + else + { + yyDone(ctx); + yyCommit(ctx); + } + return 1; +} + +YY_LOCAL(void) yyPush(yycontext *ctx, char *text, int count) { ctx->val += count; } +YY_LOCAL(void) yyPop(yycontext *ctx, char *text, int count) { ctx->val -= count; } +YY_LOCAL(void) yySet(yycontext *ctx, char *text, int count) { ctx->val[count]= ctx->yy; } + +#endif /* YY_PART */ + +#define YYACCEPT yyAccept(ctx, yythunkpos0) + +YY_RULE(int) yy_Notes(yycontext *ctx); /* 237 */ +YY_RULE(int) yy_RawNoteBlock(yycontext *ctx); /* 236 */ +YY_RULE(int) yy_RawNoteReference(yycontext *ctx); /* 235 */ +YY_RULE(int) yy_DoubleQuoteEnd(yycontext *ctx); /* 234 */ +YY_RULE(int) yy_DoubleQuoteStart(yycontext *ctx); /* 233 */ +YY_RULE(int) yy_SingleQuoteEnd(yycontext *ctx); /* 232 */ +YY_RULE(int) yy_SingleQuoteStart(yycontext *ctx); /* 231 */ +YY_RULE(int) yy_EnDash(yycontext *ctx); /* 230 */ +YY_RULE(int) yy_EmDash(yycontext *ctx); /* 229 */ +YY_RULE(int) yy_Apostrophe(yycontext *ctx); /* 228 */ +YY_RULE(int) yy_DoubleQuoted(yycontext *ctx); /* 227 */ +YY_RULE(int) yy_SingleQuoted(yycontext *ctx); /* 226 */ +YY_RULE(int) yy_Dash(yycontext *ctx); /* 225 */ +YY_RULE(int) yy_Ellipsis(yycontext *ctx); /* 224 */ +YY_RULE(int) yy_Digit(yycontext *ctx); /* 223 */ +YY_RULE(int) yy_ExtendedSpecialChar(yycontext *ctx); /* 222 */ +YY_RULE(int) yy_AlphanumericAscii(yycontext *ctx); /* 221 */ +YY_RULE(int) yy_Quoted(yycontext *ctx); /* 220 */ +YY_RULE(int) yy_HtmlTag(yycontext *ctx); /* 219 */ +YY_RULE(int) yy_Ticks5(yycontext *ctx); /* 218 */ +YY_RULE(int) yy_Ticks4(yycontext *ctx); /* 217 */ +YY_RULE(int) yy_Ticks3(yycontext *ctx); /* 216 */ +YY_RULE(int) yy_Ticks2(yycontext *ctx); /* 215 */ +YY_RULE(int) yy_Ticks1(yycontext *ctx); /* 214 */ +YY_RULE(int) yy_SkipBlock(yycontext *ctx); /* 213 */ +YY_RULE(int) yy_References(yycontext *ctx); /* 212 */ +YY_RULE(int) yy_EmptyTitle(yycontext *ctx); /* 211 */ +YY_RULE(int) yy_RefTitleParens(yycontext *ctx); /* 210 */ +YY_RULE(int) yy_RefTitleDouble(yycontext *ctx); /* 209 */ +YY_RULE(int) yy_RefTitleSingle(yycontext *ctx); /* 208 */ +YY_RULE(int) yy_RefTitle(yycontext *ctx); /* 207 */ +YY_RULE(int) yy_RefSrc(yycontext *ctx); /* 206 */ +YY_RULE(int) yy_AutoLinkEmail(yycontext *ctx); /* 205 */ +YY_RULE(int) yy_AutoLinkUrl(yycontext *ctx); /* 204 */ +YY_RULE(int) yy_TitleDouble(yycontext *ctx); /* 203 */ +YY_RULE(int) yy_TitleSingle(yycontext *ctx); /* 202 */ +YY_RULE(int) yy_Nonspacechar(yycontext *ctx); /* 201 */ +YY_RULE(int) yy_SourceContents(yycontext *ctx); /* 200 */ +YY_RULE(int) yy_Title(yycontext *ctx); /* 199 */ +YY_RULE(int) yy_Source(yycontext *ctx); /* 198 */ +YY_RULE(int) yy_Label(yycontext *ctx); /* 197 */ +YY_RULE(int) yy_ReferenceLinkSingle(yycontext *ctx); /* 196 */ +YY_RULE(int) yy_ReferenceLinkDouble(yycontext *ctx); /* 195 */ +YY_RULE(int) yy_AutoLink(yycontext *ctx); /* 194 */ +YY_RULE(int) yy_ReferenceLink(yycontext *ctx); /* 193 */ +YY_RULE(int) yy_ExplicitLink(yycontext *ctx); /* 192 */ +YY_RULE(int) yy_StrongUl(yycontext *ctx); /* 191 */ +YY_RULE(int) yy_StrongStar(yycontext *ctx); /* 190 */ +YY_RULE(int) yy_Whitespace(yycontext *ctx); /* 189 */ +YY_RULE(int) yy_EmphUl(yycontext *ctx); /* 188 */ +YY_RULE(int) yy_EmphStar(yycontext *ctx); /* 187 */ +YY_RULE(int) yy_StarLine(yycontext *ctx); /* 186 */ +YY_RULE(int) yy_UlLine(yycontext *ctx); /* 185 */ +YY_RULE(int) yy_SpecialChar(yycontext *ctx); /* 184 */ +YY_RULE(int) yy_Eof(yycontext *ctx); /* 183 */ +YY_RULE(int) yy_NormalEndline(yycontext *ctx); /* 182 */ +YY_RULE(int) yy_TerminalEndline(yycontext *ctx); /* 181 */ +YY_RULE(int) yy_LineBreak(yycontext *ctx); /* 180 */ +YY_RULE(int) yy_CharEntity(yycontext *ctx); /* 179 */ +YY_RULE(int) yy_DecEntity(yycontext *ctx); /* 178 */ +YY_RULE(int) yy_HexEntity(yycontext *ctx); /* 177 */ +YY_RULE(int) yy_AposChunk(yycontext *ctx); /* 176 */ +YY_RULE(int) yy_Alphanumeric(yycontext *ctx); /* 175 */ +YY_RULE(int) yy_StrChunk(yycontext *ctx); /* 174 */ +YY_RULE(int) yy_NormalChar(yycontext *ctx); /* 173 */ +YY_RULE(int) yy_Symbol(yycontext *ctx); /* 172 */ +YY_RULE(int) yy_Smart(yycontext *ctx); /* 171 */ +YY_RULE(int) yy_EscapedChar(yycontext *ctx); /* 170 */ +YY_RULE(int) yy_Entity(yycontext *ctx); /* 169 */ +YY_RULE(int) yy_RawHtml(yycontext *ctx); /* 168 */ +YY_RULE(int) yy_Code(yycontext *ctx); /* 167 */ +YY_RULE(int) yy_InlineNote(yycontext *ctx); /* 166 */ +YY_RULE(int) yy_NoteReference(yycontext *ctx); /* 165 */ +YY_RULE(int) yy_Link(yycontext *ctx); /* 164 */ +YY_RULE(int) yy_Image(yycontext *ctx); /* 163 */ +YY_RULE(int) yy_Emph(yycontext *ctx); /* 162 */ +YY_RULE(int) yy_Strong(yycontext *ctx); /* 161 */ +YY_RULE(int) yy_Space(yycontext *ctx); /* 160 */ +YY_RULE(int) yy_UlOrStarLine(yycontext *ctx); /* 159 */ +YY_RULE(int) yy_Str(yycontext *ctx); /* 158 */ +YY_RULE(int) yy_InStyleTags(yycontext *ctx); /* 157 */ +YY_RULE(int) yy_StyleClose(yycontext *ctx); /* 156 */ +YY_RULE(int) yy_StyleOpen(yycontext *ctx); /* 155 */ +YY_RULE(int) yy_HtmlBlockType(yycontext *ctx); /* 154 */ +YY_RULE(int) yy_HtmlBlockSelfClosing(yycontext *ctx); /* 153 */ +YY_RULE(int) yy_HtmlComment(yycontext *ctx); /* 152 */ +YY_RULE(int) yy_HtmlBlockInTags(yycontext *ctx); /* 151 */ +YY_RULE(int) yy_HtmlBlockScript(yycontext *ctx); /* 150 */ +YY_RULE(int) yy_HtmlBlockCloseScript(yycontext *ctx); /* 149 */ +YY_RULE(int) yy_HtmlBlockOpenScript(yycontext *ctx); /* 148 */ +YY_RULE(int) yy_HtmlBlockTr(yycontext *ctx); /* 147 */ +YY_RULE(int) yy_HtmlBlockCloseTr(yycontext *ctx); /* 146 */ +YY_RULE(int) yy_HtmlBlockOpenTr(yycontext *ctx); /* 145 */ +YY_RULE(int) yy_HtmlBlockThead(yycontext *ctx); /* 144 */ +YY_RULE(int) yy_HtmlBlockCloseThead(yycontext *ctx); /* 143 */ +YY_RULE(int) yy_HtmlBlockOpenThead(yycontext *ctx); /* 142 */ +YY_RULE(int) yy_HtmlBlockTh(yycontext *ctx); /* 141 */ +YY_RULE(int) yy_HtmlBlockCloseTh(yycontext *ctx); /* 140 */ +YY_RULE(int) yy_HtmlBlockOpenTh(yycontext *ctx); /* 139 */ +YY_RULE(int) yy_HtmlBlockTfoot(yycontext *ctx); /* 138 */ +YY_RULE(int) yy_HtmlBlockCloseTfoot(yycontext *ctx); /* 137 */ +YY_RULE(int) yy_HtmlBlockOpenTfoot(yycontext *ctx); /* 136 */ +YY_RULE(int) yy_HtmlBlockTd(yycontext *ctx); /* 135 */ +YY_RULE(int) yy_HtmlBlockCloseTd(yycontext *ctx); /* 134 */ +YY_RULE(int) yy_HtmlBlockOpenTd(yycontext *ctx); /* 133 */ +YY_RULE(int) yy_HtmlBlockTbody(yycontext *ctx); /* 132 */ +YY_RULE(int) yy_HtmlBlockCloseTbody(yycontext *ctx); /* 131 */ +YY_RULE(int) yy_HtmlBlockOpenTbody(yycontext *ctx); /* 130 */ +YY_RULE(int) yy_HtmlBlockLi(yycontext *ctx); /* 129 */ +YY_RULE(int) yy_HtmlBlockCloseLi(yycontext *ctx); /* 128 */ +YY_RULE(int) yy_HtmlBlockOpenLi(yycontext *ctx); /* 127 */ +YY_RULE(int) yy_HtmlBlockFrameset(yycontext *ctx); /* 126 */ +YY_RULE(int) yy_HtmlBlockCloseFrameset(yycontext *ctx); /* 125 */ +YY_RULE(int) yy_HtmlBlockOpenFrameset(yycontext *ctx); /* 124 */ +YY_RULE(int) yy_HtmlBlockDt(yycontext *ctx); /* 123 */ +YY_RULE(int) yy_HtmlBlockCloseDt(yycontext *ctx); /* 122 */ +YY_RULE(int) yy_HtmlBlockOpenDt(yycontext *ctx); /* 121 */ +YY_RULE(int) yy_HtmlBlockDd(yycontext *ctx); /* 120 */ +YY_RULE(int) yy_HtmlBlockCloseDd(yycontext *ctx); /* 119 */ +YY_RULE(int) yy_HtmlBlockOpenDd(yycontext *ctx); /* 118 */ +YY_RULE(int) yy_HtmlBlockUl(yycontext *ctx); /* 117 */ +YY_RULE(int) yy_HtmlBlockCloseUl(yycontext *ctx); /* 116 */ +YY_RULE(int) yy_HtmlBlockOpenUl(yycontext *ctx); /* 115 */ +YY_RULE(int) yy_HtmlBlockTable(yycontext *ctx); /* 114 */ +YY_RULE(int) yy_HtmlBlockCloseTable(yycontext *ctx); /* 113 */ +YY_RULE(int) yy_HtmlBlockOpenTable(yycontext *ctx); /* 112 */ +YY_RULE(int) yy_HtmlBlockPre(yycontext *ctx); /* 111 */ +YY_RULE(int) yy_HtmlBlockClosePre(yycontext *ctx); /* 110 */ +YY_RULE(int) yy_HtmlBlockOpenPre(yycontext *ctx); /* 109 */ +YY_RULE(int) yy_HtmlBlockP(yycontext *ctx); /* 108 */ +YY_RULE(int) yy_HtmlBlockCloseP(yycontext *ctx); /* 107 */ +YY_RULE(int) yy_HtmlBlockOpenP(yycontext *ctx); /* 106 */ +YY_RULE(int) yy_HtmlBlockOl(yycontext *ctx); /* 105 */ +YY_RULE(int) yy_HtmlBlockCloseOl(yycontext *ctx); /* 104 */ +YY_RULE(int) yy_HtmlBlockOpenOl(yycontext *ctx); /* 103 */ +YY_RULE(int) yy_HtmlBlockNoscript(yycontext *ctx); /* 102 */ +YY_RULE(int) yy_HtmlBlockCloseNoscript(yycontext *ctx); /* 101 */ +YY_RULE(int) yy_HtmlBlockOpenNoscript(yycontext *ctx); /* 100 */ +YY_RULE(int) yy_HtmlBlockNoframes(yycontext *ctx); /* 99 */ +YY_RULE(int) yy_HtmlBlockCloseNoframes(yycontext *ctx); /* 98 */ +YY_RULE(int) yy_HtmlBlockOpenNoframes(yycontext *ctx); /* 97 */ +YY_RULE(int) yy_HtmlBlockMenu(yycontext *ctx); /* 96 */ +YY_RULE(int) yy_HtmlBlockCloseMenu(yycontext *ctx); /* 95 */ +YY_RULE(int) yy_HtmlBlockOpenMenu(yycontext *ctx); /* 94 */ +YY_RULE(int) yy_HtmlBlockH6(yycontext *ctx); /* 93 */ +YY_RULE(int) yy_HtmlBlockCloseH6(yycontext *ctx); /* 92 */ +YY_RULE(int) yy_HtmlBlockOpenH6(yycontext *ctx); /* 91 */ +YY_RULE(int) yy_HtmlBlockH5(yycontext *ctx); /* 90 */ +YY_RULE(int) yy_HtmlBlockCloseH5(yycontext *ctx); /* 89 */ +YY_RULE(int) yy_HtmlBlockOpenH5(yycontext *ctx); /* 88 */ +YY_RULE(int) yy_HtmlBlockH4(yycontext *ctx); /* 87 */ +YY_RULE(int) yy_HtmlBlockCloseH4(yycontext *ctx); /* 86 */ +YY_RULE(int) yy_HtmlBlockOpenH4(yycontext *ctx); /* 85 */ +YY_RULE(int) yy_HtmlBlockH3(yycontext *ctx); /* 84 */ +YY_RULE(int) yy_HtmlBlockCloseH3(yycontext *ctx); /* 83 */ +YY_RULE(int) yy_HtmlBlockOpenH3(yycontext *ctx); /* 82 */ +YY_RULE(int) yy_HtmlBlockH2(yycontext *ctx); /* 81 */ +YY_RULE(int) yy_HtmlBlockCloseH2(yycontext *ctx); /* 80 */ +YY_RULE(int) yy_HtmlBlockOpenH2(yycontext *ctx); /* 79 */ +YY_RULE(int) yy_HtmlBlockH1(yycontext *ctx); /* 78 */ +YY_RULE(int) yy_HtmlBlockCloseH1(yycontext *ctx); /* 77 */ +YY_RULE(int) yy_HtmlBlockOpenH1(yycontext *ctx); /* 76 */ +YY_RULE(int) yy_HtmlBlockForm(yycontext *ctx); /* 75 */ +YY_RULE(int) yy_HtmlBlockCloseForm(yycontext *ctx); /* 74 */ +YY_RULE(int) yy_HtmlBlockOpenForm(yycontext *ctx); /* 73 */ +YY_RULE(int) yy_HtmlBlockFieldset(yycontext *ctx); /* 72 */ +YY_RULE(int) yy_HtmlBlockCloseFieldset(yycontext *ctx); /* 71 */ +YY_RULE(int) yy_HtmlBlockOpenFieldset(yycontext *ctx); /* 70 */ +YY_RULE(int) yy_HtmlBlockDl(yycontext *ctx); /* 69 */ +YY_RULE(int) yy_HtmlBlockCloseDl(yycontext *ctx); /* 68 */ +YY_RULE(int) yy_HtmlBlockOpenDl(yycontext *ctx); /* 67 */ +YY_RULE(int) yy_HtmlBlockDiv(yycontext *ctx); /* 66 */ +YY_RULE(int) yy_HtmlBlockCloseDiv(yycontext *ctx); /* 65 */ +YY_RULE(int) yy_HtmlBlockOpenDiv(yycontext *ctx); /* 64 */ +YY_RULE(int) yy_HtmlBlockDir(yycontext *ctx); /* 63 */ +YY_RULE(int) yy_HtmlBlockCloseDir(yycontext *ctx); /* 62 */ +YY_RULE(int) yy_HtmlBlockOpenDir(yycontext *ctx); /* 61 */ +YY_RULE(int) yy_HtmlBlockCenter(yycontext *ctx); /* 60 */ +YY_RULE(int) yy_HtmlBlockCloseCenter(yycontext *ctx); /* 59 */ +YY_RULE(int) yy_HtmlBlockOpenCenter(yycontext *ctx); /* 58 */ +YY_RULE(int) yy_HtmlBlockBlockquote(yycontext *ctx); /* 57 */ +YY_RULE(int) yy_HtmlBlockCloseBlockquote(yycontext *ctx); /* 56 */ +YY_RULE(int) yy_HtmlBlockOpenBlockquote(yycontext *ctx); /* 55 */ +YY_RULE(int) yy_HtmlBlockAddress(yycontext *ctx); /* 54 */ +YY_RULE(int) yy_HtmlBlockCloseAddress(yycontext *ctx); /* 53 */ +YY_RULE(int) yy_HtmlAttribute(yycontext *ctx); /* 52 */ +YY_RULE(int) yy_Spnl(yycontext *ctx); /* 51 */ +YY_RULE(int) yy_HtmlBlockOpenAddress(yycontext *ctx); /* 50 */ +YY_RULE(int) yy_OptionallyIndentedLine(yycontext *ctx); /* 49 */ +YY_RULE(int) yy_Indent(yycontext *ctx); /* 48 */ +YY_RULE(int) yy_ListBlockLine(yycontext *ctx); /* 47 */ +YY_RULE(int) yy_ListContinuationBlock(yycontext *ctx); /* 46 */ +YY_RULE(int) yy_ListBlock(yycontext *ctx); /* 45 */ +YY_RULE(int) yy_ListItem(yycontext *ctx); /* 44 */ +YY_RULE(int) yy_Enumerator(yycontext *ctx); /* 43 */ +YY_RULE(int) yy_ListItemTight(yycontext *ctx); /* 42 */ +YY_RULE(int) yy_ListLoose(yycontext *ctx); /* 41 */ +YY_RULE(int) yy_ListTight(yycontext *ctx); /* 40 */ +YY_RULE(int) yy_Spacechar(yycontext *ctx); /* 39 */ +YY_RULE(int) yy_Bullet(yycontext *ctx); /* 38 */ +YY_RULE(int) yy_VerbatimChunk(yycontext *ctx); /* 37 */ +YY_RULE(int) yy_IndentedLine(yycontext *ctx); /* 36 */ +YY_RULE(int) yy_NonblankIndentedLine(yycontext *ctx); /* 35 */ +YY_RULE(int) yy_Line(yycontext *ctx); /* 34 */ +YY_RULE(int) yy_BlockQuoteRaw(yycontext *ctx); /* 33 */ +YY_RULE(int) yy_Endline(yycontext *ctx); /* 32 */ +YY_RULE(int) yy_RawLine(yycontext *ctx); /* 31 */ +YY_RULE(int) yy_SetextBottom2(yycontext *ctx); /* 30 */ +YY_RULE(int) yy_SetextBottom1(yycontext *ctx); /* 29 */ +YY_RULE(int) yy_SetextHeading2(yycontext *ctx); /* 28 */ +YY_RULE(int) yy_SetextHeading1(yycontext *ctx); /* 27 */ +YY_RULE(int) yy_SetextHeading(yycontext *ctx); /* 26 */ +YY_RULE(int) yy_AtxHeading(yycontext *ctx); /* 25 */ +YY_RULE(int) yy_AtxStart(yycontext *ctx); /* 24 */ +YY_RULE(int) yy_Inline(yycontext *ctx); /* 23 */ +YY_RULE(int) yy_Sp(yycontext *ctx); /* 22 */ +YY_RULE(int) yy_Newline(yycontext *ctx); /* 21 */ +YY_RULE(int) yy_AtxInline(yycontext *ctx); /* 20 */ +YY_RULE(int) yy_Inlines(yycontext *ctx); /* 19 */ +YY_RULE(int) yy_NonindentSpace(yycontext *ctx); /* 18 */ +YY_RULE(int) yy_Plain(yycontext *ctx); /* 17 */ +YY_RULE(int) yy_Para(yycontext *ctx); /* 16 */ +YY_RULE(int) yy_StyleBlock(yycontext *ctx); /* 15 */ +YY_RULE(int) yy_HtmlBlock(yycontext *ctx); /* 14 */ +YY_RULE(int) yy_BulletList(yycontext *ctx); /* 13 */ +YY_RULE(int) yy_OrderedList(yycontext *ctx); /* 12 */ +YY_RULE(int) yy_Heading(yycontext *ctx); /* 11 */ +YY_RULE(int) yy_HorizontalRule(yycontext *ctx); /* 10 */ +YY_RULE(int) yy_Reference(yycontext *ctx); /* 9 */ +YY_RULE(int) yy_Note(yycontext *ctx); /* 8 */ +YY_RULE(int) yy_Verbatim(yycontext *ctx); /* 7 */ +YY_RULE(int) yy_BlockQuote(yycontext *ctx); /* 6 */ +YY_RULE(int) yy_BlankLine(yycontext *ctx); /* 5 */ +YY_RULE(int) yy_Block(yycontext *ctx); /* 4 */ +YY_RULE(int) yy_StartList(yycontext *ctx); /* 3 */ +YY_RULE(int) yy_BOM(yycontext *ctx); /* 2 */ +YY_RULE(int) yy_Doc(yycontext *ctx); /* 1 */ + +YY_ACTION(void) yy_3_RawNoteBlock(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_3_RawNoteBlock\n")); + yy = mk_str_from_list(a, true); + yy->key = RAW; + ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_2_RawNoteBlock(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_RawNoteBlock\n")); + a = cons(mk_str(yytext), a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_1_RawNoteBlock(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_RawNoteBlock\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_2_Notes(yycontext *ctx, char *yytext, int yyleng) +{ +#define b ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_Notes\n")); + notes = reverse(a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef b +#undef a +} +YY_ACTION(void) yy_1_Notes(yycontext *ctx, char *yytext, int yyleng) +{ +#define b ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_Notes\n")); + a = cons(b, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef b +#undef a +} +YY_ACTION(void) yy_2_InlineNote(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_InlineNote\n")); + yy = mk_list(NOTE, a); + yy->contents.str = 0; ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_1_InlineNote(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_InlineNote\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_3_Note(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define ref ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_3_Note\n")); + yy = mk_list(NOTE, a); + yy->contents.str = strdup(ref->contents.str); + ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +#undef ref +} +YY_ACTION(void) yy_2_Note(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define ref ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_Note\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +#undef ref +} +YY_ACTION(void) yy_1_Note(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define ref ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_Note\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +#undef ref +} +YY_ACTION(void) yy_1_RawNoteReference(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_RawNoteReference\n")); + yy = mk_str(yytext); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_NoteReference(yycontext *ctx, char *yytext, int yyleng) +{ +#define ref ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_NoteReference\n")); + element *match; + if (find_note(&match, ref->contents.str)) { + yy = mk_element(NOTE); + assert(match->children != NULL); + yy->children = match->children; + yy->contents.str = 0; + } else { + char *s; + s = malloc(strlen(ref->contents.str) + 4); + sprintf(s, "[^%s]", ref->contents.str); + yy = mk_str(s); + free(s); + } + ; +#undef yythunkpos +#undef yypos +#undef yy +#undef ref +} +YY_ACTION(void) yy_2_DoubleQuoted(yycontext *ctx, char *yytext, int yyleng) +{ +#define b ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_DoubleQuoted\n")); + yy = mk_list(DOUBLEQUOTED, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef b +#undef a +} +YY_ACTION(void) yy_1_DoubleQuoted(yycontext *ctx, char *yytext, int yyleng) +{ +#define b ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_DoubleQuoted\n")); + a = cons(b, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef b +#undef a +} +YY_ACTION(void) yy_2_SingleQuoted(yycontext *ctx, char *yytext, int yyleng) +{ +#define b ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_SingleQuoted\n")); + yy = mk_list(SINGLEQUOTED, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef b +#undef a +} +YY_ACTION(void) yy_1_SingleQuoted(yycontext *ctx, char *yytext, int yyleng) +{ +#define b ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_SingleQuoted\n")); + a = cons(b, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef b +#undef a +} +YY_ACTION(void) yy_1_EmDash(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_EmDash\n")); + yy = mk_element(EMDASH); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_EnDash(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_EnDash\n")); + yy = mk_element(ENDASH); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_Ellipsis(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_Ellipsis\n")); + yy = mk_element(ELLIPSIS); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_Apostrophe(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_Apostrophe\n")); + yy = mk_element(APOSTROPHE); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_Line(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_Line\n")); + yy = mk_str(yytext); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_StartList(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_StartList\n")); + yy = NULL; ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_RawHtml(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_RawHtml\n")); + if (extension(EXT_FILTER_HTML)) { + yy = mk_list(LIST, NULL); + } else { + yy = mk_str(yytext); + yy->key = HTML; + } + ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_Code(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_Code\n")); + yy = mk_str(yytext); yy->key = CODE; ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_2_References(yycontext *ctx, char *yytext, int yyleng) +{ +#define b ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_References\n")); + references = reverse(a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef b +#undef a +} +YY_ACTION(void) yy_1_References(yycontext *ctx, char *yytext, int yyleng) +{ +#define b ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_References\n")); + a = cons(b, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef b +#undef a +} +YY_ACTION(void) yy_1_RefTitle(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_RefTitle\n")); + yy = mk_str(yytext); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_RefSrc(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_RefSrc\n")); + yy = mk_str(yytext); + yy->key = HTML; ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_2_Label(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_Label\n")); + yy = mk_list(LIST, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_1_Label(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_Label\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_1_Reference(yycontext *ctx, char *yytext, int yyleng) +{ +#define t ctx->val[-1] +#define s ctx->val[-2] +#define l ctx->val[-3] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_Reference\n")); + yy = mk_link(l->children, s->contents.str, t->contents.str); + free_element(s); + free_element(t); + free(l); + yy->key = REFERENCE; ; +#undef yythunkpos +#undef yypos +#undef yy +#undef t +#undef s +#undef l +} +YY_ACTION(void) yy_1_AutoLinkEmail(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_AutoLinkEmail\n")); + char *mailto = malloc(strlen(yytext) + 8); + sprintf(mailto, "mailto:%s", yytext); + yy = mk_link(mk_str(yytext), mailto, ""); + free(mailto); + ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_AutoLinkUrl(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_AutoLinkUrl\n")); + yy = mk_link(mk_str(yytext), yytext, ""); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_Title(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_Title\n")); + yy = mk_str(yytext); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_Source(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_Source\n")); + yy = mk_str(yytext); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_ExplicitLink(yycontext *ctx, char *yytext, int yyleng) +{ +#define t ctx->val[-1] +#define s ctx->val[-2] +#define l ctx->val[-3] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_ExplicitLink\n")); + yy = mk_link(l->children, s->contents.str, t->contents.str); + free_element(s); + free_element(t); + free(l); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef t +#undef s +#undef l +} +YY_ACTION(void) yy_1_ReferenceLinkSingle(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_ReferenceLinkSingle\n")); + link match; + if (find_reference(&match, a->children)) { + yy = mk_link(a->children, match.url, match.title); + free(a); + } + else { + element *result; + result = mk_element(LIST); + result->children = cons(mk_str("["), cons(a, cons(mk_str("]"), mk_str(yytext)))); + yy = result; + } + ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_1_ReferenceLinkDouble(yycontext *ctx, char *yytext, int yyleng) +{ +#define b ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_ReferenceLinkDouble\n")); + link match; + if (find_reference(&match, b->children)) { + yy = mk_link(a->children, match.url, match.title); + free(a); + free_element_list(b); + } else { + element *result; + result = mk_element(LIST); + result->children = cons(mk_str("["), cons(a, cons(mk_str("]"), cons(mk_str(yytext), + cons(mk_str("["), cons(b, mk_str("]"))))))); + yy = result; + } + ; +#undef yythunkpos +#undef yypos +#undef yy +#undef b +#undef a +} +YY_ACTION(void) yy_1_Image(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_Image\n")); + if (yy->key == LINK) { + yy->key = IMAGE; + } else { + element *result; + result = yy; + yy->children = cons(mk_str("!"), result->children); + } ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_2_StrongUl(yycontext *ctx, char *yytext, int yyleng) +{ +#define b ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_StrongUl\n")); + yy = mk_list(STRONG, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef b +#undef a +} +YY_ACTION(void) yy_1_StrongUl(yycontext *ctx, char *yytext, int yyleng) +{ +#define b ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_StrongUl\n")); + a = cons(b, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef b +#undef a +} +YY_ACTION(void) yy_2_StrongStar(yycontext *ctx, char *yytext, int yyleng) +{ +#define b ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_StrongStar\n")); + yy = mk_list(STRONG, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef b +#undef a +} +YY_ACTION(void) yy_1_StrongStar(yycontext *ctx, char *yytext, int yyleng) +{ +#define b ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_StrongStar\n")); + a = cons(b, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef b +#undef a +} +YY_ACTION(void) yy_3_EmphUl(yycontext *ctx, char *yytext, int yyleng) +{ +#define b ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_3_EmphUl\n")); + yy = mk_list(EMPH, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef b +#undef a +} +YY_ACTION(void) yy_2_EmphUl(yycontext *ctx, char *yytext, int yyleng) +{ +#define b ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_EmphUl\n")); + a = cons(b, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef b +#undef a +} +YY_ACTION(void) yy_1_EmphUl(yycontext *ctx, char *yytext, int yyleng) +{ +#define b ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_EmphUl\n")); + a = cons(b, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef b +#undef a +} +YY_ACTION(void) yy_3_EmphStar(yycontext *ctx, char *yytext, int yyleng) +{ +#define b ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_3_EmphStar\n")); + yy = mk_list(EMPH, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef b +#undef a +} +YY_ACTION(void) yy_2_EmphStar(yycontext *ctx, char *yytext, int yyleng) +{ +#define b ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_EmphStar\n")); + a = cons(b, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef b +#undef a +} +YY_ACTION(void) yy_1_EmphStar(yycontext *ctx, char *yytext, int yyleng) +{ +#define b ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_EmphStar\n")); + a = cons(b, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef b +#undef a +} +YY_ACTION(void) yy_1_UlOrStarLine(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_UlOrStarLine\n")); + yy = mk_str(yytext); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_Symbol(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_Symbol\n")); + yy = mk_str(yytext); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_LineBreak(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_LineBreak\n")); + yy = mk_element(LINEBREAK); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_TerminalEndline(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_TerminalEndline\n")); + yy = NULL; ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_NormalEndline(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_NormalEndline\n")); + yy = mk_str("\n"); + yy->key = SPACE; ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_Entity(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_Entity\n")); + yy = mk_str(yytext); yy->key = HTML; ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_EscapedChar(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_EscapedChar\n")); + yy = mk_str(yytext); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_AposChunk(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_AposChunk\n")); + yy = mk_element(APOSTROPHE); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_StrChunk(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_StrChunk\n")); + yy = mk_str(yytext); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_3_Str(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_3_Str\n")); + if (a->next == NULL) { yy = a; } else { yy = mk_list(LIST, a); } ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_2_Str(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_Str\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_1_Str(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_Str\n")); + a = cons(mk_str(yytext), a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_1_Space(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_Space\n")); + yy = mk_str(" "); + yy->key = SPACE; ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_3_Inlines(yycontext *ctx, char *yytext, int yyleng) +{ +#define c ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_3_Inlines\n")); + yy = mk_list(LIST, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef c +#undef a +} +YY_ACTION(void) yy_2_Inlines(yycontext *ctx, char *yytext, int yyleng) +{ +#define c ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_Inlines\n")); + a = cons(c, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef c +#undef a +} +YY_ACTION(void) yy_1_Inlines(yycontext *ctx, char *yytext, int yyleng) +{ +#define c ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_Inlines\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef c +#undef a +} +YY_ACTION(void) yy_1_StyleBlock(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_StyleBlock\n")); + if (extension(EXT_FILTER_STYLES)) { + yy = mk_list(LIST, NULL); + } else { + yy = mk_str(yytext); + yy->key = HTMLBLOCK; + } + ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_HtmlBlock(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_HtmlBlock\n")); + if (extension(EXT_FILTER_HTML)) { + yy = mk_list(LIST, NULL); + } else { + yy = mk_str(yytext); + yy->key = HTMLBLOCK; + } + ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_OrderedList(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_OrderedList\n")); + yy->key = ORDEREDLIST; ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_3_ListContinuationBlock(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_3_ListContinuationBlock\n")); + yy = mk_str_from_list(a, false); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_2_ListContinuationBlock(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_ListContinuationBlock\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_1_ListContinuationBlock(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_ListContinuationBlock\n")); + if (strlen(yytext) == 0) + a = cons(mk_str("\001"), a); /* block separator */ + else + a = cons(mk_str(yytext), a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_3_ListBlock(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_3_ListBlock\n")); + yy = mk_str_from_list(a, false); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_2_ListBlock(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_ListBlock\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_1_ListBlock(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_ListBlock\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_3_ListItemTight(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_3_ListItemTight\n")); + element *raw; + raw = mk_str_from_list(a, false); + raw->key = RAW; + yy = mk_element(LISTITEM); + yy->children = raw; + ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_2_ListItemTight(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_ListItemTight\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_1_ListItemTight(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_ListItemTight\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_3_ListItem(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_3_ListItem\n")); + element *raw; + raw = mk_str_from_list(a, false); + raw->key = RAW; + yy = mk_element(LISTITEM); + yy->children = raw; + ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_2_ListItem(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_ListItem\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_1_ListItem(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_ListItem\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_2_ListLoose(yycontext *ctx, char *yytext, int yyleng) +{ +#define b ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_ListLoose\n")); + yy = mk_list(LIST, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef b +#undef a +} +YY_ACTION(void) yy_1_ListLoose(yycontext *ctx, char *yytext, int yyleng) +{ +#define b ctx->val[-1] +#define a ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_ListLoose\n")); + element *li; + li = b->children; + li->contents.str = realloc(li->contents.str, strlen(li->contents.str) + 3); + strcat(li->contents.str, "\n\n"); /* In loose list, \n\n added to end of each element */ + a = cons(b, a); + ; +#undef yythunkpos +#undef yypos +#undef yy +#undef b +#undef a +} +YY_ACTION(void) yy_2_ListTight(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_ListTight\n")); + yy = mk_list(LIST, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_1_ListTight(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_ListTight\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_1_BulletList(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_BulletList\n")); + yy->key = BULLETLIST; ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_HorizontalRule(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_HorizontalRule\n")); + yy = mk_element(HRULE); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_2_Verbatim(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_Verbatim\n")); + yy = mk_str_from_list(a, false); + yy->key = VERBATIM; ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_1_Verbatim(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_Verbatim\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_3_VerbatimChunk(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_3_VerbatimChunk\n")); + yy = mk_str_from_list(a, false); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_2_VerbatimChunk(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_VerbatimChunk\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_1_VerbatimChunk(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_VerbatimChunk\n")); + a = cons(mk_str("\n"), a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_4_BlockQuoteRaw(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_4_BlockQuoteRaw\n")); + yy = mk_str_from_list(a, true); + yy->key = RAW; + ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_3_BlockQuoteRaw(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_3_BlockQuoteRaw\n")); + a = cons(mk_str("\n"), a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_2_BlockQuoteRaw(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_BlockQuoteRaw\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_1_BlockQuoteRaw(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_BlockQuoteRaw\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_1_BlockQuote(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_BlockQuote\n")); + yy = mk_element(BLOCKQUOTE); + yy->children = a; + ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_2_SetextHeading2(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_SetextHeading2\n")); + yy = mk_list(H2, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_1_SetextHeading2(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_SetextHeading2\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_2_SetextHeading1(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_SetextHeading1\n")); + yy = mk_list(H1, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_1_SetextHeading1(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_SetextHeading1\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_2_AtxHeading(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define s ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_AtxHeading\n")); + yy = mk_list(s->key, a); + free(s); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +#undef s +} +YY_ACTION(void) yy_1_AtxHeading(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define s ctx->val[-2] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_AtxHeading\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +#undef s +} +YY_ACTION(void) yy_1_AtxStart(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_AtxStart\n")); + yy = mk_element(H1 + (strlen(yytext) - 1)); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_Plain(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_Plain\n")); + yy = a; yy->key = PLAIN; ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_1_Para(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_Para\n")); + yy = a; yy->key = PARA; ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_2_Doc(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_Doc\n")); + parse_result = reverse(a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} +YY_ACTION(void) yy_1_Doc(yycontext *ctx, char *yytext, int yyleng) +{ +#define a ctx->val[-1] +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_Doc\n")); + a = cons(yy, a); ; +#undef yythunkpos +#undef yypos +#undef yy +#undef a +} + +YY_RULE(int) yy_Notes(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 2, 0); + yyprintf((stderr, "%s\n", "Notes")); if (!yy_StartList(ctx)) goto l1; yyDo(ctx, yySet, -2, 0); + l2:; + { int yypos3= ctx->pos, yythunkpos3= ctx->thunkpos; + { int yypos4= ctx->pos, yythunkpos4= ctx->thunkpos; if (!yy_Note(ctx)) goto l5; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_1_Notes, ctx->begin, ctx->end); goto l4; + l5:; ctx->pos= yypos4; ctx->thunkpos= yythunkpos4; if (!yy_SkipBlock(ctx)) goto l3; + } + l4:; goto l2; + l3:; ctx->pos= yypos3; ctx->thunkpos= yythunkpos3; + } yyDo(ctx, yy_2_Notes, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "Notes", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 2, 0); + return 1; + l1:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Notes", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_RawNoteBlock(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "RawNoteBlock")); if (!yy_StartList(ctx)) goto l6; yyDo(ctx, yySet, -1, 0); + { int yypos9= ctx->pos, yythunkpos9= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l9; goto l6; + l9:; ctx->pos= yypos9; ctx->thunkpos= yythunkpos9; + } if (!yy_OptionallyIndentedLine(ctx)) goto l6; yyDo(ctx, yy_1_RawNoteBlock, ctx->begin, ctx->end); + l7:; + { int yypos8= ctx->pos, yythunkpos8= ctx->thunkpos; + { int yypos10= ctx->pos, yythunkpos10= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l10; goto l8; + l10:; ctx->pos= yypos10; ctx->thunkpos= yythunkpos10; + } if (!yy_OptionallyIndentedLine(ctx)) goto l8; yyDo(ctx, yy_1_RawNoteBlock, ctx->begin, ctx->end); goto l7; + l8:; ctx->pos= yypos8; ctx->thunkpos= yythunkpos8; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l6; + l11:; + { int yypos12= ctx->pos, yythunkpos12= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l12; goto l11; + l12:; ctx->pos= yypos12; ctx->thunkpos= yythunkpos12; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l6; yyDo(ctx, yy_2_RawNoteBlock, ctx->begin, ctx->end); yyDo(ctx, yy_3_RawNoteBlock, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "RawNoteBlock", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 1, 0); + return 1; + l6:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "RawNoteBlock", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_RawNoteReference(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "RawNoteReference")); if (!yymatchString(ctx, "[^")) goto l13; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l13; + { int yypos16= ctx->pos, yythunkpos16= ctx->thunkpos; if (!yy_Newline(ctx)) goto l16; goto l13; + l16:; ctx->pos= yypos16; ctx->thunkpos= yythunkpos16; + } + { int yypos17= ctx->pos, yythunkpos17= ctx->thunkpos; if (!yymatchChar(ctx, ']')) goto l17; goto l13; + l17:; ctx->pos= yypos17; ctx->thunkpos= yythunkpos17; + } if (!yymatchDot(ctx)) goto l13; + l14:; + { int yypos15= ctx->pos, yythunkpos15= ctx->thunkpos; + { int yypos18= ctx->pos, yythunkpos18= ctx->thunkpos; if (!yy_Newline(ctx)) goto l18; goto l15; + l18:; ctx->pos= yypos18; ctx->thunkpos= yythunkpos18; + } + { int yypos19= ctx->pos, yythunkpos19= ctx->thunkpos; if (!yymatchChar(ctx, ']')) goto l19; goto l15; + l19:; ctx->pos= yypos19; ctx->thunkpos= yythunkpos19; + } if (!yymatchDot(ctx)) goto l15; goto l14; + l15:; ctx->pos= yypos15; ctx->thunkpos= yythunkpos15; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l13; if (!yymatchChar(ctx, ']')) goto l13; yyDo(ctx, yy_1_RawNoteReference, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "RawNoteReference", ctx->buf+ctx->pos)); + return 1; + l13:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "RawNoteReference", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_DoubleQuoteEnd(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "DoubleQuoteEnd")); if (!yymatchChar(ctx, '"')) goto l20; + yyprintf((stderr, " ok %s @ %s\n", "DoubleQuoteEnd", ctx->buf+ctx->pos)); + return 1; + l20:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "DoubleQuoteEnd", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_DoubleQuoteStart(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "DoubleQuoteStart")); if (!yymatchChar(ctx, '"')) goto l21; + yyprintf((stderr, " ok %s @ %s\n", "DoubleQuoteStart", ctx->buf+ctx->pos)); + return 1; + l21:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "DoubleQuoteStart", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_SingleQuoteEnd(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "SingleQuoteEnd")); if (!yymatchChar(ctx, '\'')) goto l22; + { int yypos23= ctx->pos, yythunkpos23= ctx->thunkpos; if (!yy_Alphanumeric(ctx)) goto l23; goto l22; + l23:; ctx->pos= yypos23; ctx->thunkpos= yythunkpos23; + } + yyprintf((stderr, " ok %s @ %s\n", "SingleQuoteEnd", ctx->buf+ctx->pos)); + return 1; + l22:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "SingleQuoteEnd", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_SingleQuoteStart(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "SingleQuoteStart")); if (!yymatchChar(ctx, '\'')) goto l24; + { int yypos25= ctx->pos, yythunkpos25= ctx->thunkpos; + { int yypos26= ctx->pos, yythunkpos26= ctx->thunkpos; if (!yy_Spacechar(ctx)) goto l27; goto l26; + l27:; ctx->pos= yypos26; ctx->thunkpos= yythunkpos26; if (!yy_Newline(ctx)) goto l25; + } + l26:; goto l24; + l25:; ctx->pos= yypos25; ctx->thunkpos= yythunkpos25; + } + yyprintf((stderr, " ok %s @ %s\n", "SingleQuoteStart", ctx->buf+ctx->pos)); + return 1; + l24:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "SingleQuoteStart", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_EnDash(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "EnDash")); if (!yymatchChar(ctx, '-')) goto l28; + { int yypos29= ctx->pos, yythunkpos29= ctx->thunkpos; if (!yy_Digit(ctx)) goto l28; ctx->pos= yypos29; ctx->thunkpos= yythunkpos29; + } yyDo(ctx, yy_1_EnDash, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "EnDash", ctx->buf+ctx->pos)); + return 1; + l28:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "EnDash", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_EmDash(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "EmDash")); + { int yypos31= ctx->pos, yythunkpos31= ctx->thunkpos; if (!yymatchString(ctx, "---")) goto l32; goto l31; + l32:; ctx->pos= yypos31; ctx->thunkpos= yythunkpos31; if (!yymatchString(ctx, "--")) goto l30; + } + l31:; yyDo(ctx, yy_1_EmDash, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "EmDash", ctx->buf+ctx->pos)); + return 1; + l30:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "EmDash", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Apostrophe(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Apostrophe")); if (!yymatchChar(ctx, '\'')) goto l33; yyDo(ctx, yy_1_Apostrophe, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "Apostrophe", ctx->buf+ctx->pos)); + return 1; + l33:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Apostrophe", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_DoubleQuoted(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 2, 0); + yyprintf((stderr, "%s\n", "DoubleQuoted")); if (!yy_DoubleQuoteStart(ctx)) goto l34; if (!yy_StartList(ctx)) goto l34; yyDo(ctx, yySet, -2, 0); + { int yypos37= ctx->pos, yythunkpos37= ctx->thunkpos; if (!yy_DoubleQuoteEnd(ctx)) goto l37; goto l34; + l37:; ctx->pos= yypos37; ctx->thunkpos= yythunkpos37; + } if (!yy_Inline(ctx)) goto l34; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_1_DoubleQuoted, ctx->begin, ctx->end); + l35:; + { int yypos36= ctx->pos, yythunkpos36= ctx->thunkpos; + { int yypos38= ctx->pos, yythunkpos38= ctx->thunkpos; if (!yy_DoubleQuoteEnd(ctx)) goto l38; goto l36; + l38:; ctx->pos= yypos38; ctx->thunkpos= yythunkpos38; + } if (!yy_Inline(ctx)) goto l36; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_1_DoubleQuoted, ctx->begin, ctx->end); goto l35; + l36:; ctx->pos= yypos36; ctx->thunkpos= yythunkpos36; + } if (!yy_DoubleQuoteEnd(ctx)) goto l34; yyDo(ctx, yy_2_DoubleQuoted, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "DoubleQuoted", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 2, 0); + return 1; + l34:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "DoubleQuoted", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_SingleQuoted(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 2, 0); + yyprintf((stderr, "%s\n", "SingleQuoted")); if (!yy_SingleQuoteStart(ctx)) goto l39; if (!yy_StartList(ctx)) goto l39; yyDo(ctx, yySet, -2, 0); + { int yypos42= ctx->pos, yythunkpos42= ctx->thunkpos; if (!yy_SingleQuoteEnd(ctx)) goto l42; goto l39; + l42:; ctx->pos= yypos42; ctx->thunkpos= yythunkpos42; + } if (!yy_Inline(ctx)) goto l39; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_1_SingleQuoted, ctx->begin, ctx->end); + l40:; + { int yypos41= ctx->pos, yythunkpos41= ctx->thunkpos; + { int yypos43= ctx->pos, yythunkpos43= ctx->thunkpos; if (!yy_SingleQuoteEnd(ctx)) goto l43; goto l41; + l43:; ctx->pos= yypos43; ctx->thunkpos= yythunkpos43; + } if (!yy_Inline(ctx)) goto l41; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_1_SingleQuoted, ctx->begin, ctx->end); goto l40; + l41:; ctx->pos= yypos41; ctx->thunkpos= yythunkpos41; + } if (!yy_SingleQuoteEnd(ctx)) goto l39; yyDo(ctx, yy_2_SingleQuoted, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "SingleQuoted", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 2, 0); + return 1; + l39:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "SingleQuoted", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Dash(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Dash")); + { int yypos45= ctx->pos, yythunkpos45= ctx->thunkpos; if (!yy_EmDash(ctx)) goto l46; goto l45; + l46:; ctx->pos= yypos45; ctx->thunkpos= yythunkpos45; if (!yy_EnDash(ctx)) goto l44; + } + l45:; + yyprintf((stderr, " ok %s @ %s\n", "Dash", ctx->buf+ctx->pos)); + return 1; + l44:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Dash", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Ellipsis(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Ellipsis")); + { int yypos48= ctx->pos, yythunkpos48= ctx->thunkpos; if (!yymatchString(ctx, "...")) goto l49; goto l48; + l49:; ctx->pos= yypos48; ctx->thunkpos= yythunkpos48; if (!yymatchString(ctx, ". . .")) goto l47; + } + l48:; yyDo(ctx, yy_1_Ellipsis, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "Ellipsis", ctx->buf+ctx->pos)); + return 1; + l47:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Ellipsis", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Digit(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Digit")); if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l50; + yyprintf((stderr, " ok %s @ %s\n", "Digit", ctx->buf+ctx->pos)); + return 1; + l50:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Digit", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_ExtendedSpecialChar(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "ExtendedSpecialChar")); + { int yypos52= ctx->pos, yythunkpos52= ctx->thunkpos; yyText(ctx, ctx->begin, ctx->end); if (!( extension(EXT_SMART) )) goto l53; + { int yypos54= ctx->pos, yythunkpos54= ctx->thunkpos; if (!yymatchChar(ctx, '.')) goto l55; goto l54; + l55:; ctx->pos= yypos54; ctx->thunkpos= yythunkpos54; if (!yymatchChar(ctx, '-')) goto l56; goto l54; + l56:; ctx->pos= yypos54; ctx->thunkpos= yythunkpos54; if (!yymatchChar(ctx, '\'')) goto l57; goto l54; + l57:; ctx->pos= yypos54; ctx->thunkpos= yythunkpos54; if (!yymatchChar(ctx, '"')) goto l53; + } + l54:; goto l52; + l53:; ctx->pos= yypos52; ctx->thunkpos= yythunkpos52; yyText(ctx, ctx->begin, ctx->end); if (!( extension(EXT_NOTES) )) goto l51; if (!yymatchChar(ctx, '^')) goto l51; + } + l52:; + yyprintf((stderr, " ok %s @ %s\n", "ExtendedSpecialChar", ctx->buf+ctx->pos)); + return 1; + l51:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "ExtendedSpecialChar", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_AlphanumericAscii(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "AlphanumericAscii")); if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\003\376\377\377\007\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l58; + yyprintf((stderr, " ok %s @ %s\n", "AlphanumericAscii", ctx->buf+ctx->pos)); + return 1; + l58:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "AlphanumericAscii", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Quoted(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Quoted")); + { int yypos60= ctx->pos, yythunkpos60= ctx->thunkpos; if (!yymatchChar(ctx, '"')) goto l61; + l62:; + { int yypos63= ctx->pos, yythunkpos63= ctx->thunkpos; + { int yypos64= ctx->pos, yythunkpos64= ctx->thunkpos; if (!yymatchChar(ctx, '"')) goto l64; goto l63; + l64:; ctx->pos= yypos64; ctx->thunkpos= yythunkpos64; + } if (!yymatchDot(ctx)) goto l63; goto l62; + l63:; ctx->pos= yypos63; ctx->thunkpos= yythunkpos63; + } if (!yymatchChar(ctx, '"')) goto l61; goto l60; + l61:; ctx->pos= yypos60; ctx->thunkpos= yythunkpos60; if (!yymatchChar(ctx, '\'')) goto l59; + l65:; + { int yypos66= ctx->pos, yythunkpos66= ctx->thunkpos; + { int yypos67= ctx->pos, yythunkpos67= ctx->thunkpos; if (!yymatchChar(ctx, '\'')) goto l67; goto l66; + l67:; ctx->pos= yypos67; ctx->thunkpos= yythunkpos67; + } if (!yymatchDot(ctx)) goto l66; goto l65; + l66:; ctx->pos= yypos66; ctx->thunkpos= yythunkpos66; + } if (!yymatchChar(ctx, '\'')) goto l59; + } + l60:; + yyprintf((stderr, " ok %s @ %s\n", "Quoted", ctx->buf+ctx->pos)); + return 1; + l59:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Quoted", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlTag(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlTag")); if (!yymatchChar(ctx, '<')) goto l68; if (!yy_Spnl(ctx)) goto l68; + { int yypos69= ctx->pos, yythunkpos69= ctx->thunkpos; if (!yymatchChar(ctx, '/')) goto l69; goto l70; + l69:; ctx->pos= yypos69; ctx->thunkpos= yythunkpos69; + } + l70:; if (!yy_AlphanumericAscii(ctx)) goto l68; + l71:; + { int yypos72= ctx->pos, yythunkpos72= ctx->thunkpos; if (!yy_AlphanumericAscii(ctx)) goto l72; goto l71; + l72:; ctx->pos= yypos72; ctx->thunkpos= yythunkpos72; + } if (!yy_Spnl(ctx)) goto l68; + l73:; + { int yypos74= ctx->pos, yythunkpos74= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l74; goto l73; + l74:; ctx->pos= yypos74; ctx->thunkpos= yythunkpos74; + } + { int yypos75= ctx->pos, yythunkpos75= ctx->thunkpos; if (!yymatchChar(ctx, '/')) goto l75; goto l76; + l75:; ctx->pos= yypos75; ctx->thunkpos= yythunkpos75; + } + l76:; if (!yy_Spnl(ctx)) goto l68; if (!yymatchChar(ctx, '>')) goto l68; + yyprintf((stderr, " ok %s @ %s\n", "HtmlTag", ctx->buf+ctx->pos)); + return 1; + l68:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlTag", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Ticks5(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Ticks5")); if (!yymatchString(ctx, "`````")) goto l77; + { int yypos78= ctx->pos, yythunkpos78= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l78; goto l77; + l78:; ctx->pos= yypos78; ctx->thunkpos= yythunkpos78; + } + yyprintf((stderr, " ok %s @ %s\n", "Ticks5", ctx->buf+ctx->pos)); + return 1; + l77:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Ticks5", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Ticks4(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Ticks4")); if (!yymatchString(ctx, "````")) goto l79; + { int yypos80= ctx->pos, yythunkpos80= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l80; goto l79; + l80:; ctx->pos= yypos80; ctx->thunkpos= yythunkpos80; + } + yyprintf((stderr, " ok %s @ %s\n", "Ticks4", ctx->buf+ctx->pos)); + return 1; + l79:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Ticks4", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Ticks3(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Ticks3")); if (!yymatchString(ctx, "```")) goto l81; + { int yypos82= ctx->pos, yythunkpos82= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l82; goto l81; + l82:; ctx->pos= yypos82; ctx->thunkpos= yythunkpos82; + } + yyprintf((stderr, " ok %s @ %s\n", "Ticks3", ctx->buf+ctx->pos)); + return 1; + l81:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Ticks3", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Ticks2(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Ticks2")); if (!yymatchString(ctx, "``")) goto l83; + { int yypos84= ctx->pos, yythunkpos84= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l84; goto l83; + l84:; ctx->pos= yypos84; ctx->thunkpos= yythunkpos84; + } + yyprintf((stderr, " ok %s @ %s\n", "Ticks2", ctx->buf+ctx->pos)); + return 1; + l83:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Ticks2", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Ticks1(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Ticks1")); if (!yymatchChar(ctx, '`')) goto l85; + { int yypos86= ctx->pos, yythunkpos86= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l86; goto l85; + l86:; ctx->pos= yypos86; ctx->thunkpos= yythunkpos86; + } + yyprintf((stderr, " ok %s @ %s\n", "Ticks1", ctx->buf+ctx->pos)); + return 1; + l85:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Ticks1", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_SkipBlock(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "SkipBlock")); + { int yypos88= ctx->pos, yythunkpos88= ctx->thunkpos; if (!yy_HtmlBlock(ctx)) goto l89; goto l88; + l89:; ctx->pos= yypos88; ctx->thunkpos= yythunkpos88; + { int yypos93= ctx->pos, yythunkpos93= ctx->thunkpos; if (!yymatchChar(ctx, '#')) goto l93; goto l90; + l93:; ctx->pos= yypos93; ctx->thunkpos= yythunkpos93; + } + { int yypos94= ctx->pos, yythunkpos94= ctx->thunkpos; if (!yy_SetextBottom1(ctx)) goto l94; goto l90; + l94:; ctx->pos= yypos94; ctx->thunkpos= yythunkpos94; + } + { int yypos95= ctx->pos, yythunkpos95= ctx->thunkpos; if (!yy_SetextBottom2(ctx)) goto l95; goto l90; + l95:; ctx->pos= yypos95; ctx->thunkpos= yythunkpos95; + } + { int yypos96= ctx->pos, yythunkpos96= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l96; goto l90; + l96:; ctx->pos= yypos96; ctx->thunkpos= yythunkpos96; + } if (!yy_RawLine(ctx)) goto l90; + l91:; + { int yypos92= ctx->pos, yythunkpos92= ctx->thunkpos; + { int yypos97= ctx->pos, yythunkpos97= ctx->thunkpos; if (!yymatchChar(ctx, '#')) goto l97; goto l92; + l97:; ctx->pos= yypos97; ctx->thunkpos= yythunkpos97; + } + { int yypos98= ctx->pos, yythunkpos98= ctx->thunkpos; if (!yy_SetextBottom1(ctx)) goto l98; goto l92; + l98:; ctx->pos= yypos98; ctx->thunkpos= yythunkpos98; + } + { int yypos99= ctx->pos, yythunkpos99= ctx->thunkpos; if (!yy_SetextBottom2(ctx)) goto l99; goto l92; + l99:; ctx->pos= yypos99; ctx->thunkpos= yythunkpos99; + } + { int yypos100= ctx->pos, yythunkpos100= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l100; goto l92; + l100:; ctx->pos= yypos100; ctx->thunkpos= yythunkpos100; + } if (!yy_RawLine(ctx)) goto l92; goto l91; + l92:; ctx->pos= yypos92; ctx->thunkpos= yythunkpos92; + } + l101:; + { int yypos102= ctx->pos, yythunkpos102= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l102; goto l101; + l102:; ctx->pos= yypos102; ctx->thunkpos= yythunkpos102; + } goto l88; + l90:; ctx->pos= yypos88; ctx->thunkpos= yythunkpos88; if (!yy_BlankLine(ctx)) goto l103; + l104:; + { int yypos105= ctx->pos, yythunkpos105= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l105; goto l104; + l105:; ctx->pos= yypos105; ctx->thunkpos= yythunkpos105; + } goto l88; + l103:; ctx->pos= yypos88; ctx->thunkpos= yythunkpos88; if (!yy_RawLine(ctx)) goto l87; + } + l88:; + yyprintf((stderr, " ok %s @ %s\n", "SkipBlock", ctx->buf+ctx->pos)); + return 1; + l87:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "SkipBlock", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_References(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 2, 0); + yyprintf((stderr, "%s\n", "References")); if (!yy_StartList(ctx)) goto l106; yyDo(ctx, yySet, -2, 0); + l107:; + { int yypos108= ctx->pos, yythunkpos108= ctx->thunkpos; + { int yypos109= ctx->pos, yythunkpos109= ctx->thunkpos; if (!yy_Reference(ctx)) goto l110; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_1_References, ctx->begin, ctx->end); goto l109; + l110:; ctx->pos= yypos109; ctx->thunkpos= yythunkpos109; if (!yy_SkipBlock(ctx)) goto l108; + } + l109:; goto l107; + l108:; ctx->pos= yypos108; ctx->thunkpos= yythunkpos108; + } yyDo(ctx, yy_2_References, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "References", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 2, 0); + return 1; + l106:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "References", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_EmptyTitle(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "EmptyTitle")); yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l111; if (!yymatchString(ctx, "")) goto l111; yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l111; + yyprintf((stderr, " ok %s @ %s\n", "EmptyTitle", ctx->buf+ctx->pos)); + return 1; + l111:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "EmptyTitle", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_RefTitleParens(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "RefTitleParens")); if (!yy_Spnl(ctx)) goto l112; if (!yymatchChar(ctx, '(')) goto l112; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l112; + l113:; + { int yypos114= ctx->pos, yythunkpos114= ctx->thunkpos; + { int yypos115= ctx->pos, yythunkpos115= ctx->thunkpos; + { int yypos116= ctx->pos, yythunkpos116= ctx->thunkpos; if (!yymatchChar(ctx, ')')) goto l117; if (!yy_Sp(ctx)) goto l117; if (!yy_Newline(ctx)) goto l117; goto l116; + l117:; ctx->pos= yypos116; ctx->thunkpos= yythunkpos116; if (!yy_Newline(ctx)) goto l115; + } + l116:; goto l114; + l115:; ctx->pos= yypos115; ctx->thunkpos= yythunkpos115; + } if (!yymatchDot(ctx)) goto l114; goto l113; + l114:; ctx->pos= yypos114; ctx->thunkpos= yythunkpos114; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l112; if (!yymatchChar(ctx, ')')) goto l112; + yyprintf((stderr, " ok %s @ %s\n", "RefTitleParens", ctx->buf+ctx->pos)); + return 1; + l112:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "RefTitleParens", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_RefTitleDouble(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "RefTitleDouble")); if (!yy_Spnl(ctx)) goto l118; if (!yymatchChar(ctx, '"')) goto l118; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l118; + l119:; + { int yypos120= ctx->pos, yythunkpos120= ctx->thunkpos; + { int yypos121= ctx->pos, yythunkpos121= ctx->thunkpos; + { int yypos122= ctx->pos, yythunkpos122= ctx->thunkpos; if (!yymatchChar(ctx, '"')) goto l123; if (!yy_Sp(ctx)) goto l123; if (!yy_Newline(ctx)) goto l123; goto l122; + l123:; ctx->pos= yypos122; ctx->thunkpos= yythunkpos122; if (!yy_Newline(ctx)) goto l121; + } + l122:; goto l120; + l121:; ctx->pos= yypos121; ctx->thunkpos= yythunkpos121; + } if (!yymatchDot(ctx)) goto l120; goto l119; + l120:; ctx->pos= yypos120; ctx->thunkpos= yythunkpos120; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l118; if (!yymatchChar(ctx, '"')) goto l118; + yyprintf((stderr, " ok %s @ %s\n", "RefTitleDouble", ctx->buf+ctx->pos)); + return 1; + l118:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "RefTitleDouble", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_RefTitleSingle(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "RefTitleSingle")); if (!yy_Spnl(ctx)) goto l124; if (!yymatchChar(ctx, '\'')) goto l124; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l124; + l125:; + { int yypos126= ctx->pos, yythunkpos126= ctx->thunkpos; + { int yypos127= ctx->pos, yythunkpos127= ctx->thunkpos; + { int yypos128= ctx->pos, yythunkpos128= ctx->thunkpos; if (!yymatchChar(ctx, '\'')) goto l129; if (!yy_Sp(ctx)) goto l129; if (!yy_Newline(ctx)) goto l129; goto l128; + l129:; ctx->pos= yypos128; ctx->thunkpos= yythunkpos128; if (!yy_Newline(ctx)) goto l127; + } + l128:; goto l126; + l127:; ctx->pos= yypos127; ctx->thunkpos= yythunkpos127; + } if (!yymatchDot(ctx)) goto l126; goto l125; + l126:; ctx->pos= yypos126; ctx->thunkpos= yythunkpos126; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l124; if (!yymatchChar(ctx, '\'')) goto l124; + yyprintf((stderr, " ok %s @ %s\n", "RefTitleSingle", ctx->buf+ctx->pos)); + return 1; + l124:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "RefTitleSingle", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_RefTitle(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "RefTitle")); + { int yypos131= ctx->pos, yythunkpos131= ctx->thunkpos; if (!yy_RefTitleSingle(ctx)) goto l132; goto l131; + l132:; ctx->pos= yypos131; ctx->thunkpos= yythunkpos131; if (!yy_RefTitleDouble(ctx)) goto l133; goto l131; + l133:; ctx->pos= yypos131; ctx->thunkpos= yythunkpos131; if (!yy_RefTitleParens(ctx)) goto l134; goto l131; + l134:; ctx->pos= yypos131; ctx->thunkpos= yythunkpos131; if (!yy_EmptyTitle(ctx)) goto l130; + } + l131:; yyDo(ctx, yy_1_RefTitle, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "RefTitle", ctx->buf+ctx->pos)); + return 1; + l130:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "RefTitle", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_RefSrc(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "RefSrc")); yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l135; if (!yy_Nonspacechar(ctx)) goto l135; + l136:; + { int yypos137= ctx->pos, yythunkpos137= ctx->thunkpos; if (!yy_Nonspacechar(ctx)) goto l137; goto l136; + l137:; ctx->pos= yypos137; ctx->thunkpos= yythunkpos137; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l135; yyDo(ctx, yy_1_RefSrc, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "RefSrc", ctx->buf+ctx->pos)); + return 1; + l135:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "RefSrc", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_AutoLinkEmail(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "AutoLinkEmail")); if (!yymatchChar(ctx, '<')) goto l138; + { int yypos139= ctx->pos, yythunkpos139= ctx->thunkpos; if (!yymatchString(ctx, "mailto:")) goto l139; goto l140; + l139:; ctx->pos= yypos139; ctx->thunkpos= yythunkpos139; + } + l140:; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l138; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\062\350\377\003\376\377\377\207\376\377\377\107\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l138; + l141:; + { int yypos142= ctx->pos, yythunkpos142= ctx->thunkpos; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\062\350\377\003\376\377\377\207\376\377\377\107\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l142; goto l141; + l142:; ctx->pos= yypos142; ctx->thunkpos= yythunkpos142; + } if (!yymatchChar(ctx, '@')) goto l138; + { int yypos145= ctx->pos, yythunkpos145= ctx->thunkpos; if (!yy_Newline(ctx)) goto l145; goto l138; + l145:; ctx->pos= yypos145; ctx->thunkpos= yythunkpos145; + } + { int yypos146= ctx->pos, yythunkpos146= ctx->thunkpos; if (!yymatchChar(ctx, '>')) goto l146; goto l138; + l146:; ctx->pos= yypos146; ctx->thunkpos= yythunkpos146; + } if (!yymatchDot(ctx)) goto l138; + l143:; + { int yypos144= ctx->pos, yythunkpos144= ctx->thunkpos; + { int yypos147= ctx->pos, yythunkpos147= ctx->thunkpos; if (!yy_Newline(ctx)) goto l147; goto l144; + l147:; ctx->pos= yypos147; ctx->thunkpos= yythunkpos147; + } + { int yypos148= ctx->pos, yythunkpos148= ctx->thunkpos; if (!yymatchChar(ctx, '>')) goto l148; goto l144; + l148:; ctx->pos= yypos148; ctx->thunkpos= yythunkpos148; + } if (!yymatchDot(ctx)) goto l144; goto l143; + l144:; ctx->pos= yypos144; ctx->thunkpos= yythunkpos144; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l138; if (!yymatchChar(ctx, '>')) goto l138; yyDo(ctx, yy_1_AutoLinkEmail, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "AutoLinkEmail", ctx->buf+ctx->pos)); + return 1; + l138:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "AutoLinkEmail", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_AutoLinkUrl(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "AutoLinkUrl")); if (!yymatchChar(ctx, '<')) goto l149; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l149; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\000\000\376\377\377\007\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l149; + l150:; + { int yypos151= ctx->pos, yythunkpos151= ctx->thunkpos; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\000\000\376\377\377\007\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l151; goto l150; + l151:; ctx->pos= yypos151; ctx->thunkpos= yythunkpos151; + } if (!yymatchString(ctx, "://")) goto l149; + { int yypos154= ctx->pos, yythunkpos154= ctx->thunkpos; if (!yy_Newline(ctx)) goto l154; goto l149; + l154:; ctx->pos= yypos154; ctx->thunkpos= yythunkpos154; + } + { int yypos155= ctx->pos, yythunkpos155= ctx->thunkpos; if (!yymatchChar(ctx, '>')) goto l155; goto l149; + l155:; ctx->pos= yypos155; ctx->thunkpos= yythunkpos155; + } if (!yymatchDot(ctx)) goto l149; + l152:; + { int yypos153= ctx->pos, yythunkpos153= ctx->thunkpos; + { int yypos156= ctx->pos, yythunkpos156= ctx->thunkpos; if (!yy_Newline(ctx)) goto l156; goto l153; + l156:; ctx->pos= yypos156; ctx->thunkpos= yythunkpos156; + } + { int yypos157= ctx->pos, yythunkpos157= ctx->thunkpos; if (!yymatchChar(ctx, '>')) goto l157; goto l153; + l157:; ctx->pos= yypos157; ctx->thunkpos= yythunkpos157; + } if (!yymatchDot(ctx)) goto l153; goto l152; + l153:; ctx->pos= yypos153; ctx->thunkpos= yythunkpos153; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l149; if (!yymatchChar(ctx, '>')) goto l149; yyDo(ctx, yy_1_AutoLinkUrl, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "AutoLinkUrl", ctx->buf+ctx->pos)); + return 1; + l149:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "AutoLinkUrl", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_TitleDouble(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "TitleDouble")); if (!yymatchChar(ctx, '"')) goto l158; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l158; + l159:; + { int yypos160= ctx->pos, yythunkpos160= ctx->thunkpos; + { int yypos161= ctx->pos, yythunkpos161= ctx->thunkpos; if (!yymatchChar(ctx, '"')) goto l161; if (!yy_Sp(ctx)) goto l161; + { int yypos162= ctx->pos, yythunkpos162= ctx->thunkpos; if (!yymatchChar(ctx, ')')) goto l163; goto l162; + l163:; ctx->pos= yypos162; ctx->thunkpos= yythunkpos162; if (!yy_Newline(ctx)) goto l161; + } + l162:; goto l160; + l161:; ctx->pos= yypos161; ctx->thunkpos= yythunkpos161; + } if (!yymatchDot(ctx)) goto l160; goto l159; + l160:; ctx->pos= yypos160; ctx->thunkpos= yythunkpos160; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l158; if (!yymatchChar(ctx, '"')) goto l158; + yyprintf((stderr, " ok %s @ %s\n", "TitleDouble", ctx->buf+ctx->pos)); + return 1; + l158:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "TitleDouble", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_TitleSingle(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "TitleSingle")); if (!yymatchChar(ctx, '\'')) goto l164; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l164; + l165:; + { int yypos166= ctx->pos, yythunkpos166= ctx->thunkpos; + { int yypos167= ctx->pos, yythunkpos167= ctx->thunkpos; if (!yymatchChar(ctx, '\'')) goto l167; if (!yy_Sp(ctx)) goto l167; + { int yypos168= ctx->pos, yythunkpos168= ctx->thunkpos; if (!yymatchChar(ctx, ')')) goto l169; goto l168; + l169:; ctx->pos= yypos168; ctx->thunkpos= yythunkpos168; if (!yy_Newline(ctx)) goto l167; + } + l168:; goto l166; + l167:; ctx->pos= yypos167; ctx->thunkpos= yythunkpos167; + } if (!yymatchDot(ctx)) goto l166; goto l165; + l166:; ctx->pos= yypos166; ctx->thunkpos= yythunkpos166; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l164; if (!yymatchChar(ctx, '\'')) goto l164; + yyprintf((stderr, " ok %s @ %s\n", "TitleSingle", ctx->buf+ctx->pos)); + return 1; + l164:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "TitleSingle", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Nonspacechar(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Nonspacechar")); + { int yypos171= ctx->pos, yythunkpos171= ctx->thunkpos; if (!yy_Spacechar(ctx)) goto l171; goto l170; + l171:; ctx->pos= yypos171; ctx->thunkpos= yythunkpos171; + } + { int yypos172= ctx->pos, yythunkpos172= ctx->thunkpos; if (!yy_Newline(ctx)) goto l172; goto l170; + l172:; ctx->pos= yypos172; ctx->thunkpos= yythunkpos172; + } if (!yymatchDot(ctx)) goto l170; + yyprintf((stderr, " ok %s @ %s\n", "Nonspacechar", ctx->buf+ctx->pos)); + return 1; + l170:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Nonspacechar", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_SourceContents(yycontext *ctx) +{ + yyprintf((stderr, "%s\n", "SourceContents")); + l174:; + { int yypos175= ctx->pos, yythunkpos175= ctx->thunkpos; + { int yypos176= ctx->pos, yythunkpos176= ctx->thunkpos; + { int yypos180= ctx->pos, yythunkpos180= ctx->thunkpos; if (!yymatchChar(ctx, '(')) goto l180; goto l177; + l180:; ctx->pos= yypos180; ctx->thunkpos= yythunkpos180; + } + { int yypos181= ctx->pos, yythunkpos181= ctx->thunkpos; if (!yymatchChar(ctx, ')')) goto l181; goto l177; + l181:; ctx->pos= yypos181; ctx->thunkpos= yythunkpos181; + } + { int yypos182= ctx->pos, yythunkpos182= ctx->thunkpos; if (!yymatchChar(ctx, '>')) goto l182; goto l177; + l182:; ctx->pos= yypos182; ctx->thunkpos= yythunkpos182; + } if (!yy_Nonspacechar(ctx)) goto l177; + l178:; + { int yypos179= ctx->pos, yythunkpos179= ctx->thunkpos; + { int yypos183= ctx->pos, yythunkpos183= ctx->thunkpos; if (!yymatchChar(ctx, '(')) goto l183; goto l179; + l183:; ctx->pos= yypos183; ctx->thunkpos= yythunkpos183; + } + { int yypos184= ctx->pos, yythunkpos184= ctx->thunkpos; if (!yymatchChar(ctx, ')')) goto l184; goto l179; + l184:; ctx->pos= yypos184; ctx->thunkpos= yythunkpos184; + } + { int yypos185= ctx->pos, yythunkpos185= ctx->thunkpos; if (!yymatchChar(ctx, '>')) goto l185; goto l179; + l185:; ctx->pos= yypos185; ctx->thunkpos= yythunkpos185; + } if (!yy_Nonspacechar(ctx)) goto l179; goto l178; + l179:; ctx->pos= yypos179; ctx->thunkpos= yythunkpos179; + } goto l176; + l177:; ctx->pos= yypos176; ctx->thunkpos= yythunkpos176; if (!yymatchChar(ctx, '(')) goto l175; if (!yy_SourceContents(ctx)) goto l175; if (!yymatchChar(ctx, ')')) goto l175; + } + l176:; goto l174; + l175:; ctx->pos= yypos175; ctx->thunkpos= yythunkpos175; + } + yyprintf((stderr, " ok %s @ %s\n", "SourceContents", ctx->buf+ctx->pos)); + return 1; +} +YY_RULE(int) yy_Title(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Title")); + { int yypos187= ctx->pos, yythunkpos187= ctx->thunkpos; if (!yy_TitleSingle(ctx)) goto l188; goto l187; + l188:; ctx->pos= yypos187; ctx->thunkpos= yythunkpos187; if (!yy_TitleDouble(ctx)) goto l189; goto l187; + l189:; ctx->pos= yypos187; ctx->thunkpos= yythunkpos187; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l186; if (!yymatchString(ctx, "")) goto l186; yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l186; + } + l187:; yyDo(ctx, yy_1_Title, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "Title", ctx->buf+ctx->pos)); + return 1; + l186:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Title", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Source(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Source")); + { int yypos191= ctx->pos, yythunkpos191= ctx->thunkpos; if (!yymatchChar(ctx, '<')) goto l192; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l192; if (!yy_SourceContents(ctx)) goto l192; yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l192; if (!yymatchChar(ctx, '>')) goto l192; goto l191; + l192:; ctx->pos= yypos191; ctx->thunkpos= yythunkpos191; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l190; if (!yy_SourceContents(ctx)) goto l190; yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l190; + } + l191:; yyDo(ctx, yy_1_Source, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "Source", ctx->buf+ctx->pos)); + return 1; + l190:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Source", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Label(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "Label")); if (!yymatchChar(ctx, '[')) goto l193; + { int yypos194= ctx->pos, yythunkpos194= ctx->thunkpos; + { int yypos196= ctx->pos, yythunkpos196= ctx->thunkpos; if (!yymatchChar(ctx, '^')) goto l196; goto l195; + l196:; ctx->pos= yypos196; ctx->thunkpos= yythunkpos196; + } yyText(ctx, ctx->begin, ctx->end); if (!( extension(EXT_NOTES) )) goto l195; goto l194; + l195:; ctx->pos= yypos194; ctx->thunkpos= yythunkpos194; + { int yypos197= ctx->pos, yythunkpos197= ctx->thunkpos; if (!yymatchDot(ctx)) goto l193; ctx->pos= yypos197; ctx->thunkpos= yythunkpos197; + } yyText(ctx, ctx->begin, ctx->end); if (!( !extension(EXT_NOTES) )) goto l193; + } + l194:; if (!yy_StartList(ctx)) goto l193; yyDo(ctx, yySet, -1, 0); + l198:; + { int yypos199= ctx->pos, yythunkpos199= ctx->thunkpos; + { int yypos200= ctx->pos, yythunkpos200= ctx->thunkpos; if (!yymatchChar(ctx, ']')) goto l200; goto l199; + l200:; ctx->pos= yypos200; ctx->thunkpos= yythunkpos200; + } if (!yy_Inline(ctx)) goto l199; yyDo(ctx, yy_1_Label, ctx->begin, ctx->end); goto l198; + l199:; ctx->pos= yypos199; ctx->thunkpos= yythunkpos199; + } if (!yymatchChar(ctx, ']')) goto l193; yyDo(ctx, yy_2_Label, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "Label", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 1, 0); + return 1; + l193:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Label", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_ReferenceLinkSingle(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "ReferenceLinkSingle")); if (!yy_Label(ctx)) goto l201; yyDo(ctx, yySet, -1, 0); yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l201; + { int yypos202= ctx->pos, yythunkpos202= ctx->thunkpos; if (!yy_Spnl(ctx)) goto l202; if (!yymatchString(ctx, "[]")) goto l202; goto l203; + l202:; ctx->pos= yypos202; ctx->thunkpos= yythunkpos202; + } + l203:; yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l201; yyDo(ctx, yy_1_ReferenceLinkSingle, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "ReferenceLinkSingle", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 1, 0); + return 1; + l201:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "ReferenceLinkSingle", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_ReferenceLinkDouble(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 2, 0); + yyprintf((stderr, "%s\n", "ReferenceLinkDouble")); if (!yy_Label(ctx)) goto l204; yyDo(ctx, yySet, -2, 0); yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l204; if (!yy_Spnl(ctx)) goto l204; yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l204; + { int yypos205= ctx->pos, yythunkpos205= ctx->thunkpos; if (!yymatchString(ctx, "[]")) goto l205; goto l204; + l205:; ctx->pos= yypos205; ctx->thunkpos= yythunkpos205; + } if (!yy_Label(ctx)) goto l204; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_1_ReferenceLinkDouble, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "ReferenceLinkDouble", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 2, 0); + return 1; + l204:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "ReferenceLinkDouble", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_AutoLink(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "AutoLink")); + { int yypos207= ctx->pos, yythunkpos207= ctx->thunkpos; if (!yy_AutoLinkUrl(ctx)) goto l208; goto l207; + l208:; ctx->pos= yypos207; ctx->thunkpos= yythunkpos207; if (!yy_AutoLinkEmail(ctx)) goto l206; + } + l207:; + yyprintf((stderr, " ok %s @ %s\n", "AutoLink", ctx->buf+ctx->pos)); + return 1; + l206:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "AutoLink", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_ReferenceLink(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "ReferenceLink")); + { int yypos210= ctx->pos, yythunkpos210= ctx->thunkpos; if (!yy_ReferenceLinkDouble(ctx)) goto l211; goto l210; + l211:; ctx->pos= yypos210; ctx->thunkpos= yythunkpos210; if (!yy_ReferenceLinkSingle(ctx)) goto l209; + } + l210:; + yyprintf((stderr, " ok %s @ %s\n", "ReferenceLink", ctx->buf+ctx->pos)); + return 1; + l209:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "ReferenceLink", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_ExplicitLink(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 3, 0); + yyprintf((stderr, "%s\n", "ExplicitLink")); if (!yy_Label(ctx)) goto l212; yyDo(ctx, yySet, -3, 0); if (!yymatchChar(ctx, '(')) goto l212; if (!yy_Sp(ctx)) goto l212; if (!yy_Source(ctx)) goto l212; yyDo(ctx, yySet, -2, 0); if (!yy_Spnl(ctx)) goto l212; if (!yy_Title(ctx)) goto l212; yyDo(ctx, yySet, -1, 0); if (!yy_Sp(ctx)) goto l212; if (!yymatchChar(ctx, ')')) goto l212; yyDo(ctx, yy_1_ExplicitLink, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "ExplicitLink", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 3, 0); + return 1; + l212:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "ExplicitLink", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_StrongUl(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 2, 0); + yyprintf((stderr, "%s\n", "StrongUl")); if (!yymatchString(ctx, "__")) goto l213; + { int yypos214= ctx->pos, yythunkpos214= ctx->thunkpos; if (!yy_Whitespace(ctx)) goto l214; goto l213; + l214:; ctx->pos= yypos214; ctx->thunkpos= yythunkpos214; + } if (!yy_StartList(ctx)) goto l213; yyDo(ctx, yySet, -2, 0); + { int yypos217= ctx->pos, yythunkpos217= ctx->thunkpos; if (!yymatchString(ctx, "__")) goto l217; goto l213; + l217:; ctx->pos= yypos217; ctx->thunkpos= yythunkpos217; + } if (!yy_Inline(ctx)) goto l213; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_1_StrongUl, ctx->begin, ctx->end); + l215:; + { int yypos216= ctx->pos, yythunkpos216= ctx->thunkpos; + { int yypos218= ctx->pos, yythunkpos218= ctx->thunkpos; if (!yymatchString(ctx, "__")) goto l218; goto l216; + l218:; ctx->pos= yypos218; ctx->thunkpos= yythunkpos218; + } if (!yy_Inline(ctx)) goto l216; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_1_StrongUl, ctx->begin, ctx->end); goto l215; + l216:; ctx->pos= yypos216; ctx->thunkpos= yythunkpos216; + } if (!yymatchString(ctx, "__")) goto l213; yyDo(ctx, yy_2_StrongUl, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "StrongUl", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 2, 0); + return 1; + l213:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "StrongUl", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_StrongStar(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 2, 0); + yyprintf((stderr, "%s\n", "StrongStar")); if (!yymatchString(ctx, "**")) goto l219; + { int yypos220= ctx->pos, yythunkpos220= ctx->thunkpos; if (!yy_Whitespace(ctx)) goto l220; goto l219; + l220:; ctx->pos= yypos220; ctx->thunkpos= yythunkpos220; + } if (!yy_StartList(ctx)) goto l219; yyDo(ctx, yySet, -2, 0); + { int yypos223= ctx->pos, yythunkpos223= ctx->thunkpos; if (!yymatchString(ctx, "**")) goto l223; goto l219; + l223:; ctx->pos= yypos223; ctx->thunkpos= yythunkpos223; + } if (!yy_Inline(ctx)) goto l219; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_1_StrongStar, ctx->begin, ctx->end); + l221:; + { int yypos222= ctx->pos, yythunkpos222= ctx->thunkpos; + { int yypos224= ctx->pos, yythunkpos224= ctx->thunkpos; if (!yymatchString(ctx, "**")) goto l224; goto l222; + l224:; ctx->pos= yypos224; ctx->thunkpos= yythunkpos224; + } if (!yy_Inline(ctx)) goto l222; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_1_StrongStar, ctx->begin, ctx->end); goto l221; + l222:; ctx->pos= yypos222; ctx->thunkpos= yythunkpos222; + } if (!yymatchString(ctx, "**")) goto l219; yyDo(ctx, yy_2_StrongStar, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "StrongStar", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 2, 0); + return 1; + l219:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "StrongStar", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Whitespace(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Whitespace")); + { int yypos226= ctx->pos, yythunkpos226= ctx->thunkpos; if (!yy_Spacechar(ctx)) goto l227; goto l226; + l227:; ctx->pos= yypos226; ctx->thunkpos= yythunkpos226; if (!yy_Newline(ctx)) goto l225; + } + l226:; + yyprintf((stderr, " ok %s @ %s\n", "Whitespace", ctx->buf+ctx->pos)); + return 1; + l225:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Whitespace", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_EmphUl(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 2, 0); + yyprintf((stderr, "%s\n", "EmphUl")); if (!yymatchChar(ctx, '_')) goto l228; + { int yypos229= ctx->pos, yythunkpos229= ctx->thunkpos; if (!yy_Whitespace(ctx)) goto l229; goto l228; + l229:; ctx->pos= yypos229; ctx->thunkpos= yythunkpos229; + } if (!yy_StartList(ctx)) goto l228; yyDo(ctx, yySet, -2, 0); + { int yypos232= ctx->pos, yythunkpos232= ctx->thunkpos; + { int yypos234= ctx->pos, yythunkpos234= ctx->thunkpos; if (!yymatchChar(ctx, '_')) goto l234; goto l233; + l234:; ctx->pos= yypos234; ctx->thunkpos= yythunkpos234; + } if (!yy_Inline(ctx)) goto l233; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_1_EmphUl, ctx->begin, ctx->end); goto l232; + l233:; ctx->pos= yypos232; ctx->thunkpos= yythunkpos232; if (!yy_StrongUl(ctx)) goto l228; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_2_EmphUl, ctx->begin, ctx->end); + } + l232:; + l230:; + { int yypos231= ctx->pos, yythunkpos231= ctx->thunkpos; + { int yypos235= ctx->pos, yythunkpos235= ctx->thunkpos; + { int yypos237= ctx->pos, yythunkpos237= ctx->thunkpos; if (!yymatchChar(ctx, '_')) goto l237; goto l236; + l237:; ctx->pos= yypos237; ctx->thunkpos= yythunkpos237; + } if (!yy_Inline(ctx)) goto l236; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_1_EmphUl, ctx->begin, ctx->end); goto l235; + l236:; ctx->pos= yypos235; ctx->thunkpos= yythunkpos235; if (!yy_StrongUl(ctx)) goto l231; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_2_EmphUl, ctx->begin, ctx->end); + } + l235:; goto l230; + l231:; ctx->pos= yypos231; ctx->thunkpos= yythunkpos231; + } if (!yymatchChar(ctx, '_')) goto l228; yyDo(ctx, yy_3_EmphUl, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "EmphUl", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 2, 0); + return 1; + l228:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "EmphUl", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_EmphStar(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 2, 0); + yyprintf((stderr, "%s\n", "EmphStar")); if (!yymatchChar(ctx, '*')) goto l238; + { int yypos239= ctx->pos, yythunkpos239= ctx->thunkpos; if (!yy_Whitespace(ctx)) goto l239; goto l238; + l239:; ctx->pos= yypos239; ctx->thunkpos= yythunkpos239; + } if (!yy_StartList(ctx)) goto l238; yyDo(ctx, yySet, -2, 0); + { int yypos242= ctx->pos, yythunkpos242= ctx->thunkpos; + { int yypos244= ctx->pos, yythunkpos244= ctx->thunkpos; if (!yymatchChar(ctx, '*')) goto l244; goto l243; + l244:; ctx->pos= yypos244; ctx->thunkpos= yythunkpos244; + } if (!yy_Inline(ctx)) goto l243; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_1_EmphStar, ctx->begin, ctx->end); goto l242; + l243:; ctx->pos= yypos242; ctx->thunkpos= yythunkpos242; if (!yy_StrongStar(ctx)) goto l238; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_2_EmphStar, ctx->begin, ctx->end); + } + l242:; + l240:; + { int yypos241= ctx->pos, yythunkpos241= ctx->thunkpos; + { int yypos245= ctx->pos, yythunkpos245= ctx->thunkpos; + { int yypos247= ctx->pos, yythunkpos247= ctx->thunkpos; if (!yymatchChar(ctx, '*')) goto l247; goto l246; + l247:; ctx->pos= yypos247; ctx->thunkpos= yythunkpos247; + } if (!yy_Inline(ctx)) goto l246; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_1_EmphStar, ctx->begin, ctx->end); goto l245; + l246:; ctx->pos= yypos245; ctx->thunkpos= yythunkpos245; if (!yy_StrongStar(ctx)) goto l241; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_2_EmphStar, ctx->begin, ctx->end); + } + l245:; goto l240; + l241:; ctx->pos= yypos241; ctx->thunkpos= yythunkpos241; + } if (!yymatchChar(ctx, '*')) goto l238; yyDo(ctx, yy_3_EmphStar, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "EmphStar", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 2, 0); + return 1; + l238:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "EmphStar", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_StarLine(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "StarLine")); + { int yypos249= ctx->pos, yythunkpos249= ctx->thunkpos; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l250; if (!yymatchString(ctx, "****")) goto l250; + l251:; + { int yypos252= ctx->pos, yythunkpos252= ctx->thunkpos; if (!yymatchChar(ctx, '*')) goto l252; goto l251; + l252:; ctx->pos= yypos252; ctx->thunkpos= yythunkpos252; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l250; goto l249; + l250:; ctx->pos= yypos249; ctx->thunkpos= yythunkpos249; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l248; if (!yy_Spacechar(ctx)) goto l248; if (!yymatchChar(ctx, '*')) goto l248; + l253:; + { int yypos254= ctx->pos, yythunkpos254= ctx->thunkpos; if (!yymatchChar(ctx, '*')) goto l254; goto l253; + l254:; ctx->pos= yypos254; ctx->thunkpos= yythunkpos254; + } + { int yypos255= ctx->pos, yythunkpos255= ctx->thunkpos; if (!yy_Spacechar(ctx)) goto l248; ctx->pos= yypos255; ctx->thunkpos= yythunkpos255; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l248; + } + l249:; + yyprintf((stderr, " ok %s @ %s\n", "StarLine", ctx->buf+ctx->pos)); + return 1; + l248:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "StarLine", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_UlLine(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "UlLine")); + { int yypos257= ctx->pos, yythunkpos257= ctx->thunkpos; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l258; if (!yymatchString(ctx, "____")) goto l258; + l259:; + { int yypos260= ctx->pos, yythunkpos260= ctx->thunkpos; if (!yymatchChar(ctx, '_')) goto l260; goto l259; + l260:; ctx->pos= yypos260; ctx->thunkpos= yythunkpos260; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l258; goto l257; + l258:; ctx->pos= yypos257; ctx->thunkpos= yythunkpos257; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l256; if (!yy_Spacechar(ctx)) goto l256; if (!yymatchChar(ctx, '_')) goto l256; + l261:; + { int yypos262= ctx->pos, yythunkpos262= ctx->thunkpos; if (!yymatchChar(ctx, '_')) goto l262; goto l261; + l262:; ctx->pos= yypos262; ctx->thunkpos= yythunkpos262; + } + { int yypos263= ctx->pos, yythunkpos263= ctx->thunkpos; if (!yy_Spacechar(ctx)) goto l256; ctx->pos= yypos263; ctx->thunkpos= yythunkpos263; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l256; + } + l257:; + yyprintf((stderr, " ok %s @ %s\n", "UlLine", ctx->buf+ctx->pos)); + return 1; + l256:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "UlLine", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_SpecialChar(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "SpecialChar")); + { int yypos265= ctx->pos, yythunkpos265= ctx->thunkpos; if (!yymatchChar(ctx, '*')) goto l266; goto l265; + l266:; ctx->pos= yypos265; ctx->thunkpos= yythunkpos265; if (!yymatchChar(ctx, '_')) goto l267; goto l265; + l267:; ctx->pos= yypos265; ctx->thunkpos= yythunkpos265; if (!yymatchChar(ctx, '`')) goto l268; goto l265; + l268:; ctx->pos= yypos265; ctx->thunkpos= yythunkpos265; if (!yymatchChar(ctx, '&')) goto l269; goto l265; + l269:; ctx->pos= yypos265; ctx->thunkpos= yythunkpos265; if (!yymatchChar(ctx, '[')) goto l270; goto l265; + l270:; ctx->pos= yypos265; ctx->thunkpos= yythunkpos265; if (!yymatchChar(ctx, ']')) goto l271; goto l265; + l271:; ctx->pos= yypos265; ctx->thunkpos= yythunkpos265; if (!yymatchChar(ctx, '(')) goto l272; goto l265; + l272:; ctx->pos= yypos265; ctx->thunkpos= yythunkpos265; if (!yymatchChar(ctx, ')')) goto l273; goto l265; + l273:; ctx->pos= yypos265; ctx->thunkpos= yythunkpos265; if (!yymatchChar(ctx, '<')) goto l274; goto l265; + l274:; ctx->pos= yypos265; ctx->thunkpos= yythunkpos265; if (!yymatchChar(ctx, '!')) goto l275; goto l265; + l275:; ctx->pos= yypos265; ctx->thunkpos= yythunkpos265; if (!yymatchChar(ctx, '#')) goto l276; goto l265; + l276:; ctx->pos= yypos265; ctx->thunkpos= yythunkpos265; if (!yymatchChar(ctx, '\\')) goto l277; goto l265; + l277:; ctx->pos= yypos265; ctx->thunkpos= yythunkpos265; if (!yymatchChar(ctx, '\'')) goto l278; goto l265; + l278:; ctx->pos= yypos265; ctx->thunkpos= yythunkpos265; if (!yymatchChar(ctx, '"')) goto l279; goto l265; + l279:; ctx->pos= yypos265; ctx->thunkpos= yythunkpos265; if (!yy_ExtendedSpecialChar(ctx)) goto l264; + } + l265:; + yyprintf((stderr, " ok %s @ %s\n", "SpecialChar", ctx->buf+ctx->pos)); + return 1; + l264:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "SpecialChar", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Eof(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Eof")); + { int yypos281= ctx->pos, yythunkpos281= ctx->thunkpos; if (!yymatchDot(ctx)) goto l281; goto l280; + l281:; ctx->pos= yypos281; ctx->thunkpos= yythunkpos281; + } + yyprintf((stderr, " ok %s @ %s\n", "Eof", ctx->buf+ctx->pos)); + return 1; + l280:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Eof", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_NormalEndline(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "NormalEndline")); if (!yy_Sp(ctx)) goto l282; if (!yy_Newline(ctx)) goto l282; + { int yypos283= ctx->pos, yythunkpos283= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l283; goto l282; + l283:; ctx->pos= yypos283; ctx->thunkpos= yythunkpos283; + } + { int yypos284= ctx->pos, yythunkpos284= ctx->thunkpos; if (!yymatchChar(ctx, '>')) goto l284; goto l282; + l284:; ctx->pos= yypos284; ctx->thunkpos= yythunkpos284; + } + { int yypos285= ctx->pos, yythunkpos285= ctx->thunkpos; if (!yy_AtxStart(ctx)) goto l285; goto l282; + l285:; ctx->pos= yypos285; ctx->thunkpos= yythunkpos285; + } + { int yypos286= ctx->pos, yythunkpos286= ctx->thunkpos; if (!yy_Line(ctx)) goto l286; + { int yypos287= ctx->pos, yythunkpos287= ctx->thunkpos; if (!yymatchChar(ctx, '=')) goto l288; + l289:; + { int yypos290= ctx->pos, yythunkpos290= ctx->thunkpos; if (!yymatchChar(ctx, '=')) goto l290; goto l289; + l290:; ctx->pos= yypos290; ctx->thunkpos= yythunkpos290; + } goto l287; + l288:; ctx->pos= yypos287; ctx->thunkpos= yythunkpos287; if (!yymatchChar(ctx, '-')) goto l286; + l291:; + { int yypos292= ctx->pos, yythunkpos292= ctx->thunkpos; if (!yymatchChar(ctx, '-')) goto l292; goto l291; + l292:; ctx->pos= yypos292; ctx->thunkpos= yythunkpos292; + } + } + l287:; if (!yy_Newline(ctx)) goto l286; goto l282; + l286:; ctx->pos= yypos286; ctx->thunkpos= yythunkpos286; + } yyDo(ctx, yy_1_NormalEndline, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "NormalEndline", ctx->buf+ctx->pos)); + return 1; + l282:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "NormalEndline", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_TerminalEndline(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "TerminalEndline")); if (!yy_Sp(ctx)) goto l293; if (!yy_Newline(ctx)) goto l293; if (!yy_Eof(ctx)) goto l293; yyDo(ctx, yy_1_TerminalEndline, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "TerminalEndline", ctx->buf+ctx->pos)); + return 1; + l293:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "TerminalEndline", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_LineBreak(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "LineBreak")); if (!yymatchString(ctx, " ")) goto l294; if (!yy_NormalEndline(ctx)) goto l294; yyDo(ctx, yy_1_LineBreak, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "LineBreak", ctx->buf+ctx->pos)); + return 1; + l294:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "LineBreak", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_CharEntity(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "CharEntity")); yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l295; if (!yymatchChar(ctx, '&')) goto l295; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\003\376\377\377\007\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l295; + l296:; + { int yypos297= ctx->pos, yythunkpos297= ctx->thunkpos; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\003\376\377\377\007\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l297; goto l296; + l297:; ctx->pos= yypos297; ctx->thunkpos= yythunkpos297; + } if (!yymatchChar(ctx, ';')) goto l295; yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l295; + yyprintf((stderr, " ok %s @ %s\n", "CharEntity", ctx->buf+ctx->pos)); + return 1; + l295:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "CharEntity", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_DecEntity(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "DecEntity")); yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l298; if (!yymatchChar(ctx, '&')) goto l298; if (!yymatchChar(ctx, '#')) goto l298; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l298; + l299:; + { int yypos300= ctx->pos, yythunkpos300= ctx->thunkpos; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l300; goto l299; + l300:; ctx->pos= yypos300; ctx->thunkpos= yythunkpos300; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l298; if (!yymatchChar(ctx, ';')) goto l298; yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l298; + yyprintf((stderr, " ok %s @ %s\n", "DecEntity", ctx->buf+ctx->pos)); + return 1; + l298:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "DecEntity", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HexEntity(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HexEntity")); yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l301; if (!yymatchChar(ctx, '&')) goto l301; if (!yymatchChar(ctx, '#')) goto l301; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l301; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\003\176\000\000\000\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l301; + l302:; + { int yypos303= ctx->pos, yythunkpos303= ctx->thunkpos; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\003\176\000\000\000\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l303; goto l302; + l303:; ctx->pos= yypos303; ctx->thunkpos= yythunkpos303; + } if (!yymatchChar(ctx, ';')) goto l301; yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l301; + yyprintf((stderr, " ok %s @ %s\n", "HexEntity", ctx->buf+ctx->pos)); + return 1; + l301:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HexEntity", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_AposChunk(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "AposChunk")); yyText(ctx, ctx->begin, ctx->end); if (!( extension(EXT_SMART) )) goto l304; if (!yymatchChar(ctx, '\'')) goto l304; + { int yypos305= ctx->pos, yythunkpos305= ctx->thunkpos; if (!yy_Alphanumeric(ctx)) goto l304; ctx->pos= yypos305; ctx->thunkpos= yythunkpos305; + } yyDo(ctx, yy_1_AposChunk, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "AposChunk", ctx->buf+ctx->pos)); + return 1; + l304:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "AposChunk", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Alphanumeric(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Alphanumeric")); + { int yypos307= ctx->pos, yythunkpos307= ctx->thunkpos; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\003\376\377\377\007\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l308; goto l307; + l308:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\200")) goto l309; goto l307; + l309:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\201")) goto l310; goto l307; + l310:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\202")) goto l311; goto l307; + l311:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\203")) goto l312; goto l307; + l312:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\204")) goto l313; goto l307; + l313:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\205")) goto l314; goto l307; + l314:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\206")) goto l315; goto l307; + l315:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\207")) goto l316; goto l307; + l316:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\210")) goto l317; goto l307; + l317:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\211")) goto l318; goto l307; + l318:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\212")) goto l319; goto l307; + l319:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\213")) goto l320; goto l307; + l320:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\214")) goto l321; goto l307; + l321:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\215")) goto l322; goto l307; + l322:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\216")) goto l323; goto l307; + l323:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\217")) goto l324; goto l307; + l324:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\220")) goto l325; goto l307; + l325:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\221")) goto l326; goto l307; + l326:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\222")) goto l327; goto l307; + l327:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\223")) goto l328; goto l307; + l328:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\224")) goto l329; goto l307; + l329:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\225")) goto l330; goto l307; + l330:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\226")) goto l331; goto l307; + l331:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\227")) goto l332; goto l307; + l332:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\230")) goto l333; goto l307; + l333:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\231")) goto l334; goto l307; + l334:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\232")) goto l335; goto l307; + l335:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\233")) goto l336; goto l307; + l336:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\234")) goto l337; goto l307; + l337:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\235")) goto l338; goto l307; + l338:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\236")) goto l339; goto l307; + l339:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\237")) goto l340; goto l307; + l340:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\240")) goto l341; goto l307; + l341:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\241")) goto l342; goto l307; + l342:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\242")) goto l343; goto l307; + l343:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\243")) goto l344; goto l307; + l344:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\244")) goto l345; goto l307; + l345:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\245")) goto l346; goto l307; + l346:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\246")) goto l347; goto l307; + l347:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\247")) goto l348; goto l307; + l348:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\250")) goto l349; goto l307; + l349:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\251")) goto l350; goto l307; + l350:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\252")) goto l351; goto l307; + l351:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\253")) goto l352; goto l307; + l352:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\254")) goto l353; goto l307; + l353:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\255")) goto l354; goto l307; + l354:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\256")) goto l355; goto l307; + l355:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\257")) goto l356; goto l307; + l356:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\260")) goto l357; goto l307; + l357:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\261")) goto l358; goto l307; + l358:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\262")) goto l359; goto l307; + l359:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\263")) goto l360; goto l307; + l360:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\264")) goto l361; goto l307; + l361:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\265")) goto l362; goto l307; + l362:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\266")) goto l363; goto l307; + l363:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\267")) goto l364; goto l307; + l364:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\270")) goto l365; goto l307; + l365:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\271")) goto l366; goto l307; + l366:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\272")) goto l367; goto l307; + l367:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\273")) goto l368; goto l307; + l368:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\274")) goto l369; goto l307; + l369:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\275")) goto l370; goto l307; + l370:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\276")) goto l371; goto l307; + l371:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\277")) goto l372; goto l307; + l372:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\300")) goto l373; goto l307; + l373:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\301")) goto l374; goto l307; + l374:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\302")) goto l375; goto l307; + l375:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\303")) goto l376; goto l307; + l376:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\304")) goto l377; goto l307; + l377:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\305")) goto l378; goto l307; + l378:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\306")) goto l379; goto l307; + l379:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\307")) goto l380; goto l307; + l380:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\310")) goto l381; goto l307; + l381:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\311")) goto l382; goto l307; + l382:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\312")) goto l383; goto l307; + l383:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\313")) goto l384; goto l307; + l384:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\314")) goto l385; goto l307; + l385:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\315")) goto l386; goto l307; + l386:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\316")) goto l387; goto l307; + l387:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\317")) goto l388; goto l307; + l388:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\320")) goto l389; goto l307; + l389:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\321")) goto l390; goto l307; + l390:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\322")) goto l391; goto l307; + l391:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\323")) goto l392; goto l307; + l392:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\324")) goto l393; goto l307; + l393:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\325")) goto l394; goto l307; + l394:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\326")) goto l395; goto l307; + l395:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\327")) goto l396; goto l307; + l396:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\330")) goto l397; goto l307; + l397:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\331")) goto l398; goto l307; + l398:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\332")) goto l399; goto l307; + l399:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\333")) goto l400; goto l307; + l400:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\334")) goto l401; goto l307; + l401:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\335")) goto l402; goto l307; + l402:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\336")) goto l403; goto l307; + l403:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\337")) goto l404; goto l307; + l404:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\340")) goto l405; goto l307; + l405:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\341")) goto l406; goto l307; + l406:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\342")) goto l407; goto l307; + l407:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\343")) goto l408; goto l307; + l408:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\344")) goto l409; goto l307; + l409:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\345")) goto l410; goto l307; + l410:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\346")) goto l411; goto l307; + l411:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\347")) goto l412; goto l307; + l412:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\350")) goto l413; goto l307; + l413:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\351")) goto l414; goto l307; + l414:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\352")) goto l415; goto l307; + l415:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\353")) goto l416; goto l307; + l416:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\354")) goto l417; goto l307; + l417:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\355")) goto l418; goto l307; + l418:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\356")) goto l419; goto l307; + l419:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\357")) goto l420; goto l307; + l420:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\360")) goto l421; goto l307; + l421:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\361")) goto l422; goto l307; + l422:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\362")) goto l423; goto l307; + l423:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\363")) goto l424; goto l307; + l424:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\364")) goto l425; goto l307; + l425:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\365")) goto l426; goto l307; + l426:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\366")) goto l427; goto l307; + l427:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\367")) goto l428; goto l307; + l428:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\370")) goto l429; goto l307; + l429:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\371")) goto l430; goto l307; + l430:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\372")) goto l431; goto l307; + l431:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\373")) goto l432; goto l307; + l432:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\374")) goto l433; goto l307; + l433:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\375")) goto l434; goto l307; + l434:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\376")) goto l435; goto l307; + l435:; ctx->pos= yypos307; ctx->thunkpos= yythunkpos307; if (!yymatchString(ctx, "\377")) goto l306; + } + l307:; + yyprintf((stderr, " ok %s @ %s\n", "Alphanumeric", ctx->buf+ctx->pos)); + return 1; + l306:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Alphanumeric", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_StrChunk(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "StrChunk")); + { int yypos437= ctx->pos, yythunkpos437= ctx->thunkpos; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l438; + { int yypos441= ctx->pos, yythunkpos441= ctx->thunkpos; if (!yy_NormalChar(ctx)) goto l442; goto l441; + l442:; ctx->pos= yypos441; ctx->thunkpos= yythunkpos441; if (!yymatchChar(ctx, '_')) goto l438; + l443:; + { int yypos444= ctx->pos, yythunkpos444= ctx->thunkpos; if (!yymatchChar(ctx, '_')) goto l444; goto l443; + l444:; ctx->pos= yypos444; ctx->thunkpos= yythunkpos444; + } + { int yypos445= ctx->pos, yythunkpos445= ctx->thunkpos; if (!yy_Alphanumeric(ctx)) goto l438; ctx->pos= yypos445; ctx->thunkpos= yythunkpos445; + } + } + l441:; + l439:; + { int yypos440= ctx->pos, yythunkpos440= ctx->thunkpos; + { int yypos446= ctx->pos, yythunkpos446= ctx->thunkpos; if (!yy_NormalChar(ctx)) goto l447; goto l446; + l447:; ctx->pos= yypos446; ctx->thunkpos= yythunkpos446; if (!yymatchChar(ctx, '_')) goto l440; + l448:; + { int yypos449= ctx->pos, yythunkpos449= ctx->thunkpos; if (!yymatchChar(ctx, '_')) goto l449; goto l448; + l449:; ctx->pos= yypos449; ctx->thunkpos= yythunkpos449; + } + { int yypos450= ctx->pos, yythunkpos450= ctx->thunkpos; if (!yy_Alphanumeric(ctx)) goto l440; ctx->pos= yypos450; ctx->thunkpos= yythunkpos450; + } + } + l446:; goto l439; + l440:; ctx->pos= yypos440; ctx->thunkpos= yythunkpos440; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l438; yyDo(ctx, yy_1_StrChunk, ctx->begin, ctx->end); goto l437; + l438:; ctx->pos= yypos437; ctx->thunkpos= yythunkpos437; if (!yy_AposChunk(ctx)) goto l436; + } + l437:; + yyprintf((stderr, " ok %s @ %s\n", "StrChunk", ctx->buf+ctx->pos)); + return 1; + l436:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "StrChunk", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_NormalChar(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "NormalChar")); + { int yypos452= ctx->pos, yythunkpos452= ctx->thunkpos; + { int yypos453= ctx->pos, yythunkpos453= ctx->thunkpos; if (!yy_SpecialChar(ctx)) goto l454; goto l453; + l454:; ctx->pos= yypos453; ctx->thunkpos= yythunkpos453; if (!yy_Spacechar(ctx)) goto l455; goto l453; + l455:; ctx->pos= yypos453; ctx->thunkpos= yythunkpos453; if (!yy_Newline(ctx)) goto l452; + } + l453:; goto l451; + l452:; ctx->pos= yypos452; ctx->thunkpos= yythunkpos452; + } if (!yymatchDot(ctx)) goto l451; + yyprintf((stderr, " ok %s @ %s\n", "NormalChar", ctx->buf+ctx->pos)); + return 1; + l451:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "NormalChar", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Symbol(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Symbol")); yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l456; if (!yy_SpecialChar(ctx)) goto l456; yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l456; yyDo(ctx, yy_1_Symbol, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "Symbol", ctx->buf+ctx->pos)); + return 1; + l456:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Symbol", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Smart(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Smart")); yyText(ctx, ctx->begin, ctx->end); if (!( extension(EXT_SMART) )) goto l457; + { int yypos458= ctx->pos, yythunkpos458= ctx->thunkpos; if (!yy_Ellipsis(ctx)) goto l459; goto l458; + l459:; ctx->pos= yypos458; ctx->thunkpos= yythunkpos458; if (!yy_Dash(ctx)) goto l460; goto l458; + l460:; ctx->pos= yypos458; ctx->thunkpos= yythunkpos458; if (!yy_SingleQuoted(ctx)) goto l461; goto l458; + l461:; ctx->pos= yypos458; ctx->thunkpos= yythunkpos458; if (!yy_DoubleQuoted(ctx)) goto l462; goto l458; + l462:; ctx->pos= yypos458; ctx->thunkpos= yythunkpos458; if (!yy_Apostrophe(ctx)) goto l457; + } + l458:; + yyprintf((stderr, " ok %s @ %s\n", "Smart", ctx->buf+ctx->pos)); + return 1; + l457:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Smart", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_EscapedChar(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "EscapedChar")); if (!yymatchChar(ctx, '\\')) goto l463; + { int yypos464= ctx->pos, yythunkpos464= ctx->thunkpos; if (!yy_Newline(ctx)) goto l464; goto l463; + l464:; ctx->pos= yypos464; ctx->thunkpos= yythunkpos464; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l463; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\012\157\000\120\000\000\000\270\001\000\000\070\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l463; yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l463; yyDo(ctx, yy_1_EscapedChar, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "EscapedChar", ctx->buf+ctx->pos)); + return 1; + l463:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "EscapedChar", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Entity(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Entity")); + { int yypos466= ctx->pos, yythunkpos466= ctx->thunkpos; if (!yy_HexEntity(ctx)) goto l467; goto l466; + l467:; ctx->pos= yypos466; ctx->thunkpos= yythunkpos466; if (!yy_DecEntity(ctx)) goto l468; goto l466; + l468:; ctx->pos= yypos466; ctx->thunkpos= yythunkpos466; if (!yy_CharEntity(ctx)) goto l465; + } + l466:; yyDo(ctx, yy_1_Entity, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "Entity", ctx->buf+ctx->pos)); + return 1; + l465:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Entity", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_RawHtml(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "RawHtml")); yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l469; + { int yypos470= ctx->pos, yythunkpos470= ctx->thunkpos; if (!yy_HtmlComment(ctx)) goto l471; goto l470; + l471:; ctx->pos= yypos470; ctx->thunkpos= yythunkpos470; if (!yy_HtmlBlockScript(ctx)) goto l472; goto l470; + l472:; ctx->pos= yypos470; ctx->thunkpos= yythunkpos470; if (!yy_HtmlTag(ctx)) goto l469; + } + l470:; yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l469; yyDo(ctx, yy_1_RawHtml, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "RawHtml", ctx->buf+ctx->pos)); + return 1; + l469:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "RawHtml", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Code(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Code")); + { int yypos474= ctx->pos, yythunkpos474= ctx->thunkpos; if (!yy_Ticks1(ctx)) goto l475; if (!yy_Sp(ctx)) goto l475; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l475; + { int yypos478= ctx->pos, yythunkpos478= ctx->thunkpos; + { int yypos482= ctx->pos, yythunkpos482= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l482; goto l479; + l482:; ctx->pos= yypos482; ctx->thunkpos= yythunkpos482; + } if (!yy_Nonspacechar(ctx)) goto l479; + l480:; + { int yypos481= ctx->pos, yythunkpos481= ctx->thunkpos; + { int yypos483= ctx->pos, yythunkpos483= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l483; goto l481; + l483:; ctx->pos= yypos483; ctx->thunkpos= yythunkpos483; + } if (!yy_Nonspacechar(ctx)) goto l481; goto l480; + l481:; ctx->pos= yypos481; ctx->thunkpos= yythunkpos481; + } goto l478; + l479:; ctx->pos= yypos478; ctx->thunkpos= yythunkpos478; + { int yypos485= ctx->pos, yythunkpos485= ctx->thunkpos; if (!yy_Ticks1(ctx)) goto l485; goto l484; + l485:; ctx->pos= yypos485; ctx->thunkpos= yythunkpos485; + } if (!yymatchChar(ctx, '`')) goto l484; + l486:; + { int yypos487= ctx->pos, yythunkpos487= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l487; goto l486; + l487:; ctx->pos= yypos487; ctx->thunkpos= yythunkpos487; + } goto l478; + l484:; ctx->pos= yypos478; ctx->thunkpos= yythunkpos478; + { int yypos488= ctx->pos, yythunkpos488= ctx->thunkpos; if (!yy_Sp(ctx)) goto l488; if (!yy_Ticks1(ctx)) goto l488; goto l475; + l488:; ctx->pos= yypos488; ctx->thunkpos= yythunkpos488; + } + { int yypos489= ctx->pos, yythunkpos489= ctx->thunkpos; if (!yy_Spacechar(ctx)) goto l490; goto l489; + l490:; ctx->pos= yypos489; ctx->thunkpos= yythunkpos489; if (!yy_Newline(ctx)) goto l475; + { int yypos491= ctx->pos, yythunkpos491= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l491; goto l475; + l491:; ctx->pos= yypos491; ctx->thunkpos= yythunkpos491; + } + } + l489:; + } + l478:; + l476:; + { int yypos477= ctx->pos, yythunkpos477= ctx->thunkpos; + { int yypos492= ctx->pos, yythunkpos492= ctx->thunkpos; + { int yypos496= ctx->pos, yythunkpos496= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l496; goto l493; + l496:; ctx->pos= yypos496; ctx->thunkpos= yythunkpos496; + } if (!yy_Nonspacechar(ctx)) goto l493; + l494:; + { int yypos495= ctx->pos, yythunkpos495= ctx->thunkpos; + { int yypos497= ctx->pos, yythunkpos497= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l497; goto l495; + l497:; ctx->pos= yypos497; ctx->thunkpos= yythunkpos497; + } if (!yy_Nonspacechar(ctx)) goto l495; goto l494; + l495:; ctx->pos= yypos495; ctx->thunkpos= yythunkpos495; + } goto l492; + l493:; ctx->pos= yypos492; ctx->thunkpos= yythunkpos492; + { int yypos499= ctx->pos, yythunkpos499= ctx->thunkpos; if (!yy_Ticks1(ctx)) goto l499; goto l498; + l499:; ctx->pos= yypos499; ctx->thunkpos= yythunkpos499; + } if (!yymatchChar(ctx, '`')) goto l498; + l500:; + { int yypos501= ctx->pos, yythunkpos501= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l501; goto l500; + l501:; ctx->pos= yypos501; ctx->thunkpos= yythunkpos501; + } goto l492; + l498:; ctx->pos= yypos492; ctx->thunkpos= yythunkpos492; + { int yypos502= ctx->pos, yythunkpos502= ctx->thunkpos; if (!yy_Sp(ctx)) goto l502; if (!yy_Ticks1(ctx)) goto l502; goto l477; + l502:; ctx->pos= yypos502; ctx->thunkpos= yythunkpos502; + } + { int yypos503= ctx->pos, yythunkpos503= ctx->thunkpos; if (!yy_Spacechar(ctx)) goto l504; goto l503; + l504:; ctx->pos= yypos503; ctx->thunkpos= yythunkpos503; if (!yy_Newline(ctx)) goto l477; + { int yypos505= ctx->pos, yythunkpos505= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l505; goto l477; + l505:; ctx->pos= yypos505; ctx->thunkpos= yythunkpos505; + } + } + l503:; + } + l492:; goto l476; + l477:; ctx->pos= yypos477; ctx->thunkpos= yythunkpos477; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l475; if (!yy_Sp(ctx)) goto l475; if (!yy_Ticks1(ctx)) goto l475; goto l474; + l475:; ctx->pos= yypos474; ctx->thunkpos= yythunkpos474; if (!yy_Ticks2(ctx)) goto l506; if (!yy_Sp(ctx)) goto l506; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l506; + { int yypos509= ctx->pos, yythunkpos509= ctx->thunkpos; + { int yypos513= ctx->pos, yythunkpos513= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l513; goto l510; + l513:; ctx->pos= yypos513; ctx->thunkpos= yythunkpos513; + } if (!yy_Nonspacechar(ctx)) goto l510; + l511:; + { int yypos512= ctx->pos, yythunkpos512= ctx->thunkpos; + { int yypos514= ctx->pos, yythunkpos514= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l514; goto l512; + l514:; ctx->pos= yypos514; ctx->thunkpos= yythunkpos514; + } if (!yy_Nonspacechar(ctx)) goto l512; goto l511; + l512:; ctx->pos= yypos512; ctx->thunkpos= yythunkpos512; + } goto l509; + l510:; ctx->pos= yypos509; ctx->thunkpos= yythunkpos509; + { int yypos516= ctx->pos, yythunkpos516= ctx->thunkpos; if (!yy_Ticks2(ctx)) goto l516; goto l515; + l516:; ctx->pos= yypos516; ctx->thunkpos= yythunkpos516; + } if (!yymatchChar(ctx, '`')) goto l515; + l517:; + { int yypos518= ctx->pos, yythunkpos518= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l518; goto l517; + l518:; ctx->pos= yypos518; ctx->thunkpos= yythunkpos518; + } goto l509; + l515:; ctx->pos= yypos509; ctx->thunkpos= yythunkpos509; + { int yypos519= ctx->pos, yythunkpos519= ctx->thunkpos; if (!yy_Sp(ctx)) goto l519; if (!yy_Ticks2(ctx)) goto l519; goto l506; + l519:; ctx->pos= yypos519; ctx->thunkpos= yythunkpos519; + } + { int yypos520= ctx->pos, yythunkpos520= ctx->thunkpos; if (!yy_Spacechar(ctx)) goto l521; goto l520; + l521:; ctx->pos= yypos520; ctx->thunkpos= yythunkpos520; if (!yy_Newline(ctx)) goto l506; + { int yypos522= ctx->pos, yythunkpos522= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l522; goto l506; + l522:; ctx->pos= yypos522; ctx->thunkpos= yythunkpos522; + } + } + l520:; + } + l509:; + l507:; + { int yypos508= ctx->pos, yythunkpos508= ctx->thunkpos; + { int yypos523= ctx->pos, yythunkpos523= ctx->thunkpos; + { int yypos527= ctx->pos, yythunkpos527= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l527; goto l524; + l527:; ctx->pos= yypos527; ctx->thunkpos= yythunkpos527; + } if (!yy_Nonspacechar(ctx)) goto l524; + l525:; + { int yypos526= ctx->pos, yythunkpos526= ctx->thunkpos; + { int yypos528= ctx->pos, yythunkpos528= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l528; goto l526; + l528:; ctx->pos= yypos528; ctx->thunkpos= yythunkpos528; + } if (!yy_Nonspacechar(ctx)) goto l526; goto l525; + l526:; ctx->pos= yypos526; ctx->thunkpos= yythunkpos526; + } goto l523; + l524:; ctx->pos= yypos523; ctx->thunkpos= yythunkpos523; + { int yypos530= ctx->pos, yythunkpos530= ctx->thunkpos; if (!yy_Ticks2(ctx)) goto l530; goto l529; + l530:; ctx->pos= yypos530; ctx->thunkpos= yythunkpos530; + } if (!yymatchChar(ctx, '`')) goto l529; + l531:; + { int yypos532= ctx->pos, yythunkpos532= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l532; goto l531; + l532:; ctx->pos= yypos532; ctx->thunkpos= yythunkpos532; + } goto l523; + l529:; ctx->pos= yypos523; ctx->thunkpos= yythunkpos523; + { int yypos533= ctx->pos, yythunkpos533= ctx->thunkpos; if (!yy_Sp(ctx)) goto l533; if (!yy_Ticks2(ctx)) goto l533; goto l508; + l533:; ctx->pos= yypos533; ctx->thunkpos= yythunkpos533; + } + { int yypos534= ctx->pos, yythunkpos534= ctx->thunkpos; if (!yy_Spacechar(ctx)) goto l535; goto l534; + l535:; ctx->pos= yypos534; ctx->thunkpos= yythunkpos534; if (!yy_Newline(ctx)) goto l508; + { int yypos536= ctx->pos, yythunkpos536= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l536; goto l508; + l536:; ctx->pos= yypos536; ctx->thunkpos= yythunkpos536; + } + } + l534:; + } + l523:; goto l507; + l508:; ctx->pos= yypos508; ctx->thunkpos= yythunkpos508; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l506; if (!yy_Sp(ctx)) goto l506; if (!yy_Ticks2(ctx)) goto l506; goto l474; + l506:; ctx->pos= yypos474; ctx->thunkpos= yythunkpos474; if (!yy_Ticks3(ctx)) goto l537; if (!yy_Sp(ctx)) goto l537; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l537; + { int yypos540= ctx->pos, yythunkpos540= ctx->thunkpos; + { int yypos544= ctx->pos, yythunkpos544= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l544; goto l541; + l544:; ctx->pos= yypos544; ctx->thunkpos= yythunkpos544; + } if (!yy_Nonspacechar(ctx)) goto l541; + l542:; + { int yypos543= ctx->pos, yythunkpos543= ctx->thunkpos; + { int yypos545= ctx->pos, yythunkpos545= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l545; goto l543; + l545:; ctx->pos= yypos545; ctx->thunkpos= yythunkpos545; + } if (!yy_Nonspacechar(ctx)) goto l543; goto l542; + l543:; ctx->pos= yypos543; ctx->thunkpos= yythunkpos543; + } goto l540; + l541:; ctx->pos= yypos540; ctx->thunkpos= yythunkpos540; + { int yypos547= ctx->pos, yythunkpos547= ctx->thunkpos; if (!yy_Ticks3(ctx)) goto l547; goto l546; + l547:; ctx->pos= yypos547; ctx->thunkpos= yythunkpos547; + } if (!yymatchChar(ctx, '`')) goto l546; + l548:; + { int yypos549= ctx->pos, yythunkpos549= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l549; goto l548; + l549:; ctx->pos= yypos549; ctx->thunkpos= yythunkpos549; + } goto l540; + l546:; ctx->pos= yypos540; ctx->thunkpos= yythunkpos540; + { int yypos550= ctx->pos, yythunkpos550= ctx->thunkpos; if (!yy_Sp(ctx)) goto l550; if (!yy_Ticks3(ctx)) goto l550; goto l537; + l550:; ctx->pos= yypos550; ctx->thunkpos= yythunkpos550; + } + { int yypos551= ctx->pos, yythunkpos551= ctx->thunkpos; if (!yy_Spacechar(ctx)) goto l552; goto l551; + l552:; ctx->pos= yypos551; ctx->thunkpos= yythunkpos551; if (!yy_Newline(ctx)) goto l537; + { int yypos553= ctx->pos, yythunkpos553= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l553; goto l537; + l553:; ctx->pos= yypos553; ctx->thunkpos= yythunkpos553; + } + } + l551:; + } + l540:; + l538:; + { int yypos539= ctx->pos, yythunkpos539= ctx->thunkpos; + { int yypos554= ctx->pos, yythunkpos554= ctx->thunkpos; + { int yypos558= ctx->pos, yythunkpos558= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l558; goto l555; + l558:; ctx->pos= yypos558; ctx->thunkpos= yythunkpos558; + } if (!yy_Nonspacechar(ctx)) goto l555; + l556:; + { int yypos557= ctx->pos, yythunkpos557= ctx->thunkpos; + { int yypos559= ctx->pos, yythunkpos559= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l559; goto l557; + l559:; ctx->pos= yypos559; ctx->thunkpos= yythunkpos559; + } if (!yy_Nonspacechar(ctx)) goto l557; goto l556; + l557:; ctx->pos= yypos557; ctx->thunkpos= yythunkpos557; + } goto l554; + l555:; ctx->pos= yypos554; ctx->thunkpos= yythunkpos554; + { int yypos561= ctx->pos, yythunkpos561= ctx->thunkpos; if (!yy_Ticks3(ctx)) goto l561; goto l560; + l561:; ctx->pos= yypos561; ctx->thunkpos= yythunkpos561; + } if (!yymatchChar(ctx, '`')) goto l560; + l562:; + { int yypos563= ctx->pos, yythunkpos563= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l563; goto l562; + l563:; ctx->pos= yypos563; ctx->thunkpos= yythunkpos563; + } goto l554; + l560:; ctx->pos= yypos554; ctx->thunkpos= yythunkpos554; + { int yypos564= ctx->pos, yythunkpos564= ctx->thunkpos; if (!yy_Sp(ctx)) goto l564; if (!yy_Ticks3(ctx)) goto l564; goto l539; + l564:; ctx->pos= yypos564; ctx->thunkpos= yythunkpos564; + } + { int yypos565= ctx->pos, yythunkpos565= ctx->thunkpos; if (!yy_Spacechar(ctx)) goto l566; goto l565; + l566:; ctx->pos= yypos565; ctx->thunkpos= yythunkpos565; if (!yy_Newline(ctx)) goto l539; + { int yypos567= ctx->pos, yythunkpos567= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l567; goto l539; + l567:; ctx->pos= yypos567; ctx->thunkpos= yythunkpos567; + } + } + l565:; + } + l554:; goto l538; + l539:; ctx->pos= yypos539; ctx->thunkpos= yythunkpos539; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l537; if (!yy_Sp(ctx)) goto l537; if (!yy_Ticks3(ctx)) goto l537; goto l474; + l537:; ctx->pos= yypos474; ctx->thunkpos= yythunkpos474; if (!yy_Ticks4(ctx)) goto l568; if (!yy_Sp(ctx)) goto l568; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l568; + { int yypos571= ctx->pos, yythunkpos571= ctx->thunkpos; + { int yypos575= ctx->pos, yythunkpos575= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l575; goto l572; + l575:; ctx->pos= yypos575; ctx->thunkpos= yythunkpos575; + } if (!yy_Nonspacechar(ctx)) goto l572; + l573:; + { int yypos574= ctx->pos, yythunkpos574= ctx->thunkpos; + { int yypos576= ctx->pos, yythunkpos576= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l576; goto l574; + l576:; ctx->pos= yypos576; ctx->thunkpos= yythunkpos576; + } if (!yy_Nonspacechar(ctx)) goto l574; goto l573; + l574:; ctx->pos= yypos574; ctx->thunkpos= yythunkpos574; + } goto l571; + l572:; ctx->pos= yypos571; ctx->thunkpos= yythunkpos571; + { int yypos578= ctx->pos, yythunkpos578= ctx->thunkpos; if (!yy_Ticks4(ctx)) goto l578; goto l577; + l578:; ctx->pos= yypos578; ctx->thunkpos= yythunkpos578; + } if (!yymatchChar(ctx, '`')) goto l577; + l579:; + { int yypos580= ctx->pos, yythunkpos580= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l580; goto l579; + l580:; ctx->pos= yypos580; ctx->thunkpos= yythunkpos580; + } goto l571; + l577:; ctx->pos= yypos571; ctx->thunkpos= yythunkpos571; + { int yypos581= ctx->pos, yythunkpos581= ctx->thunkpos; if (!yy_Sp(ctx)) goto l581; if (!yy_Ticks4(ctx)) goto l581; goto l568; + l581:; ctx->pos= yypos581; ctx->thunkpos= yythunkpos581; + } + { int yypos582= ctx->pos, yythunkpos582= ctx->thunkpos; if (!yy_Spacechar(ctx)) goto l583; goto l582; + l583:; ctx->pos= yypos582; ctx->thunkpos= yythunkpos582; if (!yy_Newline(ctx)) goto l568; + { int yypos584= ctx->pos, yythunkpos584= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l584; goto l568; + l584:; ctx->pos= yypos584; ctx->thunkpos= yythunkpos584; + } + } + l582:; + } + l571:; + l569:; + { int yypos570= ctx->pos, yythunkpos570= ctx->thunkpos; + { int yypos585= ctx->pos, yythunkpos585= ctx->thunkpos; + { int yypos589= ctx->pos, yythunkpos589= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l589; goto l586; + l589:; ctx->pos= yypos589; ctx->thunkpos= yythunkpos589; + } if (!yy_Nonspacechar(ctx)) goto l586; + l587:; + { int yypos588= ctx->pos, yythunkpos588= ctx->thunkpos; + { int yypos590= ctx->pos, yythunkpos590= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l590; goto l588; + l590:; ctx->pos= yypos590; ctx->thunkpos= yythunkpos590; + } if (!yy_Nonspacechar(ctx)) goto l588; goto l587; + l588:; ctx->pos= yypos588; ctx->thunkpos= yythunkpos588; + } goto l585; + l586:; ctx->pos= yypos585; ctx->thunkpos= yythunkpos585; + { int yypos592= ctx->pos, yythunkpos592= ctx->thunkpos; if (!yy_Ticks4(ctx)) goto l592; goto l591; + l592:; ctx->pos= yypos592; ctx->thunkpos= yythunkpos592; + } if (!yymatchChar(ctx, '`')) goto l591; + l593:; + { int yypos594= ctx->pos, yythunkpos594= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l594; goto l593; + l594:; ctx->pos= yypos594; ctx->thunkpos= yythunkpos594; + } goto l585; + l591:; ctx->pos= yypos585; ctx->thunkpos= yythunkpos585; + { int yypos595= ctx->pos, yythunkpos595= ctx->thunkpos; if (!yy_Sp(ctx)) goto l595; if (!yy_Ticks4(ctx)) goto l595; goto l570; + l595:; ctx->pos= yypos595; ctx->thunkpos= yythunkpos595; + } + { int yypos596= ctx->pos, yythunkpos596= ctx->thunkpos; if (!yy_Spacechar(ctx)) goto l597; goto l596; + l597:; ctx->pos= yypos596; ctx->thunkpos= yythunkpos596; if (!yy_Newline(ctx)) goto l570; + { int yypos598= ctx->pos, yythunkpos598= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l598; goto l570; + l598:; ctx->pos= yypos598; ctx->thunkpos= yythunkpos598; + } + } + l596:; + } + l585:; goto l569; + l570:; ctx->pos= yypos570; ctx->thunkpos= yythunkpos570; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l568; if (!yy_Sp(ctx)) goto l568; if (!yy_Ticks4(ctx)) goto l568; goto l474; + l568:; ctx->pos= yypos474; ctx->thunkpos= yythunkpos474; if (!yy_Ticks5(ctx)) goto l473; if (!yy_Sp(ctx)) goto l473; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l473; + { int yypos601= ctx->pos, yythunkpos601= ctx->thunkpos; + { int yypos605= ctx->pos, yythunkpos605= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l605; goto l602; + l605:; ctx->pos= yypos605; ctx->thunkpos= yythunkpos605; + } if (!yy_Nonspacechar(ctx)) goto l602; + l603:; + { int yypos604= ctx->pos, yythunkpos604= ctx->thunkpos; + { int yypos606= ctx->pos, yythunkpos606= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l606; goto l604; + l606:; ctx->pos= yypos606; ctx->thunkpos= yythunkpos606; + } if (!yy_Nonspacechar(ctx)) goto l604; goto l603; + l604:; ctx->pos= yypos604; ctx->thunkpos= yythunkpos604; + } goto l601; + l602:; ctx->pos= yypos601; ctx->thunkpos= yythunkpos601; + { int yypos608= ctx->pos, yythunkpos608= ctx->thunkpos; if (!yy_Ticks5(ctx)) goto l608; goto l607; + l608:; ctx->pos= yypos608; ctx->thunkpos= yythunkpos608; + } if (!yymatchChar(ctx, '`')) goto l607; + l609:; + { int yypos610= ctx->pos, yythunkpos610= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l610; goto l609; + l610:; ctx->pos= yypos610; ctx->thunkpos= yythunkpos610; + } goto l601; + l607:; ctx->pos= yypos601; ctx->thunkpos= yythunkpos601; + { int yypos611= ctx->pos, yythunkpos611= ctx->thunkpos; if (!yy_Sp(ctx)) goto l611; if (!yy_Ticks5(ctx)) goto l611; goto l473; + l611:; ctx->pos= yypos611; ctx->thunkpos= yythunkpos611; + } + { int yypos612= ctx->pos, yythunkpos612= ctx->thunkpos; if (!yy_Spacechar(ctx)) goto l613; goto l612; + l613:; ctx->pos= yypos612; ctx->thunkpos= yythunkpos612; if (!yy_Newline(ctx)) goto l473; + { int yypos614= ctx->pos, yythunkpos614= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l614; goto l473; + l614:; ctx->pos= yypos614; ctx->thunkpos= yythunkpos614; + } + } + l612:; + } + l601:; + l599:; + { int yypos600= ctx->pos, yythunkpos600= ctx->thunkpos; + { int yypos615= ctx->pos, yythunkpos615= ctx->thunkpos; + { int yypos619= ctx->pos, yythunkpos619= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l619; goto l616; + l619:; ctx->pos= yypos619; ctx->thunkpos= yythunkpos619; + } if (!yy_Nonspacechar(ctx)) goto l616; + l617:; + { int yypos618= ctx->pos, yythunkpos618= ctx->thunkpos; + { int yypos620= ctx->pos, yythunkpos620= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l620; goto l618; + l620:; ctx->pos= yypos620; ctx->thunkpos= yythunkpos620; + } if (!yy_Nonspacechar(ctx)) goto l618; goto l617; + l618:; ctx->pos= yypos618; ctx->thunkpos= yythunkpos618; + } goto l615; + l616:; ctx->pos= yypos615; ctx->thunkpos= yythunkpos615; + { int yypos622= ctx->pos, yythunkpos622= ctx->thunkpos; if (!yy_Ticks5(ctx)) goto l622; goto l621; + l622:; ctx->pos= yypos622; ctx->thunkpos= yythunkpos622; + } if (!yymatchChar(ctx, '`')) goto l621; + l623:; + { int yypos624= ctx->pos, yythunkpos624= ctx->thunkpos; if (!yymatchChar(ctx, '`')) goto l624; goto l623; + l624:; ctx->pos= yypos624; ctx->thunkpos= yythunkpos624; + } goto l615; + l621:; ctx->pos= yypos615; ctx->thunkpos= yythunkpos615; + { int yypos625= ctx->pos, yythunkpos625= ctx->thunkpos; if (!yy_Sp(ctx)) goto l625; if (!yy_Ticks5(ctx)) goto l625; goto l600; + l625:; ctx->pos= yypos625; ctx->thunkpos= yythunkpos625; + } + { int yypos626= ctx->pos, yythunkpos626= ctx->thunkpos; if (!yy_Spacechar(ctx)) goto l627; goto l626; + l627:; ctx->pos= yypos626; ctx->thunkpos= yythunkpos626; if (!yy_Newline(ctx)) goto l600; + { int yypos628= ctx->pos, yythunkpos628= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l628; goto l600; + l628:; ctx->pos= yypos628; ctx->thunkpos= yythunkpos628; + } + } + l626:; + } + l615:; goto l599; + l600:; ctx->pos= yypos600; ctx->thunkpos= yythunkpos600; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l473; if (!yy_Sp(ctx)) goto l473; if (!yy_Ticks5(ctx)) goto l473; + } + l474:; yyDo(ctx, yy_1_Code, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "Code", ctx->buf+ctx->pos)); + return 1; + l473:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Code", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_InlineNote(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "InlineNote")); yyText(ctx, ctx->begin, ctx->end); if (!( extension(EXT_NOTES) )) goto l629; if (!yymatchString(ctx, "^[")) goto l629; if (!yy_StartList(ctx)) goto l629; yyDo(ctx, yySet, -1, 0); + { int yypos632= ctx->pos, yythunkpos632= ctx->thunkpos; if (!yymatchChar(ctx, ']')) goto l632; goto l629; + l632:; ctx->pos= yypos632; ctx->thunkpos= yythunkpos632; + } if (!yy_Inline(ctx)) goto l629; yyDo(ctx, yy_1_InlineNote, ctx->begin, ctx->end); + l630:; + { int yypos631= ctx->pos, yythunkpos631= ctx->thunkpos; + { int yypos633= ctx->pos, yythunkpos633= ctx->thunkpos; if (!yymatchChar(ctx, ']')) goto l633; goto l631; + l633:; ctx->pos= yypos633; ctx->thunkpos= yythunkpos633; + } if (!yy_Inline(ctx)) goto l631; yyDo(ctx, yy_1_InlineNote, ctx->begin, ctx->end); goto l630; + l631:; ctx->pos= yypos631; ctx->thunkpos= yythunkpos631; + } if (!yymatchChar(ctx, ']')) goto l629; yyDo(ctx, yy_2_InlineNote, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "InlineNote", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 1, 0); + return 1; + l629:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "InlineNote", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_NoteReference(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "NoteReference")); yyText(ctx, ctx->begin, ctx->end); if (!( extension(EXT_NOTES) )) goto l634; if (!yy_RawNoteReference(ctx)) goto l634; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_1_NoteReference, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "NoteReference", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 1, 0); + return 1; + l634:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "NoteReference", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Link(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Link")); + { int yypos636= ctx->pos, yythunkpos636= ctx->thunkpos; if (!yy_ExplicitLink(ctx)) goto l637; goto l636; + l637:; ctx->pos= yypos636; ctx->thunkpos= yythunkpos636; if (!yy_ReferenceLink(ctx)) goto l638; goto l636; + l638:; ctx->pos= yypos636; ctx->thunkpos= yythunkpos636; if (!yy_AutoLink(ctx)) goto l635; + } + l636:; + yyprintf((stderr, " ok %s @ %s\n", "Link", ctx->buf+ctx->pos)); + return 1; + l635:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Link", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Image(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Image")); if (!yymatchChar(ctx, '!')) goto l639; + { int yypos640= ctx->pos, yythunkpos640= ctx->thunkpos; if (!yy_ExplicitLink(ctx)) goto l641; goto l640; + l641:; ctx->pos= yypos640; ctx->thunkpos= yythunkpos640; if (!yy_ReferenceLink(ctx)) goto l639; + } + l640:; yyDo(ctx, yy_1_Image, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "Image", ctx->buf+ctx->pos)); + return 1; + l639:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Image", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Emph(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Emph")); + { int yypos643= ctx->pos, yythunkpos643= ctx->thunkpos; if (!yy_EmphStar(ctx)) goto l644; goto l643; + l644:; ctx->pos= yypos643; ctx->thunkpos= yythunkpos643; if (!yy_EmphUl(ctx)) goto l642; + } + l643:; + yyprintf((stderr, " ok %s @ %s\n", "Emph", ctx->buf+ctx->pos)); + return 1; + l642:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Emph", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Strong(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Strong")); + { int yypos646= ctx->pos, yythunkpos646= ctx->thunkpos; if (!yy_StrongStar(ctx)) goto l647; goto l646; + l647:; ctx->pos= yypos646; ctx->thunkpos= yythunkpos646; if (!yy_StrongUl(ctx)) goto l645; + } + l646:; + yyprintf((stderr, " ok %s @ %s\n", "Strong", ctx->buf+ctx->pos)); + return 1; + l645:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Strong", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Space(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Space")); if (!yy_Spacechar(ctx)) goto l648; + l649:; + { int yypos650= ctx->pos, yythunkpos650= ctx->thunkpos; if (!yy_Spacechar(ctx)) goto l650; goto l649; + l650:; ctx->pos= yypos650; ctx->thunkpos= yythunkpos650; + } yyDo(ctx, yy_1_Space, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "Space", ctx->buf+ctx->pos)); + return 1; + l648:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Space", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_UlOrStarLine(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "UlOrStarLine")); + { int yypos652= ctx->pos, yythunkpos652= ctx->thunkpos; if (!yy_UlLine(ctx)) goto l653; goto l652; + l653:; ctx->pos= yypos652; ctx->thunkpos= yythunkpos652; if (!yy_StarLine(ctx)) goto l651; + } + l652:; yyDo(ctx, yy_1_UlOrStarLine, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "UlOrStarLine", ctx->buf+ctx->pos)); + return 1; + l651:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "UlOrStarLine", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Str(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "Str")); if (!yy_StartList(ctx)) goto l654; yyDo(ctx, yySet, -1, 0); yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l654; if (!yy_NormalChar(ctx)) goto l654; + l655:; + { int yypos656= ctx->pos, yythunkpos656= ctx->thunkpos; if (!yy_NormalChar(ctx)) goto l656; goto l655; + l656:; ctx->pos= yypos656; ctx->thunkpos= yythunkpos656; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l654; yyDo(ctx, yy_1_Str, ctx->begin, ctx->end); + l657:; + { int yypos658= ctx->pos, yythunkpos658= ctx->thunkpos; if (!yy_StrChunk(ctx)) goto l658; yyDo(ctx, yy_2_Str, ctx->begin, ctx->end); goto l657; + l658:; ctx->pos= yypos658; ctx->thunkpos= yythunkpos658; + } yyDo(ctx, yy_3_Str, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "Str", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 1, 0); + return 1; + l654:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Str", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_InStyleTags(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "InStyleTags")); if (!yy_StyleOpen(ctx)) goto l659; + l660:; + { int yypos661= ctx->pos, yythunkpos661= ctx->thunkpos; + { int yypos662= ctx->pos, yythunkpos662= ctx->thunkpos; if (!yy_StyleClose(ctx)) goto l662; goto l661; + l662:; ctx->pos= yypos662; ctx->thunkpos= yythunkpos662; + } if (!yymatchDot(ctx)) goto l661; goto l660; + l661:; ctx->pos= yypos661; ctx->thunkpos= yythunkpos661; + } if (!yy_StyleClose(ctx)) goto l659; + yyprintf((stderr, " ok %s @ %s\n", "InStyleTags", ctx->buf+ctx->pos)); + return 1; + l659:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "InStyleTags", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_StyleClose(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "StyleClose")); if (!yymatchChar(ctx, '<')) goto l663; if (!yy_Spnl(ctx)) goto l663; if (!yymatchChar(ctx, '/')) goto l663; + { int yypos664= ctx->pos, yythunkpos664= ctx->thunkpos; if (!yymatchString(ctx, "style")) goto l665; goto l664; + l665:; ctx->pos= yypos664; ctx->thunkpos= yythunkpos664; if (!yymatchString(ctx, "STYLE")) goto l663; + } + l664:; if (!yy_Spnl(ctx)) goto l663; if (!yymatchChar(ctx, '>')) goto l663; + yyprintf((stderr, " ok %s @ %s\n", "StyleClose", ctx->buf+ctx->pos)); + return 1; + l663:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "StyleClose", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_StyleOpen(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "StyleOpen")); if (!yymatchChar(ctx, '<')) goto l666; if (!yy_Spnl(ctx)) goto l666; + { int yypos667= ctx->pos, yythunkpos667= ctx->thunkpos; if (!yymatchString(ctx, "style")) goto l668; goto l667; + l668:; ctx->pos= yypos667; ctx->thunkpos= yythunkpos667; if (!yymatchString(ctx, "STYLE")) goto l666; + } + l667:; if (!yy_Spnl(ctx)) goto l666; + l669:; + { int yypos670= ctx->pos, yythunkpos670= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l670; goto l669; + l670:; ctx->pos= yypos670; ctx->thunkpos= yythunkpos670; + } if (!yymatchChar(ctx, '>')) goto l666; + yyprintf((stderr, " ok %s @ %s\n", "StyleOpen", ctx->buf+ctx->pos)); + return 1; + l666:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "StyleOpen", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockType(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockType")); + { int yypos672= ctx->pos, yythunkpos672= ctx->thunkpos; if (!yymatchString(ctx, "address")) goto l673; goto l672; + l673:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "blockquote")) goto l674; goto l672; + l674:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "center")) goto l675; goto l672; + l675:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "dir")) goto l676; goto l672; + l676:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "div")) goto l677; goto l672; + l677:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "dl")) goto l678; goto l672; + l678:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "fieldset")) goto l679; goto l672; + l679:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "form")) goto l680; goto l672; + l680:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "h1")) goto l681; goto l672; + l681:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "h2")) goto l682; goto l672; + l682:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "h3")) goto l683; goto l672; + l683:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "h4")) goto l684; goto l672; + l684:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "h5")) goto l685; goto l672; + l685:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "h6")) goto l686; goto l672; + l686:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "hr")) goto l687; goto l672; + l687:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "isindex")) goto l688; goto l672; + l688:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "menu")) goto l689; goto l672; + l689:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "noframes")) goto l690; goto l672; + l690:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "noscript")) goto l691; goto l672; + l691:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "ol")) goto l692; goto l672; + l692:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchChar(ctx, 'p')) goto l693; goto l672; + l693:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "pre")) goto l694; goto l672; + l694:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "table")) goto l695; goto l672; + l695:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "ul")) goto l696; goto l672; + l696:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "dd")) goto l697; goto l672; + l697:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "dt")) goto l698; goto l672; + l698:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "frameset")) goto l699; goto l672; + l699:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "li")) goto l700; goto l672; + l700:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "tbody")) goto l701; goto l672; + l701:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "td")) goto l702; goto l672; + l702:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "tfoot")) goto l703; goto l672; + l703:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "th")) goto l704; goto l672; + l704:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "thead")) goto l705; goto l672; + l705:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "tr")) goto l706; goto l672; + l706:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "script")) goto l707; goto l672; + l707:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "ADDRESS")) goto l708; goto l672; + l708:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "BLOCKQUOTE")) goto l709; goto l672; + l709:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "CENTER")) goto l710; goto l672; + l710:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "DIR")) goto l711; goto l672; + l711:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "DIV")) goto l712; goto l672; + l712:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "DL")) goto l713; goto l672; + l713:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "FIELDSET")) goto l714; goto l672; + l714:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "FORM")) goto l715; goto l672; + l715:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "H1")) goto l716; goto l672; + l716:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "H2")) goto l717; goto l672; + l717:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "H3")) goto l718; goto l672; + l718:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "H4")) goto l719; goto l672; + l719:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "H5")) goto l720; goto l672; + l720:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "H6")) goto l721; goto l672; + l721:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "HR")) goto l722; goto l672; + l722:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "ISINDEX")) goto l723; goto l672; + l723:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "MENU")) goto l724; goto l672; + l724:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "NOFRAMES")) goto l725; goto l672; + l725:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "NOSCRIPT")) goto l726; goto l672; + l726:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "OL")) goto l727; goto l672; + l727:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchChar(ctx, 'P')) goto l728; goto l672; + l728:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "PRE")) goto l729; goto l672; + l729:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "TABLE")) goto l730; goto l672; + l730:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "UL")) goto l731; goto l672; + l731:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "DD")) goto l732; goto l672; + l732:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "DT")) goto l733; goto l672; + l733:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "FRAMESET")) goto l734; goto l672; + l734:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "LI")) goto l735; goto l672; + l735:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "TBODY")) goto l736; goto l672; + l736:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "TD")) goto l737; goto l672; + l737:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "TFOOT")) goto l738; goto l672; + l738:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "TH")) goto l739; goto l672; + l739:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "THEAD")) goto l740; goto l672; + l740:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "TR")) goto l741; goto l672; + l741:; ctx->pos= yypos672; ctx->thunkpos= yythunkpos672; if (!yymatchString(ctx, "SCRIPT")) goto l671; + } + l672:; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockType", ctx->buf+ctx->pos)); + return 1; + l671:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockType", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockSelfClosing(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockSelfClosing")); if (!yymatchChar(ctx, '<')) goto l742; if (!yy_Spnl(ctx)) goto l742; if (!yy_HtmlBlockType(ctx)) goto l742; if (!yy_Spnl(ctx)) goto l742; + l743:; + { int yypos744= ctx->pos, yythunkpos744= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l744; goto l743; + l744:; ctx->pos= yypos744; ctx->thunkpos= yythunkpos744; + } if (!yymatchChar(ctx, '/')) goto l742; if (!yy_Spnl(ctx)) goto l742; if (!yymatchChar(ctx, '>')) goto l742; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockSelfClosing", ctx->buf+ctx->pos)); + return 1; + l742:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockSelfClosing", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlComment(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlComment")); if (!yymatchString(ctx, "")) goto l748; goto l747; + l748:; ctx->pos= yypos748; ctx->thunkpos= yythunkpos748; + } if (!yymatchDot(ctx)) goto l747; goto l746; + l747:; ctx->pos= yypos747; ctx->thunkpos= yythunkpos747; + } if (!yymatchString(ctx, "-->")) goto l745; + yyprintf((stderr, " ok %s @ %s\n", "HtmlComment", ctx->buf+ctx->pos)); + return 1; + l745:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlComment", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockInTags(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockInTags")); + { int yypos750= ctx->pos, yythunkpos750= ctx->thunkpos; if (!yy_HtmlBlockAddress(ctx)) goto l751; goto l750; + l751:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockBlockquote(ctx)) goto l752; goto l750; + l752:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockCenter(ctx)) goto l753; goto l750; + l753:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockDir(ctx)) goto l754; goto l750; + l754:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockDiv(ctx)) goto l755; goto l750; + l755:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockDl(ctx)) goto l756; goto l750; + l756:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockFieldset(ctx)) goto l757; goto l750; + l757:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockForm(ctx)) goto l758; goto l750; + l758:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockH1(ctx)) goto l759; goto l750; + l759:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockH2(ctx)) goto l760; goto l750; + l760:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockH3(ctx)) goto l761; goto l750; + l761:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockH4(ctx)) goto l762; goto l750; + l762:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockH5(ctx)) goto l763; goto l750; + l763:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockH6(ctx)) goto l764; goto l750; + l764:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockMenu(ctx)) goto l765; goto l750; + l765:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockNoframes(ctx)) goto l766; goto l750; + l766:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockNoscript(ctx)) goto l767; goto l750; + l767:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockOl(ctx)) goto l768; goto l750; + l768:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockP(ctx)) goto l769; goto l750; + l769:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockPre(ctx)) goto l770; goto l750; + l770:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockTable(ctx)) goto l771; goto l750; + l771:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockUl(ctx)) goto l772; goto l750; + l772:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockDd(ctx)) goto l773; goto l750; + l773:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockDt(ctx)) goto l774; goto l750; + l774:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockFrameset(ctx)) goto l775; goto l750; + l775:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockLi(ctx)) goto l776; goto l750; + l776:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockTbody(ctx)) goto l777; goto l750; + l777:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockTd(ctx)) goto l778; goto l750; + l778:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockTfoot(ctx)) goto l779; goto l750; + l779:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockTh(ctx)) goto l780; goto l750; + l780:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockThead(ctx)) goto l781; goto l750; + l781:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockTr(ctx)) goto l782; goto l750; + l782:; ctx->pos= yypos750; ctx->thunkpos= yythunkpos750; if (!yy_HtmlBlockScript(ctx)) goto l749; + } + l750:; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockInTags", ctx->buf+ctx->pos)); + return 1; + l749:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockInTags", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockScript(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockScript")); if (!yy_HtmlBlockOpenScript(ctx)) goto l783; + l784:; + { int yypos785= ctx->pos, yythunkpos785= ctx->thunkpos; + { int yypos786= ctx->pos, yythunkpos786= ctx->thunkpos; if (!yy_HtmlBlockCloseScript(ctx)) goto l786; goto l785; + l786:; ctx->pos= yypos786; ctx->thunkpos= yythunkpos786; + } if (!yymatchDot(ctx)) goto l785; goto l784; + l785:; ctx->pos= yypos785; ctx->thunkpos= yythunkpos785; + } if (!yy_HtmlBlockCloseScript(ctx)) goto l783; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockScript", ctx->buf+ctx->pos)); + return 1; + l783:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockScript", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseScript(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseScript")); if (!yymatchChar(ctx, '<')) goto l787; if (!yy_Spnl(ctx)) goto l787; if (!yymatchChar(ctx, '/')) goto l787; + { int yypos788= ctx->pos, yythunkpos788= ctx->thunkpos; if (!yymatchString(ctx, "script")) goto l789; goto l788; + l789:; ctx->pos= yypos788; ctx->thunkpos= yythunkpos788; if (!yymatchString(ctx, "SCRIPT")) goto l787; + } + l788:; if (!yy_Spnl(ctx)) goto l787; if (!yymatchChar(ctx, '>')) goto l787; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseScript", ctx->buf+ctx->pos)); + return 1; + l787:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseScript", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenScript(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenScript")); if (!yymatchChar(ctx, '<')) goto l790; if (!yy_Spnl(ctx)) goto l790; + { int yypos791= ctx->pos, yythunkpos791= ctx->thunkpos; if (!yymatchString(ctx, "script")) goto l792; goto l791; + l792:; ctx->pos= yypos791; ctx->thunkpos= yythunkpos791; if (!yymatchString(ctx, "SCRIPT")) goto l790; + } + l791:; if (!yy_Spnl(ctx)) goto l790; + l793:; + { int yypos794= ctx->pos, yythunkpos794= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l794; goto l793; + l794:; ctx->pos= yypos794; ctx->thunkpos= yythunkpos794; + } if (!yymatchChar(ctx, '>')) goto l790; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenScript", ctx->buf+ctx->pos)); + return 1; + l790:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenScript", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockTr(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockTr")); if (!yy_HtmlBlockOpenTr(ctx)) goto l795; + l796:; + { int yypos797= ctx->pos, yythunkpos797= ctx->thunkpos; + { int yypos798= ctx->pos, yythunkpos798= ctx->thunkpos; if (!yy_HtmlBlockTr(ctx)) goto l799; goto l798; + l799:; ctx->pos= yypos798; ctx->thunkpos= yythunkpos798; + { int yypos800= ctx->pos, yythunkpos800= ctx->thunkpos; if (!yy_HtmlBlockCloseTr(ctx)) goto l800; goto l797; + l800:; ctx->pos= yypos800; ctx->thunkpos= yythunkpos800; + } if (!yymatchDot(ctx)) goto l797; + } + l798:; goto l796; + l797:; ctx->pos= yypos797; ctx->thunkpos= yythunkpos797; + } if (!yy_HtmlBlockCloseTr(ctx)) goto l795; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockTr", ctx->buf+ctx->pos)); + return 1; + l795:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockTr", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseTr(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseTr")); if (!yymatchChar(ctx, '<')) goto l801; if (!yy_Spnl(ctx)) goto l801; if (!yymatchChar(ctx, '/')) goto l801; + { int yypos802= ctx->pos, yythunkpos802= ctx->thunkpos; if (!yymatchString(ctx, "tr")) goto l803; goto l802; + l803:; ctx->pos= yypos802; ctx->thunkpos= yythunkpos802; if (!yymatchString(ctx, "TR")) goto l801; + } + l802:; if (!yy_Spnl(ctx)) goto l801; if (!yymatchChar(ctx, '>')) goto l801; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseTr", ctx->buf+ctx->pos)); + return 1; + l801:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseTr", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenTr(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenTr")); if (!yymatchChar(ctx, '<')) goto l804; if (!yy_Spnl(ctx)) goto l804; + { int yypos805= ctx->pos, yythunkpos805= ctx->thunkpos; if (!yymatchString(ctx, "tr")) goto l806; goto l805; + l806:; ctx->pos= yypos805; ctx->thunkpos= yythunkpos805; if (!yymatchString(ctx, "TR")) goto l804; + } + l805:; if (!yy_Spnl(ctx)) goto l804; + l807:; + { int yypos808= ctx->pos, yythunkpos808= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l808; goto l807; + l808:; ctx->pos= yypos808; ctx->thunkpos= yythunkpos808; + } if (!yymatchChar(ctx, '>')) goto l804; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenTr", ctx->buf+ctx->pos)); + return 1; + l804:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenTr", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockThead(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockThead")); if (!yy_HtmlBlockOpenThead(ctx)) goto l809; + l810:; + { int yypos811= ctx->pos, yythunkpos811= ctx->thunkpos; + { int yypos812= ctx->pos, yythunkpos812= ctx->thunkpos; if (!yy_HtmlBlockThead(ctx)) goto l813; goto l812; + l813:; ctx->pos= yypos812; ctx->thunkpos= yythunkpos812; + { int yypos814= ctx->pos, yythunkpos814= ctx->thunkpos; if (!yy_HtmlBlockCloseThead(ctx)) goto l814; goto l811; + l814:; ctx->pos= yypos814; ctx->thunkpos= yythunkpos814; + } if (!yymatchDot(ctx)) goto l811; + } + l812:; goto l810; + l811:; ctx->pos= yypos811; ctx->thunkpos= yythunkpos811; + } if (!yy_HtmlBlockCloseThead(ctx)) goto l809; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockThead", ctx->buf+ctx->pos)); + return 1; + l809:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockThead", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseThead(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseThead")); if (!yymatchChar(ctx, '<')) goto l815; if (!yy_Spnl(ctx)) goto l815; if (!yymatchChar(ctx, '/')) goto l815; + { int yypos816= ctx->pos, yythunkpos816= ctx->thunkpos; if (!yymatchString(ctx, "thead")) goto l817; goto l816; + l817:; ctx->pos= yypos816; ctx->thunkpos= yythunkpos816; if (!yymatchString(ctx, "THEAD")) goto l815; + } + l816:; if (!yy_Spnl(ctx)) goto l815; if (!yymatchChar(ctx, '>')) goto l815; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseThead", ctx->buf+ctx->pos)); + return 1; + l815:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseThead", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenThead(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenThead")); if (!yymatchChar(ctx, '<')) goto l818; if (!yy_Spnl(ctx)) goto l818; + { int yypos819= ctx->pos, yythunkpos819= ctx->thunkpos; if (!yymatchString(ctx, "thead")) goto l820; goto l819; + l820:; ctx->pos= yypos819; ctx->thunkpos= yythunkpos819; if (!yymatchString(ctx, "THEAD")) goto l818; + } + l819:; if (!yy_Spnl(ctx)) goto l818; + l821:; + { int yypos822= ctx->pos, yythunkpos822= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l822; goto l821; + l822:; ctx->pos= yypos822; ctx->thunkpos= yythunkpos822; + } if (!yymatchChar(ctx, '>')) goto l818; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenThead", ctx->buf+ctx->pos)); + return 1; + l818:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenThead", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockTh(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockTh")); if (!yy_HtmlBlockOpenTh(ctx)) goto l823; + l824:; + { int yypos825= ctx->pos, yythunkpos825= ctx->thunkpos; + { int yypos826= ctx->pos, yythunkpos826= ctx->thunkpos; if (!yy_HtmlBlockTh(ctx)) goto l827; goto l826; + l827:; ctx->pos= yypos826; ctx->thunkpos= yythunkpos826; + { int yypos828= ctx->pos, yythunkpos828= ctx->thunkpos; if (!yy_HtmlBlockCloseTh(ctx)) goto l828; goto l825; + l828:; ctx->pos= yypos828; ctx->thunkpos= yythunkpos828; + } if (!yymatchDot(ctx)) goto l825; + } + l826:; goto l824; + l825:; ctx->pos= yypos825; ctx->thunkpos= yythunkpos825; + } if (!yy_HtmlBlockCloseTh(ctx)) goto l823; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockTh", ctx->buf+ctx->pos)); + return 1; + l823:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockTh", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseTh(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseTh")); if (!yymatchChar(ctx, '<')) goto l829; if (!yy_Spnl(ctx)) goto l829; if (!yymatchChar(ctx, '/')) goto l829; + { int yypos830= ctx->pos, yythunkpos830= ctx->thunkpos; if (!yymatchString(ctx, "th")) goto l831; goto l830; + l831:; ctx->pos= yypos830; ctx->thunkpos= yythunkpos830; if (!yymatchString(ctx, "TH")) goto l829; + } + l830:; if (!yy_Spnl(ctx)) goto l829; if (!yymatchChar(ctx, '>')) goto l829; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseTh", ctx->buf+ctx->pos)); + return 1; + l829:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseTh", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenTh(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenTh")); if (!yymatchChar(ctx, '<')) goto l832; if (!yy_Spnl(ctx)) goto l832; + { int yypos833= ctx->pos, yythunkpos833= ctx->thunkpos; if (!yymatchString(ctx, "th")) goto l834; goto l833; + l834:; ctx->pos= yypos833; ctx->thunkpos= yythunkpos833; if (!yymatchString(ctx, "TH")) goto l832; + } + l833:; if (!yy_Spnl(ctx)) goto l832; + l835:; + { int yypos836= ctx->pos, yythunkpos836= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l836; goto l835; + l836:; ctx->pos= yypos836; ctx->thunkpos= yythunkpos836; + } if (!yymatchChar(ctx, '>')) goto l832; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenTh", ctx->buf+ctx->pos)); + return 1; + l832:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenTh", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockTfoot(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockTfoot")); if (!yy_HtmlBlockOpenTfoot(ctx)) goto l837; + l838:; + { int yypos839= ctx->pos, yythunkpos839= ctx->thunkpos; + { int yypos840= ctx->pos, yythunkpos840= ctx->thunkpos; if (!yy_HtmlBlockTfoot(ctx)) goto l841; goto l840; + l841:; ctx->pos= yypos840; ctx->thunkpos= yythunkpos840; + { int yypos842= ctx->pos, yythunkpos842= ctx->thunkpos; if (!yy_HtmlBlockCloseTfoot(ctx)) goto l842; goto l839; + l842:; ctx->pos= yypos842; ctx->thunkpos= yythunkpos842; + } if (!yymatchDot(ctx)) goto l839; + } + l840:; goto l838; + l839:; ctx->pos= yypos839; ctx->thunkpos= yythunkpos839; + } if (!yy_HtmlBlockCloseTfoot(ctx)) goto l837; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockTfoot", ctx->buf+ctx->pos)); + return 1; + l837:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockTfoot", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseTfoot(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseTfoot")); if (!yymatchChar(ctx, '<')) goto l843; if (!yy_Spnl(ctx)) goto l843; if (!yymatchChar(ctx, '/')) goto l843; + { int yypos844= ctx->pos, yythunkpos844= ctx->thunkpos; if (!yymatchString(ctx, "tfoot")) goto l845; goto l844; + l845:; ctx->pos= yypos844; ctx->thunkpos= yythunkpos844; if (!yymatchString(ctx, "TFOOT")) goto l843; + } + l844:; if (!yy_Spnl(ctx)) goto l843; if (!yymatchChar(ctx, '>')) goto l843; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseTfoot", ctx->buf+ctx->pos)); + return 1; + l843:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseTfoot", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenTfoot(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenTfoot")); if (!yymatchChar(ctx, '<')) goto l846; if (!yy_Spnl(ctx)) goto l846; + { int yypos847= ctx->pos, yythunkpos847= ctx->thunkpos; if (!yymatchString(ctx, "tfoot")) goto l848; goto l847; + l848:; ctx->pos= yypos847; ctx->thunkpos= yythunkpos847; if (!yymatchString(ctx, "TFOOT")) goto l846; + } + l847:; if (!yy_Spnl(ctx)) goto l846; + l849:; + { int yypos850= ctx->pos, yythunkpos850= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l850; goto l849; + l850:; ctx->pos= yypos850; ctx->thunkpos= yythunkpos850; + } if (!yymatchChar(ctx, '>')) goto l846; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenTfoot", ctx->buf+ctx->pos)); + return 1; + l846:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenTfoot", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockTd(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockTd")); if (!yy_HtmlBlockOpenTd(ctx)) goto l851; + l852:; + { int yypos853= ctx->pos, yythunkpos853= ctx->thunkpos; + { int yypos854= ctx->pos, yythunkpos854= ctx->thunkpos; if (!yy_HtmlBlockTd(ctx)) goto l855; goto l854; + l855:; ctx->pos= yypos854; ctx->thunkpos= yythunkpos854; + { int yypos856= ctx->pos, yythunkpos856= ctx->thunkpos; if (!yy_HtmlBlockCloseTd(ctx)) goto l856; goto l853; + l856:; ctx->pos= yypos856; ctx->thunkpos= yythunkpos856; + } if (!yymatchDot(ctx)) goto l853; + } + l854:; goto l852; + l853:; ctx->pos= yypos853; ctx->thunkpos= yythunkpos853; + } if (!yy_HtmlBlockCloseTd(ctx)) goto l851; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockTd", ctx->buf+ctx->pos)); + return 1; + l851:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockTd", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseTd(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseTd")); if (!yymatchChar(ctx, '<')) goto l857; if (!yy_Spnl(ctx)) goto l857; if (!yymatchChar(ctx, '/')) goto l857; + { int yypos858= ctx->pos, yythunkpos858= ctx->thunkpos; if (!yymatchString(ctx, "td")) goto l859; goto l858; + l859:; ctx->pos= yypos858; ctx->thunkpos= yythunkpos858; if (!yymatchString(ctx, "TD")) goto l857; + } + l858:; if (!yy_Spnl(ctx)) goto l857; if (!yymatchChar(ctx, '>')) goto l857; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseTd", ctx->buf+ctx->pos)); + return 1; + l857:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseTd", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenTd(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenTd")); if (!yymatchChar(ctx, '<')) goto l860; if (!yy_Spnl(ctx)) goto l860; + { int yypos861= ctx->pos, yythunkpos861= ctx->thunkpos; if (!yymatchString(ctx, "td")) goto l862; goto l861; + l862:; ctx->pos= yypos861; ctx->thunkpos= yythunkpos861; if (!yymatchString(ctx, "TD")) goto l860; + } + l861:; if (!yy_Spnl(ctx)) goto l860; + l863:; + { int yypos864= ctx->pos, yythunkpos864= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l864; goto l863; + l864:; ctx->pos= yypos864; ctx->thunkpos= yythunkpos864; + } if (!yymatchChar(ctx, '>')) goto l860; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenTd", ctx->buf+ctx->pos)); + return 1; + l860:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenTd", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockTbody(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockTbody")); if (!yy_HtmlBlockOpenTbody(ctx)) goto l865; + l866:; + { int yypos867= ctx->pos, yythunkpos867= ctx->thunkpos; + { int yypos868= ctx->pos, yythunkpos868= ctx->thunkpos; if (!yy_HtmlBlockTbody(ctx)) goto l869; goto l868; + l869:; ctx->pos= yypos868; ctx->thunkpos= yythunkpos868; + { int yypos870= ctx->pos, yythunkpos870= ctx->thunkpos; if (!yy_HtmlBlockCloseTbody(ctx)) goto l870; goto l867; + l870:; ctx->pos= yypos870; ctx->thunkpos= yythunkpos870; + } if (!yymatchDot(ctx)) goto l867; + } + l868:; goto l866; + l867:; ctx->pos= yypos867; ctx->thunkpos= yythunkpos867; + } if (!yy_HtmlBlockCloseTbody(ctx)) goto l865; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockTbody", ctx->buf+ctx->pos)); + return 1; + l865:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockTbody", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseTbody(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseTbody")); if (!yymatchChar(ctx, '<')) goto l871; if (!yy_Spnl(ctx)) goto l871; if (!yymatchChar(ctx, '/')) goto l871; + { int yypos872= ctx->pos, yythunkpos872= ctx->thunkpos; if (!yymatchString(ctx, "tbody")) goto l873; goto l872; + l873:; ctx->pos= yypos872; ctx->thunkpos= yythunkpos872; if (!yymatchString(ctx, "TBODY")) goto l871; + } + l872:; if (!yy_Spnl(ctx)) goto l871; if (!yymatchChar(ctx, '>')) goto l871; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseTbody", ctx->buf+ctx->pos)); + return 1; + l871:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseTbody", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenTbody(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenTbody")); if (!yymatchChar(ctx, '<')) goto l874; if (!yy_Spnl(ctx)) goto l874; + { int yypos875= ctx->pos, yythunkpos875= ctx->thunkpos; if (!yymatchString(ctx, "tbody")) goto l876; goto l875; + l876:; ctx->pos= yypos875; ctx->thunkpos= yythunkpos875; if (!yymatchString(ctx, "TBODY")) goto l874; + } + l875:; if (!yy_Spnl(ctx)) goto l874; + l877:; + { int yypos878= ctx->pos, yythunkpos878= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l878; goto l877; + l878:; ctx->pos= yypos878; ctx->thunkpos= yythunkpos878; + } if (!yymatchChar(ctx, '>')) goto l874; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenTbody", ctx->buf+ctx->pos)); + return 1; + l874:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenTbody", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockLi(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockLi")); if (!yy_HtmlBlockOpenLi(ctx)) goto l879; + l880:; + { int yypos881= ctx->pos, yythunkpos881= ctx->thunkpos; + { int yypos882= ctx->pos, yythunkpos882= ctx->thunkpos; if (!yy_HtmlBlockLi(ctx)) goto l883; goto l882; + l883:; ctx->pos= yypos882; ctx->thunkpos= yythunkpos882; + { int yypos884= ctx->pos, yythunkpos884= ctx->thunkpos; if (!yy_HtmlBlockCloseLi(ctx)) goto l884; goto l881; + l884:; ctx->pos= yypos884; ctx->thunkpos= yythunkpos884; + } if (!yymatchDot(ctx)) goto l881; + } + l882:; goto l880; + l881:; ctx->pos= yypos881; ctx->thunkpos= yythunkpos881; + } if (!yy_HtmlBlockCloseLi(ctx)) goto l879; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockLi", ctx->buf+ctx->pos)); + return 1; + l879:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockLi", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseLi(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseLi")); if (!yymatchChar(ctx, '<')) goto l885; if (!yy_Spnl(ctx)) goto l885; if (!yymatchChar(ctx, '/')) goto l885; + { int yypos886= ctx->pos, yythunkpos886= ctx->thunkpos; if (!yymatchString(ctx, "li")) goto l887; goto l886; + l887:; ctx->pos= yypos886; ctx->thunkpos= yythunkpos886; if (!yymatchString(ctx, "LI")) goto l885; + } + l886:; if (!yy_Spnl(ctx)) goto l885; if (!yymatchChar(ctx, '>')) goto l885; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseLi", ctx->buf+ctx->pos)); + return 1; + l885:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseLi", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenLi(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenLi")); if (!yymatchChar(ctx, '<')) goto l888; if (!yy_Spnl(ctx)) goto l888; + { int yypos889= ctx->pos, yythunkpos889= ctx->thunkpos; if (!yymatchString(ctx, "li")) goto l890; goto l889; + l890:; ctx->pos= yypos889; ctx->thunkpos= yythunkpos889; if (!yymatchString(ctx, "LI")) goto l888; + } + l889:; if (!yy_Spnl(ctx)) goto l888; + l891:; + { int yypos892= ctx->pos, yythunkpos892= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l892; goto l891; + l892:; ctx->pos= yypos892; ctx->thunkpos= yythunkpos892; + } if (!yymatchChar(ctx, '>')) goto l888; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenLi", ctx->buf+ctx->pos)); + return 1; + l888:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenLi", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockFrameset(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockFrameset")); if (!yy_HtmlBlockOpenFrameset(ctx)) goto l893; + l894:; + { int yypos895= ctx->pos, yythunkpos895= ctx->thunkpos; + { int yypos896= ctx->pos, yythunkpos896= ctx->thunkpos; if (!yy_HtmlBlockFrameset(ctx)) goto l897; goto l896; + l897:; ctx->pos= yypos896; ctx->thunkpos= yythunkpos896; + { int yypos898= ctx->pos, yythunkpos898= ctx->thunkpos; if (!yy_HtmlBlockCloseFrameset(ctx)) goto l898; goto l895; + l898:; ctx->pos= yypos898; ctx->thunkpos= yythunkpos898; + } if (!yymatchDot(ctx)) goto l895; + } + l896:; goto l894; + l895:; ctx->pos= yypos895; ctx->thunkpos= yythunkpos895; + } if (!yy_HtmlBlockCloseFrameset(ctx)) goto l893; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockFrameset", ctx->buf+ctx->pos)); + return 1; + l893:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockFrameset", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseFrameset(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseFrameset")); if (!yymatchChar(ctx, '<')) goto l899; if (!yy_Spnl(ctx)) goto l899; if (!yymatchChar(ctx, '/')) goto l899; + { int yypos900= ctx->pos, yythunkpos900= ctx->thunkpos; if (!yymatchString(ctx, "frameset")) goto l901; goto l900; + l901:; ctx->pos= yypos900; ctx->thunkpos= yythunkpos900; if (!yymatchString(ctx, "FRAMESET")) goto l899; + } + l900:; if (!yy_Spnl(ctx)) goto l899; if (!yymatchChar(ctx, '>')) goto l899; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseFrameset", ctx->buf+ctx->pos)); + return 1; + l899:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseFrameset", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenFrameset(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenFrameset")); if (!yymatchChar(ctx, '<')) goto l902; if (!yy_Spnl(ctx)) goto l902; + { int yypos903= ctx->pos, yythunkpos903= ctx->thunkpos; if (!yymatchString(ctx, "frameset")) goto l904; goto l903; + l904:; ctx->pos= yypos903; ctx->thunkpos= yythunkpos903; if (!yymatchString(ctx, "FRAMESET")) goto l902; + } + l903:; if (!yy_Spnl(ctx)) goto l902; + l905:; + { int yypos906= ctx->pos, yythunkpos906= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l906; goto l905; + l906:; ctx->pos= yypos906; ctx->thunkpos= yythunkpos906; + } if (!yymatchChar(ctx, '>')) goto l902; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenFrameset", ctx->buf+ctx->pos)); + return 1; + l902:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenFrameset", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockDt(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockDt")); if (!yy_HtmlBlockOpenDt(ctx)) goto l907; + l908:; + { int yypos909= ctx->pos, yythunkpos909= ctx->thunkpos; + { int yypos910= ctx->pos, yythunkpos910= ctx->thunkpos; if (!yy_HtmlBlockDt(ctx)) goto l911; goto l910; + l911:; ctx->pos= yypos910; ctx->thunkpos= yythunkpos910; + { int yypos912= ctx->pos, yythunkpos912= ctx->thunkpos; if (!yy_HtmlBlockCloseDt(ctx)) goto l912; goto l909; + l912:; ctx->pos= yypos912; ctx->thunkpos= yythunkpos912; + } if (!yymatchDot(ctx)) goto l909; + } + l910:; goto l908; + l909:; ctx->pos= yypos909; ctx->thunkpos= yythunkpos909; + } if (!yy_HtmlBlockCloseDt(ctx)) goto l907; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockDt", ctx->buf+ctx->pos)); + return 1; + l907:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockDt", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseDt(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseDt")); if (!yymatchChar(ctx, '<')) goto l913; if (!yy_Spnl(ctx)) goto l913; if (!yymatchChar(ctx, '/')) goto l913; + { int yypos914= ctx->pos, yythunkpos914= ctx->thunkpos; if (!yymatchString(ctx, "dt")) goto l915; goto l914; + l915:; ctx->pos= yypos914; ctx->thunkpos= yythunkpos914; if (!yymatchString(ctx, "DT")) goto l913; + } + l914:; if (!yy_Spnl(ctx)) goto l913; if (!yymatchChar(ctx, '>')) goto l913; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseDt", ctx->buf+ctx->pos)); + return 1; + l913:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseDt", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenDt(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenDt")); if (!yymatchChar(ctx, '<')) goto l916; if (!yy_Spnl(ctx)) goto l916; + { int yypos917= ctx->pos, yythunkpos917= ctx->thunkpos; if (!yymatchString(ctx, "dt")) goto l918; goto l917; + l918:; ctx->pos= yypos917; ctx->thunkpos= yythunkpos917; if (!yymatchString(ctx, "DT")) goto l916; + } + l917:; if (!yy_Spnl(ctx)) goto l916; + l919:; + { int yypos920= ctx->pos, yythunkpos920= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l920; goto l919; + l920:; ctx->pos= yypos920; ctx->thunkpos= yythunkpos920; + } if (!yymatchChar(ctx, '>')) goto l916; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenDt", ctx->buf+ctx->pos)); + return 1; + l916:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenDt", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockDd(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockDd")); if (!yy_HtmlBlockOpenDd(ctx)) goto l921; + l922:; + { int yypos923= ctx->pos, yythunkpos923= ctx->thunkpos; + { int yypos924= ctx->pos, yythunkpos924= ctx->thunkpos; if (!yy_HtmlBlockDd(ctx)) goto l925; goto l924; + l925:; ctx->pos= yypos924; ctx->thunkpos= yythunkpos924; + { int yypos926= ctx->pos, yythunkpos926= ctx->thunkpos; if (!yy_HtmlBlockCloseDd(ctx)) goto l926; goto l923; + l926:; ctx->pos= yypos926; ctx->thunkpos= yythunkpos926; + } if (!yymatchDot(ctx)) goto l923; + } + l924:; goto l922; + l923:; ctx->pos= yypos923; ctx->thunkpos= yythunkpos923; + } if (!yy_HtmlBlockCloseDd(ctx)) goto l921; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockDd", ctx->buf+ctx->pos)); + return 1; + l921:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockDd", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseDd(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseDd")); if (!yymatchChar(ctx, '<')) goto l927; if (!yy_Spnl(ctx)) goto l927; if (!yymatchChar(ctx, '/')) goto l927; + { int yypos928= ctx->pos, yythunkpos928= ctx->thunkpos; if (!yymatchString(ctx, "dd")) goto l929; goto l928; + l929:; ctx->pos= yypos928; ctx->thunkpos= yythunkpos928; if (!yymatchString(ctx, "DD")) goto l927; + } + l928:; if (!yy_Spnl(ctx)) goto l927; if (!yymatchChar(ctx, '>')) goto l927; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseDd", ctx->buf+ctx->pos)); + return 1; + l927:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseDd", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenDd(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenDd")); if (!yymatchChar(ctx, '<')) goto l930; if (!yy_Spnl(ctx)) goto l930; + { int yypos931= ctx->pos, yythunkpos931= ctx->thunkpos; if (!yymatchString(ctx, "dd")) goto l932; goto l931; + l932:; ctx->pos= yypos931; ctx->thunkpos= yythunkpos931; if (!yymatchString(ctx, "DD")) goto l930; + } + l931:; if (!yy_Spnl(ctx)) goto l930; + l933:; + { int yypos934= ctx->pos, yythunkpos934= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l934; goto l933; + l934:; ctx->pos= yypos934; ctx->thunkpos= yythunkpos934; + } if (!yymatchChar(ctx, '>')) goto l930; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenDd", ctx->buf+ctx->pos)); + return 1; + l930:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenDd", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockUl(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockUl")); if (!yy_HtmlBlockOpenUl(ctx)) goto l935; + l936:; + { int yypos937= ctx->pos, yythunkpos937= ctx->thunkpos; + { int yypos938= ctx->pos, yythunkpos938= ctx->thunkpos; if (!yy_HtmlBlockUl(ctx)) goto l939; goto l938; + l939:; ctx->pos= yypos938; ctx->thunkpos= yythunkpos938; + { int yypos940= ctx->pos, yythunkpos940= ctx->thunkpos; if (!yy_HtmlBlockCloseUl(ctx)) goto l940; goto l937; + l940:; ctx->pos= yypos940; ctx->thunkpos= yythunkpos940; + } if (!yymatchDot(ctx)) goto l937; + } + l938:; goto l936; + l937:; ctx->pos= yypos937; ctx->thunkpos= yythunkpos937; + } if (!yy_HtmlBlockCloseUl(ctx)) goto l935; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockUl", ctx->buf+ctx->pos)); + return 1; + l935:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockUl", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseUl(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseUl")); if (!yymatchChar(ctx, '<')) goto l941; if (!yy_Spnl(ctx)) goto l941; if (!yymatchChar(ctx, '/')) goto l941; + { int yypos942= ctx->pos, yythunkpos942= ctx->thunkpos; if (!yymatchString(ctx, "ul")) goto l943; goto l942; + l943:; ctx->pos= yypos942; ctx->thunkpos= yythunkpos942; if (!yymatchString(ctx, "UL")) goto l941; + } + l942:; if (!yy_Spnl(ctx)) goto l941; if (!yymatchChar(ctx, '>')) goto l941; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseUl", ctx->buf+ctx->pos)); + return 1; + l941:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseUl", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenUl(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenUl")); if (!yymatchChar(ctx, '<')) goto l944; if (!yy_Spnl(ctx)) goto l944; + { int yypos945= ctx->pos, yythunkpos945= ctx->thunkpos; if (!yymatchString(ctx, "ul")) goto l946; goto l945; + l946:; ctx->pos= yypos945; ctx->thunkpos= yythunkpos945; if (!yymatchString(ctx, "UL")) goto l944; + } + l945:; if (!yy_Spnl(ctx)) goto l944; + l947:; + { int yypos948= ctx->pos, yythunkpos948= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l948; goto l947; + l948:; ctx->pos= yypos948; ctx->thunkpos= yythunkpos948; + } if (!yymatchChar(ctx, '>')) goto l944; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenUl", ctx->buf+ctx->pos)); + return 1; + l944:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenUl", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockTable(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockTable")); if (!yy_HtmlBlockOpenTable(ctx)) goto l949; + l950:; + { int yypos951= ctx->pos, yythunkpos951= ctx->thunkpos; + { int yypos952= ctx->pos, yythunkpos952= ctx->thunkpos; if (!yy_HtmlBlockTable(ctx)) goto l953; goto l952; + l953:; ctx->pos= yypos952; ctx->thunkpos= yythunkpos952; + { int yypos954= ctx->pos, yythunkpos954= ctx->thunkpos; if (!yy_HtmlBlockCloseTable(ctx)) goto l954; goto l951; + l954:; ctx->pos= yypos954; ctx->thunkpos= yythunkpos954; + } if (!yymatchDot(ctx)) goto l951; + } + l952:; goto l950; + l951:; ctx->pos= yypos951; ctx->thunkpos= yythunkpos951; + } if (!yy_HtmlBlockCloseTable(ctx)) goto l949; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockTable", ctx->buf+ctx->pos)); + return 1; + l949:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockTable", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseTable(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseTable")); if (!yymatchChar(ctx, '<')) goto l955; if (!yy_Spnl(ctx)) goto l955; if (!yymatchChar(ctx, '/')) goto l955; + { int yypos956= ctx->pos, yythunkpos956= ctx->thunkpos; if (!yymatchString(ctx, "table")) goto l957; goto l956; + l957:; ctx->pos= yypos956; ctx->thunkpos= yythunkpos956; if (!yymatchString(ctx, "TABLE")) goto l955; + } + l956:; if (!yy_Spnl(ctx)) goto l955; if (!yymatchChar(ctx, '>')) goto l955; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseTable", ctx->buf+ctx->pos)); + return 1; + l955:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseTable", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenTable(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenTable")); if (!yymatchChar(ctx, '<')) goto l958; if (!yy_Spnl(ctx)) goto l958; + { int yypos959= ctx->pos, yythunkpos959= ctx->thunkpos; if (!yymatchString(ctx, "table")) goto l960; goto l959; + l960:; ctx->pos= yypos959; ctx->thunkpos= yythunkpos959; if (!yymatchString(ctx, "TABLE")) goto l958; + } + l959:; if (!yy_Spnl(ctx)) goto l958; + l961:; + { int yypos962= ctx->pos, yythunkpos962= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l962; goto l961; + l962:; ctx->pos= yypos962; ctx->thunkpos= yythunkpos962; + } if (!yymatchChar(ctx, '>')) goto l958; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenTable", ctx->buf+ctx->pos)); + return 1; + l958:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenTable", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockPre(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockPre")); if (!yy_HtmlBlockOpenPre(ctx)) goto l963; + l964:; + { int yypos965= ctx->pos, yythunkpos965= ctx->thunkpos; + { int yypos966= ctx->pos, yythunkpos966= ctx->thunkpos; if (!yy_HtmlBlockPre(ctx)) goto l967; goto l966; + l967:; ctx->pos= yypos966; ctx->thunkpos= yythunkpos966; + { int yypos968= ctx->pos, yythunkpos968= ctx->thunkpos; if (!yy_HtmlBlockClosePre(ctx)) goto l968; goto l965; + l968:; ctx->pos= yypos968; ctx->thunkpos= yythunkpos968; + } if (!yymatchDot(ctx)) goto l965; + } + l966:; goto l964; + l965:; ctx->pos= yypos965; ctx->thunkpos= yythunkpos965; + } if (!yy_HtmlBlockClosePre(ctx)) goto l963; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockPre", ctx->buf+ctx->pos)); + return 1; + l963:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockPre", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockClosePre(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockClosePre")); if (!yymatchChar(ctx, '<')) goto l969; if (!yy_Spnl(ctx)) goto l969; if (!yymatchChar(ctx, '/')) goto l969; + { int yypos970= ctx->pos, yythunkpos970= ctx->thunkpos; if (!yymatchString(ctx, "pre")) goto l971; goto l970; + l971:; ctx->pos= yypos970; ctx->thunkpos= yythunkpos970; if (!yymatchString(ctx, "PRE")) goto l969; + } + l970:; if (!yy_Spnl(ctx)) goto l969; if (!yymatchChar(ctx, '>')) goto l969; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockClosePre", ctx->buf+ctx->pos)); + return 1; + l969:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockClosePre", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenPre(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenPre")); if (!yymatchChar(ctx, '<')) goto l972; if (!yy_Spnl(ctx)) goto l972; + { int yypos973= ctx->pos, yythunkpos973= ctx->thunkpos; if (!yymatchString(ctx, "pre")) goto l974; goto l973; + l974:; ctx->pos= yypos973; ctx->thunkpos= yythunkpos973; if (!yymatchString(ctx, "PRE")) goto l972; + } + l973:; if (!yy_Spnl(ctx)) goto l972; + l975:; + { int yypos976= ctx->pos, yythunkpos976= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l976; goto l975; + l976:; ctx->pos= yypos976; ctx->thunkpos= yythunkpos976; + } if (!yymatchChar(ctx, '>')) goto l972; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenPre", ctx->buf+ctx->pos)); + return 1; + l972:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenPre", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockP(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockP")); if (!yy_HtmlBlockOpenP(ctx)) goto l977; + l978:; + { int yypos979= ctx->pos, yythunkpos979= ctx->thunkpos; + { int yypos980= ctx->pos, yythunkpos980= ctx->thunkpos; if (!yy_HtmlBlockP(ctx)) goto l981; goto l980; + l981:; ctx->pos= yypos980; ctx->thunkpos= yythunkpos980; + { int yypos982= ctx->pos, yythunkpos982= ctx->thunkpos; if (!yy_HtmlBlockCloseP(ctx)) goto l982; goto l979; + l982:; ctx->pos= yypos982; ctx->thunkpos= yythunkpos982; + } if (!yymatchDot(ctx)) goto l979; + } + l980:; goto l978; + l979:; ctx->pos= yypos979; ctx->thunkpos= yythunkpos979; + } if (!yy_HtmlBlockCloseP(ctx)) goto l977; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockP", ctx->buf+ctx->pos)); + return 1; + l977:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockP", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseP(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseP")); if (!yymatchChar(ctx, '<')) goto l983; if (!yy_Spnl(ctx)) goto l983; if (!yymatchChar(ctx, '/')) goto l983; + { int yypos984= ctx->pos, yythunkpos984= ctx->thunkpos; if (!yymatchChar(ctx, 'p')) goto l985; goto l984; + l985:; ctx->pos= yypos984; ctx->thunkpos= yythunkpos984; if (!yymatchChar(ctx, 'P')) goto l983; + } + l984:; if (!yy_Spnl(ctx)) goto l983; if (!yymatchChar(ctx, '>')) goto l983; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseP", ctx->buf+ctx->pos)); + return 1; + l983:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseP", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenP(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenP")); if (!yymatchChar(ctx, '<')) goto l986; if (!yy_Spnl(ctx)) goto l986; + { int yypos987= ctx->pos, yythunkpos987= ctx->thunkpos; if (!yymatchChar(ctx, 'p')) goto l988; goto l987; + l988:; ctx->pos= yypos987; ctx->thunkpos= yythunkpos987; if (!yymatchChar(ctx, 'P')) goto l986; + } + l987:; if (!yy_Spnl(ctx)) goto l986; + l989:; + { int yypos990= ctx->pos, yythunkpos990= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l990; goto l989; + l990:; ctx->pos= yypos990; ctx->thunkpos= yythunkpos990; + } if (!yymatchChar(ctx, '>')) goto l986; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenP", ctx->buf+ctx->pos)); + return 1; + l986:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenP", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOl(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOl")); if (!yy_HtmlBlockOpenOl(ctx)) goto l991; + l992:; + { int yypos993= ctx->pos, yythunkpos993= ctx->thunkpos; + { int yypos994= ctx->pos, yythunkpos994= ctx->thunkpos; if (!yy_HtmlBlockOl(ctx)) goto l995; goto l994; + l995:; ctx->pos= yypos994; ctx->thunkpos= yythunkpos994; + { int yypos996= ctx->pos, yythunkpos996= ctx->thunkpos; if (!yy_HtmlBlockCloseOl(ctx)) goto l996; goto l993; + l996:; ctx->pos= yypos996; ctx->thunkpos= yythunkpos996; + } if (!yymatchDot(ctx)) goto l993; + } + l994:; goto l992; + l993:; ctx->pos= yypos993; ctx->thunkpos= yythunkpos993; + } if (!yy_HtmlBlockCloseOl(ctx)) goto l991; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOl", ctx->buf+ctx->pos)); + return 1; + l991:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOl", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseOl(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseOl")); if (!yymatchChar(ctx, '<')) goto l997; if (!yy_Spnl(ctx)) goto l997; if (!yymatchChar(ctx, '/')) goto l997; + { int yypos998= ctx->pos, yythunkpos998= ctx->thunkpos; if (!yymatchString(ctx, "ol")) goto l999; goto l998; + l999:; ctx->pos= yypos998; ctx->thunkpos= yythunkpos998; if (!yymatchString(ctx, "OL")) goto l997; + } + l998:; if (!yy_Spnl(ctx)) goto l997; if (!yymatchChar(ctx, '>')) goto l997; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseOl", ctx->buf+ctx->pos)); + return 1; + l997:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseOl", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenOl(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenOl")); if (!yymatchChar(ctx, '<')) goto l1000; if (!yy_Spnl(ctx)) goto l1000; + { int yypos1001= ctx->pos, yythunkpos1001= ctx->thunkpos; if (!yymatchString(ctx, "ol")) goto l1002; goto l1001; + l1002:; ctx->pos= yypos1001; ctx->thunkpos= yythunkpos1001; if (!yymatchString(ctx, "OL")) goto l1000; + } + l1001:; if (!yy_Spnl(ctx)) goto l1000; + l1003:; + { int yypos1004= ctx->pos, yythunkpos1004= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l1004; goto l1003; + l1004:; ctx->pos= yypos1004; ctx->thunkpos= yythunkpos1004; + } if (!yymatchChar(ctx, '>')) goto l1000; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenOl", ctx->buf+ctx->pos)); + return 1; + l1000:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenOl", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockNoscript(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockNoscript")); if (!yy_HtmlBlockOpenNoscript(ctx)) goto l1005; + l1006:; + { int yypos1007= ctx->pos, yythunkpos1007= ctx->thunkpos; + { int yypos1008= ctx->pos, yythunkpos1008= ctx->thunkpos; if (!yy_HtmlBlockNoscript(ctx)) goto l1009; goto l1008; + l1009:; ctx->pos= yypos1008; ctx->thunkpos= yythunkpos1008; + { int yypos1010= ctx->pos, yythunkpos1010= ctx->thunkpos; if (!yy_HtmlBlockCloseNoscript(ctx)) goto l1010; goto l1007; + l1010:; ctx->pos= yypos1010; ctx->thunkpos= yythunkpos1010; + } if (!yymatchDot(ctx)) goto l1007; + } + l1008:; goto l1006; + l1007:; ctx->pos= yypos1007; ctx->thunkpos= yythunkpos1007; + } if (!yy_HtmlBlockCloseNoscript(ctx)) goto l1005; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockNoscript", ctx->buf+ctx->pos)); + return 1; + l1005:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockNoscript", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseNoscript(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseNoscript")); if (!yymatchChar(ctx, '<')) goto l1011; if (!yy_Spnl(ctx)) goto l1011; if (!yymatchChar(ctx, '/')) goto l1011; + { int yypos1012= ctx->pos, yythunkpos1012= ctx->thunkpos; if (!yymatchString(ctx, "noscript")) goto l1013; goto l1012; + l1013:; ctx->pos= yypos1012; ctx->thunkpos= yythunkpos1012; if (!yymatchString(ctx, "NOSCRIPT")) goto l1011; + } + l1012:; if (!yy_Spnl(ctx)) goto l1011; if (!yymatchChar(ctx, '>')) goto l1011; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseNoscript", ctx->buf+ctx->pos)); + return 1; + l1011:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseNoscript", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenNoscript(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenNoscript")); if (!yymatchChar(ctx, '<')) goto l1014; if (!yy_Spnl(ctx)) goto l1014; + { int yypos1015= ctx->pos, yythunkpos1015= ctx->thunkpos; if (!yymatchString(ctx, "noscript")) goto l1016; goto l1015; + l1016:; ctx->pos= yypos1015; ctx->thunkpos= yythunkpos1015; if (!yymatchString(ctx, "NOSCRIPT")) goto l1014; + } + l1015:; if (!yy_Spnl(ctx)) goto l1014; + l1017:; + { int yypos1018= ctx->pos, yythunkpos1018= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l1018; goto l1017; + l1018:; ctx->pos= yypos1018; ctx->thunkpos= yythunkpos1018; + } if (!yymatchChar(ctx, '>')) goto l1014; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenNoscript", ctx->buf+ctx->pos)); + return 1; + l1014:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenNoscript", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockNoframes(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockNoframes")); if (!yy_HtmlBlockOpenNoframes(ctx)) goto l1019; + l1020:; + { int yypos1021= ctx->pos, yythunkpos1021= ctx->thunkpos; + { int yypos1022= ctx->pos, yythunkpos1022= ctx->thunkpos; if (!yy_HtmlBlockNoframes(ctx)) goto l1023; goto l1022; + l1023:; ctx->pos= yypos1022; ctx->thunkpos= yythunkpos1022; + { int yypos1024= ctx->pos, yythunkpos1024= ctx->thunkpos; if (!yy_HtmlBlockCloseNoframes(ctx)) goto l1024; goto l1021; + l1024:; ctx->pos= yypos1024; ctx->thunkpos= yythunkpos1024; + } if (!yymatchDot(ctx)) goto l1021; + } + l1022:; goto l1020; + l1021:; ctx->pos= yypos1021; ctx->thunkpos= yythunkpos1021; + } if (!yy_HtmlBlockCloseNoframes(ctx)) goto l1019; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockNoframes", ctx->buf+ctx->pos)); + return 1; + l1019:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockNoframes", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseNoframes(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseNoframes")); if (!yymatchChar(ctx, '<')) goto l1025; if (!yy_Spnl(ctx)) goto l1025; if (!yymatchChar(ctx, '/')) goto l1025; + { int yypos1026= ctx->pos, yythunkpos1026= ctx->thunkpos; if (!yymatchString(ctx, "noframes")) goto l1027; goto l1026; + l1027:; ctx->pos= yypos1026; ctx->thunkpos= yythunkpos1026; if (!yymatchString(ctx, "NOFRAMES")) goto l1025; + } + l1026:; if (!yy_Spnl(ctx)) goto l1025; if (!yymatchChar(ctx, '>')) goto l1025; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseNoframes", ctx->buf+ctx->pos)); + return 1; + l1025:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseNoframes", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenNoframes(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenNoframes")); if (!yymatchChar(ctx, '<')) goto l1028; if (!yy_Spnl(ctx)) goto l1028; + { int yypos1029= ctx->pos, yythunkpos1029= ctx->thunkpos; if (!yymatchString(ctx, "noframes")) goto l1030; goto l1029; + l1030:; ctx->pos= yypos1029; ctx->thunkpos= yythunkpos1029; if (!yymatchString(ctx, "NOFRAMES")) goto l1028; + } + l1029:; if (!yy_Spnl(ctx)) goto l1028; + l1031:; + { int yypos1032= ctx->pos, yythunkpos1032= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l1032; goto l1031; + l1032:; ctx->pos= yypos1032; ctx->thunkpos= yythunkpos1032; + } if (!yymatchChar(ctx, '>')) goto l1028; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenNoframes", ctx->buf+ctx->pos)); + return 1; + l1028:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenNoframes", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockMenu(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockMenu")); if (!yy_HtmlBlockOpenMenu(ctx)) goto l1033; + l1034:; + { int yypos1035= ctx->pos, yythunkpos1035= ctx->thunkpos; + { int yypos1036= ctx->pos, yythunkpos1036= ctx->thunkpos; if (!yy_HtmlBlockMenu(ctx)) goto l1037; goto l1036; + l1037:; ctx->pos= yypos1036; ctx->thunkpos= yythunkpos1036; + { int yypos1038= ctx->pos, yythunkpos1038= ctx->thunkpos; if (!yy_HtmlBlockCloseMenu(ctx)) goto l1038; goto l1035; + l1038:; ctx->pos= yypos1038; ctx->thunkpos= yythunkpos1038; + } if (!yymatchDot(ctx)) goto l1035; + } + l1036:; goto l1034; + l1035:; ctx->pos= yypos1035; ctx->thunkpos= yythunkpos1035; + } if (!yy_HtmlBlockCloseMenu(ctx)) goto l1033; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockMenu", ctx->buf+ctx->pos)); + return 1; + l1033:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockMenu", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseMenu(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseMenu")); if (!yymatchChar(ctx, '<')) goto l1039; if (!yy_Spnl(ctx)) goto l1039; if (!yymatchChar(ctx, '/')) goto l1039; + { int yypos1040= ctx->pos, yythunkpos1040= ctx->thunkpos; if (!yymatchString(ctx, "menu")) goto l1041; goto l1040; + l1041:; ctx->pos= yypos1040; ctx->thunkpos= yythunkpos1040; if (!yymatchString(ctx, "MENU")) goto l1039; + } + l1040:; if (!yy_Spnl(ctx)) goto l1039; if (!yymatchChar(ctx, '>')) goto l1039; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseMenu", ctx->buf+ctx->pos)); + return 1; + l1039:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseMenu", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenMenu(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenMenu")); if (!yymatchChar(ctx, '<')) goto l1042; if (!yy_Spnl(ctx)) goto l1042; + { int yypos1043= ctx->pos, yythunkpos1043= ctx->thunkpos; if (!yymatchString(ctx, "menu")) goto l1044; goto l1043; + l1044:; ctx->pos= yypos1043; ctx->thunkpos= yythunkpos1043; if (!yymatchString(ctx, "MENU")) goto l1042; + } + l1043:; if (!yy_Spnl(ctx)) goto l1042; + l1045:; + { int yypos1046= ctx->pos, yythunkpos1046= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l1046; goto l1045; + l1046:; ctx->pos= yypos1046; ctx->thunkpos= yythunkpos1046; + } if (!yymatchChar(ctx, '>')) goto l1042; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenMenu", ctx->buf+ctx->pos)); + return 1; + l1042:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenMenu", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockH6(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockH6")); if (!yy_HtmlBlockOpenH6(ctx)) goto l1047; + l1048:; + { int yypos1049= ctx->pos, yythunkpos1049= ctx->thunkpos; + { int yypos1050= ctx->pos, yythunkpos1050= ctx->thunkpos; if (!yy_HtmlBlockH6(ctx)) goto l1051; goto l1050; + l1051:; ctx->pos= yypos1050; ctx->thunkpos= yythunkpos1050; + { int yypos1052= ctx->pos, yythunkpos1052= ctx->thunkpos; if (!yy_HtmlBlockCloseH6(ctx)) goto l1052; goto l1049; + l1052:; ctx->pos= yypos1052; ctx->thunkpos= yythunkpos1052; + } if (!yymatchDot(ctx)) goto l1049; + } + l1050:; goto l1048; + l1049:; ctx->pos= yypos1049; ctx->thunkpos= yythunkpos1049; + } if (!yy_HtmlBlockCloseH6(ctx)) goto l1047; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockH6", ctx->buf+ctx->pos)); + return 1; + l1047:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockH6", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseH6(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseH6")); if (!yymatchChar(ctx, '<')) goto l1053; if (!yy_Spnl(ctx)) goto l1053; if (!yymatchChar(ctx, '/')) goto l1053; + { int yypos1054= ctx->pos, yythunkpos1054= ctx->thunkpos; if (!yymatchString(ctx, "h6")) goto l1055; goto l1054; + l1055:; ctx->pos= yypos1054; ctx->thunkpos= yythunkpos1054; if (!yymatchString(ctx, "H6")) goto l1053; + } + l1054:; if (!yy_Spnl(ctx)) goto l1053; if (!yymatchChar(ctx, '>')) goto l1053; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseH6", ctx->buf+ctx->pos)); + return 1; + l1053:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseH6", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenH6(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenH6")); if (!yymatchChar(ctx, '<')) goto l1056; if (!yy_Spnl(ctx)) goto l1056; + { int yypos1057= ctx->pos, yythunkpos1057= ctx->thunkpos; if (!yymatchString(ctx, "h6")) goto l1058; goto l1057; + l1058:; ctx->pos= yypos1057; ctx->thunkpos= yythunkpos1057; if (!yymatchString(ctx, "H6")) goto l1056; + } + l1057:; if (!yy_Spnl(ctx)) goto l1056; + l1059:; + { int yypos1060= ctx->pos, yythunkpos1060= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l1060; goto l1059; + l1060:; ctx->pos= yypos1060; ctx->thunkpos= yythunkpos1060; + } if (!yymatchChar(ctx, '>')) goto l1056; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenH6", ctx->buf+ctx->pos)); + return 1; + l1056:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenH6", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockH5(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockH5")); if (!yy_HtmlBlockOpenH5(ctx)) goto l1061; + l1062:; + { int yypos1063= ctx->pos, yythunkpos1063= ctx->thunkpos; + { int yypos1064= ctx->pos, yythunkpos1064= ctx->thunkpos; if (!yy_HtmlBlockH5(ctx)) goto l1065; goto l1064; + l1065:; ctx->pos= yypos1064; ctx->thunkpos= yythunkpos1064; + { int yypos1066= ctx->pos, yythunkpos1066= ctx->thunkpos; if (!yy_HtmlBlockCloseH5(ctx)) goto l1066; goto l1063; + l1066:; ctx->pos= yypos1066; ctx->thunkpos= yythunkpos1066; + } if (!yymatchDot(ctx)) goto l1063; + } + l1064:; goto l1062; + l1063:; ctx->pos= yypos1063; ctx->thunkpos= yythunkpos1063; + } if (!yy_HtmlBlockCloseH5(ctx)) goto l1061; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockH5", ctx->buf+ctx->pos)); + return 1; + l1061:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockH5", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseH5(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseH5")); if (!yymatchChar(ctx, '<')) goto l1067; if (!yy_Spnl(ctx)) goto l1067; if (!yymatchChar(ctx, '/')) goto l1067; + { int yypos1068= ctx->pos, yythunkpos1068= ctx->thunkpos; if (!yymatchString(ctx, "h5")) goto l1069; goto l1068; + l1069:; ctx->pos= yypos1068; ctx->thunkpos= yythunkpos1068; if (!yymatchString(ctx, "H5")) goto l1067; + } + l1068:; if (!yy_Spnl(ctx)) goto l1067; if (!yymatchChar(ctx, '>')) goto l1067; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseH5", ctx->buf+ctx->pos)); + return 1; + l1067:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseH5", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenH5(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenH5")); if (!yymatchChar(ctx, '<')) goto l1070; if (!yy_Spnl(ctx)) goto l1070; + { int yypos1071= ctx->pos, yythunkpos1071= ctx->thunkpos; if (!yymatchString(ctx, "h5")) goto l1072; goto l1071; + l1072:; ctx->pos= yypos1071; ctx->thunkpos= yythunkpos1071; if (!yymatchString(ctx, "H5")) goto l1070; + } + l1071:; if (!yy_Spnl(ctx)) goto l1070; + l1073:; + { int yypos1074= ctx->pos, yythunkpos1074= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l1074; goto l1073; + l1074:; ctx->pos= yypos1074; ctx->thunkpos= yythunkpos1074; + } if (!yymatchChar(ctx, '>')) goto l1070; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenH5", ctx->buf+ctx->pos)); + return 1; + l1070:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenH5", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockH4(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockH4")); if (!yy_HtmlBlockOpenH4(ctx)) goto l1075; + l1076:; + { int yypos1077= ctx->pos, yythunkpos1077= ctx->thunkpos; + { int yypos1078= ctx->pos, yythunkpos1078= ctx->thunkpos; if (!yy_HtmlBlockH4(ctx)) goto l1079; goto l1078; + l1079:; ctx->pos= yypos1078; ctx->thunkpos= yythunkpos1078; + { int yypos1080= ctx->pos, yythunkpos1080= ctx->thunkpos; if (!yy_HtmlBlockCloseH4(ctx)) goto l1080; goto l1077; + l1080:; ctx->pos= yypos1080; ctx->thunkpos= yythunkpos1080; + } if (!yymatchDot(ctx)) goto l1077; + } + l1078:; goto l1076; + l1077:; ctx->pos= yypos1077; ctx->thunkpos= yythunkpos1077; + } if (!yy_HtmlBlockCloseH4(ctx)) goto l1075; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockH4", ctx->buf+ctx->pos)); + return 1; + l1075:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockH4", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseH4(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseH4")); if (!yymatchChar(ctx, '<')) goto l1081; if (!yy_Spnl(ctx)) goto l1081; if (!yymatchChar(ctx, '/')) goto l1081; + { int yypos1082= ctx->pos, yythunkpos1082= ctx->thunkpos; if (!yymatchString(ctx, "h4")) goto l1083; goto l1082; + l1083:; ctx->pos= yypos1082; ctx->thunkpos= yythunkpos1082; if (!yymatchString(ctx, "H4")) goto l1081; + } + l1082:; if (!yy_Spnl(ctx)) goto l1081; if (!yymatchChar(ctx, '>')) goto l1081; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseH4", ctx->buf+ctx->pos)); + return 1; + l1081:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseH4", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenH4(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenH4")); if (!yymatchChar(ctx, '<')) goto l1084; if (!yy_Spnl(ctx)) goto l1084; + { int yypos1085= ctx->pos, yythunkpos1085= ctx->thunkpos; if (!yymatchString(ctx, "h4")) goto l1086; goto l1085; + l1086:; ctx->pos= yypos1085; ctx->thunkpos= yythunkpos1085; if (!yymatchString(ctx, "H4")) goto l1084; + } + l1085:; if (!yy_Spnl(ctx)) goto l1084; + l1087:; + { int yypos1088= ctx->pos, yythunkpos1088= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l1088; goto l1087; + l1088:; ctx->pos= yypos1088; ctx->thunkpos= yythunkpos1088; + } if (!yymatchChar(ctx, '>')) goto l1084; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenH4", ctx->buf+ctx->pos)); + return 1; + l1084:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenH4", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockH3(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockH3")); if (!yy_HtmlBlockOpenH3(ctx)) goto l1089; + l1090:; + { int yypos1091= ctx->pos, yythunkpos1091= ctx->thunkpos; + { int yypos1092= ctx->pos, yythunkpos1092= ctx->thunkpos; if (!yy_HtmlBlockH3(ctx)) goto l1093; goto l1092; + l1093:; ctx->pos= yypos1092; ctx->thunkpos= yythunkpos1092; + { int yypos1094= ctx->pos, yythunkpos1094= ctx->thunkpos; if (!yy_HtmlBlockCloseH3(ctx)) goto l1094; goto l1091; + l1094:; ctx->pos= yypos1094; ctx->thunkpos= yythunkpos1094; + } if (!yymatchDot(ctx)) goto l1091; + } + l1092:; goto l1090; + l1091:; ctx->pos= yypos1091; ctx->thunkpos= yythunkpos1091; + } if (!yy_HtmlBlockCloseH3(ctx)) goto l1089; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockH3", ctx->buf+ctx->pos)); + return 1; + l1089:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockH3", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseH3(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseH3")); if (!yymatchChar(ctx, '<')) goto l1095; if (!yy_Spnl(ctx)) goto l1095; if (!yymatchChar(ctx, '/')) goto l1095; + { int yypos1096= ctx->pos, yythunkpos1096= ctx->thunkpos; if (!yymatchString(ctx, "h3")) goto l1097; goto l1096; + l1097:; ctx->pos= yypos1096; ctx->thunkpos= yythunkpos1096; if (!yymatchString(ctx, "H3")) goto l1095; + } + l1096:; if (!yy_Spnl(ctx)) goto l1095; if (!yymatchChar(ctx, '>')) goto l1095; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseH3", ctx->buf+ctx->pos)); + return 1; + l1095:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseH3", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenH3(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenH3")); if (!yymatchChar(ctx, '<')) goto l1098; if (!yy_Spnl(ctx)) goto l1098; + { int yypos1099= ctx->pos, yythunkpos1099= ctx->thunkpos; if (!yymatchString(ctx, "h3")) goto l1100; goto l1099; + l1100:; ctx->pos= yypos1099; ctx->thunkpos= yythunkpos1099; if (!yymatchString(ctx, "H3")) goto l1098; + } + l1099:; if (!yy_Spnl(ctx)) goto l1098; + l1101:; + { int yypos1102= ctx->pos, yythunkpos1102= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l1102; goto l1101; + l1102:; ctx->pos= yypos1102; ctx->thunkpos= yythunkpos1102; + } if (!yymatchChar(ctx, '>')) goto l1098; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenH3", ctx->buf+ctx->pos)); + return 1; + l1098:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenH3", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockH2(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockH2")); if (!yy_HtmlBlockOpenH2(ctx)) goto l1103; + l1104:; + { int yypos1105= ctx->pos, yythunkpos1105= ctx->thunkpos; + { int yypos1106= ctx->pos, yythunkpos1106= ctx->thunkpos; if (!yy_HtmlBlockH2(ctx)) goto l1107; goto l1106; + l1107:; ctx->pos= yypos1106; ctx->thunkpos= yythunkpos1106; + { int yypos1108= ctx->pos, yythunkpos1108= ctx->thunkpos; if (!yy_HtmlBlockCloseH2(ctx)) goto l1108; goto l1105; + l1108:; ctx->pos= yypos1108; ctx->thunkpos= yythunkpos1108; + } if (!yymatchDot(ctx)) goto l1105; + } + l1106:; goto l1104; + l1105:; ctx->pos= yypos1105; ctx->thunkpos= yythunkpos1105; + } if (!yy_HtmlBlockCloseH2(ctx)) goto l1103; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockH2", ctx->buf+ctx->pos)); + return 1; + l1103:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockH2", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseH2(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseH2")); if (!yymatchChar(ctx, '<')) goto l1109; if (!yy_Spnl(ctx)) goto l1109; if (!yymatchChar(ctx, '/')) goto l1109; + { int yypos1110= ctx->pos, yythunkpos1110= ctx->thunkpos; if (!yymatchString(ctx, "h2")) goto l1111; goto l1110; + l1111:; ctx->pos= yypos1110; ctx->thunkpos= yythunkpos1110; if (!yymatchString(ctx, "H2")) goto l1109; + } + l1110:; if (!yy_Spnl(ctx)) goto l1109; if (!yymatchChar(ctx, '>')) goto l1109; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseH2", ctx->buf+ctx->pos)); + return 1; + l1109:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseH2", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenH2(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenH2")); if (!yymatchChar(ctx, '<')) goto l1112; if (!yy_Spnl(ctx)) goto l1112; + { int yypos1113= ctx->pos, yythunkpos1113= ctx->thunkpos; if (!yymatchString(ctx, "h2")) goto l1114; goto l1113; + l1114:; ctx->pos= yypos1113; ctx->thunkpos= yythunkpos1113; if (!yymatchString(ctx, "H2")) goto l1112; + } + l1113:; if (!yy_Spnl(ctx)) goto l1112; + l1115:; + { int yypos1116= ctx->pos, yythunkpos1116= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l1116; goto l1115; + l1116:; ctx->pos= yypos1116; ctx->thunkpos= yythunkpos1116; + } if (!yymatchChar(ctx, '>')) goto l1112; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenH2", ctx->buf+ctx->pos)); + return 1; + l1112:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenH2", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockH1(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockH1")); if (!yy_HtmlBlockOpenH1(ctx)) goto l1117; + l1118:; + { int yypos1119= ctx->pos, yythunkpos1119= ctx->thunkpos; + { int yypos1120= ctx->pos, yythunkpos1120= ctx->thunkpos; if (!yy_HtmlBlockH1(ctx)) goto l1121; goto l1120; + l1121:; ctx->pos= yypos1120; ctx->thunkpos= yythunkpos1120; + { int yypos1122= ctx->pos, yythunkpos1122= ctx->thunkpos; if (!yy_HtmlBlockCloseH1(ctx)) goto l1122; goto l1119; + l1122:; ctx->pos= yypos1122; ctx->thunkpos= yythunkpos1122; + } if (!yymatchDot(ctx)) goto l1119; + } + l1120:; goto l1118; + l1119:; ctx->pos= yypos1119; ctx->thunkpos= yythunkpos1119; + } if (!yy_HtmlBlockCloseH1(ctx)) goto l1117; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockH1", ctx->buf+ctx->pos)); + return 1; + l1117:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockH1", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseH1(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseH1")); if (!yymatchChar(ctx, '<')) goto l1123; if (!yy_Spnl(ctx)) goto l1123; if (!yymatchChar(ctx, '/')) goto l1123; + { int yypos1124= ctx->pos, yythunkpos1124= ctx->thunkpos; if (!yymatchString(ctx, "h1")) goto l1125; goto l1124; + l1125:; ctx->pos= yypos1124; ctx->thunkpos= yythunkpos1124; if (!yymatchString(ctx, "H1")) goto l1123; + } + l1124:; if (!yy_Spnl(ctx)) goto l1123; if (!yymatchChar(ctx, '>')) goto l1123; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseH1", ctx->buf+ctx->pos)); + return 1; + l1123:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseH1", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenH1(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenH1")); if (!yymatchChar(ctx, '<')) goto l1126; if (!yy_Spnl(ctx)) goto l1126; + { int yypos1127= ctx->pos, yythunkpos1127= ctx->thunkpos; if (!yymatchString(ctx, "h1")) goto l1128; goto l1127; + l1128:; ctx->pos= yypos1127; ctx->thunkpos= yythunkpos1127; if (!yymatchString(ctx, "H1")) goto l1126; + } + l1127:; if (!yy_Spnl(ctx)) goto l1126; + l1129:; + { int yypos1130= ctx->pos, yythunkpos1130= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l1130; goto l1129; + l1130:; ctx->pos= yypos1130; ctx->thunkpos= yythunkpos1130; + } if (!yymatchChar(ctx, '>')) goto l1126; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenH1", ctx->buf+ctx->pos)); + return 1; + l1126:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenH1", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockForm(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockForm")); if (!yy_HtmlBlockOpenForm(ctx)) goto l1131; + l1132:; + { int yypos1133= ctx->pos, yythunkpos1133= ctx->thunkpos; + { int yypos1134= ctx->pos, yythunkpos1134= ctx->thunkpos; if (!yy_HtmlBlockForm(ctx)) goto l1135; goto l1134; + l1135:; ctx->pos= yypos1134; ctx->thunkpos= yythunkpos1134; + { int yypos1136= ctx->pos, yythunkpos1136= ctx->thunkpos; if (!yy_HtmlBlockCloseForm(ctx)) goto l1136; goto l1133; + l1136:; ctx->pos= yypos1136; ctx->thunkpos= yythunkpos1136; + } if (!yymatchDot(ctx)) goto l1133; + } + l1134:; goto l1132; + l1133:; ctx->pos= yypos1133; ctx->thunkpos= yythunkpos1133; + } if (!yy_HtmlBlockCloseForm(ctx)) goto l1131; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockForm", ctx->buf+ctx->pos)); + return 1; + l1131:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockForm", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseForm(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseForm")); if (!yymatchChar(ctx, '<')) goto l1137; if (!yy_Spnl(ctx)) goto l1137; if (!yymatchChar(ctx, '/')) goto l1137; + { int yypos1138= ctx->pos, yythunkpos1138= ctx->thunkpos; if (!yymatchString(ctx, "form")) goto l1139; goto l1138; + l1139:; ctx->pos= yypos1138; ctx->thunkpos= yythunkpos1138; if (!yymatchString(ctx, "FORM")) goto l1137; + } + l1138:; if (!yy_Spnl(ctx)) goto l1137; if (!yymatchChar(ctx, '>')) goto l1137; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseForm", ctx->buf+ctx->pos)); + return 1; + l1137:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseForm", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenForm(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenForm")); if (!yymatchChar(ctx, '<')) goto l1140; if (!yy_Spnl(ctx)) goto l1140; + { int yypos1141= ctx->pos, yythunkpos1141= ctx->thunkpos; if (!yymatchString(ctx, "form")) goto l1142; goto l1141; + l1142:; ctx->pos= yypos1141; ctx->thunkpos= yythunkpos1141; if (!yymatchString(ctx, "FORM")) goto l1140; + } + l1141:; if (!yy_Spnl(ctx)) goto l1140; + l1143:; + { int yypos1144= ctx->pos, yythunkpos1144= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l1144; goto l1143; + l1144:; ctx->pos= yypos1144; ctx->thunkpos= yythunkpos1144; + } if (!yymatchChar(ctx, '>')) goto l1140; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenForm", ctx->buf+ctx->pos)); + return 1; + l1140:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenForm", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockFieldset(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockFieldset")); if (!yy_HtmlBlockOpenFieldset(ctx)) goto l1145; + l1146:; + { int yypos1147= ctx->pos, yythunkpos1147= ctx->thunkpos; + { int yypos1148= ctx->pos, yythunkpos1148= ctx->thunkpos; if (!yy_HtmlBlockFieldset(ctx)) goto l1149; goto l1148; + l1149:; ctx->pos= yypos1148; ctx->thunkpos= yythunkpos1148; + { int yypos1150= ctx->pos, yythunkpos1150= ctx->thunkpos; if (!yy_HtmlBlockCloseFieldset(ctx)) goto l1150; goto l1147; + l1150:; ctx->pos= yypos1150; ctx->thunkpos= yythunkpos1150; + } if (!yymatchDot(ctx)) goto l1147; + } + l1148:; goto l1146; + l1147:; ctx->pos= yypos1147; ctx->thunkpos= yythunkpos1147; + } if (!yy_HtmlBlockCloseFieldset(ctx)) goto l1145; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockFieldset", ctx->buf+ctx->pos)); + return 1; + l1145:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockFieldset", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseFieldset(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseFieldset")); if (!yymatchChar(ctx, '<')) goto l1151; if (!yy_Spnl(ctx)) goto l1151; if (!yymatchChar(ctx, '/')) goto l1151; + { int yypos1152= ctx->pos, yythunkpos1152= ctx->thunkpos; if (!yymatchString(ctx, "fieldset")) goto l1153; goto l1152; + l1153:; ctx->pos= yypos1152; ctx->thunkpos= yythunkpos1152; if (!yymatchString(ctx, "FIELDSET")) goto l1151; + } + l1152:; if (!yy_Spnl(ctx)) goto l1151; if (!yymatchChar(ctx, '>')) goto l1151; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseFieldset", ctx->buf+ctx->pos)); + return 1; + l1151:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseFieldset", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenFieldset(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenFieldset")); if (!yymatchChar(ctx, '<')) goto l1154; if (!yy_Spnl(ctx)) goto l1154; + { int yypos1155= ctx->pos, yythunkpos1155= ctx->thunkpos; if (!yymatchString(ctx, "fieldset")) goto l1156; goto l1155; + l1156:; ctx->pos= yypos1155; ctx->thunkpos= yythunkpos1155; if (!yymatchString(ctx, "FIELDSET")) goto l1154; + } + l1155:; if (!yy_Spnl(ctx)) goto l1154; + l1157:; + { int yypos1158= ctx->pos, yythunkpos1158= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l1158; goto l1157; + l1158:; ctx->pos= yypos1158; ctx->thunkpos= yythunkpos1158; + } if (!yymatchChar(ctx, '>')) goto l1154; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenFieldset", ctx->buf+ctx->pos)); + return 1; + l1154:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenFieldset", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockDl(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockDl")); if (!yy_HtmlBlockOpenDl(ctx)) goto l1159; + l1160:; + { int yypos1161= ctx->pos, yythunkpos1161= ctx->thunkpos; + { int yypos1162= ctx->pos, yythunkpos1162= ctx->thunkpos; if (!yy_HtmlBlockDl(ctx)) goto l1163; goto l1162; + l1163:; ctx->pos= yypos1162; ctx->thunkpos= yythunkpos1162; + { int yypos1164= ctx->pos, yythunkpos1164= ctx->thunkpos; if (!yy_HtmlBlockCloseDl(ctx)) goto l1164; goto l1161; + l1164:; ctx->pos= yypos1164; ctx->thunkpos= yythunkpos1164; + } if (!yymatchDot(ctx)) goto l1161; + } + l1162:; goto l1160; + l1161:; ctx->pos= yypos1161; ctx->thunkpos= yythunkpos1161; + } if (!yy_HtmlBlockCloseDl(ctx)) goto l1159; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockDl", ctx->buf+ctx->pos)); + return 1; + l1159:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockDl", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseDl(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseDl")); if (!yymatchChar(ctx, '<')) goto l1165; if (!yy_Spnl(ctx)) goto l1165; if (!yymatchChar(ctx, '/')) goto l1165; + { int yypos1166= ctx->pos, yythunkpos1166= ctx->thunkpos; if (!yymatchString(ctx, "dl")) goto l1167; goto l1166; + l1167:; ctx->pos= yypos1166; ctx->thunkpos= yythunkpos1166; if (!yymatchString(ctx, "DL")) goto l1165; + } + l1166:; if (!yy_Spnl(ctx)) goto l1165; if (!yymatchChar(ctx, '>')) goto l1165; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseDl", ctx->buf+ctx->pos)); + return 1; + l1165:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseDl", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenDl(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenDl")); if (!yymatchChar(ctx, '<')) goto l1168; if (!yy_Spnl(ctx)) goto l1168; + { int yypos1169= ctx->pos, yythunkpos1169= ctx->thunkpos; if (!yymatchString(ctx, "dl")) goto l1170; goto l1169; + l1170:; ctx->pos= yypos1169; ctx->thunkpos= yythunkpos1169; if (!yymatchString(ctx, "DL")) goto l1168; + } + l1169:; if (!yy_Spnl(ctx)) goto l1168; + l1171:; + { int yypos1172= ctx->pos, yythunkpos1172= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l1172; goto l1171; + l1172:; ctx->pos= yypos1172; ctx->thunkpos= yythunkpos1172; + } if (!yymatchChar(ctx, '>')) goto l1168; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenDl", ctx->buf+ctx->pos)); + return 1; + l1168:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenDl", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockDiv(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockDiv")); if (!yy_HtmlBlockOpenDiv(ctx)) goto l1173; + l1174:; + { int yypos1175= ctx->pos, yythunkpos1175= ctx->thunkpos; + { int yypos1176= ctx->pos, yythunkpos1176= ctx->thunkpos; if (!yy_HtmlBlockDiv(ctx)) goto l1177; goto l1176; + l1177:; ctx->pos= yypos1176; ctx->thunkpos= yythunkpos1176; + { int yypos1178= ctx->pos, yythunkpos1178= ctx->thunkpos; if (!yy_HtmlBlockCloseDiv(ctx)) goto l1178; goto l1175; + l1178:; ctx->pos= yypos1178; ctx->thunkpos= yythunkpos1178; + } if (!yymatchDot(ctx)) goto l1175; + } + l1176:; goto l1174; + l1175:; ctx->pos= yypos1175; ctx->thunkpos= yythunkpos1175; + } if (!yy_HtmlBlockCloseDiv(ctx)) goto l1173; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockDiv", ctx->buf+ctx->pos)); + return 1; + l1173:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockDiv", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseDiv(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseDiv")); if (!yymatchChar(ctx, '<')) goto l1179; if (!yy_Spnl(ctx)) goto l1179; if (!yymatchChar(ctx, '/')) goto l1179; + { int yypos1180= ctx->pos, yythunkpos1180= ctx->thunkpos; if (!yymatchString(ctx, "div")) goto l1181; goto l1180; + l1181:; ctx->pos= yypos1180; ctx->thunkpos= yythunkpos1180; if (!yymatchString(ctx, "DIV")) goto l1179; + } + l1180:; if (!yy_Spnl(ctx)) goto l1179; if (!yymatchChar(ctx, '>')) goto l1179; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseDiv", ctx->buf+ctx->pos)); + return 1; + l1179:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseDiv", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenDiv(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenDiv")); if (!yymatchChar(ctx, '<')) goto l1182; if (!yy_Spnl(ctx)) goto l1182; + { int yypos1183= ctx->pos, yythunkpos1183= ctx->thunkpos; if (!yymatchString(ctx, "div")) goto l1184; goto l1183; + l1184:; ctx->pos= yypos1183; ctx->thunkpos= yythunkpos1183; if (!yymatchString(ctx, "DIV")) goto l1182; + } + l1183:; if (!yy_Spnl(ctx)) goto l1182; + l1185:; + { int yypos1186= ctx->pos, yythunkpos1186= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l1186; goto l1185; + l1186:; ctx->pos= yypos1186; ctx->thunkpos= yythunkpos1186; + } if (!yymatchChar(ctx, '>')) goto l1182; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenDiv", ctx->buf+ctx->pos)); + return 1; + l1182:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenDiv", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockDir(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockDir")); if (!yy_HtmlBlockOpenDir(ctx)) goto l1187; + l1188:; + { int yypos1189= ctx->pos, yythunkpos1189= ctx->thunkpos; + { int yypos1190= ctx->pos, yythunkpos1190= ctx->thunkpos; if (!yy_HtmlBlockDir(ctx)) goto l1191; goto l1190; + l1191:; ctx->pos= yypos1190; ctx->thunkpos= yythunkpos1190; + { int yypos1192= ctx->pos, yythunkpos1192= ctx->thunkpos; if (!yy_HtmlBlockCloseDir(ctx)) goto l1192; goto l1189; + l1192:; ctx->pos= yypos1192; ctx->thunkpos= yythunkpos1192; + } if (!yymatchDot(ctx)) goto l1189; + } + l1190:; goto l1188; + l1189:; ctx->pos= yypos1189; ctx->thunkpos= yythunkpos1189; + } if (!yy_HtmlBlockCloseDir(ctx)) goto l1187; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockDir", ctx->buf+ctx->pos)); + return 1; + l1187:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockDir", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseDir(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseDir")); if (!yymatchChar(ctx, '<')) goto l1193; if (!yy_Spnl(ctx)) goto l1193; if (!yymatchChar(ctx, '/')) goto l1193; + { int yypos1194= ctx->pos, yythunkpos1194= ctx->thunkpos; if (!yymatchString(ctx, "dir")) goto l1195; goto l1194; + l1195:; ctx->pos= yypos1194; ctx->thunkpos= yythunkpos1194; if (!yymatchString(ctx, "DIR")) goto l1193; + } + l1194:; if (!yy_Spnl(ctx)) goto l1193; if (!yymatchChar(ctx, '>')) goto l1193; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseDir", ctx->buf+ctx->pos)); + return 1; + l1193:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseDir", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenDir(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenDir")); if (!yymatchChar(ctx, '<')) goto l1196; if (!yy_Spnl(ctx)) goto l1196; + { int yypos1197= ctx->pos, yythunkpos1197= ctx->thunkpos; if (!yymatchString(ctx, "dir")) goto l1198; goto l1197; + l1198:; ctx->pos= yypos1197; ctx->thunkpos= yythunkpos1197; if (!yymatchString(ctx, "DIR")) goto l1196; + } + l1197:; if (!yy_Spnl(ctx)) goto l1196; + l1199:; + { int yypos1200= ctx->pos, yythunkpos1200= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l1200; goto l1199; + l1200:; ctx->pos= yypos1200; ctx->thunkpos= yythunkpos1200; + } if (!yymatchChar(ctx, '>')) goto l1196; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenDir", ctx->buf+ctx->pos)); + return 1; + l1196:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenDir", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCenter(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCenter")); if (!yy_HtmlBlockOpenCenter(ctx)) goto l1201; + l1202:; + { int yypos1203= ctx->pos, yythunkpos1203= ctx->thunkpos; + { int yypos1204= ctx->pos, yythunkpos1204= ctx->thunkpos; if (!yy_HtmlBlockCenter(ctx)) goto l1205; goto l1204; + l1205:; ctx->pos= yypos1204; ctx->thunkpos= yythunkpos1204; + { int yypos1206= ctx->pos, yythunkpos1206= ctx->thunkpos; if (!yy_HtmlBlockCloseCenter(ctx)) goto l1206; goto l1203; + l1206:; ctx->pos= yypos1206; ctx->thunkpos= yythunkpos1206; + } if (!yymatchDot(ctx)) goto l1203; + } + l1204:; goto l1202; + l1203:; ctx->pos= yypos1203; ctx->thunkpos= yythunkpos1203; + } if (!yy_HtmlBlockCloseCenter(ctx)) goto l1201; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCenter", ctx->buf+ctx->pos)); + return 1; + l1201:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCenter", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseCenter(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseCenter")); if (!yymatchChar(ctx, '<')) goto l1207; if (!yy_Spnl(ctx)) goto l1207; if (!yymatchChar(ctx, '/')) goto l1207; + { int yypos1208= ctx->pos, yythunkpos1208= ctx->thunkpos; if (!yymatchString(ctx, "center")) goto l1209; goto l1208; + l1209:; ctx->pos= yypos1208; ctx->thunkpos= yythunkpos1208; if (!yymatchString(ctx, "CENTER")) goto l1207; + } + l1208:; if (!yy_Spnl(ctx)) goto l1207; if (!yymatchChar(ctx, '>')) goto l1207; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseCenter", ctx->buf+ctx->pos)); + return 1; + l1207:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseCenter", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenCenter(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenCenter")); if (!yymatchChar(ctx, '<')) goto l1210; if (!yy_Spnl(ctx)) goto l1210; + { int yypos1211= ctx->pos, yythunkpos1211= ctx->thunkpos; if (!yymatchString(ctx, "center")) goto l1212; goto l1211; + l1212:; ctx->pos= yypos1211; ctx->thunkpos= yythunkpos1211; if (!yymatchString(ctx, "CENTER")) goto l1210; + } + l1211:; if (!yy_Spnl(ctx)) goto l1210; + l1213:; + { int yypos1214= ctx->pos, yythunkpos1214= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l1214; goto l1213; + l1214:; ctx->pos= yypos1214; ctx->thunkpos= yythunkpos1214; + } if (!yymatchChar(ctx, '>')) goto l1210; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenCenter", ctx->buf+ctx->pos)); + return 1; + l1210:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenCenter", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockBlockquote(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockBlockquote")); if (!yy_HtmlBlockOpenBlockquote(ctx)) goto l1215; + l1216:; + { int yypos1217= ctx->pos, yythunkpos1217= ctx->thunkpos; + { int yypos1218= ctx->pos, yythunkpos1218= ctx->thunkpos; if (!yy_HtmlBlockBlockquote(ctx)) goto l1219; goto l1218; + l1219:; ctx->pos= yypos1218; ctx->thunkpos= yythunkpos1218; + { int yypos1220= ctx->pos, yythunkpos1220= ctx->thunkpos; if (!yy_HtmlBlockCloseBlockquote(ctx)) goto l1220; goto l1217; + l1220:; ctx->pos= yypos1220; ctx->thunkpos= yythunkpos1220; + } if (!yymatchDot(ctx)) goto l1217; + } + l1218:; goto l1216; + l1217:; ctx->pos= yypos1217; ctx->thunkpos= yythunkpos1217; + } if (!yy_HtmlBlockCloseBlockquote(ctx)) goto l1215; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockBlockquote", ctx->buf+ctx->pos)); + return 1; + l1215:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockBlockquote", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseBlockquote(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseBlockquote")); if (!yymatchChar(ctx, '<')) goto l1221; if (!yy_Spnl(ctx)) goto l1221; if (!yymatchChar(ctx, '/')) goto l1221; + { int yypos1222= ctx->pos, yythunkpos1222= ctx->thunkpos; if (!yymatchString(ctx, "blockquote")) goto l1223; goto l1222; + l1223:; ctx->pos= yypos1222; ctx->thunkpos= yythunkpos1222; if (!yymatchString(ctx, "BLOCKQUOTE")) goto l1221; + } + l1222:; if (!yy_Spnl(ctx)) goto l1221; if (!yymatchChar(ctx, '>')) goto l1221; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseBlockquote", ctx->buf+ctx->pos)); + return 1; + l1221:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseBlockquote", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenBlockquote(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenBlockquote")); if (!yymatchChar(ctx, '<')) goto l1224; if (!yy_Spnl(ctx)) goto l1224; + { int yypos1225= ctx->pos, yythunkpos1225= ctx->thunkpos; if (!yymatchString(ctx, "blockquote")) goto l1226; goto l1225; + l1226:; ctx->pos= yypos1225; ctx->thunkpos= yythunkpos1225; if (!yymatchString(ctx, "BLOCKQUOTE")) goto l1224; + } + l1225:; if (!yy_Spnl(ctx)) goto l1224; + l1227:; + { int yypos1228= ctx->pos, yythunkpos1228= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l1228; goto l1227; + l1228:; ctx->pos= yypos1228; ctx->thunkpos= yythunkpos1228; + } if (!yymatchChar(ctx, '>')) goto l1224; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenBlockquote", ctx->buf+ctx->pos)); + return 1; + l1224:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenBlockquote", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockAddress(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockAddress")); if (!yy_HtmlBlockOpenAddress(ctx)) goto l1229; + l1230:; + { int yypos1231= ctx->pos, yythunkpos1231= ctx->thunkpos; + { int yypos1232= ctx->pos, yythunkpos1232= ctx->thunkpos; if (!yy_HtmlBlockAddress(ctx)) goto l1233; goto l1232; + l1233:; ctx->pos= yypos1232; ctx->thunkpos= yythunkpos1232; + { int yypos1234= ctx->pos, yythunkpos1234= ctx->thunkpos; if (!yy_HtmlBlockCloseAddress(ctx)) goto l1234; goto l1231; + l1234:; ctx->pos= yypos1234; ctx->thunkpos= yythunkpos1234; + } if (!yymatchDot(ctx)) goto l1231; + } + l1232:; goto l1230; + l1231:; ctx->pos= yypos1231; ctx->thunkpos= yythunkpos1231; + } if (!yy_HtmlBlockCloseAddress(ctx)) goto l1229; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockAddress", ctx->buf+ctx->pos)); + return 1; + l1229:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockAddress", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockCloseAddress(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockCloseAddress")); if (!yymatchChar(ctx, '<')) goto l1235; if (!yy_Spnl(ctx)) goto l1235; if (!yymatchChar(ctx, '/')) goto l1235; + { int yypos1236= ctx->pos, yythunkpos1236= ctx->thunkpos; if (!yymatchString(ctx, "address")) goto l1237; goto l1236; + l1237:; ctx->pos= yypos1236; ctx->thunkpos= yythunkpos1236; if (!yymatchString(ctx, "ADDRESS")) goto l1235; + } + l1236:; if (!yy_Spnl(ctx)) goto l1235; if (!yymatchChar(ctx, '>')) goto l1235; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockCloseAddress", ctx->buf+ctx->pos)); + return 1; + l1235:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockCloseAddress", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlAttribute(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlAttribute")); + { int yypos1241= ctx->pos, yythunkpos1241= ctx->thunkpos; if (!yy_AlphanumericAscii(ctx)) goto l1242; goto l1241; + l1242:; ctx->pos= yypos1241; ctx->thunkpos= yythunkpos1241; if (!yymatchChar(ctx, '-')) goto l1238; + } + l1241:; + l1239:; + { int yypos1240= ctx->pos, yythunkpos1240= ctx->thunkpos; + { int yypos1243= ctx->pos, yythunkpos1243= ctx->thunkpos; if (!yy_AlphanumericAscii(ctx)) goto l1244; goto l1243; + l1244:; ctx->pos= yypos1243; ctx->thunkpos= yythunkpos1243; if (!yymatchChar(ctx, '-')) goto l1240; + } + l1243:; goto l1239; + l1240:; ctx->pos= yypos1240; ctx->thunkpos= yythunkpos1240; + } if (!yy_Spnl(ctx)) goto l1238; + { int yypos1245= ctx->pos, yythunkpos1245= ctx->thunkpos; if (!yymatchChar(ctx, '=')) goto l1245; if (!yy_Spnl(ctx)) goto l1245; + { int yypos1247= ctx->pos, yythunkpos1247= ctx->thunkpos; if (!yy_Quoted(ctx)) goto l1248; goto l1247; + l1248:; ctx->pos= yypos1247; ctx->thunkpos= yythunkpos1247; + { int yypos1251= ctx->pos, yythunkpos1251= ctx->thunkpos; if (!yymatchChar(ctx, '>')) goto l1251; goto l1245; + l1251:; ctx->pos= yypos1251; ctx->thunkpos= yythunkpos1251; + } if (!yy_Nonspacechar(ctx)) goto l1245; + l1249:; + { int yypos1250= ctx->pos, yythunkpos1250= ctx->thunkpos; + { int yypos1252= ctx->pos, yythunkpos1252= ctx->thunkpos; if (!yymatchChar(ctx, '>')) goto l1252; goto l1250; + l1252:; ctx->pos= yypos1252; ctx->thunkpos= yythunkpos1252; + } if (!yy_Nonspacechar(ctx)) goto l1250; goto l1249; + l1250:; ctx->pos= yypos1250; ctx->thunkpos= yythunkpos1250; + } + } + l1247:; goto l1246; + l1245:; ctx->pos= yypos1245; ctx->thunkpos= yythunkpos1245; + } + l1246:; if (!yy_Spnl(ctx)) goto l1238; + yyprintf((stderr, " ok %s @ %s\n", "HtmlAttribute", ctx->buf+ctx->pos)); + return 1; + l1238:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlAttribute", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Spnl(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Spnl")); if (!yy_Sp(ctx)) goto l1253; + { int yypos1254= ctx->pos, yythunkpos1254= ctx->thunkpos; if (!yy_Newline(ctx)) goto l1254; if (!yy_Sp(ctx)) goto l1254; goto l1255; + l1254:; ctx->pos= yypos1254; ctx->thunkpos= yythunkpos1254; + } + l1255:; + yyprintf((stderr, " ok %s @ %s\n", "Spnl", ctx->buf+ctx->pos)); + return 1; + l1253:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Spnl", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlockOpenAddress(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlockOpenAddress")); if (!yymatchChar(ctx, '<')) goto l1256; if (!yy_Spnl(ctx)) goto l1256; + { int yypos1257= ctx->pos, yythunkpos1257= ctx->thunkpos; if (!yymatchString(ctx, "address")) goto l1258; goto l1257; + l1258:; ctx->pos= yypos1257; ctx->thunkpos= yythunkpos1257; if (!yymatchString(ctx, "ADDRESS")) goto l1256; + } + l1257:; if (!yy_Spnl(ctx)) goto l1256; + l1259:; + { int yypos1260= ctx->pos, yythunkpos1260= ctx->thunkpos; if (!yy_HtmlAttribute(ctx)) goto l1260; goto l1259; + l1260:; ctx->pos= yypos1260; ctx->thunkpos= yythunkpos1260; + } if (!yymatchChar(ctx, '>')) goto l1256; + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlockOpenAddress", ctx->buf+ctx->pos)); + return 1; + l1256:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlockOpenAddress", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_OptionallyIndentedLine(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "OptionallyIndentedLine")); + { int yypos1262= ctx->pos, yythunkpos1262= ctx->thunkpos; if (!yy_Indent(ctx)) goto l1262; goto l1263; + l1262:; ctx->pos= yypos1262; ctx->thunkpos= yythunkpos1262; + } + l1263:; if (!yy_Line(ctx)) goto l1261; + yyprintf((stderr, " ok %s @ %s\n", "OptionallyIndentedLine", ctx->buf+ctx->pos)); + return 1; + l1261:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "OptionallyIndentedLine", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Indent(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Indent")); + { int yypos1265= ctx->pos, yythunkpos1265= ctx->thunkpos; if (!yymatchChar(ctx, '\t')) goto l1266; goto l1265; + l1266:; ctx->pos= yypos1265; ctx->thunkpos= yythunkpos1265; if (!yymatchString(ctx, " ")) goto l1264; + } + l1265:; + yyprintf((stderr, " ok %s @ %s\n", "Indent", ctx->buf+ctx->pos)); + return 1; + l1264:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Indent", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_ListBlockLine(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "ListBlockLine")); + { int yypos1268= ctx->pos, yythunkpos1268= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l1268; goto l1267; + l1268:; ctx->pos= yypos1268; ctx->thunkpos= yythunkpos1268; + } + { int yypos1269= ctx->pos, yythunkpos1269= ctx->thunkpos; + { int yypos1270= ctx->pos, yythunkpos1270= ctx->thunkpos; if (!yy_Indent(ctx)) goto l1270; goto l1271; + l1270:; ctx->pos= yypos1270; ctx->thunkpos= yythunkpos1270; + } + l1271:; + { int yypos1272= ctx->pos, yythunkpos1272= ctx->thunkpos; if (!yy_Bullet(ctx)) goto l1273; goto l1272; + l1273:; ctx->pos= yypos1272; ctx->thunkpos= yythunkpos1272; if (!yy_Enumerator(ctx)) goto l1269; + } + l1272:; goto l1267; + l1269:; ctx->pos= yypos1269; ctx->thunkpos= yythunkpos1269; + } + { int yypos1274= ctx->pos, yythunkpos1274= ctx->thunkpos; if (!yy_HorizontalRule(ctx)) goto l1274; goto l1267; + l1274:; ctx->pos= yypos1274; ctx->thunkpos= yythunkpos1274; + } if (!yy_OptionallyIndentedLine(ctx)) goto l1267; + yyprintf((stderr, " ok %s @ %s\n", "ListBlockLine", ctx->buf+ctx->pos)); + return 1; + l1267:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "ListBlockLine", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_ListContinuationBlock(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "ListContinuationBlock")); if (!yy_StartList(ctx)) goto l1275; yyDo(ctx, yySet, -1, 0); yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l1275; + l1276:; + { int yypos1277= ctx->pos, yythunkpos1277= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l1277; goto l1276; + l1277:; ctx->pos= yypos1277; ctx->thunkpos= yythunkpos1277; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l1275; yyDo(ctx, yy_1_ListContinuationBlock, ctx->begin, ctx->end); if (!yy_Indent(ctx)) goto l1275; if (!yy_ListBlock(ctx)) goto l1275; yyDo(ctx, yy_2_ListContinuationBlock, ctx->begin, ctx->end); + l1278:; + { int yypos1279= ctx->pos, yythunkpos1279= ctx->thunkpos; if (!yy_Indent(ctx)) goto l1279; if (!yy_ListBlock(ctx)) goto l1279; yyDo(ctx, yy_2_ListContinuationBlock, ctx->begin, ctx->end); goto l1278; + l1279:; ctx->pos= yypos1279; ctx->thunkpos= yythunkpos1279; + } yyDo(ctx, yy_3_ListContinuationBlock, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "ListContinuationBlock", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 1, 0); + return 1; + l1275:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "ListContinuationBlock", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_ListBlock(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "ListBlock")); if (!yy_StartList(ctx)) goto l1280; yyDo(ctx, yySet, -1, 0); + { int yypos1281= ctx->pos, yythunkpos1281= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l1281; goto l1280; + l1281:; ctx->pos= yypos1281; ctx->thunkpos= yythunkpos1281; + } if (!yy_Line(ctx)) goto l1280; yyDo(ctx, yy_1_ListBlock, ctx->begin, ctx->end); + l1282:; + { int yypos1283= ctx->pos, yythunkpos1283= ctx->thunkpos; if (!yy_ListBlockLine(ctx)) goto l1283; yyDo(ctx, yy_2_ListBlock, ctx->begin, ctx->end); goto l1282; + l1283:; ctx->pos= yypos1283; ctx->thunkpos= yythunkpos1283; + } yyDo(ctx, yy_3_ListBlock, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "ListBlock", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 1, 0); + return 1; + l1280:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "ListBlock", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_ListItem(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "ListItem")); + { int yypos1285= ctx->pos, yythunkpos1285= ctx->thunkpos; if (!yy_Bullet(ctx)) goto l1286; goto l1285; + l1286:; ctx->pos= yypos1285; ctx->thunkpos= yythunkpos1285; if (!yy_Enumerator(ctx)) goto l1284; + } + l1285:; if (!yy_StartList(ctx)) goto l1284; yyDo(ctx, yySet, -1, 0); if (!yy_ListBlock(ctx)) goto l1284; yyDo(ctx, yy_1_ListItem, ctx->begin, ctx->end); + l1287:; + { int yypos1288= ctx->pos, yythunkpos1288= ctx->thunkpos; if (!yy_ListContinuationBlock(ctx)) goto l1288; yyDo(ctx, yy_2_ListItem, ctx->begin, ctx->end); goto l1287; + l1288:; ctx->pos= yypos1288; ctx->thunkpos= yythunkpos1288; + } yyDo(ctx, yy_3_ListItem, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "ListItem", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 1, 0); + return 1; + l1284:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "ListItem", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Enumerator(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Enumerator")); if (!yy_NonindentSpace(ctx)) goto l1289; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l1289; + l1290:; + { int yypos1291= ctx->pos, yythunkpos1291= ctx->thunkpos; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l1291; goto l1290; + l1291:; ctx->pos= yypos1291; ctx->thunkpos= yythunkpos1291; + } if (!yymatchChar(ctx, '.')) goto l1289; if (!yy_Spacechar(ctx)) goto l1289; + l1292:; + { int yypos1293= ctx->pos, yythunkpos1293= ctx->thunkpos; if (!yy_Spacechar(ctx)) goto l1293; goto l1292; + l1293:; ctx->pos= yypos1293; ctx->thunkpos= yythunkpos1293; + } + yyprintf((stderr, " ok %s @ %s\n", "Enumerator", ctx->buf+ctx->pos)); + return 1; + l1289:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Enumerator", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_ListItemTight(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "ListItemTight")); + { int yypos1295= ctx->pos, yythunkpos1295= ctx->thunkpos; if (!yy_Bullet(ctx)) goto l1296; goto l1295; + l1296:; ctx->pos= yypos1295; ctx->thunkpos= yythunkpos1295; if (!yy_Enumerator(ctx)) goto l1294; + } + l1295:; if (!yy_StartList(ctx)) goto l1294; yyDo(ctx, yySet, -1, 0); if (!yy_ListBlock(ctx)) goto l1294; yyDo(ctx, yy_1_ListItemTight, ctx->begin, ctx->end); + l1297:; + { int yypos1298= ctx->pos, yythunkpos1298= ctx->thunkpos; + { int yypos1299= ctx->pos, yythunkpos1299= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l1299; goto l1298; + l1299:; ctx->pos= yypos1299; ctx->thunkpos= yythunkpos1299; + } if (!yy_ListContinuationBlock(ctx)) goto l1298; yyDo(ctx, yy_2_ListItemTight, ctx->begin, ctx->end); goto l1297; + l1298:; ctx->pos= yypos1298; ctx->thunkpos= yythunkpos1298; + } + { int yypos1300= ctx->pos, yythunkpos1300= ctx->thunkpos; if (!yy_ListContinuationBlock(ctx)) goto l1300; goto l1294; + l1300:; ctx->pos= yypos1300; ctx->thunkpos= yythunkpos1300; + } yyDo(ctx, yy_3_ListItemTight, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "ListItemTight", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 1, 0); + return 1; + l1294:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "ListItemTight", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_ListLoose(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 2, 0); + yyprintf((stderr, "%s\n", "ListLoose")); if (!yy_StartList(ctx)) goto l1301; yyDo(ctx, yySet, -2, 0); if (!yy_ListItem(ctx)) goto l1301; yyDo(ctx, yySet, -1, 0); + l1304:; + { int yypos1305= ctx->pos, yythunkpos1305= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l1305; goto l1304; + l1305:; ctx->pos= yypos1305; ctx->thunkpos= yythunkpos1305; + } yyDo(ctx, yy_1_ListLoose, ctx->begin, ctx->end); + l1302:; + { int yypos1303= ctx->pos, yythunkpos1303= ctx->thunkpos; if (!yy_ListItem(ctx)) goto l1303; yyDo(ctx, yySet, -1, 0); + l1306:; + { int yypos1307= ctx->pos, yythunkpos1307= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l1307; goto l1306; + l1307:; ctx->pos= yypos1307; ctx->thunkpos= yythunkpos1307; + } yyDo(ctx, yy_1_ListLoose, ctx->begin, ctx->end); goto l1302; + l1303:; ctx->pos= yypos1303; ctx->thunkpos= yythunkpos1303; + } yyDo(ctx, yy_2_ListLoose, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "ListLoose", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 2, 0); + return 1; + l1301:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "ListLoose", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_ListTight(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "ListTight")); if (!yy_StartList(ctx)) goto l1308; yyDo(ctx, yySet, -1, 0); if (!yy_ListItemTight(ctx)) goto l1308; yyDo(ctx, yy_1_ListTight, ctx->begin, ctx->end); + l1309:; + { int yypos1310= ctx->pos, yythunkpos1310= ctx->thunkpos; if (!yy_ListItemTight(ctx)) goto l1310; yyDo(ctx, yy_1_ListTight, ctx->begin, ctx->end); goto l1309; + l1310:; ctx->pos= yypos1310; ctx->thunkpos= yythunkpos1310; + } + l1311:; + { int yypos1312= ctx->pos, yythunkpos1312= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l1312; goto l1311; + l1312:; ctx->pos= yypos1312; ctx->thunkpos= yythunkpos1312; + } + { int yypos1313= ctx->pos, yythunkpos1313= ctx->thunkpos; + { int yypos1314= ctx->pos, yythunkpos1314= ctx->thunkpos; if (!yy_Bullet(ctx)) goto l1315; goto l1314; + l1315:; ctx->pos= yypos1314; ctx->thunkpos= yythunkpos1314; if (!yy_Enumerator(ctx)) goto l1313; + } + l1314:; goto l1308; + l1313:; ctx->pos= yypos1313; ctx->thunkpos= yythunkpos1313; + } yyDo(ctx, yy_2_ListTight, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "ListTight", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 1, 0); + return 1; + l1308:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "ListTight", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Spacechar(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Spacechar")); + { int yypos1317= ctx->pos, yythunkpos1317= ctx->thunkpos; if (!yymatchChar(ctx, ' ')) goto l1318; goto l1317; + l1318:; ctx->pos= yypos1317; ctx->thunkpos= yythunkpos1317; if (!yymatchChar(ctx, '\t')) goto l1316; + } + l1317:; + yyprintf((stderr, " ok %s @ %s\n", "Spacechar", ctx->buf+ctx->pos)); + return 1; + l1316:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Spacechar", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Bullet(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Bullet")); + { int yypos1320= ctx->pos, yythunkpos1320= ctx->thunkpos; if (!yy_HorizontalRule(ctx)) goto l1320; goto l1319; + l1320:; ctx->pos= yypos1320; ctx->thunkpos= yythunkpos1320; + } if (!yy_NonindentSpace(ctx)) goto l1319; + { int yypos1321= ctx->pos, yythunkpos1321= ctx->thunkpos; if (!yymatchChar(ctx, '+')) goto l1322; goto l1321; + l1322:; ctx->pos= yypos1321; ctx->thunkpos= yythunkpos1321; if (!yymatchChar(ctx, '*')) goto l1323; goto l1321; + l1323:; ctx->pos= yypos1321; ctx->thunkpos= yythunkpos1321; if (!yymatchChar(ctx, '-')) goto l1319; + } + l1321:; if (!yy_Spacechar(ctx)) goto l1319; + l1324:; + { int yypos1325= ctx->pos, yythunkpos1325= ctx->thunkpos; if (!yy_Spacechar(ctx)) goto l1325; goto l1324; + l1325:; ctx->pos= yypos1325; ctx->thunkpos= yythunkpos1325; + } + yyprintf((stderr, " ok %s @ %s\n", "Bullet", ctx->buf+ctx->pos)); + return 1; + l1319:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Bullet", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_VerbatimChunk(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "VerbatimChunk")); if (!yy_StartList(ctx)) goto l1326; yyDo(ctx, yySet, -1, 0); + l1327:; + { int yypos1328= ctx->pos, yythunkpos1328= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l1328; yyDo(ctx, yy_1_VerbatimChunk, ctx->begin, ctx->end); goto l1327; + l1328:; ctx->pos= yypos1328; ctx->thunkpos= yythunkpos1328; + } if (!yy_NonblankIndentedLine(ctx)) goto l1326; yyDo(ctx, yy_2_VerbatimChunk, ctx->begin, ctx->end); + l1329:; + { int yypos1330= ctx->pos, yythunkpos1330= ctx->thunkpos; if (!yy_NonblankIndentedLine(ctx)) goto l1330; yyDo(ctx, yy_2_VerbatimChunk, ctx->begin, ctx->end); goto l1329; + l1330:; ctx->pos= yypos1330; ctx->thunkpos= yythunkpos1330; + } yyDo(ctx, yy_3_VerbatimChunk, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "VerbatimChunk", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 1, 0); + return 1; + l1326:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "VerbatimChunk", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_IndentedLine(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "IndentedLine")); if (!yy_Indent(ctx)) goto l1331; if (!yy_Line(ctx)) goto l1331; + yyprintf((stderr, " ok %s @ %s\n", "IndentedLine", ctx->buf+ctx->pos)); + return 1; + l1331:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "IndentedLine", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_NonblankIndentedLine(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "NonblankIndentedLine")); + { int yypos1333= ctx->pos, yythunkpos1333= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l1333; goto l1332; + l1333:; ctx->pos= yypos1333; ctx->thunkpos= yythunkpos1333; + } if (!yy_IndentedLine(ctx)) goto l1332; + yyprintf((stderr, " ok %s @ %s\n", "NonblankIndentedLine", ctx->buf+ctx->pos)); + return 1; + l1332:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "NonblankIndentedLine", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Line(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Line")); if (!yy_RawLine(ctx)) goto l1334; yyDo(ctx, yy_1_Line, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "Line", ctx->buf+ctx->pos)); + return 1; + l1334:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Line", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_BlockQuoteRaw(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "BlockQuoteRaw")); if (!yy_StartList(ctx)) goto l1335; yyDo(ctx, yySet, -1, 0); if (!yymatchChar(ctx, '>')) goto l1335; + { int yypos1338= ctx->pos, yythunkpos1338= ctx->thunkpos; if (!yymatchChar(ctx, ' ')) goto l1338; goto l1339; + l1338:; ctx->pos= yypos1338; ctx->thunkpos= yythunkpos1338; + } + l1339:; if (!yy_Line(ctx)) goto l1335; yyDo(ctx, yy_1_BlockQuoteRaw, ctx->begin, ctx->end); + l1340:; + { int yypos1341= ctx->pos, yythunkpos1341= ctx->thunkpos; + { int yypos1342= ctx->pos, yythunkpos1342= ctx->thunkpos; if (!yymatchChar(ctx, '>')) goto l1342; goto l1341; + l1342:; ctx->pos= yypos1342; ctx->thunkpos= yythunkpos1342; + } + { int yypos1343= ctx->pos, yythunkpos1343= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l1343; goto l1341; + l1343:; ctx->pos= yypos1343; ctx->thunkpos= yythunkpos1343; + } if (!yy_Line(ctx)) goto l1341; yyDo(ctx, yy_2_BlockQuoteRaw, ctx->begin, ctx->end); goto l1340; + l1341:; ctx->pos= yypos1341; ctx->thunkpos= yythunkpos1341; + } + l1344:; + { int yypos1345= ctx->pos, yythunkpos1345= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l1345; yyDo(ctx, yy_3_BlockQuoteRaw, ctx->begin, ctx->end); goto l1344; + l1345:; ctx->pos= yypos1345; ctx->thunkpos= yythunkpos1345; + } + l1336:; + { int yypos1337= ctx->pos, yythunkpos1337= ctx->thunkpos; if (!yymatchChar(ctx, '>')) goto l1337; + { int yypos1346= ctx->pos, yythunkpos1346= ctx->thunkpos; if (!yymatchChar(ctx, ' ')) goto l1346; goto l1347; + l1346:; ctx->pos= yypos1346; ctx->thunkpos= yythunkpos1346; + } + l1347:; if (!yy_Line(ctx)) goto l1337; yyDo(ctx, yy_1_BlockQuoteRaw, ctx->begin, ctx->end); + l1348:; + { int yypos1349= ctx->pos, yythunkpos1349= ctx->thunkpos; + { int yypos1350= ctx->pos, yythunkpos1350= ctx->thunkpos; if (!yymatchChar(ctx, '>')) goto l1350; goto l1349; + l1350:; ctx->pos= yypos1350; ctx->thunkpos= yythunkpos1350; + } + { int yypos1351= ctx->pos, yythunkpos1351= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l1351; goto l1349; + l1351:; ctx->pos= yypos1351; ctx->thunkpos= yythunkpos1351; + } if (!yy_Line(ctx)) goto l1349; yyDo(ctx, yy_2_BlockQuoteRaw, ctx->begin, ctx->end); goto l1348; + l1349:; ctx->pos= yypos1349; ctx->thunkpos= yythunkpos1349; + } + l1352:; + { int yypos1353= ctx->pos, yythunkpos1353= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l1353; yyDo(ctx, yy_3_BlockQuoteRaw, ctx->begin, ctx->end); goto l1352; + l1353:; ctx->pos= yypos1353; ctx->thunkpos= yythunkpos1353; + } goto l1336; + l1337:; ctx->pos= yypos1337; ctx->thunkpos= yythunkpos1337; + } yyDo(ctx, yy_4_BlockQuoteRaw, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "BlockQuoteRaw", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 1, 0); + return 1; + l1335:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "BlockQuoteRaw", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Endline(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Endline")); + { int yypos1355= ctx->pos, yythunkpos1355= ctx->thunkpos; if (!yy_LineBreak(ctx)) goto l1356; goto l1355; + l1356:; ctx->pos= yypos1355; ctx->thunkpos= yythunkpos1355; if (!yy_TerminalEndline(ctx)) goto l1357; goto l1355; + l1357:; ctx->pos= yypos1355; ctx->thunkpos= yythunkpos1355; if (!yy_NormalEndline(ctx)) goto l1354; + } + l1355:; + yyprintf((stderr, " ok %s @ %s\n", "Endline", ctx->buf+ctx->pos)); + return 1; + l1354:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Endline", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_RawLine(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "RawLine")); + { int yypos1359= ctx->pos, yythunkpos1359= ctx->thunkpos; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l1360; + l1361:; + { int yypos1362= ctx->pos, yythunkpos1362= ctx->thunkpos; + { int yypos1363= ctx->pos, yythunkpos1363= ctx->thunkpos; if (!yymatchChar(ctx, '\r')) goto l1363; goto l1362; + l1363:; ctx->pos= yypos1363; ctx->thunkpos= yythunkpos1363; + } + { int yypos1364= ctx->pos, yythunkpos1364= ctx->thunkpos; if (!yymatchChar(ctx, '\n')) goto l1364; goto l1362; + l1364:; ctx->pos= yypos1364; ctx->thunkpos= yythunkpos1364; + } if (!yymatchDot(ctx)) goto l1362; goto l1361; + l1362:; ctx->pos= yypos1362; ctx->thunkpos= yythunkpos1362; + } if (!yy_Newline(ctx)) goto l1360; yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l1360; goto l1359; + l1360:; ctx->pos= yypos1359; ctx->thunkpos= yythunkpos1359; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l1358; if (!yymatchDot(ctx)) goto l1358; + l1365:; + { int yypos1366= ctx->pos, yythunkpos1366= ctx->thunkpos; if (!yymatchDot(ctx)) goto l1366; goto l1365; + l1366:; ctx->pos= yypos1366; ctx->thunkpos= yythunkpos1366; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l1358; if (!yy_Eof(ctx)) goto l1358; + } + l1359:; + yyprintf((stderr, " ok %s @ %s\n", "RawLine", ctx->buf+ctx->pos)); + return 1; + l1358:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "RawLine", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_SetextBottom2(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "SetextBottom2")); if (!yymatchChar(ctx, '-')) goto l1367; + l1368:; + { int yypos1369= ctx->pos, yythunkpos1369= ctx->thunkpos; if (!yymatchChar(ctx, '-')) goto l1369; goto l1368; + l1369:; ctx->pos= yypos1369; ctx->thunkpos= yythunkpos1369; + } if (!yy_Newline(ctx)) goto l1367; + yyprintf((stderr, " ok %s @ %s\n", "SetextBottom2", ctx->buf+ctx->pos)); + return 1; + l1367:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "SetextBottom2", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_SetextBottom1(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "SetextBottom1")); if (!yymatchChar(ctx, '=')) goto l1370; + l1371:; + { int yypos1372= ctx->pos, yythunkpos1372= ctx->thunkpos; if (!yymatchChar(ctx, '=')) goto l1372; goto l1371; + l1372:; ctx->pos= yypos1372; ctx->thunkpos= yythunkpos1372; + } if (!yy_Newline(ctx)) goto l1370; + yyprintf((stderr, " ok %s @ %s\n", "SetextBottom1", ctx->buf+ctx->pos)); + return 1; + l1370:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "SetextBottom1", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_SetextHeading2(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "SetextHeading2")); + { int yypos1374= ctx->pos, yythunkpos1374= ctx->thunkpos; if (!yy_RawLine(ctx)) goto l1373; if (!yy_SetextBottom2(ctx)) goto l1373; ctx->pos= yypos1374; ctx->thunkpos= yythunkpos1374; + } if (!yy_StartList(ctx)) goto l1373; yyDo(ctx, yySet, -1, 0); + { int yypos1377= ctx->pos, yythunkpos1377= ctx->thunkpos; if (!yy_Endline(ctx)) goto l1377; goto l1373; + l1377:; ctx->pos= yypos1377; ctx->thunkpos= yythunkpos1377; + } if (!yy_Inline(ctx)) goto l1373; yyDo(ctx, yy_1_SetextHeading2, ctx->begin, ctx->end); + l1375:; + { int yypos1376= ctx->pos, yythunkpos1376= ctx->thunkpos; + { int yypos1378= ctx->pos, yythunkpos1378= ctx->thunkpos; if (!yy_Endline(ctx)) goto l1378; goto l1376; + l1378:; ctx->pos= yypos1378; ctx->thunkpos= yythunkpos1378; + } if (!yy_Inline(ctx)) goto l1376; yyDo(ctx, yy_1_SetextHeading2, ctx->begin, ctx->end); goto l1375; + l1376:; ctx->pos= yypos1376; ctx->thunkpos= yythunkpos1376; + } + { int yypos1379= ctx->pos, yythunkpos1379= ctx->thunkpos; if (!yy_Sp(ctx)) goto l1379; goto l1380; + l1379:; ctx->pos= yypos1379; ctx->thunkpos= yythunkpos1379; + } + l1380:; if (!yy_Newline(ctx)) goto l1373; if (!yy_SetextBottom2(ctx)) goto l1373; yyDo(ctx, yy_2_SetextHeading2, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "SetextHeading2", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 1, 0); + return 1; + l1373:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "SetextHeading2", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_SetextHeading1(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "SetextHeading1")); + { int yypos1382= ctx->pos, yythunkpos1382= ctx->thunkpos; if (!yy_RawLine(ctx)) goto l1381; if (!yy_SetextBottom1(ctx)) goto l1381; ctx->pos= yypos1382; ctx->thunkpos= yythunkpos1382; + } if (!yy_StartList(ctx)) goto l1381; yyDo(ctx, yySet, -1, 0); + { int yypos1385= ctx->pos, yythunkpos1385= ctx->thunkpos; if (!yy_Endline(ctx)) goto l1385; goto l1381; + l1385:; ctx->pos= yypos1385; ctx->thunkpos= yythunkpos1385; + } if (!yy_Inline(ctx)) goto l1381; yyDo(ctx, yy_1_SetextHeading1, ctx->begin, ctx->end); + l1383:; + { int yypos1384= ctx->pos, yythunkpos1384= ctx->thunkpos; + { int yypos1386= ctx->pos, yythunkpos1386= ctx->thunkpos; if (!yy_Endline(ctx)) goto l1386; goto l1384; + l1386:; ctx->pos= yypos1386; ctx->thunkpos= yythunkpos1386; + } if (!yy_Inline(ctx)) goto l1384; yyDo(ctx, yy_1_SetextHeading1, ctx->begin, ctx->end); goto l1383; + l1384:; ctx->pos= yypos1384; ctx->thunkpos= yythunkpos1384; + } + { int yypos1387= ctx->pos, yythunkpos1387= ctx->thunkpos; if (!yy_Sp(ctx)) goto l1387; goto l1388; + l1387:; ctx->pos= yypos1387; ctx->thunkpos= yythunkpos1387; + } + l1388:; if (!yy_Newline(ctx)) goto l1381; if (!yy_SetextBottom1(ctx)) goto l1381; yyDo(ctx, yy_2_SetextHeading1, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "SetextHeading1", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 1, 0); + return 1; + l1381:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "SetextHeading1", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_SetextHeading(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "SetextHeading")); + { int yypos1390= ctx->pos, yythunkpos1390= ctx->thunkpos; if (!yy_SetextHeading1(ctx)) goto l1391; goto l1390; + l1391:; ctx->pos= yypos1390; ctx->thunkpos= yythunkpos1390; if (!yy_SetextHeading2(ctx)) goto l1389; + } + l1390:; + yyprintf((stderr, " ok %s @ %s\n", "SetextHeading", ctx->buf+ctx->pos)); + return 1; + l1389:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "SetextHeading", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_AtxHeading(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 2, 0); + yyprintf((stderr, "%s\n", "AtxHeading")); if (!yy_AtxStart(ctx)) goto l1392; yyDo(ctx, yySet, -2, 0); + { int yypos1393= ctx->pos, yythunkpos1393= ctx->thunkpos; if (!yy_Sp(ctx)) goto l1393; goto l1394; + l1393:; ctx->pos= yypos1393; ctx->thunkpos= yythunkpos1393; + } + l1394:; if (!yy_StartList(ctx)) goto l1392; yyDo(ctx, yySet, -1, 0); if (!yy_AtxInline(ctx)) goto l1392; yyDo(ctx, yy_1_AtxHeading, ctx->begin, ctx->end); + l1395:; + { int yypos1396= ctx->pos, yythunkpos1396= ctx->thunkpos; if (!yy_AtxInline(ctx)) goto l1396; yyDo(ctx, yy_1_AtxHeading, ctx->begin, ctx->end); goto l1395; + l1396:; ctx->pos= yypos1396; ctx->thunkpos= yythunkpos1396; + } + { int yypos1397= ctx->pos, yythunkpos1397= ctx->thunkpos; + { int yypos1399= ctx->pos, yythunkpos1399= ctx->thunkpos; if (!yy_Sp(ctx)) goto l1399; goto l1400; + l1399:; ctx->pos= yypos1399; ctx->thunkpos= yythunkpos1399; + } + l1400:; + l1401:; + { int yypos1402= ctx->pos, yythunkpos1402= ctx->thunkpos; if (!yymatchChar(ctx, '#')) goto l1402; goto l1401; + l1402:; ctx->pos= yypos1402; ctx->thunkpos= yythunkpos1402; + } if (!yy_Sp(ctx)) goto l1397; goto l1398; + l1397:; ctx->pos= yypos1397; ctx->thunkpos= yythunkpos1397; + } + l1398:; if (!yy_Newline(ctx)) goto l1392; yyDo(ctx, yy_2_AtxHeading, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "AtxHeading", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 2, 0); + return 1; + l1392:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "AtxHeading", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_AtxStart(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "AtxStart")); yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l1403; + { int yypos1404= ctx->pos, yythunkpos1404= ctx->thunkpos; if (!yymatchString(ctx, "######")) goto l1405; goto l1404; + l1405:; ctx->pos= yypos1404; ctx->thunkpos= yythunkpos1404; if (!yymatchString(ctx, "#####")) goto l1406; goto l1404; + l1406:; ctx->pos= yypos1404; ctx->thunkpos= yythunkpos1404; if (!yymatchString(ctx, "####")) goto l1407; goto l1404; + l1407:; ctx->pos= yypos1404; ctx->thunkpos= yythunkpos1404; if (!yymatchString(ctx, "###")) goto l1408; goto l1404; + l1408:; ctx->pos= yypos1404; ctx->thunkpos= yythunkpos1404; if (!yymatchString(ctx, "##")) goto l1409; goto l1404; + l1409:; ctx->pos= yypos1404; ctx->thunkpos= yythunkpos1404; if (!yymatchChar(ctx, '#')) goto l1403; + } + l1404:; yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l1403; yyDo(ctx, yy_1_AtxStart, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "AtxStart", ctx->buf+ctx->pos)); + return 1; + l1403:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "AtxStart", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Inline(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Inline")); + { int yypos1411= ctx->pos, yythunkpos1411= ctx->thunkpos; if (!yy_Str(ctx)) goto l1412; goto l1411; + l1412:; ctx->pos= yypos1411; ctx->thunkpos= yythunkpos1411; if (!yy_Endline(ctx)) goto l1413; goto l1411; + l1413:; ctx->pos= yypos1411; ctx->thunkpos= yythunkpos1411; if (!yy_UlOrStarLine(ctx)) goto l1414; goto l1411; + l1414:; ctx->pos= yypos1411; ctx->thunkpos= yythunkpos1411; if (!yy_Space(ctx)) goto l1415; goto l1411; + l1415:; ctx->pos= yypos1411; ctx->thunkpos= yythunkpos1411; if (!yy_Strong(ctx)) goto l1416; goto l1411; + l1416:; ctx->pos= yypos1411; ctx->thunkpos= yythunkpos1411; if (!yy_Emph(ctx)) goto l1417; goto l1411; + l1417:; ctx->pos= yypos1411; ctx->thunkpos= yythunkpos1411; if (!yy_Image(ctx)) goto l1418; goto l1411; + l1418:; ctx->pos= yypos1411; ctx->thunkpos= yythunkpos1411; if (!yy_Link(ctx)) goto l1419; goto l1411; + l1419:; ctx->pos= yypos1411; ctx->thunkpos= yythunkpos1411; if (!yy_NoteReference(ctx)) goto l1420; goto l1411; + l1420:; ctx->pos= yypos1411; ctx->thunkpos= yythunkpos1411; if (!yy_InlineNote(ctx)) goto l1421; goto l1411; + l1421:; ctx->pos= yypos1411; ctx->thunkpos= yythunkpos1411; if (!yy_Code(ctx)) goto l1422; goto l1411; + l1422:; ctx->pos= yypos1411; ctx->thunkpos= yythunkpos1411; if (!yy_RawHtml(ctx)) goto l1423; goto l1411; + l1423:; ctx->pos= yypos1411; ctx->thunkpos= yythunkpos1411; if (!yy_Entity(ctx)) goto l1424; goto l1411; + l1424:; ctx->pos= yypos1411; ctx->thunkpos= yythunkpos1411; if (!yy_EscapedChar(ctx)) goto l1425; goto l1411; + l1425:; ctx->pos= yypos1411; ctx->thunkpos= yythunkpos1411; if (!yy_Smart(ctx)) goto l1426; goto l1411; + l1426:; ctx->pos= yypos1411; ctx->thunkpos= yythunkpos1411; if (!yy_Symbol(ctx)) goto l1410; + } + l1411:; + yyprintf((stderr, " ok %s @ %s\n", "Inline", ctx->buf+ctx->pos)); + return 1; + l1410:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Inline", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Sp(yycontext *ctx) +{ + yyprintf((stderr, "%s\n", "Sp")); + l1428:; + { int yypos1429= ctx->pos, yythunkpos1429= ctx->thunkpos; if (!yy_Spacechar(ctx)) goto l1429; goto l1428; + l1429:; ctx->pos= yypos1429; ctx->thunkpos= yythunkpos1429; + } + yyprintf((stderr, " ok %s @ %s\n", "Sp", ctx->buf+ctx->pos)); + return 1; +} +YY_RULE(int) yy_Newline(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Newline")); + { int yypos1431= ctx->pos, yythunkpos1431= ctx->thunkpos; if (!yymatchChar(ctx, '\n')) goto l1432; goto l1431; + l1432:; ctx->pos= yypos1431; ctx->thunkpos= yythunkpos1431; if (!yymatchChar(ctx, '\r')) goto l1430; + { int yypos1433= ctx->pos, yythunkpos1433= ctx->thunkpos; if (!yymatchChar(ctx, '\n')) goto l1433; goto l1434; + l1433:; ctx->pos= yypos1433; ctx->thunkpos= yythunkpos1433; + } + l1434:; + } + l1431:; + yyprintf((stderr, " ok %s @ %s\n", "Newline", ctx->buf+ctx->pos)); + return 1; + l1430:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Newline", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_AtxInline(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "AtxInline")); + { int yypos1436= ctx->pos, yythunkpos1436= ctx->thunkpos; if (!yy_Newline(ctx)) goto l1436; goto l1435; + l1436:; ctx->pos= yypos1436; ctx->thunkpos= yythunkpos1436; + } + { int yypos1437= ctx->pos, yythunkpos1437= ctx->thunkpos; + { int yypos1438= ctx->pos, yythunkpos1438= ctx->thunkpos; if (!yy_Sp(ctx)) goto l1438; goto l1439; + l1438:; ctx->pos= yypos1438; ctx->thunkpos= yythunkpos1438; + } + l1439:; + l1440:; + { int yypos1441= ctx->pos, yythunkpos1441= ctx->thunkpos; if (!yymatchChar(ctx, '#')) goto l1441; goto l1440; + l1441:; ctx->pos= yypos1441; ctx->thunkpos= yythunkpos1441; + } if (!yy_Sp(ctx)) goto l1437; if (!yy_Newline(ctx)) goto l1437; goto l1435; + l1437:; ctx->pos= yypos1437; ctx->thunkpos= yythunkpos1437; + } if (!yy_Inline(ctx)) goto l1435; + yyprintf((stderr, " ok %s @ %s\n", "AtxInline", ctx->buf+ctx->pos)); + return 1; + l1435:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "AtxInline", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Inlines(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 2, 0); + yyprintf((stderr, "%s\n", "Inlines")); if (!yy_StartList(ctx)) goto l1442; yyDo(ctx, yySet, -2, 0); + { int yypos1445= ctx->pos, yythunkpos1445= ctx->thunkpos; + { int yypos1447= ctx->pos, yythunkpos1447= ctx->thunkpos; if (!yy_Endline(ctx)) goto l1447; goto l1446; + l1447:; ctx->pos= yypos1447; ctx->thunkpos= yythunkpos1447; + } if (!yy_Inline(ctx)) goto l1446; yyDo(ctx, yy_1_Inlines, ctx->begin, ctx->end); goto l1445; + l1446:; ctx->pos= yypos1445; ctx->thunkpos= yythunkpos1445; if (!yy_Endline(ctx)) goto l1442; yyDo(ctx, yySet, -1, 0); + { int yypos1448= ctx->pos, yythunkpos1448= ctx->thunkpos; if (!yy_Inline(ctx)) goto l1442; ctx->pos= yypos1448; ctx->thunkpos= yythunkpos1448; + } yyDo(ctx, yy_2_Inlines, ctx->begin, ctx->end); + } + l1445:; + l1443:; + { int yypos1444= ctx->pos, yythunkpos1444= ctx->thunkpos; + { int yypos1449= ctx->pos, yythunkpos1449= ctx->thunkpos; + { int yypos1451= ctx->pos, yythunkpos1451= ctx->thunkpos; if (!yy_Endline(ctx)) goto l1451; goto l1450; + l1451:; ctx->pos= yypos1451; ctx->thunkpos= yythunkpos1451; + } if (!yy_Inline(ctx)) goto l1450; yyDo(ctx, yy_1_Inlines, ctx->begin, ctx->end); goto l1449; + l1450:; ctx->pos= yypos1449; ctx->thunkpos= yythunkpos1449; if (!yy_Endline(ctx)) goto l1444; yyDo(ctx, yySet, -1, 0); + { int yypos1452= ctx->pos, yythunkpos1452= ctx->thunkpos; if (!yy_Inline(ctx)) goto l1444; ctx->pos= yypos1452; ctx->thunkpos= yythunkpos1452; + } yyDo(ctx, yy_2_Inlines, ctx->begin, ctx->end); + } + l1449:; goto l1443; + l1444:; ctx->pos= yypos1444; ctx->thunkpos= yythunkpos1444; + } + { int yypos1453= ctx->pos, yythunkpos1453= ctx->thunkpos; if (!yy_Endline(ctx)) goto l1453; goto l1454; + l1453:; ctx->pos= yypos1453; ctx->thunkpos= yythunkpos1453; + } + l1454:; yyDo(ctx, yy_3_Inlines, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "Inlines", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 2, 0); + return 1; + l1442:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Inlines", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_NonindentSpace(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "NonindentSpace")); + { int yypos1456= ctx->pos, yythunkpos1456= ctx->thunkpos; if (!yymatchString(ctx, " ")) goto l1457; goto l1456; + l1457:; ctx->pos= yypos1456; ctx->thunkpos= yythunkpos1456; if (!yymatchString(ctx, " ")) goto l1458; goto l1456; + l1458:; ctx->pos= yypos1456; ctx->thunkpos= yythunkpos1456; if (!yymatchChar(ctx, ' ')) goto l1459; goto l1456; + l1459:; ctx->pos= yypos1456; ctx->thunkpos= yythunkpos1456; if (!yymatchString(ctx, "")) goto l1455; + } + l1456:; + yyprintf((stderr, " ok %s @ %s\n", "NonindentSpace", ctx->buf+ctx->pos)); + return 1; + l1455:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "NonindentSpace", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Plain(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "Plain")); if (!yy_Inlines(ctx)) goto l1460; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_1_Plain, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "Plain", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 1, 0); + return 1; + l1460:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Plain", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Para(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "Para")); if (!yy_NonindentSpace(ctx)) goto l1461; if (!yy_Inlines(ctx)) goto l1461; yyDo(ctx, yySet, -1, 0); if (!yy_BlankLine(ctx)) goto l1461; + l1462:; + { int yypos1463= ctx->pos, yythunkpos1463= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l1463; goto l1462; + l1463:; ctx->pos= yypos1463; ctx->thunkpos= yythunkpos1463; + } yyDo(ctx, yy_1_Para, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "Para", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 1, 0); + return 1; + l1461:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Para", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_StyleBlock(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "StyleBlock")); yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l1464; if (!yy_InStyleTags(ctx)) goto l1464; yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l1464; + l1465:; + { int yypos1466= ctx->pos, yythunkpos1466= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l1466; goto l1465; + l1466:; ctx->pos= yypos1466; ctx->thunkpos= yythunkpos1466; + } yyDo(ctx, yy_1_StyleBlock, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "StyleBlock", ctx->buf+ctx->pos)); + return 1; + l1464:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "StyleBlock", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HtmlBlock(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HtmlBlock")); yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l1467; + { int yypos1468= ctx->pos, yythunkpos1468= ctx->thunkpos; if (!yy_HtmlBlockInTags(ctx)) goto l1469; goto l1468; + l1469:; ctx->pos= yypos1468; ctx->thunkpos= yythunkpos1468; if (!yy_HtmlComment(ctx)) goto l1470; goto l1468; + l1470:; ctx->pos= yypos1468; ctx->thunkpos= yythunkpos1468; if (!yy_HtmlBlockSelfClosing(ctx)) goto l1467; + } + l1468:; yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l1467; if (!yy_BlankLine(ctx)) goto l1467; + l1471:; + { int yypos1472= ctx->pos, yythunkpos1472= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l1472; goto l1471; + l1472:; ctx->pos= yypos1472; ctx->thunkpos= yythunkpos1472; + } yyDo(ctx, yy_1_HtmlBlock, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "HtmlBlock", ctx->buf+ctx->pos)); + return 1; + l1467:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HtmlBlock", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_BulletList(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "BulletList")); + { int yypos1474= ctx->pos, yythunkpos1474= ctx->thunkpos; if (!yy_Bullet(ctx)) goto l1473; ctx->pos= yypos1474; ctx->thunkpos= yythunkpos1474; + } + { int yypos1475= ctx->pos, yythunkpos1475= ctx->thunkpos; if (!yy_ListTight(ctx)) goto l1476; goto l1475; + l1476:; ctx->pos= yypos1475; ctx->thunkpos= yythunkpos1475; if (!yy_ListLoose(ctx)) goto l1473; + } + l1475:; yyDo(ctx, yy_1_BulletList, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "BulletList", ctx->buf+ctx->pos)); + return 1; + l1473:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "BulletList", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_OrderedList(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "OrderedList")); + { int yypos1478= ctx->pos, yythunkpos1478= ctx->thunkpos; if (!yy_Enumerator(ctx)) goto l1477; ctx->pos= yypos1478; ctx->thunkpos= yythunkpos1478; + } + { int yypos1479= ctx->pos, yythunkpos1479= ctx->thunkpos; if (!yy_ListTight(ctx)) goto l1480; goto l1479; + l1480:; ctx->pos= yypos1479; ctx->thunkpos= yythunkpos1479; if (!yy_ListLoose(ctx)) goto l1477; + } + l1479:; yyDo(ctx, yy_1_OrderedList, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "OrderedList", ctx->buf+ctx->pos)); + return 1; + l1477:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "OrderedList", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Heading(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Heading")); + { int yypos1482= ctx->pos, yythunkpos1482= ctx->thunkpos; if (!yy_SetextHeading(ctx)) goto l1483; goto l1482; + l1483:; ctx->pos= yypos1482; ctx->thunkpos= yythunkpos1482; if (!yy_AtxHeading(ctx)) goto l1481; + } + l1482:; + yyprintf((stderr, " ok %s @ %s\n", "Heading", ctx->buf+ctx->pos)); + return 1; + l1481:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Heading", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_HorizontalRule(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "HorizontalRule")); if (!yy_NonindentSpace(ctx)) goto l1484; + { int yypos1485= ctx->pos, yythunkpos1485= ctx->thunkpos; if (!yymatchChar(ctx, '*')) goto l1486; if (!yy_Sp(ctx)) goto l1486; if (!yymatchChar(ctx, '*')) goto l1486; if (!yy_Sp(ctx)) goto l1486; if (!yymatchChar(ctx, '*')) goto l1486; + l1487:; + { int yypos1488= ctx->pos, yythunkpos1488= ctx->thunkpos; if (!yy_Sp(ctx)) goto l1488; if (!yymatchChar(ctx, '*')) goto l1488; goto l1487; + l1488:; ctx->pos= yypos1488; ctx->thunkpos= yythunkpos1488; + } goto l1485; + l1486:; ctx->pos= yypos1485; ctx->thunkpos= yythunkpos1485; if (!yymatchChar(ctx, '-')) goto l1489; if (!yy_Sp(ctx)) goto l1489; if (!yymatchChar(ctx, '-')) goto l1489; if (!yy_Sp(ctx)) goto l1489; if (!yymatchChar(ctx, '-')) goto l1489; + l1490:; + { int yypos1491= ctx->pos, yythunkpos1491= ctx->thunkpos; if (!yy_Sp(ctx)) goto l1491; if (!yymatchChar(ctx, '-')) goto l1491; goto l1490; + l1491:; ctx->pos= yypos1491; ctx->thunkpos= yythunkpos1491; + } goto l1485; + l1489:; ctx->pos= yypos1485; ctx->thunkpos= yythunkpos1485; if (!yymatchChar(ctx, '_')) goto l1484; if (!yy_Sp(ctx)) goto l1484; if (!yymatchChar(ctx, '_')) goto l1484; if (!yy_Sp(ctx)) goto l1484; if (!yymatchChar(ctx, '_')) goto l1484; + l1492:; + { int yypos1493= ctx->pos, yythunkpos1493= ctx->thunkpos; if (!yy_Sp(ctx)) goto l1493; if (!yymatchChar(ctx, '_')) goto l1493; goto l1492; + l1493:; ctx->pos= yypos1493; ctx->thunkpos= yythunkpos1493; + } + } + l1485:; if (!yy_Sp(ctx)) goto l1484; if (!yy_Newline(ctx)) goto l1484; if (!yy_BlankLine(ctx)) goto l1484; + l1494:; + { int yypos1495= ctx->pos, yythunkpos1495= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l1495; goto l1494; + l1495:; ctx->pos= yypos1495; ctx->thunkpos= yythunkpos1495; + } yyDo(ctx, yy_1_HorizontalRule, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "HorizontalRule", ctx->buf+ctx->pos)); + return 1; + l1484:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "HorizontalRule", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Reference(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 3, 0); + yyprintf((stderr, "%s\n", "Reference")); if (!yy_NonindentSpace(ctx)) goto l1496; + { int yypos1497= ctx->pos, yythunkpos1497= ctx->thunkpos; if (!yymatchString(ctx, "[]")) goto l1497; goto l1496; + l1497:; ctx->pos= yypos1497; ctx->thunkpos= yythunkpos1497; + } if (!yy_Label(ctx)) goto l1496; yyDo(ctx, yySet, -3, 0); if (!yymatchChar(ctx, ':')) goto l1496; if (!yy_Spnl(ctx)) goto l1496; if (!yy_RefSrc(ctx)) goto l1496; yyDo(ctx, yySet, -2, 0); if (!yy_RefTitle(ctx)) goto l1496; yyDo(ctx, yySet, -1, 0); if (!yy_BlankLine(ctx)) goto l1496; + l1498:; + { int yypos1499= ctx->pos, yythunkpos1499= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l1499; goto l1498; + l1499:; ctx->pos= yypos1499; ctx->thunkpos= yythunkpos1499; + } yyDo(ctx, yy_1_Reference, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "Reference", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 3, 0); + return 1; + l1496:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Reference", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Note(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 2, 0); + yyprintf((stderr, "%s\n", "Note")); yyText(ctx, ctx->begin, ctx->end); if (!( extension(EXT_NOTES) )) goto l1500; if (!yy_NonindentSpace(ctx)) goto l1500; if (!yy_RawNoteReference(ctx)) goto l1500; yyDo(ctx, yySet, -2, 0); if (!yymatchChar(ctx, ':')) goto l1500; if (!yy_Sp(ctx)) goto l1500; if (!yy_StartList(ctx)) goto l1500; yyDo(ctx, yySet, -1, 0); if (!yy_RawNoteBlock(ctx)) goto l1500; yyDo(ctx, yy_1_Note, ctx->begin, ctx->end); + l1501:; + { int yypos1502= ctx->pos, yythunkpos1502= ctx->thunkpos; + { int yypos1503= ctx->pos, yythunkpos1503= ctx->thunkpos; if (!yy_Indent(ctx)) goto l1502; ctx->pos= yypos1503; ctx->thunkpos= yythunkpos1503; + } if (!yy_RawNoteBlock(ctx)) goto l1502; yyDo(ctx, yy_2_Note, ctx->begin, ctx->end); goto l1501; + l1502:; ctx->pos= yypos1502; ctx->thunkpos= yythunkpos1502; + } yyDo(ctx, yy_3_Note, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "Note", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 2, 0); + return 1; + l1500:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Note", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Verbatim(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "Verbatim")); if (!yy_StartList(ctx)) goto l1504; yyDo(ctx, yySet, -1, 0); if (!yy_VerbatimChunk(ctx)) goto l1504; yyDo(ctx, yy_1_Verbatim, ctx->begin, ctx->end); + l1505:; + { int yypos1506= ctx->pos, yythunkpos1506= ctx->thunkpos; if (!yy_VerbatimChunk(ctx)) goto l1506; yyDo(ctx, yy_1_Verbatim, ctx->begin, ctx->end); goto l1505; + l1506:; ctx->pos= yypos1506; ctx->thunkpos= yythunkpos1506; + } yyDo(ctx, yy_2_Verbatim, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "Verbatim", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 1, 0); + return 1; + l1504:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Verbatim", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_BlockQuote(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "BlockQuote")); if (!yy_BlockQuoteRaw(ctx)) goto l1507; yyDo(ctx, yySet, -1, 0); yyDo(ctx, yy_1_BlockQuote, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "BlockQuote", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 1, 0); + return 1; + l1507:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "BlockQuote", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_BlankLine(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "BlankLine")); if (!yy_Sp(ctx)) goto l1508; if (!yy_Newline(ctx)) goto l1508; + yyprintf((stderr, " ok %s @ %s\n", "BlankLine", ctx->buf+ctx->pos)); + return 1; + l1508:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "BlankLine", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Block(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "Block")); + l1510:; + { int yypos1511= ctx->pos, yythunkpos1511= ctx->thunkpos; if (!yy_BlankLine(ctx)) goto l1511; goto l1510; + l1511:; ctx->pos= yypos1511; ctx->thunkpos= yythunkpos1511; + } + { int yypos1512= ctx->pos, yythunkpos1512= ctx->thunkpos; if (!yy_BlockQuote(ctx)) goto l1513; goto l1512; + l1513:; ctx->pos= yypos1512; ctx->thunkpos= yythunkpos1512; if (!yy_Verbatim(ctx)) goto l1514; goto l1512; + l1514:; ctx->pos= yypos1512; ctx->thunkpos= yythunkpos1512; if (!yy_Note(ctx)) goto l1515; goto l1512; + l1515:; ctx->pos= yypos1512; ctx->thunkpos= yythunkpos1512; if (!yy_Reference(ctx)) goto l1516; goto l1512; + l1516:; ctx->pos= yypos1512; ctx->thunkpos= yythunkpos1512; if (!yy_HorizontalRule(ctx)) goto l1517; goto l1512; + l1517:; ctx->pos= yypos1512; ctx->thunkpos= yythunkpos1512; if (!yy_Heading(ctx)) goto l1518; goto l1512; + l1518:; ctx->pos= yypos1512; ctx->thunkpos= yythunkpos1512; if (!yy_OrderedList(ctx)) goto l1519; goto l1512; + l1519:; ctx->pos= yypos1512; ctx->thunkpos= yythunkpos1512; if (!yy_BulletList(ctx)) goto l1520; goto l1512; + l1520:; ctx->pos= yypos1512; ctx->thunkpos= yythunkpos1512; if (!yy_HtmlBlock(ctx)) goto l1521; goto l1512; + l1521:; ctx->pos= yypos1512; ctx->thunkpos= yythunkpos1512; if (!yy_StyleBlock(ctx)) goto l1522; goto l1512; + l1522:; ctx->pos= yypos1512; ctx->thunkpos= yythunkpos1512; if (!yy_Para(ctx)) goto l1523; goto l1512; + l1523:; ctx->pos= yypos1512; ctx->thunkpos= yythunkpos1512; if (!yy_Plain(ctx)) goto l1509; + } + l1512:; + yyprintf((stderr, " ok %s @ %s\n", "Block", ctx->buf+ctx->pos)); + return 1; + l1509:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Block", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_StartList(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "StartList")); + { int yypos1525= ctx->pos, yythunkpos1525= ctx->thunkpos; if (!yymatchDot(ctx)) goto l1524; ctx->pos= yypos1525; ctx->thunkpos= yythunkpos1525; + } yyDo(ctx, yy_1_StartList, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "StartList", ctx->buf+ctx->pos)); + return 1; + l1524:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "StartList", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_BOM(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "BOM")); if (!yymatchString(ctx, "\357\273\277")) goto l1526; + yyprintf((stderr, " ok %s @ %s\n", "BOM", ctx->buf+ctx->pos)); + return 1; + l1526:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "BOM", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_Doc(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; yyDo(ctx, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "Doc")); + { int yypos1528= ctx->pos, yythunkpos1528= ctx->thunkpos; if (!yy_BOM(ctx)) goto l1528; goto l1529; + l1528:; ctx->pos= yypos1528; ctx->thunkpos= yythunkpos1528; + } + l1529:; if (!yy_StartList(ctx)) goto l1527; yyDo(ctx, yySet, -1, 0); + l1530:; + { int yypos1531= ctx->pos, yythunkpos1531= ctx->thunkpos; if (!yy_Block(ctx)) goto l1531; yyDo(ctx, yy_1_Doc, ctx->begin, ctx->end); goto l1530; + l1531:; ctx->pos= yypos1531; ctx->thunkpos= yythunkpos1531; + } yyDo(ctx, yy_2_Doc, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "Doc", ctx->buf+ctx->pos)); yyDo(ctx, yyPop, 1, 0); + return 1; + l1527:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "Doc", ctx->buf+ctx->pos)); + return 0; +} + +#ifndef YY_PART + +typedef int (*yyrule)(yycontext *ctx); + +YY_PARSE(int) YYPARSEFROM(YY_CTX_PARAM_ yyrule yystart) +{ + int yyok; + if (!yyctx->buflen) + { + yyctx->buflen= 1024; + yyctx->buf= (char *)malloc(yyctx->buflen); + yyctx->textlen= 1024; + yyctx->text= (char *)malloc(yyctx->textlen); + yyctx->thunkslen= 32; + yyctx->thunks= (yythunk *)malloc(sizeof(yythunk) * yyctx->thunkslen); + yyctx->valslen= 32; + yyctx->vals= (YYSTYPE *)malloc(sizeof(YYSTYPE) * yyctx->valslen); + yyctx->begin= yyctx->end= yyctx->pos= yyctx->limit= yyctx->thunkpos= 0; + } + yyctx->begin= yyctx->end= yyctx->pos; + yyctx->thunkpos= 0; + yyctx->val= yyctx->vals; + yyok= yystart(yyctx); + if (yyok) yyDone(yyctx); + yyCommit(yyctx); + return yyok; +} + +YY_PARSE(int) YYPARSE(YY_CTX_PARAM) +{ + return YYPARSEFROM(YY_CTX_ARG_ yy_Doc); +} + +#endif + + + + diff --git a/supportlibs/pegmarkdown/markdown_parser.leg b/supportlibs/pegmarkdown/markdown_parser.leg new file mode 100644 index 000000000..cd1fc0b36 --- /dev/null +++ b/supportlibs/pegmarkdown/markdown_parser.leg @@ -0,0 +1,770 @@ +%{ +/********************************************************************** + + markdown_parser.leg - markdown parser in C using a PEG grammar. + (c) 2008 John MacFarlane (jgm at berkeley dot edu). + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License or the MIT + license. See LICENSE for details. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + ***********************************************************************/ + +#include +#include +#include "markdown_peg.h" +#include "utility_functions.h" + + + +/********************************************************************** + + Definitions for leg parser generator. + YY_INPUT is the function the parser calls to get new input. + We take all new input from (static) charbuf. + + ***********************************************************************/ + + + +# define YYSTYPE element * +#ifdef __DEBUG__ +# define YY_DEBUG 1 +#endif + +#define YY_INPUT(buf, result, max_size) \ +{ \ + int yyc; \ + if (charbuf && *charbuf != '\0') { \ + yyc= *charbuf++; \ + } else { \ + yyc= EOF; \ + } \ + result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \ +} + +#define YY_RULE(T) T + + +/********************************************************************** + + PEG grammar and parser actions for markdown syntax. + + ***********************************************************************/ + +%} + +Doc = BOM? a:StartList ( Block { a = cons($$, a); } )* + { parse_result = reverse(a); } + +Block = BlankLine* + ( BlockQuote + | Verbatim + | Note + | Reference + | HorizontalRule + | Heading + | OrderedList + | BulletList + | HtmlBlock + | StyleBlock + | Para + | Plain ) + +Para = NonindentSpace a:Inlines BlankLine+ + { $$ = a; $$->key = PARA; } + +Plain = a:Inlines + { $$ = a; $$->key = PLAIN; } + +AtxInline = !Newline !(Sp? '#'* Sp Newline) Inline + +AtxStart = < ( "######" | "#####" | "####" | "###" | "##" | "#" ) > + { $$ = mk_element(H1 + (strlen(yytext) - 1)); } + +AtxHeading = s:AtxStart Sp? a:StartList ( AtxInline { a = cons($$, a); } )+ (Sp? '#'* Sp)? Newline + { $$ = mk_list(s->key, a); + free(s); } + +SetextHeading = SetextHeading1 | SetextHeading2 + +SetextBottom1 = '='+ Newline + +SetextBottom2 = '-'+ Newline + +SetextHeading1 = &(RawLine SetextBottom1) + a:StartList ( !Endline Inline { a = cons($$, a); } )+ Sp? Newline + SetextBottom1 { $$ = mk_list(H1, a); } + +SetextHeading2 = &(RawLine SetextBottom2) + a:StartList ( !Endline Inline { a = cons($$, a); } )+ Sp? Newline + SetextBottom2 { $$ = mk_list(H2, a); } + +Heading = SetextHeading | AtxHeading + +BlockQuote = a:BlockQuoteRaw + { $$ = mk_element(BLOCKQUOTE); + $$->children = a; + } + +BlockQuoteRaw = a:StartList + (( '>' ' '? Line { a = cons($$, a); } ) + ( !'>' !BlankLine Line { a = cons($$, a); } )* + ( BlankLine { a = cons(mk_str("\n"), a); } )* + )+ + { $$ = mk_str_from_list(a, true); + $$->key = RAW; + } + +NonblankIndentedLine = !BlankLine IndentedLine + +VerbatimChunk = a:StartList + ( BlankLine { a = cons(mk_str("\n"), a); } )* + ( NonblankIndentedLine { a = cons($$, a); } )+ + { $$ = mk_str_from_list(a, false); } + +Verbatim = a:StartList ( VerbatimChunk { a = cons($$, a); } )+ + { $$ = mk_str_from_list(a, false); + $$->key = VERBATIM; } + +HorizontalRule = NonindentSpace + ( '*' Sp '*' Sp '*' (Sp '*')* + | '-' Sp '-' Sp '-' (Sp '-')* + | '_' Sp '_' Sp '_' (Sp '_')*) + Sp Newline BlankLine+ + { $$ = mk_element(HRULE); } + +Bullet = !HorizontalRule NonindentSpace ('+' | '*' | '-') Spacechar+ + +BulletList = &Bullet (ListTight | ListLoose) + { $$->key = BULLETLIST; } + +ListTight = a:StartList + ( ListItemTight { a = cons($$, a); } )+ + BlankLine* !(Bullet | Enumerator) + { $$ = mk_list(LIST, a); } + +ListLoose = a:StartList + ( b:ListItem BlankLine* + { element *li; + li = b->children; + li->contents.str = realloc(li->contents.str, strlen(li->contents.str) + 3); + strcat(li->contents.str, "\n\n"); /* In loose list, \n\n added to end of each element */ + a = cons(b, a); + } )+ + { $$ = mk_list(LIST, a); } + +ListItem = ( Bullet | Enumerator ) + a:StartList + ListBlock { a = cons($$, a); } + ( ListContinuationBlock { a = cons($$, a); } )* + { element *raw; + raw = mk_str_from_list(a, false); + raw->key = RAW; + $$ = mk_element(LISTITEM); + $$->children = raw; + } + +ListItemTight = + ( Bullet | Enumerator ) + a:StartList + ListBlock { a = cons($$, a); } + ( !BlankLine + ListContinuationBlock { a = cons($$, a); } )* + !ListContinuationBlock + { element *raw; + raw = mk_str_from_list(a, false); + raw->key = RAW; + $$ = mk_element(LISTITEM); + $$->children = raw; + } + +ListBlock = a:StartList + !BlankLine Line { a = cons($$, a); } + ( ListBlockLine { a = cons($$, a); } )* + { $$ = mk_str_from_list(a, false); } + +ListContinuationBlock = a:StartList + ( < BlankLine* > + { if (strlen(yytext) == 0) + a = cons(mk_str("\001"), a); /* block separator */ + else + a = cons(mk_str(yytext), a); } ) + ( Indent ListBlock { a = cons($$, a); } )+ + { $$ = mk_str_from_list(a, false); } + +Enumerator = NonindentSpace [0-9]+ '.' Spacechar+ + +OrderedList = &Enumerator (ListTight | ListLoose) + { $$->key = ORDEREDLIST; } + +ListBlockLine = !BlankLine + !( Indent? (Bullet | Enumerator) ) + !HorizontalRule + OptionallyIndentedLine + +# Parsers for different kinds of block-level HTML content. +# This is repetitive due to constraints of PEG grammar. + +HtmlBlockOpenAddress = '<' Spnl ("address" | "ADDRESS") Spnl HtmlAttribute* '>' +HtmlBlockCloseAddress = '<' Spnl '/' ("address" | "ADDRESS") Spnl '>' +HtmlBlockAddress = HtmlBlockOpenAddress (HtmlBlockAddress | !HtmlBlockCloseAddress .)* HtmlBlockCloseAddress + +HtmlBlockOpenBlockquote = '<' Spnl ("blockquote" | "BLOCKQUOTE") Spnl HtmlAttribute* '>' +HtmlBlockCloseBlockquote = '<' Spnl '/' ("blockquote" | "BLOCKQUOTE") Spnl '>' +HtmlBlockBlockquote = HtmlBlockOpenBlockquote (HtmlBlockBlockquote | !HtmlBlockCloseBlockquote .)* HtmlBlockCloseBlockquote + +HtmlBlockOpenCenter = '<' Spnl ("center" | "CENTER") Spnl HtmlAttribute* '>' +HtmlBlockCloseCenter = '<' Spnl '/' ("center" | "CENTER") Spnl '>' +HtmlBlockCenter = HtmlBlockOpenCenter (HtmlBlockCenter | !HtmlBlockCloseCenter .)* HtmlBlockCloseCenter + +HtmlBlockOpenDir = '<' Spnl ("dir" | "DIR") Spnl HtmlAttribute* '>' +HtmlBlockCloseDir = '<' Spnl '/' ("dir" | "DIR") Spnl '>' +HtmlBlockDir = HtmlBlockOpenDir (HtmlBlockDir | !HtmlBlockCloseDir .)* HtmlBlockCloseDir + +HtmlBlockOpenDiv = '<' Spnl ("div" | "DIV") Spnl HtmlAttribute* '>' +HtmlBlockCloseDiv = '<' Spnl '/' ("div" | "DIV") Spnl '>' +HtmlBlockDiv = HtmlBlockOpenDiv (HtmlBlockDiv | !HtmlBlockCloseDiv .)* HtmlBlockCloseDiv + +HtmlBlockOpenDl = '<' Spnl ("dl" | "DL") Spnl HtmlAttribute* '>' +HtmlBlockCloseDl = '<' Spnl '/' ("dl" | "DL") Spnl '>' +HtmlBlockDl = HtmlBlockOpenDl (HtmlBlockDl | !HtmlBlockCloseDl .)* HtmlBlockCloseDl + +HtmlBlockOpenFieldset = '<' Spnl ("fieldset" | "FIELDSET") Spnl HtmlAttribute* '>' +HtmlBlockCloseFieldset = '<' Spnl '/' ("fieldset" | "FIELDSET") Spnl '>' +HtmlBlockFieldset = HtmlBlockOpenFieldset (HtmlBlockFieldset | !HtmlBlockCloseFieldset .)* HtmlBlockCloseFieldset + +HtmlBlockOpenForm = '<' Spnl ("form" | "FORM") Spnl HtmlAttribute* '>' +HtmlBlockCloseForm = '<' Spnl '/' ("form" | "FORM") Spnl '>' +HtmlBlockForm = HtmlBlockOpenForm (HtmlBlockForm | !HtmlBlockCloseForm .)* HtmlBlockCloseForm + +HtmlBlockOpenH1 = '<' Spnl ("h1" | "H1") Spnl HtmlAttribute* '>' +HtmlBlockCloseH1 = '<' Spnl '/' ("h1" | "H1") Spnl '>' +HtmlBlockH1 = HtmlBlockOpenH1 (HtmlBlockH1 | !HtmlBlockCloseH1 .)* HtmlBlockCloseH1 + +HtmlBlockOpenH2 = '<' Spnl ("h2" | "H2") Spnl HtmlAttribute* '>' +HtmlBlockCloseH2 = '<' Spnl '/' ("h2" | "H2") Spnl '>' +HtmlBlockH2 = HtmlBlockOpenH2 (HtmlBlockH2 | !HtmlBlockCloseH2 .)* HtmlBlockCloseH2 + +HtmlBlockOpenH3 = '<' Spnl ("h3" | "H3") Spnl HtmlAttribute* '>' +HtmlBlockCloseH3 = '<' Spnl '/' ("h3" | "H3") Spnl '>' +HtmlBlockH3 = HtmlBlockOpenH3 (HtmlBlockH3 | !HtmlBlockCloseH3 .)* HtmlBlockCloseH3 + +HtmlBlockOpenH4 = '<' Spnl ("h4" | "H4") Spnl HtmlAttribute* '>' +HtmlBlockCloseH4 = '<' Spnl '/' ("h4" | "H4") Spnl '>' +HtmlBlockH4 = HtmlBlockOpenH4 (HtmlBlockH4 | !HtmlBlockCloseH4 .)* HtmlBlockCloseH4 + +HtmlBlockOpenH5 = '<' Spnl ("h5" | "H5") Spnl HtmlAttribute* '>' +HtmlBlockCloseH5 = '<' Spnl '/' ("h5" | "H5") Spnl '>' +HtmlBlockH5 = HtmlBlockOpenH5 (HtmlBlockH5 | !HtmlBlockCloseH5 .)* HtmlBlockCloseH5 + +HtmlBlockOpenH6 = '<' Spnl ("h6" | "H6") Spnl HtmlAttribute* '>' +HtmlBlockCloseH6 = '<' Spnl '/' ("h6" | "H6") Spnl '>' +HtmlBlockH6 = HtmlBlockOpenH6 (HtmlBlockH6 | !HtmlBlockCloseH6 .)* HtmlBlockCloseH6 + +HtmlBlockOpenMenu = '<' Spnl ("menu" | "MENU") Spnl HtmlAttribute* '>' +HtmlBlockCloseMenu = '<' Spnl '/' ("menu" | "MENU") Spnl '>' +HtmlBlockMenu = HtmlBlockOpenMenu (HtmlBlockMenu | !HtmlBlockCloseMenu .)* HtmlBlockCloseMenu + +HtmlBlockOpenNoframes = '<' Spnl ("noframes" | "NOFRAMES") Spnl HtmlAttribute* '>' +HtmlBlockCloseNoframes = '<' Spnl '/' ("noframes" | "NOFRAMES") Spnl '>' +HtmlBlockNoframes = HtmlBlockOpenNoframes (HtmlBlockNoframes | !HtmlBlockCloseNoframes .)* HtmlBlockCloseNoframes + +HtmlBlockOpenNoscript = '<' Spnl ("noscript" | "NOSCRIPT") Spnl HtmlAttribute* '>' +HtmlBlockCloseNoscript = '<' Spnl '/' ("noscript" | "NOSCRIPT") Spnl '>' +HtmlBlockNoscript = HtmlBlockOpenNoscript (HtmlBlockNoscript | !HtmlBlockCloseNoscript .)* HtmlBlockCloseNoscript + +HtmlBlockOpenOl = '<' Spnl ("ol" | "OL") Spnl HtmlAttribute* '>' +HtmlBlockCloseOl = '<' Spnl '/' ("ol" | "OL") Spnl '>' +HtmlBlockOl = HtmlBlockOpenOl (HtmlBlockOl | !HtmlBlockCloseOl .)* HtmlBlockCloseOl + +HtmlBlockOpenP = '<' Spnl ("p" | "P") Spnl HtmlAttribute* '>' +HtmlBlockCloseP = '<' Spnl '/' ("p" | "P") Spnl '>' +HtmlBlockP = HtmlBlockOpenP (HtmlBlockP | !HtmlBlockCloseP .)* HtmlBlockCloseP + +HtmlBlockOpenPre = '<' Spnl ("pre" | "PRE") Spnl HtmlAttribute* '>' +HtmlBlockClosePre = '<' Spnl '/' ("pre" | "PRE") Spnl '>' +HtmlBlockPre = HtmlBlockOpenPre (HtmlBlockPre | !HtmlBlockClosePre .)* HtmlBlockClosePre + +HtmlBlockOpenTable = '<' Spnl ("table" | "TABLE") Spnl HtmlAttribute* '>' +HtmlBlockCloseTable = '<' Spnl '/' ("table" | "TABLE") Spnl '>' +HtmlBlockTable = HtmlBlockOpenTable (HtmlBlockTable | !HtmlBlockCloseTable .)* HtmlBlockCloseTable + +HtmlBlockOpenUl = '<' Spnl ("ul" | "UL") Spnl HtmlAttribute* '>' +HtmlBlockCloseUl = '<' Spnl '/' ("ul" | "UL") Spnl '>' +HtmlBlockUl = HtmlBlockOpenUl (HtmlBlockUl | !HtmlBlockCloseUl .)* HtmlBlockCloseUl + +HtmlBlockOpenDd = '<' Spnl ("dd" | "DD") Spnl HtmlAttribute* '>' +HtmlBlockCloseDd = '<' Spnl '/' ("dd" | "DD") Spnl '>' +HtmlBlockDd = HtmlBlockOpenDd (HtmlBlockDd | !HtmlBlockCloseDd .)* HtmlBlockCloseDd + +HtmlBlockOpenDt = '<' Spnl ("dt" | "DT") Spnl HtmlAttribute* '>' +HtmlBlockCloseDt = '<' Spnl '/' ("dt" | "DT") Spnl '>' +HtmlBlockDt = HtmlBlockOpenDt (HtmlBlockDt | !HtmlBlockCloseDt .)* HtmlBlockCloseDt + +HtmlBlockOpenFrameset = '<' Spnl ("frameset" | "FRAMESET") Spnl HtmlAttribute* '>' +HtmlBlockCloseFrameset = '<' Spnl '/' ("frameset" | "FRAMESET") Spnl '>' +HtmlBlockFrameset = HtmlBlockOpenFrameset (HtmlBlockFrameset | !HtmlBlockCloseFrameset .)* HtmlBlockCloseFrameset + +HtmlBlockOpenLi = '<' Spnl ("li" | "LI") Spnl HtmlAttribute* '>' +HtmlBlockCloseLi = '<' Spnl '/' ("li" | "LI") Spnl '>' +HtmlBlockLi = HtmlBlockOpenLi (HtmlBlockLi | !HtmlBlockCloseLi .)* HtmlBlockCloseLi + +HtmlBlockOpenTbody = '<' Spnl ("tbody" | "TBODY") Spnl HtmlAttribute* '>' +HtmlBlockCloseTbody = '<' Spnl '/' ("tbody" | "TBODY") Spnl '>' +HtmlBlockTbody = HtmlBlockOpenTbody (HtmlBlockTbody | !HtmlBlockCloseTbody .)* HtmlBlockCloseTbody + +HtmlBlockOpenTd = '<' Spnl ("td" | "TD") Spnl HtmlAttribute* '>' +HtmlBlockCloseTd = '<' Spnl '/' ("td" | "TD") Spnl '>' +HtmlBlockTd = HtmlBlockOpenTd (HtmlBlockTd | !HtmlBlockCloseTd .)* HtmlBlockCloseTd + +HtmlBlockOpenTfoot = '<' Spnl ("tfoot" | "TFOOT") Spnl HtmlAttribute* '>' +HtmlBlockCloseTfoot = '<' Spnl '/' ("tfoot" | "TFOOT") Spnl '>' +HtmlBlockTfoot = HtmlBlockOpenTfoot (HtmlBlockTfoot | !HtmlBlockCloseTfoot .)* HtmlBlockCloseTfoot + +HtmlBlockOpenTh = '<' Spnl ("th" | "TH") Spnl HtmlAttribute* '>' +HtmlBlockCloseTh = '<' Spnl '/' ("th" | "TH") Spnl '>' +HtmlBlockTh = HtmlBlockOpenTh (HtmlBlockTh | !HtmlBlockCloseTh .)* HtmlBlockCloseTh + +HtmlBlockOpenThead = '<' Spnl ("thead" | "THEAD") Spnl HtmlAttribute* '>' +HtmlBlockCloseThead = '<' Spnl '/' ("thead" | "THEAD") Spnl '>' +HtmlBlockThead = HtmlBlockOpenThead (HtmlBlockThead | !HtmlBlockCloseThead .)* HtmlBlockCloseThead + +HtmlBlockOpenTr = '<' Spnl ("tr" | "TR") Spnl HtmlAttribute* '>' +HtmlBlockCloseTr = '<' Spnl '/' ("tr" | "TR") Spnl '>' +HtmlBlockTr = HtmlBlockOpenTr (HtmlBlockTr | !HtmlBlockCloseTr .)* HtmlBlockCloseTr + +HtmlBlockOpenScript = '<' Spnl ("script" | "SCRIPT") Spnl HtmlAttribute* '>' +HtmlBlockCloseScript = '<' Spnl '/' ("script" | "SCRIPT") Spnl '>' +HtmlBlockScript = HtmlBlockOpenScript (!HtmlBlockCloseScript .)* HtmlBlockCloseScript + + +HtmlBlockInTags = HtmlBlockAddress + | HtmlBlockBlockquote + | HtmlBlockCenter + | HtmlBlockDir + | HtmlBlockDiv + | HtmlBlockDl + | HtmlBlockFieldset + | HtmlBlockForm + | HtmlBlockH1 + | HtmlBlockH2 + | HtmlBlockH3 + | HtmlBlockH4 + | HtmlBlockH5 + | HtmlBlockH6 + | HtmlBlockMenu + | HtmlBlockNoframes + | HtmlBlockNoscript + | HtmlBlockOl + | HtmlBlockP + | HtmlBlockPre + | HtmlBlockTable + | HtmlBlockUl + | HtmlBlockDd + | HtmlBlockDt + | HtmlBlockFrameset + | HtmlBlockLi + | HtmlBlockTbody + | HtmlBlockTd + | HtmlBlockTfoot + | HtmlBlockTh + | HtmlBlockThead + | HtmlBlockTr + | HtmlBlockScript + +HtmlBlock = < ( HtmlBlockInTags | HtmlComment | HtmlBlockSelfClosing ) > + BlankLine+ + { if (extension(EXT_FILTER_HTML)) { + $$ = mk_list(LIST, NULL); + } else { + $$ = mk_str(yytext); + $$->key = HTMLBLOCK; + } + } + +HtmlBlockSelfClosing = '<' Spnl HtmlBlockType Spnl HtmlAttribute* '/' Spnl '>' + +HtmlBlockType = "address" | "blockquote" | "center" | "dir" | "div" | "dl" | "fieldset" | "form" | "h1" | "h2" | "h3" | + "h4" | "h5" | "h6" | "hr" | "isindex" | "menu" | "noframes" | "noscript" | "ol" | "p" | "pre" | "table" | + "ul" | "dd" | "dt" | "frameset" | "li" | "tbody" | "td" | "tfoot" | "th" | "thead" | "tr" | "script" | + "ADDRESS" | "BLOCKQUOTE" | "CENTER" | "DIR" | "DIV" | "DL" | "FIELDSET" | "FORM" | "H1" | "H2" | "H3" | + "H4" | "H5" | "H6" | "HR" | "ISINDEX" | "MENU" | "NOFRAMES" | "NOSCRIPT" | "OL" | "P" | "PRE" | "TABLE" | + "UL" | "DD" | "DT" | "FRAMESET" | "LI" | "TBODY" | "TD" | "TFOOT" | "TH" | "THEAD" | "TR" | "SCRIPT" + +StyleOpen = '<' Spnl ("style" | "STYLE") Spnl HtmlAttribute* '>' +StyleClose = '<' Spnl '/' ("style" | "STYLE") Spnl '>' +InStyleTags = StyleOpen (!StyleClose .)* StyleClose +StyleBlock = < InStyleTags > + BlankLine* + { if (extension(EXT_FILTER_STYLES)) { + $$ = mk_list(LIST, NULL); + } else { + $$ = mk_str(yytext); + $$->key = HTMLBLOCK; + } + } + +Inlines = a:StartList ( !Endline Inline { a = cons($$, a); } + | c:Endline &Inline { a = cons(c, a); } )+ Endline? + { $$ = mk_list(LIST, a); } + +Inline = Str + | Endline + | UlOrStarLine + | Space + | Strong + | Emph + | Image + | Link + | NoteReference + | InlineNote + | Code + | RawHtml + | Entity + | EscapedChar + | Smart + | Symbol + +Space = Spacechar+ + { $$ = mk_str(" "); + $$->key = SPACE; } + +Str = a:StartList < NormalChar+ > { a = cons(mk_str(yytext), a); } + ( StrChunk { a = cons($$, a); } )* + { if (a->next == NULL) { $$ = a; } else { $$ = mk_list(LIST, a); } } + +StrChunk = < (NormalChar | '_'+ &Alphanumeric)+ > { $$ = mk_str(yytext); } | + AposChunk + +AposChunk = &{ extension(EXT_SMART) } '\'' &Alphanumeric + { $$ = mk_element(APOSTROPHE); } + +EscapedChar = '\\' !Newline < [-\\`|*_{}[\]()#+.!><] > + { $$ = mk_str(yytext); } + +Entity = ( HexEntity | DecEntity | CharEntity ) + { $$ = mk_str(yytext); $$->key = HTML; } + +Endline = LineBreak | TerminalEndline | NormalEndline + +NormalEndline = Sp Newline !BlankLine !'>' !AtxStart + !(Line ('='+ | '-'+) Newline) + { $$ = mk_str("\n"); + $$->key = SPACE; } + +TerminalEndline = Sp Newline Eof + { $$ = NULL; } + +LineBreak = " " NormalEndline + { $$ = mk_element(LINEBREAK); } + +Symbol = < SpecialChar > + { $$ = mk_str(yytext); } + +# This keeps the parser from getting bogged down on long strings of '*' or '_', +# or strings of '*' or '_' with space on each side: +UlOrStarLine = (UlLine | StarLine) { $$ = mk_str(yytext); } +StarLine = < "****" '*'* > | < Spacechar '*'+ &Spacechar > +UlLine = < "____" '_'* > | < Spacechar '_'+ &Spacechar > + +Emph = EmphStar | EmphUl + +Whitespace = Spacechar | Newline + +EmphStar = '*' !Whitespace + a:StartList + ( !'*' b:Inline { a = cons(b, a); } + | b:StrongStar { a = cons(b, a); } + )+ + '*' + { $$ = mk_list(EMPH, a); } + +EmphUl = '_' !Whitespace + a:StartList + ( !'_' b:Inline { a = cons(b, a); } + | b:StrongUl { a = cons(b, a); } + )+ + '_' + { $$ = mk_list(EMPH, a); } + +Strong = StrongStar | StrongUl + +StrongStar = "**" !Whitespace + a:StartList + ( !"**" b:Inline { a = cons(b, a); })+ + "**" + { $$ = mk_list(STRONG, a); } + +StrongUl = "__" !Whitespace + a:StartList + ( !"__" b:Inline { a = cons(b, a); })+ + "__" + { $$ = mk_list(STRONG, a); } + +Image = '!' ( ExplicitLink | ReferenceLink ) + { if ($$->key == LINK) { + $$->key = IMAGE; + } else { + element *result; + result = $$; + $$->children = cons(mk_str("!"), result->children); + } } + +Link = ExplicitLink | ReferenceLink | AutoLink + +ReferenceLink = ReferenceLinkDouble | ReferenceLinkSingle + +ReferenceLinkDouble = a:Label < Spnl > !"[]" b:Label + { link match; + if (find_reference(&match, b->children)) { + $$ = mk_link(a->children, match.url, match.title); + free(a); + free_element_list(b); + } else { + element *result; + result = mk_element(LIST); + result->children = cons(mk_str("["), cons(a, cons(mk_str("]"), cons(mk_str(yytext), + cons(mk_str("["), cons(b, mk_str("]"))))))); + $$ = result; + } + } + +ReferenceLinkSingle = a:Label < (Spnl "[]")? > + { link match; + if (find_reference(&match, a->children)) { + $$ = mk_link(a->children, match.url, match.title); + free(a); + } + else { + element *result; + result = mk_element(LIST); + result->children = cons(mk_str("["), cons(a, cons(mk_str("]"), mk_str(yytext)))); + $$ = result; + } + } + +ExplicitLink = l:Label '(' Sp s:Source Spnl t:Title Sp ')' + { $$ = mk_link(l->children, s->contents.str, t->contents.str); + free_element(s); + free_element(t); + free(l); } + +Source = ( '<' < SourceContents > '>' | < SourceContents > ) + { $$ = mk_str(yytext); } + +SourceContents = ( ( !'(' !')' !'>' Nonspacechar )+ | '(' SourceContents ')')* + +Title = ( TitleSingle | TitleDouble | < "" > ) + { $$ = mk_str(yytext); } + +TitleSingle = '\'' < ( !( '\'' Sp ( ')' | Newline ) ) . )* > '\'' + +TitleDouble = '"' < ( !( '"' Sp ( ')' | Newline ) ) . )* > '"' + +AutoLink = AutoLinkUrl | AutoLinkEmail + +AutoLinkUrl = '<' < [A-Za-z]+ "://" ( !Newline !'>' . )+ > '>' + { $$ = mk_link(mk_str(yytext), yytext, ""); } + +AutoLinkEmail = '<' ( "mailto:" )? < [-A-Za-z0-9+_./!%~$]+ '@' ( !Newline !'>' . )+ > '>' + { char *mailto = malloc(strlen(yytext) + 8); + sprintf(mailto, "mailto:%s", yytext); + $$ = mk_link(mk_str(yytext), mailto, ""); + free(mailto); + } + +Reference = NonindentSpace !"[]" l:Label ':' Spnl s:RefSrc t:RefTitle BlankLine+ + { $$ = mk_link(l->children, s->contents.str, t->contents.str); + free_element(s); + free_element(t); + free(l); + $$->key = REFERENCE; } + +Label = '[' ( !'^' &{ extension(EXT_NOTES) } | &. &{ !extension(EXT_NOTES) } ) + a:StartList + ( !']' Inline { a = cons($$, a); } )* + ']' + { $$ = mk_list(LIST, a); } + +RefSrc = < Nonspacechar+ > + { $$ = mk_str(yytext); + $$->key = HTML; } + +RefTitle = ( RefTitleSingle | RefTitleDouble | RefTitleParens | EmptyTitle ) + { $$ = mk_str(yytext); } + +EmptyTitle = < "" > + +RefTitleSingle = Spnl '\'' < ( !( '\'' Sp Newline | Newline ) . )* > '\'' + +RefTitleDouble = Spnl '"' < ( !('"' Sp Newline | Newline) . )* > '"' + +RefTitleParens = Spnl '(' < ( !(')' Sp Newline | Newline) . )* > ')' + +References = a:StartList + ( b:Reference { a = cons(b, a); } | SkipBlock )* + { references = reverse(a); } + +Ticks1 = "`" !'`' +Ticks2 = "``" !'`' +Ticks3 = "```" !'`' +Ticks4 = "````" !'`' +Ticks5 = "`````" !'`' + +Code = ( Ticks1 Sp < ( ( !'`' Nonspacechar )+ | !Ticks1 '`'+ | !( Sp Ticks1 ) ( Spacechar | Newline !BlankLine ) )+ > Sp Ticks1 + | Ticks2 Sp < ( ( !'`' Nonspacechar )+ | !Ticks2 '`'+ | !( Sp Ticks2 ) ( Spacechar | Newline !BlankLine ) )+ > Sp Ticks2 + | Ticks3 Sp < ( ( !'`' Nonspacechar )+ | !Ticks3 '`'+ | !( Sp Ticks3 ) ( Spacechar | Newline !BlankLine ) )+ > Sp Ticks3 + | Ticks4 Sp < ( ( !'`' Nonspacechar )+ | !Ticks4 '`'+ | !( Sp Ticks4 ) ( Spacechar | Newline !BlankLine ) )+ > Sp Ticks4 + | Ticks5 Sp < ( ( !'`' Nonspacechar )+ | !Ticks5 '`'+ | !( Sp Ticks5 ) ( Spacechar | Newline !BlankLine ) )+ > Sp Ticks5 + ) + { $$ = mk_str(yytext); $$->key = CODE; } + +RawHtml = < (HtmlComment | HtmlBlockScript | HtmlTag) > + { if (extension(EXT_FILTER_HTML)) { + $$ = mk_list(LIST, NULL); + } else { + $$ = mk_str(yytext); + $$->key = HTML; + } + } + +BlankLine = Sp Newline + +Quoted = '"' (!'"' .)* '"' | '\'' (!'\'' .)* '\'' +HtmlAttribute = (AlphanumericAscii | '-')+ Spnl ('=' Spnl (Quoted | (!'>' Nonspacechar)+))? Spnl +HtmlComment = "" .)* "-->" +HtmlTag = '<' Spnl '/'? AlphanumericAscii+ Spnl HtmlAttribute* '/'? Spnl '>' +Eof = !. +Spacechar = ' ' | '\t' +Nonspacechar = !Spacechar !Newline . +Newline = '\n' | '\r' '\n'? +Sp = Spacechar* +Spnl = Sp (Newline Sp)? +SpecialChar = '*' | '_' | '`' | '&' | '[' | ']' | '(' | ')' | '<' | '!' | '#' | '\\' | '\'' | '"' | ExtendedSpecialChar +NormalChar = !( SpecialChar | Spacechar | Newline ) . +Alphanumeric = [0-9A-Za-z] | '\200' | '\201' | '\202' | '\203' | '\204' | '\205' | '\206' | '\207' | '\210' | '\211' | '\212' | '\213' | '\214' | '\215' | '\216' | '\217' | '\220' | '\221' | '\222' | '\223' | '\224' | '\225' | '\226' | '\227' | '\230' | '\231' | '\232' | '\233' | '\234' | '\235' | '\236' | '\237' | '\240' | '\241' | '\242' | '\243' | '\244' | '\245' | '\246' | '\247' | '\250' | '\251' | '\252' | '\253' | '\254' | '\255' | '\256' | '\257' | '\260' | '\261' | '\262' | '\263' | '\264' | '\265' | '\266' | '\267' | '\270' | '\271' | '\272' | '\273' | '\274' | '\275' | '\276' | '\277' | '\300' | '\301' | '\302' | '\303' | '\304' | '\305' | '\306' | '\307' | '\310' | '\311' | '\312' | '\313' | '\314' | '\315' | '\316' | '\317' | '\320' | '\321' | '\322' | '\323' | '\324' | '\325' | '\326' | '\327' | '\330' | '\331' | '\332' | '\333' | '\334' | '\335' | '\336' | '\337' | '\340' | '\341' | '\342' | '\343' | '\344' | '\345' | '\346' | '\347' | '\350' | '\351' | '\352' | '\353' | '\354' | '\355' | '\356' | '\357' | '\360' | '\361' | '\362' | '\363' | '\364' | '\365' | '\366' | '\367' | '\370' | '\371' | '\372' | '\373' | '\374' | '\375' | '\376' | '\377' +AlphanumericAscii = [A-Za-z0-9] +Digit = [0-9] +BOM = "\357\273\277" + +HexEntity = < '&' '#' [Xx] [0-9a-fA-F]+ ';' > +DecEntity = < '&' '#' [0-9]+ > ';' > +CharEntity = < '&' [A-Za-z0-9]+ ';' > + +NonindentSpace = " " | " " | " " | "" +Indent = "\t" | " " +IndentedLine = Indent Line +OptionallyIndentedLine = Indent? Line + +# StartList starts a list data structure that can be added to with cons: +StartList = &. + { $$ = NULL; } + +Line = RawLine + { $$ = mk_str(yytext); } +RawLine = ( < (!'\r' !'\n' .)* Newline > | < .+ > Eof ) + +SkipBlock = HtmlBlock + | ( !'#' !SetextBottom1 !SetextBottom2 !BlankLine RawLine )+ BlankLine* + | BlankLine+ + | RawLine + +# Syntax extensions + +ExtendedSpecialChar = &{ extension(EXT_SMART) } ('.' | '-' | '\'' | '"') + | &{ extension(EXT_NOTES) } ( '^' ) + +Smart = &{ extension(EXT_SMART) } + ( Ellipsis | Dash | SingleQuoted | DoubleQuoted | Apostrophe ) + +Apostrophe = '\'' + { $$ = mk_element(APOSTROPHE); } + +Ellipsis = ("..." | ". . .") + { $$ = mk_element(ELLIPSIS); } + +Dash = EmDash | EnDash + +EnDash = '-' &Digit + { $$ = mk_element(ENDASH); } + +EmDash = ("---" | "--") + { $$ = mk_element(EMDASH); } + +SingleQuoteStart = '\'' !(Spacechar | Newline) + +SingleQuoteEnd = '\'' !Alphanumeric + +SingleQuoted = SingleQuoteStart + a:StartList + ( !SingleQuoteEnd b:Inline { a = cons(b, a); } )+ + SingleQuoteEnd + { $$ = mk_list(SINGLEQUOTED, a); } + +DoubleQuoteStart = '"' + +DoubleQuoteEnd = '"' + +DoubleQuoted = DoubleQuoteStart + a:StartList + ( !DoubleQuoteEnd b:Inline { a = cons(b, a); } )+ + DoubleQuoteEnd + { $$ = mk_list(DOUBLEQUOTED, a); } + +NoteReference = &{ extension(EXT_NOTES) } + ref:RawNoteReference + { element *match; + if (find_note(&match, ref->contents.str)) { + $$ = mk_element(NOTE); + assert(match->children != NULL); + $$->children = match->children; + $$->contents.str = 0; + } else { + char *s; + s = malloc(strlen(ref->contents.str) + 4); + sprintf(s, "[^%s]", ref->contents.str); + $$ = mk_str(s); + free(s); + } + } + +RawNoteReference = "[^" < ( !Newline !']' . )+ > ']' + { $$ = mk_str(yytext); } + +Note = &{ extension(EXT_NOTES) } + NonindentSpace ref:RawNoteReference ':' Sp + a:StartList + ( RawNoteBlock { a = cons($$, a); } ) + ( &Indent RawNoteBlock { a = cons($$, a); } )* + { $$ = mk_list(NOTE, a); + $$->contents.str = strdup(ref->contents.str); + } + +InlineNote = &{ extension(EXT_NOTES) } + "^[" + a:StartList + ( !']' Inline { a = cons($$, a); } )+ + ']' + { $$ = mk_list(NOTE, a); + $$->contents.str = 0; } + +Notes = a:StartList + ( b:Note { a = cons(b, a); } | SkipBlock )* + { notes = reverse(a); } + +RawNoteBlock = a:StartList + ( !BlankLine OptionallyIndentedLine { a = cons($$, a); } )+ + ( < BlankLine* > { a = cons(mk_str(yytext), a); } ) + { $$ = mk_str_from_list(a, true); + $$->key = RAW; + } + +%% + + diff --git a/supportlibs/pegmarkdown/markdown_peg.h b/supportlibs/pegmarkdown/markdown_peg.h new file mode 100644 index 000000000..c78d7e2cb --- /dev/null +++ b/supportlibs/pegmarkdown/markdown_peg.h @@ -0,0 +1,72 @@ +/* markdown_peg.h */ +#ifndef MARKDOWN_PEG_H +#define MARKDOWN_PEG_H + +#include "markdown_lib.h" +#include + +/* Information (label, URL and title) for a link. */ +struct Link { + struct Element *label; + char *url; + char *title; +}; + +typedef struct Link link; + +/* Union for contents of an Element (string, list, or link). */ +union Contents { + char *str; + struct Link *link; +}; + +/* Types of semantic values returned by parsers. */ +enum keys { LIST, /* A generic list of values. For ordered and bullet lists, see below. */ + RAW, /* Raw markdown to be processed further */ + SPACE, + LINEBREAK, + ELLIPSIS, + EMDASH, + ENDASH, + APOSTROPHE, + SINGLEQUOTED, + DOUBLEQUOTED, + STR, + LINK, + IMAGE, + CODE, + HTML, + EMPH, + STRONG, + PLAIN, + PARA, + LISTITEM, + BULLETLIST, + ORDEREDLIST, + H1, H2, H3, H4, H5, H6, /* Code assumes that these are in order. */ + BLOCKQUOTE, + VERBATIM, + HTMLBLOCK, + HRULE, + REFERENCE, + NOTE + }; + +/* Semantic value of a parsing action. */ +struct Element { + int key; + union Contents contents; + struct Element *children; + struct Element *next; +}; + +typedef struct Element element; + +element * parse_references(char *string, int extensions); +element * parse_notes(char *string, int extensions, element *reference_list); +element * parse_markdown(char *string, int extensions, element *reference_list, element *note_list); +void free_element_list(element * elt); +void free_element(element *elt); +void print_element_list(GString *out, element *elt, int format, int exts); + +#endif diff --git a/supportlibs/pegmarkdown/odf.c b/supportlibs/pegmarkdown/odf.c new file mode 100644 index 000000000..46265f20a --- /dev/null +++ b/supportlibs/pegmarkdown/odf.c @@ -0,0 +1,181 @@ +/********************************************************************** + + odf.c - Utility routines to enable ODF support in peg-multimarkdown. + (c) 2011 Fletcher T. Penney (http://fletcherpenney.net/). + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License or the MIT + license. See LICENSE for details. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + ***********************************************************************/ + +#include "odf.h" + + +void print_odf_header(GString *out){ + + /* Insert required XML header */ + g_string_append_printf(out, +"\n" \ +"\n"); + + /* Font Declarations */ + g_string_append_printf(out, "\n" \ + " \n" \ + "\n"); + + /* Append basic style information */ + g_string_append_printf(out, "\n" \ + "\n" \ + " \n" \ + " \n" \ + "\n" \ + " \n" \ + " \n" \ + "\n" \ + "\n" \ + " \n" \ + "\n" \ + "\n" \ + " \n" \ + " \n" \ + "\n" \ + "\n" \ + " \n" \ + "\n" \ + "\n" \ + " \n" \ + " \n" \ + "\n" \ + "\n" \ + " \n" \ + " \n" \ + "\n" \ + "\n"); + + /* Automatic style information */ + g_string_append_printf(out, "" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + "\n" \ + " \n" \ + "\n" \ + "\n" \ + " \n" \ + "\n" \ + "\n" \ + " \n" \ + "\n" \ + "\n" \ + "\n" \ + "\n" \ + "\n" \ + " \n" \ + "\n" \ + "\n" \ + "\n" \ + "\n" \ + " \n" \ + "\n" \ + "\n" \ + " \n" \ + "\n"); +} + +void print_odf_footer(GString *out) { + g_string_append_printf(out, "\n\n"); +} + diff --git a/supportlibs/pegmarkdown/odf.h b/supportlibs/pegmarkdown/odf.h new file mode 100644 index 000000000..d5bdc8860 --- /dev/null +++ b/supportlibs/pegmarkdown/odf.h @@ -0,0 +1,11 @@ +#ifndef ODF_H +#define ODF_H + +#include +#include +#include + +void print_odf_header(GString *out); +void print_odf_footer(GString *out); +#endif + diff --git a/supportlibs/pegmarkdown/parsing_functions.c b/supportlibs/pegmarkdown/parsing_functions.c new file mode 100644 index 000000000..81fd9e26f --- /dev/null +++ b/supportlibs/pegmarkdown/parsing_functions.c @@ -0,0 +1,117 @@ +/* parsing_functions.c - Functions for parsing markdown and + * freeing element lists. */ + +/* These yy_* functions come from markdown_parser.c which is + * generated from markdown_parser.leg + * */ +typedef int (*yyrule)(); + +extern int yyparse(); +extern int yyparsefrom(yyrule); +extern int yy_References(); +extern int yy_Notes(); +extern int yy_Doc(); + +#include "utility_functions.h" +#include "parsing_functions.h" +#include "markdown_peg.h" + +static void free_element_contents(element elt); + +/* free_element_list - free list of elements recursively */ +void free_element_list(element * elt) { + element * next = NULL; + while (elt != NULL) { + next = elt->next; + free_element_contents(*elt); + if (elt->children != NULL) { + free_element_list(elt->children); + elt->children = NULL; + } + free(elt); + elt = next; + } +} + +/* free_element_contents - free element contents depending on type */ +static void free_element_contents(element elt) { + switch (elt.key) { + case STR: + case SPACE: + case RAW: + case HTMLBLOCK: + case HTML: + case VERBATIM: + case CODE: + case NOTE: + free(elt.contents.str); + elt.contents.str = NULL; + break; + case LINK: + case IMAGE: + case REFERENCE: + free(elt.contents.link->url); + elt.contents.link->url = NULL; + free(elt.contents.link->title); + elt.contents.link->title = NULL; + free_element_list(elt.contents.link->label); + free(elt.contents.link); + elt.contents.link = NULL; + break; + default: + ; + } +} + +/* free_element - free element and contents */ +void free_element(element *elt) { + free_element_contents(*elt); + free(elt); +} + +element * parse_references(char *string, int extensions) { + + char *oldcharbuf; + syntax_extensions = extensions; + + oldcharbuf = charbuf; + charbuf = string; + yyparsefrom(yy_References); /* first pass, just to collect references */ + charbuf = oldcharbuf; + + return references; +} + +element * parse_notes(char *string, int extensions, element *reference_list) { + + char *oldcharbuf; + notes = NULL; + syntax_extensions = extensions; + + if (extension(EXT_NOTES)) { + references = reference_list; + oldcharbuf = charbuf; + charbuf = string; + yyparsefrom(yy_Notes); /* second pass for notes */ + charbuf = oldcharbuf; + } + + return notes; +} + +element * parse_markdown(char *string, int extensions, element *reference_list, element *note_list) { + + char *oldcharbuf; + syntax_extensions = extensions; + references = reference_list; + notes = note_list; + + oldcharbuf = charbuf; + charbuf = string; + + yyparsefrom(yy_Doc); + + charbuf = oldcharbuf; /* restore charbuf to original value */ + return parse_result; + +} diff --git a/supportlibs/pegmarkdown/parsing_functions.h b/supportlibs/pegmarkdown/parsing_functions.h new file mode 100644 index 000000000..d7b7ff426 --- /dev/null +++ b/supportlibs/pegmarkdown/parsing_functions.h @@ -0,0 +1,17 @@ +#ifndef PARSING_FUNCTIONS_H +#define PARSING_FUNCTIONS_H +/* parsing_functions.c - Functions for parsing markdown and + * freeing element lists. */ + +#include "markdown_peg.h" + +/* free_element_list - free list of elements recursively */ +void free_element_list(element * elt); +/* free_element - free element and contents */ +void free_element(element *elt); + +element * parse_references(char *string, int extensions); +element * parse_notes(char *string, int extensions, element *reference_list); +element * parse_markdown(char *string, int extensions, element *reference_list, element *note_list); + +#endif diff --git a/supportlibs/pegmarkdown/peg-0.1.9/Makefile b/supportlibs/pegmarkdown/peg-0.1.9/Makefile new file mode 100644 index 000000000..c10fbda83 --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/Makefile @@ -0,0 +1,65 @@ +CFLAGS = -g -Wall $(OFLAGS) $(XFLAGS) +OFLAGS = -O3 -DNDEBUG +#OFLAGS = -pg + +OBJS = tree.o compile.o + +all : peg leg + +peg : peg.o $(OBJS) + $(CC) $(CFLAGS) -o $@-new peg.o $(OBJS) + mv $@-new $@ + +leg : leg.o $(OBJS) + $(CC) $(CFLAGS) -o $@-new leg.o $(OBJS) + mv $@-new $@ + +ROOT = +PREFIX = /usr/local +BINDIR = $(ROOT)$(PREFIX)/bin + +install : $(BINDIR)/peg $(BINDIR)/leg + +$(BINDIR)/% : % + cp -p $< $@ + strip $@ + +uninstall : .FORCE + rm -f $(BINDIR)/peg + rm -f $(BINDIR)/leg + +peg.o : peg.c peg.peg-c + +%.peg-c : %.peg compile.c + ./peg -o $@ $< + +leg.o : leg.c + +leg.c : leg.leg compile.c + ./leg -o $@ $< + +check : check-peg check-leg + +check-peg : peg .FORCE + ./peg < peg.peg > peg.out + diff peg.peg-c peg.out + rm peg.out + +check-leg : leg .FORCE + ./leg < leg.leg > leg.out + diff leg.c leg.out + rm leg.out + +test examples : .FORCE + $(SHELL) -ec '(cd examples; $(MAKE))' + +clean : .FORCE + rm -f *~ *.o *.peg.[cd] *.leg.[cd] + $(SHELL) -ec '(cd examples; $(MAKE) $@)' + +spotless : clean .FORCE + rm -f peg + rm -f leg + $(SHELL) -ec '(cd examples; $(MAKE) $@)' + +.FORCE : diff --git a/supportlibs/pegmarkdown/peg-0.1.9/compile.c b/supportlibs/pegmarkdown/peg-0.1.9/compile.c new file mode 100644 index 000000000..74506b762 --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/compile.c @@ -0,0 +1,717 @@ +/* Copyright (c) 2007, 2012 by Ian Piumarta + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the 'Software'), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, provided that the above copyright notice(s) and this + * permission notice appear in all copies of the Software. Acknowledgement + * of the use of this Software in supporting documentation would be + * appreciated but is not required. + * + * THE SOFTWARE IS PROVIDED 'AS IS'. USE ENTIRELY AT YOUR OWN RISK. + * + * Last edited: 2012-04-29 16:09:36 by piumarta on emilia + */ + +#include +#include +#include +#include + +#include "version.h" +#include "tree.h" + +static int yyl(void) +{ + static int prev= 0; + return ++prev; +} + +static void charClassSet (unsigned char bits[], int c) { bits[c >> 3] |= (1 << (c & 7)); } +static void charClassClear(unsigned char bits[], int c) { bits[c >> 3] &= ~(1 << (c & 7)); } + +typedef void (*setter)(unsigned char bits[], int c); + +static inline int oigit(int c) { return '0' <= c && c <= '7'; } + +static int cnext(unsigned char **ccp) +{ + unsigned char *cclass= *ccp; + int c= *cclass++; + if (c) + { + if ('\\' == c && *cclass) + { + switch (c= *cclass++) + { + case 'a': c= '\a'; break; /* bel */ + case 'b': c= '\b'; break; /* bs */ + case 'e': c= '\e'; break; /* esc */ + case 'f': c= '\f'; break; /* ff */ + case 'n': c= '\n'; break; /* nl */ + case 'r': c= '\r'; break; /* cr */ + case 't': c= '\t'; break; /* ht */ + case 'v': c= '\v'; break; /* vt */ + default: + if (oigit(c)) + { + c -= '0'; + if (oigit(*cclass)) c= (c << 3) + *cclass++ - '0'; + if (oigit(*cclass)) c= (c << 3) + *cclass++ - '0'; + } + break; + } + } + *ccp= cclass; + } + return c; +} + +static char *makeCharClass(unsigned char *cclass) +{ + unsigned char bits[32]; + setter set; + int c, prev= -1; + static char string[256]; + char *ptr; + + if ('^' == *cclass) + { + memset(bits, 255, 32); + set= charClassClear; + ++cclass; + } + else + { + memset(bits, 0, 32); + set= charClassSet; + } + + while (*cclass) + { + if ('-' == *cclass && cclass[1] && prev >= 0) + { + ++cclass; + for (c= cnext(&cclass); prev <= c; ++prev) + set(bits, prev); + prev= -1; + } + else + { + c= cnext(&cclass); + set(bits, prev= c); + } + } + + ptr= string; + for (c= 0; c < 32; ++c) + ptr += sprintf(ptr, "\\%03o", bits[c]); + + return string; +} + +static void begin(void) { fprintf(output, "\n {"); } +static void end(void) { fprintf(output, "\n }"); } +static void label(int n) { fprintf(output, "\n l%d:;\t", n); } +static void jump(int n) { fprintf(output, " goto l%d;", n); } +static void save(int n) { fprintf(output, " int yypos%d= ctx->pos, yythunkpos%d= ctx->thunkpos;", n, n); } +static void restore(int n) { fprintf(output, " ctx->pos= yypos%d; ctx->thunkpos= yythunkpos%d;", n, n); } + +static void Node_compile_c_ko(Node *node, int ko) +{ + assert(node); + switch (node->type) + { + case Rule: + fprintf(stderr, "\ninternal error #1 (%s)\n", node->rule.name); + exit(1); + break; + + case Dot: + fprintf(output, " if (!yymatchDot(ctx)) goto l%d;", ko); + break; + + case Name: + fprintf(output, " if (!yy_%s(ctx)) goto l%d;", node->name.rule->rule.name, ko); + if (node->name.variable) + fprintf(output, " yyDo(ctx, yySet, %d, 0);", node->name.variable->variable.offset); + break; + + case Character: + case String: + { + int len= strlen(node->string.value); + if (1 == len) + { + if ('\'' == node->string.value[0]) + fprintf(output, " if (!yymatchChar(ctx, '\\'')) goto l%d;", ko); + else + fprintf(output, " if (!yymatchChar(ctx, '%s')) goto l%d;", node->string.value, ko); + } + else + if (2 == len && '\\' == node->string.value[0]) + fprintf(output, " if (!yymatchChar(ctx, '%s')) goto l%d;", node->string.value, ko); + else + fprintf(output, " if (!yymatchString(ctx, \"%s\")) goto l%d;", node->string.value, ko); + } + break; + + case Class: + fprintf(output, " if (!yymatchClass(ctx, (unsigned char *)\"%s\")) goto l%d;", makeCharClass(node->cclass.value), ko); + break; + + case Action: + fprintf(output, " yyDo(ctx, yy%s, ctx->begin, ctx->end);", node->action.name); + break; + + case Predicate: + fprintf(output, " yyText(ctx, ctx->begin, ctx->end); if (!(%s)) goto l%d;", node->action.text, ko); + break; + + case Alternate: + { + int ok= yyl(); + begin(); + save(ok); + for (node= node->alternate.first; node; node= node->alternate.next) + if (node->alternate.next) + { + int next= yyl(); + Node_compile_c_ko(node, next); + jump(ok); + label(next); + restore(ok); + } + else + Node_compile_c_ko(node, ko); + end(); + label(ok); + } + break; + + case Sequence: + for (node= node->sequence.first; node; node= node->sequence.next) + Node_compile_c_ko(node, ko); + break; + + case PeekFor: + { + int ok= yyl(); + begin(); + save(ok); + Node_compile_c_ko(node->peekFor.element, ko); + restore(ok); + end(); + } + break; + + case PeekNot: + { + int ok= yyl(); + begin(); + save(ok); + Node_compile_c_ko(node->peekFor.element, ok); + jump(ko); + label(ok); + restore(ok); + end(); + } + break; + + case Query: + { + int qko= yyl(), qok= yyl(); + begin(); + save(qko); + Node_compile_c_ko(node->query.element, qko); + jump(qok); + label(qko); + restore(qko); + end(); + label(qok); + } + break; + + case Star: + { + int again= yyl(), out= yyl(); + label(again); + begin(); + save(out); + Node_compile_c_ko(node->star.element, out); + jump(again); + label(out); + restore(out); + end(); + } + break; + + case Plus: + { + int again= yyl(), out= yyl(); + Node_compile_c_ko(node->plus.element, ko); + label(again); + begin(); + save(out); + Node_compile_c_ko(node->plus.element, out); + jump(again); + label(out); + restore(out); + end(); + } + break; + + default: + fprintf(stderr, "\nNode_compile_c_ko: illegal node type %d\n", node->type); + exit(1); + } +} + + +static int countVariables(Node *node) +{ + int count= 0; + while (node) + { + ++count; + node= node->variable.next; + } + return count; +} + +static void defineVariables(Node *node) +{ + int count= 0; + while (node) + { + fprintf(output, "#define %s ctx->val[%d]\n", node->variable.name, --count); + node->variable.offset= count; + node= node->variable.next; + } + fprintf(output, "#define yy ctx->yy\n"); + fprintf(output, "#define yypos ctx->pos\n"); + fprintf(output, "#define yythunkpos ctx->thunkpos\n"); +} + +static void undefineVariables(Node *node) +{ + fprintf(output, "#undef yythunkpos\n"); + fprintf(output, "#undef yypos\n"); + fprintf(output, "#undef yy\n"); + while (node) + { + fprintf(output, "#undef %s\n", node->variable.name); + node= node->variable.next; + } +} + + +static void Rule_compile_c2(Node *node) +{ + assert(node); + assert(Rule == node->type); + + if (!node->rule.expression) + fprintf(stderr, "rule '%s' used but not defined\n", node->rule.name); + else + { + int ko= yyl(), safe; + + if ((!(RuleUsed & node->rule.flags)) && (node != start)) + fprintf(stderr, "rule '%s' defined but not used\n", node->rule.name); + + safe= ((Query == node->rule.expression->type) || (Star == node->rule.expression->type)); + + fprintf(output, "\nYY_RULE(int) yy_%s(yycontext *ctx)\n{", node->rule.name); + if (!safe) save(0); + if (node->rule.variables) + fprintf(output, " yyDo(ctx, yyPush, %d, 0);", countVariables(node->rule.variables)); + fprintf(output, "\n yyprintf((stderr, \"%%s\\n\", \"%s\"));", node->rule.name); + Node_compile_c_ko(node->rule.expression, ko); + fprintf(output, "\n yyprintf((stderr, \" ok %%s @ %%s\\n\", \"%s\", ctx->buf+ctx->pos));", node->rule.name); + if (node->rule.variables) + fprintf(output, " yyDo(ctx, yyPop, %d, 0);", countVariables(node->rule.variables)); + fprintf(output, "\n return 1;"); + if (!safe) + { + label(ko); + restore(0); + fprintf(output, "\n yyprintf((stderr, \" fail %%s @ %%s\\n\", \"%s\", ctx->buf+ctx->pos));", node->rule.name); + fprintf(output, "\n return 0;"); + } + fprintf(output, "\n}"); + } + + if (node->rule.next) + Rule_compile_c2(node->rule.next); +} + +static char *header= "\ +#include \n\ +#include \n\ +#include \n\ +"; + +static char *preamble= "\ +#ifndef YY_LOCAL\n\ +#define YY_LOCAL(T) static T\n\ +#endif\n\ +#ifndef YY_ACTION\n\ +#define YY_ACTION(T) static T\n\ +#endif\n\ +#ifndef YY_RULE\n\ +#define YY_RULE(T) static T\n\ +#endif\n\ +#ifndef YY_PARSE\n\ +#define YY_PARSE(T) T\n\ +#endif\n\ +#ifndef YYPARSE\n\ +#define YYPARSE yyparse\n\ +#endif\n\ +#ifndef YYPARSEFROM\n\ +#define YYPARSEFROM yyparsefrom\n\ +#endif\n\ +#ifndef YY_INPUT\n\ +#define YY_INPUT(buf, result, max_size) \\\n\ + { \\\n\ + int yyc= getchar(); \\\n\ + result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \\\n\ + yyprintf((stderr, \"<%c>\", yyc)); \\\n\ + }\n\ +#endif\n\ +#ifndef YY_BEGIN\n\ +#define YY_BEGIN ( ctx->begin= ctx->pos, 1)\n\ +#endif\n\ +#ifndef YY_END\n\ +#define YY_END ( ctx->end= ctx->pos, 1)\n\ +#endif\n\ +#ifdef YY_DEBUG\n\ +# define yyprintf(args) fprintf args\n\ +#else\n\ +# define yyprintf(args)\n\ +#endif\n\ +#ifndef YYSTYPE\n\ +#define YYSTYPE int\n\ +#endif\n\ +\n\ +#ifndef YY_PART\n\ +\n\ +typedef struct _yycontext yycontext;\n\ +typedef void (*yyaction)(yycontext *ctx, char *yytext, int yyleng);\n\ +typedef struct _yythunk { int begin, end; yyaction action; struct _yythunk *next; } yythunk;\n\ +\n\ +struct _yycontext {\n\ + char *buf;\n\ + int buflen;\n\ + int pos;\n\ + int limit;\n\ + char *text;\n\ + int textlen;\n\ + int begin;\n\ + int end;\n\ + int textmax;\n\ + yythunk *thunks;\n\ + int thunkslen;\n\ + int thunkpos;\n\ + YYSTYPE yy;\n\ + YYSTYPE *val;\n\ + YYSTYPE *vals;\n\ + int valslen;\n\ +#ifdef YY_CTX_MEMBERS\n\ + YY_CTX_MEMBERS\n\ +#endif\n\ +};\n\ +\n\ +#ifdef YY_CTX_LOCAL\n\ +#define YY_CTX_PARAM_ yycontext *yyctx,\n\ +#define YY_CTX_PARAM yycontext *yyctx\n\ +#define YY_CTX_ARG_ yyctx,\n\ +#define YY_CTX_ARG yyctx\n\ +#else\n\ +#define YY_CTX_PARAM_\n\ +#define YY_CTX_PARAM\n\ +#define YY_CTX_ARG_\n\ +#define YY_CTX_ARG\n\ +yycontext yyctx0;\n\ +yycontext *yyctx= &yyctx0;\n\ +#endif\n\ +\n\ +YY_LOCAL(int) yyrefill(yycontext *ctx)\n\ +{\n\ + int yyn;\n\ + while (ctx->buflen - ctx->pos < 512)\n\ + {\n\ + ctx->buflen *= 2;\n\ + ctx->buf= (char *)realloc(ctx->buf, ctx->buflen);\n\ + }\n\ + YY_INPUT((ctx->buf + ctx->pos), yyn, (ctx->buflen - ctx->pos));\n\ + if (!yyn) return 0;\n\ + ctx->limit += yyn;\n\ + return 1;\n\ +}\n\ +\n\ +YY_LOCAL(int) yymatchDot(yycontext *ctx)\n\ +{\n\ + if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0;\n\ + ++ctx->pos;\n\ + return 1;\n\ +}\n\ +\n\ +YY_LOCAL(int) yymatchChar(yycontext *ctx, int c)\n\ +{\n\ + if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0;\n\ + if ((unsigned char)ctx->buf[ctx->pos] == c)\n\ + {\n\ + ++ctx->pos;\n\ + yyprintf((stderr, \" ok yymatchChar(ctx, %c) @ %s\\n\", c, ctx->buf+ctx->pos));\n\ + return 1;\n\ + }\n\ + yyprintf((stderr, \" fail yymatchChar(ctx, %c) @ %s\\n\", c, ctx->buf+ctx->pos));\n\ + return 0;\n\ +}\n\ +\n\ +YY_LOCAL(int) yymatchString(yycontext *ctx, char *s)\n\ +{\n\ + int yysav= ctx->pos;\n\ + while (*s)\n\ + {\n\ + if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0;\n\ + if (ctx->buf[ctx->pos] != *s)\n\ + {\n\ + ctx->pos= yysav;\n\ + return 0;\n\ + }\n\ + ++s;\n\ + ++ctx->pos;\n\ + }\n\ + return 1;\n\ +}\n\ +\n\ +YY_LOCAL(int) yymatchClass(yycontext *ctx, unsigned char *bits)\n\ +{\n\ + int c;\n\ + if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0;\n\ + c= (unsigned char)ctx->buf[ctx->pos];\n\ + if (bits[c >> 3] & (1 << (c & 7)))\n\ + {\n\ + ++ctx->pos;\n\ + yyprintf((stderr, \" ok yymatchClass @ %s\\n\", ctx->buf+ctx->pos));\n\ + return 1;\n\ + }\n\ + yyprintf((stderr, \" fail yymatchClass @ %s\\n\", ctx->buf+ctx->pos));\n\ + return 0;\n\ +}\n\ +\n\ +YY_LOCAL(void) yyDo(yycontext *ctx, yyaction action, int begin, int end)\n\ +{\n\ + while (ctx->thunkpos >= ctx->thunkslen)\n\ + {\n\ + ctx->thunkslen *= 2;\n\ + ctx->thunks= (yythunk *)realloc(ctx->thunks, sizeof(yythunk) * ctx->thunkslen);\n\ + }\n\ + ctx->thunks[ctx->thunkpos].begin= begin;\n\ + ctx->thunks[ctx->thunkpos].end= end;\n\ + ctx->thunks[ctx->thunkpos].action= action;\n\ + ++ctx->thunkpos;\n\ +}\n\ +\n\ +YY_LOCAL(int) yyText(yycontext *ctx, int begin, int end)\n\ +{\n\ + int yyleng= end - begin;\n\ + if (yyleng <= 0)\n\ + yyleng= 0;\n\ + else\n\ + {\n\ + while (ctx->textlen < (yyleng + 1))\n\ + {\n\ + ctx->textlen *= 2;\n\ + ctx->text= (char *)realloc(ctx->text, ctx->textlen);\n\ + }\n\ + memcpy(ctx->text, ctx->buf + begin, yyleng);\n\ + }\n\ + ctx->text[yyleng]= '\\0';\n\ + return yyleng;\n\ +}\n\ +\n\ +YY_LOCAL(void) yyDone(yycontext *ctx)\n\ +{\n\ + int pos;\n\ + for (pos= 0; pos < ctx->thunkpos; ++pos)\n\ + {\n\ + yythunk *thunk= &ctx->thunks[pos];\n\ + int yyleng= thunk->end ? yyText(ctx, thunk->begin, thunk->end) : thunk->begin;\n\ + yyprintf((stderr, \"DO [%d] %p %s\\n\", pos, thunk->action, ctx->text));\n\ + thunk->action(ctx, ctx->text, yyleng);\n\ + }\n\ + ctx->thunkpos= 0;\n\ +}\n\ +\n\ +YY_LOCAL(void) yyCommit(yycontext *ctx)\n\ +{\n\ + if ((ctx->limit -= ctx->pos))\n\ + {\n\ + memmove(ctx->buf, ctx->buf + ctx->pos, ctx->limit);\n\ + }\n\ + ctx->begin -= ctx->pos;\n\ + ctx->end -= ctx->pos;\n\ + ctx->pos= ctx->thunkpos= 0;\n\ +}\n\ +\n\ +YY_LOCAL(int) yyAccept(yycontext *ctx, int tp0)\n\ +{\n\ + if (tp0)\n\ + {\n\ + fprintf(stderr, \"accept denied at %d\\n\", tp0);\n\ + return 0;\n\ + }\n\ + else\n\ + {\n\ + yyDone(ctx);\n\ + yyCommit(ctx);\n\ + }\n\ + return 1;\n\ +}\n\ +\n\ +YY_LOCAL(void) yyPush(yycontext *ctx, char *text, int count) { ctx->val += count; }\n\ +YY_LOCAL(void) yyPop(yycontext *ctx, char *text, int count) { ctx->val -= count; }\n\ +YY_LOCAL(void) yySet(yycontext *ctx, char *text, int count) { ctx->val[count]= ctx->yy; }\n\ +\n\ +#endif /* YY_PART */\n\ +\n\ +#define YYACCEPT yyAccept(ctx, yythunkpos0)\n\ +\n\ +"; + +static char *footer= "\n\ +\n\ +#ifndef YY_PART\n\ +\n\ +typedef int (*yyrule)(yycontext *ctx);\n\ +\n\ +YY_PARSE(int) YYPARSEFROM(YY_CTX_PARAM_ yyrule yystart)\n\ +{\n\ + int yyok;\n\ + if (!yyctx->buflen)\n\ + {\n\ + yyctx->buflen= 1024;\n\ + yyctx->buf= (char *)malloc(yyctx->buflen);\n\ + yyctx->textlen= 1024;\n\ + yyctx->text= (char *)malloc(yyctx->textlen);\n\ + yyctx->thunkslen= 32;\n\ + yyctx->thunks= (yythunk *)malloc(sizeof(yythunk) * yyctx->thunkslen);\n\ + yyctx->valslen= 32;\n\ + yyctx->vals= (YYSTYPE *)malloc(sizeof(YYSTYPE) * yyctx->valslen);\n\ + yyctx->begin= yyctx->end= yyctx->pos= yyctx->limit= yyctx->thunkpos= 0;\n\ + }\n\ + yyctx->begin= yyctx->end= yyctx->pos;\n\ + yyctx->thunkpos= 0;\n\ + yyctx->val= yyctx->vals;\n\ + yyok= yystart(yyctx);\n\ + if (yyok) yyDone(yyctx);\n\ + yyCommit(yyctx);\n\ + return yyok;\n\ +}\n\ +\n\ +YY_PARSE(int) YYPARSE(YY_CTX_PARAM)\n\ +{\n\ + return YYPARSEFROM(YY_CTX_ARG_ yy_%s);\n\ +}\n\ +\n\ +#endif\n\ +"; + +void Rule_compile_c_header(void) +{ + fprintf(output, "/* A recursive-descent parser generated by peg %d.%d.%d */\n", PEG_MAJOR, PEG_MINOR, PEG_LEVEL); + fprintf(output, "\n"); + fprintf(output, "%s", header); + fprintf(output, "#define YYRULECOUNT %d\n", ruleCount); +} + +int consumesInput(Node *node) +{ + if (!node) return 0; + + switch (node->type) + { + case Rule: + { + int result= 0; + if (RuleReached & node->rule.flags) + fprintf(stderr, "possible infinite left recursion in rule '%s'\n", node->rule.name); + else + { + node->rule.flags |= RuleReached; + result= consumesInput(node->rule.expression); + node->rule.flags &= ~RuleReached; + } + return result; + } + break; + + case Dot: return 1; + case Name: return consumesInput(node->name.rule); + case Character: + case String: return strlen(node->string.value) > 0; + case Class: return 1; + case Action: return 0; + case Predicate: return 0; + + case Alternate: + { + Node *n; + for (n= node->alternate.first; n; n= n->alternate.next) + if (!consumesInput(n)) + return 0; + } + return 1; + + case Sequence: + { + Node *n; + for (n= node->alternate.first; n; n= n->alternate.next) + if (consumesInput(n)) + return 1; + } + return 0; + + case PeekFor: return 0; + case PeekNot: return 0; + case Query: return 0; + case Star: return 0; + case Plus: return consumesInput(node->plus.element); + + default: + fprintf(stderr, "\nconsumesInput: illegal node type %d\n", node->type); + exit(1); + } + return 0; +} + + +void Rule_compile_c(Node *node) +{ + Node *n; + + for (n= rules; n; n= n->rule.next) + consumesInput(n); + + fprintf(output, "%s", preamble); + for (n= node; n; n= n->rule.next) + fprintf(output, "YY_RULE(int) yy_%s(yycontext *ctx); /* %d */\n", n->rule.name, n->rule.id); + fprintf(output, "\n"); + for (n= actions; n; n= n->action.list) + { + fprintf(output, "YY_ACTION(void) yy%s(yycontext *ctx, char *yytext, int yyleng)\n{\n", n->action.name); + defineVariables(n->action.rule->rule.variables); + fprintf(output, " yyprintf((stderr, \"do yy%s\\n\"));\n", n->action.name); + fprintf(output, " %s;\n", n->action.text); + undefineVariables(n->action.rule->rule.variables); + fprintf(output, "}\n"); + } + Rule_compile_c2(node); + fprintf(output, footer, start->rule.name); +} diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/Makefile b/supportlibs/pegmarkdown/peg-0.1.9/examples/Makefile new file mode 100644 index 000000000..30d3cc8f8 --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/Makefile @@ -0,0 +1,88 @@ +EXAMPLES = test rule accept wc dc dcv calc basic localctx + +CFLAGS = -g -O3 + +DIFF = diff +TEE = cat > + +all : $(EXAMPLES) + +test : .FORCE + ../peg -o test.peg.c test.peg + $(CC) $(CFLAGS) -o test test.c + echo 'ab.ac.ad.ae.afg.afh.afg.afh.afi.afj.' | ./$@ | $(TEE) $@.out + $(DIFF) $@.ref $@.out + rm -f $@.out + @echo + +rule : .FORCE + ../peg -o rule.peg.c rule.peg + $(CC) $(CFLAGS) -o rule rule.c + echo 'abcbcdabcbcdabcbcdabcbcd' | ./$@ | $(TEE) $@.out + $(DIFF) $@.ref $@.out + rm -f $@.out + @echo + +accept : .FORCE + ../peg -o accept.peg.c accept.peg + $(CC) $(CFLAGS) -o accept accept.c + echo 'abcbcdabcbcdabcbcdabcbcd' | ./$@ | $(TEE) $@.out + $(DIFF) $@.ref $@.out + rm -f $@.out + @echo + +wc : .FORCE + ../leg -o wc.leg.c wc.leg + $(CC) $(CFLAGS) -o wc wc.leg.c + cat wc.leg | ./$@ | $(TEE) $@.out + $(DIFF) $@.ref $@.out + rm -f $@.out + @echo + +dc : .FORCE + ../peg -o dc.peg.c dc.peg + $(CC) $(CFLAGS) -o dc dc.c + echo ' 2 *3 *(3+ 4) ' | ./dc | $(TEE) $@.out + $(DIFF) $@.ref $@.out + rm -f $@.out + @echo + +dcv : .FORCE + ../peg -o dcv.peg.c dcv.peg + $(CC) $(CFLAGS) -o dcv dcv.c + echo 'a = 6; b = 7; a * b' | ./dcv | $(TEE) $@.out + $(DIFF) $@.ref $@.out + rm -f $@.out + @echo + +calc : .FORCE + ../leg -o calc.leg.c calc.leg + $(CC) $(CFLAGS) -o calc calc.leg.c + echo 'a = 6; b = 7; a * b' | ./calc | $(TEE) $@.out + $(DIFF) $@.ref $@.out + rm -f $@.out + @echo + +basic : .FORCE + ../leg -o basic.leg.c basic.leg + $(CC) $(CFLAGS) -o basic basic.leg.c + ( echo 'load "test"'; echo "run" ) | ./basic | $(TEE) $@.out + $(DIFF) $@.ref $@.out + rm -f $@.out + @echo + +localctx : .FORCE + ../peg -o test.peg.c test.peg + $(CC) $(CFLAGS) -o localctx localctx.c + echo 'ab.ac.ad.ae.afg.afh.afg.afh.afi.afj.' | ./$@ | $(TEE) $@.out + $(DIFF) $@.ref $@.out + rm -f $@.out + @echo + +clean : .FORCE + rm -f *~ *.o *.[pl]eg.[cd] $(EXAMPLES) + rm -rf *.dSYM + +spotless : clean + +.FORCE : diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/accept.c b/supportlibs/pegmarkdown/peg-0.1.9/examples/accept.c new file mode 100644 index 000000000..781e3b11d --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/accept.c @@ -0,0 +1,11 @@ +#include +#include + +#include "accept.peg.c" + +int main() +{ + while (yyparse()); + + return 0; +} diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/accept.peg b/supportlibs/pegmarkdown/peg-0.1.9/examples/accept.peg new file mode 100644 index 000000000..9b28e4040 --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/accept.peg @@ -0,0 +1,8 @@ +start <- abcd+ + +abcd <- 'a' { printf("A %d\n", yypos); } bc { printf("ABC %d\n", yypos); } &{YYACCEPT} + / 'b' { printf("B %d\n", yypos); } cd { printf("BCD %d\n", yypos); } &{YYACCEPT} + +bc <- 'b' { printf("B %d\n", yypos); } 'c' { printf("C %d\n", yypos); } + +cd <- 'c' { printf("C %d\n", yypos); } 'd' { printf("D %d\n", yypos); } diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/accept.ref b/supportlibs/pegmarkdown/peg-0.1.9/examples/accept.ref new file mode 100644 index 000000000..789f52830 --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/accept.ref @@ -0,0 +1,32 @@ +A 3 +B 3 +C 3 +ABC 3 +B 3 +C 3 +D 3 +BCD 3 +A 3 +B 3 +C 3 +ABC 3 +B 3 +C 3 +D 3 +BCD 3 +A 3 +B 3 +C 3 +ABC 3 +B 3 +C 3 +D 3 +BCD 3 +A 3 +B 3 +C 3 +ABC 3 +B 3 +C 3 +D 3 +BCD 3 diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/basic.leg b/supportlibs/pegmarkdown/peg-0.1.9/examples/basic.leg new file mode 100644 index 000000000..ed38a8d71 --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/basic.leg @@ -0,0 +1,361 @@ +# A 'syntax-directed interpreter' (all execution is a side-effect of parsing). +# Inspired by Dennis Allison's original Tiny BASIC grammar, circa 1975. +# +# Copyright (c) 2007 by Ian Piumarta +# All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the 'Software'), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, provided that the above copyright notice(s) and this +# permission notice appear in all copies of the Software. Acknowledgement +# of the use of this Software in supporting documentation would be +# appreciated but is not required. +# +# THE SOFTWARE IS PROVIDED 'AS IS'. USE ENTIRELY AT YOUR OWN RISK. +# +# Last edited: 2012-04-29 15:14:06 by piumarta on emilia + +%{ +# include + + typedef struct line line; + + struct line + { + int number; + int length; + char *text; + }; + + line *lines= 0; + int numLines= 0; + int pc= -1, epc= -1; + int batch= 0; + + int nextline(char *buf, int max); + +# define min(x, y) ((x) < (y) ? (x) : (y)) + +# define YY_INPUT(buf, result, max_size) \ + { \ + if ((pc >= 0) && (pc < numLines)) \ + { \ + line *linep= lines+pc++; \ + result= min(max_size, linep->length); \ + memcpy(buf, linep->text, result); \ + } \ + else \ + result= nextline(buf, max_size); \ + } + + union value { + int number; + char *string; + int (*binop)(int lhs, int rhs); + }; + +# define YYSTYPE union value + + int variables[26]; + + void accept(int number, char *line); + + void save(char *name); + void load(char *name); + void type(char *name); + + int lessThan(int lhs, int rhs) { return lhs < rhs; } + int lessEqual(int lhs, int rhs) { return lhs <= rhs; } + int notEqual(int lhs, int rhs) { return lhs != rhs; } + int equalTo(int lhs, int rhs) { return lhs == rhs; } + int greaterEqual(int lhs, int rhs) { return lhs >= rhs; } + int greaterThan(int lhs, int rhs) { return lhs > rhs; } + + int input(void); + + int stack[1024], sp= 0; + + char *help; + + void error(char *fmt, ...); + int findLine(int n, int create); +%} + +line = - s:statement CR +| - n:number < ( !CR . )* CR > { accept(n.number, yytext); } +| - CR +| - < ( !CR . )* CR > { epc= pc; error("syntax error"); } +| - !. { exit(0); } + +statement = 'print'- expr-list +| 'if'- e1:expression r:relop e2:expression { if (!r.binop(e1.number, e2.number)) yythunkpos= 0; } + 'then'- statement +| 'goto'- e:expression { epc= pc; if ((pc= findLine(e.number, 0)) < 0) error("no such line"); } +| 'input'- var-list +| 'let'- v:var EQUAL e:expression { variables[v.number]= e.number; } +| 'gosub'- e:expression { epc= pc; if (sp < 1024) stack[sp++]= pc, pc= findLine(e.number, 0); else error("too many gosubs"); + if (pc < 0) error("no such line"); } +| 'return'- { epc= pc; if ((pc= sp ? stack[--sp] : -1) < 0) error("no gosub"); } +| 'clear'- { while (numLines) accept(lines->number, "\n"); } +| 'list'- { int i; for (i= 0; i < numLines; ++i) printf("%5d %s", lines[i].number, lines[i].text); } +| 'run'- s:string { load(s.string); pc= 0; } +| 'run'- { pc= 0; } +| 'end'- { pc= -1; if (batch) exit(0); } +| 'rem'- ( !CR . )* +| ('bye'|'quit'|'exit')- { exit(0); } +| 'save'- s:string { save(s.string); } +| 'load'- s:string { load(s.string); } +| 'type'- s:string { type(s.string); } +| 'dir'- { system("ls *.bas"); } +| 'help'- { fprintf(stderr, "%s", help); } + +expr-list = ( e:string { printf("%s", e.string); } + | e:expression { printf("%d", e.number); } + )? ( COMMA ( e:string { printf("%s", e.string); } + | e:expression { printf("%d", e.number); } + ) + )* ( COMMA + | !COMMA { printf("\n"); } + ) + +var-list = v:var { variables[v.number]= input(); } + ( COMMA v:var { variables[v.number]= input(); } + )* + +expression = ( PLUS? l:term + | MINUS l:term { l.number = -l.number } + ) ( PLUS r:term { l.number += r.number } + | MINUS r:term { l.number -= r.number } + )* { $$.number = l.number } + +term = l:factor ( STAR r:factor { l.number *= r.number } + | SLASH r:factor { l.number /= r.number } + )* { $$.number = l.number } + +factor = v:var { $$.number = variables[v.number] } +| n:number +| OPEN expression CLOSE + +var = < [a-z] > - { $$.number = yytext[0] - 'a' } + +number = < digit+ > - { $$.number = atoi(yytext); } + +digit = [0-9] + +string = '"' < [^\"]* > '"' - { $$.string = yytext; } + +relop = '<=' - { $$.binop= lessEqual; } +| '<>' - { $$.binop= notEqual; } +| '<' - { $$.binop= lessThan; } +| '>=' - { $$.binop= greaterEqual; } +| '>' - { $$.binop= greaterThan; } +| '=' - { $$.binop= equalTo; } + +EQUAL = '=' - CLOSE = ')' - OPEN = '(' - +SLASH = '/' - STAR = '*' - MINUS = '-' - +PLUS = '+' - COMMA = ',' - + +- = [ \t]* + +CR = '\n' | '\r' | '\r\n' + +%% + +#include +#include + +char *help= + "print | [, | ...] [,]\n" + "if <|<=|<>|=|>=|> then \n" + "input [, ...] let = \n" + "goto gosub \n" + "end return\n" + "list clear\n" + "run [\"filename\"] rem \n" + "dir type \"filename\"\n" + "save \"filename\" load \"filename\"\n" + "bye|quit|exit help\n" + ; + +void error(char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + if (epc > 0) + fprintf(stderr, "\nline %d: %s", lines[epc-1].number, lines[epc-1].text); + else + fprintf(stderr, "\n"); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); + epc= pc= -1; +} + +#ifdef USE_READLINE +# include +# include +#endif + +int nextline(char *buf, int max) +{ + pc= -1; + if (batch) exit(0); + if (isatty(fileno(stdin))) + { +# ifdef USE_READLINE + char *line= readline(">"); + if (line) + { + int len= strlen(line); + if (len >= max) len= max - 1; + strncpy(buf, line, len); + (buf)[len]= '\n'; + add_history(line); + free(line); + return len + 1; + } + else + { + printf("\n"); + return 0; + } +# endif + putchar('>'); + fflush(stdout); + } + return fgets(buf, max, stdin) ? strlen(buf) : 0; +} + +int maxLines= 0; + +int findLine(int n, int create) +{ + int lo= 0, hi= numLines - 1; + while (lo <= hi) + { + int mid= (lo + hi) / 2, lno= lines[mid].number; + if (lno > n) + hi= mid - 1; + else if (lno < n) + lo= mid + 1; + else + return mid; + } + if (create) + { + if (numLines == maxLines) + { + maxLines *= 2; + lines= realloc(lines, sizeof(line) * maxLines); + } + if (lo < numLines) + memmove(lines + lo + 1, lines + lo, sizeof(line) * (numLines - lo)); + ++numLines; + lines[lo].number= n; + lines[lo].text= 0; + return lo; + } + return -1; +} + +void accept(int n, char *s) +{ + if (s[0] < 32) /* delete */ + { + int lno= findLine(n, 0); + if (lno >= 0) + { + if (lno < numLines - 1) + memmove(lines + lno, lines + lno + 1, sizeof(line) * (numLines - lno - 1)); + --numLines; + } + } + else /* insert */ + { + int lno= findLine(n, 1); + if (lines[lno].text) free(lines[lno].text); + lines[lno].length= strlen(s); + lines[lno].text= strdup(s); + } +} + +char *extend(char *name) +{ + static char path[1024]; + int len= strlen(name); + sprintf(path, "%s%s", name, (((len > 4) && !strcasecmp(".bas", name + len - 4)) ? "" : ".bas")); + return path; +} + +void save(char *name) +{ + FILE *f= fopen(name= extend(name), "w"); + if (!f) + perror(name); + else + { + int i; + for (i= 0; i < numLines; ++i) + fprintf(f, "%d %s", lines[i].number, lines[i].text); + fclose(f); + } +} + +void load(char *name) +{ + FILE *f= fopen(name= extend(name), "r"); + if (!f) + perror(name); + else + { + int lineNumber; + char lineText[1024]; + while ((1 == fscanf(f, " %d ", &lineNumber)) && fgets(lineText, sizeof(lineText), f)) + accept(lineNumber, lineText); + fclose(f); + } +} + +void type(char *name) +{ + FILE *f= fopen(name= extend(name), "r"); + if (!f) + perror(name); + else + { + int c, d; + while ((c= getc(f)) >= 0) + putchar(d= c); + fclose(f); + if ('\n' != d && '\r' != d) putchar('\n'); + } +} + +int input(void) +{ + char line[32]; + fgets(line, sizeof(line), stdin); + return atoi(line); +} + +int main(int argc, char **argv) +{ + lines= malloc(sizeof(line) * (maxLines= 32)); + numLines= 0; + + if (argc > 1) + { + batch= 1; + while (argc-- > 1) + load(*++argv); + pc= 0; + } + + while (!feof(stdin)) + yyparse(); + + return 0; +} diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/basic.ref b/supportlibs/pegmarkdown/peg-0.1.9/examples/basic.ref new file mode 100644 index 000000000..90d916c89 --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/basic.ref @@ -0,0 +1,10 @@ + 1 + 2 4 + 3 6 9 + 4 8 12 16 + 5 10 15 20 25 + 6 12 18 24 30 36 + 7 14 21 28 35 42 49 + 8 16 24 32 40 48 56 64 + 9 18 27 36 45 54 63 72 81 + 10 20 30 40 50 60 70 80 90 100 diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/bench.bas b/supportlibs/pegmarkdown/peg-0.1.9/examples/bench.bas new file mode 100644 index 000000000..ffdbd44ff --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/bench.bas @@ -0,0 +1,8 @@ +100 let n=100000 +120 let m=0 +110 let s=0 +130 let m=m+1 +140 let s=s+m +150 if m +int vars[26]; +%} + +Stmt = - e:Expr EOL { printf("%d\n", e); } + | ( !EOL . )* EOL { printf("error\n"); } + +Expr = i:ID ASSIGN s:Sum { $$= vars[i]= s; } + | s:Sum { $$= s; } + +Sum = l:Product + ( PLUS r:Product { l += r; } + | MINUS r:Product { l -= r; } + )* { $$= l; } + +Product = l:Value + ( TIMES r:Value { l *= r; } + | DIVIDE r:Value { l /= r; } + )* { $$= l; } + +Value = i:NUMBER { $$= atoi(yytext); } + | i:ID !ASSIGN { $$= vars[i]; } + | OPEN i:Expr CLOSE { $$= i; } + +NUMBER = < [0-9]+ > - { $$= atoi(yytext); } +ID = < [a-z] > - { $$= yytext[0] - 'a'; } +ASSIGN = '=' - +PLUS = '+' - +MINUS = '-' - +TIMES = '*' - +DIVIDE = '/' - +OPEN = '(' - +CLOSE = ')' - + +- = [ \t]* +EOL = '\n' | '\r\n' | '\r' | ';' + +%% + +int main() +{ + while (yyparse()); + + return 0; +} diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/calc.ref b/supportlibs/pegmarkdown/peg-0.1.9/examples/calc.ref new file mode 100644 index 000000000..dbd7d59ec --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/calc.ref @@ -0,0 +1,3 @@ +6 +7 +42 diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/dc.c b/supportlibs/pegmarkdown/peg-0.1.9/examples/dc.c new file mode 100644 index 000000000..32bf1a54a --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/dc.c @@ -0,0 +1,17 @@ +#include +#include + +int stack[1024]; +int stackp= -1; + +int push(int n) { return stack[++stackp]= n; } +int pop(void) { return stack[stackp--]; } + +#include "dc.peg.c" + +int main() +{ + while (yyparse()); + + return 0; +} diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/dc.peg b/supportlibs/pegmarkdown/peg-0.1.9/examples/dc.peg new file mode 100644 index 000000000..75dcb6719 --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/dc.peg @@ -0,0 +1,27 @@ +# Grammar + +Expr <- SPACE Sum EOL { printf("%d\n", pop()); } + / (!EOL .)* EOL { printf("error\n"); } + +Sum <- Product ( PLUS Product { int r= pop(), l= pop(); push(l + r); } + / MINUS Product { int r= pop(), l= pop(); push(l - r); } + )* + +Product <- Value ( TIMES Value { int r= pop(), l= pop(); push(l * r); } + / DIVIDE Value { int r= pop(), l= pop(); push(l / r); } + )* + +Value <- NUMBER { push(atoi(yytext)); } + / OPEN Sum CLOSE + +# Lexemes + +NUMBER <- < [0-9]+ > SPACE +PLUS <- '+' SPACE +MINUS <- '-' SPACE +TIMES <- '*' SPACE +DIVIDE <- '/' SPACE +OPEN <- '(' SPACE +CLOSE <- ')' SPACE +SPACE <- [ \t]* +EOL <- '\n' / '\r\n' / '\r' diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/dc.ref b/supportlibs/pegmarkdown/peg-0.1.9/examples/dc.ref new file mode 100644 index 000000000..d81cc0710 --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/dc.ref @@ -0,0 +1 @@ +42 diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/dcv.c b/supportlibs/pegmarkdown/peg-0.1.9/examples/dcv.c new file mode 100644 index 000000000..0c5c46d85 --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/dcv.c @@ -0,0 +1,20 @@ +#include +#include + +int stack[1024]; +int stackp= -1; +int var= 0; +int vars[26]; + +int push(int n) { return stack[++stackp]= n; } +int pop(void) { return stack[stackp--]; } +int top(void) { return stack[stackp]; } + +#include "dcv.peg.c" + +int main() +{ + while (yyparse()); + + return 0; +} diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/dcv.peg b/supportlibs/pegmarkdown/peg-0.1.9/examples/dcv.peg new file mode 100644 index 000000000..2ae3a8cb0 --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/dcv.peg @@ -0,0 +1,34 @@ +# Grammar + +Stmt <- SPACE Expr EOL { printf("%d\n", pop()); } + / (!EOL .)* EOL { printf("error\n"); } + +Expr <- ID { var= yytext[0] } ASSIGN Sum { vars[var - 'a']= top(); } + / Sum + +Sum <- Product ( PLUS Product { int r= pop(), l= pop(); push(l + r); } + / MINUS Product { int r= pop(), l= pop(); push(l - r); } + )* + +Product <- Value ( TIMES Value { int r= pop(), l= pop(); push(l * r); } + / DIVIDE Value { int r= pop(), l= pop(); push(l / r); } + )* + +Value <- NUMBER { push(atoi(yytext)); } + / < ID > !ASSIGN { push(vars[yytext[0] - 'a']); } + / OPEN Expr CLOSE + +# Lexemes + +NUMBER <- < [0-9]+ > SPACE +ID <- < [a-z] > SPACE +ASSIGN <- '=' SPACE +PLUS <- '+' SPACE +MINUS <- '-' SPACE +TIMES <- '*' SPACE +DIVIDE <- '/' SPACE +OPEN <- '(' SPACE +CLOSE <- ')' SPACE + +SPACE <- [ \t]* +EOL <- '\n' / '\r\n' / '\r' / ';' diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/dcv.ref b/supportlibs/pegmarkdown/peg-0.1.9/examples/dcv.ref new file mode 100644 index 000000000..dbd7d59ec --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/dcv.ref @@ -0,0 +1,3 @@ +6 +7 +42 diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/fibonacci.bas b/supportlibs/pegmarkdown/peg-0.1.9/examples/fibonacci.bas new file mode 100644 index 000000000..1872bd3b2 --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/fibonacci.bas @@ -0,0 +1,17 @@ +100 let n=32 +110 gosub 200 +120 print "fibonacci(",n,") = ", m +130 end + +200 let c=n +210 let b=1 +220 if c<2 then goto 400 +230 let c=c-1 +240 let a=1 +300 let c=c-1 +310 let d=a+b +320 let a=b +330 let b=d+1 +340 if c<>0 then goto 300 +400 let m=b +410 return diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/left.c b/supportlibs/pegmarkdown/peg-0.1.9/examples/left.c new file mode 100644 index 000000000..ac8cd0bd8 --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/left.c @@ -0,0 +1,17 @@ +#include + +#define YY_INPUT(buf, result, max) \ +{ \ + int c= getchar(); \ + result= (EOF == c) ? 0 : (*(buf)= c, 1); \ + if (EOF != c) printf("<%c>\n", c); \ +} + +#include "left.peg.c" + +int main() +{ + printf(yyparse() ? "success\n" : "failure\n"); + + return 0; +} diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/left.peg b/supportlibs/pegmarkdown/peg-0.1.9/examples/left.peg new file mode 100644 index 000000000..f282227d5 --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/left.peg @@ -0,0 +1,3 @@ +# Grammar + +S <- (S 'a' / 'a') !'a' diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/localctx.c b/supportlibs/pegmarkdown/peg-0.1.9/examples/localctx.c new file mode 100644 index 000000000..837ebc884 --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/localctx.c @@ -0,0 +1,13 @@ +#include + +#define YY_CTX_LOCAL + +#include "test.peg.c" + +int main() +{ + yycontext ctx; + memset(&ctx, 0, sizeof(yycontext)); + while (yyparse(&ctx)); + return 0; +} diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/localctx.ref b/supportlibs/pegmarkdown/peg-0.1.9/examples/localctx.ref new file mode 100644 index 000000000..2d181091a --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/localctx.ref @@ -0,0 +1,10 @@ +a1 ab1 . +a2 ac2 . +a3 ad3 . +a3 ae3 . +a4 af4 afg4 . +a4 af5 afh5 . +a4 af4 afg4 . +a4 af5 afh5 . +af6 afi6 a6 . +af6 af7 afj7 a6 . diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/rule.c b/supportlibs/pegmarkdown/peg-0.1.9/examples/rule.c new file mode 100644 index 000000000..15eb0c64b --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/rule.c @@ -0,0 +1,11 @@ +#include +#include + +#include "rule.peg.c" + +int main() +{ + while (yyparse()); + + return 0; +} diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/rule.peg b/supportlibs/pegmarkdown/peg-0.1.9/examples/rule.peg new file mode 100644 index 000000000..60a32faa1 --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/rule.peg @@ -0,0 +1,8 @@ +start <- abcd+ + +abcd <- 'a' { printf("A %d\n", yypos); } bc { printf("ABC %d\n", yypos); } + / 'b' { printf("B %d\n", yypos); } cd { printf("BCD %d\n", yypos); } + +bc <- 'b' { printf("B %d\n", yypos); } 'c' { printf("C %d\n", yypos); } + +cd <- 'c' { printf("C %d\n", yypos); } 'd' { printf("D %d\n", yypos); } diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/rule.ref b/supportlibs/pegmarkdown/peg-0.1.9/examples/rule.ref new file mode 100644 index 000000000..4249ebec5 --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/rule.ref @@ -0,0 +1,32 @@ +A 24 +B 24 +C 24 +ABC 24 +B 24 +C 24 +D 24 +BCD 24 +A 24 +B 24 +C 24 +ABC 24 +B 24 +C 24 +D 24 +BCD 24 +A 24 +B 24 +C 24 +ABC 24 +B 24 +C 24 +D 24 +BCD 24 +A 24 +B 24 +C 24 +ABC 24 +B 24 +C 24 +D 24 +BCD 24 diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/test.bas b/supportlibs/pegmarkdown/peg-0.1.9/examples/test.bas new file mode 100644 index 000000000..8a96e1070 --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/test.bas @@ -0,0 +1,12 @@ +10 let i=1 +20 gosub 100 +30 let i=i+1 +40 if i<=10 then goto 20 +50 end + +100 let j=1 +110 print " ", i*j, +120 let j=j+1 +130 if j<=i then goto 110 +140 print +150 return diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/test.c b/supportlibs/pegmarkdown/peg-0.1.9/examples/test.c new file mode 100644 index 000000000..0403422c3 --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/test.c @@ -0,0 +1,8 @@ +#include +#include "test.peg.c" + +int main() +{ + while (yyparse()); + return 0; +} diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/test.peg b/supportlibs/pegmarkdown/peg-0.1.9/examples/test.peg new file mode 100644 index 000000000..716d52372 --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/test.peg @@ -0,0 +1,13 @@ +start <- body '.' { printf(".\n"); } + +body <- 'a' { printf("a1 "); } 'b' { printf("ab1 "); } + + / 'a' { printf("a2 "); } 'c' { printf("ac2 "); } + + / 'a' { printf("a3 "); } ( 'd' { printf("ad3 "); } / 'e' { printf("ae3 "); } ) + + / 'a' { printf("a4 "); } ( 'f' { printf("af4 "); } 'g' { printf("afg4 "); } + / 'f' { printf("af5 "); } 'h' { printf("afh5 "); } ) + + / 'a' { printf("a6 "); } ( 'f' &{ printf("af6 ") } 'i' &{ printf("afi6 ") } + / 'f' &{ printf("af7 ") } 'j' &{ printf("afj7 ") } ) diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/test.ref b/supportlibs/pegmarkdown/peg-0.1.9/examples/test.ref new file mode 100644 index 000000000..2d181091a --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/test.ref @@ -0,0 +1,10 @@ +a1 ab1 . +a2 ac2 . +a3 ad3 . +a3 ae3 . +a4 af4 afg4 . +a4 af5 afh5 . +a4 af4 afg4 . +a4 af5 afh5 . +af6 afi6 a6 . +af6 af7 afj7 a6 . diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/username.leg b/supportlibs/pegmarkdown/peg-0.1.9/examples/username.leg new file mode 100644 index 000000000..2170052aa --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/username.leg @@ -0,0 +1,14 @@ +%{ +#include +%} + +start = "username" { printf("%s", getlogin()); } +| < . > { putchar(yytext[0]); } + +%% + +int main() +{ + while (yyparse()); + return 0; +} diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/wc.leg b/supportlibs/pegmarkdown/peg-0.1.9/examples/wc.leg new file mode 100644 index 000000000..59199c89f --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/wc.leg @@ -0,0 +1,22 @@ +%{ +#include +int lines= 0, words= 0, chars= 0; +%} + +start = (line | word | char) + +line = < (( '\n' '\r'* ) | ( '\r' '\n'* )) > { lines++; chars += yyleng; } +word = < [a-zA-Z]+ > { words++; chars += yyleng; printf("<%s>\n", yytext); } +char = . { chars++; } + +%% + +int main() +{ + while (yyparse()) + ; + printf("%d lines\n", lines); + printf("%d chars\n", chars); + printf("%d words\n", words); + return 0; +} diff --git a/supportlibs/pegmarkdown/peg-0.1.9/examples/wc.ref b/supportlibs/pegmarkdown/peg-0.1.9/examples/wc.ref new file mode 100644 index 000000000..083a46e64 --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/examples/wc.ref @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + +22 lines +425 chars +52 words diff --git a/supportlibs/pegmarkdown/peg-0.1.9/leg.c b/supportlibs/pegmarkdown/peg-0.1.9/leg.c new file mode 100644 index 000000000..91b696d1e --- /dev/null +++ b/supportlibs/pegmarkdown/peg-0.1.9/leg.c @@ -0,0 +1,1209 @@ +/* A recursive-descent parser generated by peg 0.1.9 */ + +#include +#include +#include +#define YYRULECOUNT 36 + +# include "tree.h" +# include "version.h" + +# include +# include +# include +# include +# include +# include + + typedef struct Header Header; + + struct Header { + char *text; + Header *next; + }; + + FILE *input= 0; + + int verboseFlag= 0; + + static int lineNumber= 0; + static char *fileName= 0; + static char *trailer= 0; + static Header *headers= 0; + + void makeHeader(char *text); + void makeTrailer(char *text); + + void yyerror(char *message); + +# define YY_INPUT(buf, result, max) \ + { \ + int c= getc(input); \ + if ('\n' == c || '\r' == c) ++lineNumber; \ + result= (EOF == c) ? 0 : (*(buf)= c, 1); \ + } + +# define YY_LOCAL(T) static T +# define YY_RULE(T) static T + +#ifndef YY_LOCAL +#define YY_LOCAL(T) static T +#endif +#ifndef YY_ACTION +#define YY_ACTION(T) static T +#endif +#ifndef YY_RULE +#define YY_RULE(T) static T +#endif +#ifndef YY_PARSE +#define YY_PARSE(T) T +#endif +#ifndef YYPARSE +#define YYPARSE yyparse +#endif +#ifndef YYPARSEFROM +#define YYPARSEFROM yyparsefrom +#endif +#ifndef YY_INPUT +#define YY_INPUT(buf, result, max_size) \ + { \ + int yyc= getchar(); \ + result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \ + yyprintf((stderr, "<%c>", yyc)); \ + } +#endif +#ifndef YY_BEGIN +#define YY_BEGIN ( ctx->begin= ctx->pos, 1) +#endif +#ifndef YY_END +#define YY_END ( ctx->end= ctx->pos, 1) +#endif +#ifdef YY_DEBUG +# define yyprintf(args) fprintf args +#else +# define yyprintf(args) +#endif +#ifndef YYSTYPE +#define YYSTYPE int +#endif + +#ifndef YY_PART + +typedef struct _yycontext yycontext; +typedef void (*yyaction)(yycontext *ctx, char *yytext, int yyleng); +typedef struct _yythunk { int begin, end; yyaction action; struct _yythunk *next; } yythunk; + +struct _yycontext { + char *buf; + int buflen; + int pos; + int limit; + char *text; + int textlen; + int begin; + int end; + int textmax; + yythunk *thunks; + int thunkslen; + int thunkpos; + YYSTYPE yy; + YYSTYPE *val; + YYSTYPE *vals; + int valslen; +#ifdef YY_CTX_MEMBERS + YY_CTX_MEMBERS +#endif +}; + +#ifdef YY_CTX_LOCAL +#define YY_CTX_PARAM_ yycontext *yyctx, +#define YY_CTX_PARAM yycontext *yyctx +#define YY_CTX_ARG_ yyctx, +#define YY_CTX_ARG yyctx +#else +#define YY_CTX_PARAM_ +#define YY_CTX_PARAM +#define YY_CTX_ARG_ +#define YY_CTX_ARG +yycontext yyctx0; +yycontext *yyctx= &yyctx0; +#endif + +YY_LOCAL(int) yyrefill(yycontext *ctx) +{ + int yyn; + while (ctx->buflen - ctx->pos < 512) + { + ctx->buflen *= 2; + ctx->buf= (char *)realloc(ctx->buf, ctx->buflen); + } + YY_INPUT((ctx->buf + ctx->pos), yyn, (ctx->buflen - ctx->pos)); + if (!yyn) return 0; + ctx->limit += yyn; + return 1; +} + +YY_LOCAL(int) yymatchDot(yycontext *ctx) +{ + if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0; + ++ctx->pos; + return 1; +} + +YY_LOCAL(int) yymatchChar(yycontext *ctx, int c) +{ + if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0; + if ((unsigned char)ctx->buf[ctx->pos] == c) + { + ++ctx->pos; + yyprintf((stderr, " ok yymatchChar(ctx, %c) @ %s\n", c, ctx->buf+ctx->pos)); + return 1; + } + yyprintf((stderr, " fail yymatchChar(ctx, %c) @ %s\n", c, ctx->buf+ctx->pos)); + return 0; +} + +YY_LOCAL(int) yymatchString(yycontext *ctx, char *s) +{ + int yysav= ctx->pos; + while (*s) + { + if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0; + if (ctx->buf[ctx->pos] != *s) + { + ctx->pos= yysav; + return 0; + } + ++s; + ++ctx->pos; + } + return 1; +} + +YY_LOCAL(int) yymatchClass(yycontext *ctx, unsigned char *bits) +{ + int c; + if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0; + c= (unsigned char)ctx->buf[ctx->pos]; + if (bits[c >> 3] & (1 << (c & 7))) + { + ++ctx->pos; + yyprintf((stderr, " ok yymatchClass @ %s\n", ctx->buf+ctx->pos)); + return 1; + } + yyprintf((stderr, " fail yymatchClass @ %s\n", ctx->buf+ctx->pos)); + return 0; +} + +YY_LOCAL(void) yyDo(yycontext *ctx, yyaction action, int begin, int end) +{ + while (ctx->thunkpos >= ctx->thunkslen) + { + ctx->thunkslen *= 2; + ctx->thunks= (yythunk *)realloc(ctx->thunks, sizeof(yythunk) * ctx->thunkslen); + } + ctx->thunks[ctx->thunkpos].begin= begin; + ctx->thunks[ctx->thunkpos].end= end; + ctx->thunks[ctx->thunkpos].action= action; + ++ctx->thunkpos; +} + +YY_LOCAL(int) yyText(yycontext *ctx, int begin, int end) +{ + int yyleng= end - begin; + if (yyleng <= 0) + yyleng= 0; + else + { + while (ctx->textlen < (yyleng + 1)) + { + ctx->textlen *= 2; + ctx->text= (char *)realloc(ctx->text, ctx->textlen); + } + memcpy(ctx->text, ctx->buf + begin, yyleng); + } + ctx->text[yyleng]= '\0'; + return yyleng; +} + +YY_LOCAL(void) yyDone(yycontext *ctx) +{ + int pos; + for (pos= 0; pos < ctx->thunkpos; ++pos) + { + yythunk *thunk= &ctx->thunks[pos]; + int yyleng= thunk->end ? yyText(ctx, thunk->begin, thunk->end) : thunk->begin; + yyprintf((stderr, "DO [%d] %p %s\n", pos, thunk->action, ctx->text)); + thunk->action(ctx, ctx->text, yyleng); + } + ctx->thunkpos= 0; +} + +YY_LOCAL(void) yyCommit(yycontext *ctx) +{ + if ((ctx->limit -= ctx->pos)) + { + memmove(ctx->buf, ctx->buf + ctx->pos, ctx->limit); + } + ctx->begin -= ctx->pos; + ctx->end -= ctx->pos; + ctx->pos= ctx->thunkpos= 0; +} + +YY_LOCAL(int) yyAccept(yycontext *ctx, int tp0) +{ + if (tp0) + { + fprintf(stderr, "accept denied at %d\n", tp0); + return 0; + } + else + { + yyDone(ctx); + yyCommit(ctx); + } + return 1; +} + +YY_LOCAL(void) yyPush(yycontext *ctx, char *text, int count) { ctx->val += count; } +YY_LOCAL(void) yyPop(yycontext *ctx, char *text, int count) { ctx->val -= count; } +YY_LOCAL(void) yySet(yycontext *ctx, char *text, int count) { ctx->val[count]= ctx->yy; } + +#endif /* YY_PART */ + +#define YYACCEPT yyAccept(ctx, yythunkpos0) + +YY_RULE(int) yy_end_of_line(yycontext *ctx); /* 36 */ +YY_RULE(int) yy_comment(yycontext *ctx); /* 35 */ +YY_RULE(int) yy_space(yycontext *ctx); /* 34 */ +YY_RULE(int) yy_braces(yycontext *ctx); /* 33 */ +YY_RULE(int) yy_range(yycontext *ctx); /* 32 */ +YY_RULE(int) yy_char(yycontext *ctx); /* 31 */ +YY_RULE(int) yy_END(yycontext *ctx); /* 30 */ +YY_RULE(int) yy_BEGIN(yycontext *ctx); /* 29 */ +YY_RULE(int) yy_DOT(yycontext *ctx); /* 28 */ +YY_RULE(int) yy_class(yycontext *ctx); /* 27 */ +YY_RULE(int) yy_literal(yycontext *ctx); /* 26 */ +YY_RULE(int) yy_CLOSE(yycontext *ctx); /* 25 */ +YY_RULE(int) yy_OPEN(yycontext *ctx); /* 24 */ +YY_RULE(int) yy_COLON(yycontext *ctx); /* 23 */ +YY_RULE(int) yy_PLUS(yycontext *ctx); /* 22 */ +YY_RULE(int) yy_STAR(yycontext *ctx); /* 21 */ +YY_RULE(int) yy_QUESTION(yycontext *ctx); /* 20 */ +YY_RULE(int) yy_primary(yycontext *ctx); /* 19 */ +YY_RULE(int) yy_NOT(yycontext *ctx); /* 18 */ +YY_RULE(int) yy_suffix(yycontext *ctx); /* 17 */ +YY_RULE(int) yy_action(yycontext *ctx); /* 16 */ +YY_RULE(int) yy_AND(yycontext *ctx); /* 15 */ +YY_RULE(int) yy_prefix(yycontext *ctx); /* 14 */ +YY_RULE(int) yy_BAR(yycontext *ctx); /* 13 */ +YY_RULE(int) yy_sequence(yycontext *ctx); /* 12 */ +YY_RULE(int) yy_SEMICOLON(yycontext *ctx); /* 11 */ +YY_RULE(int) yy_expression(yycontext *ctx); /* 10 */ +YY_RULE(int) yy_EQUAL(yycontext *ctx); /* 9 */ +YY_RULE(int) yy_identifier(yycontext *ctx); /* 8 */ +YY_RULE(int) yy_RPERCENT(yycontext *ctx); /* 7 */ +YY_RULE(int) yy_end_of_file(yycontext *ctx); /* 6 */ +YY_RULE(int) yy_trailer(yycontext *ctx); /* 5 */ +YY_RULE(int) yy_definition(yycontext *ctx); /* 4 */ +YY_RULE(int) yy_declaration(yycontext *ctx); /* 3 */ +YY_RULE(int) yy__(yycontext *ctx); /* 2 */ +YY_RULE(int) yy_grammar(yycontext *ctx); /* 1 */ + +YY_ACTION(void) yy_9_primary(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_9_primary\n")); + push(makePredicate("YY_END")); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_8_primary(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_8_primary\n")); + push(makePredicate("YY_BEGIN")); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_7_primary(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_7_primary\n")); + push(makeAction(yytext)); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_6_primary(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_6_primary\n")); + push(makeDot()); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_5_primary(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_5_primary\n")); + push(makeClass(yytext)); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_4_primary(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_4_primary\n")); + push(makeString(yytext)); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_3_primary(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_3_primary\n")); + push(makeName(findRule(yytext))); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_2_primary(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_primary\n")); + Node *name= makeName(findRule(yytext)); name->name.variable= pop(); push(name); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_primary(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_primary\n")); + push(makeVariable(yytext)); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_3_suffix(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_3_suffix\n")); + push(makePlus (pop())); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_2_suffix(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_suffix\n")); + push(makeStar (pop())); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_suffix(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_suffix\n")); + push(makeQuery(pop())); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_3_prefix(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_3_prefix\n")); + push(makePeekNot(pop())); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_2_prefix(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_prefix\n")); + push(makePeekFor(pop())); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_prefix(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_prefix\n")); + push(makePredicate(yytext)); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_sequence(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_sequence\n")); + Node *f= pop(); push(Sequence_append(pop(), f)); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_expression(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_expression\n")); + Node *f= pop(); push(Alternate_append(pop(), f)); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_2_definition(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_2_definition\n")); + Node *e= pop(); Rule_setExpression(pop(), e); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_definition(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_definition\n")); + if (push(beginRule(findRule(yytext)))->rule.expression) + fprintf(stderr, "rule '%s' redefined\n", yytext); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_trailer(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_trailer\n")); + makeTrailer(yytext); ; +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_1_declaration(yycontext *ctx, char *yytext, int yyleng) +{ +#define yy ctx->yy +#define yypos ctx->pos +#define yythunkpos ctx->thunkpos + yyprintf((stderr, "do yy_1_declaration\n")); + makeHeader(yytext); ; +#undef yythunkpos +#undef yypos +#undef yy +} + +YY_RULE(int) yy_end_of_line(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "end_of_line")); + { int yypos2= ctx->pos, yythunkpos2= ctx->thunkpos; if (!yymatchString(ctx, "\r\n")) goto l3; goto l2; + l3:; ctx->pos= yypos2; ctx->thunkpos= yythunkpos2; if (!yymatchChar(ctx, '\n')) goto l4; goto l2; + l4:; ctx->pos= yypos2; ctx->thunkpos= yythunkpos2; if (!yymatchChar(ctx, '\r')) goto l1; + } + l2:; + yyprintf((stderr, " ok %s @ %s\n", "end_of_line", ctx->buf+ctx->pos)); + return 1; + l1:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "end_of_line", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_comment(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "comment")); if (!yymatchChar(ctx, '#')) goto l5; + l6:; + { int yypos7= ctx->pos, yythunkpos7= ctx->thunkpos; + { int yypos8= ctx->pos, yythunkpos8= ctx->thunkpos; if (!yy_end_of_line(ctx)) goto l8; goto l7; + l8:; ctx->pos= yypos8; ctx->thunkpos= yythunkpos8; + } if (!yymatchDot(ctx)) goto l7; goto l6; + l7:; ctx->pos= yypos7; ctx->thunkpos= yythunkpos7; + } if (!yy_end_of_line(ctx)) goto l5; + yyprintf((stderr, " ok %s @ %s\n", "comment", ctx->buf+ctx->pos)); + return 1; + l5:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "comment", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_space(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "space")); + { int yypos10= ctx->pos, yythunkpos10= ctx->thunkpos; if (!yymatchChar(ctx, ' ')) goto l11; goto l10; + l11:; ctx->pos= yypos10; ctx->thunkpos= yythunkpos10; if (!yymatchChar(ctx, '\t')) goto l12; goto l10; + l12:; ctx->pos= yypos10; ctx->thunkpos= yythunkpos10; if (!yy_end_of_line(ctx)) goto l9; + } + l10:; + yyprintf((stderr, " ok %s @ %s\n", "space", ctx->buf+ctx->pos)); + return 1; + l9:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "space", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_braces(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "braces")); + { int yypos14= ctx->pos, yythunkpos14= ctx->thunkpos; if (!yymatchChar(ctx, '{')) goto l15; + l16:; + { int yypos17= ctx->pos, yythunkpos17= ctx->thunkpos; if (!yy_braces(ctx)) goto l17; goto l16; + l17:; ctx->pos= yypos17; ctx->thunkpos= yythunkpos17; + } if (!yymatchChar(ctx, '}')) goto l15; goto l14; + l15:; ctx->pos= yypos14; ctx->thunkpos= yythunkpos14; + { int yypos18= ctx->pos, yythunkpos18= ctx->thunkpos; if (!yymatchChar(ctx, '}')) goto l18; goto l13; + l18:; ctx->pos= yypos18; ctx->thunkpos= yythunkpos18; + } if (!yymatchDot(ctx)) goto l13; + } + l14:; + yyprintf((stderr, " ok %s @ %s\n", "braces", ctx->buf+ctx->pos)); + return 1; + l13:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "braces", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_range(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "range")); + { int yypos20= ctx->pos, yythunkpos20= ctx->thunkpos; if (!yy_char(ctx)) goto l21; if (!yymatchChar(ctx, '-')) goto l21; if (!yy_char(ctx)) goto l21; goto l20; + l21:; ctx->pos= yypos20; ctx->thunkpos= yythunkpos20; if (!yy_char(ctx)) goto l19; + } + l20:; + yyprintf((stderr, " ok %s @ %s\n", "range", ctx->buf+ctx->pos)); + return 1; + l19:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "range", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_char(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "char")); + { int yypos23= ctx->pos, yythunkpos23= ctx->thunkpos; if (!yymatchChar(ctx, '\\')) goto l24; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\204\040\000\000\000\000\000\070\146\100\124\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l24; goto l23; + l24:; ctx->pos= yypos23; ctx->thunkpos= yythunkpos23; if (!yymatchChar(ctx, '\\')) goto l25; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l25; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l25; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l25; goto l23; + l25:; ctx->pos= yypos23; ctx->thunkpos= yythunkpos23; if (!yymatchChar(ctx, '\\')) goto l26; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l26; + { int yypos27= ctx->pos, yythunkpos27= ctx->thunkpos; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l27; goto l28; + l27:; ctx->pos= yypos27; ctx->thunkpos= yythunkpos27; + } + l28:; goto l23; + l26:; ctx->pos= yypos23; ctx->thunkpos= yythunkpos23; + { int yypos29= ctx->pos, yythunkpos29= ctx->thunkpos; if (!yymatchChar(ctx, '\\')) goto l29; goto l22; + l29:; ctx->pos= yypos29; ctx->thunkpos= yythunkpos29; + } if (!yymatchDot(ctx)) goto l22; + } + l23:; + yyprintf((stderr, " ok %s @ %s\n", "char", ctx->buf+ctx->pos)); + return 1; + l22:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "char", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_END(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "END")); if (!yymatchChar(ctx, '>')) goto l30; if (!yy__(ctx)) goto l30; + yyprintf((stderr, " ok %s @ %s\n", "END", ctx->buf+ctx->pos)); + return 1; + l30:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "END", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_BEGIN(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "BEGIN")); if (!yymatchChar(ctx, '<')) goto l31; if (!yy__(ctx)) goto l31; + yyprintf((stderr, " ok %s @ %s\n", "BEGIN", ctx->buf+ctx->pos)); + return 1; + l31:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "BEGIN", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_DOT(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "DOT")); if (!yymatchChar(ctx, '.')) goto l32; if (!yy__(ctx)) goto l32; + yyprintf((stderr, " ok %s @ %s\n", "DOT", ctx->buf+ctx->pos)); + return 1; + l32:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "DOT", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_class(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "class")); if (!yymatchChar(ctx, '[')) goto l33; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l33; + l34:; + { int yypos35= ctx->pos, yythunkpos35= ctx->thunkpos; + { int yypos36= ctx->pos, yythunkpos36= ctx->thunkpos; if (!yymatchChar(ctx, ']')) goto l36; goto l35; + l36:; ctx->pos= yypos36; ctx->thunkpos= yythunkpos36; + } if (!yy_range(ctx)) goto l35; goto l34; + l35:; ctx->pos= yypos35; ctx->thunkpos= yythunkpos35; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l33; if (!yymatchChar(ctx, ']')) goto l33; if (!yy__(ctx)) goto l33; + yyprintf((stderr, " ok %s @ %s\n", "class", ctx->buf+ctx->pos)); + return 1; + l33:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "class", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_literal(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "literal")); + { int yypos38= ctx->pos, yythunkpos38= ctx->thunkpos; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l39; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l39; + l40:; + { int yypos41= ctx->pos, yythunkpos41= ctx->thunkpos; + { int yypos42= ctx->pos, yythunkpos42= ctx->thunkpos; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l42; goto l41; + l42:; ctx->pos= yypos42; ctx->thunkpos= yythunkpos42; + } if (!yy_char(ctx)) goto l41; goto l40; + l41:; ctx->pos= yypos41; ctx->thunkpos= yythunkpos41; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l39; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l39; if (!yy__(ctx)) goto l39; goto l38; + l39:; ctx->pos= yypos38; ctx->thunkpos= yythunkpos38; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l37; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l37; + l43:; + { int yypos44= ctx->pos, yythunkpos44= ctx->thunkpos; + { int yypos45= ctx->pos, yythunkpos45= ctx->thunkpos; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l45; goto l44; + l45:; ctx->pos= yypos45; ctx->thunkpos= yythunkpos45; + } if (!yy_char(ctx)) goto l44; goto l43; + l44:; ctx->pos= yypos44; ctx->thunkpos= yythunkpos44; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l37; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l37; if (!yy__(ctx)) goto l37; + } + l38:; + yyprintf((stderr, " ok %s @ %s\n", "literal", ctx->buf+ctx->pos)); + return 1; + l37:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "literal", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_CLOSE(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "CLOSE")); if (!yymatchChar(ctx, ')')) goto l46; if (!yy__(ctx)) goto l46; + yyprintf((stderr, " ok %s @ %s\n", "CLOSE", ctx->buf+ctx->pos)); + return 1; + l46:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "CLOSE", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_OPEN(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "OPEN")); if (!yymatchChar(ctx, '(')) goto l47; if (!yy__(ctx)) goto l47; + yyprintf((stderr, " ok %s @ %s\n", "OPEN", ctx->buf+ctx->pos)); + return 1; + l47:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "OPEN", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_COLON(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "COLON")); if (!yymatchChar(ctx, ':')) goto l48; if (!yy__(ctx)) goto l48; + yyprintf((stderr, " ok %s @ %s\n", "COLON", ctx->buf+ctx->pos)); + return 1; + l48:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "COLON", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_PLUS(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "PLUS")); if (!yymatchChar(ctx, '+')) goto l49; if (!yy__(ctx)) goto l49; + yyprintf((stderr, " ok %s @ %s\n", "PLUS", ctx->buf+ctx->pos)); + return 1; + l49:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "PLUS", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_STAR(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "STAR")); if (!yymatchChar(ctx, '*')) goto l50; if (!yy__(ctx)) goto l50; + yyprintf((stderr, " ok %s @ %s\n", "STAR", ctx->buf+ctx->pos)); + return 1; + l50:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "STAR", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_QUESTION(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "QUESTION")); if (!yymatchChar(ctx, '?')) goto l51; if (!yy__(ctx)) goto l51; + yyprintf((stderr, " ok %s @ %s\n", "QUESTION", ctx->buf+ctx->pos)); + return 1; + l51:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "QUESTION", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_primary(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "primary")); + { int yypos53= ctx->pos, yythunkpos53= ctx->thunkpos; if (!yy_identifier(ctx)) goto l54; yyDo(ctx, yy_1_primary, ctx->begin, ctx->end); if (!yy_COLON(ctx)) goto l54; if (!yy_identifier(ctx)) goto l54; + { int yypos55= ctx->pos, yythunkpos55= ctx->thunkpos; if (!yy_EQUAL(ctx)) goto l55; goto l54; + l55:; ctx->pos= yypos55; ctx->thunkpos= yythunkpos55; + } yyDo(ctx, yy_2_primary, ctx->begin, ctx->end); goto l53; + l54:; ctx->pos= yypos53; ctx->thunkpos= yythunkpos53; if (!yy_identifier(ctx)) goto l56; + { int yypos57= ctx->pos, yythunkpos57= ctx->thunkpos; if (!yy_EQUAL(ctx)) goto l57; goto l56; + l57:; ctx->pos= yypos57; ctx->thunkpos= yythunkpos57; + } yyDo(ctx, yy_3_primary, ctx->begin, ctx->end); goto l53; + l56:; ctx->pos= yypos53; ctx->thunkpos= yythunkpos53; if (!yy_OPEN(ctx)) goto l58; if (!yy_expression(ctx)) goto l58; if (!yy_CLOSE(ctx)) goto l58; goto l53; + l58:; ctx->pos= yypos53; ctx->thunkpos= yythunkpos53; if (!yy_literal(ctx)) goto l59; yyDo(ctx, yy_4_primary, ctx->begin, ctx->end); goto l53; + l59:; ctx->pos= yypos53; ctx->thunkpos= yythunkpos53; if (!yy_class(ctx)) goto l60; yyDo(ctx, yy_5_primary, ctx->begin, ctx->end); goto l53; + l60:; ctx->pos= yypos53; ctx->thunkpos= yythunkpos53; if (!yy_DOT(ctx)) goto l61; yyDo(ctx, yy_6_primary, ctx->begin, ctx->end); goto l53; + l61:; ctx->pos= yypos53; ctx->thunkpos= yythunkpos53; if (!yy_action(ctx)) goto l62; yyDo(ctx, yy_7_primary, ctx->begin, ctx->end); goto l53; + l62:; ctx->pos= yypos53; ctx->thunkpos= yythunkpos53; if (!yy_BEGIN(ctx)) goto l63; yyDo(ctx, yy_8_primary, ctx->begin, ctx->end); goto l53; + l63:; ctx->pos= yypos53; ctx->thunkpos= yythunkpos53; if (!yy_END(ctx)) goto l52; yyDo(ctx, yy_9_primary, ctx->begin, ctx->end); + } + l53:; + yyprintf((stderr, " ok %s @ %s\n", "primary", ctx->buf+ctx->pos)); + return 1; + l52:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "primary", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_NOT(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "NOT")); if (!yymatchChar(ctx, '!')) goto l64; if (!yy__(ctx)) goto l64; + yyprintf((stderr, " ok %s @ %s\n", "NOT", ctx->buf+ctx->pos)); + return 1; + l64:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "NOT", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_suffix(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "suffix")); if (!yy_primary(ctx)) goto l65; + { int yypos66= ctx->pos, yythunkpos66= ctx->thunkpos; + { int yypos68= ctx->pos, yythunkpos68= ctx->thunkpos; if (!yy_QUESTION(ctx)) goto l69; yyDo(ctx, yy_1_suffix, ctx->begin, ctx->end); goto l68; + l69:; ctx->pos= yypos68; ctx->thunkpos= yythunkpos68; if (!yy_STAR(ctx)) goto l70; yyDo(ctx, yy_2_suffix, ctx->begin, ctx->end); goto l68; + l70:; ctx->pos= yypos68; ctx->thunkpos= yythunkpos68; if (!yy_PLUS(ctx)) goto l66; yyDo(ctx, yy_3_suffix, ctx->begin, ctx->end); + } + l68:; goto l67; + l66:; ctx->pos= yypos66; ctx->thunkpos= yythunkpos66; + } + l67:; + yyprintf((stderr, " ok %s @ %s\n", "suffix", ctx->buf+ctx->pos)); + return 1; + l65:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "suffix", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_action(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "action")); if (!yymatchChar(ctx, '{')) goto l71; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l71; + l72:; + { int yypos73= ctx->pos, yythunkpos73= ctx->thunkpos; if (!yy_braces(ctx)) goto l73; goto l72; + l73:; ctx->pos= yypos73; ctx->thunkpos= yythunkpos73; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l71; if (!yymatchChar(ctx, '}')) goto l71; if (!yy__(ctx)) goto l71; + yyprintf((stderr, " ok %s @ %s\n", "action", ctx->buf+ctx->pos)); + return 1; + l71:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "action", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_AND(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "AND")); if (!yymatchChar(ctx, '&')) goto l74; if (!yy__(ctx)) goto l74; + yyprintf((stderr, " ok %s @ %s\n", "AND", ctx->buf+ctx->pos)); + return 1; + l74:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "AND", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_prefix(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "prefix")); + { int yypos76= ctx->pos, yythunkpos76= ctx->thunkpos; if (!yy_AND(ctx)) goto l77; if (!yy_action(ctx)) goto l77; yyDo(ctx, yy_1_prefix, ctx->begin, ctx->end); goto l76; + l77:; ctx->pos= yypos76; ctx->thunkpos= yythunkpos76; if (!yy_AND(ctx)) goto l78; if (!yy_suffix(ctx)) goto l78; yyDo(ctx, yy_2_prefix, ctx->begin, ctx->end); goto l76; + l78:; ctx->pos= yypos76; ctx->thunkpos= yythunkpos76; if (!yy_NOT(ctx)) goto l79; if (!yy_suffix(ctx)) goto l79; yyDo(ctx, yy_3_prefix, ctx->begin, ctx->end); goto l76; + l79:; ctx->pos= yypos76; ctx->thunkpos= yythunkpos76; if (!yy_suffix(ctx)) goto l75; + } + l76:; + yyprintf((stderr, " ok %s @ %s\n", "prefix", ctx->buf+ctx->pos)); + return 1; + l75:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "prefix", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_BAR(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "BAR")); if (!yymatchChar(ctx, '|')) goto l80; if (!yy__(ctx)) goto l80; + yyprintf((stderr, " ok %s @ %s\n", "BAR", ctx->buf+ctx->pos)); + return 1; + l80:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "BAR", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_sequence(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "sequence")); if (!yy_prefix(ctx)) goto l81; + l82:; + { int yypos83= ctx->pos, yythunkpos83= ctx->thunkpos; if (!yy_prefix(ctx)) goto l83; yyDo(ctx, yy_1_sequence, ctx->begin, ctx->end); goto l82; + l83:; ctx->pos= yypos83; ctx->thunkpos= yythunkpos83; + } + yyprintf((stderr, " ok %s @ %s\n", "sequence", ctx->buf+ctx->pos)); + return 1; + l81:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "sequence", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_SEMICOLON(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "SEMICOLON")); if (!yymatchChar(ctx, ';')) goto l84; if (!yy__(ctx)) goto l84; + yyprintf((stderr, " ok %s @ %s\n", "SEMICOLON", ctx->buf+ctx->pos)); + return 1; + l84:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "SEMICOLON", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_expression(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "expression")); if (!yy_sequence(ctx)) goto l85; + l86:; + { int yypos87= ctx->pos, yythunkpos87= ctx->thunkpos; if (!yy_BAR(ctx)) goto l87; if (!yy_sequence(ctx)) goto l87; yyDo(ctx, yy_1_expression, ctx->begin, ctx->end); goto l86; + l87:; ctx->pos= yypos87; ctx->thunkpos= yythunkpos87; + } + yyprintf((stderr, " ok %s @ %s\n", "expression", ctx->buf+ctx->pos)); + return 1; + l85:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "expression", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_EQUAL(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "EQUAL")); if (!yymatchChar(ctx, '=')) goto l88; if (!yy__(ctx)) goto l88; + yyprintf((stderr, " ok %s @ %s\n", "EQUAL", ctx->buf+ctx->pos)); + return 1; + l88:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "EQUAL", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_identifier(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "identifier")); yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l89; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\040\000\000\376\377\377\207\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l89; + l90:; + { int yypos91= ctx->pos, yythunkpos91= ctx->thunkpos; if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\040\377\003\376\377\377\207\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l91; goto l90; + l91:; ctx->pos= yypos91; ctx->thunkpos= yythunkpos91; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l89; if (!yy__(ctx)) goto l89; + yyprintf((stderr, " ok %s @ %s\n", "identifier", ctx->buf+ctx->pos)); + return 1; + l89:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "identifier", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_RPERCENT(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "RPERCENT")); if (!yymatchString(ctx, "%}")) goto l92; if (!yy__(ctx)) goto l92; + yyprintf((stderr, " ok %s @ %s\n", "RPERCENT", ctx->buf+ctx->pos)); + return 1; + l92:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "RPERCENT", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_end_of_file(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "end_of_file")); + { int yypos94= ctx->pos, yythunkpos94= ctx->thunkpos; if (!yymatchDot(ctx)) goto l94; goto l93; + l94:; ctx->pos= yypos94; ctx->thunkpos= yythunkpos94; + } + yyprintf((stderr, " ok %s @ %s\n", "end_of_file", ctx->buf+ctx->pos)); + return 1; + l93:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "end_of_file", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_trailer(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "trailer")); if (!yymatchString(ctx, "%%")) goto l95; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l95; + l96:; + { int yypos97= ctx->pos, yythunkpos97= ctx->thunkpos; if (!yymatchDot(ctx)) goto l97; goto l96; + l97:; ctx->pos= yypos97; ctx->thunkpos= yythunkpos97; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l95; yyDo(ctx, yy_1_trailer, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "trailer", ctx->buf+ctx->pos)); + return 1; + l95:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "trailer", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_definition(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "definition")); if (!yy_identifier(ctx)) goto l98; yyDo(ctx, yy_1_definition, ctx->begin, ctx->end); if (!yy_EQUAL(ctx)) goto l98; if (!yy_expression(ctx)) goto l98; yyDo(ctx, yy_2_definition, ctx->begin, ctx->end); + { int yypos99= ctx->pos, yythunkpos99= ctx->thunkpos; if (!yy_SEMICOLON(ctx)) goto l99; goto l100; + l99:; ctx->pos= yypos99; ctx->thunkpos= yythunkpos99; + } + l100:; + yyprintf((stderr, " ok %s @ %s\n", "definition", ctx->buf+ctx->pos)); + return 1; + l98:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "definition", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy_declaration(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "declaration")); if (!yymatchString(ctx, "%{")) goto l101; yyText(ctx, ctx->begin, ctx->end); if (!(YY_BEGIN)) goto l101; + l102:; + { int yypos103= ctx->pos, yythunkpos103= ctx->thunkpos; + { int yypos104= ctx->pos, yythunkpos104= ctx->thunkpos; if (!yymatchString(ctx, "%}")) goto l104; goto l103; + l104:; ctx->pos= yypos104; ctx->thunkpos= yythunkpos104; + } if (!yymatchDot(ctx)) goto l103; goto l102; + l103:; ctx->pos= yypos103; ctx->thunkpos= yythunkpos103; + } yyText(ctx, ctx->begin, ctx->end); if (!(YY_END)) goto l101; if (!yy_RPERCENT(ctx)) goto l101; yyDo(ctx, yy_1_declaration, ctx->begin, ctx->end); + yyprintf((stderr, " ok %s @ %s\n", "declaration", ctx->buf+ctx->pos)); + return 1; + l101:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "declaration", ctx->buf+ctx->pos)); + return 0; +} +YY_RULE(int) yy__(yycontext *ctx) +{ + yyprintf((stderr, "%s\n", "_")); + l106:; + { int yypos107= ctx->pos, yythunkpos107= ctx->thunkpos; + { int yypos108= ctx->pos, yythunkpos108= ctx->thunkpos; if (!yy_space(ctx)) goto l109; goto l108; + l109:; ctx->pos= yypos108; ctx->thunkpos= yythunkpos108; if (!yy_comment(ctx)) goto l107; + } + l108:; goto l106; + l107:; ctx->pos= yypos107; ctx->thunkpos= yythunkpos107; + } + yyprintf((stderr, " ok %s @ %s\n", "_", ctx->buf+ctx->pos)); + return 1; +} +YY_RULE(int) yy_grammar(yycontext *ctx) +{ int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos; + yyprintf((stderr, "%s\n", "grammar")); if (!yy__(ctx)) goto l110; + { int yypos113= ctx->pos, yythunkpos113= ctx->thunkpos; if (!yy_declaration(ctx)) goto l114; goto l113; + l114:; ctx->pos= yypos113; ctx->thunkpos= yythunkpos113; if (!yy_definition(ctx)) goto l110; + } + l113:; + l111:; + { int yypos112= ctx->pos, yythunkpos112= ctx->thunkpos; + { int yypos115= ctx->pos, yythunkpos115= ctx->thunkpos; if (!yy_declaration(ctx)) goto l116; goto l115; + l116:; ctx->pos= yypos115; ctx->thunkpos= yythunkpos115; if (!yy_definition(ctx)) goto l112; + } + l115:; goto l111; + l112:; ctx->pos= yypos112; ctx->thunkpos= yythunkpos112; + } + { int yypos117= ctx->pos, yythunkpos117= ctx->thunkpos; if (!yy_trailer(ctx)) goto l117; goto l118; + l117:; ctx->pos= yypos117; ctx->thunkpos= yythunkpos117; + } + l118:; if (!yy_end_of_file(ctx)) goto l110; + yyprintf((stderr, " ok %s @ %s\n", "grammar", ctx->buf+ctx->pos)); + return 1; + l110:; ctx->pos= yypos0; ctx->thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "grammar", ctx->buf+ctx->pos)); + return 0; +} + +#ifndef YY_PART + +typedef int (*yyrule)(yycontext *ctx); + +YY_PARSE(int) YYPARSEFROM(YY_CTX_PARAM_ yyrule yystart) +{ + int yyok; + if (!yyctx->buflen) + { + yyctx->buflen= 1024; + yyctx->buf= (char *)malloc(yyctx->buflen); + yyctx->textlen= 1024; + yyctx->text= (char *)malloc(yyctx->textlen); + yyctx->thunkslen= 32; + yyctx->thunks= (yythunk *)malloc(sizeof(yythunk) * yyctx->thunkslen); + yyctx->valslen= 32; + yyctx->vals= (YYSTYPE *)malloc(sizeof(YYSTYPE) * yyctx->valslen); + yyctx->begin= yyctx->end= yyctx->pos= yyctx->limit= yyctx->thunkpos= 0; + } + yyctx->begin= yyctx->end= yyctx->pos; + yyctx->thunkpos= 0; + yyctx->val= yyctx->vals; + yyok= yystart(yyctx); + if (yyok) yyDone(yyctx); + yyCommit(yyctx); + return yyok; +} + +YY_PARSE(int) YYPARSE(YY_CTX_PARAM) +{ + return YYPARSEFROM(YY_CTX_ARG_ yy_grammar); +} + +#endif + + +void yyerror(char *message) +{ + fprintf(stderr, "%s:%d: %s", fileName, lineNumber, message); + if (yyctx->text[0]) fprintf(stderr, " near token '%s'", yyctx->text); + if (yyctx->pos < yyctx->limit || !feof(input)) + { + yyctx->buf[yyctx->limit]= '\0'; + fprintf(stderr, " before text \""); + while (yyctx->pos < yyctx->limit) + { + if ('\n' == yyctx->buf[yyctx->pos] || '\r' == yyctx->buf[yyctx->pos]) break; + fputc(yyctx->buf[yyctx->pos++], stderr); + } + if (yyctx->pos == yyctx->limit) + { + int c; + while (EOF != (c= fgetc(input)) && '\n' != c && '\r' != c) + fputc(c, stderr); + } + fputc('\"', stderr); + } + fprintf(stderr, "\n"); + exit(1); +} + +void makeHeader(char *text) +{ + Header *header= (Header *)malloc(sizeof(Header)); + header->text= strdup(text); + header->next= headers; + headers= header; +} + +void makeTrailer(char *text) +{ + trailer= strdup(text); +} + +static void version(char *name) +{ + printf("%s version %d.%d.%d\n", name, PEG_MAJOR, PEG_MINOR, PEG_LEVEL); +} + +static void usage(char *name) +{ + version(name); + fprintf(stderr, "usage: %s [