mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-10 10:05:19 -04:00
Merge branch 'master' into Fix_ClangWarnings
This commit is contained in:
commit
9102a698e4
66 changed files with 2471 additions and 559 deletions
661
LICENSE.AGPL.txt
Normal file
661
LICENSE.AGPL.txt
Normal file
|
@ -0,0 +1,661 @@
|
||||||
|
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 19 November 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU Affero General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works, specifically designed to ensure
|
||||||
|
cooperation with the community in the case of network server software.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
our General Public Licenses are intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
Developers that use our General Public Licenses protect your rights
|
||||||
|
with two steps: (1) assert copyright on the software, and (2) offer
|
||||||
|
you this License which gives you legal permission to copy, distribute
|
||||||
|
and/or modify the software.
|
||||||
|
|
||||||
|
A secondary benefit of defending all users' freedom is that
|
||||||
|
improvements made in alternate versions of the program, if they
|
||||||
|
receive widespread use, become available for other developers to
|
||||||
|
incorporate. Many developers of free software are heartened and
|
||||||
|
encouraged by the resulting cooperation. However, in the case of
|
||||||
|
software used on network servers, this result may fail to come about.
|
||||||
|
The GNU General Public License permits making a modified version and
|
||||||
|
letting the public access it on a server without ever releasing its
|
||||||
|
source code to the public.
|
||||||
|
|
||||||
|
The GNU Affero General Public License is designed specifically to
|
||||||
|
ensure that, in such cases, the modified source code becomes available
|
||||||
|
to the community. It requires the operator of a network server to
|
||||||
|
provide the source code of the modified version running there to the
|
||||||
|
users of that server. Therefore, public use of a modified version, on
|
||||||
|
a publicly accessible server, gives the public access to the source
|
||||||
|
code of the modified version.
|
||||||
|
|
||||||
|
An older license, called the Affero General Public License and
|
||||||
|
published by Affero, was designed to accomplish similar goals. This is
|
||||||
|
a different license, not a version of the Affero GPL, but Affero has
|
||||||
|
released a new version of the Affero GPL which permits relicensing under
|
||||||
|
this license.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, if you modify the
|
||||||
|
Program, your modified version must prominently offer all users
|
||||||
|
interacting with it remotely through a computer network (if your version
|
||||||
|
supports such interaction) an opportunity to receive the Corresponding
|
||||||
|
Source of your version by providing access to the Corresponding Source
|
||||||
|
from a network server at no charge, through some standard or customary
|
||||||
|
means of facilitating copying of software. This Corresponding Source
|
||||||
|
shall include the Corresponding Source for any work covered by version 3
|
||||||
|
of the GNU General Public License that is incorporated pursuant to the
|
||||||
|
following paragraph.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the work with which it is combined will remain governed by version
|
||||||
|
3 of the GNU General Public License.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU Affero General Public License from time to time. Such new versions
|
||||||
|
will be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU Affero General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU Affero General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU Affero General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If your software can interact with users remotely through a computer
|
||||||
|
network, you should also make sure that it provides a way for users to
|
||||||
|
get its source. For example, if your program is a web application, its
|
||||||
|
interface could display a "Source" link that leads users to an archive
|
||||||
|
of the code. There are many ways you could offer source, and different
|
||||||
|
solutions will be better for different programs; see section 13 for the
|
||||||
|
specific requirements.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||||
|
<https://www.gnu.org/licenses/>.
|
|
@ -8,7 +8,7 @@ Build Status
|
||||||
| Platform | Build Status |
|
| Platform | Build Status |
|
||||||
| :------------- | :------------- |
|
| :------------- | :------------- |
|
||||||
| GNU/Linux, MacOS, (via travis-ci) | [](https://travis-ci.org/RetroShare/RetroShare) |
|
| GNU/Linux, MacOS, (via travis-ci) | [](https://travis-ci.org/RetroShare/RetroShare) |
|
||||||
| Windows, `MSys2` (via appveyor) | [](https://ci.appveyor.com/project/G10h4ck/retroshare-u4lmn) |
|
| Windows, `MSys2` (via appveyor) | [](https://ci.appveyor.com/project/RetroShare58622/retroshare) |
|
||||||
|
|
||||||
Compilation on Windows
|
Compilation on Windows
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
|
@ -85,7 +85,8 @@ environment:
|
||||||
# - cmd: echo This is batch again
|
# - cmd: echo This is batch again
|
||||||
# - cmd: set MY_VAR=12345
|
# - cmd: set MY_VAR=12345
|
||||||
install:
|
install:
|
||||||
- git submodule update --init
|
# We cannot get OBS submodule as it use illegal folder name for windows.
|
||||||
|
#- git submodule update --init
|
||||||
# Configuring MSys2
|
# Configuring MSys2
|
||||||
- set PATH=C:\msys64\usr\bin;%PATH%
|
- set PATH=C:\msys64\usr\bin;%PATH%
|
||||||
- set PATH=C:\msys64\mingw32\bin;%PATH%
|
- set PATH=C:\msys64\mingw32\bin;%PATH%
|
||||||
|
@ -195,11 +196,13 @@ after_build:
|
||||||
- windeployqt %RS_DEPLOY%\retroshare.exe
|
- windeployqt %RS_DEPLOY%\retroshare.exe
|
||||||
|
|
||||||
- copy C:\msys64\mingw32\bin\libbz2*.dll %RS_DEPLOY%\
|
- copy C:\msys64\mingw32\bin\libbz2*.dll %RS_DEPLOY%\
|
||||||
- copy C:\msys64\mingw32\bin\libeay32.dll %RS_DEPLOY%\
|
#- copy C:\msys64\mingw32\bin\libeay32.dll %RS_DEPLOY%\
|
||||||
|
- copy C:\OpenSSL-Win32\libeay32.dll %RS_DEPLOY%\
|
||||||
- copy C:\msys64\mingw32\bin\libminiupnpc.dll %RS_DEPLOY%\
|
- copy C:\msys64\mingw32\bin\libminiupnpc.dll %RS_DEPLOY%\
|
||||||
- copy C:\msys64\mingw32\bin\libsqlcipher*.dll %RS_DEPLOY%\
|
- copy C:\msys64\mingw32\bin\libsqlcipher*.dll %RS_DEPLOY%\
|
||||||
- copy C:\msys64\mingw32\bin\libsqlite3*.dll %RS_DEPLOY%\
|
- copy C:\msys64\mingw32\bin\libsqlite3*.dll %RS_DEPLOY%\
|
||||||
- copy C:\msys64\mingw32\bin\ssleay32.dll %RS_DEPLOY%\
|
#- copy C:\msys64\mingw32\bin\ssleay32.dll %RS_DEPLOY%\
|
||||||
|
- copy C:\OpenSSL-Win32\ssleay32.dll %RS_DEPLOY%\
|
||||||
- copy C:\msys64\mingw32\bin\zlib*.dll %RS_DEPLOY%\
|
- copy C:\msys64\mingw32\bin\zlib*.dll %RS_DEPLOY%\
|
||||||
- copy C:\msys64\mingw32\bin\libgcc_s_dw2*.dll %RS_DEPLOY%\
|
- copy C:\msys64\mingw32\bin\libgcc_s_dw2*.dll %RS_DEPLOY%\
|
||||||
- copy C:\msys64\mingw32\bin\libstdc*.dll %RS_DEPLOY%\
|
- copy C:\msys64\mingw32\bin\libstdc*.dll %RS_DEPLOY%\
|
||||||
|
|
|
@ -133,12 +133,7 @@ void HashStorage::data_tick()
|
||||||
|
|
||||||
if(!mChanged) // otherwise it might prevent from saving the hash cache
|
if(!mChanged) // otherwise it might prevent from saving the hash cache
|
||||||
{
|
{
|
||||||
std::cerr << "Stopping hashing thread." << std::endl;
|
stopHashThread();
|
||||||
shutdown();
|
|
||||||
mRunning = false ;
|
|
||||||
mTotalSizeToHash = 0;
|
|
||||||
mTotalFilesToHash = 0;
|
|
||||||
std::cerr << "done." << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RsServer::notify()->notifyHashingInfo(NOTIFY_HASHTYPE_FINISH, "") ;
|
RsServer::notify()->notifyHashingInfo(NOTIFY_HASHTYPE_FINISH, "") ;
|
||||||
|
@ -262,10 +257,12 @@ bool HashStorage::requestHash(const std::string& full_path,uint64_t size,rstime_
|
||||||
it->second.time_stamp = now ;
|
it->second.time_stamp = now ;
|
||||||
|
|
||||||
#ifdef WINDOWS_SYS
|
#ifdef WINDOWS_SYS
|
||||||
if(it->second.time_stamp != (uint64_t)mod_time)
|
if(it->second.modf_stamp != (uint64_t)mod_time)
|
||||||
{
|
{
|
||||||
std::cerr << "(WW) detected a 1 hour shift in file modification time. This normally happens to many files at once, when daylight saving time shifts (file=\"" << full_path << "\")." << std::endl;
|
std::cerr << "(WW) detected a 1 hour shift in file modification time. This normally happens to many files at once, when daylight saving time shifts (file=\"" << full_path << "\")." << std::endl;
|
||||||
it->second.time_stamp = (uint64_t)mod_time;
|
it->second.modf_stamp = (uint64_t)mod_time;
|
||||||
|
mChanged = true;
|
||||||
|
startHashThread();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -301,6 +298,13 @@ bool HashStorage::requestHash(const std::string& full_path,uint64_t size,rstime_
|
||||||
mTotalSizeToHash += size ;
|
mTotalSizeToHash += size ;
|
||||||
++mTotalFilesToHash;
|
++mTotalFilesToHash;
|
||||||
|
|
||||||
|
startHashThread();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HashStorage::startHashThread()
|
||||||
|
{
|
||||||
if(!mRunning)
|
if(!mRunning)
|
||||||
{
|
{
|
||||||
mRunning = true ;
|
mRunning = true ;
|
||||||
|
@ -310,8 +314,19 @@ bool HashStorage::requestHash(const std::string& full_path,uint64_t size,rstime_
|
||||||
|
|
||||||
start("fs hash cache") ;
|
start("fs hash cache") ;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
void HashStorage::stopHashThread()
|
||||||
|
{
|
||||||
|
if (mRunning)
|
||||||
|
{
|
||||||
|
std::cerr << "Stopping hashing thread." << std::endl;
|
||||||
|
shutdown();
|
||||||
|
mRunning = false ;
|
||||||
|
mTotalSizeToHash = 0;
|
||||||
|
mTotalFilesToHash = 0;
|
||||||
|
std::cerr << "done." << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HashStorage::clean()
|
void HashStorage::clean()
|
||||||
|
|
|
@ -97,6 +97,9 @@ private:
|
||||||
*/
|
*/
|
||||||
void clean() ;
|
void clean() ;
|
||||||
|
|
||||||
|
void startHashThread();
|
||||||
|
void stopHashThread();
|
||||||
|
|
||||||
// loading/saving the entire hash database to a file
|
// loading/saving the entire hash database to a file
|
||||||
|
|
||||||
void locked_save() ;
|
void locked_save() ;
|
||||||
|
|
|
@ -692,6 +692,20 @@ void p3GxsTunnelService::receiveTurtleData(const RsTurtleGenericTunnelItem *gite
|
||||||
(void) direction;
|
(void) direction;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void *data_bytes;
|
||||||
|
uint32_t data_size ;
|
||||||
|
bool accept_fast_items = false;
|
||||||
|
|
||||||
|
const RsTurtleGenericFastDataItem *fitem = dynamic_cast<const RsTurtleGenericFastDataItem*>(gitem) ;
|
||||||
|
|
||||||
|
if(fitem != NULL)
|
||||||
|
{
|
||||||
|
data_bytes = fitem->data_bytes ;
|
||||||
|
data_size = fitem->data_size ;
|
||||||
|
accept_fast_items = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
const RsTurtleGenericDataItem *item = dynamic_cast<const RsTurtleGenericDataItem*>(gitem) ;
|
const RsTurtleGenericDataItem *item = dynamic_cast<const RsTurtleGenericDataItem*>(gitem) ;
|
||||||
|
|
||||||
if(item == NULL)
|
if(item == NULL)
|
||||||
|
@ -699,15 +713,19 @@ void p3GxsTunnelService::receiveTurtleData(const RsTurtleGenericTunnelItem *gite
|
||||||
std::cerr << "(EE) item is not a data item. That is an error." << std::endl;
|
std::cerr << "(EE) item is not a data item. That is an error." << std::endl;
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
data_bytes = item->data_bytes ;
|
||||||
|
data_size = item->data_size ;
|
||||||
|
}
|
||||||
|
|
||||||
// Call the AES crypto module
|
// Call the AES crypto module
|
||||||
// - the IV is the first 8 bytes of item->data_bytes
|
// - the IV is the first 8 bytes of item->data_bytes
|
||||||
|
|
||||||
if(item->data_size < 8)
|
if(data_size < 8)
|
||||||
{
|
{
|
||||||
std::cerr << "(EE) item encrypted data stream is too small: size = " << item->data_size << std::endl;
|
std::cerr << "(EE) item encrypted data stream is too small: size = " << data_size << std::endl;
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
if(*((uint64_t*)item->data_bytes) != 0) // WTF?? we should use flags
|
if(*((uint64_t*)data_bytes) != 0) // WTF?? we should use flags
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_GXS_TUNNEL
|
#ifdef DEBUG_GXS_TUNNEL
|
||||||
std::cerr << " Item is encrypted." << std::endl;
|
std::cerr << " Item is encrypted." << std::endl;
|
||||||
|
@ -715,7 +733,7 @@ void p3GxsTunnelService::receiveTurtleData(const RsTurtleGenericTunnelItem *gite
|
||||||
|
|
||||||
// if cannot decrypt, it means the key is wrong. We need to re-negociate a new key.
|
// if cannot decrypt, it means the key is wrong. We need to re-negociate a new key.
|
||||||
|
|
||||||
handleEncryptedData((uint8_t*)item->data_bytes,item->data_size,hash,virtual_peer_id) ;
|
handleEncryptedData((uint8_t*)data_bytes,data_size,hash,virtual_peer_id,accept_fast_items) ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -725,8 +743,8 @@ void p3GxsTunnelService::receiveTurtleData(const RsTurtleGenericTunnelItem *gite
|
||||||
|
|
||||||
// Now try deserialise the decrypted data to make an RsItem out of it.
|
// Now try deserialise the decrypted data to make an RsItem out of it.
|
||||||
//
|
//
|
||||||
uint32_t pktsize = item->data_size-8;
|
uint32_t pktsize = data_size-8;
|
||||||
RsItem *citem = RsGxsTunnelSerialiser().deserialise(&((uint8_t*)item->data_bytes)[8],&pktsize) ;
|
RsItem *citem = RsGxsTunnelSerialiser().deserialise(&((uint8_t*)data_bytes)[8],&pktsize) ;
|
||||||
|
|
||||||
if(citem == NULL)
|
if(citem == NULL)
|
||||||
{
|
{
|
||||||
|
@ -752,7 +770,11 @@ void p3GxsTunnelService::receiveTurtleData(const RsTurtleGenericTunnelItem *gite
|
||||||
|
|
||||||
// This function encrypts the given data and adds a MAC and an IV into a serialised memory chunk that is then sent through the tunnel.
|
// This function encrypts the given data and adds a MAC and an IV into a serialised memory chunk that is then sent through the tunnel.
|
||||||
|
|
||||||
|
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_004
|
||||||
|
bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t data_size,const TurtleFileHash& hash,const RsPeerId& virtual_peer_id,bool accepts_fast_items)
|
||||||
|
#else
|
||||||
bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t data_size,const TurtleFileHash& hash,const RsPeerId& virtual_peer_id)
|
bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t data_size,const TurtleFileHash& hash,const RsPeerId& virtual_peer_id)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_GXS_TUNNEL
|
#ifdef DEBUG_GXS_TUNNEL
|
||||||
std::cerr << "p3GxsTunnelService::handleEncryptedDataItem()" << std::endl;
|
std::cerr << "p3GxsTunnelService::handleEncryptedDataItem()" << std::endl;
|
||||||
|
@ -795,6 +817,16 @@ bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t
|
||||||
std::cerr << "(EE) no tunnel data for tunnel ID=" << tunnel_id << ". This is a bug." << std::endl;
|
std::cerr << "(EE) no tunnel data for tunnel ID=" << tunnel_id << ". This is a bug." << std::endl;
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_004
|
||||||
|
if(accepts_fast_items)
|
||||||
|
{
|
||||||
|
if(!it2->second.accepts_fast_turtle_items)
|
||||||
|
std::cerr << "(II) received probe for Fast track turtle items for tunnel VPID " << it2->second.virtual_peer_id << ": switching to Fast items mode." << std::endl;
|
||||||
|
|
||||||
|
it2->second.accepts_fast_turtle_items = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
memcpy(aes_key,it2->second.aes_key,GXS_TUNNEL_AES_KEY_SIZE) ;
|
memcpy(aes_key,it2->second.aes_key,GXS_TUNNEL_AES_KEY_SIZE) ;
|
||||||
|
|
||||||
#ifdef DEBUG_GXS_TUNNEL
|
#ifdef DEBUG_GXS_TUNNEL
|
||||||
|
@ -1291,34 +1323,77 @@ bool p3GxsTunnelService::locked_sendEncryptedTunnelData(RsGxsTunnelItem *item)
|
||||||
|
|
||||||
// make a TurtleGenericData item out of it:
|
// make a TurtleGenericData item out of it:
|
||||||
//
|
//
|
||||||
RsTurtleGenericDataItem *gitem = new RsTurtleGenericDataItem ;
|
|
||||||
|
|
||||||
gitem->data_size = encrypted_size + GXS_TUNNEL_ENCRYPTION_IV_SIZE + GXS_TUNNEL_ENCRYPTION_HMAC_SIZE ;
|
uint32_t data_size = encrypted_size + GXS_TUNNEL_ENCRYPTION_IV_SIZE + GXS_TUNNEL_ENCRYPTION_HMAC_SIZE ;
|
||||||
gitem->data_bytes = rs_malloc(gitem->data_size) ;
|
void *data_bytes = rs_malloc(data_size) ;
|
||||||
|
|
||||||
if(gitem->data_bytes == NULL)
|
if(data_bytes == NULL)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
memcpy(& ((uint8_t*)gitem->data_bytes)[0] ,&IV,8) ;
|
memcpy(& ((uint8_t*)data_bytes)[0] ,&IV,8) ;
|
||||||
|
|
||||||
unsigned int md_len = GXS_TUNNEL_ENCRYPTION_HMAC_SIZE ;
|
unsigned int md_len = GXS_TUNNEL_ENCRYPTION_HMAC_SIZE ;
|
||||||
HMAC(EVP_sha1(),aes_key,GXS_TUNNEL_AES_KEY_SIZE,encrypted_data,encrypted_size,&(((uint8_t*)gitem->data_bytes)[GXS_TUNNEL_ENCRYPTION_IV_SIZE]),&md_len) ;
|
HMAC(EVP_sha1(),aes_key,GXS_TUNNEL_AES_KEY_SIZE,encrypted_data,encrypted_size,&(((uint8_t*)data_bytes)[GXS_TUNNEL_ENCRYPTION_IV_SIZE]),&md_len) ;
|
||||||
|
|
||||||
memcpy(& (((uint8_t*)gitem->data_bytes)[GXS_TUNNEL_ENCRYPTION_HMAC_SIZE+GXS_TUNNEL_ENCRYPTION_IV_SIZE]),encrypted_data,encrypted_size) ;
|
memcpy(& (((uint8_t*)data_bytes)[GXS_TUNNEL_ENCRYPTION_HMAC_SIZE+GXS_TUNNEL_ENCRYPTION_IV_SIZE]),encrypted_data,encrypted_size) ;
|
||||||
|
|
||||||
#ifdef DEBUG_GXS_TUNNEL
|
#ifdef DEBUG_GXS_TUNNEL
|
||||||
std::cerr << " Using IV: " << std::hex << IV << std::dec << std::endl;
|
std::cerr << " Using IV: " << std::hex << IV << std::dec << std::endl;
|
||||||
std::cerr << " Using Key: " << RsUtil::BinToHex((char*)aes_key,GXS_TUNNEL_AES_KEY_SIZE) ; std::cerr << std::endl;
|
std::cerr << " Using Key: " << RsUtil::BinToHex((char*)aes_key,GXS_TUNNEL_AES_KEY_SIZE) ; std::cerr << std::endl;
|
||||||
std::cerr << " hmac: " << RsUtil::BinToHex((char*)gitem->data_bytes,GXS_TUNNEL_ENCRYPTION_HMAC_SIZE) << std::endl;
|
std::cerr << " hmac: " << RsUtil::BinToHex((char*)data_bytes,GXS_TUNNEL_ENCRYPTION_HMAC_SIZE) << std::endl;
|
||||||
#endif
|
#endif
|
||||||
#ifdef DEBUG_GXS_TUNNEL
|
#ifdef DEBUG_GXS_TUNNEL
|
||||||
std::cerr << "GxsTunnelService::sendEncryptedTunnelData(): Sending encrypted data to virtual peer: " << virtual_peer_id << std::endl;
|
std::cerr << "GxsTunnelService::sendEncryptedTunnelData(): Sending encrypted data to virtual peer: " << virtual_peer_id << std::endl;
|
||||||
std::cerr << " gitem->data_size = " << gitem->data_size << std::endl;
|
std::cerr << " data_size = " << data_size << std::endl;
|
||||||
std::cerr << " serialised data = " << RsUtil::BinToHex((unsigned char*)gitem->data_bytes,gitem->data_size,100) ;
|
std::cerr << " serialised data = " << RsUtil::BinToHex((unsigned char*)data_bytes,data_size,100) ;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mTurtle->sendTurtleData(virtual_peer_id,gitem) ;
|
// We send the item through the turtle tunnel. We do that using the new 'fast' item type if the tunnel accepts it, and using the old slow one otherwise.
|
||||||
|
// Still if the tunnel hasn't been probed, we duplicate the packet using the new fast item format. The packet being received twice on the other side will
|
||||||
|
// be discarded with a warning.
|
||||||
|
// Note that because the data is deleted by sendTurtleData(), we need to send all packets at the end, and properly duplicate the data when needed.
|
||||||
|
|
||||||
|
#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_004
|
||||||
|
RsTurtleGenericFastDataItem *gitem = new RsTurtleGenericFastDataItem;
|
||||||
|
gitem->data_bytes = data_bytes;
|
||||||
|
gitem->data_size = data_size ;
|
||||||
|
#else
|
||||||
|
RsTurtleGenericDataItem *gitem = NULL;
|
||||||
|
RsTurtleGenericFastDataItem *gitem2 = NULL;
|
||||||
|
|
||||||
|
if(!it->second.accepts_fast_turtle_items)
|
||||||
|
{
|
||||||
|
std::cerr << "Sending old format (slow) item for packet IV=" << std::hex << IV << std::dec << " in tunnel VPID=" << it->second.virtual_peer_id << std::endl;
|
||||||
|
gitem = new RsTurtleGenericDataItem ;
|
||||||
|
|
||||||
|
gitem->data_bytes = data_bytes;
|
||||||
|
gitem->data_size = data_size ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(it->second.accepts_fast_turtle_items || !it->second.already_probed_for_fast_items)
|
||||||
|
{
|
||||||
|
std::cerr << "Sending new format (fast) item for packet IV=" << std::hex << IV << std::dec << " in tunnel VPID=" << it->second.virtual_peer_id << std::endl;
|
||||||
|
gitem2 = new RsTurtleGenericFastDataItem ;
|
||||||
|
|
||||||
|
if(gitem != NULL) // duplicate the data because it was already sent in gitem.
|
||||||
|
{
|
||||||
|
gitem2->data_bytes = rs_malloc(data_size);
|
||||||
|
gitem2->data_size = data_size ;
|
||||||
|
memcpy(gitem2->data_bytes,data_bytes,data_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gitem2->data_bytes = data_bytes;
|
||||||
|
gitem2->data_size = data_size ;
|
||||||
|
}
|
||||||
|
|
||||||
|
it->second.already_probed_for_fast_items = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
if(gitem2) mTurtle->sendTurtleData(virtual_peer_id,gitem2) ;
|
||||||
|
#endif
|
||||||
|
if(gitem) mTurtle->sendTurtleData(virtual_peer_id,gitem) ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,14 +128,12 @@ public:
|
||||||
// Creates the invite if the public key of the distant peer is available.
|
// Creates the invite if the public key of the distant peer is available.
|
||||||
// Om success, stores the invite in the map above, so that we can respond to tunnel requests.
|
// Om success, stores the invite in the map above, so that we can respond to tunnel requests.
|
||||||
//
|
//
|
||||||
virtual bool requestSecuredTunnel(const RsGxsId& to_id,const RsGxsId& from_id,RsGxsTunnelId& tunnel_id,uint32_t service_id,uint32_t& error_code) ;
|
virtual bool requestSecuredTunnel(const RsGxsId& to_id,const RsGxsId& from_id,RsGxsTunnelId& tunnel_id,uint32_t service_id,uint32_t& error_code) override ;
|
||||||
|
virtual bool closeExistingTunnel(const RsGxsTunnelId &tunnel_id,uint32_t service_id) override ;
|
||||||
virtual bool closeExistingTunnel(const RsGxsTunnelId &tunnel_id,uint32_t service_id) ;
|
virtual bool getTunnelsInfo(std::vector<GxsTunnelInfo>& infos) override ;
|
||||||
virtual bool getTunnelsInfo(std::vector<GxsTunnelInfo>& infos);
|
virtual bool getTunnelInfo(const RsGxsTunnelId& tunnel_id,GxsTunnelInfo& info) override ;
|
||||||
virtual bool getTunnelInfo(const RsGxsTunnelId& tunnel_id,GxsTunnelInfo& info);
|
virtual bool sendData(const RsGxsTunnelId& tunnel_id,uint32_t service_id,const uint8_t *data,uint32_t size) override ;
|
||||||
virtual bool sendData(const RsGxsTunnelId& tunnel_id,uint32_t service_id,const uint8_t *data,uint32_t size) ;
|
virtual bool registerClientService(uint32_t service_id,RsGxsTunnelClientService *service) override ;
|
||||||
|
|
||||||
virtual bool registerClientService(uint32_t service_id,RsGxsTunnelClientService *service) ;
|
|
||||||
|
|
||||||
// derived from p3service
|
// derived from p3service
|
||||||
|
|
||||||
|
@ -150,6 +148,9 @@ private:
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GxsTunnelPeerInfo() : last_contact(0), last_keep_alive_sent(0), status(0), direction(0)
|
GxsTunnelPeerInfo() : last_contact(0), last_keep_alive_sent(0), status(0), direction(0)
|
||||||
|
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_004
|
||||||
|
,accepts_fast_turtle_items(false)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
memset(aes_key, 0, GXS_TUNNEL_AES_KEY_SIZE);
|
memset(aes_key, 0, GXS_TUNNEL_AES_KEY_SIZE);
|
||||||
|
|
||||||
|
@ -170,8 +171,12 @@ private:
|
||||||
TurtleFileHash hash ; // hash that is last used. This is necessary for handling tunnel establishment
|
TurtleFileHash hash ; // hash that is last used. This is necessary for handling tunnel establishment
|
||||||
std::set<uint32_t> client_services ; // services that used this tunnel
|
std::set<uint32_t> client_services ; // services that used this tunnel
|
||||||
std::map<uint64_t,rstime_t> received_data_prints ; // list of recently received messages, to avoid duplicates. Kept for 20 mins at most.
|
std::map<uint64_t,rstime_t> received_data_prints ; // list of recently received messages, to avoid duplicates. Kept for 20 mins at most.
|
||||||
uint32_t total_sent ;
|
uint32_t total_sent ; // total data sent to this peer
|
||||||
uint32_t total_received ;
|
uint32_t total_received ; // total data received by this peer
|
||||||
|
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_004
|
||||||
|
bool accepts_fast_turtle_items; // does the tunnel accept RsTurtleGenericFastDataItem type?
|
||||||
|
bool already_probed_for_fast_items; // has the tunnel been probed already? If not, a fast item will be sent
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
class GxsTunnelDHInfo
|
class GxsTunnelDHInfo
|
||||||
|
@ -243,7 +248,11 @@ private:
|
||||||
bool locked_sendEncryptedTunnelData(RsGxsTunnelItem *item) ;
|
bool locked_sendEncryptedTunnelData(RsGxsTunnelItem *item) ;
|
||||||
bool locked_sendClearTunnelData(RsGxsTunnelDHPublicKeyItem *item); // this limits the usage to DH items. Others should be encrypted!
|
bool locked_sendClearTunnelData(RsGxsTunnelDHPublicKeyItem *item); // this limits the usage to DH items. Others should be encrypted!
|
||||||
|
|
||||||
|
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_004
|
||||||
|
bool handleEncryptedData(const uint8_t *data_bytes, uint32_t data_size, const TurtleFileHash& hash, const RsPeerId& virtual_peer_id, bool accepts_fast_items) ;
|
||||||
|
#else
|
||||||
bool handleEncryptedData(const uint8_t *data_bytes, uint32_t data_size, const TurtleFileHash& hash, const RsPeerId& virtual_peer_id) ;
|
bool handleEncryptedData(const uint8_t *data_bytes, uint32_t data_size, const TurtleFileHash& hash, const RsPeerId& virtual_peer_id) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
// local data
|
// local data
|
||||||
|
|
||||||
|
|
|
@ -186,8 +186,9 @@ class NetInterface;
|
||||||
class PQInterface: public RateInterface
|
class PQInterface: public RateInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit PQInterface(const RsPeerId &id) :peerId(id) { return; }
|
explicit PQInterface(const RsPeerId &id) :
|
||||||
virtual ~PQInterface() { return; }
|
traf_in(0), traf_out(0), peerId(id) {}
|
||||||
|
virtual ~PQInterface() {}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* allows user to send RsItems to a particular facility (file, network)
|
* allows user to send RsItems to a particular facility (file, network)
|
||||||
|
@ -228,6 +229,22 @@ class PQInterface: public RateInterface
|
||||||
const sockaddr_storage & /*remote_peer_address*/)
|
const sockaddr_storage & /*remote_peer_address*/)
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
|
|
||||||
|
virtual uint64_t getTraffic(bool in)
|
||||||
|
{
|
||||||
|
uint64_t ret = 0;
|
||||||
|
if (in)
|
||||||
|
{
|
||||||
|
ret = traf_in;
|
||||||
|
traf_in = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = traf_out;
|
||||||
|
traf_out = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
uint64_t traf_in;
|
||||||
|
uint64_t traf_out;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
RsPeerId peerId;
|
RsPeerId peerId;
|
||||||
|
|
|
@ -83,6 +83,8 @@ pqihandler::pqihandler() : coreMtx("pqihandler")
|
||||||
rateMax_in = 0.01;
|
rateMax_in = 0.01;
|
||||||
rateTotal_in = 0.0 ;
|
rateTotal_in = 0.0 ;
|
||||||
rateTotal_out = 0.0 ;
|
rateTotal_out = 0.0 ;
|
||||||
|
traffInSum = 0;
|
||||||
|
traffOutSum = 0;
|
||||||
last_m = time(NULL) ;
|
last_m = time(NULL) ;
|
||||||
nb_ticks = 0 ;
|
nb_ticks = 0 ;
|
||||||
mLastRateCapUpdate = 0 ;
|
mLastRateCapUpdate = 0 ;
|
||||||
|
@ -372,6 +374,9 @@ int pqihandler::UpdateRates()
|
||||||
SearchModule *mod = (it -> second);
|
SearchModule *mod = (it -> second);
|
||||||
float crate_in = mod -> pqi -> getRate(true);
|
float crate_in = mod -> pqi -> getRate(true);
|
||||||
|
|
||||||
|
traffInSum += mod -> pqi -> getTraffic(true);
|
||||||
|
traffOutSum += mod -> pqi -> getTraffic(false);
|
||||||
|
|
||||||
#ifdef PQI_HDL_DEBUG_UR
|
#ifdef PQI_HDL_DEBUG_UR
|
||||||
if(crate_in > 0.0)
|
if(crate_in > 0.0)
|
||||||
std::cerr << " got in rate for peer " << it->first << " : " << crate_in << std::endl;
|
std::cerr << " got in rate for peer " << it->first << " : " << crate_in << std::endl;
|
||||||
|
@ -540,4 +545,8 @@ void pqihandler::locked_StoreCurrentRates(float in, float out)
|
||||||
rateTotal_out = out;
|
rateTotal_out = out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pqihandler::GetTraffic(uint64_t &in, uint64_t &out)
|
||||||
|
{
|
||||||
|
in = traffInSum;
|
||||||
|
out = traffOutSum;
|
||||||
|
}
|
||||||
|
|
|
@ -87,6 +87,10 @@ class pqihandler: public P3Interface, public pqiPublisher
|
||||||
int ExtractRates(std::map<RsPeerId, RsBwRates> &ratemap, RsBwRates &totals);
|
int ExtractRates(std::map<RsPeerId, RsBwRates> &ratemap, RsBwRates &totals);
|
||||||
int ExtractTrafficInfo(std::list<RSTrafficClue> &out_lst, std::list<RSTrafficClue> &in_lst);
|
int ExtractTrafficInfo(std::list<RSTrafficClue> &out_lst, std::list<RSTrafficClue> &in_lst);
|
||||||
|
|
||||||
|
uint64_t traffInSum;
|
||||||
|
uint64_t traffOutSum;
|
||||||
|
void GetTraffic(uint64_t &in, uint64_t &out);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* check to be overloaded by those that can
|
/* check to be overloaded by those that can
|
||||||
* generates warnings otherwise
|
* generates warnings otherwise
|
||||||
|
|
|
@ -637,6 +637,13 @@ float pqiperson::getRate(bool in)
|
||||||
return activepqi -> getRate(in);
|
return activepqi -> getRate(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t pqiperson::getTraffic(bool in)
|
||||||
|
{
|
||||||
|
if ((!active) || (activepqi == NULL))
|
||||||
|
return 0;
|
||||||
|
return activepqi -> getTraffic(in);
|
||||||
|
}
|
||||||
|
|
||||||
void pqiperson::setMaxRate(bool in, float val)
|
void pqiperson::setMaxRate(bool in, float val)
|
||||||
{
|
{
|
||||||
RS_STACK_MUTEX(mPersonMtx);
|
RS_STACK_MUTEX(mPersonMtx);
|
||||||
|
|
|
@ -143,6 +143,7 @@ public:
|
||||||
virtual int getQueueSize(bool in);
|
virtual int getQueueSize(bool in);
|
||||||
virtual void getRates(RsBwRates &rates);
|
virtual void getRates(RsBwRates &rates);
|
||||||
virtual float getRate(bool in);
|
virtual float getRate(bool in);
|
||||||
|
virtual uint64_t getTraffic(bool in);
|
||||||
virtual void setMaxRate(bool in, float val);
|
virtual void setMaxRate(bool in, float val);
|
||||||
virtual void setRateCap(float val_in, float val_out);
|
virtual void setRateCap(float val_in, float val_out);
|
||||||
virtual int gatherStatistics(std::list<RSTrafficClue>& outqueue_lst,
|
virtual int gatherStatistics(std::list<RSTrafficClue>& outqueue_lst,
|
||||||
|
|
|
@ -216,6 +216,7 @@ float pqistreamer::getRate(bool b)
|
||||||
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
|
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
|
||||||
return RateInterface::getRate(b) ;
|
return RateInterface::getRate(b) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pqistreamer::setMaxRate(bool b,float f)
|
void pqistreamer::setMaxRate(bool b,float f)
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
|
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
|
||||||
|
@ -1226,7 +1227,7 @@ void pqistreamer::outSentBytes_locked(uint32_t outb)
|
||||||
mTotalSent += outb;
|
mTotalSent += outb;
|
||||||
mCurrSent += outb;
|
mCurrSent += outb;
|
||||||
mAvgSentCount += outb;
|
mAvgSentCount += outb;
|
||||||
|
PQInterface::traf_out += outb;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1243,7 +1244,7 @@ void pqistreamer::inReadBytes_locked(uint32_t inb)
|
||||||
mTotalRead += inb;
|
mTotalRead += inb;
|
||||||
mCurrRead += inb;
|
mCurrRead += inb;
|
||||||
mAvgReadCount += inb;
|
mAvgReadCount += inb;
|
||||||
|
PQInterface::traf_in += inb;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -409,6 +409,7 @@ public:
|
||||||
* @return returns 1 on succes and 0 otherwise
|
* @return returns 1 on succes and 0 otherwise
|
||||||
*/
|
*/
|
||||||
virtual int GetCurrentDataRates( float &inKb, float &outKb ) = 0;
|
virtual int GetCurrentDataRates( float &inKb, float &outKb ) = 0;
|
||||||
|
virtual int GetTrafficSum( uint64_t &inb, uint64_t &outb ) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* libretroshare: retroshare core library *
|
* libretroshare: retroshare core library *
|
||||||
* *
|
* *
|
||||||
* Copyright (C) 2012 Robert Fernie <retroshare@lunamutt.com> *
|
* Copyright (C) 2012 Robert Fernie <retroshare@lunamutt.com> *
|
||||||
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org> *
|
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||||
* *
|
* *
|
||||||
* This program is free software: you can redistribute it and/or modify *
|
* This program is free software: you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -33,6 +33,8 @@
|
||||||
#include "serialiser/rsserializable.h"
|
#include "serialiser/rsserializable.h"
|
||||||
#include "retroshare/rsturtle.h"
|
#include "retroshare/rsturtle.h"
|
||||||
#include "util/rsdeprecate.h"
|
#include "util/rsdeprecate.h"
|
||||||
|
#include "retroshare/rsgxscircles.h"
|
||||||
|
#include "util/rsmemory.h"
|
||||||
|
|
||||||
class RsGxsChannels;
|
class RsGxsChannels;
|
||||||
|
|
||||||
|
@ -102,34 +104,114 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief Create channel. Blocking API.
|
* @brief Create channel. Blocking API.
|
||||||
* @jsonapi{development}
|
* @jsonapi{development}
|
||||||
* @param[inout] channel Channel data (name, description...)
|
* @param[in] name Name of the channel
|
||||||
* @return false on error, true otherwise
|
* @param[in] description Description of the channel
|
||||||
|
* @param[in] thumbnail Optional image to show as channel thumbnail.
|
||||||
|
* @param[in] authorId Optional id of the author. Leave empty for an
|
||||||
|
* anonymous channel.
|
||||||
|
* @param[in] circleType Optional visibility rule, default public.
|
||||||
|
* @param[in] circleId If the channel is not public specify the id of
|
||||||
|
* the circle who can see the channel. Depending on
|
||||||
|
* the value you pass for
|
||||||
|
* circleType this should be be an external circle
|
||||||
|
* if EXTERNAL is passed, a local friend group id
|
||||||
|
* if NODES_GROUP is passed, empty otherwise.
|
||||||
|
* @param[out] channelId Optional storage for the id of the created
|
||||||
|
* channel, meaningful only if creations succeeds.
|
||||||
|
* @param[out] errorMessage Optional storage for error messsage, meaningful
|
||||||
|
* only if creation fail.
|
||||||
|
* @return False on error, true otherwise.
|
||||||
*/
|
*/
|
||||||
virtual bool createChannel(RsGxsChannelGroup& channel) = 0;
|
virtual bool createChannelV2(
|
||||||
|
const std::string& name,
|
||||||
|
const std::string& description,
|
||||||
|
const RsGxsImage& thumbnail = RsGxsImage(),
|
||||||
|
const RsGxsId& authorId = RsGxsId(),
|
||||||
|
RsGxsCircleType circleType = RsGxsCircleType::PUBLIC,
|
||||||
|
const RsGxsCircleId& circleId = RsGxsCircleId(),
|
||||||
|
RsGxsGroupId& channelId = RS_DEFAULT_STORAGE_PARAM(RsGxsGroupId),
|
||||||
|
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
|
||||||
|
) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Add a comment on a post or on another comment
|
* @brief Add a comment on a post or on another comment. Blocking API.
|
||||||
* @jsonapi{development}
|
* @jsonapi{development}
|
||||||
* @param[inout] comment
|
* @param[in] channelId Id of the channel in which the comment is to be
|
||||||
|
* posted
|
||||||
|
* @param[in] threadId Id of the post (that is a thread) in the channel
|
||||||
|
* where the comment is placed
|
||||||
|
* @param[in] parentId Id of the parent of the comment that is either a
|
||||||
|
* channel post Id or the Id of another comment.
|
||||||
|
* @param[in] authorId Id of the author of the comment
|
||||||
|
* @param[in] comment UTF-8 string containing the comment itself
|
||||||
|
* @param[out] commentMessageId Optional storage for the id of the comment
|
||||||
|
* that was created, meaningful only on success.
|
||||||
|
* @param[out] errorMessage Optional storage for error message, meaningful
|
||||||
|
* only on failure.
|
||||||
* @return false on error, true otherwise
|
* @return false on error, true otherwise
|
||||||
*/
|
*/
|
||||||
virtual bool createComment(RsGxsComment& comment) = 0;
|
virtual bool createCommentV2(
|
||||||
|
const RsGxsGroupId& channelId,
|
||||||
|
const RsGxsMessageId& threadId,
|
||||||
|
const RsGxsMessageId& parentId,
|
||||||
|
const RsGxsId& authorId,
|
||||||
|
const std::string& comment,
|
||||||
|
RsGxsMessageId& commentMessageId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId),
|
||||||
|
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
|
||||||
|
) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create channel post. Blocking API.
|
* @brief Create channel post. Blocking API.
|
||||||
* @jsonapi{development}
|
* @jsonapi{development}
|
||||||
* @param[inout] post
|
* @param[in] channelId Id of the channel where to put the post. Beware
|
||||||
|
* you need publish rights on that channel to post.
|
||||||
|
* @param[in] title Title of the post
|
||||||
|
* @param[in] mBody Text content of the post
|
||||||
|
* @param[in] files Optional list of attached files. These are
|
||||||
|
* supposed to be already shared,
|
||||||
|
* @see ExtraFileHash() below otherwise.
|
||||||
|
* @param[in] thumbnail Optional thumbnail image for the post.
|
||||||
|
* @param[in] origPostId If this is supposed to replace an already
|
||||||
|
* existent post, the id of the old post. If left
|
||||||
|
* blank a new post will be created.
|
||||||
|
* @param[out] postId Optional storage for the id of the created post,
|
||||||
|
* meaningful only on success.
|
||||||
|
* @param[out] errorMessage Optional storage for the error message,
|
||||||
|
* meaningful only on failure.
|
||||||
* @return false on error, true otherwise
|
* @return false on error, true otherwise
|
||||||
*/
|
*/
|
||||||
virtual bool createPost(RsGxsChannelPost& post) = 0;
|
virtual bool createPostV2(
|
||||||
|
const RsGxsGroupId& channelId, const std::string& title,
|
||||||
|
const std::string& mBody,
|
||||||
|
const std::list<RsGxsFile>& files = std::list<RsGxsFile>(),
|
||||||
|
const RsGxsImage& thumbnail = RsGxsImage(),
|
||||||
|
const RsGxsMessageId& origPostId = RsGxsMessageId(),
|
||||||
|
RsGxsMessageId& postId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId),
|
||||||
|
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief createVote
|
* @brief Create a vote
|
||||||
* @jsonapi{development}
|
* @jsonapi{development}
|
||||||
* @param[inout] vote
|
* @param[in] channelId Id of the channel where to vote
|
||||||
|
* @param[in] postId Id of the channel post of which a comment is
|
||||||
|
* voted.
|
||||||
|
* @param[in] commentId Id of the comment that is voted
|
||||||
|
* @param[in] authorId Id of the author. Needs to be of an owned
|
||||||
|
* identity.
|
||||||
|
* @param[in] vote Vote value, either RsGxsVoteType::DOWN or
|
||||||
|
* RsGxsVoteType::UP
|
||||||
|
* @param[out] voteId Optional storage for the id of the created vote,
|
||||||
|
* meaningful only on success.
|
||||||
|
* @param[out] errorMessage Optional storage for error message, meaningful
|
||||||
|
* only on failure.
|
||||||
* @return false on error, true otherwise
|
* @return false on error, true otherwise
|
||||||
*/
|
*/
|
||||||
virtual bool createVote(RsGxsVote& vote) = 0;
|
virtual bool createVoteV2(
|
||||||
|
const RsGxsGroupId& channelId, const RsGxsMessageId& postId,
|
||||||
|
const RsGxsMessageId& commentId, const RsGxsId& authorId,
|
||||||
|
RsGxsVoteType vote,
|
||||||
|
RsGxsMessageId& voteId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId),
|
||||||
|
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Edit channel details.
|
* @brief Edit channel details.
|
||||||
|
@ -315,6 +397,16 @@ public:
|
||||||
/* Following functions are deprecated as they expose internal functioning
|
/* Following functions are deprecated as they expose internal functioning
|
||||||
* semantic, instead of a safe to use API */
|
* semantic, instead of a safe to use API */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create channel. Blocking API.
|
||||||
|
* @jsonapi{development}
|
||||||
|
* @deprecated { substituted by createChannelV2 }
|
||||||
|
* @param[inout] channel Channel data (name, description...)
|
||||||
|
* @return false on error, true otherwise
|
||||||
|
*/
|
||||||
|
RS_DEPRECATED_FOR(createChannelV2)
|
||||||
|
virtual bool createChannel(RsGxsChannelGroup& channel) = 0;
|
||||||
|
|
||||||
RS_DEPRECATED_FOR(getChannelsInfo)
|
RS_DEPRECATED_FOR(getChannelsInfo)
|
||||||
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsChannelGroup> &groups) = 0;
|
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsChannelGroup> &groups) = 0;
|
||||||
|
|
||||||
|
@ -372,9 +464,29 @@ public:
|
||||||
* @param[in] group Channel data (name, description...)
|
* @param[in] group Channel data (name, description...)
|
||||||
* @return false on error, true otherwise
|
* @return false on error, true otherwise
|
||||||
*/
|
*/
|
||||||
RS_DEPRECATED_FOR(createChannel)
|
RS_DEPRECATED_FOR(createChannelV2)
|
||||||
virtual bool createGroup(uint32_t& token, RsGxsChannelGroup& group) = 0;
|
virtual bool createGroup(uint32_t& token, RsGxsChannelGroup& group) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add a comment on a post or on another comment
|
||||||
|
* @jsonapi{development}
|
||||||
|
* @deprecated
|
||||||
|
* @param[inout] comment
|
||||||
|
* @return false on error, true otherwise
|
||||||
|
*/
|
||||||
|
RS_DEPRECATED_FOR(createCommentV2)
|
||||||
|
virtual bool createComment(RsGxsComment& comment) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create channel post. Blocking API.
|
||||||
|
* @jsonapi{development}
|
||||||
|
* @deprecated
|
||||||
|
* @param[inout] post
|
||||||
|
* @return false on error, true otherwise
|
||||||
|
*/
|
||||||
|
RS_DEPRECATED_FOR(createPostV2)
|
||||||
|
virtual bool createPost(RsGxsChannelPost& post) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Request post creation.
|
* @brief Request post creation.
|
||||||
* The action is performed asyncronously, so it could fail in a subsequent
|
* The action is performed asyncronously, so it could fail in a subsequent
|
||||||
|
@ -385,9 +497,19 @@ public:
|
||||||
* @param[in] post
|
* @param[in] post
|
||||||
* @return false on error, true otherwise
|
* @return false on error, true otherwise
|
||||||
*/
|
*/
|
||||||
RS_DEPRECATED
|
RS_DEPRECATED_FOR(createPostV2)
|
||||||
virtual bool createPost(uint32_t& token, RsGxsChannelPost& post) = 0;
|
virtual bool createPost(uint32_t& token, RsGxsChannelPost& post) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief createVote
|
||||||
|
* @jsonapi{development}
|
||||||
|
* @deprecated
|
||||||
|
* @param[inout] vote
|
||||||
|
* @return false on error, true otherwise
|
||||||
|
*/
|
||||||
|
RS_DEPRECATED_FOR(createVoteV2)
|
||||||
|
virtual bool createVote(RsGxsVote& vote) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Request channel change.
|
* @brief Request channel change.
|
||||||
* The action is performed asyncronously, so it could fail in a subsequent
|
* The action is performed asyncronously, so it could fail in a subsequent
|
||||||
|
|
|
@ -42,24 +42,35 @@ class RsGxsCircles;
|
||||||
*/
|
*/
|
||||||
extern RsGxsCircles* rsGxsCircles;
|
extern RsGxsCircles* rsGxsCircles;
|
||||||
|
|
||||||
|
enum class RsGxsCircleType : uint32_t // 32 bit overkill, just for retrocompat
|
||||||
|
{
|
||||||
|
UNKNOWN = 0, /// Used to detect uninizialized values.
|
||||||
|
PUBLIC = 1, /// Public distribution
|
||||||
|
EXTERNAL = 2, /// Restricted to an external circle
|
||||||
|
|
||||||
// TODO: convert to enum
|
/** Restricted to a group of friend nodes, the administrator of the circle
|
||||||
/// The meaning of the different circle types is:
|
* behave as a hub for them */
|
||||||
static const uint32_t GXS_CIRCLE_TYPE_UNKNOWN = 0x0000 ; /// Used to detect uninizialized values.
|
NODES_GROUP = 3,
|
||||||
static const uint32_t GXS_CIRCLE_TYPE_PUBLIC = 0x0001 ; // not restricted to a circle
|
|
||||||
static const uint32_t GXS_CIRCLE_TYPE_EXTERNAL = 0x0002 ; // restricted to an external circle, made of RsGxsId
|
|
||||||
static const uint32_t GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY = 0x0003 ; // restricted to a subset of friend nodes of a given RS node given by a RsPgpId list
|
|
||||||
static const uint32_t GXS_CIRCLE_TYPE_LOCAL = 0x0004 ; // not distributed at all
|
|
||||||
static const uint32_t GXS_CIRCLE_TYPE_EXT_SELF = 0x0005 ; // self-restricted. Not used, except at creation time when the circle ID isn't known yet. Set to EXTERNAL afterwards.
|
|
||||||
static const uint32_t GXS_CIRCLE_TYPE_YOUR_EYES_ONLY = 0x0006 ; // distributed to nodes signed by your own PGP key only.
|
|
||||||
|
|
||||||
|
LOCAL = 4, /// not distributed at all
|
||||||
|
|
||||||
|
/** Self-restricted. Used only at creation time of self-restricted circles
|
||||||
|
* when the circle id isn't known yet. Once the circle id is known the type
|
||||||
|
* is set to EXTERNAL, and the external circle id is set to the id of the
|
||||||
|
* circle itself.
|
||||||
|
*/
|
||||||
|
EXT_SELF = 5,
|
||||||
|
|
||||||
|
/// distributed to nodes signed by your own PGP key only.
|
||||||
|
YOUR_EYES_ONLY = 6
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: convert to enum class
|
||||||
static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST = 0x0001 ;// user is validated by circle admin
|
static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST = 0x0001 ;// user is validated by circle admin
|
||||||
static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED = 0x0002 ;// user has subscribed the group
|
static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED = 0x0002 ;// user has subscribed the group
|
||||||
static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_KEY_AVAILABLE = 0x0004 ;// key is available, so we can encrypt for this circle
|
static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_KEY_AVAILABLE = 0x0004 ;// key is available, so we can encrypt for this circle
|
||||||
static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_ALLOWED = 0x0007 ;// user is allowed. Combines all flags above.
|
static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_ALLOWED = 0x0007 ;// user is allowed. Combines all flags above.
|
||||||
|
|
||||||
static const uint32_t GXS_CIRCLE_FLAGS_IS_EXTERNAL = 0x0008 ;// user is allowed
|
|
||||||
|
|
||||||
|
|
||||||
struct RsGxsCircleGroup : RsSerializable
|
struct RsGxsCircleGroup : RsSerializable
|
||||||
{
|
{
|
||||||
|
@ -110,8 +121,9 @@ struct RsGxsCircleMsg : RsSerializable
|
||||||
struct RsGxsCircleDetails : RsSerializable
|
struct RsGxsCircleDetails : RsSerializable
|
||||||
{
|
{
|
||||||
RsGxsCircleDetails() :
|
RsGxsCircleDetails() :
|
||||||
mCircleType(GXS_CIRCLE_TYPE_EXTERNAL), mAmIAllowed(false) {}
|
mCircleType(static_cast<uint32_t>(RsGxsCircleType::EXTERNAL)),
|
||||||
~RsGxsCircleDetails() {}
|
mAmIAllowed(false) {}
|
||||||
|
~RsGxsCircleDetails() override {}
|
||||||
|
|
||||||
RsGxsCircleId mCircleId;
|
RsGxsCircleId mCircleId;
|
||||||
std::string mCircleName;
|
std::string mCircleName;
|
||||||
|
@ -264,3 +276,34 @@ public:
|
||||||
RS_DEPRECATED_FOR("editCircle, inviteIdsToCircle")
|
RS_DEPRECATED_FOR("editCircle, inviteIdsToCircle")
|
||||||
virtual void updateGroup(uint32_t &token, RsGxsCircleGroup &group) = 0;
|
virtual void updateGroup(uint32_t &token, RsGxsCircleGroup &group) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// @deprecated Used to detect uninizialized values.
|
||||||
|
RS_DEPRECATED_FOR("RsGxsCircleType::UNKNOWN")
|
||||||
|
static const uint32_t GXS_CIRCLE_TYPE_UNKNOWN = 0x0000;
|
||||||
|
|
||||||
|
/// @deprecated not restricted to a circle
|
||||||
|
RS_DEPRECATED_FOR("RsGxsCircleType::PUBLIC")
|
||||||
|
static const uint32_t GXS_CIRCLE_TYPE_PUBLIC = 0x0001;
|
||||||
|
|
||||||
|
/// @deprecated restricted to an external circle, made of RsGxsId
|
||||||
|
RS_DEPRECATED_FOR("RsGxsCircleType::EXTERNAL")
|
||||||
|
static const uint32_t GXS_CIRCLE_TYPE_EXTERNAL = 0x0002;
|
||||||
|
|
||||||
|
/// @deprecated restricted to a subset of friend nodes of a given RS node given
|
||||||
|
/// by a RsPgpId list
|
||||||
|
RS_DEPRECATED_FOR("RsGxsCircleType::NODES_GROUP")
|
||||||
|
static const uint32_t GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY = 0x0003;
|
||||||
|
|
||||||
|
/// @deprecated not distributed at all
|
||||||
|
RS_DEPRECATED_FOR("RsGxsCircleType::LOCAL")
|
||||||
|
static const uint32_t GXS_CIRCLE_TYPE_LOCAL = 0x0004;
|
||||||
|
|
||||||
|
/// @deprecated self-restricted. Not used, except at creation time when the
|
||||||
|
/// circle ID isn't known yet. Set to EXTERNAL afterwards.
|
||||||
|
RS_DEPRECATED_FOR("RsGxsCircleType::EXT_SELF")
|
||||||
|
static const uint32_t GXS_CIRCLE_TYPE_EXT_SELF = 0x0005;
|
||||||
|
|
||||||
|
/// @deprecated distributed to nodes signed by your own PGP key only.
|
||||||
|
RS_DEPRECATED_FOR("RsGxsCircleType::YOUR_EYES_ONLY")
|
||||||
|
static const uint32_t GXS_CIRCLE_TYPE_YOUR_EYES_ONLY = 0x0006;
|
||||||
|
|
|
@ -19,11 +19,9 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
||||||
* *
|
* *
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#ifndef RETROSHARE_GXS_COMMON_OBJS_INTERFACE_H
|
#include <cstdint>
|
||||||
#define RETROSHARE_GXS_COMMON_OBJS_INTERFACE_H
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
|
@ -79,10 +77,12 @@ struct RsGxsImage : RsSerializable
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class RsGxsVoteType : uint32_t
|
||||||
#define GXS_VOTE_NONE 0x0000
|
{
|
||||||
#define GXS_VOTE_DOWN 0x0001
|
NONE = 0, /// Used to detect unset vote?
|
||||||
#define GXS_VOTE_UP 0x0002
|
DOWN = 1, /// Negative vote
|
||||||
|
UP = 2 /// Positive vote
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Status Flags to indicate Voting....
|
// Status Flags to indicate Voting....
|
||||||
|
@ -181,7 +181,11 @@ struct RsGxsCommentService
|
||||||
std::pair<RsGxsGroupId, RsGxsMessageId>& msgId ) = 0;
|
std::pair<RsGxsGroupId, RsGxsMessageId>& msgId ) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// @deprecated use RsGxsVoteType::NONE instead @see RsGxsVoteType
|
||||||
|
#define GXS_VOTE_NONE 0x0000
|
||||||
|
|
||||||
|
/// @deprecated use RsGxsVoteType::DOWN instead @see RsGxsVoteType
|
||||||
|
#define GXS_VOTE_DOWN 0x0001
|
||||||
|
|
||||||
#endif
|
/// @deprecated use RsGxsVoteType::UP instead @see RsGxsVoteType
|
||||||
|
#define GXS_VOTE_UP 0x0002
|
||||||
|
|
|
@ -52,14 +52,15 @@ namespace GXS_SERV {
|
||||||
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_MASK = 0x0000ff00;
|
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_MASK = 0x0000ff00;
|
||||||
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_NONE = 0x00000000;
|
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_NONE = 0x00000000;
|
||||||
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_GPG = 0x00000100; // Anti-spam feature. Allows to ask higher reputation to anonymous IDs
|
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_GPG = 0x00000100; // Anti-spam feature. Allows to ask higher reputation to anonymous IDs
|
||||||
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_REQUIRED = 0x00000200;
|
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_REQUIRED = 0x00000200; // unused
|
||||||
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN = 0x00000400;
|
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN = 0x00000400; // ???
|
||||||
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES = 0x00000800; // not used anymore
|
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES = 0x00000800; // not used anymore
|
||||||
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN = 0x00001000; // Anti-spam feature. Allows to ask higher reputation to unknown IDs and anonymous IDs
|
static const uint32_t FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN = 0x00001000; // Anti-spam feature. Allows to ask higher reputation to unknown IDs and anonymous IDs
|
||||||
|
|
||||||
|
// These are *not used*
|
||||||
static const uint32_t FLAG_GROUP_SIGN_PUBLISH_MASK = 0x000000ff;
|
static const uint32_t FLAG_GROUP_SIGN_PUBLISH_MASK = 0x000000ff;
|
||||||
static const uint32_t FLAG_GROUP_SIGN_PUBLISH_ENCRYPTED = 0x00000001;
|
static const uint32_t FLAG_GROUP_SIGN_PUBLISH_ENCRYPTED = 0x00000001;
|
||||||
static const uint32_t FLAG_GROUP_SIGN_PUBLISH_ALLSIGNED = 0x00000002;
|
static const uint32_t FLAG_GROUP_SIGN_PUBLISH_ALLSIGNED = 0x00000002; // unused
|
||||||
static const uint32_t FLAG_GROUP_SIGN_PUBLISH_THREADHEAD = 0x00000004;
|
static const uint32_t FLAG_GROUP_SIGN_PUBLISH_THREADHEAD = 0x00000004;
|
||||||
static const uint32_t FLAG_GROUP_SIGN_PUBLISH_NONEREQ = 0x00000008;
|
static const uint32_t FLAG_GROUP_SIGN_PUBLISH_NONEREQ = 0x00000008;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* libretroshare: retroshare core library *
|
* libretroshare: retroshare core library *
|
||||||
* *
|
* *
|
||||||
* Copyright 2011 by Christopher Evi-Parker *
|
* Copyright 2011 by Christopher Evi-Parker *
|
||||||
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org> *
|
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||||
* *
|
* *
|
||||||
* This program is free software: you can redistribute it and/or modify *
|
* This program is free software: you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -20,9 +20,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
||||||
* *
|
* *
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
#pragma once
|
||||||
#ifndef RSGXSIFACEIMPL_H
|
|
||||||
#define RSGXSIFACEIMPL_H
|
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
@ -292,19 +290,51 @@ protected:
|
||||||
* Useful for blocking API implementation.
|
* Useful for blocking API implementation.
|
||||||
* @param[in] token token associated to the request caller is waiting for
|
* @param[in] token token associated to the request caller is waiting for
|
||||||
* @param[in] maxWait maximum waiting time in milliseconds
|
* @param[in] maxWait maximum waiting time in milliseconds
|
||||||
|
* @param[in] checkEvery time in millisecond between status checks
|
||||||
*/
|
*/
|
||||||
RsTokenService::GxsRequestStatus waitToken(
|
RsTokenService::GxsRequestStatus waitToken(
|
||||||
uint32_t token,
|
uint32_t token,
|
||||||
std::chrono::milliseconds maxWait = std::chrono::milliseconds(500) )
|
std::chrono::milliseconds maxWait = std::chrono::milliseconds(500),
|
||||||
|
std::chrono::milliseconds checkEvery = std::chrono::milliseconds(2))
|
||||||
{
|
{
|
||||||
|
#if defined(__ANDROID__) && (__ANDROID_API__ < 24)
|
||||||
|
auto wkStartime = std::chrono::steady_clock::now();
|
||||||
|
int maxWorkAroundCnt = 10;
|
||||||
|
LLwaitTokenBeginLabel:
|
||||||
|
#endif
|
||||||
auto timeout = std::chrono::steady_clock::now() + maxWait;
|
auto timeout = std::chrono::steady_clock::now() + maxWait;
|
||||||
auto st = requestStatus(token);
|
auto st = requestStatus(token);
|
||||||
while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE)
|
while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE)
|
||||||
&& std::chrono::steady_clock::now() < timeout )
|
&& std::chrono::steady_clock::now() < timeout )
|
||||||
{
|
{
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(2));
|
std::this_thread::sleep_for(checkEvery);
|
||||||
st = requestStatus(token);
|
st = requestStatus(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__ANDROID__) && (__ANDROID_API__ < 24)
|
||||||
|
/* Work around for very slow/old android devices, we don't expect this
|
||||||
|
* to be necessary on newer devices. If it take unreasonably long
|
||||||
|
* something worser is already happening elsewere and we return anyway.
|
||||||
|
*/
|
||||||
|
if( st > RsTokenService::FAILED && st < RsTokenService::COMPLETE
|
||||||
|
&& maxWorkAroundCnt-- > 0 )
|
||||||
|
{
|
||||||
|
maxWait *= 10;
|
||||||
|
checkEvery *= 3;
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " Slow Android device "
|
||||||
|
<< " workaround st: " << st
|
||||||
|
<< " maxWorkAroundCnt: " << maxWorkAroundCnt
|
||||||
|
<< " maxWait: " << maxWait.count()
|
||||||
|
<< " checkEvery: " << checkEvery.count() << std::endl;
|
||||||
|
goto LLwaitTokenBeginLabel;
|
||||||
|
}
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " lasted: "
|
||||||
|
<< std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||||
|
std::chrono::steady_clock::now() - wkStartime ).count()
|
||||||
|
<< "ms" << std::endl;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,5 +342,3 @@ private:
|
||||||
RsGxsIface& mGxs;
|
RsGxsIface& mGxs;
|
||||||
RsTokenService& mTokenService;
|
RsTokenService& mTokenService;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RSGXSIFACEIMPL_H
|
|
||||||
|
|
|
@ -563,8 +563,8 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief MessageToTrash
|
* @brief MessageToTrash
|
||||||
* @jsonapi{development}
|
* @jsonapi{development}
|
||||||
* @param[in] msgId
|
* @param[in] msgId Id of the message to mode to trash box
|
||||||
* @param[in] bTrash
|
* @param[in] bTrash Move to trash if true, otherwise remove from trash
|
||||||
* @return true on success
|
* @return true on success
|
||||||
*/
|
*/
|
||||||
virtual bool MessageToTrash(const std::string &msgId, bool bTrash) = 0;
|
virtual bool MessageToTrash(const std::string &msgId, bool bTrash) = 0;
|
||||||
|
|
|
@ -44,6 +44,7 @@ class RsPostedGroup
|
||||||
|
|
||||||
RsGroupMetaData mMeta;
|
RsGroupMetaData mMeta;
|
||||||
std::string mDescription;
|
std::string mDescription;
|
||||||
|
RsGxsImage mGroupImage;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -121,15 +121,14 @@ public:
|
||||||
|
|
||||||
enum GxsRequestStatus : uint8_t
|
enum GxsRequestStatus : uint8_t
|
||||||
{
|
{
|
||||||
FAILED,
|
FAILED = 0,
|
||||||
PENDING,
|
PENDING = 1,
|
||||||
PARTIAL,
|
PARTIAL = 2,
|
||||||
COMPLETE,
|
COMPLETE = 3,
|
||||||
DONE, /// Once all data has been retrived
|
DONE = 4, /// Once all data has been retrived
|
||||||
CANCELLED
|
CANCELLED = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
RsTokenService() {}
|
RsTokenService() {}
|
||||||
virtual ~RsTokenService() {}
|
virtual ~RsTokenService() {}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ const uint8_t QOS_PRIORITY_RS_TURTLE_FILE_MAP = 3 ;
|
||||||
const uint8_t QOS_PRIORITY_RS_TURTLE_GENERIC_ITEM = 3 ;
|
const uint8_t QOS_PRIORITY_RS_TURTLE_GENERIC_ITEM = 3 ;
|
||||||
const uint8_t QOS_PRIORITY_RS_TURTLE_FORWARD_FILE_DATA= 3 ;
|
const uint8_t QOS_PRIORITY_RS_TURTLE_FORWARD_FILE_DATA= 3 ;
|
||||||
const uint8_t QOS_PRIORITY_RS_TURTLE_GENERIC_DATA = 5 ;
|
const uint8_t QOS_PRIORITY_RS_TURTLE_GENERIC_DATA = 5 ;
|
||||||
|
const uint8_t QOS_PRIORITY_RS_TURTLE_GENERIC_FAST_DATA= 7 ;
|
||||||
|
|
||||||
// File transfer
|
// File transfer
|
||||||
//
|
//
|
||||||
|
|
|
@ -44,7 +44,15 @@ void RsGxsPostedPostItem::serial_process(RsGenericSerializer::SerializeJob j,RsG
|
||||||
|
|
||||||
void RsGxsPostedGroupItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
void RsGxsPostedGroupItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
||||||
{
|
{
|
||||||
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR ,mGroup.mDescription,"mGroup.mDescription") ;
|
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR ,mDescription,"mDescription") ;
|
||||||
|
|
||||||
|
if(j == RsGenericSerializer::DESERIALIZE && ctx.mOffset == ctx.mSize)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
if((j == RsGenericSerializer::SIZE_ESTIMATE || j == RsGenericSerializer::SERIALIZE) && mGroupImage.empty())
|
||||||
|
return ;
|
||||||
|
|
||||||
|
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,mGroupImage,"mGroupImage") ;
|
||||||
}
|
}
|
||||||
|
|
||||||
RsItem *RsGxsPostedSerialiser::create_item(uint16_t service_id,uint8_t item_subtype) const
|
RsItem *RsGxsPostedSerialiser::create_item(uint16_t service_id,uint8_t item_subtype) const
|
||||||
|
@ -109,6 +117,42 @@ void RsGxsPostedPostItem::clear()
|
||||||
}
|
}
|
||||||
void RsGxsPostedGroupItem::clear()
|
void RsGxsPostedGroupItem::clear()
|
||||||
{
|
{
|
||||||
mGroup.mDescription.clear();
|
mDescription.clear();
|
||||||
|
mGroupImage.TlvClear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RsGxsPostedGroupItem::fromPostedGroup(RsPostedGroup &group, bool moveImage)
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
meta = group.mMeta;
|
||||||
|
mDescription = group.mDescription;
|
||||||
|
|
||||||
|
if (moveImage)
|
||||||
|
{
|
||||||
|
mGroupImage.binData.bin_data = group.mGroupImage.mData;
|
||||||
|
mGroupImage.binData.bin_len = group.mGroupImage.mSize;
|
||||||
|
group.mGroupImage.shallowClear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mGroupImage.binData.setBinData(group.mGroupImage.mData, group.mGroupImage.mSize);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RsGxsPostedGroupItem::toPostedGroup(RsPostedGroup &group, bool moveImage)
|
||||||
|
{
|
||||||
|
group.mMeta = meta;
|
||||||
|
group.mDescription = mDescription;
|
||||||
|
if (moveImage)
|
||||||
|
{
|
||||||
|
group.mGroupImage.take((uint8_t *) mGroupImage.binData.bin_data, mGroupImage.binData.bin_len);
|
||||||
|
// mGroupImage doesn't have a ShallowClear at the moment!
|
||||||
|
mGroupImage.binData.TlvShallowClear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
group.mGroupImage.copy((uint8_t *) mGroupImage.binData.bin_data, mGroupImage.binData.bin_len);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -42,8 +42,12 @@ public:
|
||||||
|
|
||||||
virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
|
virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
|
||||||
|
|
||||||
RsPostedGroup mGroup;
|
// use conversion functions to transform:
|
||||||
|
bool fromPostedGroup(RsPostedGroup &group, bool moveImage);
|
||||||
|
bool toPostedGroup(RsPostedGroup &group, bool moveImage);
|
||||||
|
|
||||||
|
std::string mDescription;
|
||||||
|
RsTlvImage mGroupImage;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -560,4 +560,8 @@ int p3ServerConfig::GetCurrentDataRates( float &inKb, float &outKb )
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int p3ServerConfig::GetTrafficSum(uint64_t &inb, uint64_t &outb )
|
||||||
|
{
|
||||||
|
mPqiHandler->GetTraffic(inb, outb);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
|
@ -91,6 +91,7 @@ virtual bool setOperatingMode(const std::string &opModeStr);
|
||||||
virtual int SetMaxDataRates( int downKb, int upKb );
|
virtual int SetMaxDataRates( int downKb, int upKb );
|
||||||
virtual int GetMaxDataRates( int &downKb, int &upKb );
|
virtual int GetMaxDataRates( int &downKb, int &upKb );
|
||||||
virtual int GetCurrentDataRates( float &inKb, float &outKb );
|
virtual int GetCurrentDataRates( float &inKb, float &outKb );
|
||||||
|
virtual int GetTrafficSum( uint64_t &inb, uint64_t &outb );
|
||||||
|
|
||||||
/********************* ABOVE is RsConfig Interface *******/
|
/********************* ABOVE is RsConfig Interface *******/
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* libretroshare: retroshare core library *
|
* libretroshare: retroshare core library *
|
||||||
* *
|
* *
|
||||||
* Copyright (C) 2012 Robert Fernie <retroshare@lunamutt.com> *
|
* Copyright (C) 2012 Robert Fernie <retroshare@lunamutt.com> *
|
||||||
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org> *
|
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||||
* *
|
* *
|
||||||
* This program is free software: you can redistribute it and/or modify *
|
* This program is free software: you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -31,12 +31,14 @@
|
||||||
|
|
||||||
#include "retroshare/rsgxsflags.h"
|
#include "retroshare/rsgxsflags.h"
|
||||||
#include "retroshare/rsfiles.h"
|
#include "retroshare/rsfiles.h"
|
||||||
|
#include "retroshare/rspeers.h"
|
||||||
|
|
||||||
#include "rsserver/p3face.h"
|
#include "rsserver/p3face.h"
|
||||||
#include "retroshare/rsnotify.h"
|
#include "retroshare/rsnotify.h"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
// For Dummy Msgs.
|
// For Dummy Msgs.
|
||||||
#include "util/rsrandom.h"
|
#include "util/rsrandom.h"
|
||||||
|
@ -1055,6 +1057,125 @@ bool p3GxsChannels::getChannelContent( const RsGxsGroupId& channelId,
|
||||||
return getPostData(token, posts, comments);
|
return getPostData(token, posts, comments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool p3GxsChannels::createChannelV2(
|
||||||
|
const std::string& name, const std::string& description,
|
||||||
|
const RsGxsImage& thumbnail, const RsGxsId& authorId,
|
||||||
|
RsGxsCircleType circleType, const RsGxsCircleId& circleId,
|
||||||
|
RsGxsGroupId& channelId, std::string& errorMessage )
|
||||||
|
{
|
||||||
|
// do some checks
|
||||||
|
|
||||||
|
if( circleType != RsGxsCircleType::PUBLIC
|
||||||
|
&& circleType != RsGxsCircleType::EXTERNAL
|
||||||
|
&& circleType != RsGxsCircleType::NODES_GROUP
|
||||||
|
&& circleType != RsGxsCircleType::LOCAL
|
||||||
|
&& circleType != RsGxsCircleType::YOUR_EYES_ONLY)
|
||||||
|
{
|
||||||
|
errorMessage = "circleType has invalid value";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(circleType)
|
||||||
|
{
|
||||||
|
case RsGxsCircleType::EXTERNAL:
|
||||||
|
if(circleId.isNull())
|
||||||
|
{
|
||||||
|
errorMessage = "circleType is EXTERNAL but circleId is null";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RsGxsCircleType::NODES_GROUP:
|
||||||
|
{
|
||||||
|
RsGroupInfo ginfo;
|
||||||
|
|
||||||
|
if(!rsPeers->getGroupInfo(RsNodeGroupId(circleId), ginfo))
|
||||||
|
{
|
||||||
|
errorMessage = "circleType is NODES_GROUP but circleId does not "
|
||||||
|
"correspond to an actual group of friends";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if(!circleId.isNull())
|
||||||
|
{
|
||||||
|
errorMessage = "circleType requires a null circleId, but a non "
|
||||||
|
"null circleId (";
|
||||||
|
errorMessage += circleId.toStdString();
|
||||||
|
errorMessage += ") was supplied";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a consistent channel group meta from the information supplied
|
||||||
|
RsGxsChannelGroup channel;
|
||||||
|
|
||||||
|
channel.mMeta.mGroupName = name;
|
||||||
|
channel.mMeta.mAuthorId = authorId;
|
||||||
|
channel.mMeta.mCircleType = static_cast<uint32_t>(circleType);
|
||||||
|
|
||||||
|
channel.mMeta.mSignFlags = GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_NONEREQ
|
||||||
|
| GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_REQUIRED;
|
||||||
|
|
||||||
|
channel.mMeta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_PUBLIC;
|
||||||
|
|
||||||
|
channel.mMeta.mCircleId.clear();
|
||||||
|
channel.mMeta.mInternalCircle.clear();
|
||||||
|
|
||||||
|
switch(circleType)
|
||||||
|
{
|
||||||
|
case RsGxsCircleType::NODES_GROUP:
|
||||||
|
channel.mMeta.mInternalCircle = circleId; break;
|
||||||
|
case RsGxsCircleType::EXTERNAL:
|
||||||
|
channel.mMeta.mCircleId = circleId; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the channel
|
||||||
|
channel.mDescription = description;
|
||||||
|
channel.mImage = thumbnail;
|
||||||
|
|
||||||
|
uint32_t token;
|
||||||
|
if(!createGroup(token, channel))
|
||||||
|
{
|
||||||
|
errorMessage = "Failed creating GXS group.";
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " Error! " << errorMessage
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for the group creation to complete.
|
||||||
|
RsTokenService::GxsRequestStatus wSt =
|
||||||
|
waitToken( token, std::chrono::milliseconds(5000),
|
||||||
|
std::chrono::milliseconds(20) );
|
||||||
|
if(wSt != RsTokenService::COMPLETE)
|
||||||
|
{
|
||||||
|
errorMessage = "GXS operation waitToken failed with: "
|
||||||
|
+ std::to_string(wSt);
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " Error! " << errorMessage
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!RsGenExchange::getPublishedGroupMeta(token, channel.mMeta))
|
||||||
|
{
|
||||||
|
errorMessage = "Failure getting updated group data.";
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " Error! " << errorMessage
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
channelId = channel.mMeta.mGroupId;
|
||||||
|
|
||||||
|
#ifdef RS_DEEP_SEARCH
|
||||||
|
DeepSearch::indexChannelGroup(channel);
|
||||||
|
#endif // RS_DEEP_SEARCH
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool p3GxsChannels::createChannel(RsGxsChannelGroup& channel)
|
bool p3GxsChannels::createChannel(RsGxsChannelGroup& channel)
|
||||||
{
|
{
|
||||||
uint32_t token;
|
uint32_t token;
|
||||||
|
@ -1086,33 +1207,101 @@ bool p3GxsChannels::createChannel(RsGxsChannelGroup& channel)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool p3GxsChannels::createComment(RsGxsComment& comment)
|
bool p3GxsChannels::createVoteV2(
|
||||||
|
const RsGxsGroupId& channelId, const RsGxsMessageId& postId,
|
||||||
|
const RsGxsMessageId& commentId, const RsGxsId& authorId,
|
||||||
|
RsGxsVoteType tVote, RsGxsMessageId& voteId, std::string& errorMessage )
|
||||||
{
|
{
|
||||||
|
std::vector<RsGxsChannelGroup> channelsInfo;
|
||||||
|
if(!getChannelsInfo(std::list<RsGxsGroupId>({channelId}),channelsInfo))
|
||||||
|
{
|
||||||
|
errorMessage = "Channel with Id " + channelId.toStdString()
|
||||||
|
+ " does not exist.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(commentId.isNull())
|
||||||
|
{
|
||||||
|
errorMessage = "You cannot vote on null comment "
|
||||||
|
+ commentId.toStdString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<RsGxsMessageId> s({commentId});
|
||||||
|
std::vector<RsGxsChannelPost> posts;
|
||||||
|
std::vector<RsGxsComment> comments;
|
||||||
|
|
||||||
|
if(!getChannelContent(channelId, s, posts, comments))
|
||||||
|
{
|
||||||
|
errorMessage = "You cannot vote on comment "
|
||||||
|
+ commentId.toStdString() + " of channel with Id "
|
||||||
|
+ channelId.toStdString()
|
||||||
|
+ ": this comment does not exists locally!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// is the ID a comment ID or a post ID?
|
||||||
|
// It should be comment => should have a parent ID
|
||||||
|
if(posts.front().mMeta.mParentId.isNull())
|
||||||
|
{
|
||||||
|
errorMessage = "You cannot vote on channel message "
|
||||||
|
+ commentId.toStdString() + " of channel with Id "
|
||||||
|
+ channelId.toStdString()
|
||||||
|
+ ": given id refers to a post, not a comment!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( tVote != RsGxsVoteType::NONE
|
||||||
|
&& tVote != RsGxsVoteType::UP
|
||||||
|
&& tVote != RsGxsVoteType::DOWN )
|
||||||
|
{
|
||||||
|
errorMessage = "Your vote to channel with Id "
|
||||||
|
+ channelId.toStdString() + " has wrong vote type. "
|
||||||
|
+ " Only RsGxsVoteType::NONE, RsGxsVoteType::UP, "
|
||||||
|
+ "RsGxsVoteType::DOWN are accepted.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!rsIdentity->isOwnId(authorId))
|
||||||
|
{
|
||||||
|
errorMessage = "You cannot vote to channel with Id "
|
||||||
|
+ channelId.toStdString() + " with identity "
|
||||||
|
+ authorId.toStdString() + " because it is not yours.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the vote
|
||||||
|
RsGxsVote vote;
|
||||||
|
vote.mMeta.mGroupId = channelId;
|
||||||
|
vote.mMeta.mThreadId = postId;
|
||||||
|
vote.mMeta.mParentId = commentId;
|
||||||
|
vote.mMeta.mAuthorId = authorId;
|
||||||
|
vote.mVoteType = static_cast<uint32_t>(tVote);
|
||||||
|
|
||||||
uint32_t token;
|
uint32_t token;
|
||||||
if(!createNewComment(token, comment))
|
if(!createNewVote(token, vote))
|
||||||
{
|
{
|
||||||
std::cerr << __PRETTY_FUNCTION__ << "Error! Failed creating comment."
|
errorMessage = "Error! Failed creating vote.";
|
||||||
<< std::endl;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(waitToken(token) != RsTokenService::COMPLETE)
|
if(waitToken(token) != RsTokenService::COMPLETE)
|
||||||
{
|
{
|
||||||
std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed."
|
errorMessage = "GXS operation failed.";
|
||||||
<< std::endl;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!RsGenExchange::getPublishedMsgMeta(token, comment.mMeta))
|
if(!RsGenExchange::getPublishedMsgMeta(token, vote.mMeta))
|
||||||
{
|
{
|
||||||
std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting generated "
|
errorMessage = "Failure getting generated vote data.";
|
||||||
<< " comment data." << std::endl;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
voteId = vote.mMeta.mMsgId;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @deprecated use createVoteV2 instead
|
||||||
bool p3GxsChannels::createVote(RsGxsVote& vote)
|
bool p3GxsChannels::createVote(RsGxsVote& vote)
|
||||||
{
|
{
|
||||||
uint32_t token;
|
uint32_t token;
|
||||||
|
@ -1171,11 +1360,64 @@ bool p3GxsChannels::editChannel(RsGxsChannelGroup& channel)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool p3GxsChannels::createPost(RsGxsChannelPost& post)
|
bool p3GxsChannels::createPostV2(
|
||||||
|
const RsGxsGroupId& channelId, const std::string& title,
|
||||||
|
const std::string& body, const std::list<RsGxsFile>& files,
|
||||||
|
const RsGxsImage& thumbnail, const RsGxsMessageId& origPostId,
|
||||||
|
RsGxsMessageId& postId, std::string& errorMessage )
|
||||||
{
|
{
|
||||||
|
// Do some checks
|
||||||
|
|
||||||
|
std::vector<RsGxsChannelGroup> channelsInfo;
|
||||||
|
|
||||||
|
if(!getChannelsInfo(std::list<RsGxsGroupId>({channelId}),channelsInfo))
|
||||||
|
{
|
||||||
|
errorMessage = "Channel with Id " + channelId.toStdString() +
|
||||||
|
" does not exist.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RsGxsChannelGroup& cg(*channelsInfo.begin());
|
||||||
|
|
||||||
|
if(!(cg.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_PUBLISH))
|
||||||
|
{
|
||||||
|
errorMessage = "You cannot post to channel with Id " +
|
||||||
|
channelId.toStdString() + ": missing publish rights!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!origPostId.isNull())
|
||||||
|
{
|
||||||
|
std::set<RsGxsMessageId> s({origPostId});
|
||||||
|
std::vector<RsGxsChannelPost> posts;
|
||||||
|
std::vector<RsGxsComment> comments;
|
||||||
|
|
||||||
|
if(!getChannelContent(channelId,s,posts,comments))
|
||||||
|
{
|
||||||
|
errorMessage = "You cannot edit post " + origPostId.toStdString()
|
||||||
|
+ " of channel with Id " + channelId.toStdString()
|
||||||
|
+ ": this post does not exist locally!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the post
|
||||||
|
RsGxsChannelPost post;
|
||||||
|
|
||||||
|
post.mMeta.mGroupId = channelId;
|
||||||
|
post.mMeta.mOrigMsgId = origPostId;
|
||||||
|
post.mMeta.mMsgName = title;
|
||||||
|
|
||||||
|
post.mMsg = body;
|
||||||
|
post.mFiles = files;
|
||||||
|
post.mThumbnail = thumbnail;
|
||||||
|
|
||||||
uint32_t token;
|
uint32_t token;
|
||||||
if( !createPost(token, post)
|
if(!createPost(token, post) || waitToken(token) != RsTokenService::COMPLETE)
|
||||||
|| waitToken(token) != RsTokenService::COMPLETE ) return false;
|
{
|
||||||
|
errorMessage = "GXS operation failed";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(RsGenExchange::getPublishedMsgMeta(token,post.mMeta))
|
if(RsGenExchange::getPublishedMsgMeta(token,post.mMeta))
|
||||||
{
|
{
|
||||||
|
@ -1183,12 +1425,150 @@ bool p3GxsChannels::createPost(RsGxsChannelPost& post)
|
||||||
DeepSearch::indexChannelPost(post);
|
DeepSearch::indexChannelPost(post);
|
||||||
#endif // RS_DEEP_SEARCH
|
#endif // RS_DEEP_SEARCH
|
||||||
|
|
||||||
|
postId = post.mMeta.mMsgId;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
errorMessage = "Failed to retrive created post metadata";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool p3GxsChannels::createCommentV2(const RsGxsGroupId& channelId,
|
||||||
|
const RsGxsMessageId& threadId,
|
||||||
|
const RsGxsMessageId& parentId,
|
||||||
|
const RsGxsId& authorId,
|
||||||
|
const std::string& comment,
|
||||||
|
RsGxsMessageId& commentMessageId,
|
||||||
|
std::string& errorMessage)
|
||||||
|
{
|
||||||
|
std::vector<RsGxsChannelGroup> channelsInfo;
|
||||||
|
if(!getChannelsInfo(std::list<RsGxsGroupId>({channelId}),channelsInfo))
|
||||||
|
{
|
||||||
|
errorMessage = "Channel with Id " + channelId.toStdString()
|
||||||
|
+ " does not exist.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<RsGxsChannelPost> posts;
|
||||||
|
std::vector<RsGxsComment> comments;
|
||||||
|
|
||||||
|
if(!getChannelContent( // does the post thread exist?
|
||||||
|
channelId,std::set<RsGxsMessageId>({threadId}), posts, comments ))
|
||||||
|
{
|
||||||
|
errorMessage = "You cannot comment post " + threadId.toStdString() +
|
||||||
|
" of channel with Id " + channelId.toStdString() +
|
||||||
|
": this post does not exists locally!";
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " Error: " << errorMessage
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that the post thread Id is actually that of a post thread
|
||||||
|
if(posts.size() != 1 || !posts[0].mMeta.mParentId.isNull())
|
||||||
|
{
|
||||||
|
errorMessage = "You cannot comment post " + threadId.toStdString() +
|
||||||
|
" of channel with Id " + channelId.toStdString() +
|
||||||
|
": supplied threadId is not a thread, or parentMsgId is not a" +
|
||||||
|
" comment!";
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " Error: " << errorMessage
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!parentId.isNull())
|
||||||
|
if(!getChannelContent( // does the post thread exist?
|
||||||
|
channelId,std::set<RsGxsMessageId>({parentId}),posts,comments ))
|
||||||
|
{
|
||||||
|
errorMessage = "You cannot comment post " + parentId.toStdString() +
|
||||||
|
": supplied parent comment Id is not a comment!";
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " Error: " << errorMessage
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if(comments.size() != 1 || comments[0].mMeta.mParentId.isNull())
|
||||||
|
{ // is the comment parent actually a comment?
|
||||||
|
errorMessage = "You cannot comment post " + parentId.toStdString()
|
||||||
|
+ " of channel with Id " + channelId.toStdString() +
|
||||||
|
": supplied mParentMsgId is not a comment Id!";
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " Error: " << errorMessage
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!rsIdentity->isOwnId(authorId)) // is the voter ID actually ours?
|
||||||
|
{
|
||||||
|
errorMessage = "You cannot comment to channel with Id " +
|
||||||
|
channelId.toStdString() + " with identity " +
|
||||||
|
authorId.toStdString() + " because it is not yours.";
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " Error: " << errorMessage
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now create the comment
|
||||||
|
RsGxsComment cmt;
|
||||||
|
cmt.mMeta.mGroupId = channelId;
|
||||||
|
cmt.mMeta.mThreadId = threadId;
|
||||||
|
cmt.mMeta.mParentId = parentId;
|
||||||
|
cmt.mMeta.mAuthorId = authorId;
|
||||||
|
cmt.mComment = comment;
|
||||||
|
|
||||||
|
uint32_t token;
|
||||||
|
if(!createNewComment(token, cmt))
|
||||||
|
{
|
||||||
|
errorMessage = "Failed creating comment.";
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " Error: " << errorMessage
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(waitToken(token) != RsTokenService::COMPLETE)
|
||||||
|
{
|
||||||
|
errorMessage = "GXS operation failed.";
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " Error: " << errorMessage
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!RsGenExchange::getPublishedMsgMeta(token, cmt.mMeta))
|
||||||
|
{
|
||||||
|
errorMessage = "Failure getting created comment data.";
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " Error: " << errorMessage
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
commentMessageId = cmt.mMeta.mMsgId;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool p3GxsChannels::createComment(RsGxsComment& comment) // deprecated
|
||||||
|
{
|
||||||
|
uint32_t token;
|
||||||
|
if(!createNewComment(token, comment))
|
||||||
|
{
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " Error! Failed creating comment."
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(waitToken(token) != RsTokenService::COMPLETE)
|
||||||
|
{
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " Error! GXS operation failed."
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!RsGenExchange::getPublishedMsgMeta(token, comment.mMeta))
|
||||||
|
{
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << " Error! Failure getting generated "
|
||||||
|
<< " comment data." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool p3GxsChannels::subscribeToChannel(
|
bool p3GxsChannels::subscribeToChannel(
|
||||||
const RsGxsGroupId& groupId, bool subscribe )
|
const RsGxsGroupId& groupId, bool subscribe )
|
||||||
{
|
{
|
||||||
|
@ -1428,13 +1808,31 @@ bool p3GxsChannels::updateGroup(uint32_t &token, RsGxsChannelGroup &group)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @deprecated use createPostV2 instead
|
||||||
|
bool p3GxsChannels::createPost(RsGxsChannelPost& post)
|
||||||
|
{
|
||||||
|
uint32_t token;
|
||||||
|
if( !createPost(token, post)
|
||||||
|
|| waitToken(token) != RsTokenService::COMPLETE ) return false;
|
||||||
|
|
||||||
|
if(RsGenExchange::getPublishedMsgMeta(token,post.mMeta))
|
||||||
|
{
|
||||||
|
#ifdef RS_DEEP_SEARCH
|
||||||
|
DeepSearch::indexChannelPost(post);
|
||||||
|
#endif // RS_DEEP_SEARCH
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool p3GxsChannels::createPost(uint32_t &token, RsGxsChannelPost &msg)
|
bool p3GxsChannels::createPost(uint32_t &token, RsGxsChannelPost &msg)
|
||||||
{
|
{
|
||||||
#ifdef GXSCHANNELS_DEBUG
|
#ifdef GXSCHANNELS_DEBUG
|
||||||
std::cerr << "p3GxsChannels::createChannelPost() GroupId: " << msg.mMeta.mGroupId;
|
std::cerr << __PRETTY_FUNCTION__ << " GroupId: " << msg.mMeta.mGroupId
|
||||||
std::cerr << std::endl;
|
<< std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RsGxsChannelPostItem* msgItem = new RsGxsChannelPostItem();
|
RsGxsChannelPostItem* msgItem = new RsGxsChannelPostItem();
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* libretroshare: retroshare core library *
|
* libretroshare: retroshare core library *
|
||||||
* *
|
* *
|
||||||
* Copyright (C) 2012 Robert Fernie <retroshare@lunamutt.com> *
|
* Copyright (C) 2012 Robert Fernie <retroshare@lunamutt.com> *
|
||||||
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org> *
|
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||||
* *
|
* *
|
||||||
* This program is free software: you can redistribute it and/or modify *
|
* This program is free software: you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -20,14 +20,14 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
||||||
* *
|
* *
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
#ifndef P3_GXSCHANNELS_SERVICE_HEADER
|
#pragma once
|
||||||
#define P3_GXSCHANNELS_SERVICE_HEADER
|
|
||||||
|
|
||||||
|
|
||||||
#include "retroshare/rsgxschannels.h"
|
#include "retroshare/rsgxschannels.h"
|
||||||
#include "services/p3gxscommon.h"
|
#include "services/p3gxscommon.h"
|
||||||
#include "gxs/rsgenexchange.h"
|
#include "gxs/rsgenexchange.h"
|
||||||
#include "gxs/gxstokenqueue.h"
|
#include "gxs/gxstokenqueue.h"
|
||||||
|
#include "util/rsmemory.h"
|
||||||
|
|
||||||
#include "util/rstickevent.h"
|
#include "util/rstickevent.h"
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SSGxsChannelGroup
|
class SSGxsChannelGroup
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -191,23 +192,64 @@ virtual bool ExtraFileRemove(const RsFileHash &hash);
|
||||||
std::vector<RsGxsComment>& comments );
|
std::vector<RsGxsComment>& comments );
|
||||||
|
|
||||||
/// Implementation of @see RsGxsChannels::getContentSummaries
|
/// Implementation of @see RsGxsChannels::getContentSummaries
|
||||||
virtual bool getContentSummaries( const RsGxsGroupId& channelId,
|
virtual bool getContentSummaries(
|
||||||
std::vector<RsMsgMetaData>& summaries );
|
const RsGxsGroupId& channelId,
|
||||||
|
std::vector<RsMsgMetaData>& summaries ) override;
|
||||||
|
|
||||||
/// Implementation of @see RsGxsChannels::createChannel
|
/// Implementation of @see RsGxsChannels::createChannelV2
|
||||||
virtual bool createChannel(RsGxsChannelGroup& channel);
|
virtual bool createChannelV2(
|
||||||
|
const std::string& name, const std::string& description,
|
||||||
|
const RsGxsImage& thumbnail = RsGxsImage(),
|
||||||
|
const RsGxsId& authorId = RsGxsId(),
|
||||||
|
RsGxsCircleType circleType = RsGxsCircleType::PUBLIC,
|
||||||
|
const RsGxsCircleId& circleId = RsGxsCircleId(),
|
||||||
|
RsGxsGroupId& channelId = RS_DEFAULT_STORAGE_PARAM(RsGxsGroupId),
|
||||||
|
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
|
||||||
|
) override;
|
||||||
|
|
||||||
|
/// @deprecated Implementation of @see RsGxsChannels::createComment
|
||||||
|
RS_DEPRECATED_FOR(createCommentV2)
|
||||||
|
virtual bool createComment(RsGxsComment& comment) override;
|
||||||
|
|
||||||
/// Implementation of @see RsGxsChannels::createComment
|
/// Implementation of @see RsGxsChannels::createComment
|
||||||
virtual bool createComment(RsGxsComment& comment);
|
virtual bool createCommentV2(
|
||||||
|
const RsGxsGroupId& channelId, const RsGxsMessageId& threadId,
|
||||||
|
const RsGxsMessageId& parentId, const RsGxsId& authorId,
|
||||||
|
const std::string& comment,
|
||||||
|
RsGxsMessageId& commentMessageId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId),
|
||||||
|
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
|
||||||
|
) override;
|
||||||
|
|
||||||
/// Implementation of @see RsGxsChannels::editChannel
|
/// Implementation of @see RsGxsChannels::editChannel
|
||||||
virtual bool editChannel(RsGxsChannelGroup& channel);
|
virtual bool editChannel(RsGxsChannelGroup& channel) override;
|
||||||
|
|
||||||
/// Implementation of @see RsGxsChannels::createPost
|
/// @deprecated Implementation of @see RsGxsChannels::createPost
|
||||||
virtual bool createPost(RsGxsChannelPost& post);
|
RS_DEPRECATED_FOR(createPostV2)
|
||||||
|
virtual bool createPost(RsGxsChannelPost& post) override;
|
||||||
|
|
||||||
/// Implementation of @see RsGxsChannels::createVote
|
/// Implementation of @see RsGxsChannels::createPostV2
|
||||||
virtual bool createVote(RsGxsVote& vote);
|
bool createPostV2(
|
||||||
|
const RsGxsGroupId& channelId, const std::string& title,
|
||||||
|
const std::string& body,
|
||||||
|
const std::list<RsGxsFile>& files = std::list<RsGxsFile>(),
|
||||||
|
const RsGxsImage& thumbnail = RsGxsImage(),
|
||||||
|
const RsGxsMessageId& origPostId = RsGxsMessageId(),
|
||||||
|
RsGxsMessageId& postId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId),
|
||||||
|
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
|
||||||
|
) override;
|
||||||
|
|
||||||
|
/// @deprecated Implementation of @see RsGxsChannels::createVote
|
||||||
|
RS_DEPRECATED_FOR(createVoteV2)
|
||||||
|
virtual bool createVote(RsGxsVote& vote) override;
|
||||||
|
|
||||||
|
/// Implementation of @see RsGxsChannels::createVoteV2
|
||||||
|
virtual bool createVoteV2(
|
||||||
|
const RsGxsGroupId& channelId, const RsGxsMessageId& postId,
|
||||||
|
const RsGxsMessageId& commentId, const RsGxsId& authorId,
|
||||||
|
RsGxsVoteType vote,
|
||||||
|
RsGxsMessageId& voteId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId),
|
||||||
|
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
|
||||||
|
) override;
|
||||||
|
|
||||||
/// Implementation of @see RsGxsChannels::subscribeToChannel
|
/// Implementation of @see RsGxsChannels::subscribeToChannel
|
||||||
virtual bool subscribeToChannel( const RsGxsGroupId &groupId,
|
virtual bool subscribeToChannel( const RsGxsGroupId &groupId,
|
||||||
|
@ -219,6 +261,10 @@ virtual bool ExtraFileRemove(const RsFileHash &hash);
|
||||||
virtual bool shareChannelKeys(
|
virtual bool shareChannelKeys(
|
||||||
const RsGxsGroupId& channelId, const std::set<RsPeerId>& peers );
|
const RsGxsGroupId& channelId, const std::set<RsPeerId>& peers );
|
||||||
|
|
||||||
|
/// Implementation of @see RsGxsChannels::createChannel
|
||||||
|
RS_DEPRECATED_FOR(createChannelV2)
|
||||||
|
virtual bool createChannel(RsGxsChannelGroup& channel) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Overloaded from GxsTokenQueue for Request callbacks.
|
// Overloaded from GxsTokenQueue for Request callbacks.
|
||||||
virtual void handleResponse(uint32_t token, uint32_t req_type);
|
virtual void handleResponse(uint32_t token, uint32_t req_type);
|
||||||
|
@ -263,9 +309,11 @@ bool generateGroup(uint32_t &token, std::string groupName);
|
||||||
class ChannelDummyRef
|
class ChannelDummyRef
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ChannelDummyRef() { return; }
|
ChannelDummyRef() {}
|
||||||
ChannelDummyRef(const RsGxsGroupId &grpId, const RsGxsMessageId &threadId, const RsGxsMessageId &msgId)
|
ChannelDummyRef(
|
||||||
:mGroupId(grpId), mThreadId(threadId), mMsgId(msgId) { return; }
|
const RsGxsGroupId &grpId, const RsGxsMessageId &threadId,
|
||||||
|
const RsGxsMessageId &msgId ) :
|
||||||
|
mGroupId(grpId), mThreadId(threadId), mMsgId(msgId) {}
|
||||||
|
|
||||||
RsGxsGroupId mGroupId;
|
RsGxsGroupId mGroupId;
|
||||||
RsGxsMessageId mThreadId;
|
RsGxsMessageId mThreadId;
|
||||||
|
@ -309,5 +357,3 @@ bool generateGroup(uint32_t &token, std::string groupName);
|
||||||
/// Cleanup mSearchCallbacksMap and mDistantChannelsCallbacksMap
|
/// Cleanup mSearchCallbacksMap and mDistantChannelsCallbacksMap
|
||||||
void cleanTimedOutCallbacks();
|
void cleanTimedOutCallbacks();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -79,9 +79,8 @@ bool p3Posted::getGroupData(const uint32_t &token, std::vector<RsPostedGroup> &g
|
||||||
RsGxsPostedGroupItem* item = dynamic_cast<RsGxsPostedGroupItem*>(*vit);
|
RsGxsPostedGroupItem* item = dynamic_cast<RsGxsPostedGroupItem*>(*vit);
|
||||||
if (item)
|
if (item)
|
||||||
{
|
{
|
||||||
RsPostedGroup grp = item->mGroup;
|
RsPostedGroup grp;
|
||||||
item->mGroup.mMeta = item->meta;
|
item->toPostedGroup(grp, true);
|
||||||
grp.mMeta = item->mGroup.mMeta;
|
|
||||||
delete item;
|
delete item;
|
||||||
groups.push_back(grp);
|
groups.push_back(grp);
|
||||||
}
|
}
|
||||||
|
@ -265,8 +264,8 @@ bool p3Posted::createGroup(uint32_t &token, RsPostedGroup &group)
|
||||||
std::cerr << "p3Posted::createGroup()" << std::endl;
|
std::cerr << "p3Posted::createGroup()" << std::endl;
|
||||||
|
|
||||||
RsGxsPostedGroupItem* grpItem = new RsGxsPostedGroupItem();
|
RsGxsPostedGroupItem* grpItem = new RsGxsPostedGroupItem();
|
||||||
grpItem->mGroup = group;
|
grpItem->fromPostedGroup(group, true);
|
||||||
grpItem->meta = group.mMeta;
|
|
||||||
|
|
||||||
RsGenExchange::publishGroup(token, grpItem);
|
RsGenExchange::publishGroup(token, grpItem);
|
||||||
return true;
|
return true;
|
||||||
|
@ -278,8 +277,8 @@ bool p3Posted::updateGroup(uint32_t &token, RsPostedGroup &group)
|
||||||
std::cerr << "p3Posted::updateGroup()" << std::endl;
|
std::cerr << "p3Posted::updateGroup()" << std::endl;
|
||||||
|
|
||||||
RsGxsPostedGroupItem* grpItem = new RsGxsPostedGroupItem();
|
RsGxsPostedGroupItem* grpItem = new RsGxsPostedGroupItem();
|
||||||
grpItem->mGroup = group;
|
grpItem->fromPostedGroup(group, true);
|
||||||
grpItem->meta = group.mMeta;
|
|
||||||
|
|
||||||
RsGenExchange::updateGroup(token, grpItem);
|
RsGenExchange::updateGroup(token, grpItem);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -53,6 +53,7 @@ RsItem *RsTurtleSerialiser::create_item(uint16_t service,uint8_t item_subtype) c
|
||||||
case RS_TURTLE_SUBTYPE_OPEN_TUNNEL : return new RsTurtleOpenTunnelItem();
|
case RS_TURTLE_SUBTYPE_OPEN_TUNNEL : return new RsTurtleOpenTunnelItem();
|
||||||
case RS_TURTLE_SUBTYPE_TUNNEL_OK : return new RsTurtleTunnelOkItem();
|
case RS_TURTLE_SUBTYPE_TUNNEL_OK : return new RsTurtleTunnelOkItem();
|
||||||
case RS_TURTLE_SUBTYPE_GENERIC_DATA : return new RsTurtleGenericDataItem();
|
case RS_TURTLE_SUBTYPE_GENERIC_DATA : return new RsTurtleGenericDataItem();
|
||||||
|
case RS_TURTLE_SUBTYPE_GENERIC_FAST_DATA : return new RsTurtleGenericFastDataItem();
|
||||||
case RS_TURTLE_SUBTYPE_GENERIC_SEARCH_REQUEST : return new RsTurtleGenericSearchRequestItem();
|
case RS_TURTLE_SUBTYPE_GENERIC_SEARCH_REQUEST : return new RsTurtleGenericSearchRequestItem();
|
||||||
case RS_TURTLE_SUBTYPE_GENERIC_SEARCH_RESULT : return new RsTurtleGenericSearchResultItem();
|
case RS_TURTLE_SUBTYPE_GENERIC_SEARCH_RESULT : return new RsTurtleGenericSearchResultItem();
|
||||||
|
|
||||||
|
@ -244,8 +245,12 @@ void RsTurtleTunnelOkItem::serial_process(RsGenericSerializer::SerializeJob j,Rs
|
||||||
void RsTurtleGenericDataItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
void RsTurtleGenericDataItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
||||||
{
|
{
|
||||||
RsTypeSerializer::serial_process<uint32_t>(j,ctx,tunnel_id ,"tunnel_id") ;
|
RsTypeSerializer::serial_process<uint32_t>(j,ctx,tunnel_id ,"tunnel_id") ;
|
||||||
|
|
||||||
RsTypeSerializer::TlvMemBlock_proxy prox(data_bytes,data_size) ;
|
RsTypeSerializer::TlvMemBlock_proxy prox(data_bytes,data_size) ;
|
||||||
|
RsTypeSerializer::serial_process(j,ctx,prox,"data bytes") ;
|
||||||
|
}
|
||||||
|
void RsTurtleGenericFastDataItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
||||||
|
{
|
||||||
|
RsTypeSerializer::serial_process<uint32_t>(j,ctx,tunnel_id ,"tunnel_id") ;
|
||||||
|
RsTypeSerializer::TlvMemBlock_proxy prox(data_bytes,data_size) ;
|
||||||
RsTypeSerializer::serial_process(j,ctx,prox,"data bytes") ;
|
RsTypeSerializer::serial_process(j,ctx,prox,"data bytes") ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ const uint8_t RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST = 0x11 ;
|
||||||
// const uint8_t RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST = 0x13 ;
|
// const uint8_t RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST = 0x13 ;
|
||||||
const uint8_t RS_TURTLE_SUBTYPE_CHUNK_CRC = 0x14 ;
|
const uint8_t RS_TURTLE_SUBTYPE_CHUNK_CRC = 0x14 ;
|
||||||
const uint8_t RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST = 0x15 ;
|
const uint8_t RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST = 0x15 ;
|
||||||
|
const uint8_t RS_TURTLE_SUBTYPE_GENERIC_FAST_DATA = 0x16 ;
|
||||||
|
|
||||||
|
|
||||||
class TurtleSearchRequestInfo ;
|
class TurtleSearchRequestInfo ;
|
||||||
|
@ -331,6 +332,28 @@ class RsTurtleGenericDataItem: public RsTurtleGenericTunnelItem
|
||||||
void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
|
void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Same, but with a fact priority. Can rather be used for e.g. distant chat.
|
||||||
|
//
|
||||||
|
class RsTurtleGenericFastDataItem: public RsTurtleGenericTunnelItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RsTurtleGenericFastDataItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_GENERIC_FAST_DATA), data_size(0), data_bytes(0) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_GENERIC_FAST_DATA);}
|
||||||
|
virtual ~RsTurtleGenericFastDataItem() { if(data_bytes != NULL) free(data_bytes) ; }
|
||||||
|
|
||||||
|
virtual bool shouldStampTunnel() const { return true ; }
|
||||||
|
|
||||||
|
uint32_t data_size ;
|
||||||
|
void *data_bytes ;
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
free(data_bytes) ;
|
||||||
|
data_bytes = NULL ;
|
||||||
|
data_size = 0;
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
|
||||||
|
};
|
||||||
/***********************************************************************************/
|
/***********************************************************************************/
|
||||||
/* Turtle Serialiser class */
|
/* Turtle Serialiser class */
|
||||||
/***********************************************************************************/
|
/***********************************************************************************/
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
* *
|
* *
|
||||||
* libretroshare: retroshare core library *
|
* libretroshare: retroshare core library *
|
||||||
* *
|
* *
|
||||||
* Copyright 2012-2012 by Cyril Soler <csoler@users.sourceforge.net> *
|
* Copyright 2012 Cyril Soler <csoler@users.sourceforge.net> *
|
||||||
|
* Copyright 2019 Gioacchino Mazzurco <gio@altermundi.net> *
|
||||||
* *
|
* *
|
||||||
* This program is free software: you can redistribute it and/or modify *
|
* This program is free software: you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
@ -21,9 +22,45 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <util/stacktrace.h>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "util/stacktrace.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Shorthand macro to declare optional functions output parameters
|
||||||
|
* To define an optional output paramether use the following syntax
|
||||||
|
*
|
||||||
|
\code{.cpp}
|
||||||
|
bool myFunnyFunction(
|
||||||
|
int mandatoryParamether,
|
||||||
|
BigType& myOptionalOutput = RS_DEFAULT_STORAGE_PARAM(BigType) )
|
||||||
|
\endcode
|
||||||
|
*
|
||||||
|
* The function caller then can call myFunnyFunction either passing
|
||||||
|
* myOptionalOutput parameter or not.
|
||||||
|
* @see RsGxsChannels methods for real usage examples.
|
||||||
|
*
|
||||||
|
* @details
|
||||||
|
* When const references are used to pass function parameters it is easy do make
|
||||||
|
* those params optional by defining a default value in the function
|
||||||
|
* declaration, because a temp is accepted as default parameter in those cases.
|
||||||
|
* It is not as simple when one want to make optional a non-const reference
|
||||||
|
* parameter that is usually used as output, in that case as a temp is in theory
|
||||||
|
* not acceptable.
|
||||||
|
* Yet it is possible to overcome that limitation with the following trick:
|
||||||
|
* If not passed as parameter the storage for the output parameter can be
|
||||||
|
* dinamically allocated directly by the function call, to avoid leaking memory
|
||||||
|
* on each function call the pointer to that storage is made unique so once the
|
||||||
|
* function returns it goes out of scope and is automatically deleted.
|
||||||
|
* About performance overhead: std::unique_ptr have very good performance and
|
||||||
|
* modern compilers may be even able to avoid the dynamic allocation in this
|
||||||
|
* case, any way the allocation would only happen if the parameter is not
|
||||||
|
* passed, so any effect on performace would happen only in case where the
|
||||||
|
* function is called without the parameter.
|
||||||
|
*/
|
||||||
|
#define RS_DEFAULT_STORAGE_PARAM(Type) *std::unique_ptr<Type>(new Type)
|
||||||
|
|
||||||
void *rs_malloc(size_t size) ;
|
void *rs_malloc(size_t size) ;
|
||||||
|
|
||||||
|
|
|
@ -201,7 +201,7 @@ void RsThread::start(const std::string &threadName)
|
||||||
if(threadName.length() > 15)
|
if(threadName.length() > 15)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_THREADS
|
#ifdef DEBUG_THREADS
|
||||||
THREAD_DEBUG << "RsThread::start called with to long name '" << name << "' truncating..." << std::endl;
|
THREAD_DEBUG << "RsThread::start called with to long name '" << threadName << "' truncating..." << std::endl;
|
||||||
#endif
|
#endif
|
||||||
RS_pthread_setname_np(mTid, threadName.substr(0, 15).c_str());
|
RS_pthread_setname_np(mTid, threadName.substr(0, 15).c_str());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -329,13 +329,15 @@ void SearchDialog::searchResultWidgetCustomPopupMenu( QPoint /*point*/ )
|
||||||
QMenu contextMnu(this) ;
|
QMenu contextMnu(this) ;
|
||||||
|
|
||||||
contextMnu.addAction(QIcon(IMAGE_START), tr("Download"), this, SLOT(download())) ;
|
contextMnu.addAction(QIcon(IMAGE_START), tr("Download"), this, SLOT(download())) ;
|
||||||
contextMnu.addAction(QIcon(IMAGE_BANFILE), tr("Mark as bad"), this, SLOT(ban())) ;
|
|
||||||
contextMnu.addSeparator();//--------------------------------------
|
contextMnu.addSeparator();//--------------------------------------
|
||||||
|
|
||||||
contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyResultLink())) ;
|
contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyResultLink())) ;
|
||||||
contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Send RetroShare Link"), this, SLOT(sendLinkTo())) ;
|
contextMnu.addAction(QIcon(IMAGE_COPYLINK), tr("Send RetroShare Link"), this, SLOT(sendLinkTo())) ;
|
||||||
contextMnu.addSeparator();//--------------------------------------
|
contextMnu.addSeparator();//--------------------------------------
|
||||||
|
|
||||||
|
contextMnu.addAction(QIcon(IMAGE_BANFILE), tr("Mark as bad"), this, SLOT(ban())) ;
|
||||||
|
contextMnu.addSeparator();//--------------------------------------
|
||||||
|
|
||||||
QMenu collectionMenu(tr("Collection"), this);
|
QMenu collectionMenu(tr("Collection"), this);
|
||||||
collectionMenu.setIcon(QIcon(IMAGE_LIBRARY));
|
collectionMenu.setIcon(QIcon(IMAGE_LIBRARY));
|
||||||
collectionMenu.addAction(collCreateAct);
|
collectionMenu.addAction(collCreateAct);
|
||||||
|
|
|
@ -1878,6 +1878,7 @@ void IdDialog::insertIdDetails(uint32_t token)
|
||||||
if (isOwnId)
|
if (isOwnId)
|
||||||
{
|
{
|
||||||
mStateHelper->setWidgetEnabled(ui->ownOpinion_CB, false);
|
mStateHelper->setWidgetEnabled(ui->ownOpinion_CB, false);
|
||||||
|
mStateHelper->setWidgetEnabled(ui->autoBanIdentities_CB, false);
|
||||||
ui->editIdentity->setEnabled(true);
|
ui->editIdentity->setEnabled(true);
|
||||||
ui->removeIdentity->setEnabled(true);
|
ui->removeIdentity->setEnabled(true);
|
||||||
ui->chatIdentity->setEnabled(false);
|
ui->chatIdentity->setEnabled(false);
|
||||||
|
@ -1887,6 +1888,7 @@ void IdDialog::insertIdDetails(uint32_t token)
|
||||||
{
|
{
|
||||||
// No Reputation yet!
|
// No Reputation yet!
|
||||||
mStateHelper->setWidgetEnabled(ui->ownOpinion_CB, true);
|
mStateHelper->setWidgetEnabled(ui->ownOpinion_CB, true);
|
||||||
|
mStateHelper->setWidgetEnabled(ui->autoBanIdentities_CB, true);
|
||||||
ui->editIdentity->setEnabled(false);
|
ui->editIdentity->setEnabled(false);
|
||||||
ui->removeIdentity->setEnabled(false);
|
ui->removeIdentity->setEnabled(false);
|
||||||
ui->chatIdentity->setEnabled(true);
|
ui->chatIdentity->setEnabled(true);
|
||||||
|
@ -2086,7 +2088,7 @@ void IdDialog::modifyReputation()
|
||||||
case 2: op = RsOpinion::POSITIVE; break;
|
case 2: op = RsOpinion::POSITIVE; break;
|
||||||
default:
|
default:
|
||||||
std::cerr << "Wrong value from opinion combobox. Bug??" << std::endl;
|
std::cerr << "Wrong value from opinion combobox. Bug??" << std::endl;
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
rsReputations->setOwnOpinion(id,op);
|
rsReputations->setOwnOpinion(id,op);
|
||||||
|
|
||||||
|
|
|
@ -117,7 +117,7 @@
|
||||||
<enum>Qt::NoFocus</enum>
|
<enum>Qt::NoFocus</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../icons.qrc">
|
<iconset resource="../images.qrc">
|
||||||
<normaloff>:/icons/help_64.png</normaloff>:/icons/help_64.png</iconset>
|
<normaloff>:/icons/help_64.png</normaloff>:/icons/help_64.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable">
|
<property name="checkable">
|
||||||
|
@ -284,7 +284,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1372</width>
|
<width>1372</width>
|
||||||
<height>1000</height>
|
<height>999</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="scrollAreaWidgetContentsVLayout">
|
<layout class="QVBoxLayout" name="scrollAreaWidgetContentsVLayout">
|
||||||
|
@ -562,7 +562,11 @@ border-image: url(:/images/closepressed.png)
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="2" colspan="2">
|
<item row="2" column="2" colspan="2">
|
||||||
<widget class="QLineEdit" name="lineEdit_Type"/>
|
<widget class="QLineEdit" name="lineEdit_Type">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="0" colspan="2">
|
<item row="0" column="0" colspan="2">
|
||||||
<widget class="QLabel" name="label_Nickname">
|
<widget class="QLabel" name="label_Nickname">
|
||||||
|
@ -646,7 +650,11 @@ p, li { white-space: pre-wrap; }
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="2" colspan="2">
|
<item row="7" column="2" colspan="2">
|
||||||
<widget class="QLineEdit" name="lineEdit_LastUsed"/>
|
<widget class="QLineEdit" name="lineEdit_LastUsed">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QLabel" name="label_Type">
|
<widget class="QLabel" name="label_Type">
|
||||||
|
@ -891,7 +899,11 @@ p, li { white-space: pre-wrap; }
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="2">
|
<item row="6" column="2">
|
||||||
<widget class="QLineEdit" name="lineEdit_PublishTS"/>
|
<widget class="QLineEdit" name="lineEdit_PublishTS">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -1087,8 +1099,8 @@ p, li { white-space: pre-wrap; }
|
||||||
<tabstop>idTreeWidget</tabstop>
|
<tabstop>idTreeWidget</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../icons.qrc"/>
|
|
||||||
<include location="../images.qrc"/>
|
<include location="../images.qrc"/>
|
||||||
|
<include location="../icons.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
#include "gui/FileTransfer/SearchDialog.h"
|
#include "gui/FileTransfer/SearchDialog.h"
|
||||||
#include "gui/FileTransfer/SharedFilesDialog.h"
|
#include "gui/FileTransfer/SharedFilesDialog.h"
|
||||||
#include "gui/FileTransfer/TransfersDialog.h"
|
#include "gui/FileTransfer/TransfersDialog.h"
|
||||||
#include "MessagesDialog.h"
|
#include "gui/msgs/MessagesDialog.h"
|
||||||
#include "PluginsPage.h"
|
#include "PluginsPage.h"
|
||||||
#include "NewsFeed.h"
|
#include "NewsFeed.h"
|
||||||
#include "ShareManager.h"
|
#include "ShareManager.h"
|
||||||
|
@ -730,9 +730,12 @@ void MainWindow::updateStatus()
|
||||||
float downKb = 0;
|
float downKb = 0;
|
||||||
float upKb = 0;
|
float upKb = 0;
|
||||||
rsConfig->GetCurrentDataRates(downKb, upKb);
|
rsConfig->GetCurrentDataRates(downKb, upKb);
|
||||||
|
uint64_t down = 0;
|
||||||
|
uint64_t up = 0;
|
||||||
|
rsConfig->GetTrafficSum(down, up);
|
||||||
|
|
||||||
if (ratesstatus)
|
if (ratesstatus)
|
||||||
ratesstatus->getRatesStatus(downKb, upKb);
|
ratesstatus->getRatesStatus(downKb, down, upKb, up);
|
||||||
|
|
||||||
if(torstatus)
|
if(torstatus)
|
||||||
torstatus->getTorStatus();
|
torstatus->getTorStatus();
|
||||||
|
|
|
@ -35,6 +35,7 @@ public:
|
||||||
PostedGroupInfoData() : RsUserdata() {}
|
PostedGroupInfoData() : RsUserdata() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
QMap<RsGxsGroupId, QIcon> mIcon;
|
||||||
QMap<RsGxsGroupId, QString> mDescription;
|
QMap<RsGxsGroupId, QString> mDescription;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -102,17 +103,17 @@ QString PostedDialog::icon(IconType type)
|
||||||
case ICON_NEW:
|
case ICON_NEW:
|
||||||
return ":/icons/png/add.png";
|
return ":/icons/png/add.png";
|
||||||
case ICON_YOUR_GROUP:
|
case ICON_YOUR_GROUP:
|
||||||
return ":/icons/png/feedreader.png";
|
return "";
|
||||||
case ICON_SUBSCRIBED_GROUP:
|
case ICON_SUBSCRIBED_GROUP:
|
||||||
return ":/icons/png/feed-subscribed.png";
|
return "";
|
||||||
case ICON_POPULAR_GROUP:
|
case ICON_POPULAR_GROUP:
|
||||||
return ":/icons/png/feed-popular.png";
|
return "";
|
||||||
case ICON_OTHER_GROUP:
|
case ICON_OTHER_GROUP:
|
||||||
return ":/icons/png/feed-other.png";
|
return ":/icons/png/feed-other.png";
|
||||||
case ICON_SEARCH:
|
case ICON_SEARCH:
|
||||||
return ":/images/find.png";
|
return ":/images/find.png";
|
||||||
case ICON_DEFAULT:
|
case ICON_DEFAULT:
|
||||||
return "";
|
return ":/icons/png/posted.png";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
|
@ -162,6 +163,12 @@ void PostedDialog::loadGroupSummaryToken(const uint32_t &token, std::list<RsGrou
|
||||||
RsPostedGroup &group = *groupIt;
|
RsPostedGroup &group = *groupIt;
|
||||||
groupInfo.push_back(group.mMeta);
|
groupInfo.push_back(group.mMeta);
|
||||||
|
|
||||||
|
if (group.mGroupImage.mData != NULL) {
|
||||||
|
QPixmap image;
|
||||||
|
image.loadFromData(group.mGroupImage.mData, group.mGroupImage.mSize, "PNG");
|
||||||
|
postedData->mIcon[group.mMeta.mGroupId] = image;
|
||||||
|
}
|
||||||
|
|
||||||
if (!group.mDescription.empty()) {
|
if (!group.mDescription.empty()) {
|
||||||
postedData->mDescription[group.mMeta.mGroupId] = QString::fromUtf8(group.mDescription.c_str());
|
postedData->mDescription[group.mMeta.mGroupId] = QString::fromUtf8(group.mDescription.c_str());
|
||||||
}
|
}
|
||||||
|
@ -183,4 +190,9 @@ void PostedDialog::groupInfoToGroupItemInfo(const RsGroupMetaData &groupInfo, Gr
|
||||||
if (descriptionIt != postedData->mDescription.end()) {
|
if (descriptionIt != postedData->mDescription.end()) {
|
||||||
groupItemInfo.description = descriptionIt.value();
|
groupItemInfo.description = descriptionIt.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QMap<RsGxsGroupId, QIcon>::const_iterator iconIt = postedData->mIcon.find(groupInfo.mGroupId);
|
||||||
|
if (iconIt != postedData->mIcon.end()) {
|
||||||
|
groupItemInfo.icon = iconIt.value();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
||||||
* *
|
* *
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
#include <QBuffer>
|
||||||
|
|
||||||
#include "PostedGroupDialog.h"
|
#include "PostedGroupDialog.h"
|
||||||
|
|
||||||
|
@ -25,7 +26,7 @@
|
||||||
|
|
||||||
const uint32_t PostedCreateEnabledFlags = (
|
const uint32_t PostedCreateEnabledFlags = (
|
||||||
GXS_GROUP_FLAGS_NAME |
|
GXS_GROUP_FLAGS_NAME |
|
||||||
// GXS_GROUP_FLAGS_ICON |
|
GXS_GROUP_FLAGS_ICON |
|
||||||
GXS_GROUP_FLAGS_DESCRIPTION |
|
GXS_GROUP_FLAGS_DESCRIPTION |
|
||||||
GXS_GROUP_FLAGS_DISTRIBUTION |
|
GXS_GROUP_FLAGS_DISTRIBUTION |
|
||||||
// GXS_GROUP_FLAGS_PUBLISHSIGN |
|
// GXS_GROUP_FLAGS_PUBLISHSIGN |
|
||||||
|
@ -90,14 +91,31 @@ QPixmap PostedGroupDialog::serviceImage()
|
||||||
return QPixmap(":/icons/png/posted.png");
|
return QPixmap(":/icons/png/posted.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PostedGroupDialog::preparePostedGroup(RsPostedGroup &group, const RsGroupMetaData &meta)
|
||||||
|
{
|
||||||
|
group.mMeta = meta;
|
||||||
|
group.mDescription = getDescription().toUtf8().constData();
|
||||||
|
|
||||||
|
QPixmap pixmap = getLogo();
|
||||||
|
|
||||||
|
if (!pixmap.isNull()) {
|
||||||
|
QByteArray ba;
|
||||||
|
QBuffer buffer(&ba);
|
||||||
|
|
||||||
|
buffer.open(QIODevice::WriteOnly);
|
||||||
|
pixmap.save(&buffer, "PNG"); // writes image into ba in PNG format
|
||||||
|
|
||||||
|
group.mGroupImage.copy((uint8_t *) ba.data(), ba.size());
|
||||||
|
} else {
|
||||||
|
group.mGroupImage.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool PostedGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta)
|
bool PostedGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta)
|
||||||
{
|
{
|
||||||
// Specific Function.
|
// Specific Function.
|
||||||
RsPostedGroup grp;
|
RsPostedGroup grp;
|
||||||
grp.mMeta = meta;
|
preparePostedGroup(grp, meta);
|
||||||
grp.mDescription = getDescription().toStdString();
|
|
||||||
std::cerr << "PostedGroupDialog::service_CreateGroup() storing to Queue";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
|
|
||||||
rsPosted->createGroup(token, grp);
|
rsPosted->createGroup(token, grp);
|
||||||
|
|
||||||
|
@ -107,8 +125,7 @@ bool PostedGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaDa
|
||||||
bool PostedGroupDialog::service_EditGroup(uint32_t &token, RsGroupMetaData &editedMeta)
|
bool PostedGroupDialog::service_EditGroup(uint32_t &token, RsGroupMetaData &editedMeta)
|
||||||
{
|
{
|
||||||
RsPostedGroup grp;
|
RsPostedGroup grp;
|
||||||
grp.mMeta = editedMeta;
|
preparePostedGroup(grp, editedMeta);
|
||||||
grp.mDescription = getDescription().toUtf8().constData();
|
|
||||||
|
|
||||||
std::cerr << "PostedGroupDialog::service_EditGroup() submitting changes";
|
std::cerr << "PostedGroupDialog::service_EditGroup() submitting changes";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
|
@ -140,8 +157,18 @@ bool PostedGroupDialog::service_loadGroup(uint32_t token, Mode /*mode*/, RsGroup
|
||||||
std::cerr << "PostedGroupDialog::service_loadGroup() Unfinished Loading";
|
std::cerr << "PostedGroupDialog::service_loadGroup() Unfinished Loading";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
|
|
||||||
groupMetaData = groups[0].mMeta;
|
const RsPostedGroup &group = groups[0];
|
||||||
description = QString::fromUtf8(groups[0].mDescription.c_str());
|
groupMetaData = group.mMeta;
|
||||||
|
description = QString::fromUtf8(group.mDescription.c_str());
|
||||||
|
|
||||||
|
if (group.mGroupImage.mData) {
|
||||||
|
QPixmap pixmap;
|
||||||
|
if (pixmap.loadFromData(group.mGroupImage.mData, group.mGroupImage.mSize, "PNG")) {
|
||||||
|
setLogo(pixmap);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setLogo(QPixmap(":/icons/png/posted.png"));
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,9 @@ protected:
|
||||||
virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta);
|
virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta);
|
||||||
virtual bool service_loadGroup(uint32_t token, Mode mode, RsGroupMetaData& groupMetaData, QString &description);
|
virtual bool service_loadGroup(uint32_t token, Mode mode, RsGroupMetaData& groupMetaData, QString &description);
|
||||||
virtual bool service_EditGroup(uint32_t &token, RsGroupMetaData &editedMeta);
|
virtual bool service_EditGroup(uint32_t &token, RsGroupMetaData &editedMeta);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void preparePostedGroup(RsPostedGroup &group, const RsGroupMetaData &meta);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -110,6 +110,17 @@ void PostedItem::setup()
|
||||||
QAction *CopyLinkAction = new QAction(QIcon(""),tr("Copy RetroShare Link"), this);
|
QAction *CopyLinkAction = new QAction(QIcon(""),tr("Copy RetroShare Link"), this);
|
||||||
connect(CopyLinkAction, SIGNAL(triggered()), this, SLOT(copyMessageLink()));
|
connect(CopyLinkAction, SIGNAL(triggered()), this, SLOT(copyMessageLink()));
|
||||||
|
|
||||||
|
|
||||||
|
int S = QFontMetricsF(font()).height() ;
|
||||||
|
|
||||||
|
ui->voteUpButton->setIconSize(QSize(S*1.5,S*1.5));
|
||||||
|
ui->voteDownButton->setIconSize(QSize(S*1.5,S*1.5));
|
||||||
|
ui->commentButton->setIconSize(QSize(S*1.5,S*1.5));
|
||||||
|
ui->expandButton->setIconSize(QSize(S*1.5,S*1.5));
|
||||||
|
ui->notesButton->setIconSize(QSize(S*1.5,S*1.5));
|
||||||
|
ui->readButton->setIconSize(QSize(S*1.5,S*1.5));
|
||||||
|
ui->shareButton->setIconSize(QSize(S*1.5,S*1.5));
|
||||||
|
|
||||||
QMenu *menu = new QMenu();
|
QMenu *menu = new QMenu();
|
||||||
menu->addAction(CopyLinkAction);
|
menu->addAction(CopyLinkAction);
|
||||||
ui->shareButton->setMenu(menu);
|
ui->shareButton->setMenu(menu);
|
||||||
|
@ -235,7 +246,11 @@ void PostedItem::fill()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPixmap sqpixmap2 = QPixmap(":/images/thumb-default.png");
|
||||||
|
|
||||||
mInFill = true;
|
mInFill = true;
|
||||||
|
int desired_height = 1.5*(ui->voteDownButton->height() + ui->voteUpButton->height() + ui->scoreLabel->height());
|
||||||
|
int desired_width = sqpixmap2.width()*desired_height/(float)sqpixmap2.height();
|
||||||
|
|
||||||
if(mPost.mImage.mData != NULL)
|
if(mPost.mImage.mData != NULL)
|
||||||
{
|
{
|
||||||
|
@ -243,12 +258,13 @@ void PostedItem::fill()
|
||||||
pixmap.loadFromData(mPost.mImage.mData, mPost.mImage.mSize, "PNG");
|
pixmap.loadFromData(mPost.mImage.mData, mPost.mImage.mSize, "PNG");
|
||||||
// Wiping data - as its been passed to thumbnail.
|
// Wiping data - as its been passed to thumbnail.
|
||||||
|
|
||||||
QPixmap sqpixmap = pixmap.scaled(800, 600, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
QPixmap sqpixmap = pixmap.scaled(desired_width,desired_height, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
|
||||||
ui->pictureLabel->setPixmap(sqpixmap);
|
ui->thumbnailLabel->setPixmap(sqpixmap);
|
||||||
|
ui->pictureLabel->setPixmap(pixmap);
|
||||||
ui->thumbnailLabel->setPixmap(pixmap);
|
}
|
||||||
}else
|
else
|
||||||
{
|
{
|
||||||
|
//ui->thumbnailLabel->setFixedSize(desired_width,desired_height);
|
||||||
ui->expandButton->setDisabled(true);
|
ui->expandButton->setDisabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,7 +306,7 @@ void PostedItem::fill()
|
||||||
urlstr += QString(" </span></a>");
|
urlstr += QString(" </span></a>");
|
||||||
|
|
||||||
QString siteurl = url.scheme() + "://" + url.host();
|
QString siteurl = url.scheme() + "://" + url.host();
|
||||||
sitestr = QString("<a href=\"%1\" ><span style=\" text-decoration: underline; color:#2255AA;\"> %2 </span></a>").arg(siteurl).arg(siteurl);
|
sitestr = QString("<a href=\"%1\" ><span style=\" text-decoration: underline; color:#0079d3;\"> %2 </span></a>").arg(siteurl).arg(siteurl);
|
||||||
|
|
||||||
ui->titleLabel->setText(urlstr);
|
ui->titleLabel->setText(urlstr);
|
||||||
}else
|
}else
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>617</width>
|
<width>825</width>
|
||||||
<height>190</height>
|
<height>337</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -67,6 +67,12 @@
|
||||||
</property>
|
</property>
|
||||||
<item row="0" column="0" rowspan="2">
|
<item row="0" column="0" rowspan="2">
|
||||||
<widget class="QFrame" name="voteFrame">
|
<widget class="QFrame" name="voteFrame">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>37</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true"/>
|
<string notr="true"/>
|
||||||
</property>
|
</property>
|
||||||
|
@ -100,12 +106,6 @@
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>24</width>
|
|
||||||
<height>24</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Vote up</string>
|
<string>Vote up</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -116,12 +116,6 @@
|
||||||
<iconset resource="Posted_images.qrc">
|
<iconset resource="Posted_images.qrc">
|
||||||
<normaloff>:/images/up-arrow.png</normaloff>:/images/up-arrow.png</iconset>
|
<normaloff>:/images/up-arrow.png</normaloff>:/images/up-arrow.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize">
|
|
||||||
<size>
|
|
||||||
<width>16</width>
|
|
||||||
<height>16</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="autoRaise">
|
<property name="autoRaise">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
@ -161,12 +155,6 @@
|
||||||
<iconset resource="Posted_images.qrc">
|
<iconset resource="Posted_images.qrc">
|
||||||
<normaloff>:/images/down-arrow.png</normaloff>:/images/down-arrow.png</iconset>
|
<normaloff>:/images/down-arrow.png</normaloff>:/images/down-arrow.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize">
|
|
||||||
<size>
|
|
||||||
<width>16</width>
|
|
||||||
<height>16</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="autoRaise">
|
<property name="autoRaise">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
@ -198,6 +186,12 @@
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="thumbnailLabel">
|
<widget class="QLabel" name="thumbnailLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>100</width>
|
<width>100</width>
|
||||||
|
@ -312,7 +306,7 @@
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>3</number>
|
<number>5</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
|
@ -371,25 +365,6 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="siteBoldLabel">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<weight>75</weight>
|
|
||||||
<bold>true</bold>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Site</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="siteLabel">
|
<widget class="QLabel" name="siteLabel">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
@ -426,6 +401,9 @@
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="buttonHLayout">
|
<layout class="QHBoxLayout" name="buttonHLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
@ -705,8 +683,8 @@
|
||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../images.qrc"/>
|
|
||||||
<include location="Posted_images.qrc"/>
|
<include location="Posted_images.qrc"/>
|
||||||
|
<include location="../images.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
|
@ -26,8 +26,12 @@
|
||||||
#include "PostedCreatePostDialog.h"
|
#include "PostedCreatePostDialog.h"
|
||||||
#include "PostedItem.h"
|
#include "PostedItem.h"
|
||||||
#include "gui/common/UIStateHelper.h"
|
#include "gui/common/UIStateHelper.h"
|
||||||
|
#include "gui/RetroShareLink.h"
|
||||||
|
#include "util/HandleRichText.h"
|
||||||
|
#include "util/DateTime.h"
|
||||||
|
|
||||||
#include <retroshare/rsposted.h>
|
#include <retroshare/rsposted.h>
|
||||||
|
#include "retroshare/rsgxscircles.h"
|
||||||
|
|
||||||
#define POSTED_DEFAULT_LISTING_LENGTH 10
|
#define POSTED_DEFAULT_LISTING_LENGTH 10
|
||||||
#define POSTED_MAX_INDEX 10000
|
#define POSTED_MAX_INDEX 10000
|
||||||
|
@ -66,12 +70,19 @@ PostedListWidget::PostedListWidget(const RsGxsGroupId &postedId, QWidget *parent
|
||||||
/* fill in the available OwnIds for signing */
|
/* fill in the available OwnIds for signing */
|
||||||
ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED, RsGxsId());
|
ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED, RsGxsId());
|
||||||
|
|
||||||
|
int S = QFontMetricsF(font()).height() ;
|
||||||
|
|
||||||
|
ui->submitPostButton->setIconSize(QSize(S*1.5,S*1.5));
|
||||||
|
ui->comboBox->setIconSize(QSize(S*1.5,S*1.5));
|
||||||
|
|
||||||
connect(ui->submitPostButton, SIGNAL(clicked()), this, SLOT(newPost()));
|
connect(ui->submitPostButton, SIGNAL(clicked()), this, SLOT(newPost()));
|
||||||
|
|
||||||
ui->subscribeToolButton->setToolTip(tr( "<p>Subscribing to the links will gather \
|
ui->subscribeToolButton->setToolTip(tr( "<p>Subscribing to the links will gather \
|
||||||
available posts from your subscribed friends, and make the \
|
available posts from your subscribed friends, and make the \
|
||||||
links visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the links list at left.</p>"));
|
links visible to all other friends.</p><p>Afterwards you can unsubscribe from the context menu of the links list at left.</p>"));
|
||||||
|
|
||||||
|
ui->infoframe->hide();
|
||||||
|
|
||||||
/* load settings */
|
/* load settings */
|
||||||
processSettings(true);
|
processSettings(true);
|
||||||
|
|
||||||
|
@ -293,6 +304,67 @@ void PostedListWidget::insertPostedDetails(const RsPostedGroup &group)
|
||||||
mStateHelper->setWidgetEnabled(ui->submitPostButton, IS_GROUP_SUBSCRIBED(group.mMeta.mSubscribeFlags));
|
mStateHelper->setWidgetEnabled(ui->submitPostButton, IS_GROUP_SUBSCRIBED(group.mMeta.mSubscribeFlags));
|
||||||
ui->subscribeToolButton->setSubscribed(IS_GROUP_SUBSCRIBED(group.mMeta.mSubscribeFlags));
|
ui->subscribeToolButton->setSubscribed(IS_GROUP_SUBSCRIBED(group.mMeta.mSubscribeFlags));
|
||||||
ui->subscribeToolButton->setHidden(IS_GROUP_SUBSCRIBED(group.mMeta.mSubscribeFlags)) ;
|
ui->subscribeToolButton->setHidden(IS_GROUP_SUBSCRIBED(group.mMeta.mSubscribeFlags)) ;
|
||||||
|
|
||||||
|
RetroShareLink link;
|
||||||
|
|
||||||
|
if (IS_GROUP_SUBSCRIBED(group.mMeta.mSubscribeFlags)) {
|
||||||
|
|
||||||
|
ui->infoframe->hide();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
ui->infoPosts->setText(QString::number(group.mMeta.mVisibleMsgCount));
|
||||||
|
|
||||||
|
if(group.mMeta.mLastPost==0)
|
||||||
|
ui->infoLastPost->setText(tr("Never"));
|
||||||
|
else
|
||||||
|
|
||||||
|
ui->infoLastPost->setText(DateTime::formatLongDateTime(group.mMeta.mLastPost));
|
||||||
|
|
||||||
|
QString formatDescription = QString::fromUtf8(group.mDescription.c_str());
|
||||||
|
|
||||||
|
unsigned int formatFlag = RSHTML_FORMATTEXT_EMBED_LINKS;
|
||||||
|
|
||||||
|
formatDescription = RsHtml().formatText(NULL, formatDescription, formatFlag);
|
||||||
|
|
||||||
|
ui->infoDescription->setText(formatDescription);
|
||||||
|
|
||||||
|
ui->infoAdministrator->setId(group.mMeta.mAuthorId) ;
|
||||||
|
|
||||||
|
link = RetroShareLink::createMessage(group.mMeta.mAuthorId, "");
|
||||||
|
ui->infoAdministrator->setText(link.toHtml());
|
||||||
|
|
||||||
|
QString distrib_string ( "[unknown]" );
|
||||||
|
|
||||||
|
switch(group.mMeta.mCircleType)
|
||||||
|
{
|
||||||
|
case GXS_CIRCLE_TYPE_PUBLIC: distrib_string = tr("Public") ;
|
||||||
|
break ;
|
||||||
|
case GXS_CIRCLE_TYPE_EXTERNAL:
|
||||||
|
{
|
||||||
|
RsGxsCircleDetails det ;
|
||||||
|
|
||||||
|
// !! What we need here is some sort of CircleLabel, which loads the circle and updates the label when done.
|
||||||
|
|
||||||
|
if(rsGxsCircles->getCircleDetails(group.mMeta.mCircleId,det))
|
||||||
|
distrib_string = tr("Restricted to members of circle \"")+QString::fromUtf8(det.mCircleName.c_str()) +"\"";
|
||||||
|
else
|
||||||
|
distrib_string = tr("Restricted to members of circle ")+QString::fromStdString(group.mMeta.mCircleId.toStdString()) ;
|
||||||
|
}
|
||||||
|
break ;
|
||||||
|
case GXS_CIRCLE_TYPE_YOUR_EYES_ONLY: distrib_string = tr("Your eyes only");
|
||||||
|
break ;
|
||||||
|
case GXS_CIRCLE_TYPE_LOCAL: distrib_string = tr("You and your friend nodes");
|
||||||
|
break ;
|
||||||
|
default:
|
||||||
|
std::cerr << "(EE) badly initialised group distribution ID = " << group.mMeta.mCircleType << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->infoDistribution->setText(distrib_string);
|
||||||
|
|
||||||
|
ui->infoframe->show();
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************** **** **** **** ***********************/
|
/*********************** **** **** **** ***********************/
|
||||||
|
|
|
@ -205,6 +205,186 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="infoframe">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QGroupBox" name="infoGroupBox">
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Topic Details</string>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Administrator:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="infoPostsLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Posts:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="infoLastPostLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Last Post:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0" colspan="2">
|
||||||
|
<widget class="QTextBrowser" name="infoDescription">
|
||||||
|
<property name="html">
|
||||||
|
<string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
|
p, li { white-space: pre-wrap; }
|
||||||
|
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
||||||
|
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Description</span></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="openLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="infoDescriptionLabel">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Description:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="GxsIdLabel" name="infoAdministrator">
|
||||||
|
<property name="text">
|
||||||
|
<string>unknown</string>
|
||||||
|
</property>
|
||||||
|
<property name="openExternalLinks">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLabel" name="infoPosts">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">0</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="infoLastPost">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">unknown</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<weight>75</weight>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Distribution:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLabel" name="infoDistribution">
|
||||||
|
<property name="text">
|
||||||
|
<string>unknown</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QScrollArea" name="scrollArea">
|
<widget class="QScrollArea" name="scrollArea">
|
||||||
<property name="widgetResizable">
|
<property name="widgetResizable">
|
||||||
|
@ -258,6 +438,11 @@
|
||||||
<extends>QComboBox</extends>
|
<extends>QComboBox</extends>
|
||||||
<header>gui/gxs/GxsIdChooser.h</header>
|
<header>gui/gxs/GxsIdChooser.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>GxsIdLabel</class>
|
||||||
|
<extends>QLabel</extends>
|
||||||
|
<header>gui/gxs/GxsIdLabel.h</header>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../images.qrc"/>
|
<include location="../images.qrc"/>
|
||||||
|
|
|
@ -291,7 +291,7 @@ bool ChatLobbyUserNotify::checkWord(QString message, QString word)
|
||||||
&& (!word.isEmpty())) {
|
&& (!word.isEmpty())) {
|
||||||
QString eow=" ~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="; // end of word
|
QString eow=" ~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="; // end of word
|
||||||
bool bFirstCharEOW = (nFound==0)?true:(eow.indexOf(message.at(nFound-1)) != -1);
|
bool bFirstCharEOW = (nFound==0)?true:(eow.indexOf(message.at(nFound-1)) != -1);
|
||||||
bool bLastCharEOW = ((nFound+word.length()-1) < message.length())
|
bool bLastCharEOW = (nFound+word.length() < message.length())
|
||||||
?(eow.indexOf(message.at(nFound+word.length())) != -1)
|
?(eow.indexOf(message.at(nFound+word.length())) != -1)
|
||||||
:true;
|
:true;
|
||||||
bFound = (bFirstCharEOW && bLastCharEOW);
|
bFound = (bFirstCharEOW && bLastCharEOW);
|
||||||
|
|
|
@ -135,13 +135,22 @@ void PostedGroupItem::fill()
|
||||||
|
|
||||||
ui->descLabel->setText(QString::fromUtf8(mGroup.mDescription.c_str()));
|
ui->descLabel->setText(QString::fromUtf8(mGroup.mDescription.c_str()));
|
||||||
|
|
||||||
//TODO - nice icon for subscribed group
|
if (mGroup.mGroupImage.mData != NULL) {
|
||||||
if (IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags)) {
|
QPixmap postedImage;
|
||||||
ui->logoLabel->setPixmap(QPixmap(":/images/posted_64.png"));
|
postedImage.loadFromData(mGroup.mGroupImage.mData, mGroup.mGroupImage.mSize, "PNG");
|
||||||
|
ui->logoLabel->setPixmap(QPixmap(postedImage));
|
||||||
} else {
|
} else {
|
||||||
ui->logoLabel->setPixmap(QPixmap(":/images/posted_64.png"));
|
ui->logoLabel->setPixmap(QPixmap(":/images/posted_64.png"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//TODO - nice icon for subscribed group
|
||||||
|
// if (IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags)) {
|
||||||
|
// ui->logoLabel->setPixmap(QPixmap(":/images/posted_64.png"));
|
||||||
|
// } else {
|
||||||
|
// ui->logoLabel->setPixmap(QPixmap(":/images/posted_64.png"));
|
||||||
|
// }
|
||||||
|
|
||||||
if (IS_GROUP_SUBSCRIBED(mGroup.mMeta.mSubscribeFlags)) {
|
if (IS_GROUP_SUBSCRIBED(mGroup.mMeta.mSubscribeFlags)) {
|
||||||
ui->subscribeButton->setEnabled(false);
|
ui->subscribeButton->setEnabled(false);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -49,6 +49,15 @@ GxsCommentDialog::GxsCommentDialog(QWidget *parent, RsTokenService *token_servic
|
||||||
connect(ui->refreshButton, SIGNAL(clicked()), this, SLOT(refresh()));
|
connect(ui->refreshButton, SIGNAL(clicked()), this, SLOT(refresh()));
|
||||||
connect(ui->idChooser, SIGNAL(currentIndexChanged( int )), this, SLOT(voterSelectionChanged( int )));
|
connect(ui->idChooser, SIGNAL(currentIndexChanged( int )), this, SLOT(voterSelectionChanged( int )));
|
||||||
connect(ui->idChooser, SIGNAL(idsLoaded()), this, SLOT(idChooserReady()));
|
connect(ui->idChooser, SIGNAL(idsLoaded()), this, SLOT(idChooserReady()));
|
||||||
|
|
||||||
|
connect(ui->sortBox, SIGNAL(currentIndexChanged(int)), this, SLOT(sortComments(int)));
|
||||||
|
|
||||||
|
// default sort method "HOT".
|
||||||
|
ui->treeWidget->sortByColumn(4, Qt::DescendingOrder);
|
||||||
|
|
||||||
|
int S = QFontMetricsF(font()).height() ;
|
||||||
|
|
||||||
|
ui->sortBox->setIconSize(QSize(S*1.5,S*1.5));
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsCommentDialog::~GxsCommentDialog()
|
GxsCommentDialog::~GxsCommentDialog()
|
||||||
|
@ -141,3 +150,22 @@ void GxsCommentDialog::setCommentHeader(QWidget *header)
|
||||||
ui->notesBrowser->setPlainText(QString::fromStdString(mCurrentPost.mNotes));
|
ui->notesBrowser->setPlainText(QString::fromStdString(mCurrentPost.mNotes));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GxsCommentDialog::sortComments(int i)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case 0:
|
||||||
|
ui->treeWidget->sortByColumn(4, Qt::DescendingOrder);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
ui->treeWidget->sortByColumn(2, Qt::DescendingOrder);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ui->treeWidget->sortByColumn(3, Qt::DescendingOrder);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ private slots:
|
||||||
void refresh();
|
void refresh();
|
||||||
void idChooserReady();
|
void idChooserReady();
|
||||||
void voterSelectionChanged( int index );
|
void voterSelectionChanged( int index );
|
||||||
|
void sortComments(int);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RsGxsGroupId mGrpId;
|
RsGxsGroupId mGrpId;
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Form</string>
|
<string>Form</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="GxsCommentDialogVLayout">
|
<layout class="QGridLayout" name="GxsCommentDialogGLayout">
|
||||||
<item>
|
<item row="0" column="0">
|
||||||
<widget class="QFrame" name="postFrame">
|
<widget class="QFrame" name="postFrame">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
@ -24,59 +24,63 @@
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="postFrameVLayout">
|
<layout class="QVBoxLayout" name="postFrameVLayout">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>9</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="topMargin">
|
<property name="topMargin">
|
||||||
<number>1</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>1</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="1" column="0">
|
||||||
<layout class="QHBoxLayout" name="toolBarHLayout">
|
<layout class="QHBoxLayout" name="toolBarHLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="hotSortButton">
|
<widget class="QComboBox" name="sortBox">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">sort by</span></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Hot</string>
|
<string>Hot</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable">
|
<property name="icon">
|
||||||
<bool>true</bool>
|
<iconset resource="../icons.qrc">
|
||||||
|
<normaloff>:/icons/png/flame.png</normaloff>:/icons/png/flame.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="autoExclusive">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="newSortButton">
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>New</string>
|
<string>New</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable">
|
<property name="icon">
|
||||||
<bool>true</bool>
|
<iconset resource="../icons.qrc">
|
||||||
|
<normaloff>:/icons/png/new.png</normaloff>:/icons/png/new.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="autoExclusive">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="topSortButton">
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Top</string>
|
<string>Top</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable">
|
<property name="icon">
|
||||||
<bool>true</bool>
|
<iconset resource="../icons.qrc">
|
||||||
</property>
|
<normaloff>:/icons/png/top.png</normaloff>:/icons/png/top.png</iconset>
|
||||||
<property name="checked">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="autoExclusive">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
</property>
|
||||||
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
@ -111,8 +115,11 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="2" column="0">
|
||||||
<widget class="GxsCommentTreeWidget" name="treeWidget">
|
<widget class="GxsCommentTreeWidget" name="treeWidget">
|
||||||
|
<property name="sortingEnabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
<column>
|
<column>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Comment</string>
|
<string>Comment</string>
|
||||||
|
@ -164,6 +171,8 @@
|
||||||
<header>gui/gxs/GxsCommentTreeWidget.h</header>
|
<header>gui/gxs/GxsCommentTreeWidget.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources/>
|
<resources>
|
||||||
|
<include location="../icons.qrc"/>
|
||||||
|
</resources>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "gui/gxs/GxsCommentTreeWidget.h"
|
#include "gui/gxs/GxsCommentTreeWidget.h"
|
||||||
#include "gui/gxs/GxsCreateCommentDialog.h"
|
#include "gui/gxs/GxsCreateCommentDialog.h"
|
||||||
#include "gui/gxs/GxsIdTreeWidgetItem.h"
|
#include "gui/gxs/GxsIdTreeWidgetItem.h"
|
||||||
|
#include "gui/common/RSTreeWidgetItem.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
@ -45,6 +46,7 @@
|
||||||
#define PCITEM_COLUMN_PARENTID 8
|
#define PCITEM_COLUMN_PARENTID 8
|
||||||
#define PCITEM_COLUMN_AUTHORID 9
|
#define PCITEM_COLUMN_AUTHORID 9
|
||||||
|
|
||||||
|
#define ROLE_SORT Qt::UserRole + 1
|
||||||
|
|
||||||
#define GXSCOMMENTS_LOADTHREAD 1
|
#define GXSCOMMENTS_LOADTHREAD 1
|
||||||
|
|
||||||
|
@ -140,6 +142,9 @@ GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent)
|
||||||
|
|
||||||
setItemDelegateForColumn(PCITEM_COLUMN_COMMENT,new MultiLinesCommentDelegate(QFontMetricsF(font()))) ;
|
setItemDelegateForColumn(PCITEM_COLUMN_COMMENT,new MultiLinesCommentDelegate(QFontMetricsF(font()))) ;
|
||||||
|
|
||||||
|
commentsRole = new RSTreeWidgetItemCompareRole;
|
||||||
|
commentsRole->setRole(PCITEM_COLUMN_DATE, ROLE_SORT);
|
||||||
|
|
||||||
// QFont font = QFont("ARIAL", 10);
|
// QFont font = QFont("ARIAL", 10);
|
||||||
// font.setBold(true);
|
// font.setBold(true);
|
||||||
|
|
||||||
|
@ -537,6 +542,8 @@ void GxsCommentTreeWidget::service_loadThread(const uint32_t &token)
|
||||||
text = qtime.toString("yyyy-MM-dd hh:mm:ss") ;
|
text = qtime.toString("yyyy-MM-dd hh:mm:ss") ;
|
||||||
item->setText(PCITEM_COLUMN_DATE, text) ;
|
item->setText(PCITEM_COLUMN_DATE, text) ;
|
||||||
item->setToolTip(PCITEM_COLUMN_DATE, text) ;
|
item->setToolTip(PCITEM_COLUMN_DATE, text) ;
|
||||||
|
item->setData(PCITEM_COLUMN_DATE, ROLE_SORT, QVariant(qlonglong(comment.mMeta.mPublishTs)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
text = QString::fromUtf8(comment.mComment.c_str());
|
text = QString::fromUtf8(comment.mComment.c_str());
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include <retroshare/rsgxscommon.h>
|
#include <retroshare/rsgxscommon.h>
|
||||||
#include <retroshare/rsidentity.h>
|
#include <retroshare/rsidentity.h>
|
||||||
|
|
||||||
|
class RSTreeWidgetItemCompareRole;
|
||||||
|
|
||||||
class GxsCommentTreeWidget : public QTreeWidget, public TokenResponse
|
class GxsCommentTreeWidget : public QTreeWidget, public TokenResponse
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -97,6 +99,8 @@ protected:
|
||||||
std::map<RsGxsMessageId, QTreeWidgetItem *> mLoadingMap;
|
std::map<RsGxsMessageId, QTreeWidgetItem *> mLoadingMap;
|
||||||
std::multimap<RsGxsMessageId, QTreeWidgetItem *> mPendingInsertMap;
|
std::multimap<RsGxsMessageId, QTreeWidgetItem *> mPendingInsertMap;
|
||||||
|
|
||||||
|
RSTreeWidgetItemCompareRole *commentsRole;
|
||||||
|
|
||||||
TokenQueue *mTokenQueue;
|
TokenQueue *mTokenQueue;
|
||||||
RsTokenService *mRsTokenService;
|
RsTokenService *mRsTokenService;
|
||||||
RsGxsCommentService *mCommentService;
|
RsGxsCommentService *mCommentService;
|
||||||
|
|
|
@ -760,7 +760,7 @@ void GxsGroupDialog::setGroupSignFlags(uint32_t signFlags)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ui.comments_no->setChecked(true);
|
ui.comments_no->setChecked(true);
|
||||||
ui.commentsValueLabel->setText("Allowed") ;
|
ui.commentsValueLabel->setText("Forbidden") ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>600</width>
|
<width>600</width>
|
||||||
<height>736</height>
|
<height>633</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
|
|
@ -61,11 +61,15 @@ const uint32_t ChannelEditDefaultsFlags = ChannelCreateDefaultsFlags;
|
||||||
GxsChannelGroupDialog::GxsChannelGroupDialog(TokenQueue *tokenQueue, QWidget *parent)
|
GxsChannelGroupDialog::GxsChannelGroupDialog(TokenQueue *tokenQueue, QWidget *parent)
|
||||||
: GxsGroupDialog(tokenQueue, ChannelCreateEnabledFlags, ChannelCreateDefaultsFlags, parent)
|
: GxsGroupDialog(tokenQueue, ChannelCreateEnabledFlags, ChannelCreateDefaultsFlags, parent)
|
||||||
{
|
{
|
||||||
|
ui.commentGroupBox->setEnabled(false); // These are here because comments_allowed are actually not used yet, so the group will not be changed by the setting and when
|
||||||
|
ui.comments_allowed->setChecked(true); // the group info is displayed it will therefore be set to "disabled" in all cases although it is enabled.
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsChannelGroupDialog::GxsChannelGroupDialog(TokenQueue *tokenExternalQueue, RsTokenService *tokenService, Mode mode, RsGxsGroupId groupId, QWidget *parent)
|
GxsChannelGroupDialog::GxsChannelGroupDialog(TokenQueue *tokenExternalQueue, RsTokenService *tokenService, Mode mode, RsGxsGroupId groupId, QWidget *parent)
|
||||||
: GxsGroupDialog(tokenExternalQueue, tokenService, mode, groupId, ChannelEditEnabledFlags, ChannelEditDefaultsFlags, parent)
|
: GxsGroupDialog(tokenExternalQueue, tokenService, mode, groupId, ChannelEditEnabledFlags, ChannelEditDefaultsFlags, parent)
|
||||||
{
|
{
|
||||||
|
ui.commentGroupBox->setEnabled(false); // These are here because comments_allowed are actually not used yet, so the group will not be changed by the setting and when
|
||||||
|
ui.comments_allowed->setChecked(true); // the group info is displayed it will therefore be set to "disabled" in all cases although it is enabled.
|
||||||
}
|
}
|
||||||
|
|
||||||
void GxsChannelGroupDialog::initUi()
|
void GxsChannelGroupDialog::initUi()
|
||||||
|
|
|
@ -294,7 +294,7 @@
|
||||||
<number>3</number>
|
<number>3</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="topMargin">
|
<property name="topMargin">
|
||||||
<number>3</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="rightMargin">
|
<property name="rightMargin">
|
||||||
<number>3</number>
|
<number>3</number>
|
||||||
|
@ -304,82 +304,46 @@
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QFrame" name="infoFrame">
|
<widget class="QFrame" name="infoFrame">
|
||||||
<property name="palette">
|
|
||||||
<palette>
|
|
||||||
<active>
|
|
||||||
<colorrole role="Base">
|
|
||||||
<brush brushstyle="SolidPattern">
|
|
||||||
<color alpha="255">
|
|
||||||
<red>255</red>
|
|
||||||
<green>255</green>
|
|
||||||
<blue>255</blue>
|
|
||||||
</color>
|
|
||||||
</brush>
|
|
||||||
</colorrole>
|
|
||||||
<colorrole role="Window">
|
|
||||||
<brush brushstyle="SolidPattern">
|
|
||||||
<color alpha="255">
|
|
||||||
<red>255</red>
|
|
||||||
<green>255</green>
|
|
||||||
<blue>178</blue>
|
|
||||||
</color>
|
|
||||||
</brush>
|
|
||||||
</colorrole>
|
|
||||||
</active>
|
|
||||||
<inactive>
|
|
||||||
<colorrole role="Base">
|
|
||||||
<brush brushstyle="SolidPattern">
|
|
||||||
<color alpha="255">
|
|
||||||
<red>255</red>
|
|
||||||
<green>255</green>
|
|
||||||
<blue>255</blue>
|
|
||||||
</color>
|
|
||||||
</brush>
|
|
||||||
</colorrole>
|
|
||||||
<colorrole role="Window">
|
|
||||||
<brush brushstyle="SolidPattern">
|
|
||||||
<color alpha="255">
|
|
||||||
<red>255</red>
|
|
||||||
<green>255</green>
|
|
||||||
<blue>178</blue>
|
|
||||||
</color>
|
|
||||||
</brush>
|
|
||||||
</colorrole>
|
|
||||||
</inactive>
|
|
||||||
<disabled>
|
|
||||||
<colorrole role="Base">
|
|
||||||
<brush brushstyle="SolidPattern">
|
|
||||||
<color alpha="255">
|
|
||||||
<red>255</red>
|
|
||||||
<green>255</green>
|
|
||||||
<blue>178</blue>
|
|
||||||
</color>
|
|
||||||
</brush>
|
|
||||||
</colorrole>
|
|
||||||
<colorrole role="Window">
|
|
||||||
<brush brushstyle="SolidPattern">
|
|
||||||
<color alpha="255">
|
|
||||||
<red>255</red>
|
|
||||||
<green>255</green>
|
|
||||||
<blue>178</blue>
|
|
||||||
</color>
|
|
||||||
</brush>
|
|
||||||
</colorrole>
|
|
||||||
</disabled>
|
|
||||||
</palette>
|
|
||||||
</property>
|
|
||||||
<property name="autoFillBackground">
|
<property name="autoFillBackground">
|
||||||
<bool>true</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
<enum>QFrame::Box</enum>
|
<enum>QFrame::NoFrame</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="frameShadow">
|
<property name="frameShadow">
|
||||||
<enum>QFrame::Plain</enum>
|
<enum>QFrame::Plain</enum>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Channel details</string>
|
||||||
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
|
@ -408,7 +372,7 @@
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Posts (at neighbor nodes):</string>
|
<string>Posts:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -509,6 +473,7 @@ p, li { white-space: pre-wrap; }
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
|
@ -336,11 +336,11 @@ bool RsMessageModel::passesFilter(const Rs::Msgs::MsgInfoSummary& fmpe,int colum
|
||||||
|| (std::find(fmpe.msgtags.begin(),fmpe.msgtags.end(),mQuickViewFilter) != fmpe.msgtags.end())
|
|| (std::find(fmpe.msgtags.begin(),fmpe.msgtags.end(),mQuickViewFilter) != fmpe.msgtags.end())
|
||||||
|| (mQuickViewFilter==QUICK_VIEW_STARRED && (fmpe.msgflags & RS_MSG_STAR))
|
|| (mQuickViewFilter==QUICK_VIEW_STARRED && (fmpe.msgflags & RS_MSG_STAR))
|
||||||
|| (mQuickViewFilter==QUICK_VIEW_SYSTEM && (fmpe.msgflags & RS_MSG_SYSTEM));
|
|| (mQuickViewFilter==QUICK_VIEW_SYSTEM && (fmpe.msgflags & RS_MSG_SYSTEM));
|
||||||
|
#ifdef DEBUG_MESSAGE_MODEL
|
||||||
std::cerr << "Passes filter: type=" << mFilterType << " s=\"" << s.toStdString()
|
std::cerr << "Passes filter: type=" << mFilterType << " s=\"" << s.toStdString() << "MsgFlags=" << fmpe.msgflags << " msgtags=" ;
|
||||||
<< "MsgFlags=" << fmpe.msgflags << " msgtags=" ;
|
|
||||||
foreach(uint32_t i,fmpe.msgtags) std::cerr << i << " " ;
|
foreach(uint32_t i,fmpe.msgtags) std::cerr << i << " " ;
|
||||||
std::cerr << "\" strings:" << passes_strings << " quick_view:" << passes_quick_view << std::endl;
|
std::cerr << "\" strings:" << passes_strings << " quick_view:" << passes_quick_view << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
return passes_quick_view && passes_strings;
|
return passes_quick_view && passes_strings;
|
||||||
}
|
}
|
||||||
|
@ -621,10 +621,10 @@ void RsMessageModel::getMessageSummaries(BoxName box,std::list<Rs::Msgs::MsgInfo
|
||||||
|
|
||||||
switch(box)
|
switch(box)
|
||||||
{
|
{
|
||||||
case BOX_INBOX : ok = (it->msgflags & RS_MSG_BOXMASK) == RS_MSG_INBOX ; break ;
|
case BOX_INBOX : ok = (it->msgflags & RS_MSG_BOXMASK) == RS_MSG_INBOX && !(it->msgflags & RS_MSG_TRASH); break ;
|
||||||
case BOX_SENT : ok = (it->msgflags & RS_MSG_BOXMASK) == RS_MSG_SENTBOX; break ;
|
case BOX_SENT : ok = (it->msgflags & RS_MSG_BOXMASK) == RS_MSG_SENTBOX && !(it->msgflags & RS_MSG_TRASH); break ;
|
||||||
case BOX_OUTBOX : ok = (it->msgflags & RS_MSG_BOXMASK) == RS_MSG_OUTBOX ; break ;
|
case BOX_OUTBOX : ok = (it->msgflags & RS_MSG_BOXMASK) == RS_MSG_OUTBOX && !(it->msgflags & RS_MSG_TRASH); break ;
|
||||||
case BOX_DRAFTS : ok = (it->msgflags & RS_MSG_BOXMASK) == RS_MSG_DRAFTBOX ; break ;
|
case BOX_DRAFTS : ok = (it->msgflags & RS_MSG_BOXMASK) == RS_MSG_DRAFTBOX && !(it->msgflags & RS_MSG_TRASH); break ;
|
||||||
case BOX_TRASH : ok = (it->msgflags & RS_MSG_TRASH) ; break ;
|
case BOX_TRASH : ok = (it->msgflags & RS_MSG_TRASH) ; break ;
|
||||||
default:
|
default:
|
||||||
++it;
|
++it;
|
||||||
|
|
|
@ -27,21 +27,21 @@
|
||||||
|
|
||||||
#include "MessagesDialog.h"
|
#include "MessagesDialog.h"
|
||||||
|
|
||||||
#include "notifyqt.h"
|
#include "gui/notifyqt.h"
|
||||||
#include "common/TagDefs.h"
|
#include "gui/common/TagDefs.h"
|
||||||
#include "common/PeerDefs.h"
|
#include "gui/common/PeerDefs.h"
|
||||||
#include "common/RSElidedItemDelegate.h"
|
#include "gui/common/RSElidedItemDelegate.h"
|
||||||
#include "gxs/GxsIdTreeWidgetItem.h"
|
#include "gui/gxs/GxsIdTreeWidgetItem.h"
|
||||||
#include "gxs/GxsIdDetails.h"
|
#include "gui/gxs/GxsIdDetails.h"
|
||||||
#include "gui/Identity/IdDialog.h"
|
#include "gui/Identity/IdDialog.h"
|
||||||
#include "gui/MainWindow.h"
|
#include "gui/MainWindow.h"
|
||||||
#include "msgs/MessageComposer.h"
|
#include "gui/msgs/MessageComposer.h"
|
||||||
#include "msgs/MessageInterface.h"
|
#include "gui/msgs/MessageInterface.h"
|
||||||
#include "msgs/MessageUserNotify.h"
|
#include "gui/msgs/MessageUserNotify.h"
|
||||||
#include "msgs/MessageWidget.h"
|
#include "gui/msgs/MessageWidget.h"
|
||||||
#include "msgs/TagsMenu.h"
|
#include "gui/msgs/TagsMenu.h"
|
||||||
#include "msgs/MessageModel.h"
|
#include "gui/msgs/MessageModel.h"
|
||||||
#include "settings/rsharesettings.h"
|
#include "gui/settings/rsharesettings.h"
|
||||||
|
|
||||||
#include "util/DateTime.h"
|
#include "util/DateTime.h"
|
||||||
#include "util/RsProtectedTimer.h"
|
#include "util/RsProtectedTimer.h"
|
|
@ -786,13 +786,11 @@ GenCertDialog QFrame#profileframe{
|
||||||
|
|
||||||
PostedListWidget QComboBox#comboBox {
|
PostedListWidget QComboBox#comboBox {
|
||||||
font: bold;
|
font: bold;
|
||||||
font-size: 15px;
|
|
||||||
color: #0099cc;
|
color: #0099cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedListWidget QToolButton#submitPostButton {
|
PostedListWidget QToolButton#submitPostButton {
|
||||||
font: bold;
|
font: bold;
|
||||||
font-size: 15px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedListWidget QToolButton#subscribeToolButton {
|
PostedListWidget QToolButton#subscribeToolButton {
|
||||||
|
@ -830,10 +828,7 @@ GxsForumThreadWidget QToolButton#subscribeToolButton:hover {
|
||||||
|
|
||||||
GxsChannelPostsWidget QFrame#infoFrame
|
GxsChannelPostsWidget QFrame#infoFrame
|
||||||
{
|
{
|
||||||
border: 1px solid #DCDC41;
|
|
||||||
border-radius: 6px;
|
|
||||||
background: #FFFFD7;
|
|
||||||
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsChannelPostsWidget QToolButton#subscribeToolButton {
|
GxsChannelPostsWidget QToolButton#subscribeToolButton {
|
||||||
|
@ -889,10 +884,14 @@ PostedItem QFrame#voteFrame {
|
||||||
background: #f8f9fa;
|
background: #f8f9fa;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedItem QFrame#mainFrame{
|
PostedItem QFrame#mainFrame [new=false]{
|
||||||
background: white;
|
background: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PostedItem > QFrame#mainFrame[new=true] {
|
||||||
|
background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #F0F8FD, stop:0.8 #E6F2FD, stop: 0.81 #E6F2FD, stop: 1 #D2E7FD);
|
||||||
|
}
|
||||||
|
|
||||||
PostedItem QFrame#frame_picture{
|
PostedItem QFrame#frame_picture{
|
||||||
background: white;
|
background: white;
|
||||||
}
|
}
|
||||||
|
@ -906,8 +905,7 @@ PostedItem QLabel#fromBoldLabel, QLabel#fromLabel, QLabel#dateLabel, QLabel#site
|
||||||
color: #787c7e;
|
color: #787c7e;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostedItem QToolButton#commentButton, QPushButton#shareButton, QToolButton#notesButton{
|
GxsCommentDialog QComboBox#sortBox {
|
||||||
font-size: 12px;
|
font: bold;
|
||||||
color: #878a8c;
|
color: #0099cc;
|
||||||
font-weight: bold;
|
|
||||||
}
|
}
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include "ratesstatus.h"
|
#include "ratesstatus.h"
|
||||||
#include <retroshare/rsiface.h>
|
#include <retroshare/rsiface.h>
|
||||||
|
#include "util/misc.h"
|
||||||
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
|
@ -47,13 +48,13 @@ RatesStatus::RatesStatus(QWidget *parent)
|
||||||
setLayout(hbox);
|
setLayout(hbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RatesStatus::getRatesStatus(float downKb, float upKb)
|
void RatesStatus::getRatesStatus(float downKb, uint64_t down, float upKb, uint64_t upl)
|
||||||
{
|
{
|
||||||
/* set users/friends/network */
|
/* set users/friends/network */
|
||||||
|
|
||||||
QString normalText = QString("<strong>%1:</strong> %2 (kB/s) | <strong>%3:</strong> %4 (kB/s) ")
|
QString normalText = QString("<strong>%1:</strong> %2 kB/s (%3) | <strong>%4:</strong> %5 kB/s (%6)")
|
||||||
.arg(tr("Down")).arg(downKb, 0, 'f', 2)
|
.arg(tr("Down")).arg(downKb, 0, 'f', 2).arg(misc::friendlyUnit(down))
|
||||||
.arg(tr("Up")).arg(upKb, 0, 'f', 2);
|
.arg(tr("Up")).arg(upKb, 0, 'f', 2).arg(misc::friendlyUnit(upl));
|
||||||
QString compactText = QString("%1|%2").arg(downKb, 0, 'f', 2).arg(upKb, 0, 'f', 2);
|
QString compactText = QString("%1|%2").arg(downKb, 0, 'f', 2).arg(upKb, 0, 'f', 2);
|
||||||
|
|
||||||
if (statusRates) {
|
if (statusRates) {
|
||||||
|
|
|
@ -32,7 +32,7 @@ class RatesStatus : public QWidget
|
||||||
public:
|
public:
|
||||||
RatesStatus(QWidget *parent = 0);
|
RatesStatus(QWidget *parent = 0);
|
||||||
|
|
||||||
void getRatesStatus(float downKb, float upKb);
|
void getRatesStatus(float downKb, uint64_t down, float upKb, uint64_t upl);
|
||||||
void setCompactMode(bool compact) {_compactMode = compact; }
|
void setCompactMode(bool compact) {_compactMode = compact; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -443,6 +443,7 @@ HEADERS += rshare.h \
|
||||||
gui/connect/ConfCertDialog.h \
|
gui/connect/ConfCertDialog.h \
|
||||||
gui/connect/PGPKeyDialog.h \
|
gui/connect/PGPKeyDialog.h \
|
||||||
gui/connect/FriendRecommendDialog.h \
|
gui/connect/FriendRecommendDialog.h \
|
||||||
|
gui/msgs/MessagesDialog.h \
|
||||||
gui/msgs/MessageInterface.h \
|
gui/msgs/MessageInterface.h \
|
||||||
gui/msgs/MessageComposer.h \
|
gui/msgs/MessageComposer.h \
|
||||||
gui/msgs/MessageWindow.h \
|
gui/msgs/MessageWindow.h \
|
||||||
|
@ -541,7 +542,6 @@ HEADERS += rshare.h \
|
||||||
gui/common/ToasterNotify.h \
|
gui/common/ToasterNotify.h \
|
||||||
gui/style/RSStyle.h \
|
gui/style/RSStyle.h \
|
||||||
gui/style/StyleDialog.h \
|
gui/style/StyleDialog.h \
|
||||||
gui/MessagesDialog.h \
|
|
||||||
gui/help/browser/helpbrowser.h \
|
gui/help/browser/helpbrowser.h \
|
||||||
gui/help/browser/helptextbrowser.h \
|
gui/help/browser/helptextbrowser.h \
|
||||||
gui/statusbar/peerstatus.h \
|
gui/statusbar/peerstatus.h \
|
||||||
|
@ -621,7 +621,6 @@ FORMS += gui/StartDialog.ui \
|
||||||
gui/FriendsDialog.ui \
|
gui/FriendsDialog.ui \
|
||||||
gui/ShareManager.ui \
|
gui/ShareManager.ui \
|
||||||
# gui/ShareDialog.ui \
|
# gui/ShareDialog.ui \
|
||||||
gui/MessagesDialog.ui \
|
|
||||||
gui/help/browser/helpbrowser.ui \
|
gui/help/browser/helpbrowser.ui \
|
||||||
gui/HelpDialog.ui \
|
gui/HelpDialog.ui \
|
||||||
gui/ServicePermissionDialog.ui \
|
gui/ServicePermissionDialog.ui \
|
||||||
|
@ -640,6 +639,7 @@ FORMS += gui/StartDialog.ui \
|
||||||
gui/connect/ConnectFriendWizard.ui \
|
gui/connect/ConnectFriendWizard.ui \
|
||||||
gui/connect/ConnectProgressDialog.ui \
|
gui/connect/ConnectProgressDialog.ui \
|
||||||
gui/connect/FriendRecommendDialog.ui \
|
gui/connect/FriendRecommendDialog.ui \
|
||||||
|
gui/msgs/MessagesDialog.ui \
|
||||||
gui/msgs/MessageComposer.ui \
|
gui/msgs/MessageComposer.ui \
|
||||||
gui/msgs/MessageWindow.ui\
|
gui/msgs/MessageWindow.ui\
|
||||||
gui/msgs/MessageWidget.ui\
|
gui/msgs/MessageWidget.ui\
|
||||||
|
@ -745,7 +745,6 @@ SOURCES += main.cpp \
|
||||||
# gui/ShareDialog.cpp \
|
# gui/ShareDialog.cpp \
|
||||||
# gui/SFListDelegate.cpp \
|
# gui/SFListDelegate.cpp \
|
||||||
gui/SoundManager.cpp \
|
gui/SoundManager.cpp \
|
||||||
gui/MessagesDialog.cpp \
|
|
||||||
gui/im_history/ImHistoryBrowser.cpp \
|
gui/im_history/ImHistoryBrowser.cpp \
|
||||||
gui/im_history/IMHistoryItemDelegate.cpp \
|
gui/im_history/IMHistoryItemDelegate.cpp \
|
||||||
gui/im_history/IMHistoryItemPainter.cpp \
|
gui/im_history/IMHistoryItemPainter.cpp \
|
||||||
|
@ -800,6 +799,7 @@ SOURCES += main.cpp \
|
||||||
gui/chat/ChatLobbyUserNotify.cpp \
|
gui/chat/ChatLobbyUserNotify.cpp \
|
||||||
gui/connect/ConfCertDialog.cpp \
|
gui/connect/ConfCertDialog.cpp \
|
||||||
gui/connect/PGPKeyDialog.cpp \
|
gui/connect/PGPKeyDialog.cpp \
|
||||||
|
gui/msgs/MessagesDialog.cpp \
|
||||||
gui/msgs/MessageComposer.cpp \
|
gui/msgs/MessageComposer.cpp \
|
||||||
gui/msgs/MessageWidget.cpp \
|
gui/msgs/MessageWidget.cpp \
|
||||||
gui/msgs/MessageWindow.cpp \
|
gui/msgs/MessageWindow.cpp \
|
||||||
|
|
|
@ -235,6 +235,13 @@ isEmpty(RS_UPNP_LIB):RS_UPNP_LIB = upnp ixml threadutil
|
||||||
# Why: hasing twice is not per se a security issue, but it makes it harder to change the settings for hashing.
|
# Why: hasing twice is not per se a security issue, but it makes it harder to change the settings for hashing.
|
||||||
#
|
#
|
||||||
# Backward compat: patched peers cannot connect to non patched peers older than Nov 2017.
|
# Backward compat: patched peers cannot connect to non patched peers older than Nov 2017.
|
||||||
|
#
|
||||||
|
# V07_NON_BACKWARD_COMPATIBLE_CHANGE_004:
|
||||||
|
#
|
||||||
|
# What: Do not probe that GXS tunnels accept fast items. Just assume they do.
|
||||||
|
# Why: Avoids sending probe packets
|
||||||
|
# BackwardCompat: old RS before Mai 2019 will not be able to distant chat.
|
||||||
|
#
|
||||||
###########################################################################################################################################################
|
###########################################################################################################################################################
|
||||||
|
|
||||||
#CONFIG += rs_v07_changes
|
#CONFIG += rs_v07_changes
|
||||||
|
@ -242,6 +249,7 @@ rs_v07_changes {
|
||||||
DEFINES += V07_NON_BACKWARD_COMPATIBLE_CHANGE_001
|
DEFINES += V07_NON_BACKWARD_COMPATIBLE_CHANGE_001
|
||||||
DEFINES += V07_NON_BACKWARD_COMPATIBLE_CHANGE_002
|
DEFINES += V07_NON_BACKWARD_COMPATIBLE_CHANGE_002
|
||||||
DEFINES += V07_NON_BACKWARD_COMPATIBLE_CHANGE_003
|
DEFINES += V07_NON_BACKWARD_COMPATIBLE_CHANGE_003
|
||||||
|
DEFINES += V07_NON_BACKWARD_COMPATIBLE_CHANGE_004
|
||||||
DEFINES += V07_NON_BACKWARD_COMPATIBLE_CHANGE_UNNAMED
|
DEFINES += V07_NON_BACKWARD_COMPATIBLE_CHANGE_UNNAMED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue