From: Soren Stoutner Date: Thu, 7 Jul 2016 22:21:02 +0000 (-0700) Subject: Add the ability to edit bookmarks. X-Git-Tag: v1.8~5 X-Git-Url: https://gitweb.stoutner.com/?a=commitdiff_plain;h=8951c7351854bbfc9f2815e74b81cc2a4d606bf0;p=PrivacyBrowserAndroid.git Add the ability to edit bookmarks. --- diff --git a/.idea/dictionaries/soren.xml b/.idea/dictionaries/soren.xml index f0434fc3..2d91de18 100644 --- a/.idea/dictionaries/soren.xml +++ b/.idea/dictionaries/soren.xml @@ -11,6 +11,7 @@ bookmarkurl buildapi buildversion + checkedtextview chromeversion commitdiff coordinatorlayout @@ -28,6 +29,7 @@ linearlayout listview logins + lossless mozilla nojs orbot @@ -36,6 +38,7 @@ redmine referer relativelayout + requery robinlinus samsung securitypatch diff --git a/app/src/main/assets/about_license.html b/app/src/main/assets/about_license.html deleted file mode 100644 index b495595d..00000000 --- a/app/src/main/assets/about_license.html +++ /dev/null @@ -1,712 +0,0 @@ - - - - - - - - -

Copyright

- -

Privacy Browser is copyright © 2015-2016 by Soren Stoutner.

- - -

License

- -

Privacy Browser is released under the GPLv3+ license. - The full text of the license is at the bottom of this document.

- - -

Attributions

- -

The icons in Privacy Browser come from the Android Material icon set, which is released under the CC-BY license.

- -

- - - - are derived from ic_security and ic_language. Modifications were made by Soren Stoutner in 2016.

- -

ic_language.

- -

ic_home.

- -

ic_arrow_back.

- -

ic_arrow_forward.

- -

ic_bookmark_border.

- -

ic_file_download.

- -

ic_settings.

- -

ic_import_contacts.

- -

ic_info_outline.

- -

ic_exit_to_app.

- -

ic_add.

- -

ic_download.

-
- -

GNU General Public License

-

Version 3, 29 June 2007

- -

Copyright © 2007 Free Software Foundation, Inc. - <http://fsf.org/>

- Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed.

- -

Preamble

- -

The GNU General Public License is a free, copyleft license for - software and other kinds of works.

- -

The licenses for most software and other practical works are designed - to take away your freedom to share and change the works. By contrast, - the GNU General Public License is 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. We, the Free Software Foundation, use the - GNU General Public License for most of our software; it applies also to - any other work released this way by its authors. You can apply it to - your programs, too.

- -

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.

- -

To protect your rights, we need to prevent others from denying you - these rights or asking you to surrender the rights. Therefore, you have - certain responsibilities if you distribute copies of the software, or if - you modify it: responsibilities to respect the freedom of others.

- -

For example, if you distribute copies of such a program, whether - gratis or for a fee, you must pass on to the recipients the same - freedoms that you received. You must make sure that they, too, receive - or can get the source code. And you must show them these terms so they - know their rights.

- -

Developers that use the GNU GPL protect your rights with two steps: - (1) assert copyright on the software, and (2) offer you this License - giving you legal permission to copy, distribute and/or modify it.

- -

For the developers' and authors' protection, the GPL clearly explains - that there is no warranty for this free software. For both users' and - authors' sake, the GPL requires that modified versions be marked as - changed, so that their problems will not be attributed erroneously to - authors of previous versions.

- -

Some devices are designed to deny users access to install or run - modified versions of the software inside them, although the manufacturer - can do so. This is fundamentally incompatible with the aim of - protecting users' freedom to change the software. The systematic - pattern of such abuse occurs in the area of products for individuals to - use, which is precisely where it is most unacceptable. Therefore, we - have designed this version of the GPL to prohibit the practice for those - products. If such problems arise substantially in other domains, we - stand ready to extend this provision to those domains in future versions - of the GPL, as needed to protect the freedom of users.

- -

Finally, every program is threatened constantly by software patents. - States should not allow patents to restrict development and use of - software on general-purpose computers, but in those that do, we wish to - avoid the special danger that patents applied to a free program could - make it effectively proprietary. To prevent this, the GPL assures that - patents cannot be used to render the program non-free.

- -

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 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 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 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:

- - - -

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. Use with the GNU Affero General Public License.

- -

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 Affero 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 special requirements of the GNU Affero General Public License, - section 13, concerning interaction through a network will apply to the - combination as such.

- -

14. Revised Versions of this License.

- -

The Free Software Foundation may publish revised and/or new versions of - the GNU 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 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 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 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

- - \ No newline at end of file diff --git a/app/src/main/assets/about_licenses.html b/app/src/main/assets/about_licenses.html new file mode 100644 index 00000000..6ff69285 --- /dev/null +++ b/app/src/main/assets/about_licenses.html @@ -0,0 +1,714 @@ + + + + + + + + +

Copyright

+ +

Privacy Browser is copyright © 2015-2016 by Soren Stoutner.

+ + +

License

+ +

Privacy Browser is released under the GPLv3+ license. + The full text of the license is at the bottom of this document.

+ + +

Attributions

+ +

The icons in Privacy Browser come from the Android Material icon set, which is released under the CC-BY license.

+ +

+ + + + are derived from ic_security and ic_language. Modifications were made by Soren Stoutner in 2016.

+ +

ic_language.

+ +

ic_home.

+ +

ic_arrow_back.

+ +

ic_arrow_forward.

+ +

ic_bookmark_border.

+ +

ic_file_download.

+ +

ic_settings.

+ +

ic_import_contacts.

+ +

ic_info_outline.

+ +

ic_exit_to_app.

+ +

ic_add.

+ +

ic_edit.

+ +

ic_download.

+
+ +

GNU General Public License

+

Version 3, 29 June 2007

+ +

Copyright © 2007 Free Software Foundation, Inc. + <http://fsf.org/>

+ Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed.

+ +

Preamble

+ +

The GNU General Public License is a free, copyleft license for + software and other kinds of works.

+ +

The licenses for most software and other practical works are designed + to take away your freedom to share and change the works. By contrast, + the GNU General Public License is 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. We, the Free Software Foundation, use the + GNU General Public License for most of our software; it applies also to + any other work released this way by its authors. You can apply it to + your programs, too.

+ +

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.

+ +

To protect your rights, we need to prevent others from denying you + these rights or asking you to surrender the rights. Therefore, you have + certain responsibilities if you distribute copies of the software, or if + you modify it: responsibilities to respect the freedom of others.

+ +

For example, if you distribute copies of such a program, whether + gratis or for a fee, you must pass on to the recipients the same + freedoms that you received. You must make sure that they, too, receive + or can get the source code. And you must show them these terms so they + know their rights.

+ +

Developers that use the GNU GPL protect your rights with two steps: + (1) assert copyright on the software, and (2) offer you this License + giving you legal permission to copy, distribute and/or modify it.

+ +

For the developers' and authors' protection, the GPL clearly explains + that there is no warranty for this free software. For both users' and + authors' sake, the GPL requires that modified versions be marked as + changed, so that their problems will not be attributed erroneously to + authors of previous versions.

+ +

Some devices are designed to deny users access to install or run + modified versions of the software inside them, although the manufacturer + can do so. This is fundamentally incompatible with the aim of + protecting users' freedom to change the software. The systematic + pattern of such abuse occurs in the area of products for individuals to + use, which is precisely where it is most unacceptable. Therefore, we + have designed this version of the GPL to prohibit the practice for those + products. If such problems arise substantially in other domains, we + stand ready to extend this provision to those domains in future versions + of the GPL, as needed to protect the freedom of users.

+ +

Finally, every program is threatened constantly by software patents. + States should not allow patents to restrict development and use of + software on general-purpose computers, but in those that do, we wish to + avoid the special danger that patents applied to a free program could + make it effectively proprietary. To prevent this, the GPL assures that + patents cannot be used to render the program non-free.

+ +

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 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 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 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:

+ + + +

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. Use with the GNU Affero General Public License.

+ +

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 Affero 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 special requirements of the GNU Affero General Public License, + section 13, concerning interaction through a network will apply to the + combination as such.

+ +

14. Revised Versions of this License.

+ +

The Free Software Foundation may publish revised and/or new versions of + the GNU 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 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 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 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

