diff --git a/build_scripts/Debian+Ubuntu/changelog b/build_scripts/Debian+Ubuntu/changelog index 15c1216c6..bb6fcd9b7 100644 --- a/build_scripts/Debian+Ubuntu/changelog +++ b/build_scripts/Debian+Ubuntu/changelog @@ -1,5 +1,199 @@ retroshare06 (0.6.2-1.XXXXXX~YYYYYY) YYYYYY; urgency=low + 5b3b903 csoler Sun, 23 Apr 2017 17:33:21 +0200 added missing line for ubuntu zesty + 73bfc27 csoler Sun, 23 Apr 2017 17:33:50 +0200 Merge pull request #784 from PhenomRetroShare/Fix_RelaySettingsPage + 4c326f5 Phenom Sun, 23 Apr 2017 10:27:18 +0200 Fix Relay setting page. + 0e087db defnax Sat, 22 Apr 2017 17:32:59 +0200 Fixed to use right icons for context menu actions + 8b9c447 electr Sat, 22 Apr 2017 10:13:23 +0200 fixed possible crash and return value in rsGetHostByName(), thanks to Kotyara for reporting this + 4ab6021 csoler Fri, 21 Apr 2017 19:45:30 +0200 Merge pull request #782 from PhenomRetroShare/Fix_MacOSX_Compilation + 936dcba Phenom Fri, 21 Apr 2017 18:50:36 +0200 Fix UnitTest compilation. + 969b5ce Phenom Fri, 21 Apr 2017 15:57:57 +0200 Fix MacOSX compilation. + 7400a8d csoler Thu, 20 Apr 2017 20:59:12 +0200 Merge pull request #780 from csoler/v0.6-ImprovedGUI + 5f8bf03 csoler Thu, 20 Apr 2017 20:54:51 +0200 added mechanism to allow services to document the names of their items, and improved bandwidth graph to show names for GXS services. Other services still need to supply their own names + ccfd12b csoler Wed, 19 Apr 2017 18:53:49 +0200 Merge pull request #778 from csoler/v0.6-ImprovedGUI + f406b81 csoler Wed, 19 Apr 2017 18:46:58 +0200 removed all FFT code and cleaned up deleted code in graphwidget.cpp + 1da89dd csoler Wed, 19 Apr 2017 17:16:30 +0200 changed FFT code in graph widget into a more efficient one, with free licence + e95ddb9 csoler Tue, 18 Apr 2017 20:28:36 +0200 Merge pull request #767 from PhenomRetroShare/Fix_CommentWithLineReturn + 5f969e7 csoler Tue, 18 Apr 2017 20:27:20 +0200 Merge pull request #776 from PhenomRetroShare/Fix_ClangWarnings + 3ab39c6 csoler Tue, 18 Apr 2017 20:26:14 +0200 Merge pull request #777 from PhenomRetroShare/Fix_EncodeRadixInRSLinks + 3c5e61a Phenom Tue, 18 Apr 2017 17:36:43 +0200 Encode Radix in RSLinks. + 3733137 Phenom Tue, 18 Apr 2017 11:25:41 +0200 Fix Clang warnings: implicit conversion + 7d9a803 Phenom Tue, 18 Apr 2017 11:18:10 +0200 Fix Clang warnings: bdnet_inet_ntoa C-linkage + 4faaaf7 csoler Mon, 17 Apr 2017 22:03:48 +0200 Merge pull request #775 from csoler/v0.6-PRTest + 87dd614 Phenom Fri, 7 Apr 2017 19:32:19 +0200 Fix Clang Warnings: private field 'encoding_debug_file' is not used + 4f939b2 Phenom Fri, 7 Apr 2017 19:29:27 +0200 Fix Clang warnings: unused function 'set_item_background' + 76f7573 Phenom Fri, 7 Apr 2017 18:48:40 +0200 Fix Clang warnings: comparison of array != a null pointer is always true + 0bbd149 Phenom Fri, 7 Apr 2017 18:42:22 +0200 Fix Clang warnings: comparison of integers of different signs + a476a81 Phenom Fri, 7 Apr 2017 18:40:02 +0200 Fix Clang warnings: function 'update_children_background' is not needed + d8a7313 Phenom Fri, 7 Apr 2017 18:32:55 +0200 Fix Clang warnings: implicit conversion from 'double' to 'int' + 19196e2 Phenom Fri, 7 Apr 2017 18:21:49 +0200 Fix Clang warnings: ariable 'status' is used uninitialized + a3a53b9 Phenom Fri, 7 Apr 2017 18:19:42 +0200 Fix Clang warnings: unused parameter 'req' + 94ac821 Phenom Wed, 29 Mar 2017 18:13:17 +0200 Fix Clang warnings: Unused variable Pi + fd92bca Phenom Tue, 28 Mar 2017 21:18:25 +0200 Fix Clang warnings: variable 'layout' is used uninitialized + 8d85cf5 Phenom Tue, 28 Mar 2017 21:16:05 +0200 Fix Clang warnings: 'xxxWidget::sizeHint' hides overloaded vf + 6f2d7bb Phenom Sun, 19 Mar 2017 10:51:48 +0100 Fix Clang warnings: implicit conversion from 'double' to 'int' + 07b67e9 Phenom Sun, 19 Mar 2017 10:40:34 +0100 Fix Clang warnings: 'PopupDistantChatDialog::init' hides overloaded virtual function + eea49d9 Phenom Sat, 18 Mar 2017 11:56:11 +0100 Fix Clang warnings: change ChatDialog::init definition + 9319caf Phenom Sat, 18 Mar 2017 11:32:56 +0100 Fix Clang warnings: 'Node::advance' hides overloaded virtual function + 13c8f7d Phenom Sat, 18 Mar 2017 11:28:29 +0100 Fix Clang warnings: Infinite recursion + e0225ef Phenom Sat, 18 Mar 2017 11:19:42 +0100 Fix Clang warnings: 'ChatLobbyDialog::init' hides overloaded virtual function + de4f6c0 Phenom Sat, 18 Mar 2017 10:42:38 +0100 Fix Clang warnings: Z-order assignment to spacer + 32eeb95 Phenom Sat, 18 Mar 2017 10:25:23 +0100 Fix Clang warnings: unused private field + 4ac3b3f Phenom Sat, 18 Mar 2017 10:20:57 +0100 Fix Clang warnings: implicit conversion of NULL to bool + e83104e Phenom Sat, 18 Mar 2017 10:19:31 +0100 Fix Clang warnings: Add author and date to #warning + 039908b Phenom Thu, 16 Mar 2017 22:58:06 +0100 Fix Clang warnings: private field not used + 872f42b Phenom Thu, 16 Mar 2017 22:55:18 +0100 Fix Clang warnings: Overloaded vf hide in pluginmanager + 2204309 Phenom Thu, 16 Mar 2017 22:11:33 +0100 Fix Clang warnings: extraneous parentheses + dc533b1 Phenom Thu, 16 Mar 2017 22:01:22 +0100 Fix Clang warnings: private field not used + 6532150 Phenom Thu, 16 Mar 2017 21:04:38 +0100 Fix Clang warnings: Overloaded vf hide in p3dhtmgr + 5bc6558 Phenom Thu, 16 Mar 2017 18:28:48 +0100 Fix Clang warnings: explicitly assigning value to itself + 6fecac5 Phenom Thu, 16 Mar 2017 17:50:25 +0100 Fix Clang warnings: Overloaded vf hide + cf963c0 Phenom Wed, 15 Mar 2017 20:41:39 +0100 Fix Clang warnings: struct declared as class + 105840a Phenom Wed, 15 Mar 2017 19:03:39 +0100 Fix Clang Warning: Overloaded vf hide + da4b168 Phenom Wed, 15 Mar 2017 18:55:24 +0100 Fix Clang warnings: mFns is not used + cbc264f Phenom Wed, 15 Mar 2017 18:53:30 +0100 Fix clang warning:Implicit conversion from enumeration + b2e37fe csoler Sat, 15 Apr 2017 20:24:06 +0200 Merge pull request #773 from csoler/v0.6-Identity + 273aae7 csoler Sat, 15 Apr 2017 19:01:13 +0200 fixed sharing of own identity + 98e1a6d electr Thu, 13 Apr 2017 14:12:46 +0200 Merge pull request #770 from Sonetio/fix_reselecting_accounts + 144d570 Konrad Thu, 13 Apr 2017 13:40:30 +0200 Fixed: Thread safe access to RsControlModule member variables + dcc8c6e Konrad Thu, 13 Apr 2017 13:31:32 +0200 Changed: Using PeersHandler::mRsPeers instead of rsPeers + a382d68 electr Thu, 13 Apr 2017 09:22:19 +0200 Merge pull request #769 from electron128/fix-gui-multiinstance + aa81cc1 Konrad Wed, 12 Apr 2017 20:24:18 +0200 Added: Functions for handling PGP account details requests + 9402b8e Konrad Mon, 10 Apr 2017 23:42:22 +0200 Fixed: mFixedPassword remained empty after logging + e1350a0 Konrad Mon, 10 Apr 2017 22:58:23 +0200 Fixed: Re-selecting accounts via RsControlModule; Added: Sending feedback about incorrect password + 3130ec9 csoler Mon, 10 Apr 2017 20:02:14 +0200 added GUI async call to ID serialised data. Allows to copy+paste identities. + 4c9b620 electr Sun, 9 Apr 2017 10:26:18 +0200 fixed --base-dir command line argument in rs-gui when running multiple instances. Only forward "link" and "rsfile" arguments to a running instance. Start a new instance if other arguments are present. + 7f12ca2 electr Sun, 9 Apr 2017 09:57:48 +0200 fixed name of local socket where RS waits for rslinks etc. + d66e653 csoler Sat, 8 Apr 2017 23:39:05 +0200 fixed bug in deserialisation of group informaiton + 54cd402 csoler Sat, 8 Apr 2017 21:43:07 +0200 fixed a few bugs in latest identity link code + 6d29038 csoler Sat, 8 Apr 2017 21:12:48 +0200 added RSLink for GXS identities + 4f5da86 csoler Sat, 8 Apr 2017 19:07:33 +0200 added method to serialise/deserialise groups to/from memory and export of GxsIdentities to memory chunk in radix format + f175533 Phenom Sat, 8 Apr 2017 14:06:47 +0200 Fix comment view when they have line return. + 4067c95 electr Wed, 5 Apr 2017 18:49:32 +0200 Merge pull request #760 from Sonetio/windows_service + 6e65fcd Konrad Sat, 1 Apr 2017 14:32:49 +0200 Removed: Unused #include statement + 8543525 Konrad Sat, 1 Apr 2017 14:28:55 +0200 Fixed: Linker problem + fbc1bb4 Konrad Wed, 29 Mar 2017 16:06:39 +0200 Added: function for handling autosubscribing lobbies + 22956be Konrad Tue, 28 Mar 2017 11:24:16 +0200 Deleted: functions for hadling particular lobbies types in ChatHandler + 6e53002 Konrad Tue, 28 Mar 2017 11:20:51 +0200 Added: tokens in PeersHandler + efd6ce3 Konrad Tue, 28 Mar 2017 11:19:50 +0200 Changed: Simplified asking for deferred self signature + 5694581 Konrad Tue, 28 Mar 2017 11:18:27 +0200 Changed: Qt dependecies are optional + 4031e49 Konrad Mon, 27 Mar 2017 16:11:04 +0200 Deleted: unused stateTokens + c33107c Konrad Sun, 26 Mar 2017 19:12:04 +0200 Fixed: backward comptiblity + bef7540 Konrad Sun, 26 Mar 2017 15:11:07 +0200 Fixed building on Travis CI + dbcf2d2 csoler Sat, 25 Mar 2017 20:27:18 +0100 Merge pull request #756 from RetroPooh/guistuff + 04af39f csoler Sat, 25 Mar 2017 20:24:40 +0100 Merge pull request #754 from PhenomRetroShare/Fix_WinNoSQLCipherCompil + ccb632a csoler Sat, 25 Mar 2017 19:26:12 +0100 Merge pull request #749 from PhenomRetroShare/Fix_WindowsHeightAtFirstStart + 8624c93 Konrad Sat, 25 Mar 2017 18:33:35 +0100 Added functions for hadling particular lobbies types to ChatHandler + 194878a Konrad Sat, 25 Mar 2017 18:31:13 +0100 Added functions for handling own and not own identities to IdentityHandler + cb32f30 Konrad Sat, 25 Mar 2017 18:28:31 +0100 Added states handling to PeersHandler + 28d37c2 Konrad Sat, 25 Mar 2017 18:25:26 +0100 Added password storing to RsControlModule for GUI benefits + 39967b7 Konrad Sat, 25 Mar 2017 18:23:28 +0100 Added name of requests to be used by GUI + ae95b49 Konrad Sat, 25 Mar 2017 18:20:53 +0100 Added SettingsHandler to handle response to settings requests + cb04134 Konrad Sat, 25 Mar 2017 18:15:47 +0100 Added Windows support to libresapi when working with retroshare_android_service + b0d2249 Konrad Sat, 25 Mar 2017 18:12:39 +0100 Added Windows support to retroshare-android-service + f5e7217 RetroP Tue, 21 Mar 2017 17:24:59 +0300 statistics - router - fix bold marking for tunnel speeds over 1mbs + 85cfda1 RetroP Tue, 21 Mar 2017 16:52:40 +0300 add tree item counters for channels,forums,posted + 50c81d7 RetroP Tue, 21 Mar 2017 16:41:39 +0300 chat lobby list - mark signed lobbies with color + 000dabf RetroP Tue, 21 Mar 2017 15:02:46 +0300 chat lobby list - add tree item counters + 19bd51d RetroP Tue, 21 Mar 2017 14:57:06 +0300 searchdialog - mark current downloads green + 5efa8e3 Phenom Fri, 17 Mar 2017 22:14:14 +0100 Fix Windows Compilation with CONFIG+=no_sqlcipher + ca0521c csoler Thu, 16 Mar 2017 21:01:27 +0100 allowed to edit subject hen editing forum posts. Only the latest subject is visible + 107d48f Phenom Wed, 15 Mar 2017 22:50:51 +0100 Fix windows height at first start. + 2046dbe csoler Wed, 15 Mar 2017 20:53:01 +0100 merged latest fixes from official 0.6.2 release branch + e4fad45 csoler Wed, 15 Mar 2017 20:51:40 +0100 fixed layout in ConfCertDialog, removed overnumerous tabs + 2114374 csoler Wed, 15 Mar 2017 19:26:07 +0100 fixed update of Tor proxy address in hidden nodes server page + 44f2971 csoler Tue, 14 Mar 2017 20:04:22 +0100 Merge pull request #682 from csoler/v0.6-EditPosts + a0d1089 csoler Sat, 11 Mar 2017 18:15:35 +0100 added branch parameter to makeSourcePackage script + fdab480 csoler Sat, 11 Mar 2017 18:10:14 +0100 added minimum version number for debian stretch + 733b114 thunde Fri, 10 Mar 2017 15:57:40 +0100 Updated languages from Transifex + ed5779f csoler Fri, 10 Mar 2017 15:39:22 +0100 Merge pull request #743 from mestaritonttu/patch-22 + 69c3df6 csoler Fri, 10 Mar 2017 15:36:50 +0100 fixed bug in total item size estimation in pqiqosstreamer due to item slicing + c377bf3 csoler Fri, 10 Mar 2017 15:12:10 +0100 fixed debug output for groups with no data + fd84639 csoler Fri, 10 Mar 2017 15:05:41 +0100 removed some debug info + c87de3e csoler Fri, 10 Mar 2017 10:48:40 +0100 fixed mistake in pointer handling + cf2edb5 csoler Thu, 9 Mar 2017 22:47:06 +0100 fixed memory leak in deleteGroup and removed unnecessary pointer in the functions called below + a545481 csoler Thu, 9 Mar 2017 22:05:06 +0100 fixed memory leak when receving multi-chunk file lists + 5b819eb csoler Thu, 9 Mar 2017 20:59:01 +0100 added missing virtual destructor causing a memory leak + 1f8fd95 csoler Thu, 9 Mar 2017 20:48:26 +0100 fixed uninitialised memory read in chacha20 test code + d5f2ae8 csoler Thu, 9 Mar 2017 20:39:12 +0100 fixed memory leak recently introduced with openssl-1.1.0 changes + f76454d csoler Thu, 9 Mar 2017 13:05:03 +0100 updated full pipeline packaging script for debian + 999e845 mestar Wed, 8 Mar 2017 13:17:34 +0200 Fix grammar + e6cf628 csoler Tue, 7 Mar 2017 21:58:59 +0100 Merge pull request #740 from RetroPooh/trstats + 283a2ee csoler Tue, 7 Mar 2017 21:54:56 +0100 Merge pull request #717 from PhenomRetroShare/Fix_SettingListWidth + b3b2a4b csoler Tue, 7 Mar 2017 21:54:10 +0100 Merge pull request #726 from mestaritonttu/patch-8 + bbc27b2 csoler Tue, 7 Mar 2017 21:53:21 +0100 Merge pull request #736 from mestaritonttu/patch-18 + 3d0c28d csoler Tue, 7 Mar 2017 21:52:19 +0100 Merge pull request #724 from mestaritonttu/patch-6 + ed22b48 csoler Tue, 7 Mar 2017 21:51:51 +0100 Merge pull request #738 from mestaritonttu/patch-20 + 376be42 csoler Tue, 7 Mar 2017 21:51:13 +0100 Merge pull request #739 from mestaritonttu/patch-21 + b3578f6 csoler Tue, 7 Mar 2017 21:50:20 +0100 Merge pull request #734 from mestaritonttu/patch-16 + d9c084b csoler Tue, 7 Mar 2017 21:49:52 +0100 Merge pull request #730 from mestaritonttu/patch-12 + 5bad326 csoler Tue, 7 Mar 2017 21:49:14 +0100 Merge pull request #725 from mestaritonttu/patch-7 + ec21698 csoler Tue, 7 Mar 2017 21:48:30 +0100 Merge pull request #727 from mestaritonttu/patch-9 + 7d8e06b csoler Tue, 7 Mar 2017 21:47:43 +0100 Merge pull request #732 from mestaritonttu/patch-14 + f3e29bd csoler Tue, 7 Mar 2017 21:47:00 +0100 Merge pull request #731 from mestaritonttu/patch-13 + 17c44db csoler Tue, 7 Mar 2017 21:46:21 +0100 Merge pull request #733 from mestaritonttu/patch-15 + 5f9f061 csoler Tue, 7 Mar 2017 21:45:50 +0100 Merge pull request #735 from mestaritonttu/patch-17 + 8881a44 csoler Tue, 7 Mar 2017 21:45:11 +0100 Merge pull request #737 from mestaritonttu/patch-19 + 160c289 csoler Tue, 7 Mar 2017 21:44:42 +0100 Merge pull request #728 from mestaritonttu/patch-10 + 22308bc csoler Tue, 7 Mar 2017 21:44:14 +0100 Merge pull request #729 from mestaritonttu/patch-11 + fedffd7 csoler Tue, 7 Mar 2017 21:43:36 +0100 Merge pull request #723 from mestaritonttu/patch-5 + d3f0f9d RetroP Tue, 7 Mar 2017 17:50:13 +0300 router stats - mark active tunnels bold + 87f9dba mestar Tue, 7 Mar 2017 14:05:21 +0200 Improvements and typo fixes in strings + 222cf48 mestar Tue, 7 Mar 2017 14:03:05 +0200 Various improvements and fixes to strings + 83283d9 mestar Tue, 7 Mar 2017 13:58:43 +0200 Remove extra your + 7005126 mestar Tue, 7 Mar 2017 13:57:10 +0200 Added whitespace to strings + 6ec5415 mestar Tue, 7 Mar 2017 13:55:02 +0200 ASCII uppercase + 28d2e27 mestar Tue, 7 Mar 2017 13:53:08 +0200 Remove whitespace from string + 931531b mestar Tue, 7 Mar 2017 13:51:28 +0200 Fix typo + 65c7ca7 mestar Tue, 7 Mar 2017 13:49:57 +0200 Clarify sorting by posts + 21b7861 mestar Tue, 7 Mar 2017 13:48:14 +0200 Fix grammar + ba18fcd mestar Tue, 7 Mar 2017 13:45:31 +0200 Fix grammar + a4c2015 mestar Tue, 7 Mar 2017 13:41:45 +0200 Fix typos + 6b4f7e3 mestar Tue, 7 Mar 2017 13:39:39 +0200 Removed extra "to" + b444567 mestar Tue, 7 Mar 2017 13:34:53 +0200 Added period + 400dde9 mestar Tue, 7 Mar 2017 13:09:04 +0200 Added whitespace + c9a4a55 mestar Tue, 7 Mar 2017 13:06:22 +0200 Fix grammar + 86e7243 mestar Tue, 7 Mar 2017 12:56:25 +0200 Fix typos + d7dc9cc mestar Tue, 7 Mar 2017 12:53:18 +0200 Whitespace inside

+ a518225 csoler Tue, 7 Mar 2017 11:27:17 +0100 Merge pull request #716 from felisucoibi/master + 6a6bcf7 thunde Mon, 6 Mar 2017 21:46:42 +0100 Fixed Windows compile of VOIP + dc65d3f Phenom Sun, 5 Mar 2017 13:22:30 +0100 Fix Setting list width. + 0316c8c thunde Mon, 6 Mar 2017 06:34:06 +0100 Added workaround for crash on Windows 7 for Qt versions with gcc 5.3.0. The call to GetProcAddress in openssl (cryptlib.c) finds an function pointer to the not existing function _OPENSSL_isservice in the executable running on Windows 7. + 313e1b3 csoler Sun, 5 Mar 2017 20:08:53 +0100 updated translation files + 88a5c03 csoler Sun, 5 Mar 2017 20:08:36 +0100 removed some debug info + 94c9c94 thunde Sun, 5 Mar 2017 14:30:45 +0100 updated version number to 0.6.2 in rsversion.in + b71f475 csoler Sun, 5 Mar 2017 14:14:46 +0100 qick fix to allow re-advertising for known forums/channels during the same session. Will be reset at restart (probably best) + fbd72dd csoler Sun, 5 Mar 2017 13:57:49 +0100 fixed settings SoundPage + 15bb0ff felisu Sun, 5 Mar 2017 02:45:37 +0100 Update ChatPage.h + 951820f felisu Sun, 5 Mar 2017 02:45:07 +0100 Update ForumPage.h + 63174aa felisu Sun, 5 Mar 2017 02:44:18 +0100 Update PostedPage.h + ca75515 felisu Sun, 5 Mar 2017 02:43:40 +0100 Update MessagePage.h + d3cdd15 csoler Sat, 4 Mar 2017 21:20:34 +0100 fixed uninitialised memory read in GxsReputation + dec5c5c csoler Sat, 4 Mar 2017 21:13:34 +0100 suppressed uninitialised memory leak in LocalDirectoryStorage + b14e4d5 csoler Sat, 4 Mar 2017 21:08:10 +0100 removed memory leak due to missing delete for BWGraph + 0bd0056 csoler Sat, 4 Mar 2017 20:52:41 +0100 fixed memory leak in RsGxsNetService + 7111579 csoler Sat, 4 Mar 2017 20:52:06 +0100 fixed memory leak in config of msgService + 2302c46 csoler Sat, 4 Mar 2017 16:41:10 +0100 updated version number in changelog + 0024ddf csoler Sat, 4 Mar 2017 16:39:39 +0100 fixed utf8 bug in ShareManager + 3600905 csoler Sat, 4 Mar 2017 12:04:41 +0100 updated packaging files + c715b03 csoler Sat, 4 Mar 2017 11:56:51 +0100 updated version number to 0.6.2 + 5e2a253 csoler Sat, 4 Mar 2017 11:44:31 +0100 updated ubuntu changelog + bd8189c csoler Tue, 28 Feb 2017 18:05:44 +0100 added test to prevent msgs with a different name to be used as different version + 763f227 csoler Sun, 26 Feb 2017 20:39:40 +0100 merged upstream/master into v0.6-EditPosts branch + 22f2edb csoler Sat, 11 Feb 2017 10:45:30 +0100 removed debug info and added comment + ea82d26 csoler Thu, 9 Feb 2017 23:35:59 +0100 fixed signature verification bug for versionned messages + 5bf8376 csoler Thu, 9 Feb 2017 21:49:24 +0100 fixed a few more bugs in post version UI + 8deeec6 csoler Thu, 9 Feb 2017 18:45:55 +0100 fixed UI for post versions + b93130a csoler Thu, 9 Feb 2017 16:15:35 +0100 fixed a few bugs in post version collecting + f8056e5 csoler Thu, 9 Feb 2017 14:49:43 +0100 added collection of older posts versions. + 6681985 csoler Wed, 8 Feb 2017 20:40:47 +0100 merged upstream/master + dfcb66d csoler Fri, 3 Feb 2017 13:02:53 +0100 added spinbox to show older versions + 777a73e csoler Fri, 3 Feb 2017 12:48:51 +0100 added GUI for editing forum messages + + -- Retroshare Dev Team Dim, 23 Apr 2017 16:00:00 +0100 + +retroshare06 (0.6.2-1.931442~trusty) trusty; urgency=low + 931442a csoler Sat, 4 Mar 2017 00:07:51 +0100 fixed compilation b4e0a8f csoler Sat, 4 Mar 2017 00:04:52 +0100 removed unused file DirectoriesPage.{cpp,ui,h} e257563 csoler Sat, 4 Mar 2017 00:01:21 +0100 merged Directories settings page into Transfers and renamed it Files diff --git a/build_scripts/Debian+Ubuntu/control.stretch b/build_scripts/Debian+Ubuntu/control.stretch index 9b557e3b8..6968c9964 100644 --- a/build_scripts/Debian+Ubuntu/control.stretch +++ b/build_scripts/Debian+Ubuntu/control.stretch @@ -2,7 +2,7 @@ Source: retroshare06 Section: devel Priority: standard Maintainer: Cyril Soler -Build-Depends: debhelper (>= 7), libglib2.0-dev, libupnp-dev, libssl-dev, libxss-dev, libgnome-keyring-dev, libbz2-dev, libspeex-dev, libspeexdsp-dev, libxslt1-dev, cmake, libcurl4-openssl-dev, libopencv-dev, tcl8.6, libsqlcipher-dev, libmicrohttpd-dev, libavcodec-dev, qtmultimedia5-dev, qttools5-dev, libqt5x11extras5-dev, qt5-default +Build-Depends: debhelper (>= 7), libglib2.0-dev, libupnp-dev, libssl-dev, libxss-dev, libgnome-keyring-dev, libbz2-dev, libspeex-dev, libspeexdsp-dev, libxslt1-dev, cmake, libcurl4-openssl-dev, libopencv-dev, tcl8.6, libsqlcipher-dev (>= 3.4.0), libmicrohttpd-dev, libavcodec-dev, qtmultimedia5-dev, qttools5-dev, libqt5x11extras5-dev, qt5-default Standards-Version: 3.9.6 Homepage: http://retroshare.sourceforge.net diff --git a/build_scripts/Debian+Ubuntu/control.zesty b/build_scripts/Debian+Ubuntu/control.zesty new file mode 100644 index 000000000..9b557e3b8 --- /dev/null +++ b/build_scripts/Debian+Ubuntu/control.zesty @@ -0,0 +1,44 @@ +Source: retroshare06 +Section: devel +Priority: standard +Maintainer: Cyril Soler +Build-Depends: debhelper (>= 7), libglib2.0-dev, libupnp-dev, libssl-dev, libxss-dev, libgnome-keyring-dev, libbz2-dev, libspeex-dev, libspeexdsp-dev, libxslt1-dev, cmake, libcurl4-openssl-dev, libopencv-dev, tcl8.6, libsqlcipher-dev, libmicrohttpd-dev, libavcodec-dev, qtmultimedia5-dev, qttools5-dev, libqt5x11extras5-dev, qt5-default +Standards-Version: 3.9.6 +Homepage: http://retroshare.sourceforge.net + +Package: retroshare06-voip-plugin +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, retroshare06, libspeex1, libspeexdsp1, libqt5multimedia5 +Description: RetroShare VOIP plugin + This package provides a plugin for RetroShare, a secured Friend-to-Friend communication + plateform. The plugin adds voice-over-IP functionality to the private chat window. Both + friends chatting together need the plugin installed to be able to talk together. + +Package: retroshare06-feedreader-plugin +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, retroshare06 +Description: RetroShare FeedReader plugin + This package provides a plugin for RetroShare, a secured Friend-to-Friend communication + plateform. The plugin adds a RSS feed reader tab to retroshare. + +Package: retroshare06-nogui +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, gnome-keyring +Conflicts: retroshare06 +Description: Secure communication with friends + This is the command-line client for RetroShare network. This client + can be contacted and talked-to using SSL. Clients exist for portable + devices running e.g. Android. + +Package: retroshare06 +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, gnome-keyring +Conflicts: retroshare06-nogui +Description: Secure communication with friends + RetroShare is a Open Source cross-platform, private and secure decentralised + commmunication platform. It lets you to securely chat and share files with your + friends and family, using a web-of-trust to authenticate peers and OpenSSL to + encrypt all communication. RetroShare provides filesharing, chat, messages, + forums and channels. + + diff --git a/build_scripts/Debian+Ubuntu/makeSourcePackage.sh b/build_scripts/Debian+Ubuntu/makeSourcePackage.sh index 45c4ffc33..dc5892b07 100755 --- a/build_scripts/Debian+Ubuntu/makeSourcePackage.sh +++ b/build_scripts/Debian+Ubuntu/makeSourcePackage.sh @@ -4,6 +4,7 @@ version="0.6.2" gitpath="https://github.com/RetroShare/RetroShare.git" workdir=retroshare06-${version} +branch="v0.6.2-official_release" #bubba3="Y" # comment out to compile for bubba3 ###################################################### @@ -53,7 +54,7 @@ while [ ${#} -gt 0 ]; do done if test "${dist}" = "" ; then - dist="precise trusty vivid xenial yakkety" + dist="precise trusty vivid xenial yakkety zesty" fi echo Attempting to get revision number... @@ -66,6 +67,7 @@ echo " "Commit count : ${ccount} echo " "Date : ${date} echo " "Time : ${time} echo " "Hash : ${hhsh} +echo " "Using branch : ${branch} echo " "Using revision : ${rev} echo Done. @@ -80,7 +82,7 @@ echo Extracting base archive... mkdir -p ${workdir}/src echo Checking out latest snapshot... cd ${workdir}/src -git clone --depth 1 https://github.com/RetroShare/RetroShare.git . +git clone --depth 1 https://github.com/RetroShare/RetroShare.git --single-branch --branch $branch . cd - if ! test -d ${workdir}/src/libretroshare/; then @@ -114,6 +116,8 @@ for i in ${dist}; do if test "${i}" = "lucid" ; then cp ../control.ubuntu_lucid debian/control + elif test "${i}" = "zesty" ; then + cp ../control.zesty debian/control elif test "${i}" = "squeeze" ; then cp ../control.squeeze_bubba3 debian/control elif test "${i}" = "precise" ; then diff --git a/libbitdht/src/udp/udpbitdht.cc b/libbitdht/src/udp/udpbitdht.cc index 5410d50e0..39c13e182 100644 --- a/libbitdht/src/udp/udpbitdht.cc +++ b/libbitdht/src/udp/udpbitdht.cc @@ -58,7 +58,7 @@ /*************************************/ UdpBitDht::UdpBitDht(UdpPublisher *pub, bdNodeId *id, std::string appVersion, std::string bootstrapfile, const std::string& filteredipfile, bdDhtFunctions *fns) - :UdpSubReceiver(pub), dhtMtx(true), mFns(fns) + :UdpSubReceiver(pub), dhtMtx(true)//, mFns(fns) { std::string usedVersion; diff --git a/libbitdht/src/udp/udpbitdht.h b/libbitdht/src/udp/udpbitdht.h index 36946877e..f1e167abf 100644 --- a/libbitdht/src/udp/udpbitdht.h +++ b/libbitdht/src/udp/udpbitdht.h @@ -119,7 +119,7 @@ void clearDataTransferred(); bdMutex dhtMtx; /* for all class data (below) */ bdNodeManager *mBitDhtManager; - bdDhtFunctions *mFns; + //bdDhtFunctions *mFns; uint32_t mReadBytes; diff --git a/libbitdht/src/util/bdbloom.cc b/libbitdht/src/util/bdbloom.cc index 36f3a3bee..016808ea4 100644 --- a/libbitdht/src/util/bdbloom.cc +++ b/libbitdht/src/util/bdbloom.cc @@ -144,6 +144,11 @@ std::string bloomFilter::getFilter() bytes++; } + if (bytes==0) + { + std::cerr << "(EE) Error. Cannot allocate memory for 0 byte in " << __PRETTY_FUNCTION__ << std::endl; + return std::string(); + } // convert to binary array. uint8_t *tmparray = (uint8_t *) malloc(bytes); diff --git a/libbitdht/src/util/bdnet.h b/libbitdht/src/util/bdnet.h index 9b9d36f48..7e3e24644 100644 --- a/libbitdht/src/util/bdnet.h +++ b/libbitdht/src/util/bdnet.h @@ -103,8 +103,6 @@ int bdnet_inet_aton(const char *name, struct in_addr *addr); int bdnet_checkTTL(int fd); void bdsockaddr_clear(struct sockaddr_in *addr); -/* thread-safe version of inet_ntoa */ -std::string bdnet_inet_ntoa(struct in_addr in); /* Extra stuff to declare for windows error handling (mimics unix errno) */ @@ -175,4 +173,7 @@ int usleep(unsigned int usec); } /* C Interface */ #endif +/* thread-safe version of inet_ntoa */ +std::string bdnet_inet_ntoa(struct in_addr in); + #endif /* BITDHT_UNIVERSAL_NETWORK_HEADER */ diff --git a/libresapi/src/api/ApiServer.cpp b/libresapi/src/api/ApiServer.cpp index b9606a003..327dd6260 100644 --- a/libresapi/src/api/ApiServer.cpp +++ b/libresapi/src/api/ApiServer.cpp @@ -17,6 +17,10 @@ #include "ChannelsHandler.h" #include "StatsHandler.h" +#ifdef LIBRESAPI_QT + #include "SettingsHandler.h" +#endif + /* data types in json http://json.org/ string (utf-8 unicode) @@ -237,6 +241,9 @@ public: mApiPluginHandler(sts, ifaces), mChannelsHandler(ifaces.mGxsChannels), mStatsHandler() +#ifdef LIBRESAPI_QT + ,mSettingsHandler(sts) +#endif { // the dynamic cast is to not confuse the addResourceHandler template like this: // addResourceHandler(derived class, parent class) @@ -262,7 +269,11 @@ public: &ChannelsHandler::handleRequest); router.addResourceHandler("stats", dynamic_cast(&mStatsHandler), &StatsHandler::handleRequest); - } +#ifdef LIBRESAPI_QT + router.addResourceHandler("settings", dynamic_cast(&mSettingsHandler), + &SettingsHandler::handleRequest); +#endif + } PeersHandler mPeersHandler; IdentityHandler mIdentityHandler; @@ -274,6 +285,10 @@ public: ApiPluginHandler mApiPluginHandler; ChannelsHandler mChannelsHandler; StatsHandler mStatsHandler; + +#ifdef LIBRESAPI_QT + SettingsHandler mSettingsHandler; +#endif }; ApiServer::ApiServer(): @@ -362,6 +377,9 @@ std::string ApiServer::handleRequest(Request &request) if(data.isRawData()) return data.getRawData(); + if(!resp.mCallbackName.empty()) + outstream << resource_api::makeKeyValueReference("callback_name", resp.mCallbackName); + outstream << resource_api::makeKeyValue("debug_msg", debugString.str()); outstream << resource_api::makeKeyValueReference("returncode", returncode); if(!resp.mStateToken.isNull()) diff --git a/libresapi/src/api/ApiTypes.h b/libresapi/src/api/ApiTypes.h index c443eb170..6d6d5c746 100644 --- a/libresapi/src/api/ApiTypes.h +++ b/libresapi/src/api/ApiTypes.h @@ -252,6 +252,9 @@ public: StateToken mStateToken; + //Just for GUI benefit + std::string mCallbackName; + // the result StreamBase& mDataStream; diff --git a/libresapi/src/api/ChatHandler.cpp b/libresapi/src/api/ChatHandler.cpp index 4335389df..6e7fa07fe 100644 --- a/libresapi/src/api/ChatHandler.cpp +++ b/libresapi/src/api/ChatHandler.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -144,8 +145,10 @@ ChatHandler::ChatHandler(StateTokenServer *sts, RsNotify *notify, RsMsgs *msgs, addResourceHandler("*", this, &ChatHandler::handleWildcard); addResourceHandler("lobbies", this, &ChatHandler::handleLobbies); + addResourceHandler("create_lobby", this, &ChatHandler::handleCreateLobby); addResourceHandler("subscribe_lobby", this, &ChatHandler::handleSubscribeLobby); addResourceHandler("unsubscribe_lobby", this, &ChatHandler::handleUnsubscribeLobby); + addResourceHandler("autosubscribe_lobby", this, &ChatHandler::handleAutoSubsribeLobby); addResourceHandler("clear_lobby", this, &ChatHandler::handleClearLobby); addResourceHandler("lobby_participants", this, &ChatHandler::handleLobbyParticipants); addResourceHandler("messages", this, &ChatHandler::handleMessages); @@ -889,6 +892,15 @@ void ChatHandler::handleUnsubscribeLobby(Request &req, Response &resp) resp.setOk(); } +void ChatHandler::handleAutoSubsribeLobby(Request& req, Response& resp) +{ + ChatLobbyId chatId = 0; + bool autosubsribe; + req.mStream << makeKeyValueReference("chatid", chatId) << makeKeyValueReference("autosubsribe", autosubsribe); + mRsMsgs->setLobbyAutoSubscribe(chatId, autosubsribe); + resp.setOk(); +} + void ChatHandler::handleClearLobby(Request &req, Response &resp) { ChatLobbyId id = 0; @@ -930,13 +942,14 @@ void ChatHandler::handleMessages(Request &req, Response &resp) { RS_STACK_MUTEX(mMtx); /********** LOCKED **********/ - ChatId id(req.mPath.top()); + ChatId id(req.mPath.top()); + // make response a list resp.mDataStream.getStreamToMember(); if(id.isNotSet()) { - resp.setFail("\""+req.mPath.top()+"\" is not a valid chat id"); - return; + resp.setFail("\""+req.mPath.top()+"\" is not a valid chat id"); + return; } std::map >::iterator mit = mMsgs.find(id); if(mit == mMsgs.end()) @@ -973,10 +986,11 @@ void ChatHandler::handleSendMessage(Request &req, Response &resp) void ChatHandler::handleMarkChatAsRead(Request &req, Response &resp) { RS_STACK_MUTEX(mMtx); /********** LOCKED **********/ - ChatId id(req.mPath.top()); + ChatId id(req.mPath.top()); + if(id.isNotSet()) { - resp.setFail("\""+req.mPath.top()+"\" is not a valid chat id"); + resp.setFail("\""+req.mPath.top()+"\" is not a valid chat id"); return; } std::map >::iterator mit = mMsgs.find(id); @@ -1197,4 +1211,37 @@ void ChatHandler::handleCloseDistantChatConnexion(Request& req, Response& resp) else resp.setFail("Failed to close distant chat"); } +void ChatHandler::handleCreateLobby(Request& req, Response& resp) +{ + std::set invited_identites; + std::string lobby_name; + std::string lobby_topic; + std::string gxs_id; + + req.mStream << makeKeyValueReference("lobby_name", lobby_name); + req.mStream << makeKeyValueReference("lobby_topic", lobby_topic); + req.mStream << makeKeyValueReference("gxs_id", gxs_id); + + RsGxsId gxsId(gxs_id); + + bool lobby_public; + bool pgp_signed; + + req.mStream << makeKeyValueReference("lobby_public", lobby_public); + req.mStream << makeKeyValueReference("pgp_signed", pgp_signed); + + ChatLobbyFlags lobby_flags; + + if(lobby_public) + lobby_flags |= RS_CHAT_LOBBY_FLAGS_PUBLIC; + + if(pgp_signed) + lobby_flags |= RS_CHAT_LOBBY_FLAGS_PGP_SIGNED; + + mRsMsgs->createChatLobby(lobby_name, gxsId, lobby_topic, invited_identites, lobby_flags); + + tick(); + resp.setOk(); +} + } // namespace resource_api diff --git a/libresapi/src/api/ChatHandler.h b/libresapi/src/api/ChatHandler.h index dc075c77f..9cda3e551 100644 --- a/libresapi/src/api/ChatHandler.h +++ b/libresapi/src/api/ChatHandler.h @@ -118,8 +118,10 @@ public: private: void handleWildcard(Request& req, Response& resp); void handleLobbies(Request& req, Response& resp); + void handleCreateLobby(Request& req, Response& resp); void handleSubscribeLobby(Request& req, Response& resp); void handleUnsubscribeLobby(Request& req, Response& resp); + void handleAutoSubsribeLobby(Request& req, Response& resp); void handleClearLobby(Request& req, Response& resp); ResponseTask* handleLobbyParticipants(Request& req, Response& resp); void handleMessages(Request& req, Response& resp); diff --git a/libresapi/src/api/FileSearchHandler.cpp b/libresapi/src/api/FileSearchHandler.cpp index 2b56317ad..c159ad913 100644 --- a/libresapi/src/api/FileSearchHandler.cpp +++ b/libresapi/src/api/FileSearchHandler.cpp @@ -10,8 +10,8 @@ namespace resource_api { -FileSearchHandler::FileSearchHandler(StateTokenServer *sts, RsNotify *notify, RsTurtle *turtle, RsFiles *files): - mStateTokenServer(sts), mNotify(notify), mTurtle(turtle), mFiles(files), +FileSearchHandler::FileSearchHandler(StateTokenServer *sts, RsNotify *notify, RsTurtle *turtle, RsFiles */*files*/): + mStateTokenServer(sts), mNotify(notify), mTurtle(turtle),// mFiles(files), mMtx("FileSearchHandler") { mNotify->registerNotifyClient(this); diff --git a/libresapi/src/api/FileSearchHandler.h b/libresapi/src/api/FileSearchHandler.h index 1cab730a4..a049c2207 100644 --- a/libresapi/src/api/FileSearchHandler.h +++ b/libresapi/src/api/FileSearchHandler.h @@ -24,7 +24,7 @@ private: StateTokenServer* mStateTokenServer; RsNotify* mNotify; RsTurtle* mTurtle; - RsFiles* mFiles; + //RsFiles* mFiles; class Search{ public: diff --git a/libresapi/src/api/IdentityHandler.cpp b/libresapi/src/api/IdentityHandler.cpp index 4d3f0ff80..be2e28622 100644 --- a/libresapi/src/api/IdentityHandler.cpp +++ b/libresapi/src/api/IdentityHandler.cpp @@ -1,6 +1,7 @@ #include "IdentityHandler.h" #include +#include #include #include "Operators.h" @@ -95,15 +96,59 @@ protected: } }; +class DeleteIdentityTask : public GxsResponseTask +{ +public: + DeleteIdentityTask(RsIdentity* idservice) : + GxsResponseTask(idservice, idservice->getTokenService()), + mToken(0), + mRsIdentity(idservice) + {} + +protected: + virtual void gxsDoWork(Request &req, Response &resp) + { + RsGxsIdGroup group; + std::string gxs_id; + + req.mStream << makeKeyValueReference("gxs_id", gxs_id); + group.mMeta.mGroupId = RsGxsGroupId(gxs_id); + + mRsIdentity->deleteIdentity(mToken, group); + addWaitingToken(mToken); + + done(); + return; + } + +private: + uint32_t mToken; + RsIdentity* mRsIdentity; + RsGxsId mId; +}; + IdentityHandler::IdentityHandler(StateTokenServer *sts, RsNotify *notify, RsIdentity *identity): mStateTokenServer(sts), mNotify(notify), mRsIdentity(identity), mMtx("IdentityHandler Mtx"), mStateToken(sts->getNewToken()) { mNotify->registerNotifyClient(this); - addResourceHandler("*", this, &IdentityHandler::handleWildcard); - addResourceHandler("own", this, &IdentityHandler::handleOwn); - addResourceHandler("create_identity", this, &IdentityHandler::handleCreateIdentity); + addResourceHandler("*", this, &IdentityHandler::handleWildcard); + addResourceHandler("own", this, &IdentityHandler::handleOwn); + + addResourceHandler("own_ids", this, &IdentityHandler::handleOwnIdsRequest); + addResourceHandler("notown_ids", this, &IdentityHandler::handleNotOwnIdsRequest); + + addResourceHandler("add_contact", this, &IdentityHandler::handleAddContact); + addResourceHandler("remove_contact", this, &IdentityHandler::handleRemoveContact); + + addResourceHandler("create_identity", this, &IdentityHandler::handleCreateIdentity); + addResourceHandler("delete_identity", this, &IdentityHandler::handleDeleteIdentity); + + addResourceHandler("get_identity_details", this, &IdentityHandler::handleGetIdentityDetails); + + addResourceHandler("set_ban_node", this, &IdentityHandler::handleSetBanNode); + addResourceHandler("set_opinion", this, &IdentityHandler::handleSetOpinion); } IdentityHandler::~IdentityHandler() @@ -162,6 +207,7 @@ void IdentityHandler::handleWildcard(Request & /*req*/, Response &resp) << makeKeyValueReference("gxs_id", grp.mMeta.mGroupId) << makeKeyValueReference("pgp_id",grp.mPgpId ) << makeKeyValueReference("name", grp.mMeta.mGroupName) + << makeKeyValueReference("contact", grp.mIsAContact) << makeKeyValueReference("own", own) << makeKeyValueReference("pgp_linked", pgp_linked); } @@ -172,6 +218,313 @@ void IdentityHandler::handleWildcard(Request & /*req*/, Response &resp) else resp.setFail(); } + +void IdentityHandler::handleNotOwnIdsRequest(Request & /*req*/, Response &resp) +{ + bool ok = true; + + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStateToken; + } + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + uint32_t token; + mRsIdentity->getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts); + + time_t start = time(NULL); + while((mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + &&(mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_FAILED) + &&((time(NULL) < (start+10))) + ) + { +#ifdef WINDOWS_SYS + Sleep(500); +#else + usleep(500*1000); +#endif + } + + if(mRsIdentity->getTokenService()->requestStatus(token) == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + { + std::vector grps; + ok &= mRsIdentity->getGroupData(token, grps); + for(std::vector::iterator vit = grps.begin(); vit != grps.end(); vit++) + { + RsGxsIdGroup& grp = *vit; + //electron: not very happy about this, i think the flags should stay hidden in rsidentities + if(!(grp.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) && grp.mIsAContact) + { + bool pgp_linked = (grp.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility ) ; + resp.mDataStream.getStreamToMember() + << makeKeyValueReference("id", grp.mMeta.mGroupId) /// @deprecated using "id" as key can cause problems in some JS based languages like Qml @see gxs_id instead + << makeKeyValueReference("gxs_id", grp.mMeta.mGroupId) + << makeKeyValueReference("pgp_id",grp.mPgpId ) + << makeKeyValueReference("name", grp.mMeta.mGroupName) + << makeKeyValueReference("pgp_linked", pgp_linked); + } + } + } + else ok = false; + + if(ok) resp.setOk(); + else resp.setFail(); +} + +void IdentityHandler::handleOwnIdsRequest(Request & /*req*/, Response &resp) +{ + bool ok = true; + + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStateToken; + } + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + uint32_t token; + mRsIdentity->getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts); + + time_t start = time(NULL); + while((mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + &&(mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_FAILED) + &&((time(NULL) < (start+10))) + ) + { +#ifdef WINDOWS_SYS + Sleep(500); +#else + usleep(500*1000); +#endif + } + + if(mRsIdentity->getTokenService()->requestStatus(token) == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + { + std::vector grps; + ok &= mRsIdentity->getGroupData(token, grps); + for(std::vector::iterator vit = grps.begin(); vit != grps.end(); vit++) + { + RsGxsIdGroup& grp = *vit; + //electron: not very happy about this, i think the flags should stay hidden in rsidentities + if(vit->mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) + { + bool pgp_linked = (grp.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility ) ; + resp.mDataStream.getStreamToMember() + << makeKeyValueReference("own_gxs_id", grp.mMeta.mGroupId) + << makeKeyValueReference("pgp_id",grp.mPgpId ) + << makeKeyValueReference("name", grp.mMeta.mGroupName) + << makeKeyValueReference("pgp_linked", pgp_linked); + } + } + + } + else + ok = false; + + if(ok) resp.setOk(); + else resp.setFail(); +} + +void IdentityHandler::handleAddContact(Request& req, Response& resp) +{ + std::string gxs_id; + req.mStream << makeKeyValueReference("gxs_id", gxs_id); + + mRsIdentity->setAsRegularContact(RsGxsId(gxs_id), true); + + { + RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ + mStateTokenServer->replaceToken(mStateToken); + } + + resp.setOk(); +} + +void IdentityHandler::handleRemoveContact(Request& req, Response& resp) +{ + std::string gxs_id; + req.mStream << makeKeyValueReference("gxs_id", gxs_id); + + mRsIdentity->setAsRegularContact(RsGxsId(gxs_id), false); + + { + RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ + mStateTokenServer->replaceToken(mStateToken); + } + + resp.setOk(); +} + +void IdentityHandler::handleGetIdentityDetails(Request& req, Response& resp) +{ + std::string gxs_id; + req.mStream << makeKeyValueReference("gxs_id", gxs_id); + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + uint32_t token; + + std::list groupIds; + groupIds.push_back(RsGxsGroupId(gxs_id)); + mRsIdentity->getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds); + + time_t start = time(NULL); + while((mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + &&(mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_FAILED) + &&((time(NULL) < (start+10))) + ) + { +#ifdef WINDOWS_SYS + Sleep(500); +#else + usleep(500*1000); +#endif + } + + RsGxsIdGroup data; + std::vector datavector; + if (!mRsIdentity->getGroupData(token, datavector)) + { + resp.setFail(); + return; + } + + if(datavector.empty()) + { + resp.setFail(); + return; + } + + data = datavector[0]; + + resp.mDataStream << makeKeyValue("gxs_name", data.mMeta.mGroupName); + resp.mDataStream << makeKeyValue("gxs_id", data.mMeta.mGroupId.toStdString()); + + resp.mDataStream << makeKeyValue("pgp_id_known", data.mPgpKnown); + resp.mDataStream << makeKeyValue("pgp_id", data.mPgpId.toStdString()); + + std::string pgp_name; + if (data.mPgpKnown) + { + RsPeerDetails details; + rsPeers->getGPGDetails(data.mPgpId, details); + pgp_name = details.name; + } + else + { + if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility) + pgp_name = "[Unknown node]"; + else + pgp_name = "Anonymous Id"; + } + resp.mDataStream << makeKeyValue("pgp_name", pgp_name); + + resp.mDataStream << makeKeyValue("last_usage", (uint32_t)data.mLastUsageTS); + + bool isAnonymous = false; + if(!data.mPgpKnown) + { + if (!(data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility)) + isAnonymous = true; + } + resp.mDataStream << makeKeyValue("anonymous", isAnonymous); + + + bool isOwnId = (data.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN); + resp.mDataStream << makeKeyValue("own", isOwnId); + + std::string type; + if(isOwnId) + { + if (data.mPgpKnown && !data.mPgpId.isNull()) + type = "Identity owned by you, linked to your Retroshare node"; + else + type = "Anonymous identity, owned by you"; + } + else if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility) + { + if (data.mPgpKnown) + { + if (rsPeers->isGPGAccepted(data.mPgpId)) + type = "Linked to a friend Retroshare node"; + else + type = "Linked to a known Retroshare node"; + } + else + type = "Linked to unknown Retroshare node"; + } + else + type = "Anonymous identity"; + + resp.mDataStream << makeKeyValue("type", type); + + resp.mDataStream << makeKeyValue("bannned_node", rsReputations->isNodeBanned(data.mPgpId)); + + RsReputations::ReputationInfo info; + rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId), data.mPgpId, info); + resp.mDataStream << makeKeyValue("friends_positive_votes", info.mFriendsPositiveVotes); + resp.mDataStream << makeKeyValue("friends_negative_votes", info.mFriendsNegativeVotes); + resp.mDataStream << makeKeyValue("overall_reputation_level", (int)info.mOverallReputationLevel); + resp.mDataStream << makeKeyValue("own_opinion", (int)info.mOwnOpinion); + + RsIdentityDetails details; + mRsIdentity->getIdDetails(RsGxsId(data.mMeta.mGroupId), details); + StreamBase& usagesStream = resp.mDataStream.getStreamToMember("usages"); + usagesStream.getStreamToMember(); + + for(std::map::const_iterator it(details.mUseCases.begin()); it != details.mUseCases.end(); ++it) + { + usagesStream.getStreamToMember() + << makeKeyValue("usage_time", (uint32_t)data.mLastUsageTS) + << makeKeyValue("usage_service", (int)(it->first.mServiceId)) + << makeKeyValue("usage_case", (int)(it->first.mUsageCode)); + } + + resp.setOk(); +} + +void IdentityHandler::handleSetBanNode(Request& req, Response& resp) +{ + std::string pgp_id; + req.mStream << makeKeyValueReference("pgp_id", pgp_id); + RsPgpId pgpId(pgp_id); + + bool banned_node; + req.mStream << makeKeyValueReference("banned_node", banned_node); + rsReputations->banNode(pgpId, banned_node); + + resp.setOk(); +} + +void IdentityHandler::handleSetOpinion(Request& req, Response& resp) +{ + std::string gxs_id; + req.mStream << makeKeyValueReference("gxs_id", gxs_id); + RsGxsId gxsId(gxs_id); + + int own_opinion; + req.mStream << makeKeyValueReference("own_opinion", own_opinion); + + RsReputations::Opinion opinion; + switch(own_opinion) + { + case 0: + opinion = RsReputations::OPINION_NEGATIVE; + break; + case 1: opinion = + RsReputations::OPINION_NEUTRAL; + break; + case 2: + opinion = RsReputations::OPINION_POSITIVE; + break; + default: + resp.setFail(); + return; + } + rsReputations->setOwnOpinion(gxsId, opinion); + + resp.setOk(); +} + ResponseTask* IdentityHandler::handleOwn(Request & /* req */, Response &resp) { StateToken state; @@ -192,4 +545,9 @@ ResponseTask* IdentityHandler::handleCreateIdentity(Request & /* req */, Respons return new CreateIdentityTask(mRsIdentity); } +ResponseTask* IdentityHandler::handleDeleteIdentity(Request& req, Response& resp) +{ + return new DeleteIdentityTask(mRsIdentity); +} + } // namespace resource_api diff --git a/libresapi/src/api/IdentityHandler.h b/libresapi/src/api/IdentityHandler.h index 5e5d67f13..bac61f574 100644 --- a/libresapi/src/api/IdentityHandler.h +++ b/libresapi/src/api/IdentityHandler.h @@ -23,8 +23,20 @@ public: private: void handleWildcard(Request& req, Response& resp); + void handleNotOwnIdsRequest(Request& req, Response& resp); + void handleOwnIdsRequest(Request& req, Response& resp); + + void handleAddContact(Request& req, Response& resp); + void handleRemoveContact(Request& req, Response& resp); + + void handleGetIdentityDetails(Request& req, Response& resp); + + void handleSetBanNode(Request& req, Response& resp); + void handleSetOpinion(Request& req, Response& resp); + ResponseTask *handleOwn(Request& req, Response& resp); ResponseTask *handleCreateIdentity(Request& req, Response& resp); + ResponseTask *handleDeleteIdentity(Request& req, Response& resp); StateTokenServer* mStateTokenServer; RsNotify* mNotify; diff --git a/libresapi/src/api/PeersHandler.cpp b/libresapi/src/api/PeersHandler.cpp index 0f35e59e9..d7f13fd6e 100644 --- a/libresapi/src/api/PeersHandler.cpp +++ b/libresapi/src/api/PeersHandler.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include @@ -12,6 +14,12 @@ namespace resource_api { +#define PEER_STATE_ONLINE 1 +#define PEER_STATE_BUSY 2 +#define PEER_STATE_AWAY 3 +#define PEER_STATE_AVAILABLE 4 +#define PEER_STATE_INACTIVE 5 +#define PEER_STATE_OFFLINE 6 // todo: groups, add friend, remove friend, permissions void peerDetailsToStream(StreamBase& stream, RsPeerDetails& details) @@ -21,7 +29,50 @@ void peerDetailsToStream(StreamBase& stream, RsPeerDetails& details) << makeKeyValueReference("name", details.name) << makeKeyValueReference("location", details.location) << makeKeyValueReference("pgp_id", details.gpg_id) - ; + << makeKeyValueReference("pgp_id", details.gpg_id); + + if(details.state & RS_PEER_STATE_CONNECTED) + { + std::list statusInfo; + rsStatus->getStatusList(statusInfo); + + std::string state_string; + std::list::iterator it; + for (it = statusInfo.begin(); it != statusInfo.end(); ++it) + { + if (it->id == details.id) + { + switch (it->status) + { + case RS_STATUS_INACTIVE: + state_string = "inactive"; + break; + + case RS_STATUS_ONLINE: + state_string = "online"; + break; + + case RS_STATUS_AWAY: + state_string = "away"; + break; + + case RS_STATUS_BUSY: + state_string = "busy"; + break; + default: + state_string = "undefined"; + break; + } + break; + } + } + stream << makeKeyValueReference("state_string", state_string); + } + else + { + std::string state_string = "undefined"; + stream << makeKeyValueReference("state_string", state_string); + } } bool peerInfoToStream(StreamBase& stream, RsPeerDetails& details, RsPeers* peers, std::list& grpInfo, bool have_avatar) @@ -29,7 +80,9 @@ bool peerInfoToStream(StreamBase& stream, RsPeerDetails& details, RsPeers* peers bool ok = true; peerDetailsToStream(stream, details); stream << makeKeyValue("is_online", peers->isOnline(details.id)) - << makeKeyValue("chat_id", ChatId(details.id).toStdString()); + << makeKeyValue("chat_id", ChatId(details.id).toStdString()) + << makeKeyValue("custom_state_string", rsMsgs->getCustomStateString(details.id)); + std::string avatar_address = "/"+details.id.toStdString()+"/avatar_image"; @@ -54,6 +107,84 @@ bool peerInfoToStream(StreamBase& stream, RsPeerDetails& details, RsPeers* peers return ok; } +std::string peerStateString(int peerState) +{ + if (peerState & RS_PEER_STATE_CONNECTED) { + return "Connected"; + } else if (peerState & RS_PEER_STATE_UNREACHABLE) { + return "Unreachable"; + } else if (peerState & RS_PEER_STATE_ONLINE) { + return "Available"; + } else if (peerState & RS_PEER_STATE_FRIEND) { + return "Offline"; + } + + return "Neighbor"; +} + +std::string connectStateString(RsPeerDetails &details) +{ + std::string stateString; + bool isConnected = false; + + switch (details.connectState) { + case 0: + stateString = peerStateString(details.state); + break; + case RS_PEER_CONNECTSTATE_TRYING_TCP: + stateString = "Trying TCP"; + break; + case RS_PEER_CONNECTSTATE_TRYING_UDP: + stateString = "Trying UDP"; + break; + case RS_PEER_CONNECTSTATE_CONNECTED_TCP: + stateString = "Connected: TCP"; + isConnected = true; + break; + case RS_PEER_CONNECTSTATE_CONNECTED_UDP: + stateString = "Connected: UDP"; + isConnected = true; + break; + case RS_PEER_CONNECTSTATE_CONNECTED_TOR: + stateString = "Connected: Tor"; + isConnected = true; + break; + case RS_PEER_CONNECTSTATE_CONNECTED_I2P: + stateString = "Connected: I2P"; + isConnected = true; + break; + case RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN: + stateString = "Connected: Unknown"; + isConnected = true; + break; + } + + if(isConnected) { + stateString += " "; + if(details.actAsServer) + stateString += "inbound connection"; + else + stateString += "outbound connection"; + } + + if (details.connectStateString.empty() == false) { + if (stateString.empty() == false) { + stateString += ": "; + } + stateString += details.connectStateString; + } + + /* HACK to display DHT Status info too */ + if (details.foundDHT) { + if (stateString.empty() == false) { + stateString += ", "; + } + stateString += "DHT: Contact"; + } + + return stateString; +} + PeersHandler::PeersHandler(StateTokenServer* sts, RsNotify* notify, RsPeers *peers, RsMsgs* msgs): mStateTokenServer(sts), mNotify(notify), @@ -63,7 +194,15 @@ PeersHandler::PeersHandler(StateTokenServer* sts, RsNotify* notify, RsPeers *pee mNotify->registerNotifyClient(this); mStateTokenServer->registerTickClient(this); addResourceHandler("*", this, &PeersHandler::handleWildcard); - addResourceHandler("examine_cert", this, &PeersHandler::handleExamineCert); + addResourceHandler("get_state_string", this, &PeersHandler::handleGetStateString); + addResourceHandler("set_state_string", this, &PeersHandler::handleSetStateString); + addResourceHandler("get_custom_state_string", this, &PeersHandler::handleGetCustomStateString); + addResourceHandler("set_custom_state_string", this, &PeersHandler::handleSetCustomStateString); + addResourceHandler("get_pgp_options", this, &PeersHandler::handleGetPGPOptions); + addResourceHandler("set_pgp_options", this, &PeersHandler::handleSetPGPOptions); + addResourceHandler("get_node_options", this, &PeersHandler::handleGetNodeOptions); + addResourceHandler("set_node_options", this, &PeersHandler::handleSetNodeOptions); + addResourceHandler("examine_cert", this, &PeersHandler::handleExamineCert); } PeersHandler::~PeersHandler() @@ -82,6 +221,12 @@ void PeersHandler::notifyListChange(int list, int /* type */) } } +void PeersHandler::notifyPeerStatusChanged(const std::string& /*peer_id*/, uint32_t /*state*/) +{ + RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ + mStateTokenServer->replaceToken(mStateToken); +} + void PeersHandler::notifyPeerHasNewAvatar(std::string /*peer_id*/) { RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ @@ -100,6 +245,27 @@ void PeersHandler::tick() mStateTokenServer->discardToken(mStateToken); mStateToken = mStateTokenServer->getNewToken(); } + + StatusInfo statusInfo; + rsStatus->getOwnStatus(statusInfo); + if(statusInfo.status != status) + { + status = statusInfo.status; + + RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ + mStateTokenServer->discardToken(mStringStateToken); + mStringStateToken = mStateTokenServer->getNewToken(); + } + + std::string custom_state = rsMsgs->getCustomStateString(); + if(custom_state != custom_state_string) + { + custom_state_string = custom_state; + + RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ + mStateTokenServer->discardToken(mCustomStateToken); + mCustomStateToken = mStateTokenServer->getNewToken(); + } } void PeersHandler::notifyUnreadMsgCountChanged(const RsPeerId &peer, uint32_t count) @@ -121,6 +287,73 @@ static bool have_avatar(RsMsgs* msgs, const RsPeerId& id) return size != 0; } +void PeersHandler::handleGetStateString(Request& /*req*/, Response& resp) +{ + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStringStateToken; + } + + std::string state_string; + StatusInfo statusInfo; + if (rsStatus->getOwnStatus(statusInfo)) + { + if(statusInfo.status == RS_STATUS_ONLINE) + state_string = "online"; + else if(statusInfo.status == RS_STATUS_BUSY) + state_string = "busy"; + else if(statusInfo.status == RS_STATUS_AWAY) + state_string = "away"; + else if(statusInfo.status == RS_STATUS_INACTIVE) + state_string = "inactive"; + else + state_string = "undefined"; + } + else + state_string = "undefined"; + + resp.mDataStream << makeKeyValueReference("state_string", state_string); + resp.setOk(); +} + +void PeersHandler::handleSetStateString(Request& req, Response& resp) +{ + std::string state_string; + req.mStream << makeKeyValueReference("state_string", state_string); + + uint32_t status = RS_STATUS_OFFLINE; + if(state_string == "online") + status = RS_STATUS_ONLINE; + else if(state_string == "busy") + status = RS_STATUS_BUSY; + else if(state_string == "away") + status = RS_STATUS_AWAY; + + rsStatus->sendStatus(RsPeerId(), status); + resp.setOk(); +} + +void PeersHandler::handleGetCustomStateString(Request& /*req*/, Response& resp) +{ + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mCustomStateToken; + } + + std::string custom_state_string = rsMsgs->getCustomStateString(); + resp.mDataStream << makeKeyValueReference("custom_state_string", custom_state_string); + resp.setOk(); +} + +void PeersHandler::handleSetCustomStateString(Request& req, Response& resp) +{ + std::string custom_state_string; + req.mStream << makeKeyValueReference("custom_state_string", custom_state_string); + + rsMsgs->setCustomStateString(custom_state_string); + resp.setOk(); +} + void PeersHandler::handleWildcard(Request &req, Response &resp) { bool ok = false; @@ -176,6 +409,9 @@ void PeersHandler::handleWildcard(Request &req, Response &resp) RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ unread_msgs = mUnreadMsgsCounts; } + std::list statusInfo; + rsStatus->getStatusList(statusInfo); + // list all peers ok = true; std::list identities; @@ -216,6 +452,11 @@ void PeersHandler::handleWildcard(Request &req, Response &resp) StreamBase& locationStream = itemStream.getStreamToMember("locations"); // mark as list (in case list is empty) locationStream.getStreamToMember(); + + int bestPeerState = 0; + unsigned int bestRSState = 0; + std::string bestCustomStateString; + for(std::vector::iterator vit = detailsVec.begin(); vit != detailsVec.end(); ++vit) { if(vit->gpg_id == *lit) @@ -226,8 +467,85 @@ void PeersHandler::handleWildcard(Request &req, Response &resp) unread = unread_msgs.find(vit->id)->second; stream << makeKeyValueReference("unread_msgs", unread); peerInfoToStream(stream,*vit, mRsPeers, grpInfo, have_avatar(mRsMsgs, vit->id)); - } + + + /* Custom state string */ + std::string customStateString; + if (vit->state & RS_PEER_STATE_CONNECTED) + { + customStateString = rsMsgs->getCustomStateString(vit->id); + } + + int peerState = 0; + + if (vit->state & RS_PEER_STATE_CONNECTED) + { + // get the status info for this ssl id + int rsState = 0; + std::list::iterator it; + for (it = statusInfo.begin(); it != statusInfo.end(); ++it) + { + if (it->id == vit->id) + { + rsState = it->status; + switch (rsState) + { + case RS_STATUS_INACTIVE: + peerState = PEER_STATE_INACTIVE; + break; + + case RS_STATUS_ONLINE: + peerState = PEER_STATE_ONLINE; + break; + + case RS_STATUS_AWAY: + peerState = PEER_STATE_AWAY; + break; + + case RS_STATUS_BUSY: + peerState = PEER_STATE_BUSY; + break; + } + + /* find the best ssl contact for the gpg item */ + if (bestPeerState == 0 || peerState < bestPeerState) + { + bestPeerState = peerState; + bestRSState = rsState; + bestCustomStateString = customStateString; + } + else if (peerState == bestPeerState) + { + /* equal state */ + if (bestCustomStateString.empty() && !customStateString.empty()) + { + bestPeerState = peerState; + bestRSState = rsState; + bestCustomStateString = customStateString; + } + } + break; + } + } + } + } } + itemStream << makeKeyValue("custom_state_string", bestCustomStateString); + + std::string state_string; + + if(bestRSState == RS_STATUS_ONLINE) + state_string = "online"; + else if(bestRSState == RS_STATUS_BUSY) + state_string = "busy"; + else if(bestRSState == RS_STATUS_AWAY) + state_string = "away"; + else if(bestRSState == RS_STATUS_INACTIVE) + state_string = "inactive"; + else + state_string = "undefined"; + + itemStream << makeKeyValue("state_string", state_string); } resp.mStateToken = getCurrentStateToken(); } @@ -300,6 +618,237 @@ void PeersHandler::handleExamineCert(Request &req, Response &resp) } } +void PeersHandler::handleGetPGPOptions(Request& req, Response& resp) +{ + std::string pgp_id; + req.mStream << makeKeyValueReference("pgp_id", pgp_id); + + RsPgpId pgp(pgp_id); + RsPeerDetails detail; + + if(!mRsPeers->getGPGDetails(pgp, detail)) + { + resp.setFail(); + return; + } + + std::string pgp_key = mRsPeers->getPGPKey(detail.gpg_id, false); + + resp.mDataStream << makeKeyValue("pgp_fingerprint", detail.fpr.toStdString()); + resp.mDataStream << makeKeyValueReference("pgp_key", pgp_key); + + resp.mDataStream << makeKeyValue("direct_transfer", detail.service_perm_flags & RS_NODE_PERM_DIRECT_DL); + resp.mDataStream << makeKeyValue("allow_push", detail.service_perm_flags & RS_NODE_PERM_ALLOW_PUSH); + resp.mDataStream << makeKeyValue("require_WL", detail.service_perm_flags & RS_NODE_PERM_REQUIRE_WL); + + resp.mDataStream << makeKeyValue("own_sign", detail.ownsign); + resp.mDataStream << makeKeyValue("trustLvl", detail.trustLvl); + + uint32_t max_upload_speed = 0; + uint32_t max_download_speed = 0; + + mRsPeers->getPeerMaximumRates(pgp, max_upload_speed, max_download_speed); + + resp.mDataStream << makeKeyValueReference("maxUploadSpeed", max_upload_speed); + resp.mDataStream << makeKeyValueReference("maxDownloadSpeed", max_download_speed); + + StreamBase& signersStream = resp.mDataStream.getStreamToMember("gpg_signers"); + + // mark as list (in case list is empty) + signersStream.getStreamToMember(); + + for(std::list::const_iterator it(detail.gpgSigners.begin()); it != detail.gpgSigners.end(); ++it) + { + RsPeerDetails detail; + if(!mRsPeers->getGPGDetails(*it, detail)) + continue; + + std::string pgp_id = (*it).toStdString(); + std::string name = detail.name; + + signersStream.getStreamToMember() + << makeKeyValueReference("pgp_id", pgp_id) + << makeKeyValueReference("name", name); + } + + resp.setOk(); +} + +void PeersHandler::handleSetPGPOptions(Request& req, Response& resp) +{ + std::string pgp_id; + req.mStream << makeKeyValueReference("pgp_id", pgp_id); + + RsPgpId pgp(pgp_id); + RsPeerDetails detail; + + if(!mRsPeers->getGPGDetails(pgp, detail)) + { + resp.setFail(); + return; + } + + int trustLvl; + req.mStream << makeKeyValueReference("trustLvl", trustLvl); + + if(trustLvl != (int)detail.trustLvl) + mRsPeers->trustGPGCertificate(pgp, trustLvl); + + int max_upload_speed; + int max_download_speed; + + req.mStream << makeKeyValueReference("max_upload_speed", max_upload_speed); + req.mStream << makeKeyValueReference("max_download_speed", max_download_speed); + + mRsPeers->setPeerMaximumRates(pgp, (uint32_t)max_upload_speed, (uint32_t)max_download_speed); + + bool direct_transfer; + bool allow_push; + bool require_WL; + + req.mStream << makeKeyValueReference("direct_transfer", direct_transfer); + req.mStream << makeKeyValueReference("allow_push", allow_push); + req.mStream << makeKeyValueReference("require_WL", require_WL); + + ServicePermissionFlags flags(0); + + if(direct_transfer) + flags = flags | RS_NODE_PERM_DIRECT_DL; + if(allow_push) + flags = flags | RS_NODE_PERM_ALLOW_PUSH; + if(require_WL) + flags = flags | RS_NODE_PERM_REQUIRE_WL; + + mRsPeers->setServicePermissionFlags(pgp, flags); + + bool own_sign; + req.mStream << makeKeyValueReference("own_sign", own_sign); + + if(own_sign) + mRsPeers->signGPGCertificate(pgp); + + resp.mStateToken = getCurrentStateToken(); + + resp.setOk(); +} + +void PeersHandler::handleGetNodeOptions(Request& req, Response& resp) +{ + std::string peer_id; + req.mStream << makeKeyValueReference("peer_id", peer_id); + + RsPeerId peerId(peer_id); + RsPeerDetails detail; + if(!mRsPeers->getPeerDetails(peerId, detail)) + { + resp.setFail(); + return; + } + + resp.mDataStream << makeKeyValue("peer_id", detail.id.toStdString()); + resp.mDataStream << makeKeyValue("name", detail.name); + resp.mDataStream << makeKeyValue("location", detail.location); + resp.mDataStream << makeKeyValue("pgp_id", detail.gpg_id.toStdString()); + resp.mDataStream << makeKeyValue("last_contact", detail.lastConnect); + + std::string status_message = mRsMsgs->getCustomStateString(detail.id); + resp.mDataStream << makeKeyValueReference("status_message", status_message); + + std::string encryption; + RsPeerCryptoParams cdet; + if(RsControl::instance()->getPeerCryptoDetails(detail.id, cdet) && cdet.connexion_state != 0) + { + encryption = cdet.cipher_version; + encryption += ": "; + encryption += cdet.cipher_name; + + if(cdet.cipher_version != "TLSv1.2") + encryption += cdet.cipher_bits_1; + } + else + encryption = "Not connected"; + + resp.mDataStream << makeKeyValueReference("encryption", encryption); + + resp.mDataStream << makeKeyValue("is_hidden_node", detail.isHiddenNode); + if (detail.isHiddenNode) + { + resp.mDataStream << makeKeyValue("local_address", detail.hiddenNodeAddress); + resp.mDataStream << makeKeyValue("local_port", (int)detail.hiddenNodePort); + resp.mDataStream << makeKeyValue("ext_address", std::string("none")); + resp.mDataStream << makeKeyValue("ext_port", 0); + resp.mDataStream << makeKeyValue("dyn_dns", std::string("none")); + } + else + { + resp.mDataStream << makeKeyValue("local_address", detail.localAddr); + resp.mDataStream << makeKeyValue("local_port", (int)detail.localPort); + resp.mDataStream << makeKeyValue("ext_address", detail.extAddr); + resp.mDataStream << makeKeyValue("ext_port", (int)detail.extPort); + resp.mDataStream << makeKeyValue("dyn_dns", detail.dyndns); + } + + resp.mDataStream << makeKeyValue("connection_status", connectStateString(detail)); + + StreamBase& addressesStream = resp.mDataStream.getStreamToMember("ip_addresses"); + + // mark as list (in case list is empty) + addressesStream.getStreamToMember(); + + for(std::list::const_iterator it(detail.ipAddressList.begin()); it != detail.ipAddressList.end(); ++it) + { + addressesStream.getStreamToMember() << makeKeyValue("ip_address", (*it)); + } + + std::string certificate = mRsPeers->GetRetroshareInvite(detail.id, false); + resp.mDataStream << makeKeyValueReference("certificate", certificate); + + resp.setOk(); +} + +void PeersHandler::handleSetNodeOptions(Request& req, Response& resp) +{ + std::string peer_id; + req.mStream << makeKeyValueReference("peer_id", peer_id); + + RsPeerId peerId(peer_id); + RsPeerDetails detail; + if(!mRsPeers->getPeerDetails(peerId, detail)) + { + resp.setFail(); + return; + } + + std::string local_address; + std::string ext_address; + std::string dyn_dns; + int local_port; + int ext_port; + + req.mStream << makeKeyValueReference("local_address", local_address); + req.mStream << makeKeyValueReference("local_port", local_port); + req.mStream << makeKeyValueReference("ext_address", ext_address); + req.mStream << makeKeyValueReference("ext_port", ext_port); + req.mStream << makeKeyValueReference("dyn_dns", dyn_dns); + + if(!detail.isHiddenNode) + { + if(detail.localAddr != local_address || (int)detail.localPort != local_port) + mRsPeers->setLocalAddress(peerId, local_address, local_port); + if(detail.extAddr != ext_address || (int)detail.extPort != ext_port) + mRsPeers->setExtAddress(peerId, ext_address, ext_port); + if(detail.dyndns != dyn_dns) + mRsPeers->setDynDNS(peerId, dyn_dns); + } + else + { + if(detail.hiddenNodeAddress != local_address || detail.hiddenNodePort != local_port) + rsPeers->setHiddenNode(peerId, local_address, local_port); + } + + resp.setOk(); +} + StateToken PeersHandler::getCurrentStateToken() { RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ diff --git a/libresapi/src/api/PeersHandler.h b/libresapi/src/api/PeersHandler.h index dfcc9e10c..c4e0ddc3d 100644 --- a/libresapi/src/api/PeersHandler.h +++ b/libresapi/src/api/PeersHandler.h @@ -21,6 +21,7 @@ public: // from NotifyClient // note: this may get called from foreign threads virtual void notifyListChange(int list, int type); // friends list change + virtual void notifyPeerStatusChanged(const std::string& /*peer_id*/, uint32_t /*state*/); virtual void notifyPeerHasNewAvatar(std::string /*peer_id*/); // from Tickable @@ -35,6 +36,18 @@ private: void handleWildcard(Request& req, Response& resp); void handleExamineCert(Request& req, Response& resp); + void handleGetStateString(Request& req, Response& resp); + void handleSetStateString(Request& req, Response& resp); + + void handleGetCustomStateString(Request& req, Response& resp); + void handleSetCustomStateString(Request& req, Response& resp); + + void handleGetPGPOptions(Request& req, Response& resp); + void handleSetPGPOptions(Request& req, Response& resp); + + void handleGetNodeOptions(Request& req, Response& resp); + void handleSetNodeOptions(Request& req, Response& resp); + // a helper which ensures proper mutex locking StateToken getCurrentStateToken(); @@ -44,9 +57,14 @@ private: RsMsgs* mRsMsgs; // required for avatar data std::list mOnlinePeers; + uint32_t status; + std::string custom_state_string; RsMutex mMtx; StateToken mStateToken; // mutex protected + StateToken mStringStateToken; // mutex protected + StateToken mCustomStateToken; // mutex protected + std::map mUnreadMsgsCounts; }; } // namespace resource_api diff --git a/libresapi/src/api/ResourceRouter.cpp b/libresapi/src/api/ResourceRouter.cpp index a13201a27..48050cdb6 100644 --- a/libresapi/src/api/ResourceRouter.cpp +++ b/libresapi/src/api/ResourceRouter.cpp @@ -37,6 +37,13 @@ ResponseTask* ResourceRouter::handleRequest(Request& req, Response& resp) if(vit->first == req.mPath.top()) { req.mPath.pop(); + + //Just for GUI benefit + std::string callbackName; + req.mStream << makeKeyValueReference("callback_name", callbackName); + resp.mCallbackName = callbackName; + // + return vit->second->handleRequest(req, resp); } } diff --git a/libresapi/src/api/RsControlModule.cpp b/libresapi/src/api/RsControlModule.cpp index 9430df170..ece94b7af 100644 --- a/libresapi/src/api/RsControlModule.cpp +++ b/libresapi/src/api/RsControlModule.cpp @@ -6,6 +6,7 @@ #include #include +#include #include "api/ApiServer.h" #include "api/Operators.h" @@ -23,7 +24,9 @@ RsControlModule::RsControlModule(int argc, char **argv, StateTokenServer* sts, A mDataMtx("RsControlModule::mDataMtx"), mRunState(WAITING_INIT), mAutoLoginNextTime(false), - mWantPassword(false) + mWantPassword(false), + mPrevIsBad(false), + mPassword("") { mStateToken = sts->getNewToken(); this->argc = argc; @@ -55,13 +58,16 @@ bool RsControlModule::processShouldExit() return mProcessShouldExit; } -bool RsControlModule::askForPassword(const std::string &title, const std::string &key_details, bool /* prev_is_bad */, std::string &password, bool& cancelled) +bool RsControlModule::askForPassword(const std::string &title, const std::string &key_details, bool prev_is_bad, std::string &password, bool& cancelled) { cancelled = false ; { RS_STACK_MUTEX(mDataMtx); // ********** LOCKED ********** + + mPrevIsBad = prev_is_bad; + if(mFixedPassword != "") - { + { password = mFixedPassword; return true; } @@ -69,25 +75,31 @@ bool RsControlModule::askForPassword(const std::string &title, const std::string mWantPassword = true; mTitle = title; mKeyName = key_details; - mPassword = ""; + + if(mPassword != "") + { + password = mPassword; + mWantPassword = false; + return true; + } + mStateTokenServer->replaceToken(mStateToken); } - bool wait = true; - while(wait) + int i = 0; + while(i<100) { usleep(5*1000); - RS_STACK_MUTEX(mDataMtx); // ********** LOCKED ********** - wait = mWantPassword; - if(!wait && mPassword != "") + + if(mPassword != "") { - password = mPassword; - mPassword = ""; + password = mPassword; mWantPassword = false; mStateTokenServer->replaceToken(mStateToken); return true; } + i++; } return false; } @@ -124,6 +136,11 @@ void RsControlModule::run() bool login_ok = false; while(!login_ok) { + { + RsStackMutex stack(mDataMtx); // ********** LOCKED ********** + mPassword = ""; + } + // skip account selection if autologin is available if(initResult != RS_INIT_HAVE_ACCOUNT) setRunState(WAITING_ACCOUNT_SELECT); @@ -174,8 +191,19 @@ void RsControlModule::run() std::cerr << "RsControlModule::run() LockAndLoadCertificates failed. Unexpected switch value: " << retVal << std::endl; break; } + + { + RsStackMutex stack(mDataMtx); // ********** LOCKED ********** + mLoadPeerId.clear(); + } } + { + RsStackMutex stack(mDataMtx); // ********** LOCKED ********** + mFixedPassword = mPassword; + mPassword = ""; + } + setRunState(WAITING_STARTUP); std::cerr << "RsControlModule: login ok, starting Retroshare worker threads..." << std::endl; @@ -305,7 +333,8 @@ void RsControlModule::handlePassword(Request &req, Response &resp) resp.mDataStream << makeKeyValueReference("want_password", mWantPassword) - << makeKeyValueReference("key_name", mKeyName); + << makeKeyValueReference("key_name", mKeyName) + << makeKeyValueReference("prev_is_bad", mPrevIsBad); resp.mStateToken = mStateToken; resp.setOk(); } @@ -425,17 +454,18 @@ void RsControlModule::handleCreateLocation(Request &req, Response &resp) RsPeerId ssl_id; std::string err_string; // give the password to the password callback - { - RsStackMutex stack(mDataMtx); // ********** LOCKED ********** - mFixedPassword = pgp_password; - } + { + RsStackMutex stack(mDataMtx); // ********** LOCKED ********** + mPassword = pgp_password; + mFixedPassword = pgp_password; + } bool ssl_ok = RsAccounts::GenerateSSLCertificate(pgp_id, "", ssl_name, "", hidden_port!=0, ssl_password, ssl_id, err_string); // clear fixed password to restore normal password operation - { - RsStackMutex stack(mDataMtx); // ********** LOCKED ********** - mFixedPassword = ""; - } +// { +// RsStackMutex stack(mDataMtx); // ********** LOCKED ********** +// mFixedPassword = ""; +// } if (ssl_ok) { @@ -456,6 +486,20 @@ void RsControlModule::handleCreateLocation(Request &req, Response &resp) resp.setFail("could not create a new location. Error: "+err_string); } +bool RsControlModule::askForDeferredSelfSignature(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,int& signature_result, std::string reason /*=""*/) +{ + if(rsPeers->gpgSignData(data,len,sign,signlen,reason)) + { + signature_result = SELF_SIGNATURE_RESULT_SUCCESS; + return true; + } + else + { + signature_result = SELF_SIGNATURE_RESULT_FAILED; + return false; + } +} + void RsControlModule::setRunState(RunState s, std::string errstr) { RsStackMutex stack(mDataMtx); // ********** LOCKED ********** diff --git a/libresapi/src/api/RsControlModule.h b/libresapi/src/api/RsControlModule.h index d3c8ad18b..8b8b1f3f0 100644 --- a/libresapi/src/api/RsControlModule.h +++ b/libresapi/src/api/RsControlModule.h @@ -31,8 +31,9 @@ public: // returns true if the process should terminate bool processShouldExit(); - // from NotifyClient - virtual bool askForPassword(const std::string &title, const std::string& key_details, bool prev_is_bad , std::string& password,bool& canceled); + // from NotifyClient + virtual bool askForPassword(const std::string &title, const std::string& key_details, bool prev_is_bad , std::string& password,bool& canceled) override; + virtual bool askForDeferredSelfSignature(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,int& signature_result, std::string reason = "") override; protected: // from RsThread @@ -76,6 +77,7 @@ private: // to notify that a password callback is waiting // to answer the request, clear the flag and set the password bool mWantPassword; + bool mPrevIsBad ; std::string mTitle; std::string mKeyName; std::string mPassword; diff --git a/libresapi/src/api/SettingsHandler.cpp b/libresapi/src/api/SettingsHandler.cpp new file mode 100644 index 000000000..6e1aa75da --- /dev/null +++ b/libresapi/src/api/SettingsHandler.cpp @@ -0,0 +1,182 @@ +#include "SettingsHandler.h" + +#include + +#include + +namespace resource_api +{ + #define SETTINGS_FILE (QString::fromUtf8(RsAccounts::AccountDirectory().c_str()) + "/Sonet.conf") + + SettingsHandler::SettingsHandler(StateTokenServer *sts, const QString settingsGroup) : + QSettings(SETTINGS_FILE, QSettings::IniFormat), + mStateTokenServer(sts), + mMtx("SettingsHandler Mutex"), + mStateToken(sts->getNewToken()) + { + RsPeerId sPreferedId; + m_bValid = RsAccounts::GetPreferredAccountId(sPreferedId); + + if (!settingsGroup.isEmpty()) + beginGroup(settingsGroup); + + addResourceHandler("*", this, &SettingsHandler::handleSettingsRequest); + addResourceHandler("get_advanced_mode", this, &SettingsHandler::handleGetAdvancedMode); + addResourceHandler("set_advanced_mode", this, &SettingsHandler::handleSetAdvancedMode); + addResourceHandler("get_flickable_grid_mode", this, &SettingsHandler::handleGetFlickableGridMode); + addResourceHandler("set_flickable_grid_mode", this, &SettingsHandler::handleSetFlickableGridMode); + addResourceHandler("get_auto_login", this, &SettingsHandler::handleGetAutoLogin); + addResourceHandler("set_auto_login", this, &SettingsHandler::handleSetAutoLogin); + } + + SettingsHandler::~SettingsHandler() + { + sync(); + } + + void SettingsHandler::handleSettingsRequest(Request &/*req*/, Response &resp) + { + + } + + void SettingsHandler::handleGetAdvancedMode(Request &/*req*/, Response &resp) + { + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStateToken; + } + + bool advanced_mode = valueFromGroup("General", "Advanced", false).toBool(); + resp.mDataStream << makeKeyValueReference("advanced_mode", advanced_mode); + resp.setOk(); + sync(); + } + + void SettingsHandler::handleSetAdvancedMode(Request &req, Response &resp) + { + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStateToken; + } + + bool advanced_mode; + req.mStream << makeKeyValueReference("advanced_mode", advanced_mode); + setValueToGroup("General", "Advanced", advanced_mode); + resp.setOk(); + sync(); + } + + void SettingsHandler::handleGetFlickableGridMode(Request &/*req*/, Response &resp) + { + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStateToken; + } + + bool flickable_grid_mode = valueFromGroup("General", "FlickableGrid", false).toBool(); + resp.mDataStream << makeKeyValueReference("flickable_grid_mode", flickable_grid_mode); + resp.setOk(); + sync(); + } + + void SettingsHandler::handleSetFlickableGridMode(Request &req, Response &resp) + { + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStateToken; + } + + bool flickable_grid_mode; + req.mStream << makeKeyValueReference("flickable_grid_mode", flickable_grid_mode); + setValueToGroup("General", "FlickableGrid", flickable_grid_mode); + + resp.setOk(); + sync(); + } + + void SettingsHandler::handleGetAutoLogin(Request &/*req*/, Response &resp) + { + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStateToken; + } + + bool autoLogin = RsInit::getAutoLogin();; + resp.mDataStream << makeKeyValueReference("auto_login", autoLogin); + resp.setOk(); + sync(); + } + + void SettingsHandler::handleSetAutoLogin(Request &req, Response &resp) + { + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStateToken; + } + + bool autoLogin; + req.mStream << makeKeyValueReference("auto_login", autoLogin); + RsInit::setAutoLogin(autoLogin); + + resp.setOk(); + sync(); + } + + QVariant SettingsHandler::value(const QString &key, const QVariant &defaultVal) const + { + if (m_bValid == false) + { + return defaultVal.isNull() ? defaultValue(key) : defaultVal; + } + return QSettings::value(key, defaultVal.isNull() ? defaultValue(key) : defaultVal); + } + + void SettingsHandler::setValue(const QString &key, const QVariant &val) + { + if (m_bValid == false) + { + std::cerr << "RSettings::setValue() Calling on invalid object, key = " << key.toStdString() << std::endl; + return; + } + if (val == defaultValue(key)) + QSettings::remove(key); + else if (val != value(key)) + QSettings::setValue(key, val); + } + + QVariant SettingsHandler::valueFromGroup(const QString &group, const QString &key, const QVariant &defaultVal) + { + beginGroup(group); + QVariant val = value(key, defaultVal); + endGroup(); + + return val; + } + + void SettingsHandler::setValueToGroup(const QString &group, const QString &key, const QVariant &val) + { + beginGroup(group); + setValue(key, val); + endGroup(); + } + + void SettingsHandler::setDefault(const QString &key, const QVariant &val) + { + _defaults.insert(key, val); + } + + QVariant SettingsHandler::defaultValue(const QString &key) const + { + if (_defaults.contains(key)) + return _defaults.value(key); + return QVariant(); + } + + void SettingsHandler::reset() + { + /* Static method, so we have to create a QSettings object. */ + QSettings settings(SETTINGS_FILE, QSettings::IniFormat); + settings.clear(); + } +} // namespace resource_api + diff --git a/libresapi/src/api/SettingsHandler.h b/libresapi/src/api/SettingsHandler.h new file mode 100644 index 000000000..b4c21fae2 --- /dev/null +++ b/libresapi/src/api/SettingsHandler.h @@ -0,0 +1,59 @@ +#ifndef SETTINGSHANDLER_H +#define SETTINGSHANDLER_H + +#include + +#include + +#include "ResourceRouter.h" +#include "StateTokenServer.h" + +/* Reimplemented class RSettings*/ +namespace resource_api +{ + class SettingsHandler : public ResourceRouter, public QSettings + { + public: + SettingsHandler(StateTokenServer* sts, const QString group = QString()); + ~SettingsHandler(); + + static void reset(); + + QVariant value(const QString &key, + const QVariant &defaultVal = QVariant()) const; + + void setValue(const QString &key, const QVariant &val); + + QVariant valueFromGroup(const QString &group, const QString &key, + const QVariant &defaultVal = QVariant()); + void setValueToGroup(const QString &group, const QString &key, + const QVariant &val); + + protected: + void setDefault(const QString &key, const QVariant &val); + QVariant defaultValue(const QString &key) const; + + bool m_bValid; + + private: + void handleSettingsRequest(Request& req, Response& resp); + + void handleGetAdvancedMode(Request& req, Response& resp); + void handleSetAdvancedMode(Request& req, Response& resp); + + void handleGetFlickableGridMode(Request& req, Response& resp); + void handleSetFlickableGridMode(Request& req, Response& resp); + + void handleGetAutoLogin(Request& req, Response& resp); + void handleSetAutoLogin(Request& req, Response& resp); + + QHash _defaults; + + StateTokenServer* mStateTokenServer; + + RsMutex mMtx; + StateToken mStateToken; // mutex protected + }; +} // namespace resource_api + +#endif // SETTINGSHANDLER_H diff --git a/libresapi/src/libresapi.pro b/libresapi/src/libresapi.pro index f310198fb..e548ea9d0 100644 --- a/libresapi/src/libresapi.pro +++ b/libresapi/src/libresapi.pro @@ -10,6 +10,40 @@ DESTDIR = lib INCLUDEPATH += ../../libretroshare/src +retroshare_android_service { + win32 { + OBJECTS_DIR = temp/obj + + LIBS_DIR = $$PWD/../../libs/lib + LIBS += $$OUT_PWD/../../libretroshare/src/lib/libretroshare.a + LIBS += $$OUT_PWD/../../openpgpsdk/src/lib/libops.a + + for(lib, LIB_DIR):LIBS += -L"$$lib" + for(bin, BIN_DIR):LIBS += -L"$$bin" + + + LIBS += -lssl -lcrypto -lpthread -lminiupnpc -lz -lws2_32 + LIBS += -luuid -lole32 -liphlpapi -lcrypt32 -lgdi32 + LIBS += -lwinmm + + DEFINES *= WINDOWS_SYS WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T + + DEPENDPATH += . $$INC_DIR + INCLUDEPATH += . $$INC_DIR + + greaterThan(QT_MAJOR_VERSION, 4) { + # Qt 5 + RC_INCLUDEPATH += $$_PRO_FILE_PWD_/../../libretroshare/src + } else { + # Qt 4 + QMAKE_RC += --include-dir=$$_PRO_FILE_PWD_/../../libretroshare/src + } + } + + DEPENDPATH += . ../../libretroshare/src/ + INCLUDEPATH += ../../libretroshare/src/ +} + libresapihttpserver { CONFIG += libmicrohttpd @@ -183,3 +217,11 @@ libresapilocalserver { SOURCES *= api/ApiServerLocal.cpp HEADERS *= api/ApiServerLocal.h } + +qt_dependencies { + CONFIG *= qt + QT *= core + + SOURCES += api/SettingsHandler.cpp + HEADERS += api/SettingsHandler.h +} diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index c59da85de..b946b5931 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -1273,6 +1273,58 @@ bool RsGenExchange::getMsgRelatedMeta(const uint32_t &token, GxsMsgRelatedMetaMa return ok; } +bool RsGenExchange::getSerializedGroupData(const uint32_t &token, RsGxsGroupId& id,unsigned char *& data,uint32_t& size) +{ + RS_STACK_MUTEX(mGenMtx) ; + + std::list nxsGrps; + + if(!mDataAccess->getGroupData(token, nxsGrps)) + return false ; + + if(nxsGrps.size() != 1) + { + std::cerr << "(EE) getSerializedGroupData() got multiple groups in single request. This is unexpected." << std::endl; + + for(std::list::const_iterator it(nxsGrps.begin());it!=nxsGrps.end();++it) + delete *it ; + + return false ; + } + RsNxsGrp *nxs_grp = *(nxsGrps.begin()); + + size = nxs_grp->serial_size() ; + id = nxs_grp->metaData->mGroupId ; + + if(size > 1024*1024 || NULL==(data = (unsigned char *)rs_malloc(size))) + { + std::cerr << "(EE) getSerializedGroupData() cannot allocate mem chunk of size " << size << ". Too big, or no room." << std::endl; + delete nxs_grp ; + return false ; + } + + return nxs_grp->serialise(data,size) ; +} + +bool RsGenExchange::deserializeGroupData(unsigned char *data,uint32_t size) +{ + RS_STACK_MUTEX(mGenMtx) ; + + RsItem *item = RsNxsSerialiser(mServType).deserialise(data, &size); + + RsNxsGrp *nxs_grp = dynamic_cast(item) ; + + if(item == NULL) + { + std::cerr << "(EE) RsGenExchange::deserializeGroupData(): cannot deserialise this data. Something's wrong." << std::endl; + delete item ; + return false ; + } + + mReceivedGrps.push_back( GxsPendingItem(nxs_grp, nxs_grp->grpId,time(NULL)) ); + + return true ; +} bool RsGenExchange::getGroupData(const uint32_t &token, std::vector& grpItem) { diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 8ebd40bd7..43891a80d 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -288,6 +288,20 @@ protected: */ bool getGroupData(const uint32_t &token, std::vector& grpItem); + /*! + * \brief getSerializedGroupData + * Retrieves the complete group data serialized into a chunk of memory. This can be useful to + * transfer a full group from one machine to another. + * + * \param token token previously obtained from cache request + * \param data memory chunk allocated (using malloc) + * \param size size of the memory chunk. + * \return + */ + + bool getSerializedGroupData(const uint32_t &token, RsGxsGroupId &id, unsigned char *& data, uint32_t& size); + bool deserializeGroupData(unsigned char *data, uint32_t size); + template bool getGroupDataT(const uint32_t &token, std::vector& grpItem) { diff --git a/libretroshare/src/gxs/rsgxsdata.h b/libretroshare/src/gxs/rsgxsdata.h index 6e85193dc..76924167c 100644 --- a/libretroshare/src/gxs/rsgxsdata.h +++ b/libretroshare/src/gxs/rsgxsdata.h @@ -33,8 +33,8 @@ #include "rsitems/rsgxsitems.h" -class RsGroupMetaData; -class RsMsgMetaData; +struct RsGroupMetaData; +struct RsMsgMetaData; static const uint32_t RS_GXS_GRP_META_DATA_VERSION_ID_0001 = 0x0000 ; // change this, and keep old values if the content changes static const uint32_t RS_GXS_GRP_META_DATA_VERSION_ID_0002 = 0xaf01 ; // current API diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index 8fcbbde5d..56899d4ce 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -75,6 +75,12 @@ bool RsGxsDataAccess::requestGroupInfo(uint32_t &token, uint32_t ansType, const gir->mGroupIds = groupIds; req = gir; } + else if(reqType & GXS_REQUEST_TYPE_GROUP_SERIALIZED_DATA) + { + GroupSerializedDataReq* gir = new GroupSerializedDataReq(); + gir->mGroupIds = groupIds; + req = gir; + } if(req == NULL) { @@ -103,34 +109,25 @@ bool RsGxsDataAccess::requestGroupInfo(uint32_t &token, uint32_t ansType, const uint32_t reqType = opts.mReqType; if(reqType & GXS_REQUEST_TYPE_GROUP_META) - { - GroupMetaReq* gmr = new GroupMetaReq(); - req = gmr; - } + req = new GroupMetaReq(); else if(reqType & GXS_REQUEST_TYPE_GROUP_DATA) - { - GroupDataReq* gdr = new GroupDataReq(); - req = gdr; - } + req = new GroupDataReq(); else if(reqType & GXS_REQUEST_TYPE_GROUP_IDS) - { - GroupIdReq* gir = new GroupIdReq(); - req = gir; - } - - if(req == NULL) + req = new GroupIdReq(); + else if(reqType & GXS_REQUEST_TYPE_GROUP_SERIALIZED_DATA) + req = new GroupSerializedDataReq(); + else { std::cerr << "RsGxsDataAccess::requestGroupInfo() request type not recognised, type " << reqType << std::endl; return false; - }else - { - generateToken(token); -#ifdef DATA_DEBUG - std::cerr << "RsGxsDataAccess::requestGroupInfo() gets Token: " << token << std::endl; -#endif } + generateToken(token); +#ifdef DATA_DEBUG + std::cerr << "RsGxsDataAccess::requestGroupInfo() gets Token: " << token << std::endl; +#endif + setReq(req, token, ansType, opts); storeRequest(req); @@ -430,7 +427,16 @@ bool RsGxsDataAccess::getGroupData(const uint32_t& token, std::list& else if(req->status == GXS_REQUEST_V2_STATUS_COMPLETE) { GroupDataReq* gmreq = dynamic_cast(req); - if(gmreq) + GroupSerializedDataReq* gsreq = dynamic_cast(req); + + if(gsreq) + { + grpData.swap(gsreq->mGroupData); + gsreq->mGroupData.clear(); + + locked_updateRequestStatus(token, GXS_REQUEST_V2_STATUS_DONE); + } + else if(gmreq) { grpData.swap(gmreq->mGroupData); gmreq->mGroupData.clear(); @@ -804,6 +810,7 @@ void RsGxsDataAccess::processRequests() MsgIdReq* mir; MsgRelatedInfoReq* mri; GroupStatisticRequest* gsr; + GroupSerializedDataReq* grr; ServiceStatisticRequest* ssr; #ifdef DATA_DEBUG @@ -851,6 +858,11 @@ void RsGxsDataAccess::processRequests() { ok = getServiceStatistic(ssr); } + else if((grr = dynamic_cast(req)) != NULL) + { + ok = getGroupSerializedData(grr); + } + else { std::cerr << "RsGxsDataAccess::processRequests() Failed to process request, token: " @@ -929,7 +941,30 @@ bool RsGxsDataAccess::getServiceStatistic(const uint32_t &token, GxsServiceStati return true; } +bool RsGxsDataAccess::getGroupSerializedData(GroupSerializedDataReq* req) +{ + std::map grpData; + std::list grpIdsOut; + getGroupList(req->mGroupIds, req->Options, grpIdsOut); + + if(grpIdsOut.empty()) + return true; + + + for(std::list::iterator lit = grpIdsOut.begin();lit != grpIdsOut.end();++lit) + grpData[*lit] = NULL; + + bool ok = mDataStore->retrieveNxsGrps(grpData, true, true); + req->mGroupData.clear(); + + std::map::iterator mit = grpData.begin(); + + for(; mit != grpData.end(); ++mit) + req->mGroupData.push_back(mit->second) ; + + return ok; +} bool RsGxsDataAccess::getGroupData(GroupDataReq* req) { std::map grpData; diff --git a/libretroshare/src/gxs/rsgxsdataaccess.h b/libretroshare/src/gxs/rsgxsdataaccess.h index ac21f4c41..d39823f81 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.h +++ b/libretroshare/src/gxs/rsgxsdataaccess.h @@ -418,6 +418,13 @@ private: */ bool getGroupStatistic(GroupStatisticRequest* req); + /*! + * + * Attempts to retrieve group data in serialized format + * @param req Request object to satisfy + */ + bool getGroupSerializedData(GroupSerializedDataReq* req); + /*! * * Attempts to service statistic diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 1811f2658..789a77441 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -328,6 +328,23 @@ RsGxsNetService::RsGxsNetService(uint16_t servType, RsGeneralDataService *gds, mUpdateCounter = 0; } +void RsGxsNetService::getItemNames(std::map& names) const +{ + names.clear(); + + names[RS_PKT_SUBTYPE_NXS_SYNC_GRP_REQ_ITEM ] = "Group Sync Request" ; + names[RS_PKT_SUBTYPE_NXS_SYNC_GRP_ITEM ] = "Group Sync" ; + names[RS_PKT_SUBTYPE_NXS_SYNC_GRP_STATS_ITEM ] = "Group Stats" ; + names[RS_PKT_SUBTYPE_NXS_GRP_ITEM ] = "Group Data" ; + names[RS_PKT_SUBTYPE_NXS_ENCRYPTED_DATA_ITEM ] = "Encrypted data" ; + names[RS_PKT_SUBTYPE_NXS_SESSION_KEY_ITEM ] = "Session Key" ; + names[RS_PKT_SUBTYPE_NXS_SYNC_MSG_ITEM ] = "Message Sync" ; + names[RS_PKT_SUBTYPE_NXS_SYNC_MSG_REQ_ITEM ] = "Message Sync Request" ; + names[RS_PKT_SUBTYPE_NXS_MSG_ITEM ] = "Message Data" ; + names[RS_PKT_SUBTYPE_NXS_TRANSAC_ITEM ] = "Transaction" ; + names[RS_PKT_SUBTYPE_NXS_GRP_PUBLISH_KEY_ITEM ] = "Publish key" ; +} + RsGxsNetService::~RsGxsNetService() { RS_STACK_MUTEX(mNxsMutex) ; @@ -1972,7 +1989,7 @@ void RsGxsNetService::updateServerSyncTS() #endif // I keep the creation, but the data is not used yet. -#warning disabled this, but do we need it? +#warning csoler 2016-12-12: Disabled this, but do we need it? // RsGxsServerMsgUpdate& msui(mServerMsgUpdateMap[grpId]) ; // (cyril) I'm removing this, because the msgUpdateTS is updated when new messages are received by calling locked_stampMsgServerUpdateTS(). @@ -3000,7 +3017,7 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr) } // FIXTESTS global variable rsReputations not available in unittests! -#warning Update the code below to correctly send/recv dependign on reputation +#warning csoler 2016-12-23: Update the code below to correctly send/recv dependign on reputation if(!grpSyncItem->authorId.isNull() && mReputations->overallReputationLevel(grpSyncItem->authorId) == RsReputations::REPUTATION_LOCALLY_NEGATIVE) { #ifdef NXS_NET_DEBUG_0 diff --git a/libretroshare/src/gxs/rsgxsnetservice.h b/libretroshare/src/gxs/rsgxsnetservice.h index b74e53998..fe1dbef0d 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.h +++ b/libretroshare/src/gxs/rsgxsnetservice.h @@ -99,6 +99,7 @@ public: virtual RsServiceInfo getServiceInfo() { return mServiceInfo; } + virtual void getItemNames(std::map& names) const ; public: diff --git a/libretroshare/src/gxs/rsgxsnetutils.cc b/libretroshare/src/gxs/rsgxsnetutils.cc index 4d54ce117..7454ba58a 100644 --- a/libretroshare/src/gxs/rsgxsnetutils.cc +++ b/libretroshare/src/gxs/rsgxsnetutils.cc @@ -45,7 +45,7 @@ bool AuthorPending::getAuthorRep(GixsReputation& rep, const RsGxsId& authorId, c rep.id = authorId ; rep.reputation_level = mRep->overallReputationLevel(authorId); -#warning can it happen that reputations do not have the info yet? +#warning csoler 2017-01-10: Can it happen that reputations do not have the info yet? return true ; #ifdef TO_BE_REMOVED { diff --git a/libretroshare/src/gxs/rsgxsrequesttypes.h b/libretroshare/src/gxs/rsgxsrequesttypes.h index a344a55e7..8009f294b 100644 --- a/libretroshare/src/gxs/rsgxsrequesttypes.h +++ b/libretroshare/src/gxs/rsgxsrequesttypes.h @@ -61,6 +61,12 @@ public: std::list mGroupIds; std::list mGroupIdResult; }; +class GroupSerializedDataReq : public GxsRequest +{ +public: + std::list mGroupIds; + std::list mGroupData; +}; class GroupDataReq : public GxsRequest { diff --git a/libretroshare/src/gxstunnel/p3gxstunnel.cc b/libretroshare/src/gxstunnel/p3gxstunnel.cc index 75f50c7d9..69bc091f4 100644 --- a/libretroshare/src/gxstunnel/p3gxstunnel.cc +++ b/libretroshare/src/gxstunnel/p3gxstunnel.cc @@ -1195,7 +1195,7 @@ bool p3GxsTunnelService::locked_sendClearTunnelData(RsGxsTunnelDHPublicKeyItem * if(gitem->data_bytes == NULL) { delete gitem ; - return NULL ; + return false ; } // by convention, we use a IV of 0 for unencrypted data. memset(gitem->data_bytes,0,8) ; diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index dce14eafd..46daa85e8 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -279,7 +279,12 @@ win32 { CONFIG += upnp_miniupnpc - LIBS += -lsqlcipher + no_sqlcipher { + PKGCONFIG *= sqlite3 + LIBS += -lsqlite3 + } else { + LIBS += -lsqlcipher + } DEPENDPATH += . $$INC_DIR INCLUDEPATH += . $$INC_DIR diff --git a/libretroshare/src/plugins/pluginmanager.cc b/libretroshare/src/plugins/pluginmanager.cc index bbc1761fb..fa38394a5 100644 --- a/libretroshare/src/plugins/pluginmanager.cc +++ b/libretroshare/src/plugins/pluginmanager.cc @@ -50,9 +50,14 @@ RsPluginManager::RsPluginManager(const RsFileHash &hash) _allow_all_plugins = false ; } +bool RsPluginManager::loadConfiguration(RsFileHash &loadHash) +{ + return p3Config::loadConfiguration(loadHash); +} + void RsPluginManager::loadConfiguration() { - RsFileHash dummyHash ; + RsFileHash dummyHash; p3Config::loadConfiguration(dummyHash); } diff --git a/libretroshare/src/plugins/pluginmanager.h b/libretroshare/src/plugins/pluginmanager.h index 5f2a8c3b7..27a74f870 100644 --- a/libretroshare/src/plugins/pluginmanager.h +++ b/libretroshare/src/plugins/pluginmanager.h @@ -74,6 +74,7 @@ class RsPluginManager: public RsPluginHandler, public p3Config // -------------------- Own members -------------------------// // virtual void addConfigurations(p3ConfigMgr *cfgMgr) ; + virtual bool loadConfiguration(RsFileHash &loadHash) ; virtual void loadConfiguration() ; /*! diff --git a/libretroshare/src/pqi/p3dhtmgr.cc b/libretroshare/src/pqi/p3dhtmgr.cc index a93577581..c1d929c94 100644 --- a/libretroshare/src/pqi/p3dhtmgr.cc +++ b/libretroshare/src/pqi/p3dhtmgr.cc @@ -92,7 +92,7 @@ dhtPeerEntry::dhtPeerEntry() return; } -p3DhtMgr::p3DhtMgr(std::string id, pqiConnectCb *cb) +p3DhtMgr::p3DhtMgr(RsPeerId id, pqiConnectCb *cb) :pqiNetAssistConnect(id, cb), dhtMtx("p3DhtMgr"), mStunRequired(true) { /* setup own entry */ @@ -237,13 +237,13 @@ bool p3DhtMgr::setExternalInterface( /* add / remove peers */ -bool p3DhtMgr::findPeer(std::string id) +bool p3DhtMgr::findPeer(const RsPeerId& id) { RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/ mDhtModifications = true; - std::map::iterator it; + std::map::iterator it; it = peers.find(id); if (it != peers.end()) { @@ -281,14 +281,14 @@ bool p3DhtMgr::findPeer(std::string id) return true; } -bool p3DhtMgr::dropPeer(std::string id) +bool p3DhtMgr::dropPeer(const RsPeerId& id) { RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/ mDhtModifications = true; /* once we are connected ... don't worry about them anymore */ - std::map::iterator it; + std::map::iterator it; it = peers.find(id); if (it == peers.end()) { @@ -302,14 +302,14 @@ bool p3DhtMgr::dropPeer(std::string id) } /* post DHT key saying we should connect */ -bool p3DhtMgr::notifyPeer(std::string id) +bool p3DhtMgr::notifyPeer(const RsPeerId& id) { RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/ #ifdef DHT_DEBUG - std::cerr << "p3DhtMgr::notifyPeer() " << id << std::endl; + std::cerr << "p3DhtMgr::notifyPeer() " << id.toStdString() << std::endl; #endif - std::map::iterator it; + std::map::iterator it; it = peers.find(id); if (it == peers.end()) { @@ -333,7 +333,7 @@ bool p3DhtMgr::notifyPeer(std::string id) #ifdef DHT_LOGS { /* Log */ - rslog(RSL_WARNING, p3dhtzone, "p3DhtMgr::notifyPeer() Id: " + id + " TO SOON - DROPPING"); + rslog(RSL_WARNING, p3dhtzone, "p3DhtMgr::notifyPeer() Id: " + id.toStdString() + " TO SOON - DROPPING"); } #endif @@ -352,7 +352,7 @@ bool p3DhtMgr::notifyPeer(std::string id) #ifdef DHT_LOGS { /* Log */ - rslog(RSL_WARNING, p3dhtzone, "p3DhtMgr::notifyPeer() Id: " + id + " PEER NOT FOUND - Trigger Search"); + rslog(RSL_WARNING, p3dhtzone, "p3DhtMgr::notifyPeer() Id: " + id.toStdString() + " PEER NOT FOUND - Trigger Search"); } #endif it->second.lastTS = 0; @@ -364,14 +364,14 @@ bool p3DhtMgr::notifyPeer(std::string id) } /* extract current peer status */ -bool p3DhtMgr::getPeerStatus(std::string id, - struct sockaddr_in &laddr, - struct sockaddr_in &raddr, +bool p3DhtMgr::getPeerStatus(const RsPeerId &id, + struct sockaddr_in &laddr, + struct sockaddr_in &raddr, uint32_t &type, uint32_t &state) { RsStackMutex stack(dhtMtx); /* LOCK MUTEX */ - std::map::iterator it; + std::map::iterator it; it = peers.find(id); /* ignore OFF peers */ @@ -776,7 +776,7 @@ int p3DhtMgr::checkPeerDHTKeys() dhtMtx.lock(); /* LOCK MUTEX */ /* iterate through and find min time and suitable candidate */ - std::map::iterator it,pit; + std::map::iterator it,pit; time_t now = time(NULL); uint32_t period = 0; uint32_t repeatPeriod = 6000; @@ -802,7 +802,7 @@ int p3DhtMgr::checkPeerDHTKeys() period = DHT_CHECK_PERIOD; } #ifdef DHT_DEBUG - std::cerr << "p3DhtMgr::checkPeerDHTKeys() Peer: " << it->second.id; + std::cerr << "p3DhtMgr::checkPeerDHTKeys() Peer: " << it->second.id.toStdString(); std::cerr << " Period: " << period; std::cerr << " Delta: " << delta; std::cerr << std::endl; @@ -865,7 +865,7 @@ int p3DhtMgr::checkNotifyDHT() RsStackMutex stack(dhtMtx); /***** LOCK MUTEX *****/ /* iterate through and find min time and suitable candidate */ - std::map::iterator it; + std::map::iterator it; time_t now = time(NULL); int repeatPeriod = DHT_DEFAULT_PERIOD; @@ -1015,7 +1015,7 @@ int p3DhtMgr::checkStunState() if (mDhtState == DHT_STATE_CHECK_PEERS) { /* check that they have all be searched for */ - std::map::iterator it; + std::map::iterator it; for(it = peers.begin(); it != peers.end(); it++) { if (it->second.state == DHT_PEER_INIT) @@ -1287,7 +1287,7 @@ int p3DhtMgr::status(std::ostream &out) out << "OWN DETAILS END----------------------------------------" << std::endl; /* now peers states */ - std::map::iterator it; + std::map::iterator it; out << "PEER DETAILS ------------------------------------------" << std::endl; for(it = peers.begin(); it != peers.end(); it++) { @@ -1622,15 +1622,13 @@ bool p3DhtMgr::dhtResultNotify(std::string idhash) std::cerr << "p3DhtMgr::dhtResultNotify() from idhash: "; std::cerr << RsUtil::BinToHex(idhash) << std::endl; #endif - std::map::iterator it; + std::map::iterator it; time_t now = time(NULL); /* if notify - we must match on the second hash */ for(it = peers.begin(); (it != peers.end()) && ((it->second).hash2 != idhash); it++) ; /* update data */ - std::string peerid; - /* ignore OFF peers */ if ((it != peers.end()) && (it->second.state != DHT_PEER_OFF)) { @@ -1677,7 +1675,7 @@ bool p3DhtMgr::dhtResultSearch(std::string idhash, std::cerr << "p3DhtMgr::dhtResultSearch() for idhash: "; std::cerr << RsUtil::BinToHex(idhash) << std::endl; #endif - std::map::iterator it; + std::map::iterator it; bool doCb = false; bool doStun = false; uint32_t stunFlags = 0; @@ -1780,7 +1778,7 @@ bool p3DhtMgr::dhtResultSearch(std::string idhash, void printDhtPeerEntry(dhtPeerEntry *ent, std::ostream &out) { - out << "DhtEntry: ID: " << ent->id; + out << "DhtEntry: ID: " << ent->id.toStdString(); out << " State: " << ent->state; out << " lastTS: " << ent->lastTS; out << " notifyPending: " << ent->notifyPending; diff --git a/libretroshare/src/pqi/p3dhtmgr.h b/libretroshare/src/pqi/p3dhtmgr.h index f08c2bc96..86d6b5424 100644 --- a/libretroshare/src/pqi/p3dhtmgr.h +++ b/libretroshare/src/pqi/p3dhtmgr.h @@ -78,7 +78,7 @@ class dhtPeerEntry public: dhtPeerEntry(); - std::string id; + RsPeerId id; uint32_t state; time_t lastTS; @@ -97,7 +97,7 @@ class p3DhtMgr: public pqiNetAssistConnect, public RsThread /* */ public: - p3DhtMgr(std::string id, pqiConnectCb *cb); + p3DhtMgr(RsPeerId id, pqiConnectCb *cb); /********** External DHT Interface ************************ * These Functions are the external interface @@ -121,15 +121,15 @@ virtual bool setExternalInterface(struct sockaddr_in laddr, struct sockaddr_in raddr, uint32_t type); /* add / remove peers */ -virtual bool findPeer(std::string id); -virtual bool dropPeer(std::string id); +virtual bool findPeer(const RsPeerId& id); +virtual bool dropPeer(const RsPeerId& id); /* post DHT key saying we should connect (callback when done) */ -virtual bool notifyPeer(std::string id); +virtual bool notifyPeer(const RsPeerId& id); /* extract current peer status */ -virtual bool getPeerStatus(std::string id, - struct sockaddr_in &laddr, struct sockaddr_in &raddr, +virtual bool getPeerStatus(const RsPeerId& id, + struct sockaddr_in &laddr, struct sockaddr_in &raddr, uint32_t &type, uint32_t &mode); /* stun */ @@ -154,17 +154,17 @@ virtual bool dhtResultBootstrap(std::string idhash); protected: /* can block briefly (called only from thread) */ -virtual bool dhtPublish(std::string id, +virtual bool dhtPublish(std::string idhash, struct sockaddr_in &laddr, struct sockaddr_in &raddr, uint32_t type, std::string sign); -virtual bool dhtNotify(std::string peerid, std::string ownId, +virtual bool dhtNotify(std::string idhash, std::string ownIdHash, std::string sign); -virtual bool dhtSearch(std::string id, uint32_t mode); +virtual bool dhtSearch(std::string idhash, uint32_t mode); -virtual bool dhtBootstrap(std::string storehash, std::string ownIdHash, +virtual bool dhtBootstrap(std::string idhash, std::string ownIdHash, std::string sign); /* to publish bootstrap */ @@ -232,7 +232,7 @@ std::string randomBootstrapId(); dhtPeerEntry ownEntry; time_t ownNotifyTS; - std::map peers; + std::map peers; std::list stunIds; bool mStunRequired; diff --git a/libretroshare/src/pqi/p3peermgr.h b/libretroshare/src/pqi/p3peermgr.h index ee581b275..f0a9a44cb 100644 --- a/libretroshare/src/pqi/p3peermgr.h +++ b/libretroshare/src/pqi/p3peermgr.h @@ -397,7 +397,7 @@ private: std::map mReportedOwnAddresses ; std::map groupList; - uint32_t lastGroupId; + //uint32_t lastGroupId; std::list saveCleanupList; /* TEMPORARY LIST WHEN SAVING */ diff --git a/libretroshare/src/pqi/p3servicecontrol.cc b/libretroshare/src/pqi/p3servicecontrol.cc index 0b3b1514e..d0d9acbdc 100644 --- a/libretroshare/src/pqi/p3servicecontrol.cc +++ b/libretroshare/src/pqi/p3servicecontrol.cc @@ -30,7 +30,9 @@ #include "rsitems/rsitem.h" #include "serialiser/rsserial.h" #include "serialiser/rsbaseserial.h" +#include "serialiser/rsnxsitems.h" #include "pqi/p3cfgmgr.h" +#include "pqi/pqiservice.h" /*******************************/ // #define SERVICECONTROL_DEBUG 1 @@ -139,7 +141,7 @@ public: std::cerr << __PRETTY_FUNCTION__ << ": error while deserialising! Item will be dropped." << std::endl; return NULL ; } - + /* add mandatory parts first */ ok &= getRawUInt32(data, rssize, &offset, &item->mServiceId); ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, item->mServiceName); @@ -249,6 +251,13 @@ const RsPeerId& p3ServiceControl::getOwnId() return mOwnPeerId; } +bool p3ServiceControl::getServiceItemNames(uint32_t serviceId,std::map& names) +{ + if(mServiceServer != NULL) + return mServiceServer->getServiceItemNames(serviceId,names) ; + + return false ; +} /* Interface for Services */ bool p3ServiceControl::registerService(const RsServiceInfo &info, bool defaultOn) @@ -538,7 +547,7 @@ bool p3ServiceControl::updateServicePermissions(uint32_t serviceId, const RsServ { for(pit = onlinePeers.begin(); pit != onlinePeers.end(); ++pit) { - if (it->second.peerHasPermission(*pit) != + if (it->second.peerHasPermission(*pit) != permissions.peerHasPermission(*pit)) { mUpdatedSet.insert(*pit); @@ -598,7 +607,7 @@ bool p3ServiceControl::checkFilter(uint32_t serviceId, const RsPeerId &peerId) #endif // must allow ServiceInfo through, or we have nothing! -#define FULLID_SERVICEINFO ((((uint32_t) RS_PKT_VERSION_SERVICE) << 24) + ((RS_SERVICE_TYPE_SERVICEINFO) << 8)) +#define FULLID_SERVICEINFO ((((uint32_t) RS_PKT_VERSION_SERVICE) << 24) + ((RS_SERVICE_TYPE_SERVICEINFO) << 8)) //if (serviceId == RS_SERVICE_TYPE_SERVICEINFO) if (serviceId == FULLID_SERVICEINFO) @@ -692,21 +701,21 @@ bool ServiceInfoCompatible(const RsServiceInfo &info1, const RsServiceInfo &info } // ensure that info1 meets minimum requirements for info2 - if (!versionOkay(info1.mVersionMajor, info1.mVersionMinor, + if (!versionOkay(info1.mVersionMajor, info1.mVersionMinor, info2.mMinVersionMajor, info2.mMinVersionMinor)) { return false; } // ensure that info2 meets minimum requirements for info1 - if (!versionOkay(info2.mVersionMajor, info2.mVersionMinor, + if (!versionOkay(info2.mVersionMajor, info2.mVersionMinor, info1.mMinVersionMajor, info1.mMinVersionMinor)) { return false; } return true; } - + bool p3ServiceControl::updateFilterByPeer(const RsPeerId &peerId) { @@ -791,8 +800,8 @@ bool p3ServiceControl::updateFilterByPeer_locked(const RsPeerId &peerId) std::cerr << "p3ServiceControl::updateFilterByPeer_locked() Empty ... Clearing"; std::cerr << std::endl; #endif - - // empty, remove... + + // empty, remove... recordFilterChanges_locked(peerId, originalFilter, peerFilter); if (fit != mPeerFilterMap.end()) { @@ -883,7 +892,7 @@ bool p3ServiceControl::updateFilterByPeer_locked(const RsPeerId &peerId) std::cerr << "p3ServiceControl::updateFilterByPeer_locked() Empty(2) ... Clearing"; std::cerr << std::endl; #endif - + if (fit != mPeerFilterMap.end()) { mPeerFilterMap.erase(fit); @@ -901,7 +910,7 @@ bool p3ServiceControl::updateFilterByPeer_locked(const RsPeerId &peerId) return true; } -void p3ServiceControl::recordFilterChanges_locked(const RsPeerId &peerId, +void p3ServiceControl::recordFilterChanges_locked(const RsPeerId &peerId, ServicePeerFilter &originalFilter, ServicePeerFilter &updatedFilter) { #ifdef SERVICECONTROL_DEBUG @@ -1203,7 +1212,7 @@ bool p3ServiceControl::loadList(std::list& loadList) if(item != NULL) mServicePermissionMap[item->mServiceId] = *item ; - + delete *it ; } @@ -1397,49 +1406,49 @@ void p3ServiceControl::notifyServices() std::cerr << "p3ServiceControl::notifyServices(): Noone Monitoring ... skipping"; std::cerr << std::endl; #endif - + continue; } - + std::list peers; std::set::const_iterator pit; - for(pit = it->second.mAdded.begin(); + for(pit = it->second.mAdded.begin(); pit != it->second.mAdded.end(); ++pit) { pqiServicePeer peer; peer.id = *pit; peer.actions = RS_SERVICE_PEER_CONNECTED; - + peers.push_back(peer); - + #ifdef SERVICECONTROL_DEBUG std::cerr << "p3ServiceControl::notifyServices(): Peer: " << *pit << " CONNECTED"; std::cerr << std::endl; #endif } - - for(pit = it->second.mRemoved.begin(); + + for(pit = it->second.mRemoved.begin(); pit != it->second.mRemoved.end(); ++pit) { pqiServicePeer peer; peer.id = *pit; peer.actions = RS_SERVICE_PEER_DISCONNECTED; - + peers.push_back(peer); - + #ifdef SERVICECONTROL_DEBUG std::cerr << "p3ServiceControl::notifyServices(): Peer: " << *pit << " DISCONNECTED"; std::cerr << std::endl; #endif } - + for(; sit != eit; ++sit) { #ifdef SERVICECONTROL_DEBUG std::cerr << "p3ServiceControl::notifyServices(): Sending to Monitoring Service"; std::cerr << std::endl; #endif - + sit->second->statusChange(peers); } } @@ -1501,17 +1510,17 @@ void RsServicePermissions::resetPermission(const RsPeerId& peerId) } RsServiceInfo::RsServiceInfo( - const uint16_t service_type, - const std::string service_name, + const uint16_t service_type, + const std::string service_name, const uint16_t version_major, const uint16_t version_minor, const uint16_t min_version_major, const uint16_t min_version_minor) - :mServiceName(service_name), - mServiceType((((uint32_t) RS_PKT_VERSION_SERVICE) << 24) + (((uint32_t) service_type) << 8)), - mVersionMajor(version_major), + :mServiceName(service_name), + mServiceType((((uint32_t) RS_PKT_VERSION_SERVICE) << 24) + (((uint32_t) service_type) << 8)), + mVersionMajor(version_major), mVersionMinor(version_minor), - mMinVersionMajor(min_version_major), + mMinVersionMajor(min_version_major), mMinVersionMinor(min_version_minor) { return; @@ -1519,7 +1528,7 @@ RsServiceInfo::RsServiceInfo( RsServiceInfo::RsServiceInfo() - :mServiceName("unknown"), + :mServiceName("unknown"), mServiceType(0), mVersionMajor(0), mVersionMinor(0), diff --git a/libretroshare/src/pqi/p3servicecontrol.h b/libretroshare/src/pqi/p3servicecontrol.h index 948481a2b..9c9724347 100644 --- a/libretroshare/src/pqi/p3servicecontrol.h +++ b/libretroshare/src/pqi/p3servicecontrol.h @@ -36,6 +36,8 @@ #include "pqi/pqiservicemonitor.h" #include "pqi/p3linkmgr.h" +class p3ServiceServer ; + class ServiceNotifications { public: @@ -101,6 +103,9 @@ virtual bool updateServicePermissions(uint32_t serviceId, const RsServicePermiss virtual void getPeersConnected(const uint32_t serviceId, std::set &peerSet); virtual bool isPeerConnected(const uint32_t serviceId, const RsPeerId &peerId); + // Gets the list of items used by that service +virtual bool getServiceItemNames(uint32_t serviceId,std::map& names) ; + /** * Registration for all Services. */ @@ -132,6 +137,8 @@ virtual bool updateServicesProvided(const RsPeerId &peerId, const RsPeerServiceI // pqiMonitor. virtual void statusChange(const std::list &plist); + virtual void setServiceServer(p3ServiceServer *p) { mServiceServer = p ; } + protected: // configuration. virtual bool saveList(bool &cleanup, std::list&); @@ -196,6 +203,7 @@ bool peerHasPermissionForService_locked(const RsPeerId &peerId, uint32_t service // Below here is saved in Configuration. std::map mServicePermissionMap; + p3ServiceServer *mServiceServer ; }; diff --git a/libretroshare/src/pqi/pqimonitor.cc b/libretroshare/src/pqi/pqimonitor.cc index 03894a66d..fac7a50f9 100644 --- a/libretroshare/src/pqi/pqimonitor.cc +++ b/libretroshare/src/pqi/pqimonitor.cc @@ -61,14 +61,20 @@ void pqiConnectCbDummy::peerStatus(const RsPeerId& id, const pqiIpAddrSet &ad std::cerr << out << std::endl; } -void pqiConnectCbDummy::peerConnectRequest(const RsPeerId& id, - const struct sockaddr_storage &raddr, uint32_t source) +void pqiConnectCbDummy::peerConnectRequest(const RsPeerId &id, const sockaddr_storage &raddr + , const sockaddr_storage &proxyaddr, const sockaddr_storage &srcaddr + , uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth) { std::cerr << "pqiConnectCbDummy::peerConnectRequest()"; std::cerr << " id: " << id; std::cerr << " raddr: " << sockaddr_storage_tostring(raddr); + std::cerr << " proxyaddr: " << sockaddr_storage_tostring(proxyaddr); + std::cerr << " srcaddr: " << sockaddr_storage_tostring(srcaddr); std::cerr << " source: " << source; - std::cerr << std::endl; + std::cerr << " flags: " << flags; + std::cerr << " delay: " << delay; + std::cerr << " bandwidth: " << bandwidth; + std::cerr << std::endl; } void pqiMonitor::disconnectPeer(const RsPeerId &/*peer*/) diff --git a/libretroshare/src/pqi/pqimonitor.h b/libretroshare/src/pqi/pqimonitor.h index 34d998e75..94e9bdf05 100644 --- a/libretroshare/src/pqi/pqimonitor.h +++ b/libretroshare/src/pqi/pqimonitor.h @@ -179,8 +179,9 @@ virtual ~pqiConnectCbDummy(); virtual void peerStatus(const RsPeerId& id, const pqiIpAddrSet &addrs, uint32_t type, uint32_t mode, uint32_t source); -virtual void peerConnectRequest(const RsPeerId& id, - const struct sockaddr_storage &raddr, uint32_t source); + virtual void peerConnectRequest(const RsPeerId& id, const struct sockaddr_storage &raddr, + const struct sockaddr_storage &proxyaddr, const struct sockaddr_storage &srcaddr, + uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth); //virtual void stunStatus(std::string id, const struct sockaddr_storage &raddr, uint32_t type, uint32_t flags); }; diff --git a/libretroshare/src/pqi/pqiperson.cc b/libretroshare/src/pqi/pqiperson.cc index cade0c39e..e7d1cf18b 100644 --- a/libretroshare/src/pqi/pqiperson.cc +++ b/libretroshare/src/pqi/pqiperson.cc @@ -40,7 +40,7 @@ static struct RsLog::logInfo pqipersonzoneInfo = {RsLog::Default, "pqiperson"}; pqiperson::pqiperson(const RsPeerId& id, pqipersongrp *pg) : PQInterface(id), mNotifyMtx("pqiperson-notify"), mPersonMtx("pqiperson"), - active(false), activepqi(NULL), inConnectAttempt(false), waittimes(0), + active(false), activepqi(NULL), inConnectAttempt(false),// waittimes(0), pqipg(pg) {} // TODO: must check id! pqiperson::~pqiperson() diff --git a/libretroshare/src/pqi/pqiperson.h b/libretroshare/src/pqi/pqiperson.h index f3ff940e1..69faec48c 100644 --- a/libretroshare/src/pqi/pqiperson.h +++ b/libretroshare/src/pqi/pqiperson.h @@ -29,6 +29,7 @@ #define MRK_PQI_PERSON_HEADER +#include #include "pqi/pqi.h" #include "util/rsnet.h" @@ -66,7 +67,7 @@ public: virtual int reset() { pqistreamer::reset(); return ni->reset(); } virtual int disconnect() { return reset() ; } virtual bool connect_parameter(uint32_t type, uint32_t value) { return ni->connect_parameter(type, value);} - virtual bool connect_parameter(uint32_t type, std::string value) { return ni->connect_parameter(type, value);} + virtual bool connect_parameter(uint32_t type, const std::string &value) { return ni->connect_parameter(type, value);} virtual bool connect_additional_address(uint32_t type, const struct sockaddr_storage &addr) { return ni->connect_additional_address(type, addr); } virtual int getConnectAddress(struct sockaddr_storage &raddr){ return ni->getConnectAddress(raddr); } @@ -171,7 +172,7 @@ private: bool active; pqiconnect *activepqi; bool inConnectAttempt; - int waittimes; + //int waittimes; time_t lastHeartbeatReceived; // use to track connection failure pqipersongrp *pqipg; /* parent for callback */ }; diff --git a/libretroshare/src/pqi/pqiservice.cc b/libretroshare/src/pqi/pqiservice.cc index 4ba249c69..d9c93cc18 100644 --- a/libretroshare/src/pqi/pqiservice.cc +++ b/libretroshare/src/pqi/pqiservice.cc @@ -79,11 +79,26 @@ int p3ServiceServer::addService(pqiService *ts, bool defaultOn) services[info.mServiceType] = ts; // This doesn't need to be in Mutex. - mServiceControl->registerService(info, defaultOn); + mServiceControl->registerService(info,defaultOn); return 1; } +bool p3ServiceServer::getServiceItemNames(uint32_t service_type,std::map& names) +{ + RsStackMutex stack(srvMtx); /********* LOCKED *********/ + + std::map::iterator it=services.find(service_type) ; + + if(it != services.end()) + { + it->second->getItemNames(names) ; + return true ; + } + else + return false ; +} + int p3ServiceServer::removeService(pqiService *ts) { RsStackMutex stack(srvMtx); /********* LOCKED *********/ diff --git a/libretroshare/src/pqi/pqiservice.h b/libretroshare/src/pqi/pqiservice.h index c293cc005..41c540d4c 100644 --- a/libretroshare/src/pqi/pqiservice.h +++ b/libretroshare/src/pqi/pqiservice.h @@ -60,24 +60,26 @@ class p3ServiceServerIface; class pqiService { - protected: +protected: pqiService() // our type of packets. - :mServiceServer(NULL) { return; } + :mServiceServer(NULL) { return; } -virtual ~pqiService() { return; } + virtual ~pqiService() { return; } - public: -void setServiceServer(p3ServiceServerIface *server); - // -virtual bool recv(RsRawItem *) = 0; -virtual bool send(RsRawItem *item); +public: + void setServiceServer(p3ServiceServerIface *server); + // + virtual bool recv(RsRawItem *) = 0; + virtual bool send(RsRawItem *item); -virtual RsServiceInfo getServiceInfo() = 0; + virtual RsServiceInfo getServiceInfo() = 0; -virtual int tick() { return 0; } + virtual int tick() { return 0; } - private: + virtual void getItemNames(std::map& /*names*/) const {} // This does nothing by default. Service should derive it in order to give info for the UI + +private: p3ServiceServerIface *mServiceServer; // const, no need for mutex. }; @@ -97,10 +99,10 @@ public: virtual ~p3ServiceServerIface() {} -virtual bool recvItem(RsRawItem *) = 0; -virtual bool sendItem(RsRawItem *) = 0; - + virtual bool recvItem(RsRawItem *) = 0; + virtual bool sendItem(RsRawItem *) = 0; + virtual bool getServiceItemNames(uint32_t service_type,std::map& names) =0; }; class p3ServiceServer : public p3ServiceServerIface @@ -108,13 +110,15 @@ class p3ServiceServer : public p3ServiceServerIface public: p3ServiceServer(pqiPublisher *pub, p3ServiceControl *ctrl); -int addService(pqiService *, bool defaultOn); -int removeService(pqiService *); + int addService(pqiService *, bool defaultOn); + int removeService(pqiService *); -bool recvItem(RsRawItem *); -bool sendItem(RsRawItem *); + bool recvItem(RsRawItem *); + bool sendItem(RsRawItem *); -int tick(); + bool getServiceItemNames(uint32_t service_type, std::map& names) ; + + int tick(); public: private: @@ -122,7 +126,7 @@ private: pqiPublisher *mPublisher; // constant no need for mutex. p3ServiceControl *mServiceControl; - RsMutex srvMtx; + RsMutex srvMtx; std::map services; }; diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc index b7709bb82..bcc49cbbc 100644 --- a/libretroshare/src/pqi/pqissl.cc +++ b/libretroshare/src/pqi/pqissl.cc @@ -1009,7 +1009,7 @@ int pqissl::Basic_Connection_Complete() return -1; } - else if ((err == ECONNREFUSED)) + else if (err == ECONNREFUSED) { rslog(RSL_WARNING, pqisslzone, "pqissl::Basic_Connection_Complete() ECONNREFUSED: cert: " + PeerId().toStdString()); diff --git a/libretroshare/src/pqi/pqissludp.cc b/libretroshare/src/pqi/pqissludp.cc index 9519e2af3..29bd228c9 100644 --- a/libretroshare/src/pqi/pqissludp.cc +++ b/libretroshare/src/pqi/pqissludp.cc @@ -53,7 +53,7 @@ static const uint32_t PQI_SSLUDP_DEF_CONN_PERIOD = 300; /* 5 minutes? */ /********** PQI SSL UDP STUFF **************************************/ pqissludp::pqissludp(PQInterface *parent, p3LinkMgr *lm) : - pqissl(NULL, parent, lm), tou_bio(NULL), listen_checktime(0), + pqissl(NULL, parent, lm), tou_bio(NULL),// listen_checktime(0), mConnectPeriod(PQI_SSLUDP_DEF_CONN_PERIOD), mConnectFlags(0), mConnectBandwidth(0) { diff --git a/libretroshare/src/pqi/pqissludp.h b/libretroshare/src/pqi/pqissludp.h index 848717bbd..195e9e604 100644 --- a/libretroshare/src/pqi/pqissludp.h +++ b/libretroshare/src/pqi/pqissludp.h @@ -95,7 +95,7 @@ private: BIO *tou_bio; // specific to ssludp. - long listen_checktime; + //long listen_checktime; uint32_t mConnectPeriod; uint32_t mConnectFlags; diff --git a/libretroshare/src/pqi/sslfns.cc b/libretroshare/src/pqi/sslfns.cc index 7cf742956..ba5a9e6a3 100644 --- a/libretroshare/src/pqi/sslfns.cc +++ b/libretroshare/src/pqi/sslfns.cc @@ -627,7 +627,7 @@ bool getX509id(X509 *x509, RsPeerId& xid) * more randomness */ -#warning this is cryptographically horrible. We should do a hash of the public key here!!! +#warning csoler 2017-02-19: This is cryptographically horrible. We should do a hash of the public key here!!! xid = RsPeerId(&signdata[signlen - CERTSIGNLEN]) ; diff --git a/libretroshare/src/retroshare/rsgxsifacetypes.h b/libretroshare/src/retroshare/rsgxsifacetypes.h index 0b1682327..fd477fc9f 100644 --- a/libretroshare/src/retroshare/rsgxsifacetypes.h +++ b/libretroshare/src/retroshare/rsgxsifacetypes.h @@ -26,7 +26,7 @@ typedef std::pair RsGxsGrpMsgIdPair; typedef std::map > MsgRelatedIdResult; typedef std::map > GxsMsgReq; -class RsMsgMetaData; +struct RsMsgMetaData; typedef std::map > MsgMetaResult; diff --git a/libretroshare/src/retroshare/rsgxsservice.h b/libretroshare/src/retroshare/rsgxsservice.h index 8f26e5262..6afed31c6 100644 --- a/libretroshare/src/retroshare/rsgxsservice.h +++ b/libretroshare/src/retroshare/rsgxsservice.h @@ -5,7 +5,7 @@ #include "retroshare/rsgxsifacetypes.h" #include "retroshare/rstokenservice.h" -class RsMsgMetaData ; +struct RsMsgMetaData ; typedef std::map > GxsMsgMetaMap; typedef std::map > GxsMsgRelatedMetaMap; diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index 82f4932a3..6be124e93 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -305,6 +305,9 @@ public: virtual bool setAsRegularContact(const RsGxsId& id,bool is_a_contact) = 0 ; virtual bool isARegularContact(const RsGxsId& id) = 0 ; + virtual bool serialiseIdentityToMemory(const RsGxsId& id,std::string& radix_string)=0; + virtual bool deserialiseIdentityFromMemory(const std::string& radix_string)=0; + /*! * \brief overallReputationLevel * Returns the overall reputation level of the supplied identity. See rsreputations.h @@ -319,6 +322,7 @@ public: */ virtual bool getGroupData(const uint32_t &token, std::vector &groups) = 0; + virtual bool getGroupSerializedData(const uint32_t &token, std::map& serialized_groups)=0; //virtual bool getMsgData(const uint32_t &token, std::vector &opinions) = 0; }; diff --git a/libretroshare/src/retroshare/rsservicecontrol.h b/libretroshare/src/retroshare/rsservicecontrol.h index a6d8fde7c..7558764e7 100644 --- a/libretroshare/src/retroshare/rsservicecontrol.h +++ b/libretroshare/src/retroshare/rsservicecontrol.h @@ -109,6 +109,7 @@ virtual ~RsServiceControl() { return; } virtual bool getOwnServices(RsPeerServiceInfo &info) = 0; virtual std::string getServiceName(uint32_t service_id) = 0; +virtual bool getServiceItemNames(uint32_t service_id,std::map& names) = 0; virtual bool getServicesAllowed(const RsPeerId &peerId, RsPeerServiceInfo &info) = 0; virtual bool getServicesProvided(const RsPeerId &peerId, RsPeerServiceInfo &info) = 0; diff --git a/libretroshare/src/retroshare/rstokenservice.h b/libretroshare/src/retroshare/rstokenservice.h index c55213965..5e74a527f 100644 --- a/libretroshare/src/retroshare/rstokenservice.h +++ b/libretroshare/src/retroshare/rstokenservice.h @@ -47,6 +47,7 @@ #define GXS_REQUEST_TYPE_GROUP_STATS 0x01600000 #define GXS_REQUEST_TYPE_SERVICE_STATS 0x03200000 +#define GXS_REQUEST_TYPE_GROUP_SERIALIZED_DATA 0x04000000 // TODO CLEANUP: RS_TOKREQOPT_MSG_* should be an inner enum of RsTokReqOptions diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index 73a5801fd..f43dfb485 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -1037,6 +1037,9 @@ bool p3Peers::setProxyServer(const uint32_t type, const std::string &addr_str, c std::cerr << "(EE) attempt to set proxy server address to something not allowed: " << addr_str << ":" << port << std::endl; return false ; } + + std::cerr << "Settign proxy server address to " << addr_str << ":" << port << std::endl; + struct sockaddr_storage addr; struct sockaddr_in *addrv4p = (struct sockaddr_in *) &addr; addrv4p->sin_family = AF_INET; diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 47036b691..fd378b286 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1243,6 +1243,8 @@ int RsServer::StartupRetroShare() pqih = new pqisslpersongrp(serviceCtrl, flags, mPeerMgr); //pqih = new pqipersongrpDummy(none, flags); + serviceCtrl->setServiceServer(pqih) ; + /****** New Ft Server **** !!! */ ftServer *ftserver = new ftServer(mPeerMgr, serviceCtrl); ftserver->setConfigDirectory(rsAccounts->PathAccountDirectory()); diff --git a/libretroshare/src/services/p3banlist.cc b/libretroshare/src/services/p3banlist.cc index 800fe697c..6fd733de5 100644 --- a/libretroshare/src/services/p3banlist.cc +++ b/libretroshare/src/services/p3banlist.cc @@ -67,8 +67,8 @@ */ RsBanList *rsBanList = NULL ; -p3BanList::p3BanList(p3ServiceControl *sc, p3NetMgr *nm) - :p3Service(), mBanMtx("p3BanList"), mServiceCtrl(sc), mNetMgr(nm) +p3BanList::p3BanList(p3ServiceControl *sc, p3NetMgr */*nm*/) + :p3Service(), mBanMtx("p3BanList"), mServiceCtrl(sc)//, mNetMgr(nm) { addSerialType(new RsBanListSerialiser()); diff --git a/libretroshare/src/services/p3banlist.h b/libretroshare/src/services/p3banlist.h index 7cdc983a5..5a31bd1b1 100644 --- a/libretroshare/src/services/p3banlist.h +++ b/libretroshare/src/services/p3banlist.h @@ -148,7 +148,7 @@ private: std::map mWhiteListedRanges; p3ServiceControl *mServiceCtrl; - p3NetMgr *mNetMgr; + //p3NetMgr *mNetMgr; time_t mLastDhtInfoRequest ; bool mIPFilteringEnabled ; diff --git a/libretroshare/src/services/p3gxsreputation.cc b/libretroshare/src/services/p3gxsreputation.cc index d2ad1b9da..ae4189cfe 100644 --- a/libretroshare/src/services/p3gxsreputation.cc +++ b/libretroshare/src/services/p3gxsreputation.cc @@ -1036,7 +1036,7 @@ bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::O if (rit == mReputations.end()) { -#warning we should set the owner node id here. +#warning csoler 2017-01-05: We should set the owner node id here. mReputations[gxsid] = Reputation(gxsid); rit = mReputations.find(gxsid); } diff --git a/libretroshare/src/services/p3gxsreputation.h b/libretroshare/src/services/p3gxsreputation.h index 06ff7415b..ad45e2298 100644 --- a/libretroshare/src/services/p3gxsreputation.h +++ b/libretroshare/src/services/p3gxsreputation.h @@ -176,7 +176,7 @@ private: time_t mLastIdentityFlagsUpdate ; bool mReputationsUpdated; - float mAutoBanIdentitiesLimit ; + //float mAutoBanIdentitiesLimit ; bool mAutoSetPositiveOptionToContacts; p3LinkMgr *mLinkMgr; diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 37c609373..f267accd0 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -70,6 +70,8 @@ static const time_t MAX_KEEP_KEYS_SIGNED_KNOWN = 30 * 86400 ; // signed ident static const uint32_t MAX_DELAY_BEFORE_CLEANING= 1800 ; // clean old keys every 30 mins +static const uint32_t MAX_SERIALISED_IDENTITY_AGE = 600 ; // after 10 mins, a serialised identity record must be renewed. + RsIdentity *rsIdentity = NULL; /****** @@ -97,13 +99,12 @@ RsIdentity *rsIdentity = NULL; #define BG_REPUTATION 3 -#define GXSIDREQ_CACHELOAD 0x0001 -#define GXSIDREQ_CACHEOWNIDS 0x0002 - -#define GXSIDREQ_PGPHASH 0x0010 -#define GXSIDREQ_RECOGN 0x0020 - -#define GXSIDREQ_OPINION 0x0030 +#define GXSIDREQ_CACHELOAD 0x0001 +#define GXSIDREQ_CACHEOWNIDS 0x0002 +#define GXSIDREQ_PGPHASH 0x0010 +#define GXSIDREQ_RECOGN 0x0020 +#define GXSIDREQ_OPINION 0x0030 +#define GXSIDREQ_SERIALIZE_TO_MEMORY 0x0040 #define GXSIDREQ_CACHETEST 0x1000 @@ -697,6 +698,84 @@ bool p3IdService::getOwnIds(std::list &ownIds) return true ; } +bool p3IdService::serialiseIdentityToMemory(const RsGxsId& id,std::string& radix_string) +{ + RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ + + // look into cache. If available, return the data. If not, request it. + + std::map::const_iterator it = mSerialisedIdentities.find(id); + + if(it != mSerialisedIdentities.end()) + { + Radix64::encode(it->second.mMem,it->second.mSize,radix_string) ; + + if(it->second.mLastUsageTS + MAX_SERIALISED_IDENTITY_AGE > time(NULL)) + return true ; + + std::cerr << "Identity " << id << " will be re-serialised, because the last record is too old." << std::endl; + } + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + uint32_t token = 0; + std::list groupIds; + + groupIds.push_back(RsGxsGroupId(id)) ; + + RsGenExchange::getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds); + GxsTokenQueue::queueRequest(token, GXSIDREQ_SERIALIZE_TO_MEMORY); + + return false; +} + +void p3IdService::handle_get_serialized_grp(uint32_t token) +{ + // store the serialized data in cache. + + unsigned char *mem = NULL; + uint32_t size; + RsGxsGroupId id ; + + if(!RsGenExchange::getSerializedGroupData(token,id, mem,size)) + { + std::cerr << "(EE) call to RsGenExchage::getSerializedGroupData() failed." << std::endl; + return ; + } + + std::cerr << "Received serialised group from RsGenExchange." << std::endl; + + std::map::const_iterator it = mSerialisedIdentities.find(RsGxsId(id)); + + if(it != mSerialisedIdentities.end()) + free(it->second.mMem) ; + + SerialisedIdentityStruct s ; + s.mMem = mem ; + s.mSize = size ; + s.mLastUsageTS = time(NULL) ; + + mSerialisedIdentities[RsGxsId(id)] = s ; +} + +bool p3IdService::deserialiseIdentityFromMemory(const std::string& radix_string) +{ + std::vector mem = Radix64::decode(radix_string) ; + + if(mem.empty()) + { + std::cerr << "Cannot decode radix string \"" << radix_string << "\"" << std::endl; + return false ; + } + + if(!RsGenExchange::deserializeGroupData(mem.data(),mem.size())) + { + std::cerr << "Cannot load identity from radix string \"" << radix_string << "\"" << std::endl; + return false ; + } + + return true ; +} bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) { @@ -709,7 +788,7 @@ bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) if (params.isPgpLinked) { -#warning Backward compatibility issue to fix here in v0.7.0 +#warning csoler 2017-02-07: Backward compatibility issue to fix here in v0.7.0 // This is a hack, because a bad decision led to having RSGXSID_GROUPFLAG_REALID be equal to GXS_SERV::FLAG_PRIVACY_PRIVATE. // In order to keep backward compatibility, we'll also add the new value @@ -1395,6 +1474,28 @@ bool p3IdService::getGroupData(const uint32_t &token, std::vector return ok; } +bool p3IdService::getGroupSerializedData(const uint32_t &token, std::map& serialized_groups) +{ + unsigned char *mem = NULL; + uint32_t size; + RsGxsGroupId id ; + + serialized_groups.clear() ; + + if(!RsGenExchange::getSerializedGroupData(token,id, mem,size)) + { + std::cerr << "(EE) call to RsGenExchage::getSerializedGroupData() failed." << std::endl; + return false; + } + + std::string radix ; + + Radix64::encode(mem,size,radix) ; + + serialized_groups[RsGxsId(id)] = radix ; + + return true; +} /********************************************************************************/ /********************************************************************************/ @@ -4117,6 +4218,9 @@ void p3IdService::handleResponse(uint32_t token, uint32_t req_type) case GXSIDREQ_OPINION: opinion_handlerequest(token); break; + case GXSIDREQ_SERIALIZE_TO_MEMORY: + handle_get_serialized_grp(token) ; + default: /* error */ std::cerr << "p3IdService::handleResponse() Unknown Request Type: " << req_type; diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index f745aca83..a88f0ad7e 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -212,6 +212,13 @@ private: void init(const RsGxsIdGroupItem *item, const RsTlvPublicRSAKey& in_pub_key, const RsTlvPrivateRSAKey& in_priv_key,const std::list &tagList); }; +struct SerialisedIdentityStruct +{ + unsigned char *mMem ; + uint32_t mSize ; + time_t mLastUsageTS; +}; + // Not sure exactly what should be inherited here? // Chris - please correct as necessary. @@ -238,6 +245,8 @@ public: // These are exposed via RsIdentity. virtual bool getGroupData(const uint32_t &token, std::vector &groups); + virtual bool getGroupSerializedData(const uint32_t &token, std::map& serialized_groups); + //virtual bool getMsgData(const uint32_t &token, std::vector &opinions); // These are local - and not exposed via RsIdentity. @@ -302,6 +311,8 @@ public: virtual bool requestKey(const RsGxsId &id, const std::list &peers, const RsIdentityUsage &use_info); virtual bool requestPrivateKey(const RsGxsId &id); + virtual bool serialiseIdentityToMemory(const RsGxsId& id,std::string& radix_string); + virtual bool deserialiseIdentityFromMemory(const std::string& radix_string); /**************** RsGixsReputation Implementation ****************/ @@ -394,6 +405,12 @@ private: bool mBgSchedule_Active; uint32_t mBgSchedule_Mode; + /***********************************8 + * Fonction to receive and handle group serialisation to memory + */ + + virtual void handle_get_serialized_grp(uint32_t token); + /************************************************************************ * pgphash processing. * @@ -524,6 +541,8 @@ private: std::map > mIdsNotPresent; std::map mKeysTS ; + std::map mSerialisedIdentities ; + // keep a list of regular contacts. This is useful to sort IDs, and allow some services to priviledged ids only. std::set mContacts; RsNetworkExchangeService* mNes; diff --git a/libretroshare/src/util/radix64.h b/libretroshare/src/util/radix64.h index dc7f8528c..7776995f9 100644 --- a/libretroshare/src/util/radix64.h +++ b/libretroshare/src/util/radix64.h @@ -93,9 +93,9 @@ again: idx = (idx + 1) % 4; } - idx = idx; + //idx = idx; - return buf; + return buf ; } /**************** @@ -147,7 +147,7 @@ again: private: static inline char *bintoasc() { static char bta[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; return bta ; } - static inline char *asctobin() { static char s[256]; return s ; } /* runtime radix64_initd */ + static inline uint8_t *asctobin() { static uint8_t s[256]; return s ; } /* runtime radix64_initd */ static int& is_radix64_initd() { static int is_inited = false ; return is_inited ; } /* hey, guess what: this is a read-only table. diff --git a/libretroshare/src/util/rsnet.cc b/libretroshare/src/util/rsnet.cc index 63501511b..8b8c9ef82 100644 --- a/libretroshare/src/util/rsnet.cc +++ b/libretroshare/src/util/rsnet.cc @@ -81,15 +81,18 @@ bool rsGetHostByName(const std::string& hostname, in_addr& returned_addr) addrinfo *info = NULL; int res = getaddrinfo(hostname.c_str(),NULL,NULL,&info) ; + bool ok = true; if(res > 0 || info == NULL || info->ai_addr == NULL) { std::cerr << "(EE) getaddrinfo returned error " << res << " on string \"" << hostname << "\"" << std::endl; returned_addr.s_addr = 0 ; + ok = false; } else returned_addr.s_addr = ((sockaddr_in*)info->ai_addr)->sin_addr.s_addr ; - freeaddrinfo(info) ; + if(info) + freeaddrinfo(info) ; #ifdef DEPRECATED_TO_REMOVE #if defined(WINDOWS_SYS) || defined(__APPLE__) || defined(__HAIKU__) @@ -123,7 +126,7 @@ bool rsGetHostByName(const std::string& hostname, in_addr& returned_addr) returned_addr.s_addr = *(unsigned long*) (result->h_addr); #endif - return true ; + return ok; } bool isValidNet(const struct in_addr *addr) diff --git a/openpgpsdk/src/openpgpsdk/packet-parse.c b/openpgpsdk/src/openpgpsdk/packet-parse.c index b80cf4ef8..a4596a55c 100644 --- a/openpgpsdk/src/openpgpsdk/packet-parse.c +++ b/openpgpsdk/src/openpgpsdk/packet-parse.c @@ -2394,7 +2394,7 @@ static int parse_secret_key(ops_region_t *region,ops_parse_info_t *pinfo) else if(C.secret_key.s2k_usage != OPS_S2KU_NONE) { // this is V3 style, looks just like a V4 simple hash - C.secret_key.algorithm=C.secret_key.s2k_usage; + C.secret_key.algorithm=(ops_symmetric_algorithm_t)C.secret_key.s2k_usage; C.secret_key.s2k_usage=OPS_S2KU_ENCRYPTED; C.secret_key.s2k_specifier=OPS_S2KS_SIMPLE; C.secret_key.hash_algorithm=OPS_HASH_MD5; diff --git a/plugins/FeedReader/services/p3FeedReaderThread.cc b/plugins/FeedReader/services/p3FeedReaderThread.cc index c638304f4..9ec1106ef 100644 --- a/plugins/FeedReader/services/p3FeedReaderThread.cc +++ b/plugins/FeedReader/services/p3FeedReaderThread.cc @@ -651,7 +651,7 @@ static time_t parseRFC822Date(const std::string &pubDate) offset = abs(offset); offset = ((offset / 100)*60 + (offset % 100))*sgn; } else { - for (int i=0; known_zones[i].tzName != 0; i++) { + for (int i=0; known_zones[i].tzName[0] != 0; i++) { if (0 == strncasecmp(dateString, known_zones[i].tzName, strlen(known_zones[i].tzName))) { offset = known_zones[i].tzOffset; break; diff --git a/plugins/VOIP/gui/VOIPGUIHandler.cpp b/plugins/VOIP/gui/VOIPGUIHandler.cpp index 6a7d7d703..f999ed437 100644 --- a/plugins/VOIP/gui/VOIPGUIHandler.cpp +++ b/plugins/VOIP/gui/VOIPGUIHandler.cpp @@ -155,7 +155,7 @@ void VOIPGUIHandler::ReceivedVoipBandwidthInfo(const RsPeerId &peer_id, int byte #endif ChatDialog *di = ChatDialog::getExistingChat(ChatId(peer_id)) ; - if(!di) + if(di) { ChatWidget *cw = di->getChatWidget(); diff --git a/plugins/VOIP/gui/VOIPToasterNotify.cpp b/plugins/VOIP/gui/VOIPToasterNotify.cpp index d2de3f6bd..eff862467 100644 --- a/plugins/VOIP/gui/VOIPToasterNotify.cpp +++ b/plugins/VOIP/gui/VOIPToasterNotify.cpp @@ -180,7 +180,7 @@ ToasterItem* VOIPToasterNotify::testToasterItem(QString tag) if (tag == "Invitation") toaster = new ToasterItem(new VOIPToasterItem(ownId, tr("Test VOIP Invitation"), VOIPToasterItem::Invitation)); #endif if (tag == "AudioCall") toaster = new ToasterItem(new VOIPToasterItem(ownId, tr("Test VOIP Audio Call"), VOIPToasterItem::AudioCall)); - if (tag == "VideoCall") toaster = new ToasterItem(new VOIPToasterItem(ownId, tr("Test VOIP Video Call"), VOIPToasterItem::VideoCall)); + if (tag == "VideoCall" || toaster == NULL) toaster = new ToasterItem(new VOIPToasterItem(ownId, tr("Test VOIP Video Call"), VOIPToasterItem::VideoCall)); return toaster; } diff --git a/plugins/VOIP/gui/VideoProcessor.h b/plugins/VOIP/gui/VideoProcessor.h index 4e47b2c29..4946c4342 100644 --- a/plugins/VOIP/gui/VideoProcessor.h +++ b/plugins/VOIP/gui/VideoProcessor.h @@ -66,7 +66,9 @@ private: AVPacket decoding_buffer; uint64_t encoding_frame_count ; +#ifdef DEBUG_MPEG_VIDEO FILE *encoding_debug_file ; +#endif }; // This class decodes video from a stream. It keeps a queue of diff --git a/retroshare-android-service/src/retroshare-android-service.pro b/retroshare-android-service/src/retroshare-android-service.pro index c2caa12a0..54843d34f 100644 --- a/retroshare-android-service/src/retroshare-android-service.pro +++ b/retroshare-android-service/src/retroshare-android-service.pro @@ -6,13 +6,11 @@ QT += core network QT -= gui CONFIG += c++11 -CONFIG += dll +android-g++:CONFIG += dll android-g++:TEMPLATE = lib !android-g++:TEMPLATE = app -SOURCES += service.cpp - DEPENDPATH *= ../../libresapi/src INCLUDEPATH *= ../../libresapi/src PRE_TARGETDEPS *= ../../libresapi/src/lib/libresapi.a @@ -22,3 +20,34 @@ DEPENDPATH *= ../../libretroshare/src INCLUDEPATH *= ../../libretroshare/src PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a LIBS *= ../../libretroshare/src/lib/libretroshare.a + +win32 { + OBJECTS_DIR = temp/obj + + LIBS_DIR = $$PWD/../../libs/lib + LIBS += $$OUT_PWD/../../libretroshare/src/lib/libretroshare.a + LIBS += $$OUT_PWD/../../openpgpsdk/src/lib/libops.a + + for(lib, LIB_DIR):LIBS += -L"$$lib" + for(bin, BIN_DIR):LIBS += -L"$$bin" + + + LIBS += -lssl -lcrypto -lpthread -lminiupnpc -lz -lws2_32 + LIBS += -luuid -lole32 -liphlpapi -lcrypt32 -lgdi32 + LIBS += -lwinmm + + DEFINES *= WINDOWS_SYS WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T + + DEPENDPATH += . $$INC_DIR + INCLUDEPATH += . $$INC_DIR + + greaterThan(QT_MAJOR_VERSION, 4) { + # Qt 5 + RC_INCLUDEPATH += $$_PRO_FILE_PWD_/../../libretroshare/src + } else { + # Qt 4 + QMAKE_RC += --include-dir=$$_PRO_FILE_PWD_/../../libretroshare/src + } +} + +SOURCES += service.cpp diff --git a/retroshare-android-service/src/service.cpp b/retroshare-android-service/src/service.cpp index d3759dc61..84ec62301 100644 --- a/retroshare-android-service/src/service.cpp +++ b/retroshare-android-service/src/service.cpp @@ -24,12 +24,10 @@ # include "util/androiddebug.h" #endif -#include "retroshare/rsinit.h" #include "api/ApiServer.h" #include "api/ApiServerLocal.h" #include "api/RsControlModule.h" - using namespace resource_api; int main(int argc, char *argv[]) @@ -39,11 +37,17 @@ int main(int argc, char *argv[]) #endif QCoreApplication a(argc, argv); + ApiServer api; RsControlModule ctrl_mod(argc, argv, api.getStateTokenServer(), &api, true); api.addResourceHandler("control", dynamic_cast(&ctrl_mod), &resource_api::RsControlModule::handleRequest); - QString sockPath = QString::fromStdString(RsAccounts::ConfigDirectory()); +#ifdef QT_DEBUG + QString sockPath = "RS/"; +#else + QString sockPath = QCoreApplication::applicationDirPath(); +#endif + sockPath.append("/libresapi.sock"); qDebug() << "Listening on:" << sockPath; ApiServerLocal apiServerLocal(&api, sockPath); (void) apiServerLocal; diff --git a/retroshare-gui/src/gui/ChatLobbyWidget.cpp b/retroshare-gui/src/gui/ChatLobbyWidget.cpp index 07d5112be..dadf04939 100644 --- a/retroshare-gui/src/gui/ChatLobbyWidget.cpp +++ b/retroshare-gui/src/gui/ChatLobbyWidget.cpp @@ -378,8 +378,12 @@ static void updateItem(QTreeWidget *treeWidget, QTreeWidgetItem *item, ChatLobby +QObject::tr("Id:")+" "+QString::number(id,16) ; if(lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED) + { tooltipstr += QObject::tr("\nSecurity: no anonymous IDs") ; - + QColor foreground = QColor(0, 128, 0); // green + for (int column = 0; column < COLUMN_COUNT; ++column) + item->setTextColor(column, foreground); + } item->setToolTip(0,tooltipstr) ; } @@ -653,7 +657,9 @@ void ChatLobbyWidget::updateDisplay() updateItem(ui.lobbyTreeWidget, item, lobby.lobby_id, lobby.lobby_name,lobby.lobby_topic, lobby.gxs_ids.size(), true, autoSubscribe,lobby_flags); } publicSubLobbyItem->setHidden(publicSubLobbyItem->childCount()==0); + publicSubLobbyItem->setText(COLUMN_NAME, tr("Public Subscribed chat rooms")+ QString(" (") + QString::number(publicSubLobbyItem->childCount())+QString(")")); privateSubLobbyItem->setHidden(privateSubLobbyItem->childCount()==0); + publicLobbyItem->setText(COLUMN_NAME, tr("Public chat rooms")+ " (" + QString::number(publicLobbyItem->childCount())+QString(")")); } void ChatLobbyWidget::createChatLobby() diff --git a/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp b/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp index 851679931..4728dde14 100644 --- a/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp +++ b/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp @@ -407,6 +407,13 @@ void SearchDialog::download() for(std::list::const_iterator it(srcIds.begin()); it!=srcIds.end(); ++it) { std::cout << *it << "-" << std::endl; }//for(std::list::const_iterator + //QColor foreground = QColor(0, 128, 0); // green + QColor foreground = textColorDownloading(); + QBrush brush(foreground); + for (int i = 0; i < item->columnCount(); ++i) + { + item->setForeground(i, brush); + } }//if(!rsFiles -> FileRequest( }//if (item->text(SR_HASH_COL).isEmpty()) }//for (int i = 0 @@ -1189,6 +1196,11 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s found = true ; if (!item->data(SR_DATA_COL, SR_ROLE_LOCAL).toBool()) { + + FileInfo fi; + if (rsFiles->FileDetails(file.hash, RS_FILE_HINTS_DOWNLOAD, fi)) + break; + QColor foreground; int sources = friendSource + anonymousSource ; @@ -1281,6 +1293,12 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s setForeground = true; } } + if (rsFiles->FileDetails(file.hash, RS_FILE_HINTS_DOWNLOAD, fi)) + { + //foreground = QColor(0, 128, 0); // green + foreground = textColorDownloading(); + setForeground = true; + } if (setForeground) { QBrush brush(foreground); diff --git a/retroshare-gui/src/gui/FileTransfer/SearchDialog.h b/retroshare-gui/src/gui/FileTransfer/SearchDialog.h index bfc5892cc..57846692c 100644 --- a/retroshare-gui/src/gui/FileTransfer/SearchDialog.h +++ b/retroshare-gui/src/gui/FileTransfer/SearchDialog.h @@ -38,6 +38,7 @@ class SearchDialog : public MainPage Q_OBJECT Q_PROPERTY(QColor textColorLocal READ textColorLocal WRITE setTextColorLocal) + Q_PROPERTY(QColor textColorDownloading READ textColorDownloading WRITE setTextColorDownloading) Q_PROPERTY(QColor textColorNoSources READ textColorNoSources WRITE setTextColorNoSources) Q_PROPERTY(QColor textColorLowSources READ textColorLowSources WRITE setTextColorLowSources) Q_PROPERTY(QColor textColorHighSources READ textColorHighSources WRITE setTextColorHighSources) @@ -51,11 +52,13 @@ public: void searchKeywords(const QString& keywords); QColor textColorLocal() const { return mTextColorLocal; } + QColor textColorDownloading() const { return mTextColorDownloading; } QColor textColorNoSources() const { return mTextColorNoSources; } QColor textColorLowSources() const { return mTextColorLowSources; } QColor textColorHighSources() const { return mTextColorHighSources; } void setTextColorLocal(QColor color) { mTextColorLocal = color; } + void setTextColorDownloading(QColor color) { mTextColorDownloading = color; } void setTextColorNoSources(QColor color) { mTextColorNoSources = color; } void setTextColorLowSources(QColor color) { mTextColorLowSources = color; } void setTextColorHighSources(QColor color) { mTextColorHighSources = color; } @@ -154,6 +157,7 @@ private: /* Color definitions (for standard see qss.default) */ QColor mTextColorLocal; + QColor mTextColorDownloading; QColor mTextColorNoSources; QColor mTextColorLowSources; QColor mTextColorHighSources; diff --git a/retroshare-gui/src/gui/GenCertDialog.cpp b/retroshare-gui/src/gui/GenCertDialog.cpp index ff8fbf909..c65c08b89 100644 --- a/retroshare-gui/src/gui/GenCertDialog.cpp +++ b/retroshare-gui/src/gui/GenCertDialog.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -45,7 +46,7 @@ #include #define IMAGE_GOOD ":/images/accepted16.png" -#define IMAGE_BAD ":/images/deletemail24.png" +#define IMAGE_BAD ":/images/cancel.png" class EntropyCollectorWidget: public QTextBrowser { @@ -133,8 +134,8 @@ GenCertDialog::GenCertDialog(bool onlyGenerateIdentity, QWidget *parent) //ui.headerFrame->setHeaderImage(QPixmap(":/icons/svg/profile.svg")); //ui.headerFrame->setHeaderText(tr("Create a new profile")); - connect(ui.reuse_existing_node_CB, SIGNAL(clicked()), this, SLOT(switchReuseExistingNode())); - connect(ui.adv_checkbox, SIGNAL(clicked()), this, SLOT(setupState())); + connect(ui.reuse_existing_node_CB, SIGNAL(triggered()), this, SLOT(switchReuseExistingNode())); + connect(ui.adv_checkbox, SIGNAL(triggered()), this, SLOT(setupState())); connect(ui.nodeType_CB, SIGNAL(currentIndexChanged(int)), this, SLOT(setupState())); connect(ui.genButton, SIGNAL(clicked()), this, SLOT(genPerson())); @@ -172,6 +173,11 @@ GenCertDialog::GenCertDialog(bool onlyGenerateIdentity, QWidget *parent) /* get all available pgp private certificates.... * mark last one as default. */ + + QMenu *menu = new QMenu(tr("Advanced options")); + menu->addAction(ui.adv_checkbox); + menu->addAction(ui.reuse_existing_node_CB); + ui.optionsButton->setMenu(menu); mAllFieldsOk = false ; mEntropyOk = false ; @@ -246,22 +252,22 @@ void GenCertDialog::setupState() genNewGPGKey = generate_new; - ui.no_node_label->setVisible(false); + //ui.no_node_label->setVisible(false); setWindowTitle(generate_new?tr("Create new profile and new Retroshare node"):tr("Create new Retroshare node")); //ui.headerFrame->setHeaderText(generate_new?tr("Create a new profile and node"):tr("Create a new node")); ui.label_nodeType->setVisible(adv_state) ; ui.nodeType_CB->setVisible(adv_state) ; - ui.reuse_existing_node_CB->setVisible(adv_state) ; + ui.reuse_existing_node_CB->setEnabled(adv_state) ; ui.importIdentity_PB->setVisible(adv_state && !generate_new) ; ui.exportIdentity_PB->setVisible(adv_state && !generate_new) ; ui.genPGPuser->setVisible(adv_state && haveGPGKeys && !generate_new) ; - ui.genprofileinfo_label->setVisible(false); - ui.no_gpg_key_label->setText(tr("Welcome to Retroshare. Before you can proceed you need to create a profile and associate a node with it. To do so please fill out this form.\nAlternatively you can import a (previously exported) profile. Just uncheck \"Create a new profile\"")); - ui.no_gpg_key_label->setVisible(false); + //ui.genprofileinfo_label->setVisible(false); + //ui.no_gpg_key_label->setText(tr("Welcome to Retroshare. Before you can proceed you need to create a profile and associate a node with it. To do so please fill out this form.\nAlternatively you can import a (previously exported) profile. Just uncheck \"Create a new profile\"")); + //no_gpg_key_label->setVisible(false); ui.nickname_label->setVisible(adv_state) ; ui.nickname_input->setVisible(adv_state) ; @@ -269,7 +275,7 @@ void GenCertDialog::setupState() ui.name_label->setVisible(true); ui.name_input->setVisible(generate_new); - ui.header_label->setVisible(false) ; + //ui.header_label->setVisible(false) ; ui.nickname_label->setVisible(adv_state && !mOnlyGenerateIdentity); ui.nickname_input->setVisible(adv_state && !mOnlyGenerateIdentity); @@ -300,14 +306,16 @@ void GenCertDialog::setupState() if(mEntropyOk && mAllFieldsOk) { ui.genButton->setEnabled(true) ; - ui.genButton->setIcon(QIcon(IMAGE_GOOD)) ; + //ui.genButton->setIcon(QIcon(IMAGE_GOOD)) ; ui.genButton->setToolTip(tr("Click to create your node and/or profile")) ; + ui.generate_label->setPixmap(QPixmap(IMAGE_GOOD)) ; } else { ui.genButton->setEnabled(false) ; - ui.genButton->setIcon(QIcon(IMAGE_BAD)) ; + //ui.genButton->setIcon(QIcon(IMAGE_BAD)) ; ui.genButton->setToolTip(tr("Disabled until all fields correctly set and enough randomness collected.")) ; + ui.generate_label->setPixmap(QPixmap(IMAGE_BAD)) ; } } @@ -495,9 +503,9 @@ void GenCertDialog::genPerson() } //generate a new gpg key std::string err_string; - ui.no_gpg_key_label->setText(tr("Generating new node key, please be patient: this process needs generating large prime numbers, and can take some minutes on slow computers. \n\nFill in your password when asked, to sign your new key.")); - ui.no_gpg_key_label->show(); - ui.reuse_existing_node_CB->hide(); + //_key_label->setText(tr("Generating new node key, please be patient: this process needs generating large prime numbers, and can take some minutes on slow computers. \n\nFill in your password when asked, to sign your new key.")); + //ui.no_gpg_key_label->show(); + //ui.reuse_existing_node_CB->hide(); ui.name_label->hide(); ui.name_input->hide(); ui.nickname_label->hide(); @@ -514,9 +522,9 @@ void GenCertDialog::genPerson() ui.node_input->hide(); ui.genButton->hide(); ui.importIdentity_PB->hide(); - ui.genprofileinfo_label->hide(); + //ui.genprofileinfo_label->hide(); ui.nodeType_CB->hide(); - ui.adv_checkbox->hide(); + //ui.adv_checkbox->hide(); ui.keylength_label->hide(); ui.keylength_comboBox->hide(); diff --git a/retroshare-gui/src/gui/GenCertDialog.ui b/retroshare-gui/src/gui/GenCertDialog.ui index 8325ffa3a..468c17693 100644 --- a/retroshare-gui/src/gui/GenCertDialog.ui +++ b/retroshare-gui/src/gui/GenCertDialog.ui @@ -6,8 +6,8 @@ 0 0 - 724 - 667 + 533 + 544 @@ -54,7 +54,10 @@ - :/images/logo/logo_splash.png + :/images/logo/logo_spash2.png + + + false Qt::AlignCenter @@ -77,22 +80,13 @@ - - - - 16777215 - 32 - - - - <html><head/><body><p>Use this if you need to import an existing profile, if you want to generate a new node with an already existing key, or if you want to create a TOR/I2P hidden node.</p></body></html> - + - Advanced options + Options - :/icons/settings/general.svg:/icons/settings/general.svg + :/icons/svg/options.svg:/icons/svg/options.svg @@ -100,667 +94,481 @@ 24 - + false + + true + - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 178 - - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 178 - - - - - - - - - 255 - 255 - 178 - - - - - - - 255 - 255 - 178 - - - - - - - - true + + + - QFrame::Box + QFrame::StyledPanel - - You can create a new profile with this form. -Alternatively you can use an existing profile. Just uncheck "Create a new profile" - - - true + + QFrame::Raised + + + + + + + + + + + + + + PGP key length + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + <html><head/><body><p>Put a strong password here. This password protects your private node key!</p></body></html> + + + + + + 1024 + + + QLineEdit::Password + + + + + + + This password is for PGP + + + Password + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + + + + This password is for PGP + + + Password (check) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Please move your mouse around in order to collect as much randomness as possible. A minimum of 20% is needed to create your node keys.</p></body></html> + + + 24 + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + + Standard node + + + + + TOR/I2P Hidden node + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + <html><head/><body><p>Your node name designates the Retroshare instance that</p><p>will run on this computer.</p></body></html> + + + 64 + + + + + + + Node name + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 32 + + + + <html><head/><body><p>The profile name identifies you over the network.</p><p>It is used by your friends to accept connections from you.</p><p>You can create multiple Retroshare nodes with the</p><p>same profile on different computers.</p><p><br/></p></body></html> + + + + + + 64 + + + + + + + + 0 + 0 + + + + Your profile is associated with a PGP key pair. RetroShare currently ignores DSA keys. + + + + + + + + + + + 0 + 0 + + + + Export this profle + + + + + + + + 0 + 0 + + + + Import profile + + + + + + + + + + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Put a strong password here. This password protects your private node key!</p></body></html> + + + + + + 1024 + + + QLineEdit::Password + + + + + + + Profile name + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Randomness + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Node type + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + hidden address + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 6 + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 32 + + + + <html><head/><body><p>This should be a Tor Onion address of the form: xa76giaf6ifda7ri63i263.onion <br/>or an I2P address in the form: [52 characters].b32.i2p </p><p>In order to get one, you must configure either Tor or I2P to create a new hidden service / server tunnel. </p><p>You can also leave this blank now, but your node will only work if you correctly set the Tor/I2P service address in Options-&gt;Network-&gt;Hidden Service configuration panel.</p></body></html> + + + 64 + + + + + + + Port + + + + + + + + 0 + 0 + + + + <html><head/><body><p>This is your connection port.</p><p>Any value between 1024 and 65535 </p><p>should be ok. You can change it later.</p></body></html> + + + 1 + + + 65535 + + + 7812 + + + + + + + + + + + + Chat identity + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Identities are used when you write in chat rooms, forums and channel comments. </p><p>They also receive/send email over the Retroshare network. You can create</p><p>a signed identity now, or do it later on when you get to need it.</p></body></html> + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 12 + + + + + + + Go! + + + + 16 + 16 + + + + + + + + + + + + + + - - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 178 - - - - - - - - - 255 - 255 - 255 - - - - - - - 255 - 255 - 178 - - - - - - - - - 255 - 255 - 178 - - - - - - - 255 - 255 - 178 - - - - - - - - true - - - QFrame::Box - - - You can create and run Retroshare nodes on different computers using the same profile. To do so just export the selected profile, import it on the other computer and create a new node with it. - - - true - - - - - - - It looks like no profile (PGP keys) exists. Please fill in the form below to create one, or import an existing profile. - - - true - - - - - - - No node exists for this profile. - - - true - - - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - <html><head/><body><p>Put a strong password here. This password protects your private node key!</p></body></html> - - - - - - 1024 - - - QLineEdit::Password - - - - - - - This password is for PGP - - - Password - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - - - - This password is for PGP - - - Password (check) - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Please move your mouse around in order to collect as much randomness as possible. A minimum of 20% is needed to create your node keys.</p></body></html> - - - 24 - - - - - - - - - - - - - - - - - - - - - - 0 - 0 - - - - - Standard node - - - - - TOR/I2P Hidden node - - - - - - - - PGP key length - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - <html><head/><body><p>Your node name designates the Retroshare instance that</p><p>will run on this computer.</p></body></html> - - - 64 - - - - - - - Node name - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 32 - - - - <html><head/><body><p>The profile name identifies you over the network.</p><p>It is used by your friends to accept connections from you.</p><p>You can create multiple Retroshare nodes with the</p><p>same profile on different computers.</p><p><br/></p></body></html> - - - - - - 64 - - - - - - - - 0 - 0 - - - - Your profile is associated with a PGP key pair. RetroShare currently ignores DSA keys. - - - - - - - - 0 - 0 - - - - Export this profle - - - - - - - - 0 - 0 - - - - Import profile - - - - - - - - 0 - 0 - - - - Re-use an existing profile - - - - - - - - - - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Put a strong password here. This password protects your private node key!</p></body></html> - - - - - - 1024 - - - QLineEdit::Password - - - - - - - Profile name - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Randomness - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Node type - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - hidden address - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - 6 - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 32 - - - - <html><head/><body><p>This should be a Tor Onion address of the form: xa76giaf6ifda7ri63i263.onion <br/>or an I2P address in the form: [52 characters].b32.i2p </p><p>In order to get one, you must configure either Tor or I2P to create a new hidden service / server tunnel. </p><p>You can also leave this blank now, but your node will only work if you correctly set the Tor/I2P service address in Options-&gt;Network-&gt;Hidden Service configuration panel.</p></body></html> - - - 64 - - - - - - - Port - - - - - - - - 0 - 0 - - - - <html><head/><body><p>This is your connection port.</p><p>Any value between 1024 and 65535 </p><p>should be ok. You can change it later.</p></body></html> - - - 1 - - - 65535 - - - 7812 - - - - - - - - - - - - Chat identity - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Identities are used when you write in chat rooms, forums and channel comments. </p><p>They also receive/send email over the Retroshare network. You can create</p><p>a signed identity now, or do it later on when you get to need it.</p></body></html> - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - - - Go! - - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - @@ -778,27 +586,33 @@ Alternatively you can use an existing profile. Just uncheck "Create a new p + + + true + + + Advanced options + + + + + true + + + Use existing node + + - - - StyledLabel - QLabel -

gui/common/StyledLabel.h
- - name_input node_input password_input password_input_2 - adv_checkbox keylength_comboBox exportIdentity_PB - reuse_existing_node_CB genPGPuser hiddenaddr_input hiddenport_spinBox - genButton importIdentity_PB diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 25db8896d..755dab9c9 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -55,10 +55,11 @@ *****/ // Data Requests. -#define IDDIALOG_IDLIST 1 -#define IDDIALOG_IDDETAILS 2 -#define IDDIALOG_REPLIST 3 -#define IDDIALOG_REFRESH 4 +#define IDDIALOG_IDLIST 1 +#define IDDIALOG_IDDETAILS 2 +#define IDDIALOG_REPLIST 3 +#define IDDIALOG_REFRESH 4 +#define IDDIALOG_SERIALIZED_GROUP 5 #define CIRCLEGROUP_CIRCLE_COL_GROUPNAME 0 #define CIRCLEGROUP_CIRCLE_COL_GROUPID 1 @@ -814,7 +815,7 @@ void IdDialog::loadCircleGroupData(const uint32_t& token) #ifdef ID_DEBUG std::cerr << "Loading circle info" << std::endl; #endif - + std::vector circle_grp_v ; rsGxsCircles->getGroupData(token, circle_grp_v); @@ -1207,6 +1208,7 @@ void IdDialog::CircleListCustomPopupMenu( QPoint ) contextMnu.exec(QCursor::pos()); } +#ifdef SUSPENDED static void set_item_background(QTreeWidgetItem *item, uint32_t type) { QBrush brush; @@ -1247,7 +1249,6 @@ static void update_children_background(QTreeWidgetItem *item, uint32_t type) } } -#ifdef SUSPENDED static void set_tree_background(QTreeWidget *tree, uint32_t type) { std::cerr << "CirclesDialog set_tree_background()"; @@ -1385,6 +1386,8 @@ void IdDialog::updateSelection() } } + + void IdDialog::requestIdList() { //Disable by default, will be enable by insertIdDetails() @@ -1990,7 +1993,7 @@ QString IdDialog::createUsageString(const RsIdentityUsage& u) const return tr("Membership verification in circle %1.").arg(QString::fromStdString(u.mGrpId.toStdString())); } -#warning TODO! Add the different strings and translations here. +#warning TODO! csoler 2017-01-03: Add the different strings and translations here. default: return QString("Undone yet"); } @@ -2174,6 +2177,45 @@ void IdDialog::insertRepList(uint32_t token) mStateHelper->setActive(IDDIALOG_REPLIST, true); } +void IdDialog::handleSerializedGroupData(uint32_t token) +{ + std::map serialized_group_map ; + + rsIdentity->getGroupSerializedData(token, serialized_group_map); + + if(serialized_group_map.size() < 1) + { + std::cerr << "(EE) Cannot get radix data " << std::endl; + return; + } + if(serialized_group_map.size() > 1) + { + std::cerr << "(EE) Too many results for serialized data" << std::endl; + return; + } + + RsGxsId gxs_id = serialized_group_map.begin()->first ; + std::string radix = serialized_group_map.begin()->second ; + + RsIdentityDetails details ; + + if(!rsIdentity->getIdDetails(gxs_id,details)) + { + std::cerr << "(EE) Cannot get id details for key " << gxs_id << std::endl; + return; + } + + QList urls ; + + RetroShareLink link ; + link.createIdentity(gxs_id,QString::fromUtf8(details.mNickname.c_str()),QString::fromStdString(radix)) ; + urls.push_back(link); + + RSLinkClipboard::copyLinks(urls) ; + + QMessageBox::information(NULL,tr("information"),tr("This identity link was copied to your clipboard. Paste it in a mail, or a message to transmit the identity to someone.")) ; +} + void IdDialog::loadRequest(const TokenQueue * queue, const TokenRequest &req) { #ifdef ID_DEBUG @@ -2197,6 +2239,10 @@ void IdDialog::loadRequest(const TokenQueue * queue, const TokenRequest &req) insertRepList(req.mToken); break; + case IDDIALOG_SERIALIZED_GROUP: + handleSerializedGroupData(req.mToken); + break; + case IDDIALOG_REFRESH: // replaced by RsGxsUpdateBroadcastPage // updateDisplay(true); @@ -2240,165 +2286,211 @@ void IdDialog::loadRequest(const TokenQueue * queue, const TokenRequest &req) void IdDialog::IdListCustomPopupMenu( QPoint ) { - QMenu *contextMenu = new QMenu(this); + QMenu *contextMenu = new QMenu(this); - std::list own_identities ; - rsIdentity->getOwnIds(own_identities) ; + std::list own_identities ; + rsIdentity->getOwnIds(own_identities) ; - // make some stats about what's selected. If the same value is used for all selected items, it can be switched. + // make some stats about what's selected. If the same value is used for all selected items, it can be switched. - QList selected_items = ui->idTreeWidget->selectedItems(); + QList selected_items = ui->idTreeWidget->selectedItems(); - bool root_node_present = false ; - bool one_item_owned_by_you = false ; - uint32_t n_positive_reputations = 0 ; - uint32_t n_negative_reputations = 0 ; - uint32_t n_neutral_reputations = 0 ; - uint32_t n_is_a_contact = 0 ; - uint32_t n_is_not_a_contact = 0 ; - uint32_t n_selected_items =0 ; + bool root_node_present = false ; + bool one_item_owned_by_you = false ; + uint32_t n_positive_reputations = 0 ; + uint32_t n_negative_reputations = 0 ; + uint32_t n_neutral_reputations = 0 ; + uint32_t n_is_a_contact = 0 ; + uint32_t n_is_not_a_contact = 0 ; + uint32_t n_selected_items =0 ; - for(QList::const_iterator it(selected_items.begin());it!=selected_items.end();++it) - { - if(*it == allItem || *it == contactsItem || *it == ownItem) - { - root_node_present = true ; - continue ; - } - - uint32_t item_flags = (*it)->data(RSID_COL_KEYID,Qt::UserRole).toUInt() ; - - if(item_flags & RSID_FILTER_OWNED_BY_YOU) - one_item_owned_by_you = true ; - -#ifdef ID_DEBUG - std::cerr << " item flags = " << item_flags << std::endl; -#endif - RsGxsId keyId((*it)->text(RSID_COL_KEYID).toStdString()); - - RsIdentityDetails det ; - rsIdentity->getIdDetails(keyId,det) ; - - switch(det.mReputation.mOwnOpinion) - { - case RsReputations::OPINION_NEGATIVE: ++n_negative_reputations ; - break ; - - case RsReputations::OPINION_POSITIVE: ++n_positive_reputations ; - break ; - - case RsReputations::OPINION_NEUTRAL: ++n_neutral_reputations ; - break ; - } - - ++n_selected_items ; - - if(rsIdentity->isARegularContact(keyId)) - ++n_is_a_contact ; - else - ++n_is_not_a_contact ; - } - - if(!root_node_present) // don't show menu if some of the root nodes are present + for(QList::const_iterator it(selected_items.begin());it!=selected_items.end();++it) + { + if(*it == allItem || *it == contactsItem || *it == ownItem) { - - if(!one_item_owned_by_you) - { - QWidget *widget = new QWidget(contextMenu); - widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); - - // create menu header - QHBoxLayout *hbox = new QHBoxLayout(widget); - hbox->setMargin(0); - hbox->setSpacing(6); - - QLabel *iconLabel = new QLabel(widget); - QPixmap pix = QPixmap(":/images/user/friends24.png").scaledToHeight(QFontMetricsF(iconLabel->font()).height()*1.5); - iconLabel->setPixmap(pix); - iconLabel->setMaximumSize(iconLabel->frameSize().height() + pix.height(), pix.width()); - hbox->addWidget(iconLabel); - - QLabel *textLabel = new QLabel("" + ui->titleBarLabel->text() + "", widget); - hbox->addWidget(textLabel); - - QSpacerItem *spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); - hbox->addItem(spacerItem); - - widget->setLayout(hbox); - - QWidgetAction *widgetAction = new QWidgetAction(this); - widgetAction->setDefaultWidget(widget); - contextMenu->addAction(widgetAction); - - if(n_selected_items == 1) // if only one item is selected, allow to chat with this item - { - if(own_identities.size() <= 1) - { - QAction *action = contextMenu->addAction(QIcon(":/images/chat_24.png"), tr("Chat with this person"), this, SLOT(chatIdentity())); - - if(own_identities.empty()) - action->setEnabled(false) ; - else - action->setData(QString::fromStdString((own_identities.front()).toStdString())) ; - } - else - { - QMenu *mnu = contextMenu->addMenu(QIcon(":/images/chat_24.png"),tr("Chat with this person as...")) ; - - for(std::list::const_iterator it=own_identities.begin();it!=own_identities.end();++it) - { - RsIdentityDetails idd ; - rsIdentity->getIdDetails(*it,idd) ; - - QPixmap pixmap ; - - if(idd.mAvatar.mSize == 0 || !pixmap.loadFromData(idd.mAvatar.mData, idd.mAvatar.mSize, "PNG")) - pixmap = QPixmap::fromImage(GxsIdDetails::makeDefaultIcon(*it)) ; - - QAction *action = mnu->addAction(QIcon(pixmap), QString("%1 (%2)").arg(QString::fromUtf8(idd.mNickname.c_str()), QString::fromStdString((*it).toStdString())), this, SLOT(chatIdentity())); - action->setData(QString::fromStdString((*it).toStdString())) ; - } - } - } - - // always allow to send messages - contextMenu->addAction(QIcon(":/images/mail_new.png"), tr("Send message"), this, SLOT(sendMsg())); - - contextMenu->addSeparator(); - - if(n_is_a_contact == 0) - contextMenu->addAction(QIcon(), tr("Add to Contacts"), this, SLOT(addtoContacts())); - - if(n_is_not_a_contact == 0) - contextMenu->addAction(QIcon(":/images/cancel.png"), tr("Remove from Contacts"), this, SLOT(removefromContacts())); - - contextMenu->addSeparator(); - - if(n_positive_reputations == 0) // only unban when all items are banned - contextMenu->addAction(QIcon(":/icons/png/thumbs-up.png"), tr("Set positive opinion"), this, SLOT(positivePerson())); - - if(n_neutral_reputations == 0) // only unban when all items are banned - contextMenu->addAction(QIcon(":/icons/png/thumbs-neutral.png"), tr("Set neutral opinion"), this, SLOT(neutralPerson())); - - if(n_negative_reputations == 0) - contextMenu->addAction(QIcon(":/icons/png/thumbs-down.png"), tr("Set negative opinion"), this, SLOT(negativePerson())); - } - - if(one_item_owned_by_you && n_selected_items==1) - { - contextMenu->addSeparator(); - - contextMenu->addAction(ui->editIdentity); - contextMenu->addAction(ui->removeIdentity); - } - + root_node_present = true ; + continue ; } - contextMenu = ui->idTreeWidget->createStandardContextMenu(contextMenu); + uint32_t item_flags = (*it)->data(RSID_COL_KEYID,Qt::UserRole).toUInt() ; - contextMenu->exec(QCursor::pos()); - delete contextMenu; + if(item_flags & RSID_FILTER_OWNED_BY_YOU) + one_item_owned_by_you = true ; + +#ifdef ID_DEBUG + std::cerr << " item flags = " << item_flags << std::endl; +#endif + RsGxsId keyId((*it)->text(RSID_COL_KEYID).toStdString()); + + RsIdentityDetails det ; + rsIdentity->getIdDetails(keyId,det) ; + + switch(det.mReputation.mOwnOpinion) + { + case RsReputations::OPINION_NEGATIVE: ++n_negative_reputations ; + break ; + + case RsReputations::OPINION_POSITIVE: ++n_positive_reputations ; + break ; + + case RsReputations::OPINION_NEUTRAL: ++n_neutral_reputations ; + break ; + } + + ++n_selected_items ; + + if(rsIdentity->isARegularContact(keyId)) + ++n_is_a_contact ; + else + ++n_is_not_a_contact ; + } + + if(!root_node_present) // don't show menu if some of the root nodes are present + { + + if(!one_item_owned_by_you) + { + QWidget *widget = new QWidget(contextMenu); + widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); + + // create menu header + QHBoxLayout *hbox = new QHBoxLayout(widget); + hbox->setMargin(0); + hbox->setSpacing(6); + + QLabel *iconLabel = new QLabel(widget); + QPixmap pix = QPixmap(":/images/user/friends24.png").scaledToHeight(QFontMetricsF(iconLabel->font()).height()*1.5); + iconLabel->setPixmap(pix); + iconLabel->setMaximumSize(iconLabel->frameSize().height() + pix.height(), pix.width()); + hbox->addWidget(iconLabel); + + QLabel *textLabel = new QLabel("" + ui->titleBarLabel->text() + "", widget); + hbox->addWidget(textLabel); + + QSpacerItem *spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + hbox->addItem(spacerItem); + + widget->setLayout(hbox); + + QWidgetAction *widgetAction = new QWidgetAction(this); + widgetAction->setDefaultWidget(widget); + contextMenu->addAction(widgetAction); + + if(n_selected_items == 1) // if only one item is selected, allow to chat with this item + { + if(own_identities.size() <= 1) + { + QAction *action = contextMenu->addAction(QIcon(":/images/chat_24.png"), tr("Chat with this person"), this, SLOT(chatIdentity())); + + if(own_identities.empty()) + action->setEnabled(false) ; + else + action->setData(QString::fromStdString((own_identities.front()).toStdString())) ; + } + else + { + QMenu *mnu = contextMenu->addMenu(QIcon(":/images/chat_24.png"),tr("Chat with this person as...")) ; + + for(std::list::const_iterator it=own_identities.begin();it!=own_identities.end();++it) + { + RsIdentityDetails idd ; + rsIdentity->getIdDetails(*it,idd) ; + + QPixmap pixmap ; + + if(idd.mAvatar.mSize == 0 || !pixmap.loadFromData(idd.mAvatar.mData, idd.mAvatar.mSize, "PNG")) + pixmap = QPixmap::fromImage(GxsIdDetails::makeDefaultIcon(*it)) ; + + QAction *action = mnu->addAction(QIcon(pixmap), QString("%1 (%2)").arg(QString::fromUtf8(idd.mNickname.c_str()), QString::fromStdString((*it).toStdString())), this, SLOT(chatIdentity())); + action->setData(QString::fromStdString((*it).toStdString())) ; + } + } + } + + if (n_selected_items==1) + contextMenu->addAction(QIcon(":/images/chat_24.png"),tr("Copy identity to clipboard"),this,SLOT(copyRetroshareLink())) ; + + // always allow to send messages + contextMenu->addAction(QIcon(":/images/mail_new.png"), tr("Send message"), this, SLOT(sendMsg())); + + contextMenu->addSeparator(); + + if(n_is_a_contact == 0) + contextMenu->addAction(QIcon(), tr("Add to Contacts"), this, SLOT(addtoContacts())); + + if(n_is_not_a_contact == 0) + contextMenu->addAction(QIcon(":/images/cancel.png"), tr("Remove from Contacts"), this, SLOT(removefromContacts())); + + contextMenu->addSeparator(); + + if(n_positive_reputations == 0) // only unban when all items are banned + contextMenu->addAction(QIcon(":/icons/png/thumbs-up.png"), tr("Set positive opinion"), this, SLOT(positivePerson())); + + if(n_neutral_reputations == 0) // only unban when all items are banned + contextMenu->addAction(QIcon(":/icons/png/thumbs-neutral.png"), tr("Set neutral opinion"), this, SLOT(neutralPerson())); + + if(n_negative_reputations == 0) + contextMenu->addAction(QIcon(":/icons/png/thumbs-down.png"), tr("Set negative opinion"), this, SLOT(negativePerson())); + } + + if(one_item_owned_by_you && n_selected_items==1) + { + contextMenu->addSeparator(); + + contextMenu->addAction(QIcon(":/images/chat_24.png"),tr("Copy identity to clipboard"),this,SLOT(copyRetroshareLink())) ; + contextMenu->addAction(ui->editIdentity); + contextMenu->addAction(ui->removeIdentity); + } + + } + + contextMenu = ui->idTreeWidget->createStandardContextMenu(contextMenu); + + contextMenu->exec(QCursor::pos()); + delete contextMenu; +} + +void IdDialog::copyRetroshareLink() +{ + QTreeWidgetItem *item = ui->idTreeWidget->currentItem(); + + if (!item) + { + std::cerr << "IdDialog::editIdentity() Invalid item"; + std::cerr << std::endl; + return; + } + + RsGxsId gxs_id(item->text(RSID_COL_KEYID).toStdString()); + + if(gxs_id.isNull()) + { + std::cerr << "Null GXS id. Something went wrong." << std::endl; + return ; + } + + RsIdentityDetails details ; + + if(! rsIdentity->getIdDetails(gxs_id,details)) + return ; + + if (!mIdQueue) + return; + + mStateHelper->setLoading(IDDIALOG_SERIALIZED_GROUP, true); + + mIdQueue->cancelActiveRequestTokens(IDDIALOG_SERIALIZED_GROUP); + + std::list ids ; + ids.push_back(RsGxsGroupId(gxs_id)) ; + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_SERIALIZED_DATA; + + uint32_t token; + + mIdQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids, IDDIALOG_SERIALIZED_GROUP); } void IdDialog::chatIdentity() diff --git a/retroshare-gui/src/gui/Identity/IdDialog.h b/retroshare-gui/src/gui/Identity/IdDialog.h index a44d83677..1eaae935d 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.h +++ b/retroshare-gui/src/gui/Identity/IdDialog.h @@ -93,6 +93,7 @@ private slots: void editIdentity(); void chatIdentity(); void sendMsg(); + void copyRetroshareLink(); void on_closeInfoFrameButton_clicked(); void updateSelection(); @@ -132,6 +133,7 @@ private: void requestRepList(); void insertRepList(uint32_t token); + void handleSerializedGroupData(uint32_t token); void requestIdEdit(std::string &id); void showIdEdit(uint32_t token); diff --git a/retroshare-gui/src/gui/Identity/IdDialog.ui b/retroshare-gui/src/gui/Identity/IdDialog.ui index 016ff28e1..1c52802ef 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.ui +++ b/retroshare-gui/src/gui/Identity/IdDialog.ui @@ -287,7 +287,7 @@ 692 - + @@ -296,12 +296,12 @@ QFrame::Raised - + 12 - + @@ -397,7 +397,7 @@ QFrame::Box - + 6 @@ -514,7 +514,7 @@ border-image: url(:/images/closepressed.png) Identity info - + @@ -526,7 +526,7 @@ border-image: url(:/images/closepressed.png) - + Your opinion: @@ -540,7 +540,7 @@ border-image: url(:/images/closepressed.png) - + Qt::Horizontal @@ -728,7 +728,7 @@ p, li { white-space: pre-wrap; } - + @@ -774,12 +774,12 @@ p, li { white-space: pre-wrap; } - + 6 - + 34 @@ -813,14 +813,14 @@ p, li { white-space: pre-wrap; } - + Qt::Vertical - + 34 @@ -856,7 +856,7 @@ p, li { white-space: pre-wrap; } - + Qt::Vertical @@ -874,11 +874,11 @@ p, li { white-space: pre-wrap; } - + Usage statistics - + @@ -886,7 +886,7 @@ p, li { white-space: pre-wrap; } - + Qt::Vertical @@ -900,10 +900,8 @@ p, li { white-space: pre-wrap; } detailsGroupBox - detailsGroupBox - groupBox + usageStatisticsGBox headerFramePerson - verticalSpacer_2 diff --git a/retroshare-gui/src/gui/MainWindow.cpp b/retroshare-gui/src/gui/MainWindow.cpp index 4fecfa620..af2e10574 100644 --- a/retroshare-gui/src/gui/MainWindow.cpp +++ b/retroshare-gui/src/gui/MainWindow.cpp @@ -676,7 +676,8 @@ void MainWindow::updateTrayCombine() } } - notifyMenu->menuAction()->setVisible(visible); + if (notifyMenu) + notifyMenu->menuAction()->setVisible(visible); // update tray icon updateFriends(); @@ -1207,7 +1208,7 @@ void MainWindow::showHelpDialog(const QString &topic) void MainWindow::retranslateUi() { - retranslateUi(); + //retranslateUi(); foreach (MainPage *page, ui->stackPages->pages()) { page->retranslateUi(); } diff --git a/retroshare-gui/src/gui/People/CircleWidget.cpp b/retroshare-gui/src/gui/People/CircleWidget.cpp index 3a192f97a..b36a3fa56 100644 --- a/retroshare-gui/src/gui/People/CircleWidget.cpp +++ b/retroshare-gui/src/gui/People/CircleWidget.cpp @@ -96,7 +96,7 @@ void CircleWidget::updateData(const RsGroupMetaData& gxs_group_info } } -QSize CircleWidget::sizeHint() +QSize CircleWidget::sizeHint() const { QSize size; size.setHeight(ui->graphicsView->size().height() + ui->label->size().height()); diff --git a/retroshare-gui/src/gui/People/CircleWidget.h b/retroshare-gui/src/gui/People/CircleWidget.h index 08b6ad6dc..75d6899ba 100644 --- a/retroshare-gui/src/gui/People/CircleWidget.h +++ b/retroshare-gui/src/gui/People/CircleWidget.h @@ -24,7 +24,7 @@ public: , const RsGxsCircleDetails& details); //Start QWidget Properties - QSize sizeHint(); + QSize sizeHint() const; //Start FlowLayoutItem Properties virtual const QPixmap getImage(); virtual const QPixmap getDragImage(); diff --git a/retroshare-gui/src/gui/People/IdentityWidget.cpp b/retroshare-gui/src/gui/People/IdentityWidget.cpp index 902a4dc18..0fcfbc127 100644 --- a/retroshare-gui/src/gui/People/IdentityWidget.cpp +++ b/retroshare-gui/src/gui/People/IdentityWidget.cpp @@ -148,7 +148,7 @@ void IdentityWidget::updateData(const RsGxsIdGroup &gxs_group_info, const RsPeer updateData(pgp_details); } -QSize IdentityWidget::sizeHint() +QSize IdentityWidget::sizeHint() const { QSize size; size.setHeight(ui->graphicsView->size().height() + ui->labelName->size().height()); diff --git a/retroshare-gui/src/gui/People/IdentityWidget.h b/retroshare-gui/src/gui/People/IdentityWidget.h index c9ade98e3..7f5dcd97f 100644 --- a/retroshare-gui/src/gui/People/IdentityWidget.h +++ b/retroshare-gui/src/gui/People/IdentityWidget.h @@ -26,7 +26,7 @@ public: , const RsPeerDetails& pgp_details); //Start QWidget Properties - QSize sizeHint(); + QSize sizeHint() const; //Start FlowLayoutItem Properties virtual const QPixmap getImage(); virtual const QPixmap getDragImage(); diff --git a/retroshare-gui/src/gui/People/PeopleDialog.cpp b/retroshare-gui/src/gui/People/PeopleDialog.cpp index 5098da953..bdf247a4f 100644 --- a/retroshare-gui/src/gui/People/PeopleDialog.cpp +++ b/retroshare-gui/src/gui/People/PeopleDialog.cpp @@ -901,7 +901,7 @@ void PeopleDialog::pf_dropEventOccursExt(QDropEvent *event) QWidget *wid = qobject_cast(event->source());//QT5 return QObject - FlowLayout *layout; + FlowLayout *layout = NULL; if (wid) layout = qobject_cast(wid->layout()); if (layout) { @@ -991,7 +991,7 @@ void PeopleDialog::pf_dropEventOccursInt(QDropEvent *event) QWidget *wid = qobject_cast(event->source());//QT5 return QObject - FlowLayout *layout; + FlowLayout *layout = NULL; if (wid) layout = qobject_cast(wid->layout()); if (layout) { diff --git a/retroshare-gui/src/gui/RetroShareLink.cpp b/retroshare-gui/src/gui/RetroShareLink.cpp index 957b61f7f..28a2d09c6 100644 --- a/retroshare-gui/src/gui/RetroShareLink.cpp +++ b/retroshare-gui/src/gui/RetroShareLink.cpp @@ -67,7 +67,8 @@ #define HOST_SEARCH "search" #define HOST_CERTIFICATE "certificate" #define HOST_PUBLIC_MSG "public_msg" -#define HOST_REGEXP "file|extra|person|forum|channel|posted|search|message|certificate|private_chat|public_msg" +#define HOST_IDENTITY "identity" +#define HOST_REGEXP "file|extra|person|forum|channel|posted|search|message|certificate|private_chat|public_msg|identity" #define FILE_NAME "name" #define FILE_SIZE "size" @@ -89,6 +90,9 @@ #define POSTED_ID "id" #define POSTED_MSGID "msgid" +#define IDENTITY_NAME "name" +#define IDENTITY_ID "gxsid" +#define IDENTITY_GROUP "groupdata" #define MESSAGE_ID "id" #define MESSAGE_SUBJECT "subject" @@ -303,6 +307,21 @@ void RetroShareLink::fromUrl(const QUrl& url) return; } + if(url.host() == HOST_IDENTITY) { + _type = TYPE_IDENTITY ; + QString name = decodedQueryItemValue(urlQuery, IDENTITY_NAME) ; + QString radix= decodedQueryItemValue(urlQuery, IDENTITY_GROUP) ; + QString gxsid= urlQuery.queryItemValue(IDENTITY_ID) ; + + RsGxsId id(gxsid.toStdString()) ; + + if(!id.isNull()) + createIdentity(id,name,radix) ; + else + std::cerr << "(EE) identity link is not valid." << std::endl; + return ; + } + if (url.host() == HOST_MESSAGE) { _type = TYPE_MESSAGE; std::string id = urlQuery.queryItemValue(MESSAGE_ID).toStdString(); @@ -312,7 +331,7 @@ void RetroShareLink::fromUrl(const QUrl& url) if (url.host() == HOST_CERTIFICATE) { _type = TYPE_CERTIFICATE; - _radix = urlQuery.queryItemValue(CERTIFICATE_RADIX); + _radix = decodedQueryItemValue(urlQuery, CERTIFICATE_RADIX); #ifdef DEBUG_RSLINK std::cerr << "Got a certificate link!!" << std::endl; @@ -333,6 +352,21 @@ RetroShareLink::RetroShareLink() clear(); } +bool RetroShareLink::createIdentity(const RsGxsId& id, const QString& name, const QString& radix_data) +{ + clear(); + + _name = name; + _hash = QString::fromStdString(id.toStdString()); + _radix_group_data = radix_data ; + + _type = TYPE_IDENTITY; + + check(); + + return valid(); +} + bool RetroShareLink::createExtraFile(const QString& name, uint64_t size, const QString& hash,const QString& ssl_id) { clear(); @@ -534,6 +568,7 @@ void RetroShareLink::clear() _GPGid = "" ; _time_stamp = 0 ; _encrypted_chat_info = "" ; + _radix_group_data = "" ; } void RetroShareLink::check() @@ -565,6 +600,17 @@ void RetroShareLink::check() if(!checkPGPId(_GPGid)) _valid = false ; break ; + case TYPE_IDENTITY: + if(_name.isNull()) + _valid = false ; + + if(_radix_group_data.isNull()) + _valid = false ; + + if(_hash.isNull()) + _valid = false ; + break ; + case TYPE_PERSON: if(_size != 0) _valid = false; @@ -651,6 +697,9 @@ QString RetroShareLink::title() const return QObject::tr("%1 (%2, Extra - Source included)").arg(hash()).arg(misc::friendlyUnit(size())); case TYPE_FILE: return QString("%1 (%2)").arg(hash()).arg(misc::friendlyUnit(size())); + case TYPE_IDENTITY: + return _name ; + case TYPE_PERSON: return PeerDefs::rsidFromId(RsPgpId(hash().toStdString())); case TYPE_FORUM: @@ -711,6 +760,14 @@ QString RetroShareLink::toString() const break; + case TYPE_IDENTITY: + url.setScheme(RSLINK_SCHEME) ; + url.setHost(HOST_IDENTITY) ; + urlQuery.addQueryItem(IDENTITY_ID,_hash) ; + urlQuery.addQueryItem(IDENTITY_NAME,encodeItem(_name)) ; + urlQuery.addQueryItem(IDENTITY_GROUP,encodeItem(_radix_group_data)) ; + break ; + case TYPE_EXTRAFILE: url.setScheme(RSLINK_SCHEME); url.setHost(HOST_EXTRAFILE); @@ -782,9 +839,9 @@ QString RetroShareLink::toString() const case TYPE_CERTIFICATE: url.setScheme(RSLINK_SCHEME); url.setHost(HOST_CERTIFICATE) ; - urlQuery.addQueryItem(CERTIFICATE_RADIX, _radix); - urlQuery.addQueryItem(CERTIFICATE_NAME, _name); - urlQuery.addQueryItem(CERTIFICATE_LOCATION, _location); + urlQuery.addQueryItem(CERTIFICATE_RADIX, encodeItem(_radix)); + urlQuery.addQueryItem(CERTIFICATE_NAME, encodeItem(_name)); + urlQuery.addQueryItem(CERTIFICATE_LOCATION, encodeItem(_location)); break; } @@ -798,9 +855,11 @@ QString RetroShareLink::toString() const QString RetroShareLink::niceName() const { - if (type() == TYPE_PERSON) { + if (type() == TYPE_PERSON) return PeerDefs::rsid(name().toUtf8().constData(), RsPgpId(hash().toStdString())); - } + + if(type() == TYPE_IDENTITY) + return QObject::tr("Identity link (name=%1, ID=%2)").arg(_name).arg(_hash) ; if(type() == TYPE_PUBLIC_MSG) { RsPeerDetails detail; @@ -1011,6 +1070,7 @@ static void processList(const QStringList &list, const QString &textSingular, co case TYPE_POSTED: case TYPE_SEARCH: case TYPE_MESSAGE: + case TYPE_IDENTITY: case TYPE_CERTIFICATE: case TYPE_PUBLIC_MSG: case TYPE_PRIVATE_CHAT: @@ -1156,6 +1216,15 @@ static void processList(const QStringList &list, const QString &textSingular, co } break ; + case TYPE_IDENTITY: + { + if(rsIdentity->deserialiseIdentityFromMemory(link.radixGroupData().toStdString())) + QMessageBox::information(NULL,QObject::tr("Identity added to People"),QObject::tr("The identity was added to people. You can now chat with it, send messages to it, etc.")) ; + else + QMessageBox::warning(NULL,QObject::tr("Identity cannot be added to People"),QObject::tr("The identity was not added to people. Some error occured. The link is probably corrupted.")) ; + } + break; + case TYPE_FILE: case TYPE_EXTRAFILE: { diff --git a/retroshare-gui/src/gui/RetroShareLink.h b/retroshare-gui/src/gui/RetroShareLink.h index d1390d18d..241d56740 100644 --- a/retroshare-gui/src/gui/RetroShareLink.h +++ b/retroshare-gui/src/gui/RetroShareLink.h @@ -68,7 +68,8 @@ class RetroShareLink TYPE_EXTRAFILE = 0x08, TYPE_PRIVATE_CHAT = 0x09, TYPE_PUBLIC_MSG = 0x0a, - TYPE_POSTED = 0x0b + TYPE_POSTED = 0x0b, + TYPE_IDENTITY = 0x0c }; public: @@ -76,7 +77,7 @@ class RetroShareLink RetroShareLink(const QUrl& url); RetroShareLink(const QString& url); -#warning these methods should be static and return a created link +#warning csoler 2017-01-04: These methods should be static and return a created link bool createFile(const QString& name, uint64_t size, const QString& hash); bool createExtraFile(const QString& name, uint64_t size, const QString& hash, const QString& ssl_id); bool createPerson(const RsPgpId &id); @@ -85,6 +86,7 @@ class RetroShareLink bool createSearch(const QString& keywords); bool createMessage(const RsPeerId &peerId, const QString& subject); bool createMessage(const RsGxsId &peerId, const QString& subject); + bool createIdentity(const RsGxsId& gxs_id,const QString& name,const QString& radix_data) ; bool createCertificate(const RsPeerId &ssl_id) ; bool createPublicMsgInvite(time_t time_stamp,const QString& pgp_id,const QString& hash) ; bool createUnknwonSslCertificate(const RsPeerId &sslId, const RsPgpId &gpgId = RsPgpId()) ; @@ -101,12 +103,13 @@ class RetroShareLink const QString& SSLId() const { return _SSLid ; } const QString& GPGId() const { return _GPGid ; } const QString& localIPAndPort() const { return _loc_ip_port ; } - const QString& externalIPAndPort() const { return _ext_ip_port ; } - const QString& dyndns() const { return _dyndns_name ; } - const QString& location() const { return _location ; } - const QString& radix() const { return _radix ; } - time_t timeStamp() const { return _time_stamp ; } - QString title() const; + const QString& externalIPAndPort() const { return _ext_ip_port ; } + const QString& dyndns() const { return _dyndns_name ; } + const QString& location() const { return _location ; } + const QString& radix() const { return _radix ; } + time_t timeStamp() const { return _time_stamp ; } + QString title() const; + QString radixGroupData() const { return _radix_group_data ;} unsigned int subType() const { return _subType; } void setSubType(unsigned int subType) { _subType = subType; } @@ -158,12 +161,13 @@ class RetroShareLink QString _GPGBase64String ; // GPG Cert QString _GPGBase64CheckSum ; // GPG Cert QString _location ; // location - QString _ext_ip_port ; - QString _loc_ip_port ; - QString _dyndns_name ; + QString _ext_ip_port ; + QString _loc_ip_port ; + QString _dyndns_name ; QString _radix ; - QString _encrypted_chat_info ; // encrypted data string for the recipient of a chat invite - time_t _time_stamp ; // time stamp at which the link will expire. + QString _encrypted_chat_info ; // encrypted data string for the recipient of a chat invite + time_t _time_stamp ; // time stamp at which the link will expire. + QString _radix_group_data; unsigned int _subType; // for general use as sub type for _type (RSLINK_SUBTYPE_...) }; diff --git a/retroshare-gui/src/gui/chat/ChatDialog.cpp b/retroshare-gui/src/gui/chat/ChatDialog.cpp index 2ab8b8e90..9fe8220ab 100644 --- a/retroshare-gui/src/gui/chat/ChatDialog.cpp +++ b/retroshare-gui/src/gui/chat/ChatDialog.cpp @@ -63,7 +63,7 @@ void ChatDialog::closeEvent(QCloseEvent *event) emit dialogClose(this); } -void ChatDialog::init(ChatId id, const QString &title) +void ChatDialog::init(const ChatId &id, const QString &title) { mChatId = id; ChatWidget *cw = getChatWidget(); @@ -102,14 +102,14 @@ void ChatDialog::init(ChatId id, const QString &title) if (chatflags & RS_CHAT_OPEN) { if (id.isLobbyId()) { ChatLobbyDialog* cld = new ChatLobbyDialog(id.toLobbyId()); - cld->init(); + cld->init(ChatId(), ""); cd = cld; } else if(id.isDistantChatId()) { PopupDistantChatDialog* pdcd = new PopupDistantChatDialog(id.toDistantChatId()); - pdcd->init(id.toDistantChatId()); + pdcd->init(id, ""); cd = pdcd; } else diff --git a/retroshare-gui/src/gui/chat/ChatDialog.h b/retroshare-gui/src/gui/chat/ChatDialog.h index f6b4ae57e..a5c6a0bc3 100644 --- a/retroshare-gui/src/gui/chat/ChatDialog.h +++ b/retroshare-gui/src/gui/chat/ChatDialog.h @@ -84,7 +84,7 @@ protected: virtual QString getPeerName(const ChatId &sslid) const ; // can be overloaded for chat dialogs that have specific peers virtual QString getOwnName() const; - virtual void init(ChatId id, const QString &title); + virtual void init(const ChatId &id, const QString &title); virtual void addChatMsg(const ChatMessage& msg) = 0; ChatId mChatId; diff --git a/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp b/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp index 4056156bb..20352b888 100644 --- a/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp +++ b/retroshare-gui/src/gui/chat/ChatLobbyDialog.cpp @@ -304,7 +304,7 @@ void ChatLobbyDialog::showInPeopleTab() idDialog->navigate(nickname); } -void ChatLobbyDialog::init() +void ChatLobbyDialog::init(const ChatId &/*id*/, const QString &/*title*/) { ChatLobbyInfo linfo ; diff --git a/retroshare-gui/src/gui/chat/ChatLobbyDialog.h b/retroshare-gui/src/gui/chat/ChatLobbyDialog.h index 40fb44014..420524f93 100644 --- a/retroshare-gui/src/gui/chat/ChatLobbyDialog.h +++ b/retroshare-gui/src/gui/chat/ChatLobbyDialog.h @@ -71,7 +71,7 @@ protected: virtual ~ChatLobbyDialog(); void processSettings(bool load); - virtual void init(); + virtual void init(const ChatId &id, const QString &title); virtual bool canClose(); virtual void addChatMsg(const ChatMessage &msg); diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp index 2ea4ba348..37e2b589e 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp @@ -76,7 +76,7 @@ ChatWidget::ChatWidget(QWidget *parent) : int iconHeight = FMM*QFontMetricsF(font()).height() ; QSize iconSize = QSize(iconHeight,iconHeight); - QSize buttonSize = QSize(iconSize + QSize(FMM,FMM)); + QSize buttonSize = QSize(iconSize + QSize((int)FMM,(int)FMM)); newMessages = false; typing = false; @@ -258,7 +258,7 @@ void ChatWidget::addChatBarWidget(QWidget *w) { int iconHeight = FMM*QFontMetricsF(font()).height() ; QSize iconSize = QSize(iconHeight,iconHeight); - QSize buttonSize = QSize(iconSize + QSize(FMM,FMM)); + QSize buttonSize = QSize(iconSize + QSize((int)FMM,(int)FMM)); w->setFixedSize(buttonSize); ui->pluginButtonFrame->layout()->addWidget(w) ; } diff --git a/retroshare-gui/src/gui/chat/PopupChatDialog.h b/retroshare-gui/src/gui/chat/PopupChatDialog.h index 0a304b14c..49e3036b3 100644 --- a/retroshare-gui/src/gui/chat/PopupChatDialog.h +++ b/retroshare-gui/src/gui/chat/PopupChatDialog.h @@ -46,7 +46,7 @@ protected: /** Default destructor */ virtual ~PopupChatDialog(); - virtual void init(const ChatId &chat_id, const QString &title); + virtual void init(const ChatId &chat_id, const QString &title); virtual void showDialog(uint chatflags); virtual ChatWidget *getChatWidget(); virtual bool hasPeerStatus() { return true; } diff --git a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp index 4992b5ff5..dea397310 100644 --- a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp +++ b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp @@ -63,9 +63,12 @@ PopupDistantChatDialog::PopupDistantChatDialog(const DistantChatPeerId& tunnel_i updateDisplay() ; } -void PopupDistantChatDialog::init(const DistantChatPeerId &peer_id) +void PopupDistantChatDialog::init(const ChatId &chat_id, const QString &/*title*/) { - _tunnel_id = peer_id; + if (!chat_id.isDistantChatId()) + return; + + _tunnel_id = chat_id.toDistantChatId(); DistantChatPeerInfo tinfo; if(!rsMsgs->getDistantChatStatus(_tunnel_id,tinfo)) @@ -74,15 +77,15 @@ void PopupDistantChatDialog::init(const DistantChatPeerId &peer_id) RsIdentityDetails iddetails ; if(rsIdentity->getIdDetails(tinfo.to_id,iddetails)) - PopupChatDialog::init(ChatId(peer_id), QString::fromUtf8(iddetails.mNickname.c_str())) ; + PopupChatDialog::init(chat_id, QString::fromUtf8(iddetails.mNickname.c_str())) ; else - PopupChatDialog::init(ChatId(peer_id), QString::fromStdString(tinfo.to_id.toStdString())) ; + PopupChatDialog::init(chat_id, QString::fromStdString(tinfo.to_id.toStdString())) ; // Do not use setOwnId, because we don't want the user to change the GXS avatar from the chat window // it will not be transmitted. ui.ownAvatarWidget->setOwnId() ; // sets the flag - ui.ownAvatarWidget->setId(ChatId(peer_id)) ; // sets the actual Id + ui.ownAvatarWidget->setId(chat_id) ; // sets the actual Id } void PopupDistantChatDialog::updateDisplay() diff --git a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h index dfe75b9de..ff05f70c0 100644 --- a/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h +++ b/retroshare-gui/src/gui/chat/PopupDistantChatDialog.h @@ -38,7 +38,7 @@ class PopupDistantChatDialog: public PopupChatDialog /** Default destructor */ virtual ~PopupDistantChatDialog(); - virtual void init(const DistantChatPeerId& peer_id); + virtual void init(const ChatId& chat_id, const QString &title); virtual void closeEvent(QCloseEvent *e) ; virtual QString getPeerName(const ChatId &id) const ; diff --git a/retroshare-gui/src/gui/common/MimeTextEdit.cpp b/retroshare-gui/src/gui/common/MimeTextEdit.cpp index 5ff657ce3..9c0395ffb 100644 --- a/retroshare-gui/src/gui/common/MimeTextEdit.cpp +++ b/retroshare-gui/src/gui/common/MimeTextEdit.cpp @@ -77,6 +77,7 @@ void MimeTextEdit::insertFromMimeData(const QMimeData* source) } } #endif + if (source == NULL) return; //insert retroshare links QList links; diff --git a/retroshare-gui/src/gui/common/RSGraphWidget.cpp b/retroshare-gui/src/gui/common/RSGraphWidget.cpp index 90cf069c2..b7759d846 100644 --- a/retroshare-gui/src/gui/common/RSGraphWidget.cpp +++ b/retroshare-gui/src/gui/common/RSGraphWidget.cpp @@ -99,6 +99,11 @@ QString RSGraphSource::displayValue(float v) const return QString::number(v,'f',_digits) + " " + unitName() ; } +void RSGraphSource::getCumulatedValues(std::vector& vals) const +{ + for(std::map::const_iterator it = _totals.begin();it!=_totals.end();++it) + vals.push_back(it->second) ; +} void RSGraphSource::getCurrentValues(std::vector& vals) const { std::map > >::const_iterator it = _points.begin(); @@ -108,9 +113,9 @@ void RSGraphSource::getCurrentValues(std::vector& vals) const vals.push_back(QPointF( (now - it->second.back().first)/1000.0f,it->second.back().second)) ; } -QString RSGraphSource::legend(int i,float v) const +QString RSGraphSource::legend(int i,float v,bool show_value) const { - return displayName(i) + " (" + displayValue(v) + " )"; + return displayName(i) + (show_value?(" (" + displayValue(v) + ")"):""); } void RSGraphSource::getDataPoints(int index,std::vector& pts,float filter_factor) const @@ -209,11 +214,30 @@ void RSGraphSource::update() } else ++it ; + + updateTotals(); +} + +void RSGraphSource::updateTotals() +{ + // now compute totals + + _totals.clear(); + + for(std::map > >::const_iterator it(_points.begin());it!=_points.end();++it) + { + float& f = _totals[it->first] ; + + f = 0.0f ; + for(std::list >::const_iterator it2=it->second.begin();it2!=it->second.end();++it2) + f += (*it2).second ; + } } void RSGraphSource::reset() { - _points.clear() ; + _points.clear(); + _totals.clear(); } void RSGraphSource::setCollectionTimeLimit(qint64 s) { _time_limit_msecs = s ; } @@ -630,8 +654,19 @@ void RSGraphWidget::paintLegend() { //int bottom = _rec.height(); - std::vector vals ; - _source->getCurrentValues(vals) ; + std::vector vals ; + + if(_flags & RSGRAPH_FLAGS_LEGEND_CUMULATED) + _source->getCumulatedValues(vals) ; + else + { + std::vector cvals ; + _source->getCurrentValues(cvals) ; + + for(uint32_t i=0;idisplayName(i).toStdString()) == _masked_entries.end() ) { - if( _rec.width() - (vals[i].x()-0)*_time_scale < SCALE_WIDTH*fact ) - continue ; +// if( _rec.width() - (vals[i].x()-0)*_time_scale < SCALE_WIDTH*fact ) +// continue ; qreal paintStep = 4*fact+FS; qreal pos = 15*fact+j*paintStep; - QString text = _source->legend(i,vals[i].y()) ; + + QString text = _source->legend(i,vals[i]) ; QPen oldPen = _painter->pen(); _painter->setPen(QPen(getColor(i), Qt::SolidLine)); diff --git a/retroshare-gui/src/gui/common/RSGraphWidget.h b/retroshare-gui/src/gui/common/RSGraphWidget.h index 84a4ee3be..2159ba0dc 100644 --- a/retroshare-gui/src/gui/common/RSGraphWidget.h +++ b/retroshare-gui/src/gui/common/RSGraphWidget.h @@ -69,8 +69,11 @@ public: // return the vector of last values up to date virtual void getCurrentValues(std::vector& vals) const ; + // return the vector of cumulated values up to date + virtual void getCumulatedValues(std::vector& vals) const; + // returns what to display in the legend. Derive this to show additional info. - virtual QString legend(int i,float v) const ; + virtual QString legend(int i, float v, bool show_value=true) const ; // Returns the n^th interpolated value at the given time in floating point seconds backward. virtual void getDataPoints(int index, std::vector& pts, float filter_factor=0.0f) const ; @@ -95,11 +98,13 @@ protected slots: protected: virtual void getValues(std::map& values) const = 0 ;// overload this in your own class to fill in the values you want to display. + void updateTotals(); qint64 getTime() const ; // returns time in ms since RS has started // Storage of collected events. The string is any string used to represent the collected data. std::map > > _points ; + std::map _totals ; QTimer *_timer ; @@ -118,8 +123,9 @@ public: static const uint32_t RSGRAPH_FLAGS_LOG_SCALE_Y = 0x0002 ;// log scale in Y static const uint32_t RSGRAPH_FLAGS_ALWAYS_COLLECT = 0x0004 ;// keep collecting while not displayed static const uint32_t RSGRAPH_FLAGS_PAINT_STYLE_PLAIN = 0x0008 ;// use plain / line drawing style - static const uint32_t RSGRAPH_FLAGS_SHOW_LEGEND = 0x0010 ;// show legend in the graph - static const uint32_t RSGRAPH_FLAGS_PAINT_STYLE_FLAT = 0x0020 ;// do not interpolate, and draw flat colored boxes + static const uint32_t RSGRAPH_FLAGS_SHOW_LEGEND = 0x0010 ;// show legend in the graph + static const uint32_t RSGRAPH_FLAGS_PAINT_STYLE_FLAT = 0x0020 ;// do not interpolate, and draw flat colored boxes + static const uint32_t RSGRAPH_FLAGS_LEGEND_CUMULATED = 0x0040 ;// show the total in the legend rather than current values /** Bandwidth graph style. */ enum GraphStyle diff --git a/retroshare-gui/src/gui/common/UserNotify.cpp b/retroshare-gui/src/gui/common/UserNotify.cpp index 96cbf554b..6c70b3c9f 100644 --- a/retroshare-gui/src/gui/common/UserNotify.cpp +++ b/retroshare-gui/src/gui/common/UserNotify.cpp @@ -99,7 +99,7 @@ void UserNotify::initialize(QToolBar *mainToolBar, QAction *mainAction, QListWid } } mListItem = listItem; - if (mListItem && !mMainAction) { + if (mListItem && mMainAction) { mButtonText = mMainAction->text(); } } diff --git a/retroshare-gui/src/gui/common/rwindow.cpp b/retroshare-gui/src/gui/common/rwindow.cpp index 32cfba943..e86be7fa2 100644 --- a/retroshare-gui/src/gui/common/rwindow.cpp +++ b/retroshare-gui/src/gui/common/rwindow.cpp @@ -76,11 +76,20 @@ RWindow::restoreWindowState() m_bSaveStateOnClose = true; // now we save the window state on close #if QT_VERSION >= 0x040200 - QByteArray geometry = getSetting("Geometry", QByteArray()).toByteArray(); - if (geometry.isEmpty()) + QByteArray geo = getSetting("Geometry", QByteArray()).toByteArray(); + if (geo.isEmpty()) + { adjustSize(); + QRect rect = geometry(); + int h = fontMetrics().height()*40; + if (rect.height()show(); ui.label_version->show(); - ui.groupBox->show(); + //ui.groupBox->show(); ui.groupBox_4->show(); - ui.tabWidget->show(); + //ui.tabWidget->show(); //ui.rsid->hide(); //ui.label_rsid->hide(); ui.pgpfingerprint->show(); diff --git a/retroshare-gui/src/gui/connect/ConfCertDialog.ui b/retroshare-gui/src/gui/connect/ConfCertDialog.ui index 469bae218..fec736831 100644 --- a/retroshare-gui/src/gui/connect/ConfCertDialog.ui +++ b/retroshare-gui/src/gui/connect/ConfCertDialog.ui @@ -6,8 +6,8 @@ 0 0 - 722 - 651 + 1104 + 1086 @@ -69,7 +69,7 @@ - 1 + 0 @@ -85,7 +85,7 @@ - Friend info + Node info: @@ -249,6 +249,114 @@ + + + + Current address: + + + + + + + + 0 + + + 65535 + + + 7812 + + + + + + + + + + 0 + + + 65535 + + + 7812 + + + + + + + Dynamic DNS + + + + + + + + + + External Address + + + + + + + + + + Port + + + + + + + Port + + + + + + + Qt::LeftToRight + + + Local Address + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + + + + + List of known addresses: + + + + + + Qt::DefaultContextMenu + + + QAbstractItemView::MultiSelection + + + + + + @@ -264,170 +372,6 @@ - - - - :/images/kcmsystem24.png:/images/kcmsystem24.png - - - Connectivity - - - - - - 1 - - - - Peer Addresses - - - - - - Peer Address - - - - - - Qt::Vertical - - - - 20 - 47 - - - - - - - - Qt::Vertical - - - - 20 - 47 - - - - - - - - - - Qt::LeftToRight - - - Local Address - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - External Address - - - - - - - - - - Dynamic DNS - - - - - - - - - - Port - - - - - - - Port - - - - - - - 0 - - - 65535 - - - 7812 - - - - - - - 0 - - - 65535 - - - 7812 - - - - - - - - - - - - - Addresses list - - - - - - Addresses list - - - - - - - Qt::DefaultContextMenu - - - QAbstractItemView::MultiSelection - - - - - - - - - Retroshare Certificate diff --git a/retroshare-gui/src/gui/elastic/edge.cpp b/retroshare-gui/src/gui/elastic/edge.cpp index 4fec24fe7..e9e60f06b 100644 --- a/retroshare-gui/src/gui/elastic/edge.cpp +++ b/retroshare-gui/src/gui/elastic/edge.cpp @@ -46,7 +46,7 @@ #include -static const double Pi = 3.14159265358979323846264338327950288419717; +//static const double Pi = 3.14159265358979323846264338327950288419717; Edge::Edge(Node *sourceNode, Node *destNode) : arrowSize(10) diff --git a/retroshare-gui/src/gui/elastic/fft.h b/retroshare-gui/src/gui/elastic/fft.h new file mode 100644 index 000000000..0b5c48ad7 --- /dev/null +++ b/retroshare-gui/src/gui/elastic/fft.h @@ -0,0 +1,831 @@ +/****************************************************************** + + Original FFT code Credits: + Copyright Takuya OOURA, 1996-2001 + http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html + +******************************************************************/ + +/* +Fast Fourier/Cosine/Sine Transform + dimension :two + data length :power of 2 + decimation :frequency + radix :4, 2, row-column + data :inplace + table :use +functions + cdft2d: Complex Discrete Fourier Transform + rdft2d: Real Discrete Fourier Transform + ddct2d: Discrete Cosine Transform + ddst2d: Discrete Sine Transform +function prototypes + void cdft2d(int, int, int, double **, int *, double *); + void rdft2d(int, int, int, double **, int *, double *); + void ddct2d(int, int, int, double **, double **, int *, double *); + void ddst2d(int, int, int, double **, double **, int *, double *); + + +-------- Complex DFT (Discrete Fourier Transform) -------- + [definition] + + X[k1][k2] = sum_j1=0^n1-1 sum_j2=0^n2-1 x[j1][j2] * + exp(2*pi*i*j1*k1/n1) * + exp(2*pi*i*j2*k2/n2), 0<=k1 + X[k1][k2] = sum_j1=0^n1-1 sum_j2=0^n2-1 x[j1][j2] * + exp(-2*pi*i*j1*k1/n1) * + exp(-2*pi*i*j2*k2/n2), 0<=k1 + ip[0] = 0; // first time only + cdft2d(n1, 2*n2, 1, a, ip, w); + + ip[0] = 0; // first time only + cdft2d(n1, 2*n2, -1, a, ip, w); + [parameters] + n1 :data length (int) + n1 >= 1, n1 = power of 2 + 2*n2 :data length (int) + n2 >= 1, n2 = power of 2 + a[0...n1-1][0...2*n2-1] + :input/output data (double **) + input data + a[j1][2*j2] = Re(x[j1][j2]), + a[j1][2*j2+1] = Im(x[j1][j2]), + 0<=j1= 2+sqrt(n) + (n = max(n1, n2)) + ip[0],ip[1] are pointers of the cos/sin table. + w[0...*] + :cos/sin table (double *) + length of w >= max(n1/2, n2/2) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + cdft2d(n1, 2*n2, -1, a, ip, w); + is + cdft2d(n1, 2*n2, 1, a, ip, w); + for (j1 = 0; j1 <= n1 - 1; j1++) { + for (j2 = 0; j2 <= 2 * n2 - 1; j2++) { + a[j1][j2] *= 1.0 / (n1 * n2); + } + } +*/ + + +/* -------- initializing routines -------- */ + +#pragma once +#include + +class fft +{ +public: + static void makewt(int nw, int *ip, double *w) + { + int nwh, j; + double delta, x, y; + + ip[0] = nw; + ip[1] = 1; + if (nw > 2) { + nwh = nw >> 1; + delta = atan(1.0) / nwh; + w[0] = 1; + w[1] = 0; + w[nwh] = cos(delta * nwh); + w[nwh + 1] = w[nwh]; + for (j = 2; j <= nwh - 2; j += 2) { +#ifdef __APPLE__ + __sincos(delta*j,&y,&x); +#else + sincos(delta*j,&y,&x) ; +#endif + //x = cos(delta * j); + //y = sin(delta * j); + w[j] = x; + w[j + 1] = y; + w[nw - j] = y; + w[nw - j + 1] = x; + } + bitrv2(nw, ip + 2, w); + } + } + + + /* -------- child routines -------- */ + + + static void bitrv2(int n, int *ip, double *a) + { + int j, j1, k, k1, l, m, m2; + double xr, xi; + + ip[0] = 0; + l = n; + m = 1; + while ((m << 2) < l) { + l >>= 1; + for (j = 0; j <= m - 1; j++) { + ip[m + j] = ip[j] + l; + } + m <<= 1; + } + if ((m << 2) > l) { + for (k = 1; k <= m - 1; k++) { + for (j = 0; j <= k - 1; j++) { + j1 = (j << 1) + ip[k]; + k1 = (k << 1) + ip[j]; + xr = a[j1]; + xi = a[j1 + 1]; + a[j1] = a[k1]; + a[j1 + 1] = a[k1 + 1]; + a[k1] = xr; + a[k1 + 1] = xi; + } + } + } else { + m2 = m << 1; + for (k = 1; k <= m - 1; k++) { + for (j = 0; j <= k - 1; j++) { + j1 = (j << 1) + ip[k]; + k1 = (k << 1) + ip[j]; + xr = a[j1]; + xi = a[j1 + 1]; + a[j1] = a[k1]; + a[j1 + 1] = a[k1 + 1]; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 += m2; + xr = a[j1]; + xi = a[j1 + 1]; + a[j1] = a[k1]; + a[j1 + 1] = a[k1 + 1]; + a[k1] = xr; + a[k1 + 1] = xi; + } + } + } + } + + + static void bitrv2col(int n1, int n, int *ip, double **a) + { + int i, j, j1, k, k1, l, m, m2; + double xr, xi; + + ip[0] = 0; + l = n; + m = 1; + while ((m << 2) < l) { + l >>= 1; + for (j = 0; j <= m - 1; j++) { + ip[m + j] = ip[j] + l; + } + m <<= 1; + } + if ((m << 2) > l) { + for (i = 0; i <= n1 - 1; i++) { + for (k = 1; k <= m - 1; k++) { + for (j = 0; j <= k - 1; j++) { + j1 = (j << 1) + ip[k]; + k1 = (k << 1) + ip[j]; + xr = a[i][j1]; + xi = a[i][j1 + 1]; + a[i][j1] = a[i][k1]; + a[i][j1 + 1] = a[i][k1 + 1]; + a[i][k1] = xr; + a[i][k1 + 1] = xi; + } + } + } + } else { + m2 = m << 1; + for (i = 0; i <= n1 - 1; i++) { + for (k = 1; k <= m - 1; k++) { + for (j = 0; j <= k - 1; j++) { + j1 = (j << 1) + ip[k]; + k1 = (k << 1) + ip[j]; + xr = a[i][j1]; + xi = a[i][j1 + 1]; + a[i][j1] = a[i][k1]; + a[i][j1 + 1] = a[i][k1 + 1]; + a[i][k1] = xr; + a[i][k1 + 1] = xi; + j1 += m2; + k1 += m2; + xr = a[i][j1]; + xi = a[i][j1 + 1]; + a[i][j1] = a[i][k1]; + a[i][j1 + 1] = a[i][k1 + 1]; + a[i][k1] = xr; + a[i][k1 + 1] = xi; + } + } + } + } + } + + + static void bitrv2row(int n, int n2, int *ip, double **a) + { + int i, j, j1, k, k1, l, m; + double xr, xi; + + ip[0] = 0; + l = n; + m = 1; + while ((m << 1) < l) { + l >>= 1; + for (j = 0; j <= m - 1; j++) { + ip[m + j] = ip[j] + l; + } + m <<= 1; + } + if ((m << 1) > l) { + for (k = 1; k <= m - 1; k++) { + for (j = 0; j <= k - 1; j++) { + j1 = j + ip[k]; + k1 = k + ip[j]; + for (i = 0; i <= n2 - 2; i += 2) { + xr = a[j1][i]; + xi = a[j1][i + 1]; + a[j1][i] = a[k1][i]; + a[j1][i + 1] = a[k1][i + 1]; + a[k1][i] = xr; + a[k1][i + 1] = xi; + } + } + } + } else { + for (k = 1; k <= m - 1; k++) { + for (j = 0; j <= k - 1; j++) { + j1 = j + ip[k]; + k1 = k + ip[j]; + for (i = 0; i <= n2 - 2; i += 2) { + xr = a[j1][i]; + xi = a[j1][i + 1]; + a[j1][i] = a[k1][i]; + a[j1][i + 1] = a[k1][i + 1]; + a[k1][i] = xr; + a[k1][i + 1] = xi; + } + j1 += m; + k1 += m; + for (i = 0; i <= n2 - 2; i += 2) { + xr = a[j1][i]; + xi = a[j1][i + 1]; + a[j1][i] = a[k1][i]; + a[j1][i + 1] = a[k1][i + 1]; + a[k1][i] = xr; + a[k1][i + 1] = xi; + } + } + } + } + } + + + static void cftbcol(int n1, int n, double **a, double *w) + { + int i, j, j1, j2, j3, k, k1, ks, l, m; + double wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + for (i = 0; i <= n1 - 1; i++) { + l = 2; + while ((l << 1) < n) { + m = l << 2; + for (j = 0; j <= l - 2; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[i][j] + a[i][j1]; + x0i = a[i][j + 1] + a[i][j1 + 1]; + x1r = a[i][j] - a[i][j1]; + x1i = a[i][j + 1] - a[i][j1 + 1]; + x2r = a[i][j2] + a[i][j3]; + x2i = a[i][j2 + 1] + a[i][j3 + 1]; + x3r = a[i][j2] - a[i][j3]; + x3i = a[i][j2 + 1] - a[i][j3 + 1]; + a[i][j] = x0r + x2r; + a[i][j + 1] = x0i + x2i; + a[i][j2] = x0r - x2r; + a[i][j2 + 1] = x0i - x2i; + a[i][j1] = x1r - x3i; + a[i][j1 + 1] = x1i + x3r; + a[i][j3] = x1r + x3i; + a[i][j3 + 1] = x1i - x3r; + } + if (m < n) { + wk1r = w[2]; + for (j = m; j <= l + m - 2; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[i][j] + a[i][j1]; + x0i = a[i][j + 1] + a[i][j1 + 1]; + x1r = a[i][j] - a[i][j1]; + x1i = a[i][j + 1] - a[i][j1 + 1]; + x2r = a[i][j2] + a[i][j3]; + x2i = a[i][j2 + 1] + a[i][j3 + 1]; + x3r = a[i][j2] - a[i][j3]; + x3i = a[i][j2 + 1] - a[i][j3 + 1]; + a[i][j] = x0r + x2r; + a[i][j + 1] = x0i + x2i; + a[i][j2] = x2i - x0i; + a[i][j2 + 1] = x0r - x2r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[i][j1] = wk1r * (x0r - x0i); + a[i][j1 + 1] = wk1r * (x0r + x0i); + x0r = x3i + x1r; + x0i = x3r - x1i; + a[i][j3] = wk1r * (x0i - x0r); + a[i][j3 + 1] = wk1r * (x0i + x0r); + } + k1 = 1; + ks = -1; + for (k = (m << 1); k <= n - m; k += m) { + k1++; + ks = -ks; + wk1r = w[k1 << 1]; + wk1i = w[(k1 << 1) + 1]; + wk2r = ks * w[k1]; + wk2i = w[k1 + ks]; + wk3r = wk1r - 2 * wk2i * wk1i; + wk3i = 2 * wk2i * wk1r - wk1i; + for (j = k; j <= l + k - 2; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[i][j] + a[i][j1]; + x0i = a[i][j + 1] + a[i][j1 + 1]; + x1r = a[i][j] - a[i][j1]; + x1i = a[i][j + 1] - a[i][j1 + 1]; + x2r = a[i][j2] + a[i][j3]; + x2i = a[i][j2 + 1] + a[i][j3 + 1]; + x3r = a[i][j2] - a[i][j3]; + x3i = a[i][j2 + 1] - a[i][j3 + 1]; + a[i][j] = x0r + x2r; + a[i][j + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[i][j2] = wk2r * x0r - wk2i * x0i; + a[i][j2 + 1] = wk2r * x0i + wk2i * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[i][j1] = wk1r * x0r - wk1i * x0i; + a[i][j1 + 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[i][j3] = wk3r * x0r - wk3i * x0i; + a[i][j3 + 1] = wk3r * x0i + wk3i * x0r; + } + } + } + l = m; + } + if (l < n) { + for (j = 0; j <= l - 2; j += 2) { + j1 = j + l; + x0r = a[i][j] - a[i][j1]; + x0i = a[i][j + 1] - a[i][j1 + 1]; + a[i][j] += a[i][j1]; + a[i][j + 1] += a[i][j1 + 1]; + a[i][j1] = x0r; + a[i][j1 + 1] = x0i; + } + } + } + } + + + static void cftbrow(int n, int n2, double **a, double *w) + { + int i, j, j1, j2, j3, k, k1, ks, l, m; + double wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + l = 1; + while ((l << 1) < n) { + m = l << 2; + for (j = 0; j <= l - 1; j++) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + for (i = 0; i <= n2 - 2; i += 2) { + x0r = a[j][i] + a[j1][i]; + x0i = a[j][i + 1] + a[j1][i + 1]; + x1r = a[j][i] - a[j1][i]; + x1i = a[j][i + 1] - a[j1][i + 1]; + x2r = a[j2][i] + a[j3][i]; + x2i = a[j2][i + 1] + a[j3][i + 1]; + x3r = a[j2][i] - a[j3][i]; + x3i = a[j2][i + 1] - a[j3][i + 1]; + a[j][i] = x0r + x2r; + a[j][i + 1] = x0i + x2i; + a[j2][i] = x0r - x2r; + a[j2][i + 1] = x0i - x2i; + a[j1][i] = x1r - x3i; + a[j1][i + 1] = x1i + x3r; + a[j3][i] = x1r + x3i; + a[j3][i + 1] = x1i - x3r; + } + } + if (m < n) { + wk1r = w[2]; + for (j = m; j <= l + m - 1; j++) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + for (i = 0; i <= n2 - 2; i += 2) { + x0r = a[j][i] + a[j1][i]; + x0i = a[j][i + 1] + a[j1][i + 1]; + x1r = a[j][i] - a[j1][i]; + x1i = a[j][i + 1] - a[j1][i + 1]; + x2r = a[j2][i] + a[j3][i]; + x2i = a[j2][i + 1] + a[j3][i + 1]; + x3r = a[j2][i] - a[j3][i]; + x3i = a[j2][i + 1] - a[j3][i + 1]; + a[j][i] = x0r + x2r; + a[j][i + 1] = x0i + x2i; + a[j2][i] = x2i - x0i; + a[j2][i + 1] = x0r - x2r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j1][i] = wk1r * (x0r - x0i); + a[j1][i + 1] = wk1r * (x0r + x0i); + x0r = x3i + x1r; + x0i = x3r - x1i; + a[j3][i] = wk1r * (x0i - x0r); + a[j3][i + 1] = wk1r * (x0i + x0r); + } + } + k1 = 1; + ks = -1; + for (k = (m << 1); k <= n - m; k += m) { + k1++; + ks = -ks; + wk1r = w[k1 << 1]; + wk1i = w[(k1 << 1) + 1]; + wk2r = ks * w[k1]; + wk2i = w[k1 + ks]; + wk3r = wk1r - 2 * wk2i * wk1i; + wk3i = 2 * wk2i * wk1r - wk1i; + for (j = k; j <= l + k - 1; j++) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + for (i = 0; i <= n2 - 2; i += 2) { + x0r = a[j][i] + a[j1][i]; + x0i = a[j][i + 1] + a[j1][i + 1]; + x1r = a[j][i] - a[j1][i]; + x1i = a[j][i + 1] - a[j1][i + 1]; + x2r = a[j2][i] + a[j3][i]; + x2i = a[j2][i + 1] + a[j3][i + 1]; + x3r = a[j2][i] - a[j3][i]; + x3i = a[j2][i + 1] - a[j3][i + 1]; + a[j][i] = x0r + x2r; + a[j][i + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j2][i] = wk2r * x0r - wk2i * x0i; + a[j2][i + 1] = wk2r * x0i + wk2i * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j1][i] = wk1r * x0r - wk1i * x0i; + a[j1][i + 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3][i] = wk3r * x0r - wk3i * x0i; + a[j3][i + 1] = wk3r * x0i + wk3i * x0r; + } + } + } + } + l = m; + } + if (l < n) { + for (j = 0; j <= l - 1; j++) { + j1 = j + l; + for (i = 0; i <= n2 - 2; i += 2) { + x0r = a[j][i] - a[j1][i]; + x0i = a[j][i + 1] - a[j1][i + 1]; + a[j][i] += a[j1][i]; + a[j][i + 1] += a[j1][i + 1]; + a[j1][i] = x0r; + a[j1][i + 1] = x0i; + } + } + } + } + + + static void cftfcol(int n1, int n, double **a, double *w) + { + int i, j, j1, j2, j3, k, k1, ks, l, m; + double wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + for (i = 0; i <= n1 - 1; i++) { + l = 2; + while ((l << 1) < n) { + m = l << 2; + for (j = 0; j <= l - 2; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[i][j] + a[i][j1]; + x0i = a[i][j + 1] + a[i][j1 + 1]; + x1r = a[i][j] - a[i][j1]; + x1i = a[i][j + 1] - a[i][j1 + 1]; + x2r = a[i][j2] + a[i][j3]; + x2i = a[i][j2 + 1] + a[i][j3 + 1]; + x3r = a[i][j2] - a[i][j3]; + x3i = a[i][j2 + 1] - a[i][j3 + 1]; + a[i][j] = x0r + x2r; + a[i][j + 1] = x0i + x2i; + a[i][j2] = x0r - x2r; + a[i][j2 + 1] = x0i - x2i; + a[i][j1] = x1r + x3i; + a[i][j1 + 1] = x1i - x3r; + a[i][j3] = x1r - x3i; + a[i][j3 + 1] = x1i + x3r; + } + if (m < n) { + wk1r = w[2]; + for (j = m; j <= l + m - 2; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[i][j] + a[i][j1]; + x0i = a[i][j + 1] + a[i][j1 + 1]; + x1r = a[i][j] - a[i][j1]; + x1i = a[i][j + 1] - a[i][j1 + 1]; + x2r = a[i][j2] + a[i][j3]; + x2i = a[i][j2 + 1] + a[i][j3 + 1]; + x3r = a[i][j2] - a[i][j3]; + x3i = a[i][j2 + 1] - a[i][j3 + 1]; + a[i][j] = x0r + x2r; + a[i][j + 1] = x0i + x2i; + a[i][j2] = x0i - x2i; + a[i][j2 + 1] = x2r - x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[i][j1] = wk1r * (x0i + x0r); + a[i][j1 + 1] = wk1r * (x0i - x0r); + x0r = x3i - x1r; + x0i = x3r + x1i; + a[i][j3] = wk1r * (x0r + x0i); + a[i][j3 + 1] = wk1r * (x0r - x0i); + } + k1 = 1; + ks = -1; + for (k = (m << 1); k <= n - m; k += m) { + k1++; + ks = -ks; + wk1r = w[k1 << 1]; + wk1i = w[(k1 << 1) + 1]; + wk2r = ks * w[k1]; + wk2i = w[k1 + ks]; + wk3r = wk1r - 2 * wk2i * wk1i; + wk3i = 2 * wk2i * wk1r - wk1i; + for (j = k; j <= l + k - 2; j += 2) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[i][j] + a[i][j1]; + x0i = a[i][j + 1] + a[i][j1 + 1]; + x1r = a[i][j] - a[i][j1]; + x1i = a[i][j + 1] - a[i][j1 + 1]; + x2r = a[i][j2] + a[i][j3]; + x2i = a[i][j2 + 1] + a[i][j3 + 1]; + x3r = a[i][j2] - a[i][j3]; + x3i = a[i][j2 + 1] - a[i][j3 + 1]; + a[i][j] = x0r + x2r; + a[i][j + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[i][j2] = wk2r * x0r + wk2i * x0i; + a[i][j2 + 1] = wk2r * x0i - wk2i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[i][j1] = wk1r * x0r + wk1i * x0i; + a[i][j1 + 1] = wk1r * x0i - wk1i * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[i][j3] = wk3r * x0r + wk3i * x0i; + a[i][j3 + 1] = wk3r * x0i - wk3i * x0r; + } + } + } + l = m; + } + if (l < n) { + for (j = 0; j <= l - 2; j += 2) { + j1 = j + l; + x0r = a[i][j] - a[i][j1]; + x0i = a[i][j + 1] - a[i][j1 + 1]; + a[i][j] += a[i][j1]; + a[i][j + 1] += a[i][j1 + 1]; + a[i][j1] = x0r; + a[i][j1 + 1] = x0i; + } + } + } + } + + + static void cftfrow(int n, int n2, double **a, double *w) + { + int i, j, j1, j2, j3, k, k1, ks, l, m; + double wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + l = 1; + while ((l << 1) < n) { + m = l << 2; + for (j = 0; j <= l - 1; j++) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + for (i = 0; i <= n2 - 2; i += 2) { + x0r = a[j][i] + a[j1][i]; + x0i = a[j][i + 1] + a[j1][i + 1]; + x1r = a[j][i] - a[j1][i]; + x1i = a[j][i + 1] - a[j1][i + 1]; + x2r = a[j2][i] + a[j3][i]; + x2i = a[j2][i + 1] + a[j3][i + 1]; + x3r = a[j2][i] - a[j3][i]; + x3i = a[j2][i + 1] - a[j3][i + 1]; + a[j][i] = x0r + x2r; + a[j][i + 1] = x0i + x2i; + a[j2][i] = x0r - x2r; + a[j2][i + 1] = x0i - x2i; + a[j1][i] = x1r + x3i; + a[j1][i + 1] = x1i - x3r; + a[j3][i] = x1r - x3i; + a[j3][i + 1] = x1i + x3r; + } + } + if (m < n) { + wk1r = w[2]; + for (j = m; j <= l + m - 1; j++) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + for (i = 0; i <= n2 - 2; i += 2) { + x0r = a[j][i] + a[j1][i]; + x0i = a[j][i + 1] + a[j1][i + 1]; + x1r = a[j][i] - a[j1][i]; + x1i = a[j][i + 1] - a[j1][i + 1]; + x2r = a[j2][i] + a[j3][i]; + x2i = a[j2][i + 1] + a[j3][i + 1]; + x3r = a[j2][i] - a[j3][i]; + x3i = a[j2][i + 1] - a[j3][i + 1]; + a[j][i] = x0r + x2r; + a[j][i + 1] = x0i + x2i; + a[j2][i] = x0i - x2i; + a[j2][i + 1] = x2r - x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j1][i] = wk1r * (x0i + x0r); + a[j1][i + 1] = wk1r * (x0i - x0r); + x0r = x3i - x1r; + x0i = x3r + x1i; + a[j3][i] = wk1r * (x0r + x0i); + a[j3][i + 1] = wk1r * (x0r - x0i); + } + } + k1 = 1; + ks = -1; + for (k = (m << 1); k <= n - m; k += m) { + k1++; + ks = -ks; + wk1r = w[k1 << 1]; + wk1i = w[(k1 << 1) + 1]; + wk2r = ks * w[k1]; + wk2i = w[k1 + ks]; + wk3r = wk1r - 2 * wk2i * wk1i; + wk3i = 2 * wk2i * wk1r - wk1i; + for (j = k; j <= l + k - 1; j++) { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + for (i = 0; i <= n2 - 2; i += 2) { + x0r = a[j][i] + a[j1][i]; + x0i = a[j][i + 1] + a[j1][i + 1]; + x1r = a[j][i] - a[j1][i]; + x1i = a[j][i + 1] - a[j1][i + 1]; + x2r = a[j2][i] + a[j3][i]; + x2i = a[j2][i + 1] + a[j3][i + 1]; + x3r = a[j2][i] - a[j3][i]; + x3i = a[j2][i + 1] - a[j3][i + 1]; + a[j][i] = x0r + x2r; + a[j][i + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j2][i] = wk2r * x0r + wk2i * x0i; + a[j2][i + 1] = wk2r * x0i - wk2i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j1][i] = wk1r * x0r + wk1i * x0i; + a[j1][i + 1] = wk1r * x0i - wk1i * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j3][i] = wk3r * x0r + wk3i * x0i; + a[j3][i + 1] = wk3r * x0i - wk3i * x0r; + } + } + } + } + l = m; + } + if (l < n) { + for (j = 0; j <= l - 1; j++) { + j1 = j + l; + for (i = 0; i <= n2 - 2; i += 2) { + x0r = a[j][i] - a[j1][i]; + x0i = a[j][i + 1] - a[j1][i + 1]; + a[j][i] += a[j1][i]; + a[j][i + 1] += a[j1][i + 1]; + a[j1][i] = x0r; + a[j1][i + 1] = x0i; + } + } + } + } + static int *alloc_1d_int(int n1) + { + int *i; + + i = (int *) malloc(sizeof(int) * n1); + return i; + } + + static void free_1d_int(int *i) { free(i); } + + static double *alloc_1d_double(int n1) + { + double *d; + + d = (double *) malloc(sizeof(double) * n1); + return d; + } + + + static void free_1d_double(double *d) { free(d); } + static double **alloc_2d_double(int n1, int n2) + { + double **dd, *d; + int j; + + dd = (double **) malloc(sizeof(double *) * n1); + d = (double *) malloc(sizeof(double) * n1 * n2); + + dd[0] = d; + for (j = 1; j < n1; j++) { + dd[j] = dd[j - 1] + n2; + } + return dd; + } + + static void free_2d_double(double **dd) { free(dd[0]); free(dd); } + + + static void cdft2d(int n1, int n2, int isgn, double **a, int *ip, double *w) + { + int n; + + n = n1 << 1; + if (n < n2) { + n = n2; + } + if (n > (ip[0] << 2)) { + makewt(n >> 2, ip, w); + } + if (n2 > 4) { + bitrv2col(n1, n2, ip + 2, a); + } + if (n1 > 2) { + bitrv2row(n1, n2, ip + 2, a); + } + if (isgn < 0) { + cftfcol(n1, n2, a, w); + cftfrow(n1, n2, a, w); + } else { + cftbcol(n1, n2, a, w); + cftbrow(n1, n2, a, w); + } + } +}; diff --git a/retroshare-gui/src/gui/elastic/graphwidget.cpp b/retroshare-gui/src/gui/elastic/graphwidget.cpp index bb1f9ffb8..9aeebbeda 100644 --- a/retroshare-gui/src/gui/elastic/graphwidget.cpp +++ b/retroshare-gui/src/gui/elastic/graphwidget.cpp @@ -42,6 +42,7 @@ #include "graphwidget.h" #include "edge.h" #include "node.h" +#include "fft.h" #include #include @@ -50,86 +51,9 @@ #include -#define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr - -void fourn(double data[],unsigned long nn[],unsigned long ndim,int isign) -{ - int i1,i2,i3,i2rev,i3rev,ip1,ip2,ip3,ifp1,ifp2; - int ibit,idim,k1,k2,n,nprev,nrem,ntot; - double tempi,tempr; - double theta,wi,wpi,wpr,wr,wtemp; - - ntot=1; - for (idim=1;idim<=(long)ndim;++idim) - ntot *= nn[idim]; - nprev=1; - for (idim=ndim;idim>=1;idim--) { - n=nn[idim]; - nrem=ntot/(n*nprev); - ip1=nprev << 1; - ip2=ip1*n; - ip3=ip2*nrem; - i2rev=1; - for (i2=1;i2<=ip2;i2+=ip1) { - if (i2 < i2rev) { - for (i1=i2;i1<=i2+ip1-2;i1+=2) { - for (i3=i1;i3<=ip3;i3+=ip2) { - i3rev=i2rev+i3-i2; - SWAP(data[i3],data[i3rev]); - SWAP(data[i3+1],data[i3rev+1]); - } - } - } - ibit=ip2 >> 1; - while (ibit >= ip1 && i2rev > ibit) { - i2rev -= ibit; - ibit >>= 1; - } - i2rev += ibit; - } - ifp1=ip1; - while (ifp1 < ip2) { - ifp2=ifp1 << 1; - theta=isign*6.28318530717959/(ifp2/ip1); - wtemp=sin(0.5*theta); - wpr = -2.0*wtemp*wtemp; - wpi=sin(theta); - wr=1.0; - wi=0.0; - for (i3=1;i3<=ifp1;i3+=ip1) { - for (i1=i3;i1<=i3+ip1-2;i1+=2) { - for (i2=i1;i2<=ip3;i2+=ifp2) { - k1=i2; - k2=k1+ifp1; - tempr=wr*data[k2]-wi*data[k2+1]; - tempi=wr*data[k2+1]+wi*data[k2]; - data[k2]=data[k1]-tempr; - data[k2+1]=data[k1+1]-tempi; - data[k1] += tempr; - data[k1+1] += tempi; - } - } - wr=(wtemp=wr)*wpr-wi*wpi+wr; - wi=wi*wpr+wtemp*wpi+wi; - } - ifp1=ifp2; - } - nprev *= n; - } -} - -#undef SWAP - GraphWidget::GraphWidget(QWidget *) : timerId(0), mIsFrozen(false) { -// QGraphicsScene *scene = new QGraphicsScene(QRectF(0,0,500,500),this); -// scene->setItemIndexMethod(QGraphicsScene::NoIndex); -// scene->clear() ; -// setScene(scene); - -// scene()->setSceneRect(0, 0, width(), height()); - setCacheMode(CacheBackground); setViewportUpdateMode(BoundingRectViewportUpdate); setRenderHint(QPainter::Antialiasing); @@ -142,18 +66,6 @@ GraphWidget::GraphWidget(QWidget *) void GraphWidget::clearGraph() { -// QGraphicsScene *scene = new QGraphicsScene(this); -// scene->setItemIndexMethod(QGraphicsScene::NoIndex); -// setScene(scene); - -// scene->addItem(centerNode); -// centerNode->setPos(0, 0); - -// if (oldscene != NULL) -// { -// delete oldscene; -// } - scene()->clear(); scene()->setSceneRect(0, 0, width(), height()); @@ -229,18 +141,6 @@ void GraphWidget::itemMoved() void GraphWidget::keyPressEvent(QKeyEvent *event) { switch (event->key()) { -// case Qt::Key_Up: -// centerNode->moveBy(0, -20); -// break; -// case Qt::Key_Down: -// centerNode->moveBy(0, 20); -// break; -// case Qt::Key_Left: -// centerNode->moveBy(-20, 0); -// break; -// case Qt::Key_Right: -// centerNode->moveBy(20, 0); -// break; case Qt::Key_Plus: scaleView(qreal(1.2)); break; @@ -259,45 +159,63 @@ void GraphWidget::keyPressEvent(QKeyEvent *event) } } -static void convolveWithGaussian(double *forceMap,unsigned int S,int /*s*/) +static void convolveWithForce(double *forceMap,unsigned int S,int /*s*/) { - static double *bf = NULL ; + static double **bf = NULL ; + static double **tmp = NULL ; + static int *ip = NULL ; + static double *w = NULL ; + static uint32_t last_S = 0 ; if(bf == NULL) { - bf = new double[S*S*2] ; + bf = fft::alloc_2d_double(S, 2*S); for(unsigned int i=0;i derivative is constant - bf[2*(i+S*j)+1] = 0 ; + + bf[i][j*2+0] = log(sqrtf(0.1 + x*x+y*y)); // linear -> derivative is constant + bf[i][j*2+1] = 0 ; } - unsigned long nn[2] = {S,S}; - fourn(&bf[-1],&nn[-1],2,1) ; + ip = fft::alloc_1d_int(2 + (int) sqrt(S + 0.5)); + w = fft::alloc_1d_double(S/2+S); + ip[0] = 0; + + fft::cdft2d(S, 2*S, 1, bf, ip, w); } - unsigned long nn[2] = {S,S}; - fourn(&forceMap[-1],&nn[-1],2,1) ; + if(last_S != S) + { + if(tmp) + fft::free_2d_double(tmp) ; + + tmp = fft::alloc_2d_double(S, 2*S); + last_S = S ; + } + memcpy(tmp[0],forceMap,S*S*2*sizeof(double)) ; + + fft::cdft2d(S, 2*S, 1, tmp, ip, w); for (unsigned int i=0;isceneRect()) ; - if( (hit++ & 7) == 0) + if( (hit++ & 3) == 0) { memset(forceMap,0,2*S*S*sizeof(double)) ; @@ -348,7 +266,7 @@ void GraphWidget::timerEvent(QTimerEvent *event) } // compute convolution with 1/omega kernel. - convolveWithGaussian(forceMap,S,20) ; + convolveWithForce(forceMap,S,20) ; } foreach (Node *node, _nodes) @@ -362,7 +280,7 @@ void GraphWidget::timerEvent(QTimerEvent *event) bool itemsMoved = false; foreach (Node *node, _nodes) - if(node->advance()) + if(node->progress()) itemsMoved = true; if (!itemsMoved) { @@ -435,43 +353,6 @@ void GraphWidget::wheelEvent(QWheelEvent *event) scaleView(pow((double)2, -event->delta() / 240.0)); } -//void GraphWidget::drawBackground(QPainter *painter, const QRectF &rect) -//{ -// Q_UNUSED(rect); -// -// // Shadow -// QRectF sceneRect = this->sceneRect(); -// QRectF rightShadow(sceneRect.right(), sceneRect.top() + 5, 5, sceneRect.height()); -// QRectF bottomShadow(sceneRect.left() + 5, sceneRect.bottom(), sceneRect.width(), 5); -// if (rightShadow.intersects(rect) || rightShadow.contains(rect)) -// painter->fillRect(rightShadow, Qt::darkGray); -// if (bottomShadow.intersects(rect) || bottomShadow.contains(rect)) -// painter->fillRect(bottomShadow, Qt::darkGray); -// -// // Fill -// QLinearGradient gradient(sceneRect.topLeft(), sceneRect.bottomRight()); -// gradient.setColorAt(0, Qt::white); -// gradient.setColorAt(1, Qt::lightGray); -// painter->fillRect(rect.intersected(sceneRect), gradient); -// painter->setBrush(Qt::NoBrush); -// painter->drawRect(sceneRect); -// -// // Text -// QRectF textRect(sceneRect.left() + 4, sceneRect.top() + 4, -// sceneRect.width() - 4, sceneRect.height() - 4); -// QString message(tr("Click and drag the nodes around, and zoom with the mouse " -// "wheel or the '+' and '-' keys")); -// -// QFont font = painter->font(); -// font.setBold(true); -// font.setPointSize(14); -// painter->setFont(font); -// painter->setPen(Qt::lightGray); -// painter->drawText(textRect.translated(2, 2), message); -// painter->setPen(Qt::black); -// painter->drawText(textRect, message); -//} - void GraphWidget::scaleView(qreal scaleFactor) { qreal factor = matrix().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width(); diff --git a/retroshare-gui/src/gui/elastic/node.cpp b/retroshare-gui/src/gui/elastic/node.cpp index bc33151df..6a3020b21 100644 --- a/retroshare-gui/src/gui/elastic/node.cpp +++ b/retroshare-gui/src/gui/elastic/node.cpp @@ -215,7 +215,7 @@ void Node::calculateForces(const double *map,int width,int height,int W,int H,fl newPos.setY(qMin(qMax(newPos.y(), sceneRect.top()) , sceneRect.bottom())); } -bool Node::advance() +bool Node::progress() { if(_type == GraphWidget::ELASTIC_NODE_TYPE_OWN) return false; diff --git a/retroshare-gui/src/gui/elastic/node.h b/retroshare-gui/src/gui/elastic/node.h index 13c717b0b..e43fa3521 100644 --- a/retroshare-gui/src/gui/elastic/node.h +++ b/retroshare-gui/src/gui/elastic/node.h @@ -77,7 +77,7 @@ public: std::string descString() const { return _desc_string ; } void calculateForces(const double *data,int width,int height,int W,int H,float x,float y,float speedf); - bool advance(); + bool progress(); QRectF boundingRect() const; QPainterPath shape() const; diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp index 2fa1f3b1e..a99e815c7 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp @@ -25,6 +25,7 @@ #include #include +#include "gui/common/RSElidedItemDelegate.h" #include "gui/gxs/GxsCommentTreeWidget.h" #include "gui/gxs/GxsCreateCommentDialog.h" #include "gui/gxs/GxsIdTreeWidgetItem.h" @@ -57,6 +58,10 @@ GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent) // QTreeWidget* widget = this; setContextMenuPolicy(Qt::CustomContextMenu); + RSElidedItemDelegate *itemDelegate = new RSElidedItemDelegate(this); + itemDelegate->setSpacing(QSize(0, 2)); + setItemDelegate(itemDelegate); + setWordWrap(true); // QFont font = QFont("ARIAL", 10); // font.setBold(true); diff --git a/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.cpp b/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.cpp index a1e20e37c..500693df0 100644 --- a/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.cpp @@ -25,6 +25,8 @@ #include "GxsCreateCommentDialog.h" #include "ui_GxsCreateCommentDialog.h" +#include "util/HandleRichText.h" + #include #include @@ -45,7 +47,11 @@ void GxsCreateCommentDialog::createComment() { RsGxsComment comment; - comment.mComment = std::string(ui->commentTextEdit->document()->toPlainText().toUtf8()); + QString text = ui->commentTextEdit->toHtml(); + RsHtml::optimizeHtml(text); + std::string msg = text.toUtf8().constData(); + + comment.mComment = msg; comment.mMeta.mParentId = mParentId.second; comment.mMeta.mGroupId = mParentId.first; comment.mMeta.mThreadId = mThreadId; diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index b18ab3688..cd792623d 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -863,7 +863,8 @@ void GxsGroupDialog::requestGroup(const RsGxsGroupId &groupId) std::cerr << std::endl; uint32_t token; - mInternalTokenQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, GXSGROUP_INTERNAL_LOADGROUP); + if (mInternalTokenQueue) + mInternalTokenQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, GXSGROUP_INTERNAL_LOADGROUP) ; } void GxsGroupDialog::loadGroup(uint32_t token) diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp index 2bfdb6c0d..6ab4ca165 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp @@ -841,8 +841,11 @@ void GxsGroupFrameDialog::insertGroupsData(const std::list &gro /* now we can add them in as a tree! */ ui->groupTreeWidget->fillGroupItems(mYourGroups, adminList); ui->groupTreeWidget->fillGroupItems(mSubscribedGroups, subList); + mSubscribedGroups->setText(2, QString::number(mSubscribedGroups->childCount())); // 1 COLUMN_UNREAD 2 COLUMN_POPULARITY ui->groupTreeWidget->fillGroupItems(mPopularGroups, popList); + mPopularGroups->setText(2, QString::number(mPopularGroups->childCount())); ui->groupTreeWidget->fillGroupItems(mOtherGroups, otherList); + mOtherGroups->setText(2, QString::number(mOtherGroups->childCount())); mInFill = false; diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp index 788490e40..aaab89231 100644 --- a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp @@ -308,7 +308,7 @@ void CreateGxsForumMsg::loadFormInformation() ui.forumName->setText(misc::removeNewLine(name)); ui.forumSubject->setText(misc::removeNewLine(subj)); - ui.forumSubject->setReadOnly(!mOrigMsgId.isNull()); + //ui.forumSubject->setReadOnly(!mOrigMsgId.isNull()); if (ui.forumSubject->text().isEmpty()) { diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index 4254af49e..6afa8dbdd 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -60,6 +60,7 @@ /* Images for context menu icons */ #define IMAGE_MESSAGE ":/images/mail_new.png" #define IMAGE_MESSAGEREPLY ":/images/mail_reply.png" +#define IMAGE_MESSAGEEDIT ":/images/edit_16.png" #define IMAGE_MESSAGEREMOVE ":/images/mail_delete.png" #define IMAGE_DOWNLOAD ":/images/start.png" #define IMAGE_DOWNLOADALL ":/images/startall.png" @@ -485,7 +486,7 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/) QMenu contextMnu(this); - QAction *editAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Edit"), &contextMnu); + QAction *editAct = new QAction(QIcon(IMAGE_MESSAGEEDIT), tr("Edit"), &contextMnu); connect(editAct, SIGNAL(triggered()), this, SLOT(editforummessage())); QAction *replyAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Reply"), &contextMnu); @@ -531,7 +532,7 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/) 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 *showinpeopleAct = new QAction(QIcon(":/images/message-mail.png"), tr("Show author in people tab"), &contextMnu); + QAction *showinpeopleAct = new QAction(QIcon(":/images/info16.png"), tr("Show author in people tab"), &contextMnu); connect(showinpeopleAct, SIGNAL(triggered()), this, SLOT(showInPeopleTab())); if (IS_GROUP_SUBSCRIBED(mSubscribeFlags)) { @@ -1607,7 +1608,7 @@ void GxsForumThreadWidget::insertMessage() int current_index = 0 ; - for(uint32_t i=0;i<(*it).size();++i) + for(int i=0;i<(*it).size();++i) { ui->versions_CB->insertItem(i, ((i==0)?tr("(Latest) "):tr("(Old) "))+" "+DateTime::formatLongDateTime( (*it)[i].first)); ui->versions_CB->setItemData(i,QString::fromStdString((*it)[i].second.toStdString())); diff --git a/retroshare-gui/src/gui/images.qrc b/retroshare-gui/src/gui/images.qrc index adad4c232..fbdb66d3d 100644 --- a/retroshare-gui/src/gui/images.qrc +++ b/retroshare-gui/src/gui/images.qrc @@ -1,667 +1,668 @@ - - images/network_map.png - images/global_switch_on.png - images/global_switch_off.png - images/switch00.png - images/switch01.png - images/switch10.png - images/switch11.png - images/add_chat24.png - images/RSS_004_32.png - images/mail-encrypted-full.png - images/mail-signed-full.png - images/document-edit-sign.png - images/decrypt-mail.png - images/inbox_22.png - images/blue_lock.png - images/blue_lock_open.png - images/d-chat64.png - images/edit_24.png - images/streaming.png - images/white-bubble-64.png - images/orange-bubble-64.png - images/stock_signature_bad.png - images/stock_signature_ok.png - images/stock_signature_missing.png - images/stock_signature_unverified.png - images/anonymous_128_blue.png - images/browsable_128_green.png - images/browsable_128_blue.png - images/blank_128_green.png - images/blank_128_blue.png - images/door_in.png - images/tor-logo.png - images/help/addafriend.png - images/help/addfriendkey.png - images/help/dhtgreen.png - icons/help_64.png - images/help/natgreen.png - images/help/natred.png - images/attach.png - images/pgp.png - images/rs_wizard.png - images/avatar_request.png - images/avatar_refused.png - images/avatar_request_unknown.png - images/backblue.png - images/backchat.png - images/buttonframe.png - images/btn1.png - images/btn2.png - images/btn3.png - images/btn4.png - images/btn_26.png - images/btn_26_hover.png - images/btn_26_pressed.png - images/btn_27.png - images/btn_27_hover.png - images/btn_blue.png - images/btn_blue_hover.png - images/btn_green.png - images/btn_green_hover.png - images/btn_green_pressed.png - images/connect_creating.png - images/dht16.png - images/dht32.png - images/edit-clear-history.png - images/edit_16.png - images/feedback_arrow.png - images/feedback_arrow_hover.png - images/firewall_24.png - images/list_bullet_arrow.png - images/rc_combined.png - images/combobox_arrow.png - images/arrow-left.png - images/arrow-right.png - help/authors.html - help/licence.html - help/thanks.html - images/accepted16.png - images/add_image24.png - images/add_channel64.png - images/add_channel24.png - images/add_channel32.png - images/admin-16.png - images/admin-32.png - images/admin-24.png - images/admin-48.png - images/user/add_group22.png - images/user/add_group256.png - images/user/edit_group64.png - images/avatarstatus-bg-116.png - images/avatarstatus-bg-online-116.png - images/avatarstatus-bg-idle-116.png - images/avatarstatus-bg-away-116.png - images/avatarstatus-bg-busy-116.png - images/avatarstatus-bg-offline-116.png - images/avatarstatus-bg-70.png - images/avatarstatus-bg-online-70.png - images/avatarstatus-bg-idle-70.png - images/avatarstatus-bg-away-70.png - images/avatarstatus-bg-busy-70.png - images/avatarstatus-bg-offline-70.png - images/browse-looking.gif - images/back.png - images/backgroundl.png - images/blockdevice.png - images/blockdevice2.png - images/configure.png - images/channels.png - images/turtle.png - images/channels16.png - images/channels24.png - images/channels32.png - images/channels_new.png - images/channelsred.png - images/channelsyellow.png - images/channelsgreen.png - images/channelsblue.png - images/copyrslink.png - images/contacts24.png - images/contactsclosed24.png - images/connection.png - images/contact_new.png - images/contact_new22.png - images/contact.png - images/contact22.png - images/Client0.png - images/Client1.png - images/Client2.png - images/Client3.png - images/Client4.png - images/closenormal.png - images/closehover.png - images/closepressed.png - images/denied16.png - images/filetype-association.png - images/FileTypeAny.png - images/FileTypeArchive.png - images/FileTypeAudio.png - images/FileTypeCDImage.png - images/FileTypeDocument.png - images/FileTypePicture.png - images/FileTypeProgram.png - images/FileTypeVideo.png - images/fonts.png - images/folder16.png - images/foldermail.png - images/folderopen.png - images/fileopen.png - images/graph-downloaded.png - images/graph-downloading.png - images/graph-notdownload.png - images/graph-checking.png - images/graph-blue.png - images/add-share24.png - images/add_24x24.png - images/advsearch_24x24.png - images/amsn16.png - images/attachment.png - images/avatar_background.png - images/backgroundimage.png - images/button_cancel.png - images/calendar.png - images/chat.png - images/chat_22.png - images/chat_24.png - images/chat_32.png - images/chat_64.png - images/chat_x24.png - images/chat_red24.png - images/cancel.png - images/close-down.png - images/close_normal.png - images/console-small-down.png - images/console-small-hover.png - images/console-small-up.png - images/contact_new128.png - images/copy.png - images/delete.png - images/deleteall.png - images/deletemail-pressed.png - images/deletemail24.png - images/directoryadd_24x24_shadow.png - images/directoryremove_24x24_shadow.png - images/directoryselect_24x24_shadow.png - images/diskSave.png - images/document_save.png - images/down.png - images/down_24x24.png - images/download.png - images/download16.png - images/edit_add24.png - images/edit-bold.png - images/edit-italic.png - images/edit-underline.png - images/edit_remove24.png - images/encrypted16.png - images/encrypted22.png - images/encrypted32.png - images/encrypted48.png - images/disabled_plugin_48.png - images/evolution.png - images/exit_24x24.png - images/exit_32.png - images/expand_frame.png - images/exportpeers_16x16.png - images/extension_32.png - images/filefind.png - images/fileinfo.png - images/filename.png - images/filepriority.png - images/filecomments.png - images/filerating0.png - images/filerating1.png - images/filerating2.png - images/filerating3.png - images/filerating4.png - images/filerating5.png - images/fileshare16.png - images/fileshare24.png - images/fileshare32.png - images/fileshare48.png - images/fileshare64.png - images/find.png - images/find-16.png - images/emoticons/kopete/kopete020.png - images/flags/af.png - images/flags/bg.png - images/flags/zh_CN.png - images/flags/zh_TW.png - images/flags/ca_ES.png - images/flags/cs.png - images/flags/de.png - images/flags/da.png - images/flags/el.png - images/flags/en.png - images/flags/es.png - images/flags/fi.png - images/flags/fr.png - images/flags/hu.png - images/flags/it.png - images/flags/ja_JP.png - images/flags/ko.png - images/flags/nl.png - images/flags/pl.png - images/flags/pt.png - images/flags/ru.png - images/flags/sv.png - images/flags/sl.png - images/flags/tr.png - images/folder-draft.png - images/folder-draft24-pressed.png - images/folder-draft24.png - images/folder_inbox64.png - images/folder-inbox.png - images/folder-inbox-new.png - images/folder-outbox.png - images/folder-sent.png - images/folder-trash.png - images/folder_doments.png - images/folder_green.png - images/folder_red.png - images/folder_grey.png - images/folder_yellow.png - images/folder_open.png - images/folder_video.png - images/folder_blueshared.png - images/forward.png - images/friendsfolder24.png - images/kgames.png - images/go-down.png - images/go-top.png - images/go-up.png - images/go-bottom.png - images/graph-area.png - images/graph-line.png - images/groupchat.png - images/genbackground.png - images/gohome.png - images/gpgp_key_generate.png - images/help.png - images/help24.png - images/hide_toolbox_frame.png - images/hide_frame.png - images/highlight.png - images/hi16-app-ktorrent.png - images/hi24-app-ktorrent.png - images/hot_0.png - images/hot_1.png - images/hot_2.png - images/hot_3.png - images/hot_4.png - images/hot_5.png - images/image16.png - images/imageblocked_24.png - images/info16.png - images/im-user.png - images/im-user-offline.png - images/im-user-away.png - images/im-user-busy.png - images/im-user-inactive.png - images/informations_24x24.png - images/connect_friend.png - images/kalarm.png - images/kbackgammon.png - images/kblogger.png - images/hi48-app-kblogger.png - images/hi64-app-kblogger.png - images/transfers_new.png - images/kcmsystem24.png - images/kdmconfig.png - images/konsole.png - images/newsfeed128.png - images/newsfeed128_notify.png - images/konversation.png - images/konversation16.png - images/konversation128.png - images/konv_message2.png - images/konv_message3.png - images/konv_message64.png - images/konversation64.png - images/forums_new.png - images/ksysguard.png - images/ksysguard32.png - images/ktorrent.png - images/ktorrent32.png - images/knewsticker24.png - images/library.png - images/loadcert16.png - images/ledoff1.png - images/ledon1.png - images/locale.png - images/looknfeel.png - images/lphoto.png - images/lphoto16.png - images/lphoto24.png - images/logo/logo_16.png - images/logo/logo_24.png - images/logo/logo_24_0.png - images/logo/logo_24_1.png - images/logo/logo_24_2.png - images/logo/logo_32.png - images/logo/logo_48.png - images/logo/logo_64.png - images/logo/logo_128.png - images/logo/logo_256.png - images/logo/logo_512.png - images/logo/logo_info.png - images/logo/logo_splash.png - images/logobar/logo_bar_fill.png - images/logobar/logo_bar_start.png - images/logobar/rslogo.png - images/logobar/rslogo2.png - images/mail-message-new.png - images/mail-signed.png - images/mail-signature-unknown.png - images/mail_delete.png - images/mail_get.png - images/mail_reply.png - images/mail_replyall.png - images/mail_forward.png - images/mail_send.png - images/mail_new.png - images/mail_send24.png - images/mailforward24-hover.png - images/message-mail.png - images/message-mail-read.png - images/message-mail-imapdelete.png - images/message-mail-replied-read.png - images/message-mail-forwarded-read.png - images/message-mail-replied.png - images/message-mail-forwarded.png - images/message-mail-replied-forw.png - images/message-mail-replied-forw-read.png - images/message-state-read.png - images/message-state-unread.png - images/message-state-header.png - images/message-state-new.png - images/message-news.png - images/message_new.png - images/message.png - images/messenger.png - images/mute-off-16.png - images/mute-on-16.png - images/my_documents_16.png - images/my_documents_22.png - images/network.png - images/network16.png - images/network32.png - images/new-mail-alert.png - images/new_forum16.png - images/newmsg.png - images/no_avatar_70.png - images/no_avatar_background.png - images/openimage.png - images/office-chart-area-stacked.png - images/office-chart-line.png - images/pasterslink.png - images/package_games1.png - images/pin32.png - images/print24.png - images/priorityauto.png - images/priorityhigh.png - images/prioritylow.png - images/prioritynormal.png - images/pause.png - images/preview.png - images/player_play.png - images/quick_restart24.png - images/quote_24.png - images/redled.png - images/greenled.png - images/grayled.png - images/yellowled.png - images/rate-1.png - images/rate-2.png - images/rate-3.png - images/rate-4.png - images/rate-5.png - images/rating.png - images/records.png - images/replymail-pressed.png - images/replymail24.png - images/replymailall24-hover.png - images/reset.png - images/resume.png - images/security-high-16.png - images/security-high-48.png - images/security-low-48.png - images/security-medium-48.png - images/security-high-off-48.png - images/security-low-off-48.png - images/security-medium-off-48.png - images/save24.png - images/send24.png - images/settings.png - images/settings16.png - images/show_toolbox_frame.png - images/start.png - images/stop.png - images/star-on-16.png - images/star-off-16.png - images/StatsCumulative.png - images/StatisticsDetail.png - images/status_unknown.png - images/startall.png - images/server_24x24.png - images/sort_incr.png - images/sort_decrease.png - images/sound.png - images/tab-dock.png - images/tab-undock.png - images/tab-new.png - images/tag24.png - images/transferupdown.png - images/tools_wizard.png - images/typing.png - images/trustsettings.png - images/uploads.png - images/headerFrame.png - images/loader/indicator-16.gif - images/loader/indicator-32.gif - images/loader/circleball-16.gif - images/loader/progress.gif - images/mimetypes/pdf.png - images/mimetypes/rscollection-16.png - images/mimetypes/patch.png - images/mimetypes/source_c.png - images/mimetypes/source_cpp.png - images/mimetypes/source_h.png - images/view-certificate-copy-32.png - images/view-certificate-export-32.png - images/textedit/textbold.png - images/textedit/textitalic.png - images/textedit/textunder.png - images/textedit/textjustify.png - images/textedit/textcenter.png - images/textedit/textleft.png - images/textedit/textright.png - images/textedit/editcopy.png - images/textedit/editcut.png - images/textedit/editpaste.png - images/textedit/editredo.png - images/textedit/editundo.png - images/textedit/exportpdf.png - images/textedit/filenew.png - images/textedit/fileopen.png - images/textedit/fileprint.png - images/textedit/filesave.png - images/textedit/format-text-color.png - images/textedit/format-list-ordered.png - images/textedit/format-list-unordered.png - images/textedit/zoomin.png - images/textedit/zoomout.png - images/textedit/format_font_size_more.png - images/textedit/format_font_size_less.png - images/textedit/hi22-action-format-text-blockquote.png - images/textedit/hi22-action-format-text-code.png - images/textedit/hi22-action-insert-more-mark.png - images/toaster/chat.png - images/toaster/hangup.png - images/toaster/pickup.png - images/toaster/backgroundtoaster.png - images/thumb-default-video.png - images/user/add_user24.png - images/user/add_user48.png - images/user/remove_user24.png - images/user/deny_user48.png - images/user/friends24.png - images/user/friends32.png - images/user/friends64.png - images/user/friends24_notify.png - images/user/friend_suggestion16.png - images/user/identity16.png - images/user/identity24.png - images/user/identity24_low.png - images/user/identity32.png - images/user/identity48.png - images/user/identityinfo48.png - images/user/identityinfo64.png - images/user/identityoffline24.png - images/user/identity24away.png - images/user/identity24busy.png - images/user/identity24idle.png - images/user/identityavaiblecyan24.png - images/user/invite24.png - images/user/agt_forum24.png - images/user/agt_forum32.png - images/user/identitygray16.png - images/user/add_user16.png - images/user/personal64.png - images/user/personal128.png - images/user/kuser24.png - images/user/agt_forum64.png - images/user/agt_forum128.png - images/user/group16.png - images/user/group24.png - images/user/servicepermissions64.png - images/user/user_request16.png - images/user/user_request48.png - images/user/user_request_unknown48.png - images/up.png - images/up0down0.png - images/up0down1.png - images/up1down1.png - images/up1down0.png - images/underconstruction.png - images/user.png - images/view-certificate-sign-32.png - images/view_calendar_day.png - images/view_calendar_week.png - images/view_calendar_month.png - images/view_calendar_list.png - images/view_split_top_bottom.png - images/vote_up.png - images/vote_down.png - images/vote_neutral.png - images/window_fullscreen.png - images/window_nofullscreen.png - images/identity/identities_32.png - images/identity/identity_64.png - images/identity/identity_create_32.png - images/identity/identity_create_64.png - images/identity/identity_delete_32.png - images/identity/identity_edit_32.png - images/identity/identity_edit_64.png - qss/chat/standard/private/info.xml - qss/chat/standard/private/incoming.htm - qss/chat/standard/private/outgoing.htm - qss/chat/standard/private/hincoming.htm - qss/chat/standard/private/houtgoing.htm - qss/chat/standard/private/ooutgoing.htm - qss/chat/standard/private/system.htm - qss/chat/standard/private/main.css - qss/chat/standard/private/variants/Standard.css - qss/chat/standard/public/info.xml - qss/chat/standard/public/incoming.htm - qss/chat/standard/public/outgoing.htm - qss/chat/standard/public/hincoming.htm - qss/chat/standard/public/houtgoing.htm - qss/chat/standard/public/ooutgoing.htm - qss/chat/standard/public/system.htm - qss/chat/standard/public/main.css - qss/chat/standard/public/variants/Standard.css - qss/chat/standard/history/info.xml - qss/chat/standard/history/incoming.htm - qss/chat/standard/history/outgoing.htm - qss/chat/standard/history/hincoming.htm - qss/chat/standard/history/houtgoing.htm - qss/chat/standard/history/ooutgoing.htm - qss/chat/standard/history/system.htm - qss/chat/standard/history/main.css - qss/chat/standard/history/variants/Standard.css - qss/chat/compact/private/info.xml - qss/chat/compact/private/incoming.htm - qss/chat/compact/private/outgoing.htm - qss/chat/compact/private/hincoming.htm - qss/chat/compact/private/houtgoing.htm - qss/chat/compact/private/ooutgoing.htm - qss/chat/compact/private/system.htm - qss/chat/compact/private/main.css - qss/chat/compact/private/variants/Standard.css - qss/chat/compact/private/variants/Colored.css - qss/chat/compact/public/info.xml - qss/chat/compact/public/incoming.htm - qss/chat/compact/public/outgoing.htm - qss/chat/compact/public/hincoming.htm - qss/chat/compact/public/houtgoing.htm - qss/chat/compact/public/ooutgoing.htm - qss/chat/compact/public/system.htm - qss/chat/compact/public/main.css - qss/chat/compact/public/variants/Standard.css - qss/chat/compact/public/variants/Colored.css - qss/chat/compact/history/info.xml - qss/chat/compact/history/incoming.htm - qss/chat/compact/history/outgoing.htm - qss/chat/compact/history/hincoming.htm - qss/chat/compact/history/houtgoing.htm - qss/chat/compact/history/ooutgoing.htm - qss/chat/compact/history/system.htm - qss/chat/compact/history/main.css - qss/chat/compact/history/variants/Standard.css - qss/chat/compact/history/variants/Colored.css - qss/stylesheet/qss.default - qss/stylesheet/Standard.qss - images/connect/connectFriendWatermark.png - images/connect/connectFriendLogo.png - images/connect/connectFriendBanner.png - images/connect/connectFriendBanner1.png - images/connect/info16.png - images/connect/mail_send.png - images/tags/pgp-known.png - images/tags/pgp-unknown.png - images/tags/anon.png - images/tags/dev-ambassador.png - images/tags/dev-translator.png - images/tags/dev-patcher.png - images/tags/developer.png - images/circles/circles_32.png - images/circles/circles_64.png - images/newsfeed/news-feed-32.png - images/newsfeed/news-feed-notify-32.png - images/share-icon-16.png - help/version.html - images/view-certificate-sign-48.png - images/toasterEnable.png - images/toasterDisable.png - images/library_edit.png - images/library_view.png - images/library_add.png - images/library64.png - images/library16.png - images/btn_red_pressed.png - images/btn_red_hover.png - images/btn_red.png - images/view-feeds.png - images/view-files.png - images/emblem-web.png - images/rsmessenger16.png - images/rsmessenger32.png - images/rsmessenger48.png - images/SmileyText.png - images/SimpleText.png - images/ColoredText.png - + + images/logo/logo_spash2.png + images/network_map.png + images/global_switch_on.png + images/global_switch_off.png + images/switch00.png + images/switch01.png + images/switch10.png + images/switch11.png + images/add_chat24.png + images/RSS_004_32.png + images/mail-encrypted-full.png + images/mail-signed-full.png + images/document-edit-sign.png + images/decrypt-mail.png + images/inbox_22.png + images/blue_lock.png + images/blue_lock_open.png + images/d-chat64.png + images/edit_24.png + images/streaming.png + images/white-bubble-64.png + images/orange-bubble-64.png + images/stock_signature_bad.png + images/stock_signature_ok.png + images/stock_signature_missing.png + images/stock_signature_unverified.png + images/anonymous_128_blue.png + images/browsable_128_green.png + images/browsable_128_blue.png + images/blank_128_green.png + images/blank_128_blue.png + images/door_in.png + images/tor-logo.png + images/help/addafriend.png + images/help/addfriendkey.png + images/help/dhtgreen.png + icons/help_64.png + images/help/natgreen.png + images/help/natred.png + images/attach.png + images/pgp.png + images/rs_wizard.png + images/avatar_request.png + images/avatar_refused.png + images/avatar_request_unknown.png + images/backblue.png + images/backchat.png + images/buttonframe.png + images/btn1.png + images/btn2.png + images/btn3.png + images/btn4.png + images/btn_26.png + images/btn_26_hover.png + images/btn_26_pressed.png + images/btn_27.png + images/btn_27_hover.png + images/btn_blue.png + images/btn_blue_hover.png + images/btn_green.png + images/btn_green_hover.png + images/btn_green_pressed.png + images/connect_creating.png + images/dht16.png + images/dht32.png + images/edit-clear-history.png + images/edit_16.png + images/feedback_arrow.png + images/feedback_arrow_hover.png + images/firewall_24.png + images/list_bullet_arrow.png + images/rc_combined.png + images/combobox_arrow.png + images/arrow-left.png + images/arrow-right.png + help/authors.html + help/licence.html + help/thanks.html + images/accepted16.png + images/add_image24.png + images/add_channel64.png + images/add_channel24.png + images/add_channel32.png + images/admin-16.png + images/admin-32.png + images/admin-24.png + images/admin-48.png + images/user/add_group22.png + images/user/add_group256.png + images/user/edit_group64.png + images/avatarstatus-bg-116.png + images/avatarstatus-bg-online-116.png + images/avatarstatus-bg-idle-116.png + images/avatarstatus-bg-away-116.png + images/avatarstatus-bg-busy-116.png + images/avatarstatus-bg-offline-116.png + images/avatarstatus-bg-70.png + images/avatarstatus-bg-online-70.png + images/avatarstatus-bg-idle-70.png + images/avatarstatus-bg-away-70.png + images/avatarstatus-bg-busy-70.png + images/avatarstatus-bg-offline-70.png + images/browse-looking.gif + images/back.png + images/backgroundl.png + images/blockdevice.png + images/blockdevice2.png + images/configure.png + images/channels.png + images/turtle.png + images/channels16.png + images/channels24.png + images/channels32.png + images/channels_new.png + images/channelsred.png + images/channelsyellow.png + images/channelsgreen.png + images/channelsblue.png + images/copyrslink.png + images/contacts24.png + images/contactsclosed24.png + images/connection.png + images/contact_new.png + images/contact_new22.png + images/contact.png + images/contact22.png + images/Client0.png + images/Client1.png + images/Client2.png + images/Client3.png + images/Client4.png + images/closenormal.png + images/closehover.png + images/closepressed.png + images/denied16.png + images/filetype-association.png + images/FileTypeAny.png + images/FileTypeArchive.png + images/FileTypeAudio.png + images/FileTypeCDImage.png + images/FileTypeDocument.png + images/FileTypePicture.png + images/FileTypeProgram.png + images/FileTypeVideo.png + images/fonts.png + images/folder16.png + images/foldermail.png + images/folderopen.png + images/fileopen.png + images/graph-downloaded.png + images/graph-downloading.png + images/graph-notdownload.png + images/graph-checking.png + images/graph-blue.png + images/add-share24.png + images/add_24x24.png + images/advsearch_24x24.png + images/amsn16.png + images/attachment.png + images/avatar_background.png + images/backgroundimage.png + images/button_cancel.png + images/calendar.png + images/chat.png + images/chat_22.png + images/chat_24.png + images/chat_32.png + images/chat_64.png + images/chat_x24.png + images/chat_red24.png + images/cancel.png + images/close-down.png + images/close_normal.png + images/console-small-down.png + images/console-small-hover.png + images/console-small-up.png + images/contact_new128.png + images/copy.png + images/delete.png + images/deleteall.png + images/deletemail-pressed.png + images/deletemail24.png + images/directoryadd_24x24_shadow.png + images/directoryremove_24x24_shadow.png + images/directoryselect_24x24_shadow.png + images/diskSave.png + images/document_save.png + images/down.png + images/down_24x24.png + images/download.png + images/download16.png + images/edit_add24.png + images/edit-bold.png + images/edit-italic.png + images/edit-underline.png + images/edit_remove24.png + images/encrypted16.png + images/encrypted22.png + images/encrypted32.png + images/encrypted48.png + images/disabled_plugin_48.png + images/evolution.png + images/exit_24x24.png + images/exit_32.png + images/expand_frame.png + images/exportpeers_16x16.png + images/extension_32.png + images/filefind.png + images/fileinfo.png + images/filename.png + images/filepriority.png + images/filecomments.png + images/filerating0.png + images/filerating1.png + images/filerating2.png + images/filerating3.png + images/filerating4.png + images/filerating5.png + images/fileshare16.png + images/fileshare24.png + images/fileshare32.png + images/fileshare48.png + images/fileshare64.png + images/find.png + images/find-16.png + images/emoticons/kopete/kopete020.png + images/flags/af.png + images/flags/bg.png + images/flags/zh_CN.png + images/flags/zh_TW.png + images/flags/ca_ES.png + images/flags/cs.png + images/flags/de.png + images/flags/da.png + images/flags/el.png + images/flags/en.png + images/flags/es.png + images/flags/fi.png + images/flags/fr.png + images/flags/hu.png + images/flags/it.png + images/flags/ja_JP.png + images/flags/ko.png + images/flags/nl.png + images/flags/pl.png + images/flags/pt.png + images/flags/ru.png + images/flags/sv.png + images/flags/sl.png + images/flags/tr.png + images/folder-draft.png + images/folder-draft24-pressed.png + images/folder-draft24.png + images/folder_inbox64.png + images/folder-inbox.png + images/folder-inbox-new.png + images/folder-outbox.png + images/folder-sent.png + images/folder-trash.png + images/folder_doments.png + images/folder_green.png + images/folder_red.png + images/folder_grey.png + images/folder_yellow.png + images/folder_open.png + images/folder_video.png + images/folder_blueshared.png + images/forward.png + images/friendsfolder24.png + images/kgames.png + images/go-down.png + images/go-top.png + images/go-up.png + images/go-bottom.png + images/graph-area.png + images/graph-line.png + images/groupchat.png + images/genbackground.png + images/gohome.png + images/gpgp_key_generate.png + images/help.png + images/help24.png + images/hide_toolbox_frame.png + images/hide_frame.png + images/highlight.png + images/hi16-app-ktorrent.png + images/hi24-app-ktorrent.png + images/hot_0.png + images/hot_1.png + images/hot_2.png + images/hot_3.png + images/hot_4.png + images/hot_5.png + images/image16.png + images/imageblocked_24.png + images/info16.png + images/im-user.png + images/im-user-offline.png + images/im-user-away.png + images/im-user-busy.png + images/im-user-inactive.png + images/informations_24x24.png + images/connect_friend.png + images/kalarm.png + images/kbackgammon.png + images/kblogger.png + images/hi48-app-kblogger.png + images/hi64-app-kblogger.png + images/transfers_new.png + images/kcmsystem24.png + images/kdmconfig.png + images/konsole.png + images/newsfeed128.png + images/newsfeed128_notify.png + images/konversation.png + images/konversation16.png + images/konversation128.png + images/konv_message2.png + images/konv_message3.png + images/konv_message64.png + images/konversation64.png + images/forums_new.png + images/ksysguard.png + images/ksysguard32.png + images/ktorrent.png + images/ktorrent32.png + images/knewsticker24.png + images/library.png + images/loadcert16.png + images/ledoff1.png + images/ledon1.png + images/locale.png + images/looknfeel.png + images/lphoto.png + images/lphoto16.png + images/lphoto24.png + images/logo/logo_16.png + images/logo/logo_24.png + images/logo/logo_24_0.png + images/logo/logo_24_1.png + images/logo/logo_24_2.png + images/logo/logo_32.png + images/logo/logo_48.png + images/logo/logo_64.png + images/logo/logo_128.png + images/logo/logo_256.png + images/logo/logo_512.png + images/logo/logo_info.png + images/logo/logo_splash.png + images/logobar/logo_bar_fill.png + images/logobar/logo_bar_start.png + images/logobar/rslogo.png + images/logobar/rslogo2.png + images/mail-message-new.png + images/mail-signed.png + images/mail-signature-unknown.png + images/mail_delete.png + images/mail_get.png + images/mail_reply.png + images/mail_replyall.png + images/mail_forward.png + images/mail_send.png + images/mail_new.png + images/mail_send24.png + images/mailforward24-hover.png + images/message-mail.png + images/message-mail-read.png + images/message-mail-imapdelete.png + images/message-mail-replied-read.png + images/message-mail-forwarded-read.png + images/message-mail-replied.png + images/message-mail-forwarded.png + images/message-mail-replied-forw.png + images/message-mail-replied-forw-read.png + images/message-state-read.png + images/message-state-unread.png + images/message-state-header.png + images/message-state-new.png + images/message-news.png + images/message_new.png + images/message.png + images/messenger.png + images/mute-off-16.png + images/mute-on-16.png + images/my_documents_16.png + images/my_documents_22.png + images/network.png + images/network16.png + images/network32.png + images/new-mail-alert.png + images/new_forum16.png + images/newmsg.png + images/no_avatar_70.png + images/no_avatar_background.png + images/openimage.png + images/office-chart-area-stacked.png + images/office-chart-line.png + images/pasterslink.png + images/package_games1.png + images/pin32.png + images/print24.png + images/priorityauto.png + images/priorityhigh.png + images/prioritylow.png + images/prioritynormal.png + images/pause.png + images/preview.png + images/player_play.png + images/quick_restart24.png + images/quote_24.png + images/redled.png + images/greenled.png + images/grayled.png + images/yellowled.png + images/rate-1.png + images/rate-2.png + images/rate-3.png + images/rate-4.png + images/rate-5.png + images/rating.png + images/records.png + images/replymail-pressed.png + images/replymail24.png + images/replymailall24-hover.png + images/reset.png + images/resume.png + images/security-high-16.png + images/security-high-48.png + images/security-low-48.png + images/security-medium-48.png + images/security-high-off-48.png + images/security-low-off-48.png + images/security-medium-off-48.png + images/save24.png + images/send24.png + images/settings.png + images/settings16.png + images/show_toolbox_frame.png + images/start.png + images/stop.png + images/star-on-16.png + images/star-off-16.png + images/StatsCumulative.png + images/StatisticsDetail.png + images/status_unknown.png + images/startall.png + images/server_24x24.png + images/sort_incr.png + images/sort_decrease.png + images/sound.png + images/tab-dock.png + images/tab-undock.png + images/tab-new.png + images/tag24.png + images/transferupdown.png + images/tools_wizard.png + images/typing.png + images/trustsettings.png + images/uploads.png + images/headerFrame.png + images/loader/indicator-16.gif + images/loader/indicator-32.gif + images/loader/circleball-16.gif + images/loader/progress.gif + images/mimetypes/pdf.png + images/mimetypes/rscollection-16.png + images/mimetypes/patch.png + images/mimetypes/source_c.png + images/mimetypes/source_cpp.png + images/mimetypes/source_h.png + images/view-certificate-copy-32.png + images/view-certificate-export-32.png + images/textedit/textbold.png + images/textedit/textitalic.png + images/textedit/textunder.png + images/textedit/textjustify.png + images/textedit/textcenter.png + images/textedit/textleft.png + images/textedit/textright.png + images/textedit/editcopy.png + images/textedit/editcut.png + images/textedit/editpaste.png + images/textedit/editredo.png + images/textedit/editundo.png + images/textedit/exportpdf.png + images/textedit/filenew.png + images/textedit/fileopen.png + images/textedit/fileprint.png + images/textedit/filesave.png + images/textedit/format-text-color.png + images/textedit/format-list-ordered.png + images/textedit/format-list-unordered.png + images/textedit/zoomin.png + images/textedit/zoomout.png + images/textedit/format_font_size_more.png + images/textedit/format_font_size_less.png + images/textedit/hi22-action-format-text-blockquote.png + images/textedit/hi22-action-format-text-code.png + images/textedit/hi22-action-insert-more-mark.png + images/toaster/chat.png + images/toaster/hangup.png + images/toaster/pickup.png + images/toaster/backgroundtoaster.png + images/thumb-default-video.png + images/user/add_user24.png + images/user/add_user48.png + images/user/remove_user24.png + images/user/deny_user48.png + images/user/friends24.png + images/user/friends32.png + images/user/friends64.png + images/user/friends24_notify.png + images/user/friend_suggestion16.png + images/user/identity16.png + images/user/identity24.png + images/user/identity24_low.png + images/user/identity32.png + images/user/identity48.png + images/user/identityinfo48.png + images/user/identityinfo64.png + images/user/identityoffline24.png + images/user/identity24away.png + images/user/identity24busy.png + images/user/identity24idle.png + images/user/identityavaiblecyan24.png + images/user/invite24.png + images/user/agt_forum24.png + images/user/agt_forum32.png + images/user/identitygray16.png + images/user/add_user16.png + images/user/personal64.png + images/user/personal128.png + images/user/kuser24.png + images/user/agt_forum64.png + images/user/agt_forum128.png + images/user/group16.png + images/user/group24.png + images/user/servicepermissions64.png + images/user/user_request16.png + images/user/user_request48.png + images/user/user_request_unknown48.png + images/up.png + images/up0down0.png + images/up0down1.png + images/up1down1.png + images/up1down0.png + images/underconstruction.png + images/user.png + images/view-certificate-sign-32.png + images/view_calendar_day.png + images/view_calendar_week.png + images/view_calendar_month.png + images/view_calendar_list.png + images/view_split_top_bottom.png + images/vote_up.png + images/vote_down.png + images/vote_neutral.png + images/window_fullscreen.png + images/window_nofullscreen.png + images/identity/identities_32.png + images/identity/identity_64.png + images/identity/identity_create_32.png + images/identity/identity_create_64.png + images/identity/identity_delete_32.png + images/identity/identity_edit_32.png + images/identity/identity_edit_64.png + qss/chat/standard/private/info.xml + qss/chat/standard/private/incoming.htm + qss/chat/standard/private/outgoing.htm + qss/chat/standard/private/hincoming.htm + qss/chat/standard/private/houtgoing.htm + qss/chat/standard/private/ooutgoing.htm + qss/chat/standard/private/system.htm + qss/chat/standard/private/main.css + qss/chat/standard/private/variants/Standard.css + qss/chat/standard/public/info.xml + qss/chat/standard/public/incoming.htm + qss/chat/standard/public/outgoing.htm + qss/chat/standard/public/hincoming.htm + qss/chat/standard/public/houtgoing.htm + qss/chat/standard/public/ooutgoing.htm + qss/chat/standard/public/system.htm + qss/chat/standard/public/main.css + qss/chat/standard/public/variants/Standard.css + qss/chat/standard/history/info.xml + qss/chat/standard/history/incoming.htm + qss/chat/standard/history/outgoing.htm + qss/chat/standard/history/hincoming.htm + qss/chat/standard/history/houtgoing.htm + qss/chat/standard/history/ooutgoing.htm + qss/chat/standard/history/system.htm + qss/chat/standard/history/main.css + qss/chat/standard/history/variants/Standard.css + qss/chat/compact/private/info.xml + qss/chat/compact/private/incoming.htm + qss/chat/compact/private/outgoing.htm + qss/chat/compact/private/hincoming.htm + qss/chat/compact/private/houtgoing.htm + qss/chat/compact/private/ooutgoing.htm + qss/chat/compact/private/system.htm + qss/chat/compact/private/main.css + qss/chat/compact/private/variants/Standard.css + qss/chat/compact/private/variants/Colored.css + qss/chat/compact/public/info.xml + qss/chat/compact/public/incoming.htm + qss/chat/compact/public/outgoing.htm + qss/chat/compact/public/hincoming.htm + qss/chat/compact/public/houtgoing.htm + qss/chat/compact/public/ooutgoing.htm + qss/chat/compact/public/system.htm + qss/chat/compact/public/main.css + qss/chat/compact/public/variants/Standard.css + qss/chat/compact/public/variants/Colored.css + qss/chat/compact/history/info.xml + qss/chat/compact/history/incoming.htm + qss/chat/compact/history/outgoing.htm + qss/chat/compact/history/hincoming.htm + qss/chat/compact/history/houtgoing.htm + qss/chat/compact/history/ooutgoing.htm + qss/chat/compact/history/system.htm + qss/chat/compact/history/main.css + qss/chat/compact/history/variants/Standard.css + qss/chat/compact/history/variants/Colored.css + qss/stylesheet/qss.default + qss/stylesheet/Standard.qss + images/connect/connectFriendWatermark.png + images/connect/connectFriendLogo.png + images/connect/connectFriendBanner.png + images/connect/connectFriendBanner1.png + images/connect/info16.png + images/connect/mail_send.png + images/tags/pgp-known.png + images/tags/pgp-unknown.png + images/tags/anon.png + images/tags/dev-ambassador.png + images/tags/dev-translator.png + images/tags/dev-patcher.png + images/tags/developer.png + images/circles/circles_32.png + images/circles/circles_64.png + images/newsfeed/news-feed-32.png + images/newsfeed/news-feed-notify-32.png + images/share-icon-16.png + help/version.html + images/view-certificate-sign-48.png + images/toasterEnable.png + images/toasterDisable.png + images/library_edit.png + images/library_view.png + images/library_add.png + images/library64.png + images/library16.png + images/btn_red_pressed.png + images/btn_red_hover.png + images/btn_red.png + images/view-feeds.png + images/view-files.png + images/emblem-web.png + images/rsmessenger16.png + images/rsmessenger32.png + images/rsmessenger48.png + images/SmileyText.png + images/SimpleText.png + images/ColoredText.png + diff --git a/retroshare-gui/src/gui/images/cancel.png b/retroshare-gui/src/gui/images/cancel.png index e2db55f22..87cd0b012 100644 Binary files a/retroshare-gui/src/gui/images/cancel.png and b/retroshare-gui/src/gui/images/cancel.png differ diff --git a/retroshare-gui/src/gui/images/logo/logo_spash2.png b/retroshare-gui/src/gui/images/logo/logo_spash2.png new file mode 100644 index 000000000..dab5aa938 Binary files /dev/null and b/retroshare-gui/src/gui/images/logo/logo_spash2.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qss.default b/retroshare-gui/src/gui/qss/stylesheet/qss.default index b762d626a..db24fd45e 100644 --- a/retroshare-gui/src/gui/qss/stylesheet/qss.default +++ b/retroshare-gui/src/gui/qss/stylesheet/qss.default @@ -174,6 +174,7 @@ FriendList SearchDialog { qproperty-textColorLocal: red; + qproperty-textColorDownloading: green; qproperty-textColorNoSources: rgb(0, 0, 19); qproperty-textColorLowSources: rgb(0, 0, 38); qproperty-textColorHighSources: rgb(0, 0, 228); diff --git a/retroshare-gui/src/gui/settings/RelayPage.cpp b/retroshare-gui/src/gui/settings/RelayPage.cpp index 258bc05aa..d26550c8b 100644 --- a/retroshare-gui/src/gui/settings/RelayPage.cpp +++ b/retroshare-gui/src/gui/settings/RelayPage.cpp @@ -29,6 +29,7 @@ #include #include #include +#include "util/misc.h" #include @@ -127,35 +128,37 @@ void RelayPage::load() uint32_t count; uint32_t bandwidth; rsDht->getRelayAllowance(RSDHT_RELAY_CLASS_FRIENDS, count, bandwidth); - ui.noFriendSpinBox->setValue(count); - ui.bandFriendSpinBox->setValue(bandwidth / 1000); + whileBlocking(ui.noFriendSpinBox)->setValue(count); + whileBlocking(ui.bandFriendSpinBox)->setValue(bandwidth / 1024); rsDht->getRelayAllowance(RSDHT_RELAY_CLASS_FOF, count, bandwidth); - ui.noFOFSpinBox->setValue(count); - ui.bandFOFSpinBox->setValue(bandwidth / 1000); + whileBlocking(ui.noFOFSpinBox)->setValue(count); + whileBlocking(ui.bandFOFSpinBox)->setValue(bandwidth / 1024); rsDht->getRelayAllowance(RSDHT_RELAY_CLASS_GENERAL, count, bandwidth); - ui.noGeneralSpinBox->setValue(count); - ui.bandGeneralSpinBox->setValue(bandwidth / 1000); + whileBlocking(ui.noGeneralSpinBox)->setValue(count); + whileBlocking(ui.bandGeneralSpinBox)->setValue(bandwidth / 1024); + + updateTotals(); uint32_t relayMode = rsDht->getRelayMode(); if (relayMode & RSDHT_RELAY_ENABLED) { - ui.enableCheckBox->setCheckState(Qt::Checked); + whileBlocking(ui.enableCheckBox)->setCheckState(Qt::Checked); if ((relayMode & RSDHT_RELAY_MODE_MASK) == RSDHT_RELAY_MODE_OFF) { - ui.serverCheckBox->setCheckState(Qt::Unchecked); + whileBlocking(ui.serverCheckBox)->setCheckState(Qt::Unchecked); } else { - ui.serverCheckBox->setCheckState(Qt::Checked); + whileBlocking(ui.serverCheckBox)->setCheckState(Qt::Checked); } } else { - ui.enableCheckBox->setCheckState(Qt::Unchecked); - ui.serverCheckBox->setCheckState(Qt::Unchecked); + whileBlocking(ui.enableCheckBox)->setCheckState(Qt::Unchecked); + whileBlocking(ui.serverCheckBox)->setCheckState(Qt::Unchecked); } loadServers(); diff --git a/retroshare-gui/src/gui/settings/ServerPage.cpp b/retroshare-gui/src/gui/settings/ServerPage.cpp index 4357f0d2c..d9dd900fb 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.cpp +++ b/retroshare-gui/src/gui/settings/ServerPage.cpp @@ -109,7 +109,7 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) connect( ui.netModeComboBox, SIGNAL( activated ( int ) ), this, SLOT( toggleUPnP( ) ) ); connect( ui.allowIpDeterminationCB, SIGNAL( toggled( bool ) ), this, SLOT( toggleIpDetermination(bool) ) ); connect( ui.cleanKnownIPs_PB, SIGNAL( clicked( ) ), this, SLOT( clearKnownAddressList() ) ); - connect( ui.testIncoming_PB, SIGNAL( clicked( ) ), this, SLOT( updateInProxyIndicator() ) ); + connect( ui.testIncoming_PB, SIGNAL( clicked( ) ), this, SLOT( saveAndTestInProxy() ) ); connect( ui.showDiscStatusBar,SIGNAL(toggled(bool)),this,SLOT(updateShowDiscStatusBar())) ; #ifdef SERVER_DEBUG @@ -132,6 +132,12 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) connect(ui.totalUploadRate, SIGNAL(valueChanged(int)),this,SLOT(saveRates())); } +void ServerPage::saveAndTestInProxy() +{ + saveAddresses(); + updateInProxyIndicator() ; +} + void ServerPage::checkIpRange(const QString& ipstr) { QColor color; diff --git a/retroshare-gui/src/gui/settings/ServerPage.h b/retroshare-gui/src/gui/settings/ServerPage.h index 02685bfc0..5b300e084 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.h +++ b/retroshare-gui/src/gui/settings/ServerPage.h @@ -61,6 +61,7 @@ private slots: // ban list void updateSelectedBlackListIP(int row, int, int, int); void updateSelectedWhiteListIP(int row,int,int,int); + void saveAndTestInProxy(); void addIpRangeToBlackList(); void addIpRangeToWhiteList(); void moveToWhiteList0(); diff --git a/retroshare-gui/src/gui/settings/ServerPage.ui b/retroshare-gui/src/gui/settings/ServerPage.ui index 3755b0536..a0f16a62b 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.ui +++ b/retroshare-gui/src/gui/settings/ServerPage.ui @@ -26,7 +26,7 @@ - 0 + 2 @@ -985,7 +985,7 @@ You can connect to Hidden Nodes, even if you are running a standard Node, so why <html><head/><body><p>This button simulates a SSL connection to your hidden address using the corresponding proxy. If your hidden node is reachable, it should cause a SSL handshake error, which RS will interpret as a valid connection state. This operation might also cause several &quot;security warning&quot; about connections from your local host IP (127.0.0.1) in the News Feed if you enabled it, which you should interpret as a sign of good communication.</p></body></html> - Test + Apply diff --git a/retroshare-gui/src/gui/statistics/BWGraph.cpp b/retroshare-gui/src/gui/statistics/BWGraph.cpp index 08c208868..a7451c560 100644 --- a/retroshare-gui/src/gui/statistics/BWGraph.cpp +++ b/retroshare-gui/src/gui/statistics/BWGraph.cpp @@ -107,16 +107,25 @@ void BWGraphSource::update() // remove empty lists + float duration = 0.0f; + for(std::map > >::iterator it=_points.begin();it!=_points.end();) if(it->second.empty()) - { - std::map > >::iterator tmp(it) ; - ++tmp; - _points.erase(it) ; - it=tmp ; - } + { + std::map > >::iterator tmp(it) ; + ++tmp; + _points.erase(it) ; + it=tmp ; + } else + { + float d = it->second.back().first - it->second.front().first; + + if(duration < d) + duration = d ; + ++it ; + } // also clears history @@ -138,11 +147,36 @@ void BWGraphSource::update() break ; } + // now update the totals, and possibly convert into an average if the unit requires it. + + updateTotals(); + + if(_current_unit == UNIT_KILOBYTES) + for(std::map::iterator it(_totals.begin());it!=_totals.end();++it) + it->second /= (duration/1000.0) ; + #ifdef BWGRAPH_DEBUG std::cerr << "Traffic history has size " << mTrafficHistory.size() << std::endl; #endif } +std::string BWGraphSource::makeSubItemName(uint16_t service_id,uint8_t sub_item_type) const +{ + RsServiceInfoWithNames& s(mServiceInfoMap[service_id]) ; + + if(s.item_names.empty()) + return "item #"+QString("%1").arg(sub_item_type,2,16,QChar('0')).toStdString() ; + else + { + std::map::const_iterator it = s.item_names.find(sub_item_type) ; + + if(it == s.item_names.end()) + return "item #"+QString("%1").arg(sub_item_type,2,16,QChar('0')).toStdString() + " (undocumented)"; + + return QString("%1").arg(sub_item_type,2,16,QChar('0')).toStdString()+": " + it->second ; + } +} + void BWGraphSource::convertTrafficClueToValues(const std::list& lst,std::map& vals) const { vals.clear() ; @@ -162,7 +196,7 @@ void BWGraphSource::convertTrafficClueToValues(const std::list& l for(uint32_t i=0;i<256;++i) if(clue_per_sub_id[i].count > 0) - vals["item #"+QString::number(i,16).toStdString()] = (_current_unit == UNIT_KILOBYTES)?(clue_per_sub_id[i].size):(clue_per_sub_id[i].count) ; + vals[makeSubItemName(clue_per_sub_id[i].service_id,i)] = (_current_unit == UNIT_KILOBYTES)?(clue_per_sub_id[i].size):(clue_per_sub_id[i].count) ; } break ; @@ -233,11 +267,14 @@ void BWGraphSource::convertTrafficClueToValues(const std::list& l for(std::list::const_iterator it(lst.begin());it!=lst.end();++it) if(it->service_id == _current_selected_service) + { clue_per_sub_id[it->service_sub_id] += *it ; + clue_per_sub_id[it->service_sub_id].service_id = it->service_id ; + } for(uint32_t i=0;i<256;++i) if(clue_per_sub_id[i].count > 0) - vals["item #"+QString::number(i,16).toStdString()] = (_current_unit == UNIT_KILOBYTES)?(clue_per_sub_id[i].size):(clue_per_sub_id[i].count) ; + vals[makeSubItemName(clue_per_sub_id[i].service_id,i)] = (_current_unit == UNIT_KILOBYTES)?(clue_per_sub_id[i].size):(clue_per_sub_id[i].count) ; } break ; @@ -297,7 +334,11 @@ BWGraphSource::BWGraphSource() rsServiceControl->getOwnServices(rspsi) ; for(std::map::const_iterator it(rspsi.mServiceList.begin());it!=rspsi.mServiceList.end();++it) + { mServiceInfoMap[ (it->first >> 8) & 0xffff ] = it->second ; + + rsServiceControl->getServiceItemNames(it->first,mServiceInfoMap[(it->first >> 8) & 0xffff].item_names) ; + } } void BWGraphSource::getValues(std::map& values) const @@ -359,9 +400,9 @@ QString BWGraphSource::displayValue(float v) const return QString() ; } -QString BWGraphSource::legend(int i,float v) const +QString BWGraphSource::legend(int i,float v,bool show_value) const { - return RSGraphSource::legend(i,v) ;//+ " Total: " + niceNumber(_total_recv) ; + return RSGraphSource::legend(i,v,show_value) ; } QString BWGraphSource::niceNumber(float v) const { @@ -446,6 +487,7 @@ void BWGraphSource::setUnit(int unit) recomputeCurrentCurves() ; } + void BWGraphSource::setDirection(int dir) { if(dir == _current_direction) diff --git a/retroshare-gui/src/gui/statistics/BWGraph.h b/retroshare-gui/src/gui/statistics/BWGraph.h index 865893473..3e2c4b8b2 100644 --- a/retroshare-gui/src/gui/statistics/BWGraph.h +++ b/retroshare-gui/src/gui/statistics/BWGraph.h @@ -13,6 +13,14 @@ public: std::list out_rstcl ; std::list in_rstcl ; }; + class RsServiceInfoWithNames: public RsServiceInfo + { + public: + RsServiceInfoWithNames(const RsServiceInfo& s) : RsServiceInfo(s) {} + RsServiceInfoWithNames(){} + + std::map item_names ; + }; BWGraphSource() ; @@ -25,7 +33,7 @@ public: virtual void getValues(std::map& values) const; virtual QString displayValue(float v) const; - virtual QString legend(int i,float v) const; + virtual QString legend(int i,float v,bool show_value=true) const; virtual void update(); QString unitName() const ; @@ -45,6 +53,7 @@ public: protected: void convertTrafficClueToValues(const std::list &lst, std::map &vals) const; + std::string makeSubItemName(uint16_t service_id,uint8_t sub_item_type) const; void recomputeCurrentCurves() ; std::string visibleFriendName(const RsPeerId &pid) const ; @@ -67,7 +76,7 @@ private: std::map mVisibleFriends ; std::set mVisibleServices ; - mutable std::map mServiceInfoMap ; + mutable std::map mServiceInfoMap ; }; class BWGraph: public RSGraphWidget diff --git a/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.cpp b/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.cpp index b3fd9a063..6ae112803 100644 --- a/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.cpp +++ b/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.cpp @@ -28,13 +28,18 @@ BandwidthStatsWidget::BandwidthStatsWidget(QWidget *parent) ui.bwgraph_BW->setSelector(BWGraphSource::SELECTOR_TYPE_SERVICE,BWGraphSource::GRAPH_TYPE_SUM) ; ui.bwgraph_BW->setUnit(BWGraphSource::UNIT_KILOBYTES) ; + ui.bwgraph_BW->resetFlags(RSGraphWidget::RSGRAPH_FLAGS_LEGEND_CUMULATED) ; + + updateUnitSelection(0); + // Setup connections - QObject::connect(ui.friend_CB ,SIGNAL(currentIndexChanged(int)),this, SLOT( updateFriendSelection(int))) ; - QObject::connect(ui.updn_CB ,SIGNAL(currentIndexChanged(int)),this, SLOT( updateUpDownSelection(int))) ; - QObject::connect(ui.unit_CB ,SIGNAL(currentIndexChanged(int)),this, SLOT( updateUnitSelection(int))) ; - QObject::connect(ui.service_CB,SIGNAL(currentIndexChanged(int)),this, SLOT(updateServiceSelection(int))) ; - QObject::connect(ui.logScale_CB,SIGNAL(toggled(bool)),this, SLOT(toggleLogScale(bool))) ; + QObject::connect(ui.friend_CB ,SIGNAL(currentIndexChanged(int )),this, SLOT( updateFriendSelection(int ))) ; + QObject::connect(ui.updn_CB ,SIGNAL(currentIndexChanged(int )),this, SLOT( updateUpDownSelection(int ))) ; + QObject::connect(ui.unit_CB ,SIGNAL(currentIndexChanged(int )),this, SLOT( updateUnitSelection(int ))) ; + QObject::connect(ui.service_CB ,SIGNAL(currentIndexChanged(int )),this, SLOT(updateServiceSelection(int ))) ; + QObject::connect(ui.legend_CB ,SIGNAL(currentIndexChanged(int )),this, SLOT( updateLegendType(int ))) ; + QObject::connect(ui.logScale_CB,SIGNAL( toggled(bool)),this, SLOT( toggleLogScale(bool))) ; // setup one timer for auto-update @@ -156,6 +161,13 @@ void BandwidthStatsWidget::updateFriendSelection(int n) ui.bwgraph_BW->setSelector(BWGraphSource::SELECTOR_TYPE_FRIEND,BWGraphSource::GRAPH_TYPE_SINGLE,ui.friend_CB->itemData(ci,Qt::UserRole).toString().toStdString()) ; } } +void BandwidthStatsWidget::updateLegendType(int n) +{ + if(n==0) + ui.bwgraph_BW->resetFlags(RSGraphWidget::RSGRAPH_FLAGS_LEGEND_CUMULATED) ; + else + ui.bwgraph_BW->setFlags(RSGraphWidget::RSGRAPH_FLAGS_LEGEND_CUMULATED) ; +} void BandwidthStatsWidget::updateServiceSelection(int n) { if(n == 0) @@ -187,7 +199,13 @@ void BandwidthStatsWidget::updateUpDownSelection(int n) void BandwidthStatsWidget::updateUnitSelection(int n) { if(n==0) + { ui.bwgraph_BW->setUnit(BWGraphSource::UNIT_KILOBYTES) ; + ui.legend_CB->setItemText(1,tr("Average")); + } else + { ui.bwgraph_BW->setUnit(BWGraphSource::UNIT_COUNT) ; + ui.legend_CB->setItemText(1,tr("Total")); + } } diff --git a/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.h b/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.h index 9a835fc57..055555f73 100644 --- a/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.h +++ b/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.h @@ -15,7 +15,8 @@ protected slots: void updateUpDownSelection(int n); void updateUnitSelection(int n); void toggleLogScale(bool b); - + void updateLegendType(int n); + private: Ui::BwStatsWidget ui; diff --git a/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.ui b/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.ui index e99058ac3..fdfefb99b 100644 --- a/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.ui +++ b/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.ui @@ -6,7 +6,7 @@ 0 0 - 1128 + 1148 385 @@ -14,7 +14,16 @@ Form - + + 0 + + + 0 + + + 0 + + 0 @@ -103,6 +112,27 @@ + + + + Legend: + + + + + + + + Current + + + + + Total + + + + diff --git a/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp b/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp index a309717b8..a8e830624 100644 --- a/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp +++ b/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp @@ -379,7 +379,7 @@ void GlobalRouterStatisticsWidget::updateContent() painter.setPen(QColor::fromRgb(0,0,0)) ; - painter.setPen(QColor::fromRgb(0.5,0.5,0.5)); + painter.setPen(QColor::fromRgb(127,127,127)); painter.drawRect(ox+2*cellx,current_oy+0.15*celly,fm_monospace.width(ids)+cellx*matrix_info.friend_ids.size()- 2*cellx,celly) ; float total_length = (matrix_info.friend_ids.size()+2)*cellx ; diff --git a/retroshare-gui/src/gui/statistics/TurtleRouterDialog.cpp b/retroshare-gui/src/gui/statistics/TurtleRouterDialog.cpp index 6d8a46e32..a76b5b5c3 100644 --- a/retroshare-gui/src/gui/statistics/TurtleRouterDialog.cpp +++ b/retroshare-gui/src/gui/statistics/TurtleRouterDialog.cpp @@ -153,7 +153,7 @@ void TurtleRouterDialog::updateTunnelRequests( const std::vectorsetFont(0,font); } - if(strtol(tunnels_info[i][5].c_str(), NULL, 0)>1000) // fast + if(strtof(tunnels_info[i][5].c_str(), NULL)>1000) // fast { font.setBold(true); item->setFont(0,font); diff --git a/retroshare-gui/src/retroshare-gui.pro b/retroshare-gui/src/retroshare-gui.pro index 9e2951f87..6c4fdeb67 100644 --- a/retroshare-gui/src/retroshare-gui.pro +++ b/retroshare-gui/src/retroshare-gui.pro @@ -5,7 +5,7 @@ QT += network xml CONFIG += qt gui uic qrc resources idle bitdht CONFIG += link_prl TARGET = RetroShare06 -DEFINES += TARGET=\\\"$TARGET\\\" +DEFINES += TARGET=\\\"$${TARGET}\\\" # Plz never commit the .pro with these flags enabled. # Use this flag when developping new features only. diff --git a/retroshare-gui/src/rshare.cpp b/retroshare-gui/src/rshare.cpp index a2de0840a..040992afe 100644 --- a/retroshare-gui/src/rshare.cpp +++ b/retroshare-gui/src/rshare.cpp @@ -68,6 +68,17 @@ #define ARG_RSFILE_L "rsfile" /**< Open RsFile with or without arg */ //Other defined for server in /libretroshare/src/rsserver/rsinit.cc:351 +// The arguments here can be send to a running instance. +// If the command line contains arguments not listed here, we have to start a new instance. +// For exmample, the user wants to start a second instance using --base-dir arg of libretroshare. +static const char* const forwardableArgs[] = { + ARG_RSLINK_S, + ARG_RSLINK_L, + ARG_RSFILE_S, + ARG_RSFILE_L, + NULL, +}; + /* Static member variables */ QMap Rshare::_args; /**< List of command-line arguments. */ QString Rshare::_style; /**< The current GUI style. */ @@ -115,6 +126,27 @@ void qt_msg_handler(QtMsgType type, const char *msg) } } +static bool notifyRunningInstance() +{ + // Connect to the Local Server of the main process to notify it + // that a new process had been started + QLocalSocket localSocket; + localSocket.connectToServer(QString(TARGET)); + + std::cerr << "Rshare::Rshare waitForConnected to other instance." << std::endl; + if( localSocket.waitForConnected(100) ) + { + std::cerr << "Rshare::Rshare Connection etablished. Waiting for disconnection." << std::endl; + localSocket.waitForDisconnected(1000); + return true; + } + else + { + std::cerr << "Rshare::Rshare failed to connect to other instance." << std::endl; + return false; + } +} + /** Constructor. Parses the command-line arguments, resets Rshare's * configuration (if requested), and sets up the GUI style and language * translation. */ @@ -128,7 +160,32 @@ Rshare::Rshare(QStringList args, int &argc, char **argv, const QString &dir) { QString serverName = QString(TARGET); - if (!args.isEmpty()) { + // check if another instance is running + bool haveRunningInstance = notifyRunningInstance(); + + bool sendArgsToRunningInstance = haveRunningInstance; + if(args.empty()) + sendArgsToRunningInstance = false; + // if we find non-forwardable args, start a new instance + for(int i = 0; i < args.size(); ++i) + { + const char* const* argit = forwardableArgs; + bool found = false; + while(*argit && i < args.size()) + { + if(args.value(i) == "-"+QString(*argit) || args.value(i) == "--"+QString(*argit)) + { + found = true; + if(argNeedsValue(*argit)) + i++; + } + argit++; + } + if(!found) + sendArgsToRunningInstance = false; + } + + if (sendArgsToRunningInstance) { // load into shared memory QBuffer buffer; buffer.open(QBuffer::ReadWrite); @@ -156,30 +213,29 @@ Rshare::Rshare(QStringList args, int &argc, char **argv, const QString &dir) memcpy(to, from, qMin(newArgs.size(), size)); newArgs.unlock(); - // Connect to the Local Server of the main process to notify it - // that a new process had been started - QLocalSocket localSocket; - localSocket.connectToServer(QString(TARGET)); - std::cerr << "Rshare::Rshare waitForConnected to other instance." << std::endl; - if( localSocket.waitForConnected(100) ) + if(notifyRunningInstance()) { - std::cerr << "Rshare::Rshare Connection etablished. Waiting for disconnection." << std::endl; - localSocket.waitForDisconnected(1000); newArgs.detach(); std::cerr << "Rshare::Rshare Arguments was sended." << std::endl << " To disable it, in Options - General - Misc," << std::endl << " uncheck \"Use Local Server to get new Arguments\"." << std::endl; ::exit(EXIT_SUCCESS); // Terminate the program using STDLib's exit function } + else + std::cerr << "Rshare::Rshare failed to connect to other instance." << std::endl; newArgs.detach(); } - // No main process exists - // Or started without arguments - // So we start a Local Server to listen for connections from new process - localServer= new QLocalServer(); - QObject::connect(localServer, SIGNAL(newConnection()), this, SLOT(slotConnectionEstablished())); - updateLocalServer(); + + if(!haveRunningInstance) + { + // No main process exists + // Or started without arguments + // So we start a Local Server to listen for connections from new process + localServer= new QLocalServer(); + QObject::connect(localServer, SIGNAL(newConnection()), this, SLOT(slotConnectionEstablished())); + updateLocalServer(); + } } #if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0) diff --git a/retroshare-gui/src/util/HandleRichText.cpp b/retroshare-gui/src/util/HandleRichText.cpp index 73801bd5b..96fd36d73 100644 --- a/retroshare-gui/src/util/HandleRichText.cpp +++ b/retroshare-gui/src/util/HandleRichText.cpp @@ -230,12 +230,13 @@ bool RsHtml::canReplaceAnchor(QDomDocument &/*doc*/, QDomElement &/*element*/, c case RetroShareLink::TYPE_PERSON: case RetroShareLink::TYPE_FORUM: case RetroShareLink::TYPE_CHANNEL: - case RetroShareLink::TYPE_POSTED: case RetroShareLink::TYPE_SEARCH: case RetroShareLink::TYPE_MESSAGE: case RetroShareLink::TYPE_EXTRAFILE: case RetroShareLink::TYPE_PRIVATE_CHAT: case RetroShareLink::TYPE_PUBLIC_MSG: + case RetroShareLink::TYPE_POSTED: + case RetroShareLink::TYPE_IDENTITY: // not yet implemented break; @@ -259,12 +260,13 @@ void RsHtml::anchorStylesheetForImg(QDomDocument &/*doc*/, QDomElement &/*elemen case RetroShareLink::TYPE_PERSON: case RetroShareLink::TYPE_FORUM: case RetroShareLink::TYPE_CHANNEL: - case RetroShareLink::TYPE_POSTED: case RetroShareLink::TYPE_SEARCH: case RetroShareLink::TYPE_MESSAGE: case RetroShareLink::TYPE_EXTRAFILE: case RetroShareLink::TYPE_PRIVATE_CHAT: case RetroShareLink::TYPE_PUBLIC_MSG: + case RetroShareLink::TYPE_POSTED: + case RetroShareLink::TYPE_IDENTITY: // not yet implemented break; diff --git a/retroshare.pri b/retroshare.pri index 498131aea..e27348311 100644 --- a/retroshare.pri +++ b/retroshare.pri @@ -29,6 +29,11 @@ retroshare_qml_app:CONFIG -= no_retroshare_qml_app CONFIG *= no_libresapilocalserver libresapilocalserver:CONFIG -= no_libresapilocalserver +# To enable Qt dependencies in libresapi append the following +# assignation to qmake command line "CONFIG+=qt_dependencies" +CONFIG *= no_qt_dependencies +qt_dependencies:CONFIG -= no_qt_dependencies + # To disable libresapi via HTTP (based on libmicrohttpd) append the following # assignation to qmake command line "CONFIG+=no_libresapihttpserver" CONFIG *= libresapihttpserver @@ -155,6 +160,7 @@ unfinished { wikipoos:DEFINES *= RS_USE_WIKI rs_gxs:DEFINES *= RS_ENABLE_GXS libresapilocalserver:DEFINES *= LIBRESAPI_LOCAL_SERVER +qt_dependencies:DEFINES *= LIBRESAPI_QT libresapihttpserver:DEFINES *= ENABLE_WEBUI sqlcipher:DEFINES -= NO_SQLCIPHER no_sqlcipher:DEFINES *= NO_SQLCIPHER diff --git a/tests/unittests/libretroshare/gxs/nxs_test/nxstesthub.cc b/tests/unittests/libretroshare/gxs/nxs_test/nxstesthub.cc index 216f971c1..36b288341 100644 --- a/tests/unittests/libretroshare/gxs/nxs_test/nxstesthub.cc +++ b/tests/unittests/libretroshare/gxs/nxs_test/nxstesthub.cc @@ -53,6 +53,7 @@ public: { return recvItem(i); } + bool getServiceItemNames(uint32_t /*service_type*/, std::map& /*names*/) { return false; } private: RsPeerId mPeerId; RecvPeerItemIface* mRecvIface;