+ + \ No newline at end of file diff --git a/app/src/main/assets/images/ic_edit.png b/app/src/main/assets/images/ic_edit.png new file mode 100644 index 00000000..f4612f08 Binary files /dev/null and b/app/src/main/assets/images/ic_edit.png differ diff --git a/app/src/main/java/com/stoutner/privacybrowser/AboutActivity.java b/app/src/main/java/com/stoutner/privacybrowser/AboutActivity.java index 62978aac..6b462acd 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/AboutActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/AboutActivity.java @@ -83,7 +83,7 @@ public class AboutActivity extends AppCompatActivity { return getString(R.string.changelog); case 4: - return getString(R.string.license); + return getString(R.string.licenses); case 5: return getString(R.string.contributors); diff --git a/app/src/main/java/com/stoutner/privacybrowser/AboutTabFragment.java b/app/src/main/java/com/stoutner/privacybrowser/AboutTabFragment.java index 19de018e..c49fbc88 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/AboutTabFragment.java +++ b/app/src/main/java/com/stoutner/privacybrowser/AboutTabFragment.java @@ -151,7 +151,7 @@ public class AboutTabFragment extends Fragment { break; case 4: - tabWebView.loadUrl("file:///android_asset/about_license.html"); + tabWebView.loadUrl("file:///android_asset/about_licenses.html"); break; case 5: diff --git a/app/src/main/java/com/stoutner/privacybrowser/BookmarksActivity.java b/app/src/main/java/com/stoutner/privacybrowser/BookmarksActivity.java index 556bd60c..108dcc04 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/BookmarksActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/BookmarksActivity.java @@ -25,6 +25,8 @@ import android.content.Context; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; @@ -40,6 +42,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AdapterView; +import android.widget.CheckBox; import android.widget.EditText; import android.widget.ImageView; import android.widget.ListView; @@ -47,12 +50,17 @@ import android.widget.TextView; import java.io.ByteArrayOutputStream; -public class BookmarksActivity extends AppCompatActivity implements CreateBookmark.CreateBookmarkListener { - private BookmarksDatabaseHandler bookmarksDatabaseHandler; - private ListView bookmarksListView; +public class BookmarksActivity extends AppCompatActivity implements CreateBookmark.CreateBookmarkListener, EditBookmark.EditBookmarkListener { + // `bookmarksDatabaseHandler` is public static so it can be accessed from EditBookmark. It is also used in `onCreate()`, + // `onCreateBookmarkCreate()`, `updateBookmarksListView()`, and `updateBookmarksListViewExcept()`. + public static BookmarksDatabaseHandler bookmarksDatabaseHandler; - // deleteBookmarkMenuItem is used in onCreate() and onPrepareOptionsMenu(). - private MenuItem deleteBookmarkMenuItem; + // `bookmarksListView` is public static so it can be accessed from EditBookmark. + // It is also used in `onCreate()`, `updateBookmarksListView()`, and `updateBookmarksListViewExcept()`. + public static ListView bookmarksListView; + + // `contextualActionMode` is used in `onCreate()` and `onEditBookmarkSave()`. + private ActionMode contextualActionMode; @Override protected void onCreate(Bundle savedInstanceState) { @@ -69,13 +77,16 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma appBar.setDisplayHomeAsUpEnabled(true); // Initialize the database handler and the ListView. + // `this` specifies the context. The two `null`s do not specify the database name or a `CursorFactory`. + // The `0` is to specify a database version, but that is set instead using a constant in BookmarksDatabaseHandler. bookmarksDatabaseHandler = new BookmarksDatabaseHandler(this, null, null, 0); bookmarksListView = (ListView) findViewById(R.id.bookmarks_listview); // Display the bookmarks in the ListView. updateBookmarksListView(); - // Set a listener so that tapping a list item loads the URL. We need to store the activity in a variable so that we can return to the parent activity after loading the URL. + // Set a listener so that tapping a list item loads the URL. We need to store the activity + // in a variable so that we can return to the parent activity after loading the URL. final Activity bookmarksActivity = this; bookmarksListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override @@ -92,26 +103,20 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma } }); - // registerForContextMenu(bookmarksListView); - + // `MultiChoiceModeListener` handles long clicks. bookmarksListView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() { - @Override - public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { - String numberSelectedString; - long[] selectedItemsLongArray = bookmarksListView.getCheckedItemIds(); - - numberSelectedString = selectedItemsLongArray.length + " " + getString(R.string.selected); - - mode.setSubtitle(numberSelectedString); - } + // `editBookmarkMenuItem` is used in `onCreateActionMode()` and `onItemCheckedStateChanged`. + MenuItem editBookmarkMenuItem; @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { - // Inflate the menu for the contextual app bar. + // Inflate the menu for the contextual app bar and set the title. getMenuInflater().inflate(R.menu.bookmarks_context_menu, menu); - mode.setTitle(R.string.bookmarks); + // Get a handle for `R.id.edit_bookmark`. + editBookmarkMenuItem = menu.findItem(R.id.edit_bookmark); + return true; } @@ -120,25 +125,52 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma return false; } + @Override + public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { + // Get an array of the selected bookmarks. + long[] selectedBookmarksLongArray = bookmarksListView.getCheckedItemIds(); + + // Calculate the number of selected bookmarks. + int numberOfSelectedBookmarks = selectedBookmarksLongArray.length; + + // List the number of selected bookmarks in the subtitle. + mode.setSubtitle(numberOfSelectedBookmarks + " " + getString(R.string.selected)); + + // Show the `Edit` option only if 1 bookmark is selected. + if (numberOfSelectedBookmarks == 1) { + editBookmarkMenuItem.setVisible(true); + } else { + editBookmarkMenuItem.setVisible(false); + } + } + @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { int menuItemId = item.getItemId(); switch (menuItemId) { + case R.id.edit_bookmark: + // Show the `EditBookmark` `AlertDialog` and name the instance `@string/edit_bookmark`. + DialogFragment editBookmarkDialog = new EditBookmark(); + editBookmarkDialog.show(getFragmentManager(), "@string/edit_bookmark"); + + contextualActionMode = mode; + break; + case R.id.delete_bookmark: // Get an array of the selected rows. - final long[] selectedItemsLongArray = bookmarksListView.getCheckedItemIds(); + final long[] selectedBookmarksLongArray = bookmarksListView.getCheckedItemIds(); String snackbarMessage; // Determine how many items are in the array and prepare an appropriate Snackbar message. - if (selectedItemsLongArray.length == 1) { + if (selectedBookmarksLongArray.length == 1) { snackbarMessage = getString(R.string.one_bookmark_deleted); } else { - snackbarMessage = selectedItemsLongArray.length + " " + getString(R.string.bookmarks_deleted); + snackbarMessage = selectedBookmarksLongArray.length + " " + getString(R.string.bookmarks_deleted); } - updateBookmarksListViewExcept(selectedItemsLongArray); + updateBookmarksListViewExcept(selectedBookmarksLongArray); // Show a SnackBar. Snackbar.make(findViewById(R.id.bookmarks_coordinatorlayout), snackbarMessage, Snackbar.LENGTH_LONG) @@ -162,7 +194,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // The Snackbar was dismissed without the "Undo" button being pushed. default: // Delete each selected row. - for (long databaseIdLong : selectedItemsLongArray) { + for (long databaseIdLong : selectedBookmarksLongArray) { // Convert `databaseIdLong` to an int. int databaseIdInt = (int) databaseIdLong; @@ -177,7 +209,9 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma // Close the contextual app bar. mode.finish(); + break; } + // Consume the click. return true; } @@ -193,68 +227,81 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma createBookmarkFAB.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - // Show the CreateBookmark AlertDialog and name the instance "@string/create_bookmark". + // Show the `CreateBookmark` `AlertDialog` and name the instance `@string/create_bookmark`. DialogFragment createBookmarkDialog = new CreateBookmark(); createBookmarkDialog.show(getFragmentManager(), "@string/create_bookmark"); } }); } - /* - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - getMenuInflater().inflate(R.menu.bookmarks_context_menu, menu); - } */ - - /*@Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.menu_bookmarks_options, menu); - - return true; - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - // Disable the delete icon. - deleteBookmarkMenuItem = menu.findItem(R.id.delete_bookmark); - deleteBookmarkMenuItem.setVisible(false); - - // Run all the other default commands. - super.onPrepareOptionsMenu(menu); - - // `return true` displays the menu; - return true; - }*/ - @Override public void onCreateBookmarkCancel(DialogFragment createBookmarkDialogFragment) { - // Do nothing because the user selected "Cancel". + // Do nothing because the user selected `Cancel`. } @Override public void onCreateBookmarkCreate(DialogFragment createBookmarkDialogFragment) { - // Get the EditTexts from the DialogFragment and extract the strings. + // Get the `EditText`s from the `createBookmarkDialogFragment` and extract the strings. EditText createBookmarkNameEditText = (EditText) createBookmarkDialogFragment.getDialog().findViewById(R.id.create_bookmark_name_edittext); String bookmarkNameString = createBookmarkNameEditText.getText().toString(); - EditText createBookmarkURLEditText = (EditText) createBookmarkDialogFragment.getDialog().findViewById(R.id.create_bookmark_url_edittext); - String bookmarkURLString = createBookmarkURLEditText.getText().toString(); + EditText createBookmarkUrlEditText = (EditText) createBookmarkDialogFragment.getDialog().findViewById(R.id.create_bookmark_url_edittext); + String bookmarkUrlString = createBookmarkUrlEditText.getText().toString(); - // Convert the favoriteIcon Bitmap to a byte array. + // Convert the favoriteIcon Bitmap to a byte array. `0` is for lossless compression (the only option for a PNG). ByteArrayOutputStream favoriteIconByteArrayOutputStream = new ByteArrayOutputStream(); MainWebViewActivity.favoriteIcon.compress(Bitmap.CompressFormat.PNG, 0, favoriteIconByteArrayOutputStream); byte[] favoriteIconByteArray = favoriteIconByteArrayOutputStream.toByteArray(); // Create the bookmark. - bookmarksDatabaseHandler.createBookmark(bookmarkNameString, bookmarkURLString, favoriteIconByteArray); + bookmarksDatabaseHandler.createBookmark(bookmarkNameString, bookmarkUrlString, favoriteIconByteArray); // Refresh the ListView. updateBookmarksListView(); } + @Override + public void onEditBookmarkCancel(DialogFragment editBookmarkDialogFragment) { + // Do nothing because the user selected `Cancel`. + } + + @Override + public void onEditBookmarkSave(DialogFragment editBookmarkDialogFragment) { + // Get the `EditText`s from the `editBookmarkDialogFragment` and extract the strings. + EditText editBookmarkNameEditText = (EditText) editBookmarkDialogFragment.getDialog().findViewById(R.id.edit_bookmark_name_edittext); + String bookmarkNameString = editBookmarkNameEditText.getText().toString(); + EditText editBookmarkUrlEditText = (EditText) editBookmarkDialogFragment.getDialog().findViewById(R.id.edit_bookmark_url_edittext); + String bookmarkUrlString = editBookmarkUrlEditText.getText().toString(); + + CheckBox useNewFavoriteIconBitmap = (CheckBox) editBookmarkDialogFragment.getDialog().findViewById(R.id.edit_bookmark_use_new_favorite_icon_checkbox); + byte[] favoriteIconByteArray; + + // Get a long array with the the databaseId of the selected bookmark and convert it to an `int`. + long[] selectedBookmarksLongArray = bookmarksListView.getCheckedItemIds(); + int selectedBookmarkDatabaseId = (int) selectedBookmarksLongArray[0]; + + if (useNewFavoriteIconBitmap.isChecked()) { + ImageView newFavoriteIconImageView = (ImageView) editBookmarkDialogFragment.getDialog().findViewById(R.id.edit_bookmark_new_favorite_icon); + Drawable favoriteIconDrawable = newFavoriteIconImageView.getDrawable(); + Bitmap favoriteIconBitmap = ((BitmapDrawable) favoriteIconDrawable).getBitmap(); + ByteArrayOutputStream favoriteIconByteArrayOutputStream = new ByteArrayOutputStream(); + favoriteIconBitmap.compress(Bitmap.CompressFormat.PNG, 0, favoriteIconByteArrayOutputStream); + favoriteIconByteArray = favoriteIconByteArrayOutputStream.toByteArray(); + bookmarksDatabaseHandler.updateBookmark(selectedBookmarkDatabaseId, bookmarkNameString, bookmarkUrlString, favoriteIconByteArray); + + } else { + // Update the bookmark. + bookmarksDatabaseHandler.updateBookmark(selectedBookmarkDatabaseId, bookmarkNameString, bookmarkUrlString); + } + + contextualActionMode.finish(); + + // Refresh the `ListView`. + updateBookmarksListView(); + } + private void updateBookmarksListView() { // Get a Cursor with the current contents of the bookmarks database. - final Cursor bookmarksCursor = bookmarksDatabaseHandler.getBookmarksCursor(); + final Cursor bookmarksCursor = bookmarksDatabaseHandler.getAllBookmarksCursor(); // Setup bookmarksCursorAdapter with `this` context. The `false` disables autoRequery. CursorAdapter bookmarksCursorAdapter = new CursorAdapter(this, bookmarksCursor, false) { @@ -266,10 +313,10 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma @Override public void bindView(View view, Context context, Cursor cursor) { - // Get the favorite icon byte array from the cursor. - byte[] favoriteIconByteArray = cursor.getBlob(cursor.getColumnIndex(BookmarksDatabaseHandler.FAVORITEICON)); + // Get the favorite icon byte array from the `Cursor`. + byte[] favoriteIconByteArray = cursor.getBlob(cursor.getColumnIndex(BookmarksDatabaseHandler.FAVORITE_ICON)); - // Convert the byte array to a Bitmap beginning at the first byte and ending at the last. + // Convert the byte array to a `Bitmap` beginning at the first byte and ending at the last. Bitmap favoriteIconBitmap = BitmapFactory.decodeByteArray(favoriteIconByteArray, 0, favoriteIconByteArray.length); // Display the bitmap in `bookmarkFavoriteIcon`. @@ -304,7 +351,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma @Override public void bindView(View view, Context context, Cursor cursor) { // Get the favorite icon byte array from the cursor. - byte[] favoriteIconByteArray = cursor.getBlob(cursor.getColumnIndex(BookmarksDatabaseHandler.FAVORITEICON)); + byte[] favoriteIconByteArray = cursor.getBlob(cursor.getColumnIndex(BookmarksDatabaseHandler.FAVORITE_ICON)); // Convert the byte array to a Bitmap beginning at the first byte and ending at the last. Bitmap favoriteIconBitmap = BitmapFactory.decodeByteArray(favoriteIconByteArray, 0, favoriteIconByteArray.length); diff --git a/app/src/main/java/com/stoutner/privacybrowser/BookmarksDatabaseHandler.java b/app/src/main/java/com/stoutner/privacybrowser/BookmarksDatabaseHandler.java index cacc8530..2194bc99 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/BookmarksDatabaseHandler.java +++ b/app/src/main/java/com/stoutner/privacybrowser/BookmarksDatabaseHandler.java @@ -31,12 +31,12 @@ public class BookmarksDatabaseHandler extends SQLiteOpenHelper { private static final String BOOKMARKS_TABLE = "bookmarks"; public static final String _ID = "_id"; - public static final String DISPLAYORDER = "displayorder"; + public static final String DISPLAY_ORDER = "displayorder"; public static final String BOOKMARK_NAME = "bookmarkname"; public static final String BOOKMARK_URL = "bookmarkurl"; - public static final String PARENTFOLDER = "parentfolder"; - public static final String ISFOLDER = "isfolder"; - public static final String FAVORITEICON = "favoriteicon"; + public static final String PARENT_FOLDER = "parentfolder"; + public static final String IS_FOLDER = "isfolder"; + public static final String FAVORITE_ICON = "favoriteicon"; public BookmarksDatabaseHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, BOOKMARKS_DATABASE, factory, SCHEMA_VERSION); @@ -47,12 +47,12 @@ public class BookmarksDatabaseHandler extends SQLiteOpenHelper { // Create the database if it doesn't exist. String CREATE_BOOKMARKS_TABLE = "CREATE TABLE " + BOOKMARKS_TABLE + " (" + _ID + " integer primary key, " + - DISPLAYORDER + " integer, " + + DISPLAY_ORDER + " integer, " + BOOKMARK_NAME + " text, " + BOOKMARK_URL + " text, " + - PARENTFOLDER + " text, " + - ISFOLDER + " boolean, " + - FAVORITEICON + " blob);"; + PARENT_FOLDER + " text, " + + IS_FOLDER + " boolean, " + + FAVORITE_ICON + " blob);"; bookmarksDatabase.execSQL(CREATE_BOOKMARKS_TABLE); } @@ -68,9 +68,9 @@ public class BookmarksDatabaseHandler extends SQLiteOpenHelper { // ID is created automatically. bookmarkContentValues.put(BOOKMARK_NAME, bookmarkName); bookmarkContentValues.put(BOOKMARK_URL, bookmarkURL); - bookmarkContentValues.put(PARENTFOLDER, ""); - bookmarkContentValues.put(ISFOLDER, false); - bookmarkContentValues.put(FAVORITEICON, favoriteIcon); + bookmarkContentValues.put(PARENT_FOLDER, ""); + bookmarkContentValues.put(IS_FOLDER, false); + bookmarkContentValues.put(FAVORITE_ICON, favoriteIcon); // Get a writable database handle. SQLiteDatabase bookmarksDatabase = this.getWritableDatabase(); @@ -82,16 +82,17 @@ public class BookmarksDatabaseHandler extends SQLiteOpenHelper { bookmarksDatabase.close(); } - public Cursor getBookmarksCursor() { + public Cursor getBookmarkCursor(int databaseId) { // Get a readable database handle. SQLiteDatabase bookmarksDatabase = this.getReadableDatabase(); - // Get everything in the BOOKMARKS_TABLE. - final String GET_ALL_BOOKMARKS = "Select * FROM " + BOOKMARKS_TABLE; + // Prepare the SQL statement to get the cursor for `databaseId`. + final String GET_ONE_BOOKMARK = "Select * FROM " + BOOKMARKS_TABLE + + " WHERE " + _ID + " = " + databaseId; - // Return the results as a Cursor. The second argument is `null` because there are no selectionArgs. - // We can't close the Cursor because we need to use it in the parent activity. - return bookmarksDatabase.rawQuery(GET_ALL_BOOKMARKS, null); + // Return the results as a `Cursor`. The second argument is `null` because there are no selectionArgs. + // We can't close the `Cursor` because we need to use it in the parent activity. + return bookmarksDatabase.rawQuery(GET_ONE_BOOKMARK, null); } public Cursor getBookmarksCursorExcept(long[] exceptIdLongArray) { @@ -114,9 +115,21 @@ public class BookmarksDatabaseHandler extends SQLiteOpenHelper { final String GET_All_BOOKMARKS_EXCEPT_SPECIFIED = "Select * FROM " + BOOKMARKS_TABLE + " WHERE " + _ID + " NOT IN (" + doNotGetIdsString + ")"; + // Return the results as a `Cursor`. The second argument is `null` because there are no selectionArgs. + // We can't close the `Cursor` because we need to use it in the parent activity. + return bookmarksDatabase.rawQuery(GET_All_BOOKMARKS_EXCEPT_SPECIFIED, null); + } + + public Cursor getAllBookmarksCursor() { + // Get a readable database handle. + SQLiteDatabase bookmarksDatabase = this.getReadableDatabase(); + + // Get everything in the BOOKMARKS_TABLE. + final String GET_ALL_BOOKMARKS = "Select * FROM " + BOOKMARKS_TABLE; + // Return the results as a Cursor. The second argument is `null` because there are no selectionArgs. // We can't close the Cursor because we need to use it in the parent activity. - return bookmarksDatabase.rawQuery(GET_All_BOOKMARKS_EXCEPT_SPECIFIED, null); + return bookmarksDatabase.rawQuery(GET_ALL_BOOKMARKS, null); } public String getBookmarkURL(int databaseId) { @@ -143,6 +156,41 @@ public class BookmarksDatabaseHandler extends SQLiteOpenHelper { return bookmarkURLString; } + public void updateBookmark(int databaseId, String bookmarkName, String bookmarkUrl) { + // Store the updated values in `bookmarkContentValues`. + ContentValues bookmarkContentValues = new ContentValues(); + + bookmarkContentValues.put(BOOKMARK_NAME, bookmarkName); + bookmarkContentValues.put(BOOKMARK_URL, bookmarkUrl); + + // Get a writable database handle. + SQLiteDatabase bookmarksDatabase = this.getWritableDatabase(); + + // Update the database. The last argument is `null` because there are no `whereArgs`. + bookmarksDatabase.update(BOOKMARKS_TABLE, bookmarkContentValues, _ID + " = " + databaseId, null); + + // Close the database handle. + bookmarksDatabase.close(); + } + + public void updateBookmark(int databaseId, String bookmarkName, String bookmarkUrl, byte[] favoriteIcon) { + // Store the updated values in `bookmarkContentValues`. + ContentValues bookmarkContentValues = new ContentValues(); + + bookmarkContentValues.put(BOOKMARK_NAME, bookmarkName); + bookmarkContentValues.put(BOOKMARK_URL, bookmarkUrl); + bookmarkContentValues.put(FAVORITE_ICON, favoriteIcon); + + // Get a writable database handle. + SQLiteDatabase bookmarksDatabase = this.getWritableDatabase(); + + // Update the database. The last argument is `null` because there are no `whereArgs`. + bookmarksDatabase.update(BOOKMARKS_TABLE, bookmarkContentValues, _ID + " = " + databaseId, null); + + // Close the database handle. + bookmarksDatabase.close(); + } + public void deleteBookmark(int databaseId) { // Get a writable database handle. SQLiteDatabase bookmarksDatabase = this.getWritableDatabase(); diff --git a/app/src/main/java/com/stoutner/privacybrowser/CreateBookmark.java b/app/src/main/java/com/stoutner/privacybrowser/CreateBookmark.java index f844ca34..64714358 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/CreateBookmark.java +++ b/app/src/main/java/com/stoutner/privacybrowser/CreateBookmark.java @@ -26,11 +26,9 @@ import android.content.DialogInterface; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.support.annotation.NonNull; -// If we don't use android.support.v7.app.AlertDialog instead of android.app.AlertDialog then the dialog will be covered by the keyboard. +// If we don't use `android.support.v7.app.AlertDialog` instead of `android.app.AlertDialog` then the dialog will be covered by the keyboard. import android.support.v7.app.AlertDialog; import android.view.KeyEvent; -import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import android.widget.EditText; @@ -43,12 +41,14 @@ public class CreateBookmark extends DialogFragment { void onCreateBookmarkCreate(DialogFragment createBookmarkDialogFragment); } - // createBookmarkListener is used in onAttach() and onCreateDialog() + // `createBookmarkListener` is used in `onAttach()` and `onCreateDialog()` private CreateBookmarkListener createBookmarkListener; - // Check to make sure the parent activity implements the listener. + public void onAttach(Activity parentActivity) { super.onAttach(parentActivity); + + // Get a handle for `CreateBookmarkListener` from the `parentActivity`. try { createBookmarkListener = (CreateBookmarkListener) parentActivity; } catch(ClassCastException exception) { @@ -56,62 +56,57 @@ public class CreateBookmark extends DialogFragment { } } - // onCreateDialog requires @NonNull. @Override - @NonNull public Dialog onCreateDialog(Bundle savedInstanceState) { // Create a drawable version of the favorite icon. Drawable favoriteIconDrawable = new BitmapDrawable(getResources(), MainWebViewActivity.favoriteIcon); - // Get the activity's layout inflater. - LayoutInflater customDialogInflater = getActivity().getLayoutInflater(); - - // Use AlertDialog.Builder to create the AlertDialog. The style formats the color of the button text. + // Use `AlertDialog.Builder` to create the `AlertDialog`. The style formats the color of the button text. AlertDialog.Builder createBookmarkDialogBuilder = new AlertDialog.Builder(getActivity(), R.style.PrivacyBrowser_AlertDialog); createBookmarkDialogBuilder.setTitle(R.string.create_bookmark); createBookmarkDialogBuilder.setIcon(favoriteIconDrawable); - // The parent view is "null" because it will be assigned by AlertDialog. - createBookmarkDialogBuilder.setView(customDialogInflater.inflate(R.layout.create_bookmark_dialog, null)); + // The parent view is `null` because it will be assigned by `AlertDialog`. + createBookmarkDialogBuilder.setView(getActivity().getLayoutInflater().inflate(R.layout.create_bookmark_dialog, null)); - // Set an onClick listener on the negative button. + // Set an `onClick()` listener for the negative button. createBookmarkDialogBuilder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + // Return the `DialogFragment` to the parent activity on cancel. createBookmarkListener.onCreateBookmarkCancel(CreateBookmark.this); } }); - // Set an onClick listener on the positive button. + // Set an `onClick()` listener for the positive button. createBookmarkDialogBuilder.setPositiveButton(R.string.create, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + // Return the `DialogFragment` to the parent activity on create. createBookmarkListener.onCreateBookmarkCreate(CreateBookmark.this); } }); - // Create an AlertDialog from the AlertDialog.Builder. + // Create an `AlertDialog` from the `AlertDialog.Builder`. final AlertDialog createBookmarkDialog = createBookmarkDialogBuilder.create(); - // Show the keyboard when the Dialog is displayed on the screen. + // Show the keyboard when the `Dialog` is displayed on the screen. createBookmarkDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); - // We need to show the AlertDialog before we can call setOnKeyListener() below. + // We need to show the `AlertDialog` before we can call `setOnKeyListener()` below. createBookmarkDialog.show(); - // Allow the "enter" key on the keyboard to create the bookmark from "create_bookmark_name_edittext". + // Allow the `enter` key on the keyboard to create the bookmark from `create_bookmark_name_edittext`. EditText createBookmarkNameEditText = (EditText) createBookmarkDialog.findViewById(R.id.create_bookmark_name_edittext); assert createBookmarkNameEditText != null; // Remove the warning below that createBookmarkNameEditText might be null. createBookmarkNameEditText.setOnKeyListener(new View.OnKeyListener() { public boolean onKey(View v, int keyCode, KeyEvent event) { - // If the event is a key-down on the "enter" button, select the PositiveButton "Create". + // If the event is a key-down on the `enter` button, select the PositiveButton `Create`. if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { - // Trigger the createBookmarkListener. + // Trigger `createBookmarkListener` and return the DialogFragment to the parent activity. createBookmarkListener.onCreateBookmarkCreate(CreateBookmark.this); - - // Manually dismiss the AlertDialog. + // Manually dismiss the `AlertDialog`. createBookmarkDialog.dismiss(); - // Consume the event. return true; } else { // If any other key was pressed, do not consume the event. @@ -120,22 +115,20 @@ public class CreateBookmark extends DialogFragment { } }); - // Set the formattedUrlString as the initial text of "create_bookmark_url_edittext". + // Set the formattedUrlString as the initial text of `create_bookmark_url_edittext`. EditText createBookmarkUrlEditText = (EditText) createBookmarkDialog.findViewById(R.id.create_bookmark_url_edittext); - assert createBookmarkUrlEditText != null;// Remove the warning below that createBookmarkUrlEditText might be null. + assert createBookmarkUrlEditText != null;// Remove the warning below that `createBookmarkUrlEditText` might be null. createBookmarkUrlEditText.setText(MainWebViewActivity.formattedUrlString); - // Allow the "enter" key on the keyboard to create the bookmark from "create_bookmark_url_edittext". + // Allow the `enter` key on the keyboard to create the bookmark from `create_bookmark_url_edittext`. createBookmarkUrlEditText.setOnKeyListener(new View.OnKeyListener() { public boolean onKey(View v, int keyCode, KeyEvent event) { // If the event is a key-down on the "enter" button, select the PositiveButton "Create". if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { - // Trigger the create listener. + // Trigger `createBookmarkListener` and return the DialogFragment to the parent activity. createBookmarkListener.onCreateBookmarkCreate(CreateBookmark.this); - - // Manually dismiss the AlertDialog. + // Manually dismiss the `AlertDialog`. createBookmarkDialog.dismiss(); - // Consume the event. return true; } else { // If any other key was pressed, do not consume the event. @@ -144,7 +137,7 @@ public class CreateBookmark extends DialogFragment { } }); - // onCreateDialog requires the return of an AlertDialog + // `onCreateDialog()` requires the return of an `AlertDialog`. return createBookmarkDialog; } } \ No newline at end of file diff --git a/app/src/main/java/com/stoutner/privacybrowser/CreateHomeScreenShortcut.java b/app/src/main/java/com/stoutner/privacybrowser/CreateHomeScreenShortcut.java index f4f4034e..ea225ca3 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/CreateHomeScreenShortcut.java +++ b/app/src/main/java/com/stoutner/privacybrowser/CreateHomeScreenShortcut.java @@ -26,7 +26,6 @@ import android.content.DialogInterface; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.support.annotation.NonNull; // If we don't use android.support.v7.app.AlertDialog instead of android.app.AlertDialog then the dialog will be covered by the keyboard. import android.support.v7.app.AlertDialog; import android.view.KeyEvent; @@ -56,9 +55,7 @@ public class CreateHomeScreenShortcut extends DialogFragment { } } - // onCreateDialog requires @NonNull. @Override - @NonNull public Dialog onCreateDialog(Bundle savedInstanceState) { // Create a drawable version of the favorite icon. Drawable favoriteIconDrawable = new BitmapDrawable(getResources(), MainWebViewActivity.favoriteIcon); diff --git a/app/src/main/java/com/stoutner/privacybrowser/EditBookmark.java b/app/src/main/java/com/stoutner/privacybrowser/EditBookmark.java new file mode 100644 index 00000000..27d522b8 --- /dev/null +++ b/app/src/main/java/com/stoutner/privacybrowser/EditBookmark.java @@ -0,0 +1,166 @@ +/** + * Copyright 2016 Soren Stoutner . + * + * This file is part of Privacy Browser . + * + * Privacy Browser is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Privacy Browser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Privacy Browser. If not, see . + */ + +package com.stoutner.privacybrowser; + +import android.app.Activity; +import android.app.Dialog; +import android.app.DialogFragment; +import android.content.DialogInterface; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +// If we don't use `android.support.v7.app.AlertDialog` instead of `android.app.AlertDialog` then the dialog will be covered by the keyboard. +import android.support.v7.app.AlertDialog; +import android.view.KeyEvent; +import android.view.View; +import android.view.WindowManager; +import android.widget.EditText; +import android.widget.ImageView; + +public class EditBookmark extends DialogFragment { + // The public interface is used to send information back to the parent activity. + public interface EditBookmarkListener { + void onEditBookmarkCancel(DialogFragment editBookmarkDialogFragment); + + void onEditBookmarkSave(DialogFragment editBookmarkDialogFragment); + } + + // `editBookmarkListener` is used in `onAttach()` and `onCreateDialog()` + private EditBookmarkListener editBookmarkListener; + + public void onAttach(Activity parentActivity) { + super.onAttach(parentActivity); + + // Get a handle for `EditBookmarkListener` from the `parentActivity`. + try { + editBookmarkListener = (EditBookmarkListener) parentActivity; + } catch(ClassCastException exception) { + throw new ClassCastException(parentActivity.toString() + " must implement EditBookmarkListener."); + } + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + // Get a long array with the the databaseId of the selected bookmark and convert it to an `int`. + long[] selectedBookmarksLongArray = BookmarksActivity.bookmarksListView.getCheckedItemIds(); + int selectedBookmarkDatabaseId = (int) selectedBookmarksLongArray[0]; + + // Get a `Cursor` with the specified bookmark and move it to the first position. + Cursor bookmarkCursor = BookmarksActivity.bookmarksDatabaseHandler.getBookmarkCursor(selectedBookmarkDatabaseId); + bookmarkCursor.moveToFirst(); + + // Get the favorite icon byte array from the `Cursor`. + byte[] favoriteIconByteArray = bookmarkCursor.getBlob(bookmarkCursor.getColumnIndex(BookmarksDatabaseHandler.FAVORITE_ICON)); + // Convert the byte array to a `Bitmap` beginning at the first byte and ending at the last. + Bitmap favoriteIconBitmap = BitmapFactory.decodeByteArray(favoriteIconByteArray, 0, favoriteIconByteArray.length); + // Convert the `Bitmap` to a `Drawable`. + Drawable favoriteIconDrawable = new BitmapDrawable(getResources(), favoriteIconBitmap); + + // Use `AlertDialog.Builder` to create the `AlertDialog`. The style formats the color of the button text. + AlertDialog.Builder editBookmarkDialogBuilder = new AlertDialog.Builder(getActivity(), R.style.PrivacyBrowser_AlertDialog); + editBookmarkDialogBuilder.setTitle(R.string.edit_bookmark); + editBookmarkDialogBuilder.setIcon(favoriteIconDrawable); + // The parent view is `null` because it will be assigned by `AlertDialog`. + editBookmarkDialogBuilder.setView(getActivity().getLayoutInflater().inflate(R.layout.edit_bookmark_dialog, null)); + + // Set an `onClick()` listener for the negative button. + editBookmarkDialogBuilder.setNegativeButton(R.string.cancel, new Dialog.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // Return the `DialogFragment` to the parent activity on cancel. + editBookmarkListener.onEditBookmarkCancel(EditBookmark.this); + } + }); + + // Set the `onClick()` listener fo the positive button. + editBookmarkDialogBuilder.setPositiveButton(R.string.save, new Dialog.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // Return the `DialogFragment` to the parent activity on save. + editBookmarkListener.onEditBookmarkSave(EditBookmark.this); + } + }); + + + // Create an `AlertDialog` from the `AlertDialog.Builder`. + final AlertDialog editBookmarkDialog = editBookmarkDialogBuilder.create(); + + // Show the keyboard when the `Dialog` is displayed on the screen. + editBookmarkDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); + + // We need to show the `AlertDialog` before we can call `setOnKeyListener()` below. + editBookmarkDialog.show(); + + // Get a `Drawable` of the favorite icon from `mainWebView` and display it in `edit_bookmark_new_favorite_icon`. + ImageView newFavoriteIcon = (ImageView) editBookmarkDialog.findViewById(R.id.edit_bookmark_new_favorite_icon); + assert newFavoriteIcon != null; // Remove the warning below that `newFavoriteIcon` might be null. + newFavoriteIcon.setImageBitmap(MainWebViewActivity.favoriteIcon); + + // Load the text for `edit_bookmark_name_edittext`. + EditText bookmarkNameEditText = (EditText) editBookmarkDialog.findViewById(R.id.edit_bookmark_name_edittext); + assert bookmarkNameEditText != null; // Remove the warning below that `bookmarkNameEditText` might be null. + bookmarkNameEditText.setText(bookmarkCursor.getString(bookmarkCursor.getColumnIndex(BookmarksDatabaseHandler.BOOKMARK_NAME))); + + // Allow the `enter` key on the keyboard to save the bookmark from `edit_bookmark_name_edittext`. + bookmarkNameEditText.setOnKeyListener(new View.OnKeyListener() { + public boolean onKey(View v, int keyCode, KeyEvent event) { + // If the event is a key-down on the "enter" button, select the PositiveButton `Save`. + if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { + // Trigger `editBookmarkListener` and return the DialogFragment to the parent activity. + editBookmarkListener.onEditBookmarkSave(EditBookmark.this); + // Manually dismiss the `AlertDialog`. + editBookmarkDialog.dismiss(); + // Consume the event. + return true; + } else { // If any other key was pressed, do not consume the event. + return false; + } + } + }); + + // Load the text for `create_bookmark_url_edittext`. + EditText bookmarkUrlEditText = (EditText) editBookmarkDialog.findViewById(R.id.edit_bookmark_url_edittext); + assert bookmarkUrlEditText != null;// Remove the warning below that `bookmarkUrlEditText` might be null. + bookmarkUrlEditText.setText(bookmarkCursor.getString(bookmarkCursor.getColumnIndex(BookmarksDatabaseHandler.BOOKMARK_URL))); + + // Allow the "enter" key on the keyboard to save the bookmark from `edit_bookmark_url_edittext`. + bookmarkUrlEditText.setOnKeyListener(new View.OnKeyListener() { + public boolean onKey(View v, int keyCode, KeyEvent event) { + // If the event is a key-down on the `enter` button, select the PositiveButton `Save`. + if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { + // Trigger `editBookmarkListener` and return the DialogFragment to the parent activity. + editBookmarkListener.onEditBookmarkSave(EditBookmark.this); + // Manually dismiss the `AlertDialog`. + editBookmarkDialog.dismiss(); + // Consume the event. + return true; + } else { // If any other key was pressed, do not consume the event. + return false; + } + } + }); + + // `onCreateDialog` requires the return of an `AlertDialog`. + return editBookmarkDialog; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/stoutner/privacybrowser/MainWebViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/MainWebViewActivity.java index 5f549b25..e59168fe 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/MainWebViewActivity.java @@ -65,8 +65,8 @@ import java.net.URLEncoder; // We need to use AppCompatActivity from android.support.v7.app.AppCompatActivity to have access to the SupportActionBar until the minimum API is >= 21. public class MainWebViewActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, CreateHomeScreenShortcut.CreateHomeScreenSchortcutListener { - // favoriteIcon is public static so it can be accessed from CreateHomeScreenShortcut and BookmarksActivity. - // It is also used in onCreate() and onCreateHomeScreenShortcutCreate(). + // `favoriteIcon` is public static so it can be accessed from `CreateHomeScreenShortcut`, `BookmarksActivity`, and `EditBookmark`. + // It is also used in `onCreate()` and `onCreateHomeScreenShortcutCreate()`. public static Bitmap favoriteIcon; // mainWebView is public static so it can be accessed from SettingsFragment. diff --git a/app/src/main/res/drawable/back.xml b/app/src/main/res/drawable/back.xml index 28da543b..e69b5ad5 100644 --- a/app/src/main/res/drawable/back.xml +++ b/app/src/main/res/drawable/back.xml @@ -3,6 +3,7 @@ . --> + + + + + diff --git a/app/src/main/res/drawable/exit.xml b/app/src/main/res/drawable/exit.xml index f50586d2..89d4faff 100644 --- a/app/src/main/res/drawable/exit.xml +++ b/app/src/main/res/drawable/exit.xml @@ -3,6 +3,7 @@ . --> - - - + + + - - + + + + + + + + android:layout_marginTop="6dp" + android:layout_marginBottom="12dp" + android:layout_marginStart="4dp" + android:layout_marginEnd="4dp" > + + + \ No newline at end of file diff --git a/app/src/main/res/layout/create_home_screen_shortcut_dialog.xml b/app/src/main/res/layout/create_home_screen_shortcut_dialog.xml index 32d2eb4d..5e924111 100644 --- a/app/src/main/res/layout/create_home_screen_shortcut_dialog.xml +++ b/app/src/main/res/layout/create_home_screen_shortcut_dialog.xml @@ -21,23 +21,22 @@ + android:layout_height="wrap_content" + android:layout_width="match_parent" > - + - \ No newline at end of file diff --git a/app/src/main/res/layout/edit_bookmark_dialog.xml b/app/src/main/res/layout/edit_bookmark_dialog.xml new file mode 100644 index 00000000..1768ca08 --- /dev/null +++ b/app/src/main/res/layout/edit_bookmark_dialog.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/main_coordinatorlayout.xml b/app/src/main/res/layout/main_coordinatorlayout.xml index b59aeb45..520f450e 100644 --- a/app/src/main/res/layout/main_coordinatorlayout.xml +++ b/app/src/main/res/layout/main_coordinatorlayout.xml @@ -71,7 +71,8 @@ android:layout_height="match_parent" android:layout_gravity="start" app:headerLayout="@layout/navigation_header" - app:menu="@menu/webview_navigation_menu"/> + app:menu="@menu/webview_navigation_menu" + app:itemIconTint="@color/blue_gray" /> . --> - + - - + - - - - + - - + - \ No newline at end of file diff --git a/app/src/main/res/menu/bookmarks_context_menu.xml b/app/src/main/res/menu/bookmarks_context_menu.xml index 0d64adc0..6b2fc748 100644 --- a/app/src/main/res/menu/bookmarks_context_menu.xml +++ b/app/src/main/res/menu/bookmarks_context_menu.xml @@ -22,10 +22,17 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index dad5ef3f..02fa590f 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -22,7 +22,8 @@ #FF000000 #FF1976D2 - #FF0D4781 + #FF0D47A1 + #FF607d8b #FF64DD17 #FFBBDEFB #FFD50000 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6c87a126..5b5ad90d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -35,6 +35,7 @@ Favorite Icon + URL or Search Terms Navigation Drawer @@ -70,11 +71,16 @@ Create bookmark + Edit bookmark + Save Bookmark name Bookmark URL + New favorite icon + Use new icon Selected + Edit Delete 1 Bookmark Deleted Bookmarks Deleted @@ -191,7 +197,7 @@ Permissions Privacy Policy Changelog - License + Licenses Contributors Links